ability to alter environment per job

git-svn-id: https://subversion.assembla.com/svn/qmcdev/trunk@6401 e5b18d87-469d-4833-9cc0-8cdfa06e9491
This commit is contained in:
Jaron Krogel 2014-11-13 20:33:08 +00:00
parent 505250db83
commit 2828381b3c
4 changed files with 767 additions and 93 deletions

View File

@ -132,6 +132,9 @@ class Job(Pobj):
app_props = None,
app = None,
env = None,
user_env = True,
presub = '',
postsub = '',
outfile = None,
errfile = None,
mode = None,
@ -170,6 +173,9 @@ class Job(Pobj):
self.app_props = app_props
self.outfile = outfile
self.errfile = errfile
self.user_env = user_env
self.presub = presub
self.postsub = postsub
self.name = name
self.queue = queue
self.bundled_jobs= bundled_jobs
@ -862,7 +868,13 @@ class Workstation(Machine):
def submit_job(self,job):
pad = self.enter(job.directory,msg=job.simid)
command = 'export OMP_NUM_THREADS='+str(job.threads)+'\n'
if len(job.presub)>0:
command += job.presub+'\n'
#end if
command += job.run_command(self.app_launcher)
if len(job.postsub)>0:
command += job.postsub+'\n'
#end if
command = ('\n'+command).replace('\n','\n '+pad)
job.status = job.states.running
process = obj()
@ -1390,12 +1402,6 @@ class Supercomputer(Machine):
os.system(command)
#end def remove_job
def set_submission_commands(self,job):
self.pre_submission_commands = 'date\n'
self.post_submission_commands= ''
#end def set_submission_commands
def setup_environment(self,job):
env = ''
@ -1412,13 +1418,16 @@ class Supercomputer(Machine):
job.subfile = job.name+'.'+self.sub_launcher+'.in'
env = self.setup_environment(job)
command = job.run_command(self.app_launcher)
self.set_submission_commands(job)
c = self.write_job_header(job)+'\n'
c+=self.pre_submission_commands+'\n'
if len(job.presub)>0:
c+=job.presub+'\n'
#end if
c+=env
c+=command+'\n'
c+=self.post_submission_commands+'\n'
if len(job.postsub)>0:
c+=job.postsub+'\n'
#end if
filepath = os.path.join(job.directory,job.subfile)
fobj = open(filepath,'w')
@ -1479,8 +1488,10 @@ class Kraken(Supercomputer):
c+='#PBS -l size='+str(job.tot_cores)+'\n'
c+='#PBS -o '+job.outfile+'\n'
c+='#PBS -e '+job.errfile+'\n'
c+='''#PBS -V
if job.user_env:
c+='#PBS -V\n'
#end if
c+='''
cd $PBS_O_WORKDIR
export MPICH_PTL_SEND_CREDITS=-1
export MPICH_MAX_SHORT_MSG_SIZE=1024
@ -1518,7 +1529,9 @@ class Jaguar(Supercomputer):
c+='#PBS -l gres=widow2%widow3\n'
c+='#PBS -o '+job.outfile+'\n'
c+='#PBS -e '+job.errfile+'\n'
#c+='#PBS -V\n'
if job.user_env:
c+='#PBS -V\n'
#end if
c+='''
echo $PBS_O_WORKDIR
cd $PBS_O_WORKDIR
@ -1555,8 +1568,10 @@ class Taub(Supercomputer):
c+='#PBS -l walltime='+job.pbs_walltime()+'\n'
c+='#PBS -e '+job.errfile+'\n'
c+='#PBS -o '+job.outfile+'\n'
c+='''#PBS -V
if job.user_env:
c+='#PBS -V\n'
#end if
c+='''
cd ${PBS_O_WORKDIR}
export MPICH_PTL_SEND_CREDITS=-1
@ -1618,8 +1633,10 @@ class OIC5(Supercomputer):
c+='#PBS -W x=\"NACCESSPOLICY:SINGLEJOB\"\n'
c+='#PBS -o '+job.outfile+'\n'
c+='#PBS -e '+job.errfile+'\n'
c+='''#PBS -V
if job.user_env:
c+='#PBS -V\n'
#end if
c+='''
echo $PBS_O_WORKDIR
cd $PBS_O_WORKDIR
'''
@ -1645,9 +1662,7 @@ cd $PBS_O_WORKDIR
class Edison(Supercomputer):
name = 'edison'
class NerscMachine(Supercomputer):
batch_capable = True
def process_job_extra(self,job):
@ -1667,7 +1682,6 @@ class Edison(Supercomputer):
#end if
#end def process_job_extra
def write_job_header(self,job):
if job.queue is None:
job.queue = 'regular'
@ -1680,30 +1694,25 @@ class Edison(Supercomputer):
c+='#PBS -l mppwidth={0}\n'.format(job.tot_cores)
c+='#PBS -o '+job.outfile+'\n'
c+='#PBS -e '+job.errfile+'\n'
c+='''#PBS -V
if job.user_env:
c+='#PBS -V\n'
#end if
c+='''
echo $PBS_O_WORKDIR
cd $PBS_O_WORKDIR
'''
return c
#end def write_job_header
#end class NerscMachine
def read_process_id(self,output):
pid = None
lines = output.splitlines()
for line in lines:
if 'edison' in line:
spid = line.split('.')[0]
if spid.isdigit():
pid = int(spid)
#end if
#end if
#end for
return pid
#end def read_process_id
class Edison(NerscMachine):
name = 'edison'
#end class Edison
class Hopper(NerscMachine):
name = 'hopper'
#end class Hopper
@ -1720,8 +1729,10 @@ class BlueWatersXK(Supercomputer):
c+='#PBS -l nodes={0}:ppn={1}:xk\n'.format(job.nodes,job.ppn)
c+='#PBS -o '+job.outfile+'\n'
c+='#PBS -e '+job.errfile+'\n'
c+='''#PBS -V
if job.user_env:
c+='#PBS -V\n'
#end if
c+='''
echo $PBS_O_WORKDIR
cd $PBS_O_WORKDIR
'''
@ -1745,8 +1756,10 @@ class BlueWatersXE(Supercomputer):
c+='#PBS -l nodes={0}:ppn={1}:xe\n'.format(job.nodes,job.ppn)
c+='#PBS -o '+job.outfile+'\n'
c+='#PBS -e '+job.errfile+'\n'
c+='''#PBS -V
if job.user_env:
c+='#PBS -V\n'
#end if
c+='''
echo $PBS_O_WORKDIR
cd $PBS_O_WORKDIR
'''
@ -1777,7 +1790,9 @@ class Titan(Supercomputer):
c+='#PBS -l nodes={0}\n'.format(job.nodes)
#c+='#PBS -l gres=widow3\n'
c+='#PBS -l gres=atlas1\n'
c+='#PBS -V\n'
if job.user_env:
c+='#PBS -V\n'
#end if
c+='''
echo $PBS_O_WORKDIR
cd $PBS_O_WORKDIR
@ -1817,7 +1832,9 @@ class EOS(Supercomputer):
c+='#PBS -l walltime={0}\n'.format(job.pbs_walltime())
c+='#PBS -l nodes={0}\n'.format(job.nodes)
c+='#PBS -l gres=atlas1\n'
c+='#PBS -V\n'
if job.user_env:
c+='#PBS -V\n'
#end if
c+='''
echo $PBS_O_WORKDIR
cd $PBS_O_WORKDIR
@ -1907,7 +1924,9 @@ class Lonestar(Supercomputer): # Lonestar contribution from Paul Young
c+='#$ -l h_rt={0}\n'.format(job.pbs_walltime())
c+='#$ -pe 12way {0}\n'.format(job.nodes*12)
c+='#$ -cwd\n'
c+='#$ -V\n'
if job.user_env:
c+='#$ -V\n'
#end if
return c
#end def write_job_header
@ -2054,6 +2073,7 @@ Jaguar( 18688, 2, 8, 32, 100, 'aprun', 'qsub', 'qstat', 'q
Kraken( 9408, 2, 6, 16, 100, 'aprun', 'qsub', 'qstat', 'qdel')
Taub( 400, 2, 6, 24, 50, 'mpirun', 'qsub', 'qstat', 'qdel')
OIC5( 28, 2, 16, 128, 1000, 'mpirun', 'qsub', 'qstat', 'qdel')
Hopper( 6384, 2, 12, 64, 1000, 'aprun', 'qsub', 'qstat', 'qdel')
Edison( 664, 2, 8, 64, 100, 'aprun', 'qsub', 'qstat', 'qdel')
BlueWatersXK( 3072, 1, 16, 32, 100, 'aprun', 'qsub', 'qstat', 'qdel')
BlueWatersXE(22640, 2, 16, 64, 100, 'aprun', 'qsub', 'qstat', 'qdel')

View File

@ -281,6 +281,8 @@ class SemilocalPP(Pseudopotential):
numeric = False
interpolatable = True
formats = ['qmcpack']
def __init__(self,filepath=None,format=None,name=None,src=None):
self.name = name
self.rcut = None
@ -327,7 +329,31 @@ class SemilocalPP(Pseudopotential):
return self.channels[l]
#end def get_channel
def remove_channel(self,l):
if l in self.channels:
del self.channels[l]
if self.local==l:
lmax = -1
for lt in self.channels.keys():
li = self.l_int_from_text(lt)
if li>lmax:
lmax = li
self.local = lt
#end if
#end for
self.lmax = lmax
#end if
#end if
#end def remove_channel
def l_int_from_text(self,ltext):
lint = 'spdfgh'.find(ltext)
return lint
#end def l_int_from_text
def evaluate(self,r=None,l=None,rpow=0,with_local=False):
if self.numeric and not self.interpolatable:
r = None
@ -685,21 +711,48 @@ class GFit(DevBase):
class GaussianPP(SemilocalPP):
requires_format = True
formats = 'gaussian gamess'.split()
formats = SemilocalPP.formats + 'gaussian gamess'.split()
@staticmethod
def process_float(s):
return float(s.replace('D','e').replace('d','e'))
#end def process_float
def __init__(self,filepath=None,format=None,name=None,src=None):
self.basis = None
SemilocalPP.__init__(self,filepath,format,name,src)
#end def __init__
def read_text(self,text,format=None):
rawlines = text.splitlines()
lines = []
sections = []
last_empty = True
for rline in rawlines:
line = rline.strip()
if (not line.startswith('!')) and (not line.startswith('#')) and len(line)>0:
if last_empty:
lines = []
sections.append(lines)
#end if
lines.append(line)
last_empty = False
else:
last_empty = True
#end if
#end for
del lines
if len(sections)==2:
basis_lines = sections[0]
lines = sections[1]
else:
basis_lines = None
lines = sections[0]
#end if
format=format.lower()
channels = []
basis = None
if format=='gamess':
i=0
name,type,Zcore,lmax = lines[i].split(); i+=1
@ -715,6 +768,24 @@ class GaussianPP(SemilocalPP):
#end for
channels.append(terms)
#end while
if basis_lines!=None:
i=1
basis = obj()
while i<len(basis_lines):
tokens = basis_lines[i].split(); i+=1
ltext = tokens[0].lower()
ngauss = int(tokens[1])
scale = array(tokens[2:],dtype=float)
bterms = obj()
for j in xrange(ngauss):
index,expon,coeff = basis_lines[i].split(); i+=1
expon = GaussianPP.process_float(expon)
coeff = GaussianPP.process_float(coeff)
bterms.append(obj(expon=expon,coeff=coeff))
#end for
basis.append(obj(l=ltext,scale=scale,terms=bterms))
#end while
#end if
elif format=='gaussian':
i=0
element,token = lines[i].split(); i+=1
@ -731,6 +802,24 @@ class GaussianPP(SemilocalPP):
#end for
channels.append(terms)
#end while
if basis_lines!=None:
i=1
basis = obj()
while i<len(basis_lines):
tokens = basis_lines[i].split(); i+=1
ltext = tokens[0].lower()
ngauss = int(tokens[1])
scale = array(tokens[2:],dtype=float)
bterms = obj()
for j in xrange(ngauss):
expon,coeff = basis_lines[i].split(); i+=1
expon = GaussianPP.process_float(expon)
coeff = GaussianPP.process_float(coeff)
bterms.append(obj(expon=expon,coeff=coeff))
#end for
basis.append(obj(l=ltext,scale=scale,terms=bterms))
#end while
#end if
else:
self.error('ability to read file format {0} has not been implemented'.format(format))
#end if
@ -752,7 +841,8 @@ class GaussianPP(SemilocalPP):
)
for c in range(len(channels)):
if c==0:
cname = 'loc'
#cname = 'loc'
cname = self.l_channels[lmax]
self.local = cname
else:
cname = self.l_channels[c-1]
@ -765,6 +855,7 @@ class GaussianPP(SemilocalPP):
#end for
self.channels[cname] = channel
#end for
self.basis = basis
if len(self.channels)!=self.lmax+1:
self.error('number of channels is not lmax+1!')
#end if
@ -774,32 +865,69 @@ class GaussianPP(SemilocalPP):
def write_text(self,format=None):
text = ''
format = format.lower()
if format=='qmcpack':
return self.write_qmcpack()
#end if
channel_order = [self.local]
for c in self.all_channels:
if c in self.channels and c!=self.local:
channel_order.append(c)
#end if
#end for
if format=='gamess':
text += '{0}-PP GEN {1} {2}\n'.format(self.element,self.Zcore,self.lmax)
for c in self.all_channels:
if c in self.channels:
channel = self.channels[c]
text += '{0}\n'.format(len(channel))
for i in sorted(channel.keys()):
g = channel[i]
text += '{0:12.8f} {1} {2:12.8f}\n'.format(g.coeff,g.rpow,g.expon)
if self.basis!=None:
text += '{0} {1} 0. 0. 0.\n'.format(self.element,self.Zcore+self.Zval)
for ib in xrange(len(self.basis)):
b = self.basis[ib]
line = '{0} {1}'.format(b.l,len(b.terms))
for s in b.scale:
line += ' {0}'.format(s)
#end for
#end if
text += line + '\n'
for it in xrange(len(b.terms)):
t = b.terms[it]
text += '{0} {1:12.8e} {2:12.8e}\n'.format(it+1,t.expon,t.coeff)
#end for
#end for
text += '\n'
#end if
text += '{0}-PP GEN {1} {2}\n'.format(self.element,self.Zcore,self.lmax)
for c in channel_order:
channel = self.channels[c]
text += '{0}\n'.format(len(channel))
for i in sorted(channel.keys()):
g = channel[i]
text += '{0:12.8f} {1} {2:12.8f}\n'.format(g.coeff,g.rpow,g.expon)
#end for
#end for
text += '\n'
elif format=='gaussian':
text += '{0} 0\n'.format(self.element)
text += '{0}_PP {1} {2}\n'.format(self.element,self.lmax,self.Zcore)
for c in self.all_channels:
if c in self.channels:
channel = self.channels[c]
text += '{0} channel\n'.format(c)
text += '{0}\n'.format(len(channel))
for i in sorted(channel.keys()):
g = channel[i]
text += '{0} {1:12.8f} {2:12.8f}\n'.format(g.rpow,g.expon,g.coeff)
if self.basis!=None:
for ib in xrange(len(self.basis)):
b = self.basis[ib]
line = '{0} {1}'.format(b.l,len(b.terms))
for s in b.scale:
line += ' {0}'.format(s)
#end for
#end if
text += line + '\n'
for it in xrange(len(b.terms)):
t = b.terms[it]
text += '{0:12.8e} {1:12.8e}\n'.format(t.expon,t.coeff)
#end for
#end for
text += '\n'
#end if
text += '{0} 0\n'.format(self.element)
text += '{0}_PP {1} {2}\n'.format(self.element,self.lmax,self.Zcore)
for c in channel_order:
channel = self.channels[c]
text += '{0} channel\n'.format(c)
text += '{0}\n'.format(len(channel))
for i in sorted(channel.keys()):
g = channel[i]
text += '{0} {1:12.8f} {2:12.8f}\n'.format(g.rpow,g.expon,g.coeff)
#end for
#end for
text += '\n'
else:

View File

@ -1,7 +1,7 @@
import os
from generic import obj
from simulation import Simulation
from simulation import Simulation,SimulationInput,SimulationAnalyzer
from vasp_input import VaspInput,generate_vasp_input
from vasp_analyzer import VaspAnalyzer
@ -87,3 +87,146 @@ def generate_vasp(**kwargs):
return vasp
#end def generate_vasp
# VASP HT (hand template) classes and functions
class VaspHTAnalyzer(SimulationAnalyzer):
def __init__(self,arg0=None,xml=False,analyze=False):
self.info = obj(xml=xml)
prefix = None
if isinstance(arg0,Simulation):
sim = arg0
infile = sim.infile
path = sim.locdir
elif arg0!=None:
path,infile = os.path.split(arg0)
if infile=='':
infile = None
#end if
if infile!=None:
if not infile.endswith('INCAR'):
self.error('please provide the path to an INCAR file')
#end if
prefix = infile.replace('INCAR','').strip()
if prefix=='':
prefix=None
#end if
#end if
else:
self.info.xml = False
return
#end if
self.info.set(
path = path,
infile = infile,
prefix = prefix
)
if analyze:
self.analyze()
#end if
#end def __init__
def analyze(self):
if self.info.xml:
xmlfile = 'vasprun.xml'
if self.info.prefix!=None:
xmlfile = self.info.prefix+xmlfile
#end if
self.xmldata = read_vxml(os.path.join(self.info.path,xmlfile))
#end if
#end def analyze
#end class VaspHTAnalyzer
class VaspHT(Simulation):
input_type = SimulationInput
analyzer_type = VaspHTAnalyzer
generic_identifier = 'vasp_ht'
infile_extension = None
application = 'vasp'
application_properties = set(['serial','mpi'])
application_results = set([])
allow_overlapping_files = True
vasp_save_files = 'INCAR KPOINTS POSCAR CONTCAR DOSCAR EIGENVAL IBZKPT OSZICAR OUTCAR PCDAT XDATCAR vasprun.xml'.split()
all_inputs = 'INCAR KPOINTS POSCAR POTCAR'.split()
all_outputs = 'CHG CHGCAR CONTCAR DOSCAR EIGENVAL IBZKPT OSZICAR OUTCAR PCDAT PROCAR WAVECAR XDATCAR'.split()
def set_files(self):
self.infile = 'INCAR'
self.outfile = self.identifier + self.outfile_extension
self.errfile = self.identifier + self.errfile_extension
#end def set_files
def check_result(self,result_name,sim):
return False
#end def check_result
def get_result(self,result_name,sim):
self.not_implemented()
#end def get_result
def incorporate_result(self,result_name,result,sim):
self.not_implemented()
#end def incorporate_result
def app_command(self):
command_line_args = ''
return self.app_name + command_line_args
#end def app_command
def check_sim_status(self):
success = False
outpath = os.path.join(self.locdir,'OUTCAR')
if os.path.exists(outpath):
outcar = open(outpath,'r').read()
success = 'General timing and accounting' in outcar
#end if
self.finished = success
#end def check_sim_status
def get_output_files(self):
output_files = []
for file in self.vasp_save_files:
native_file = os.path.join(self.locdir,file)
save_file = os.path.join(self.locdir,self.identifier+'.'+file)
if os.path.exists(native_file):
os.system('cp {0} {1}'.format(native_file,save_file))
output_files.append(file)
#end if
#end for
return output_files
#end def get_output_files
#end class VaspHT
def generate_vasp_ht(**kwargs):
sim_args,inp_args = Simulation.separate_inputs(kwargs,copy_pseudos=False)
if not 'input' in sim_args:
VaspHT.class_error('input keyword is required','generate_vasp_ht')
#end if
vasp_ht = VaspHT(**sim_args)
return vasp_ht
#end def generate_vasp_ht

View File

@ -8,6 +8,7 @@ from developer import DevBase
from debug import *
# vasp xml reader classes/functions
class VXML(DevBase):
basic_types = set('i v dimension field set time'.split())
@ -407,51 +408,433 @@ def read_vxml(filepath):
# vasp outcar functions
class VaspLines(DevBase):
def __init__(self,lines):
self.pointer = 0
self.lines = lines
#end def __init__
def advance_line(self,amount):
self.pointer += amount
return self.lines[self.pointer]
#end def advance_line
def advance_token(self,token):
psave = self.pointer
for line in self.lines[self.pointer:]:
if token in line:
return line
#end if
self.pointer += 1
#end while
self.pointer = psave
return None
#end def advance
def advance(self,amount):
self.pointer += amount
#end def advance
def remainder(self):
return self.lines[self.pointer:]
#end def remainder
def rewind(self,point=0):
self.pointer = point
#end def rewind
def get_line(self,point=None):
if point is None:
point = self.pointer
#end if
return self.lines[point]
#end def get_line
def get_line_ahead(self,nahead):
return self.lines[self.pointer+nahead]
#end def get_line_ahead
#end class VaspLines
def read_outcar_header_values(vlines,odata):
line = vlines.advance_token('TOTEN')
odata.total_energy = float(line.split()[4])
vlines.advance_token('energy without entropy')
#end def read_outcar_header_values
def read_outcar_core_potentials(vlines,odata):
line = vlines.advance_token('the test charge radii are')
odata.core_potential_radii = array(line.split()[5:],dtype=float)
vlines.advance(2)
n = 0
cpots = []
for line in vlines.remainder():
ls = line.strip()
n+=1
if len(ls)==0:
break
#end if
tokens = line.replace('-',' -').split()
cpots.extend(tokens[1::2])
#end for
odata.core_potentials = array(cpots,dtype=float)
vlines.advance(n)
#end def read_outcar_core_potentials
def read_outcar_fermi_energy(vlines,odata):
line = vlines.advance_token('E-fermi')
odata.Efermi = float(line.split()[2])
#end def read_outcar_fermi_energy
def read_outcar_bands(vlines,odata):
bands = obj()
line = vlines.advance_token('spin component')
if line!=None:
last_empty = True
n = 0
for line in vlines.remainder():
if len(line)>2:
if line[1]=='s':
ns = int(line.split()[2])
spin = obj()
bands[ns] = spin
elif line[1]=='k':
tokens = line.split()
nk = int(tokens[1])
kp = array(tokens[3:],dtype=float)
kpoint = obj(kpoint=kp,energies=[],occupations=[])
spin[nk]=kpoint
elif line[2]=='b':
None
else:
bnum,energy,occ = line.split()
kpoint.energies.append(float(energy))
kpoint.occupations.append(float(occ))
#end if
last_empty = False
else:
if last_empty:
break
#end if
last_empty = True
#end if
n+=1
#end for
vlines.advance(n)
#end if
for ns,spin in bands.iteritems():
for nk,kpoint in spin.iteritems():
kpoint.energies = array(kpoint.energies,dtype=float)
kpoint.occupations = array(kpoint.occupations,dtype=float)
#end for
#end for
odata.bands = bands
#end def read_outcar_bands
def read_outcar_charge_mag(vlines,odata,token):
ion = obj(s=[],p=[],d=[],tot=[])
total = obj()
vlines.advance_token(token)
vlines.advance(4)
prev_end = False
n=0
for line in vlines.remainder():
n+=1
if prev_end:
break
#end if
if line[0]=='-':
prev_end = True
else:
vals = array(line.split()[1:],dtype=float)
ion.s.append(vals[0])
ion.p.append(vals[1])
ion.d.append(vals[2])
ion.tot.append(vals[3])
#end if
#end for
for channel,vals in ion.iteritems():
ion[channel] = array(vals,dtype=float)
#end for
vlines.advance(n)
vals = array(line.split()[1:],dtype=float)
total.s = vals[0]
total.p = vals[1]
total.d = vals[2]
total.tot = vals[3]
return ion,total
#end def read_outcar_charge_mag
def read_outcar_total_charge(vlines,odata):
ion,total = read_outcar_charge_mag(vlines,odata,'total charge ') # trailing space is important
odata.ion_charge = ion
odata.total_charge = total
#end def read_outcar_total_charge
def read_outcar_magnetization(vlines,odata):
ion,total = read_outcar_charge_mag(vlines,odata,'magnetization')
odata.ion_magnetization = ion
odata.total_magnetization = total
#end def read_outcar_magnetization
def read_outcar_stress(vlines,odata):
vlines.advance_token('FORCE on cell')
line = vlines.advance_line(1)
dirs = line.split()[1:]
st = array(vlines.advance_token('Total').split()[1:],dtype=float)
st_kb = array(vlines.advance_line(1).split()[2:],dtype=float)
pressure = float(vlines.advance_line(1).split()[3])
stress = obj()
stress_kb = obj()
for i in range(len(dirs)):
d = dirs[i].lower()
stress[d] = st[i]
stress_kb[d] = st_kb[i]
#end for
odata.stress = stress
odata.stress_kb = stress_kb
odata.pressure = pressure
#end def read_outcar_stress
def read_outcar_cell(vlines,odata):
vlines.advance_token('VOLUME and BASIS')
volume = float(vlines.advance_line(3).split()[-1])
a1 = vlines.advance_line(2).split()[0:3]
a2 = vlines.advance_line(1).split()[0:3]
a3 = vlines.advance_line(1).split()[0:3]
lattice_vectors = array([a1,a2,a3],dtype=float)
odata.volume = volume
odata.lattice_vectors = lattice_vectors
#end def read_outcar_cell
def read_outcar_position_force(vlines,odata):
position = []
force = []
vlines.advance_token('POSITION')
vlines.advance(2)
prev_end = False
for line in vlines.remainder():
if prev_end:
break
#end if
if line[1]=='-':
prev_end = True
else:
tokens = line.split()
position.append(tokens[0:3])
force.append(tokens[3:6])
#end if
#end for
total_drift = line.split()[2:5]
odata.position = array(position,dtype=float)
odata.force = array(force,dtype=float)
odata.total_drift = array(total_drift,dtype=float)
#end def read_outcar_position_force
def read_outcar_accounting(vlines,odata):
time = obj()
memory = obj()
vlines.advance_token('General timing and accounting')
vlines.advance(2)
time.cpu = float(vlines.advance_line(1).split()[-1])
time.user = float(vlines.advance_line(1).split()[-1])
time.system = float(vlines.advance_line(1).split()[-1])
time.elapsed = float(vlines.advance_line(1).split()[-1])
vlines.advance(1)
memory.maximum = float(vlines.advance_line(1).split()[-1])
memory.average = float(vlines.advance_line(1).split()[-1])
odata.time = time
odata.memory = memory
#end def read_outcar_accounting
class OutcarData(DevBase):
any_functions = [
('header_values' , read_outcar_header_values ),
]
elast_functions = [
('core_potentials' , read_outcar_core_potentials),
('fermi_energy' , read_outcar_fermi_energy ),
('bands' , read_outcar_bands ),
('total_charge' , read_outcar_total_charge ),
('magnetization' , read_outcar_magnetization ),
('stress' , read_outcar_stress ),
('cell' , read_outcar_cell ),
('position_force' , read_outcar_position_force ),
]
ilast_functions = [
('accounting' , read_outcar_accounting ),
]
read_outcar_functions = any_functions + elast_functions + ilast_functions
def __init__(self,filepath=None,lines=None):
if filepath!=None:
if not os.path.exists(filepath):
self.error('file {0} does not exist'.format(filepath))
#end if
f = open(filepath,'r')
lines = f.read().splitlines()
f.close()
#end if
self.vlines = VaspLines(lines)
#end def __init__
def read(self,ilast=False,elast=False,all=True):
ilast |= all
elast |= all
vlines = self.vlines
del self.vlines
read_functions = []
read_functions.extend(self.any_functions)
if elast:
read_functions.extend(self.elast_functions)
if ilast:
read_functions.extend(self.ilast_functions)
#end if
#end if
for quantity,read_function in read_functions:
try:
read_function(vlines,self)
except:
None
#end try
#end for
#end def read
#end class OutcarData
# main analyzer class
class VaspAnalyzer(SimulationAnalyzer):
def __init__(self,arg0=None,xml=False,analyze=False):
self.info = obj(xml=xml)
prefix = None
path = None
prefix = None
incar = None
outcar = None
xmlfile = None
if isinstance(arg0,Simulation):
sim = arg0
infile = sim.infile
file = sim.infile
path = sim.locdir
elif arg0!=None:
path,infile = os.path.split(arg0)
if infile=='':
infile = None
#end if
if infile!=None:
if not infile.endswith('INCAR'):
self.error('please provide the path to an INCAR file')
#end if
prefix = infile.replace('INCAR','').strip()
if prefix=='':
prefix=None
#end if
#end if
path,file = os.path.split(arg0)
else:
self.info.xml = False
return
file = ''
xml = False
#end if
self.info.set(
path = path,
infile = infile,
prefix = prefix
if len(file)>0:
if file.endswith('INCAR'):
incar = file
prefix = file.replace('INCAR','').strip()
elif file.endswith('OUTCAR'):
prefix = file.replace('OUTCAR','').strip()
else:
self.error('please provide the path to an INCAR or OUTCAR file')
#end if
outcar = prefix+'OUTCAR'
xmlfile = prefix+'vasprun.xml'
if prefix=='':
prefix=None
#end if
#end if
self.info = obj(
path = path,
prefix = prefix,
incar = incar,
outcar = outcar,
xmlfile = xmlfile,
xml = xml
)
if analyze:
self.analyze()
#end if
#end def __init__
def analyze(self):
def analyze(self,outcar=None):
if outcar is None and self.info.outcar!=None:
outcar = os.path.join(self.info.path,self.info.outcar)
#ned if
if self.info.xml:
xmlfile = 'vasprun.xml'
if self.info.prefix!=None:
xmlfile = self.info.prefix+xmlfile
#end if
self.xmldata = read_vxml(os.path.join(self.info.path,xmlfile))
self.xmldata = read_vxml(os.path.join(self.info.path,self.info.xmlfile))
#end if
if outcar!=None:
self.analyze_outcar(outcar)
#end if
#end def analyze
def analyze_outcar(self,outcar):
if not os.path.exists(outcar):
self.error('outcar file {0} does not exist'.format(outcar))
#end if
oc = open(outcar,'r')
lines = oc.read().splitlines()
oc.close()
del oc
# gather initialization lines
init = []
n = 0
for line in lines:
if len(line)>0 and line[0]=='-' and 'Iteration' in line:
break
#end if
init.append(line)
n+=1
#end for
# gather lines for each iteration
ion_steps = obj()
for line in lines[n:]:
if len(line)>0 and line[0]=='-' and 'Iteration' in line:
iteration = []
inum,enum = line.strip(' -Iteration)').split('(')
inum = int(inum)
enum = int(enum)
if not inum in ion_steps:
ion_steps[inum] = obj()
#end if
ion_steps[inum][enum] = OutcarData(lines=iteration)
#end if
iteration.append(line)
#end for
del lines
del n
# read data from each iteration
if len(ion_steps)>0:
imax = array(ion_steps.keys(),dtype=int).max()
for inum,ion_step in ion_steps.iteritems():
ilast = inum==imax
if len(ion_step)>0:
emax = array(ion_step.keys(),dtype=int).max()
for enum,elec_step in ion_step.iteritems():
elast = enum==emax
elec_step.read(ilast,elast,all=False)
if ilast and elast:
self.transfer_from(elec_step)
#end if
#end for
#end if
#end for
#end if
self.ion_steps = ion_steps
#end def analyze_outcar
#end class VaspAnalyzer