mirror of https://github.com/QMCPACK/qmcpack.git
Merge pull request #262 from jtkrogel/dev
nexus: better guard for structure file and internal consistency
This commit is contained in:
commit
ef1451cac5
|
@ -154,13 +154,11 @@ def morse_reduced_mass(m1,m2=None):
|
|||
m1 = ptable[m1].atomic_weight.me
|
||||
#end if
|
||||
if m2 is None:
|
||||
m = m1
|
||||
else:
|
||||
if isinstance(m2,str):
|
||||
m2 = ptable[m2].atomic_weight.me
|
||||
#end if
|
||||
m = 1./(1./m1+1./m2) # reduced mass
|
||||
m2 = m1
|
||||
elif isinstance(m2,str):
|
||||
m2 = ptable[m2].atomic_weight.me
|
||||
#end if
|
||||
m = 1./(1./m1+1./m2) # reduced mass
|
||||
return m
|
||||
#end def morse_reduced_mass
|
||||
|
||||
|
|
|
@ -396,18 +396,50 @@ class PhysicalSystem(Matter):
|
|||
#end def pseudize
|
||||
|
||||
|
||||
def check_folded_system(self):
|
||||
def check_folded_system(self,exit=True,message=False):
|
||||
msg = ''
|
||||
sys_folded = self.folded_system!=None
|
||||
struct_folded = self.structure.folded_structure!=None
|
||||
if sys_folded!=struct_folded:
|
||||
self.error('folding of physical system and structure is not consistent\n system folded: {0}\n structure folded: {1}'.format(sys_folded,struct_folded))
|
||||
msg+='folding of physical system and structure is not consistent\nsystem folded: {0}\nstructure folded: {1}\n'.format(sys_folded,struct_folded)
|
||||
#end if
|
||||
if sys_folded and id(self.structure.folded_structure)!=id(self.folded_system.structure):
|
||||
self.error('structure of folded system and folded structure are distinct\n this is not allowed and may be a developer error')
|
||||
msg+='structure of folded system and folded structure are distinct\nthis is not allowed and may be a developer error'
|
||||
#end if
|
||||
success = len(msg)==0
|
||||
if not success and exit:
|
||||
self.error(msg)
|
||||
#end if
|
||||
if not message:
|
||||
return success
|
||||
else:
|
||||
return success,msg
|
||||
#end if
|
||||
#end def check_folded_system
|
||||
|
||||
|
||||
def check_consistent(self,tol=1e-8,exit=True,message=False):
|
||||
fs,fm = self.check_folded_system(exit=False,message=True)
|
||||
cs,cm = self.structure.check_consistent(tol,exit=False,message=True)
|
||||
msg = ''
|
||||
if not fs:
|
||||
msg += fm+'\n'
|
||||
#end if
|
||||
if not cs:
|
||||
msg += cm+'\n'
|
||||
#end if
|
||||
consistent = len(msg)==0
|
||||
if not consistent and exit:
|
||||
self.error(msg)
|
||||
#end if
|
||||
if not message:
|
||||
return consistent
|
||||
else:
|
||||
return consistent,msg
|
||||
#end if
|
||||
#end def check_consistent
|
||||
|
||||
|
||||
def change_units(self,units):
|
||||
self.structure.change_units(units,folded=False)
|
||||
if self.folded_system!=None:
|
||||
|
@ -623,14 +655,27 @@ def generate_physical_system(**kwargs):
|
|||
if 'structure' in kwargs:
|
||||
s = kwargs['structure']
|
||||
is_str = isinstance(s,str)
|
||||
if is_str and os.path.exists(s):# and '.' in os.path.split(s)[1]:
|
||||
if 'elem' in kwargs:
|
||||
kwargs['structure'] = read_structure(s,elem=kwargs['elem'])
|
||||
if is_str:
|
||||
if os.path.exists(s):
|
||||
if 'elem' in kwargs:
|
||||
kwargs['structure'] = read_structure(s,elem=kwargs['elem'])
|
||||
else:
|
||||
kwargs['structure'] = read_structure(s)
|
||||
#end if
|
||||
else:
|
||||
kwargs['structure'] = read_structure(s)
|
||||
slow = s.lower()
|
||||
format = None
|
||||
if '.' in slow:
|
||||
format = slow.rsplit('.')[1]
|
||||
elif 'poscar' in slow:
|
||||
format = 'poscar'
|
||||
#end if
|
||||
is_path = '/' in s
|
||||
is_file = format in set('xyz xsf poscar cif fhi-aims'.split())
|
||||
if is_path or is_file:
|
||||
PhysicalSystem.class_error('user provided structure file does not exist\nstructure file path: '+s,'generate_physical_system')
|
||||
#end if
|
||||
#end if
|
||||
elif is_str and '/' in s:
|
||||
PhysicalSystem.class_error('path provided for structure file does not exist: '+s,'generate_physical_system')
|
||||
#end if
|
||||
#end if
|
||||
|
||||
|
|
|
@ -29,6 +29,57 @@ from execute import execute
|
|||
from debug import ci
|
||||
|
||||
|
||||
unique_vdw_functionals = [
|
||||
'optb86b-vdw',
|
||||
'vdw-df3', # optB88+vdW
|
||||
'vdw-df',
|
||||
'vdw-df2',
|
||||
'rev-vdw-df2',
|
||||
'vdw-df-c09',
|
||||
'vdw-df2-c09',
|
||||
'rvv10',
|
||||
]
|
||||
repeat_vdw_functionals = [
|
||||
'vdw-df4', # 'optB86b-vdW'
|
||||
]
|
||||
unique_functionals = [
|
||||
'revpbe',
|
||||
'pw86pbe',
|
||||
'b86bpbe',
|
||||
'pbe0',
|
||||
'hse',
|
||||
'gaup',
|
||||
'pbesol',
|
||||
'pbeq2d',
|
||||
'optbk88',
|
||||
'optb86b',
|
||||
'pbe',
|
||||
'wc',
|
||||
'b3lyp',
|
||||
'pbc',
|
||||
'bp',
|
||||
'pw91',
|
||||
'hcth',
|
||||
'olyp',
|
||||
'tpss',
|
||||
'oep',
|
||||
'hf',
|
||||
'blyp',
|
||||
'lda',
|
||||
'sogga',
|
||||
'm06l',
|
||||
'ev93',
|
||||
]+unique_vdw_functionals
|
||||
repeat_functionals = [
|
||||
'q2d', # pbeq2d
|
||||
'pz', # lda
|
||||
]+repeat_vdw_functionals
|
||||
|
||||
vdw_functionals = set(unique_vdw_functionals+repeat_vdw_functionals)
|
||||
allowed_functionals = set(unique_functionals+repeat_functionals)
|
||||
|
||||
|
||||
|
||||
class Pwscf(Simulation):
|
||||
input_type = PwscfInput
|
||||
analyzer_type = PwscfAnalyzer
|
||||
|
@ -41,11 +92,11 @@ class Pwscf(Simulation):
|
|||
|
||||
vdw_table = None
|
||||
|
||||
@staticmethod
|
||||
def settings(vdw_table=None):
|
||||
# van der Waals family of functional require the vdW table generated by
|
||||
# generate_vdW_kernel_table.x: specify 'vdw_table' in settings
|
||||
Pwscf.vdw_table = vdw_table
|
||||
@staticmethod
|
||||
def settings(vdw_table=None):
|
||||
# van der Waals family of functional require the vdW table generated by
|
||||
# generate_vdW_kernel_table.x: specify 'vdw_table' in settings
|
||||
Pwscf.vdw_table = vdw_table
|
||||
#end def settings
|
||||
|
||||
#def propagate_identifier(self):
|
||||
|
@ -75,16 +126,20 @@ class Pwscf(Simulation):
|
|||
if not os.path.exists(outdir):
|
||||
os.makedirs(outdir)
|
||||
#end if
|
||||
#copy over vdw_table for vdW-DF functional
|
||||
#copy over vdw_table for vdW-DF functional
|
||||
if self.path_exists('input/system/input_dft'):
|
||||
if self.input.system.input_dft.lower().startswith('vdw-df'):
|
||||
functional = self.input.system.input_dft.lower()
|
||||
if '+' not in functional and functional not in allowed_functionals:
|
||||
self.warn('functional "{0}" is unknown to pwscf'.format(functional))
|
||||
#end if
|
||||
if functional in vdw_functionals:
|
||||
if self.vdw_table is None:
|
||||
self.error('attempting to run vdW-DF functional, but vdw_table is missing\nplease provide path to table file via "vdw_table" parameter in settings')
|
||||
self.error('attempting to run vdW functional "{0}", but vdw_table is missing\nplease provide path to table file via "vdw_table" parameter in settings'.format(functional))
|
||||
#end if
|
||||
cd_rel = os.path.relpath(self.vdw_table,self.locdir)
|
||||
# copy instead of link to vdw_table to avoid file-lock from multiple pw.x instances
|
||||
cp_cmd = 'cd '+self.locdir+';cp '+cd_rel+' .'
|
||||
os.system(cp_cmd)
|
||||
cd_rel = os.path.relpath(self.vdw_table,self.locdir)
|
||||
# copy instead of link to vdw_table to avoid file-lock from multiple pw.x instances
|
||||
cp_cmd = 'cd '+self.locdir+';cp '+cd_rel+' .'
|
||||
os.system(cp_cmd)
|
||||
#end if
|
||||
#end if
|
||||
#end def write_prep
|
||||
|
|
|
@ -474,6 +474,11 @@ class Simulation(NexusCore):
|
|||
#end if
|
||||
if isinstance(self.system,PhysicalSystem):
|
||||
self.system = self.system.copy()
|
||||
consistent,msg = self.system.check_consistent(exit=False,message=True)
|
||||
if not consistent:
|
||||
locdir = os.path.join(nexus_core.local_directory,nexus_core.runs,self.path)
|
||||
self.error('user provided physical system is not internally consistent\nsimulation identifier: {0}\nlocal directory: {1}\nmore details on the user error are given below\n\n{2}'.format(self.identifier,locdir,msg))
|
||||
#end if
|
||||
elif self.system!=None:
|
||||
self.error('system must be a PhysicalSystem object\nyou provided an object of type: {0}'.format(self.system.__class__.__name__))
|
||||
#end if
|
||||
|
|
|
@ -766,6 +766,26 @@ class Structure(Sobj):
|
|||
#end def __init__
|
||||
|
||||
|
||||
def check_consistent(self,tol=1e-8,exit=True,message=False):
|
||||
msg = ''
|
||||
if self.has_axes():
|
||||
kaxes = 2*pi*inv(self.axes).T
|
||||
abs_diff = abs(self.kaxes-kaxes).sum()
|
||||
if abs_diff>tol:
|
||||
msg += 'direct and reciprocal space axes are not consistent\naxes present:\n{0}\nkaxes present:\n{1}\nconsistent kaxes:\n{2}\nabsolute difference: {3}\n'.format(self.axes,self.kaxes,kaxes,abs_diff)
|
||||
#end if
|
||||
#end if
|
||||
consistent = len(msg)==0
|
||||
if not consistent and exit:
|
||||
self.error(msg)
|
||||
#end if
|
||||
if not message:
|
||||
return consistent
|
||||
else:
|
||||
return consistent,msg
|
||||
#end if
|
||||
#end def check_consistent
|
||||
|
||||
|
||||
def set_axes(self,axes):
|
||||
self.reset_axes(axes)
|
||||
|
@ -3181,8 +3201,11 @@ class Structure(Sobj):
|
|||
#end def add_kmesh
|
||||
|
||||
|
||||
def kpoints_unit(self):
|
||||
return dot(self.kpoints,inv(self.kaxes))
|
||||
def kpoints_unit(self,kpoints=None):
|
||||
if kpoints is None:
|
||||
kpoints = self.kpoints
|
||||
#end if
|
||||
return dot(kpoints,inv(self.kaxes))
|
||||
#end def kpoints_unit
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue