mirror of https://github.com/QMCPACK/qmcpack.git
363 lines
11 KiB
Python
363 lines
11 KiB
Python
##################################################################
|
|
## (c) Copyright 2015- by Jaron T. Krogel ##
|
|
##################################################################
|
|
|
|
|
|
#====================================================================#
|
|
# pw2casino.py #
|
|
# Nexus interface for the pw2casino tool distributed with PWSCF. #
|
|
# pseudopotentials between file formats. #
|
|
# #
|
|
# Content summary: #
|
|
# generate_pw2casino #
|
|
# User-facing function to create pw2casino simulation objects. #
|
|
# #
|
|
# generate_pw2casino_input #
|
|
# User-facing funcion to create input for pw2casino. #
|
|
# #
|
|
# Pw2casino #
|
|
# Simulation class for pw2casino. #
|
|
# #
|
|
# Pw2casinoInput #
|
|
# SimulationInput class for pw2casino. #
|
|
# #
|
|
# Pw2casinoAnalyzer #
|
|
# SimulationAnalyzer class for pw2casino. #
|
|
# Reads data from pw2casino log output into numeric form. #
|
|
# #
|
|
#====================================================================#
|
|
|
|
|
|
import os
|
|
from generic import obj
|
|
from unit_converter import convert
|
|
from simulation import Simulation,SimulationInput,SimulationAnalyzer
|
|
|
|
|
|
def read_str(sv):
|
|
return sv.strip('"').strip("'")
|
|
#end def read_str
|
|
|
|
def read_int(sv):
|
|
return int(sv)
|
|
#end def read_int
|
|
|
|
def read_float(sv):
|
|
return float(sv.replace('d','e').replace('D','e'))
|
|
#end def read_float
|
|
|
|
bconv = {'.true.':True,'.false.':False}
|
|
def read_bool(sv):
|
|
return bconv[sv]
|
|
#end def read_bool
|
|
|
|
def write_str(val):
|
|
return "'"+val+"'"
|
|
#end def write_str
|
|
|
|
def write_int(val):
|
|
return str(val)
|
|
#end def write_int
|
|
|
|
def write_float(val):
|
|
return str(val)
|
|
#end def write_float
|
|
|
|
def write_bool(val):
|
|
return '.'+str(val).lower()+'.'
|
|
#end def write_bool
|
|
|
|
readval={str:read_str,int:read_int,float:read_float,bool:read_bool}
|
|
writeval={str:write_str,int:write_int,float:write_float,bool:write_bool}
|
|
|
|
|
|
class Pw2casinoInput(SimulationInput):
|
|
ints = []
|
|
floats = []
|
|
strs = ['outdir','prefix']
|
|
bools = ['write_psir']
|
|
|
|
var_types = dict()
|
|
for v in ints:
|
|
var_types[v]=int
|
|
for v in floats:
|
|
var_types[v]=float
|
|
for v in strs:
|
|
var_types[v]=str
|
|
for v in bools:
|
|
var_types[v]=bool
|
|
|
|
allowed = set(ints+floats+strs+bools)
|
|
|
|
def read_text(self,contents,filepath=None):
|
|
lines = contents.split('\n')
|
|
inside = False
|
|
for l in lines:
|
|
if inside:
|
|
tokens = l.split(',')
|
|
for t in tokens:
|
|
ts = t.strip()
|
|
if ts!='' and ts!='/':
|
|
name,value = ts.split('=')
|
|
name = name.strip()
|
|
value= value.strip()
|
|
if name in self.allowed:
|
|
vtype = self.var_types[name]
|
|
value = readval[vtype](value)
|
|
sobj[name]=value
|
|
else:
|
|
print name in self.allowed
|
|
self.error('encountered unknown variable: '+name)
|
|
#end if
|
|
#end if
|
|
#end for
|
|
#end if
|
|
if '&' in l:
|
|
inside=True
|
|
section = l.lstrip('&').lower()
|
|
sobj = obj()
|
|
self[section]=sobj
|
|
elif l.strip()=='/':
|
|
inside=False
|
|
#end if
|
|
#end for
|
|
#end def read_text
|
|
|
|
def write_text(self,filepath=None):
|
|
contents = ''
|
|
for sname,section in self.iteritems():
|
|
contents+='&'+sname+'\n'
|
|
for name,value in section.iteritems():
|
|
vtype = type(value)
|
|
contents += ' '+name+' = '+writeval[vtype](value)+'\n'
|
|
#end for
|
|
contents+='/\n'
|
|
#end for
|
|
return contents
|
|
#end def write_text
|
|
|
|
|
|
def __init__(self,filepath=None,**vars):
|
|
if filepath!=None:
|
|
self.read(filepath)
|
|
else:
|
|
inputpp = obj()
|
|
for name,value in vars.iteritems():
|
|
inputpp[name] = value
|
|
#end for
|
|
self.inputpp = inputpp
|
|
#end if
|
|
#end def __init__
|
|
#end class Pw2casinoInput
|
|
|
|
|
|
def generate_pw2casino_input(prefix='pwscf',outdir='pwscf_output'):
|
|
pw = Pw2casinoInput(
|
|
prefix = prefix,
|
|
outdir = outdir
|
|
)
|
|
return pw
|
|
#end def generate_pw2casino_input
|
|
|
|
|
|
|
|
class Pw2casinoAnalyzer(SimulationAnalyzer):
|
|
def __init__(self,arg0=None,arg1=None):
|
|
if isinstance(arg0,Simulation):
|
|
sim = arg0
|
|
self.dir = sim.locdir
|
|
self.infile = sim.infile
|
|
self.outfile = sim.outfile
|
|
prefix,outdir = sim.input.inputpp.tuple('prefix','outdir')
|
|
elif arg0 is not None:
|
|
if arg1 is None:
|
|
self.error('must specify output file')
|
|
#end if
|
|
self.dir,self.infile = os.path.split(arg0)
|
|
self.outfile = os.path.split(arg1)[1]
|
|
#end if
|
|
#end def __init__
|
|
|
|
|
|
def analyze(self):
|
|
outfile = os.path.join(self.dir,self.outfile)
|
|
if not os.path.exists(outfile):
|
|
self.error('output file does not exist\n file path: '+outfile)
|
|
#end if
|
|
fobj = open(outfile,'r')
|
|
lines = fobj.read().split('\n')
|
|
fobj.close()
|
|
|
|
self.units = 'Ha'
|
|
|
|
energies = obj()
|
|
for line in lines:
|
|
ls = line.strip()
|
|
name = None
|
|
if ls.startswith('Kinetic energy'):
|
|
name = 'kinetic'
|
|
elif ls.startswith('Local energy'):
|
|
name = 'local'
|
|
elif ls.startswith('Non-Local energy'):
|
|
name = 'nonlocal'
|
|
elif ls.startswith('Ewald energy'):
|
|
name = 'ewald'
|
|
elif ls.startswith('xc contribution'):
|
|
name = 'xc'
|
|
elif ls.startswith('hartree energy'):
|
|
name = 'hartree'
|
|
elif ls.startswith('Total energy'):
|
|
name = 'total'
|
|
#end if
|
|
if name!=None:
|
|
energies[name] = float(ls.split()[2])
|
|
#end if
|
|
#end for
|
|
self.energies = energies
|
|
#end def analyze
|
|
|
|
|
|
def change_units(self,new_unit):
|
|
old_unit = self.units
|
|
for name in self.energy.keys():
|
|
self.energy[name] = convert(self.energy[name],old_unit,new_unit)
|
|
#end for
|
|
self.units = new_unit
|
|
#end def change_units
|
|
|
|
|
|
def get_result(self,result_name):
|
|
self.not_implemented()
|
|
#end def get_result
|
|
#end class Pw2casinoAnalyzer
|
|
|
|
|
|
class Pw2casino(Simulation):
|
|
input_type = Pw2casinoInput
|
|
analyzer_type = Pw2casinoAnalyzer
|
|
generic_identifier = 'pw2casino'
|
|
application = 'pw2casino.x'
|
|
application_properties = set(['serial'])
|
|
application_results = set(['orbitals'])
|
|
|
|
def check_result(self,result_name,sim):
|
|
calculating_result = False
|
|
inputpp = self.input.inputpp
|
|
if result_name=='kinetic_energy':
|
|
calculating_result = True
|
|
else:
|
|
calculating_result = False
|
|
self.error('ability to check for result '+result_name+' has not been implemented')
|
|
#end if
|
|
return calculating_result
|
|
#end def check_result
|
|
|
|
def get_result(self,result_name,sim):
|
|
result = obj()
|
|
inputpp = self.input.inputpp
|
|
prefix = 'pwscf'
|
|
outdir = './'
|
|
if 'prefix' in inputpp:
|
|
prefix = inputpp.prefix
|
|
#end if
|
|
if 'outdir' in inputpp:
|
|
outdir = inputpp.outdir
|
|
#end if
|
|
if outdir.startswith('./'):
|
|
outdir = outdir[2:]
|
|
#end if
|
|
if result_name=='':
|
|
None
|
|
else:
|
|
self.error('ability to get result '+result_name+' has not been implemented')
|
|
#end if
|
|
return result
|
|
#end def get_result
|
|
|
|
def incorporate_result(self,result_name,result,sim):
|
|
if result_name=='orbitals':
|
|
pwin = sim.input.control
|
|
p2in = self.input.inputpp
|
|
pwprefix = 'pwscf'
|
|
p2prefix = 'pwscf'
|
|
pwoutdir = './'
|
|
p2outdir = './'
|
|
if 'prefix' in pwin:
|
|
pwprefix = pwin.prefix
|
|
if 'prefix' in p2in:
|
|
p2prefix = p2in.prefix
|
|
if 'outdir' in pwin:
|
|
pwoutdir = pwin.outdir
|
|
if 'outdir' in p2in:
|
|
p2outdir = p2in.outdir
|
|
if pwoutdir.startswith('./'):
|
|
pwoutdir = pwoutdir[2:]
|
|
if p2outdir.startswith('./'):
|
|
p2outdir = p2outdir[2:]
|
|
pwdir = os.path.abspath(os.path.join(sim.locdir ,pwoutdir))
|
|
p2dir = os.path.abspath(os.path.join(self.locdir,p2outdir))
|
|
errors = False
|
|
if pwdir!=p2dir:
|
|
self.error('to use orbitals, '+self.generic_identifier+' must have the same outdir as pwscf\n pwscf outdir: '+pwdir+'\n '+self.generic_identifier+' outdir: '+p2dir,exit=False)
|
|
errors = True
|
|
#end if
|
|
if pwprefix!=p2prefix:
|
|
self.error('to use orbitals, '+self.generic_identifier+' must have the same prefix as pwscf\n pwscf prefix: '+pwprefix+'\n '+self.generic_identifier+' prefix: '+p2prefix,exit=False)
|
|
errors = True
|
|
#end if
|
|
if errors:
|
|
self.error(self.generic_identifier+' cannot use orbitals from pwscf')
|
|
#end if
|
|
else:
|
|
self.error('ability to incorporate result '+result_name+' has not been implemented')
|
|
#end if
|
|
#end def incorporate_result
|
|
|
|
|
|
def check_sim_status(self):
|
|
outfile = os.path.join(self.locdir,self.outfile)
|
|
fobj = open(outfile,'r')
|
|
output = fobj.read()
|
|
fobj.close()
|
|
|
|
success = 'Total energy' in output
|
|
|
|
self.finished = success and self.job.finished
|
|
#end def check_sim_status
|
|
|
|
|
|
def get_output_files(self):
|
|
output_files = []
|
|
return output_files
|
|
#end def get_output_files
|
|
|
|
|
|
def app_command(self):
|
|
return self.app_name+'<'+self.infile
|
|
#end def app_command
|
|
#end class Pw2casino
|
|
|
|
|
|
|
|
|
|
def generate_pw2casino(**kwargs):
|
|
kw = set(kwargs.keys())
|
|
sim_kw = kw & Simulation.allowed_inputs
|
|
inp_kw = (kw - sim_kw)
|
|
sim_args = dict()
|
|
inp_args = dict()
|
|
for kw in sim_kw:
|
|
sim_args[kw] = kwargs[kw]
|
|
#end for
|
|
for kw in inp_kw:
|
|
inp_args[kw] = kwargs[kw]
|
|
#end for
|
|
|
|
sim_args['input'] = generate_pw2casino_input(**inp_args)
|
|
pw2casino = Pw2casino(**sim_args)
|
|
|
|
return pw2casino
|
|
#end def generate_pw2casino
|
|
|
|
|