qmcpack/nexus/lib/qmcpack_converters.py

1397 lines
43 KiB
Python

##################################################################
## (c) Copyright 2015- by Jaron T. Krogel ##
##################################################################
#====================================================================#
# qmcpack_converters.py #
# Nexus interfaces for orbital converter tools of QMCPACK: #
# pw2qmcpack and convert4qmc #
# #
# Content summary: #
# generate_pw2qmcpack #
# User-facing function to create pw2qmcpack simulation objects. #
# #
# generate_pw2qmcpack_input #
# User-facing funcion to create input for pw2qmcpack. #
# #
# Pw2qmcpack #
# Simulation class for pw2qmcpack. #
# #
# Pw2qmcpackInput #
# SimulationInput class for pw2qmcpack. #
# #
# Pw2qmcpackAnalyzer #
# SimulationAnalyzer class for pw2qmcpack. #
# #
# #
# Convert4qmcInput #
# Class representing command line interface of convert4qmc. #
# #
# Convert4qmcAnalyzer #
# Placeholder class for output analysis. #
# #
# Convert4qmc #
# Class representing convert4qmc instance. #
# #
# generate_convert4qmc_input #
# Function to generate arbitrary convert4qmc input. #
# #
# generate_convert4qmc #
# Function to generate Convert4qmc simulation object. #
# #
#====================================================================#
import os
from generic import obj
from simulation import Simulation,SimulationInput,SimulationAnalyzer
from pwscf import Pwscf
from gamess import Gamess
from pyscf_sim import Pyscf
from quantum_package import QuantumPackage
# read/write functions associated with pw2qmcpack only
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 Pw2qmcpackInput(SimulationInput):
ints = []
floats = []
strs = ['outdir','prefix']
bools = ['write_psir']
var_types = dict()
for v in ints:
var_types[v]=int
#end for
for v in floats:
var_types[v]=float
#end for
for v in strs:
var_types[v]=str
#end for
for v in bools:
var_types[v]=bool
#end for
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:
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.items():
contents+='&'+sname+'\n'
for name,value in section.items():
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.items():
inputpp[name] = value
#end for
self.inputpp = inputpp
#end if
#end def __init__
#end class Pw2qmcpackInput
def generate_pw2qmcpack_input(prefix='pwscf',outdir='pwscf_output',write_psir=False):
pw = Pw2qmcpackInput(
prefix = prefix,
outdir = outdir,
write_psir = write_psir
)
return pw
#end def generate_pw2qmcpack_input
def read_eshdf_eig_data(filename, Ef_list):
import numpy as np
from numpy import array,pi
from numpy.linalg import inv
from unit_converter import convert
from hdfreader import read_hdf
from developer import error
def h5int(i):
return array(i,dtype=int)[0]
#end def h5int
h = read_hdf(filename,view=True)
axes = array(h.supercell.primitive_vectors)
kaxes = 2*pi*inv(axes).T
nk = h5int(h.electrons.number_of_kpoints)
ns = h5int(h.electrons.number_of_spins)
if (len(Ef_list) == 1 and ns == 2):
# Using the same E_fermi for up and down electrons
E_fermi = Ef_list[0]
Ef_list = np.array([E_fermi, E_fermi])
elif len(Ef_list) != ns:
msg = 'Ef "%s" must have same length as nspin=%d' % (str(Ef_list), ns)
error(msg)
data = obj()
for k in range(nk):
kp = h.electrons['kpoint_'+str(k)]
for s, Ef in zip(range(ns), Ef_list):
E_fermi = Ef+1e-8
eig_s = []
path = 'electrons/kpoint_{0}/spin_{1}'.format(k,s)
spin = h.get_path(path)
eig = convert(array(spin.eigenvalues),'Ha','eV')
nst = h5int(spin.number_of_states)
for st in range(nst):
e = eig[st]
if e<E_fermi:
eig_s.append(e)
#end if
#end for
data[k,s] = obj(
kpoint = array(kp.reduced_k),
eig = array(eig_s),
)
#end for
#end for
res = obj(
orbfile = filename,
axes = axes,
kaxes = kaxes,
nkpoints = nk,
nspins = ns,
data = data,
)
return res
#end def read_eshdf_eig_data
def gcta_occupation(wfh5, ntwist):
nspin = wfh5.nspins
nk = wfh5.nkpoints
nprim = nk//ntwist
assert nprim*ntwist == nk
nelecs_at_twist = []
for itwist in range(ntwist):
iks = range(itwist, nk, ntwist)
# calculate nelec for each spin
nelecs = []
for ispin in range(nspin):
nl = [len(wfh5.data[ik, ispin].eig) for ik in iks]
nup = sum(nl)
nelecs.append(nup)
if nspin == 1:
nelecs.append(nup)
nelecs_at_twist.append(nelecs)
return nelecs_at_twist
#end gcta_occupation
class Pw2qmcpackAnalyzer(SimulationAnalyzer):
def __init__(self,arg0):
if isinstance(arg0,Simulation):
sim = arg0
self.infile = sim.infile
prefix,outdir = sim.input.inputpp.tuple('prefix','outdir')
self.dir = sim.locdir
self.h5file = os.path.join(sim.locdir,outdir,prefix+'.pwscf.h5')
else:
self.infile = arg0
#end if
#end def __init__
def analyze(self, Ef_list=None):
if Ef_list is not None:
self.wfh5 = read_eshdf_eig_data(self.h5file, Ef_list)
#end if
#end def analyze
def get_result(self,result_name):
self.not_implemented()
#end def get_result
#end class Pw2qmcpackAnalyzer
class Pw2qmcpack(Simulation):
input_type = Pw2qmcpackInput
analyzer_type = Pw2qmcpackAnalyzer
generic_identifier = 'pw2qmcpack'
application = 'pw2qmcpack.x'
application_properties = set(['serial'])
application_results = set(['orbitals','gc_occupation'])
def check_result(self,result_name,sim):
calculating_result = False
if result_name=='orbitals':
calculating_result = True
elif result_name=='gc_occupation':
calculating_result = True
#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=='orbitals':
result.h5file = os.path.join(self.locdir,outdir,prefix+'.pwscf.h5')
result.ptcl_xml = os.path.join(self.locdir,outdir,prefix+'.ptcl.xml')
result.wfs_xml = os.path.join(self.locdir,outdir,prefix+'.wfs.xml')
elif result_name=='gc_occupation':
pass # defer to Qmcpack.incorporate_result
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):
implemented = True
if result_name=='orbitals':
if isinstance(sim,Pwscf):
pwin = sim.input.control
p2in = self.input.inputpp
pwprefix = 'pwscf'
p2prefix = 'pwscf'
pwoutdir = './'
p2outdir = './'
if 'prefix' in pwin:
pwprefix = pwin.prefix
#end if
if 'prefix' in p2in:
p2prefix = p2in.prefix
#end if
if 'outdir' in pwin:
pwoutdir = pwin.outdir
#end if
if 'outdir' in p2in:
p2outdir = p2in.outdir
#end if
if pwoutdir.startswith('./'):
pwoutdir = pwoutdir[2:]
#end if
if p2outdir.startswith('./'):
p2outdir = p2outdir[2:]
#end if
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:
implemented = False
#end if
else:
implemented = False
#end if
if not implemented:
self.error('ability to incorporate result "{0}" from {1} has not been implemented'.format(result_name,sim.__class__.__name__))
#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()
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
h5file = os.path.join(self.locdir,outdir,prefix+'.pwscf.h5')
ptcl_xml = os.path.join(self.locdir,outdir,prefix+'.ptcl.xml')
wfs_xml = os.path.join(self.locdir,outdir,prefix+'.wfs.xml')
must_exist = [h5file,ptcl_xml,wfs_xml]
files_exist = True
for file in must_exist:
files_exist = files_exist and os.path.exists(file)
#end for
outfin = True
#outfin = outfin and 'esh5 create' in output
#outfin = outfin and 'Creating electrons' in output
outfin = outfin and 'npw=' in output
outfin = outfin and 'ik=' in output
outfin = outfin or 'JOB DONE' in output
success = files_exist and outfin
#self.finished = success and self.job.finished
# pw2qmcpack has too many variants to assess completion based on log output
# assume (optimistically) that job completion indicates success
self.finished = files_exist 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 Pw2qmcpack
def generate_pw2qmcpack(**kwargs):
sim_args,inp_args = Simulation.separate_inputs(kwargs)
if not 'input' in sim_args:
sim_args.input = generate_pw2qmcpack_input(**inp_args)
#end if
pw2qmcpack = Pw2qmcpack(**sim_args)
return pw2qmcpack
#end def generate_pw2qmcpack
class Convert4qmcInput(SimulationInput):
input_codes = '''
pyscf
qp
gaussian
casino
vsvb
gamess
gamess_ascii
gamess_fmo
gamess_xml
'''.split()
input_order = input_codes + '''
prefix
hdf5
add_cusp
psi_tag
ion_tag
no_jastrow
production
orbitals
multidet
gridtype
first
last
size
ci
read_initial_guess
target_state
natural_orbitals
threshold
opt_det_coeffs
zero_ci
add_3body_J
'''.split()
input_aliases = obj(
pyscf = 'pyscf',
qp = 'QP',
gaussian = 'gaussian',
casino = 'casino',
vsvb = 'VSVB',
gamess = 'gamess',
gamess_ascii = 'gamess',
gamess_fmo = 'gamessFMO',
gamess_xml = 'gamesxml', # not a typo
prefix = 'prefix',
hdf5 = 'hdf5',
add_cusp = 'addCusp',
psi_tag = 'psi_tag',
ion_tag = 'ion_tag',
no_jastrow = 'nojastrow',
production = 'production',
orbitals = 'orbitals',
multidet = 'multidet',
gridtype = 'gridtype',
first = 'first',
last = 'last',
size = 'size',
ci = 'ci',
read_initial_guess = 'readInitialGuess',
target_state = 'TargetState',
natural_orbitals = 'NaturalOrbitals',
threshold = 'threshold',
opt_det_coeffs = 'optDetCoeffs',
zero_ci = 'zeroCi',
add_3body_J = 'add3BodyJ',
)
input_types = obj(
app_name = str, # executable name
pyscf = str, # file path
qp = str, # file path
gaussian = str, # file path
casino = str, # file path
vsvb = str, # file path
gamess = str, # file path
gamess_ascii = str, # file path
gamess_fmo = str, # file path
gamess_xml = str, # file path
prefix = str, # any name
hdf5 = bool,
add_cusp = bool,
psi_tag = str, # wavefunction tag
ion_tag = str, # particeset tag
no_jastrow = bool,
production = bool,
orbitals = str,
multidet = str,
gridtype = str,
first = float,
last = float,
size = int,
ci = str, # file path
read_initial_guess = int,
target_state = int,
natural_orbitals = int,
threshold = float,
opt_det_coeffs = bool,
zero_ci = bool,
add_3body_J = bool,
)
input_defaults = obj(
app_name = 'convert4qmc',
pyscf = None, # input codes
qp = None,
gaussian = None,
casino = None,
vsvb = None,
gamess = None,
gamess_ascii = None,
gamess_fmo = None,
gamess_xml = None,
prefix = None, # general options
hdf5 = False,
add_cusp = False,
psi_tag = None,
ion_tag = None,
no_jastrow = False,
production = False,
orbitals = None,
multidet = None,
gridtype = None,
first = None,
last = None,
size = None,
ci = None, # gamess specific below
read_initial_guess = None,
target_state = None,
natural_orbitals = None,
threshold = None,
opt_det_coeffs = False,
zero_ci = False,
add_3body_J = False,# deprecated
)
def __init__(self,**kwargs):
# check that only allowed keyword inputs are provided
invalid = set(kwargs.keys())-set(self.input_types.keys())
if len(invalid)>0:
self.error('invalid inputs encountered\ninvalid keywords: {0}\nvalid keyword inputs are: {1}'.format(sorted(invalid),sorted(self.input_types.keys())))
#end if
# assign inputs
self.set(**kwargs)
# assign default values
self.set_optional(**self.input_defaults)
# check that all keyword inputs are valid
self.check_valid()
#end def __init__
def check_valid(self,exit=True):
valid = True
# check that all inputs have valid types and assign them
for k,v in self.items():
if v is not None and not isinstance(v,self.input_types[k]):
valid = False
if exit:
self.error('keyword input {0} must be of type {1}\nyou provided a value of type {2}\nplease revise your input and try again'.format(k,self.input_types[k].__name__,v.__class__.__name__))
#end if
break
#end if
#end for
return valid
#end def check_valid
def set_app_name(self,app_name):
self.app_name = app_name
#end def set_app_name
def input_code(self):
input_code = None
for k in self.input_codes:
if k in self and self[k] is not None:
if input_code is not None:
input_code = None
break
else:
input_code = self[k]
#end if
#end if
#end for
return input_code
#end def input_code
def has_input_code(self):
return self.input_code() is not None
#end def has_input_code
def app_command(self):
self.check_valid()
c = self.app_name
for k in self.input_order:
if k in self:
v = self[k]
n = self.input_aliases[k]
if isinstance(v,bool):
if v:
c += ' -{0}'.format(n)
#end if
elif v is not None:
c += ' -{0} {1}'.format(n,str(v))
#end if
#end if
#end for
return c
#end def app_command
def read(self,filepath):
None
#end def read
def write_text(self,filepath=None):
return self.app_command()
#end def write_text
def output_files(self):
prefix = 'sample'
if self.prefix!=None:
prefix = self.prefix
#end if
wfn_file = prefix+'.Gaussian-G2.xml'
ptcl_file = prefix+'.Gaussian-G2.ptcl.xml'
return wfn_file,ptcl_file
#end def output_files
#end class Convert4qmcInput
def generate_convert4qmc_input(**kwargs):
return Convert4qmcInput(**kwargs)
#end def generate_convert4qmc_input
class Convert4qmcAnalyzer(SimulationAnalyzer):
def __init__(self,arg0):
if isinstance(arg0,Simulation):
self.infile = arg0.infile
else:
self.infile = arg0
#end if
#end def __init__
def analyze(self):
None
#end def analyze
#end class Convert4qmcAnalyzer
class Convert4qmc(Simulation):
input_type = Convert4qmcInput
analyzer_type = Convert4qmcAnalyzer
generic_identifier = 'convert4qmc'
application = 'convert4qmc'
application_properties = set(['serial'])
application_results = set(['orbitals','particles','determinantset'])
renew_app_command = True
def __init__(self,*args,**kwargs):
Simulation.__init__(self,*args,**kwargs)
self.input_code = None
#end def __init__
def set_app_name(self,app_name):
self.app_name = app_name
self.input.set_app_name(app_name)
#end def set_app_name
def propagate_identifier(self):
None
#self.input.prefix = self.identifier
#end def propagate_identifier
def get_prefix(self):
input = self.input
prefix = 'sample'
if input.prefix is not None:
prefix = input.prefix
#end if
return prefix
#end def get_prefix
def list_output_files(self):
# try to support both pre and post v3.3.0 convert4qmc
prefix = self.get_prefix()
wfn_file = prefix+'.Gaussian-G2.xml'
ptcl_file = prefix+'.Gaussian-G2.ptcl.xml'
if not os.path.exists(os.path.join(self.locdir,ptcl_file)):
if self.input.no_jastrow:
wfn_file = prefix+'.wfnoj.xml'
else:
wfn_file = prefix+'.wfj.xml'
#end if
ptcl_file = prefix+'.structure.xml'
#end if
return wfn_file,ptcl_file
#end def list_output_files
def check_result(self,result_name,sim):
calculating_result = result_name in self.application_results
return calculating_result
#end def check_result
def get_result(self,result_name,sim):
result = obj()
input = self.input
wfn_file,ptcl_file = self.list_output_files()
if result_name=='orbitals':
result.location = os.path.join(self.locdir,wfn_file)
orbfile = self.get_prefix()+'.orbs.h5'
result.orbfile = os.path.join(self.locdir,orbfile)
elif result_name=='particles':
result.location = os.path.join(self.locdir,ptcl_file)
elif result_name=='determinantset':
result.location = os.path.join(self.locdir,wfn_file)
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):
implemented = True
input = self.input
if isinstance(sim,Gamess):
self.input_code = 'gamess'
if result_name=='orbitals':
orbpath = os.path.relpath(result.location,self.locdir)
if result.scftyp=='mcscf':
input.gamess_ascii = orbpath
input.ci = orbpath
elif result.scftyp=='none': # cisd, etc
input.gamess_ascii = orbpath
input.ci = orbpath
if result.mos>0:
input.read_initial_guess = result.mos
elif result.norbitals>0:
input.read_initial_guess = result.norbitals
#end if
else:
input.gamess_ascii = orbpath
#end if
self.job.app_command = input.app_command()
else:
implemented = False
#end if
elif isinstance(sim,Pyscf):
self.input_code = 'pyscf'
if result_name=='orbitals':
orbpath = os.path.relpath(result.h5_file,self.locdir)
input.orbitals = orbpath
else:
implemented = False
#end if
elif isinstance(sim,QuantumPackage):
self.input_code = 'qp'
if result_name=='orbitals':
orbpath = os.path.relpath(result.outfile,self.locdir)
input.orbitals = orbpath
else:
implemented = False
#end if
else:
implemented = False
#end if
if not implemented:
self.error('ability to incorporate result "{0}" from {1} has not been implemented'.format(result_name,sim.__class__.__name__))
#end if
#end def incorporate_result
def check_sim_status(self):
output = open(os.path.join(self.locdir,self.outfile),'r').read()
#errors = open(os.path.join(self.locdir,self.errfile),'r').read()
# Recent versions of convert4qmc no longer produce the orbs.h5 file.
# Instead, the file produced directly by e.g. Pyscf is used instead.
# Therefore, make a symlink to the previously produced file in
# place of the orbs.h5 file.
orbs = self.input.orbitals
finished = self.job.finished
h5_orbs = orbs is not None and orbs.endswith('.h5')
if finished and h5_orbs:
orbfile = self.get_prefix()+'.orbs.h5'
orbfilepath = os.path.join(self.locdir,orbfile)
h5_orbs_missing = not os.path.exists(orbfilepath)
if h5_orbs_missing:
cwd = os.getcwd()
os.chdir(self.locdir)
os.system('ln -s {} {}'.format(orbs,orbfile))
os.chdir(cwd)
#end if
#end if
success = 'QMCGaussianParserBase::dump' in output
for filename in self.list_output_files():
success &= os.path.exists(os.path.join(self.locdir,filename))
#end for
self.failed = not success
self.finished = 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.input.app_command()
#end def app_command
#end class Convert4qmc
def generate_convert4qmc(**kwargs):
sim_args,inp_args = Simulation.separate_inputs(kwargs)
if 'identifier' in sim_args and not 'prefix' in inp_args:
inp_args.prefix = sim_args.identifier
#end if
if not 'input' in sim_args:
sim_args.input = generate_convert4qmc_input(**inp_args)
#end if
convert4qmc = Convert4qmc(**sim_args)
return convert4qmc
#end def generate_convert4qmc
class Convertpw4qmcInput(SimulationInput):
def __init__(self,data_file=None):
self.data_file=data_file
#end def __init__
def read(self, filepath):
None
#end def read
def write(self, filepath):
None
#end class Convertpw4qmcInput
def generate_convertpw4qmc_input(**kwargs):
return Convertpw4qmcInput(**kwargs)
#end def genreate_convertpw4qmc_input
class Convertpw4qmcAnalyzer(SimulationAnalyzer):
def __init__(self,arg0):
if isinstance(arg0,Simulation):
self.infile = arg0.infile
else:
self.infile = arg0
#end if
#end def __init__
def analyze(self):
None
#end def analyze
#end class Convertpw4qmcAnalyzer
class Convertpw4qmc(Simulation):
input_type = Convertpw4qmcInput
analyzer_type = Convertpw4qmcAnalyzer
generic_identifier = 'convertpw4qmc'
application = 'convertpw4qmc'
application_properties = set(['serial'])
application_results = set(['orbitals'])
renew_app_command = True
def set_app_name(self,app_name):
self.app_name = app_name
#end def set_app_name
def propagate_identifier(self):
None
#end def propagate_identifier
def set_files(self):
# no input file
self.infile = None
if self.outfile is None:
self.outfile = self.identifier + self.outfile_extension
#end if
if self.errfile is None:
self.errfile = self.identifier + self.errfile_extension
#end if
#end def set_files
def check_result(self,result_name,sim):
return result_name=='orbitals'
#end def check_result
def get_result(self,result_name,sim):
result = obj()
input = self.input
if result_name=='orbitals':
wfn_file = 'eshdf.h5'
orbfile = os.path.join(self.locdir,wfn_file)
result.location = orbfile
result.h5file = orbfile
else:
self.error('ability to get result '+result_name+' has not been implemented')
#end if
return result
#end def get_result
def get_output_files(self):
output_files = []
return output_files
#end def get_output_files
def app_command(self):
app_name = self.app_name
data_file = self.input.data_file
command = '{} {}'.format(app_name,data_file)
return command
#end def app_command
def incorporate_result(self,result_name,result,sim):
implemented = True
if result_name=='orbitals':
if isinstance(sim,Pwscf):
pwin = sim.input.control
pwprefix = 'pwscf'
p2prefix = 'pwscf'
pwoutdir = './'
p2outdir = './'
if 'prefix' in pwin:
pwprefix = pwin.prefix
#end if
if 'outdir' in pwin:
pwoutdir = pwin.outdir
#end if
if pwoutdir.startswith('./'):
pwoutdir = pwoutdir[2:]
#end if
pwsdir = os.path.abspath(os.path.join(sim.locdir ,pwoutdir, pwprefix+'.save'))
charge_density_h5 = os.path.join(pwsdir, 'charge-density.hdf5')
data_file_schema = os.path.join(pwsdir, 'data-file-schema.xml')
errors = False
if not os.path.exists(data_file_schema):
self.error('to use orbitals, '+self.generic_identifier+' must have data-file-schema.xml file', exit=False)
errors = True
#end if
if not os.path.exists(charge_density_h5):
self.error('to use orbitals, '+self.generic_identifier+' must have charge-density.h5 file.\nNeed to rebuild QE with hdf5 support', exit=False)
errors = True
#end if
if errors:
self.error(self.generic_identifier+' cannot use orbitals from pwscf')
#end if
if self.input.data_file is None:
self.input.data_file = data_file_schema
else:
implemented = False
#end if
else:
implemented = False
#end if
if not implemented:
self.error('ability to incorporate result "{0}" from {1} has not been implemented'.format(result_name,sim.__class__.__name__))
#end if
#end def incorporate_result
def check_sim_status(self):
h5file = os.path.join(self.locdir,'eshdf.h5')
must_exist = [h5file]
files_exist = True
for file in must_exist:
files_exist = files_exist and os.path.exists(file)
#end for
success = files_exist
self.finished = files_exist and self.job.finished
#end def check_sim_status
#end class Convertpw4qmc
def generate_convertpw4qmc(**kwargs):
sim_args,inp_args = Simulation.separate_inputs(kwargs)
if not 'input' in sim_args:
sim_args.input = generate_convertpw4qmc_input(**inp_args)
#end if
sim = Convertpw4qmc(**sim_args)
return sim
#end def generate_convertpw4qmc
class PyscfToAfqmcInput(SimulationInput):
input_order = '''
help
input
output
wavefunction
qmcpack_input
cholesky_threshold
kpoint
gdf
ao
cas
disable_ham
num_dets
real_ham
verbose
'''.split()
input_flags = obj(
help = 'h',
input = 'i',
output = 'o',
wavefunction = 'w',
qmcpack_input = 'q',
cholesky_threshold = 't',
kpoint = 'k',
gdf = 'g',
ao = 'a',
cas = 'c',
disable_ham = 'd',
num_dets = 'n',
real_ham = 'r',
verbose = 'v',
)
input_types = obj(
app_name = str,
help = bool,
input = str,
output = str,
wavefunction = str,
qmcpack_input = str,
cholesky_threshold = float,
kpoint = bool,
gdf = bool,
ao = bool,
cas = tuple,
disable_ham = bool,
num_dets = int,
real_ham = int,
verbose = bool,
)
input_defaults = obj(
app_name = 'pyscf_to_afqmc.py',
help = False,
input = None,
output = None,
wavefunction = None,
qmcpack_input = None,
cholesky_threshold = None,
kpoint = False,
gdf = False,
ao = False,
cas = None,
disable_ham = False,
num_dets = None,
real_ham = None,
verbose = False,
)
def __init__(self,**kwargs):
# reassign inputs provided via short flag names
for k,v in PyscfToAfqmcInput.input_flags.items():
if v in kwargs:
kwargs[k] = kwargs.pop(v)
#end if
#end for
# check that only allowed keyword inputs are provided
invalid = set(kwargs.keys())-set(self.input_types.keys())
if len(invalid)>0:
self.error('invalid inputs encountered\ninvalid keywords: {0}\nvalid keyword inputs are: {1}'.format(sorted(invalid),sorted(self.input_types.keys())))
#end if
# assign inputs
self.set(**kwargs)
# assign default values
self.set_optional(**self.input_defaults)
# check that all keyword inputs are valid
self.check_valid()
#end def __init__
def check_valid(self,exit=True):
valid = True
# check that all inputs have valid types and assign them
for k,v in self.items():
if v is not None and not isinstance(v,self.input_types[k]):
valid = False
if exit:
self.error('keyword input "{0}" must be of type "{1}"\nyou provided a value of type "{2}"\nplease revise your input and try again'.format(k,self.input_types[k].__name__),v.__class__.__name__)
#end if
break
#end if
#end for
if 'cas' in self and self.cas is not None:
if len(self.cas)!=2:
valid = False
if exit:
self.error('keyword input "cas" must contain only two elements\nnumber of elements provided: {}\nvalue provided: {}'.format(len(self.cas),self.cas))
#end if
#end if
noninteger = False
for v in self.cas:
noninteger |= not isinstance(v,int)
#end for
if noninteger:
valid = False
if exit:
self.error('keyword input "cas" must contain two integers\nvalue provided: {}'.format(self.cas))
#end if
#end if
#end if
return valid
#end def check_valid
def is_valid(self):
return self.check_valid(exit=False)
#end def is_valid
def set_app_name(self,app_name):
self.app_name = app_name
#end def set_app_name
def app_command(self):
self.check_valid()
c = self.app_name
for k in self.input_order:
if k in self:
v = self[k]
n = self.input_flags[k]
if isinstance(v,bool):
if v:
c += ' -{0}'.format(n)
#end if
elif isinstance(v,tuple):
vs = ''
for tv in v:
vs += '{},'.format(tv)
#end for
c += ' -{0} {1}'.format(n,vs[:-1])
elif v is not None:
c += ' -{0} {1}'.format(n,str(v))
#end if
#end if
#end for
return c
#end def app_command
def read(self,filepath):
None
#end def read
def write_text(self,filepath=None):
return self.app_command()
#end def write_text
#end class PyscfToAfqmcInput
def generate_pyscf_to_afqmc_input(**kwargs):
return PyscfToAfqmcInput(**kwargs)
#end def generate_pyscf_to_afqmc_input
class PyscfToAfqmcAnalyzer(SimulationAnalyzer):
def __init__(self,arg0):
if isinstance(arg0,Simulation):
self.infile = arg0.infile
else:
self.infile = arg0
#end if
#end def __init__
def analyze(self):
None
#end def analyze
#end class PyscfToAfqmcAnalyzer
class PyscfToAfqmc(Simulation):
input_type = PyscfToAfqmcInput
analyzer_type = PyscfToAfqmcAnalyzer
generic_identifier = 'pyscf2afqmc'
application = 'pyscf_to_afqmc.py'
application_properties = set(['serial'])
application_results = set(['wavefunction','hamiltonian'])
renew_app_command = True
def set_app_name(self,app_name):
self.app_name = app_name
self.input.set_app_name(app_name)
#end def set_app_name
def check_result(self,result_name,sim):
calculating_result = False
if result_name=='wavefunction':
calculating_result = self.input.output is not None
elif result_name=='hamiltonian':
calculating_result = self.input.output is not None
#end if
return calculating_result
#end def check_result
def get_result(self,result_name,sim):
result = obj()
input = self.input
if result_name in ('wavefunction','hamiltonian'):
result.h5_file = os.path.join(self.locdir,input.output)
if input.qmcpack_input is not None:
result.xml = os.path.join(self.locdir,input.qmcpack_input)
#end if
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):
implemented = True
input = self.input
if isinstance(sim,Pyscf):
if result_name=='wavefunction':
chkfile = os.path.relpath(result.chkfile,self.locdir)
input.input = chkfile
else:
implemented = False
#end if
else:
implemented = False
#end if
if not implemented:
self.error('ability to incorporate result "{0}" from {1} has not been implemented'.format(result_name,sim.__class__.__name__))
#end if
#end def incorporate_result
def check_sim_status(self):
output = open(os.path.join(self.locdir,self.outfile),'r').read()
success = '# Finished.' in output
success &= os.path.exists(os.path.join(self.locdir,self.input.output))
self.failed = not success
self.finished = 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.input.app_command()
#end def app_command
#end class PyscfToAfqmc
def generate_pyscf_to_afqmc(**kwargs):
sim_args,inp_args = Simulation.separate_inputs(kwargs)
if 'identifier' in sim_args:
if 'output' not in inp_args:
inp_args.output = '{}.afqmc.h5'.format(sim_args.identifier)
#end if
if 'qmcpack_input' not in inp_args:
inp_args.qmcpack_input = '{}.afqmc.xml'.format(sim_args.identifier)
#end if
#end if
if not 'input' in sim_args:
sim_args.input = generate_pyscf_to_afqmc_input(**inp_args)
#end if
sim = PyscfToAfqmc(**sim_args)
return sim
#end def generate_pyscf_to_afqmc