From 3751252aa244120cae1c07af65d89bac2c7ad4e8 Mon Sep 17 00:00:00 2001 From: Jaron Krogel Date: Thu, 4 Dec 2014 14:13:43 +0000 Subject: [PATCH] gamess update for mcscf workflows git-svn-id: https://subversion.assembla.com/svn/qmcdev/trunk@6410 e5b18d87-469d-4833-9cc0-8cdfa06e9491 --- nexus/library/convert4qmc.py | 11 +- nexus/library/gamess.py | 14 ++- nexus/library/gamess_input.py | 33 ++++- nexus/library/qmcpack.py | 5 +- nexus/library/qmcpack_input.py | 223 ++++++++++++++++++++++++++++----- 5 files changed, 240 insertions(+), 46 deletions(-) diff --git a/nexus/library/convert4qmc.py b/nexus/library/convert4qmc.py index 9fa703837..45269a9d7 100644 --- a/nexus/library/convert4qmc.py +++ b/nexus/library/convert4qmc.py @@ -146,7 +146,13 @@ class Convert4qmc(Simulation): def incorporate_result(self,result_name,result,sim): if result_name=='orbitals': - self.input.gamess_ascii = os.path.relpath(result.location,self.locdir) + orbpath = os.path.relpath(result.location,self.locdir) + if result.scftyp=='mcscf': + self.input.gamess_ascii = orbpath + self.input.ci = orbpath + else: + self.input.gamess_ascii = orbpath + #end if self.job.app_command = self.input.app_command() else: self.error('ability to incorporate result '+result_name+' has not been implemented') @@ -184,6 +190,9 @@ class Convert4qmc(Simulation): 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) diff --git a/nexus/library/gamess.py b/nexus/library/gamess.py index 9d6baa709..40269cc5e 100644 --- a/nexus/library/gamess.py +++ b/nexus/library/gamess.py @@ -50,7 +50,7 @@ class Gamess(Simulation): def check_result(self,result_name,sim): input = self.input if result_name=='orbitals': - calculating_result = 'contrl' in input and 'scftyp' in input.contrl and input.contrl.scftyp in ('rhf','rohf','uhf') + calculating_result = 'contrl' in input and 'scftyp' in input.contrl and input.contrl.scftyp.lower() in ('rhf','rohf','uhf','mcscf') else: calculating_result = False #end if @@ -60,14 +60,16 @@ class Gamess(Simulation): def get_result(self,result_name,sim): result = obj() + input = self.input analyzer = self.load_analyzer_image() if result_name=='orbitals': - result.location = os.path.join(self.locdir,self.outfile) - result.vec = None + result.location = os.path.join(self.locdir,self.outfile) + result.vec = None result.norbitals = 0 + result.scftyp = input.contrl.scftyp.lower() if 'punch' in analyzer and 'vec' in analyzer.punch: result.norbitals = analyzer.punch.norbitals - result.vec = analyzer.punch.vec + result.vec = analyzer.punch.vec #end if else: self.error('ability to get result '+result_name+' has not been implemented') @@ -85,9 +87,11 @@ class Gamess(Simulation): if not 'guess' in input: input.guess = GuessGroup() #end if + input.guess.clear() input.guess.set( guess = 'moread', - norb = result.norbitals + norb = result.norbitals, + prtmo = True ) input.vec = FormattedGroup(result.vec) else: diff --git a/nexus/library/gamess_input.py b/nexus/library/gamess_input.py index 69890c104..49b945a1e 100644 --- a/nexus/library/gamess_input.py +++ b/nexus/library/gamess_input.py @@ -605,6 +605,31 @@ class CidrtGroup(KeywordSpecGroup): nprt = set([0,1,2,3]), ) #end class CidrtGroup + + + +class DetGroup(KeywordSpecGroup): + keywords = set([ + 'ncore' ,'nact' ,'nels' ,'sz' ,'group' ,'stsym' ,'irreps', + 'nstate','prttol','analys','itermx','cvgtol','nhgss' ,'nstgss', + 'mxxpan','clobbr','pures' ,'iroot' ,'nflgdm','saflg' ,'wstate', + 'idwref','dwparm' + ]) + + integers = set(['ncore','nact','nels','nstate','itermx','nhgss','nstgss', + 'mxxpan','iroot','idwref']) + reals = set(['sz','prttol','cvgtol','dwparm']) + bools = set(['analys','clobbr','pures','saflg']) + strings = set(['group','stsym']) + arrays = set(['irreps','nflgdm','wstate']) + + allowed_values = obj( + group = set(['c1','c2','ci','cs','c2v','c2h','d2','d2h','c4v','d4','d4h']), + stsym = set(['a','ag','au','ap','app','a','b','a1','a2','b1','b2','ag', + 'bu','bg','au','a','b1','b2','b3','ag','b1g','b2g','b3g', + 'au','b1u','b2u','b3u']), + ) +#end class DetGroup @@ -655,7 +680,7 @@ class GamessInput(SimulationInput,GIbase): all_groups = set(group_order) key_groups = set(['contrl','system','guess','scf','mcscf','dft', - 'gugdia','drt','cidrt']) + 'gugdia','drt','cidrt','det']) card_groups = set() #card_groups = set(['ecp','data','mcp','gcilst','points','stone','efrag', @@ -674,7 +699,8 @@ class GamessInput(SimulationInput,GIbase): dft = DftGroup, gugdia = GugdiaGroup, drt = DrtGroup, - cidrt = CidrtGroup + cidrt = CidrtGroup, + det = DetGroup ) keyspec_group_order = [] for gname in group_order: @@ -951,7 +977,6 @@ def generate_any_gamess_input(**kwargs): invalid_names = kwset-GamessInput.all_name_aliases if len(invalid_names)>0: - obj.class_error('this\nthat\nother') GamessInput.class_error('invalid group names or keywords encountered\n invalid names/keywords provided: {0}\n please check if these group names or keywords are actually valid GAMESS inputs\n if so, unsupported groups can be generated by providing the keywords as a single argument:\n generate_gamess_input(\n ...,\n group_name = obj(assign keywords),\n ...,\n )'.format(sorted(invalid_names)),'generate_gamess_input') #end if @@ -1016,7 +1041,7 @@ def generate_any_gamess_input(**kwargs): # handle nexus specific input generation keywords # ecp 287 # data 37 - if pskw.system!=None: + if pskw.system!=None and not 'data' in gi: system = pskw.system if not 'contrl' in gi: gi.contrl = ContrlGroup() diff --git a/nexus/library/qmcpack.py b/nexus/library/qmcpack.py index fc0093b5f..d4ed47744 100644 --- a/nexus/library/qmcpack.py +++ b/nexus/library/qmcpack.py @@ -206,10 +206,9 @@ class Qmcpack(Simulation): elif isinstance(sim,Convert4qmc): res = QmcpackInput(result.location) - wfn = res.qmcsystem.wavefunction - qs = input.simulation.qmcsystem + qs = input.simulation.qmcsystem oldwfn = qs.wavefunction - newwfn = wfn.copy() + newwfn = res.qmcsystem.wavefunction if 'jastrows' in newwfn: del newwfn.jastrows #end if diff --git a/nexus/library/qmcpack_input.py b/nexus/library/qmcpack_input.py index ecd5b09ab..ac7301ed3 100644 --- a/nexus/library/qmcpack_input.py +++ b/nexus/library/qmcpack_input.py @@ -140,36 +140,41 @@ class collection(hidden): #self.add(value) #end def __setitem__ - def add(self,element,strict=True): - identifier = element.identifier - public = self.public() - missing_identifier = False - if not element.tag in plurals_inv and element.collection_id is None: - self.error('collection cannot be formed\n encountered non-plural element\n element class: {0}\n element tag: {1}\n tags allowed in a collection: {2}'.format(element.__class__.__name__,element.tag,sorted(plurals_inv.keys()))) - elif identifier is None: - key = len(public) - elif isinstance(identifier,str): - if identifier in element: - key = element[identifier] - else: - missing_identifier = True - #end if - else: - key = '' - for ident in identifier: - if ident in element: - key+=element[ident] + def add(self,element,strict=True,key=None): + if key is None: + identifier = element.identifier + public = self.public() + missing_identifier = False + if not element.tag in plurals_inv and element.collection_id is None: + self.error('collection cannot be formed\n encountered non-plural element\n element class: {0}\n element tag: {1}\n tags allowed in a collection: {2}'.format(element.__class__.__name__,element.tag,sorted(plurals_inv.keys()))) + elif identifier is None: + key = len(public) + elif isinstance(identifier,str): + if identifier in element: + key = element[identifier] + else: + missing_identifier = True #end if - #end for - missing_identifier = key=='' + else: + key = '' + for ident in identifier: + if ident in element: + key+=element[ident] + #end if + #end for + missing_identifier = key=='' + #end if + if missing_identifier: + key = len(public) + #if strict: + # self.error('collection cannot be formed\n element is missing an identifier\n element class: {0}\n element tag: {1}\n identifier looked for: {2}\n element contents:\n{3}'.format(element.__class__.__name__,element.tag,identifier,str(element))) + #else: + # return False + ##end if + #end if #end if - if missing_identifier: - key = len(public) - #if strict: - # self.error('collection cannot be formed\n element is missing an identifier\n element class: {0}\n element tag: {1}\n identifier looked for: {2}\n element contents:\n{3}'.format(element.__class__.__name__,element.tag,identifier,str(element))) - #else: - # return False - ##end if + if key in public: + self.error('attempted to add duplicate key to collection: {0}\n keys present: {1}'.format(key,sorted(public.keys()))) #end if public[key] = element self.hidden().order.append(key) @@ -196,6 +201,14 @@ class collection(hidden): #end for return lst #end def list + + def pairlist(self): + pairs = [] + for key in self.hidden().order: + pairs.append((key,self[key])) + #end for + return pairs + #end def pairlist #end class collection @@ -1359,7 +1372,7 @@ param = Param() class simulation(QIxml): - elements = ['project','random','qmcsystem','particleset','wavefunction','hamiltonian','init','traces','qmc','loop'] + elements = ['project','random','include','qmcsystem','particleset','wavefunction','hamiltonian','init','traces','qmc','loop'] write_types = obj(random=yesno) #end class simulation @@ -1373,12 +1386,15 @@ class application(QIxml): attributes = ['name','role','class','version'] #end class application - class random(QIxml): attributes = ['seed','parallel'] write_types= obj(parallel=truefalse) #end class random +class include(QIxml): + attributes = ['href'] +#end def include + class qmcsystem(QIxml): elements = ['simulationcell','particleset','wavefunction','hamiltonian'] @@ -1729,7 +1745,7 @@ class traces(QIxml): write_types = obj(write_=yesno,verbose=yesno,scalar=yesno,array=yesno, scalar_defaults=yesno,array_defaults=yesno, particle=yesno,particle_defaults=yesno) -#end class +#end class traces class loop(QIxml): @@ -1822,7 +1838,7 @@ classes = [ #standard classes atomicbasisset,basisgroup,init,var,traces,scalar_traces,particle_traces,array_traces, reference_points,nearestneighbors,neighbor_trace,dm1b, coefficient,radfunc,spindensity,structurefactor, - sposet,bspline_builder,composite_builder,heg_builder + sposet,bspline_builder,composite_builder,heg_builder,include ] types = dict( #simple types and factories host = param, @@ -1854,7 +1870,8 @@ plurals = obj( neighbor_traces = 'neighbor_trace', sposet_builders = 'sposet_builder', sposets = 'sposet', - radfuncs = 'radfunc' + radfuncs = 'radfunc', + qmcsystems = 'qmcsystem' ) plurals_inv = plurals.inverse() plural_names = set(plurals.keys()) @@ -2400,6 +2417,146 @@ class QmcpackInput(SimulationInput,Names): Param.metadata = None #end def include_xml + # This include functionality is currently not being used + # The rationale is essentially this: + # -Having includes explicitly represented in the input file object + # makes it very difficult to search for various components + # i.e. where is the particleset? the wavefunction? a particular determinant? + # -Difficulty in locating components makes it difficult to modify them + # -Includes necessarily introduce greater variability in input file structure + # and it is difficult to ensure every possible form is preserved each and + # every time a modification is made + # -The only time it is undesirable to incorporate the contents of an + # include directly into the input file object is if the data is large + # e.g. for an xml wavefunction or pseudopotential. + # In these cases, an external file should be provided that contains + # only the large object in question (pseudo or wavefunction). + # This is already done for pseudopotentials and should be done for + # wavefunctions, e.g. multideterminants. + # Until that time, wavefunctions will be explicitly read into the full + # input file. + def add_include(self,element_type,href,placement='on'): + # check the element type + elems = ['cell','ptcl','wfs','ham'] + emap = obj( + simulationcell = 'cell', + particleset = 'ptcl', + wavefunction = 'wfs', + hamiltonian = 'ham' + ) + if not element_type in elems: + self.error('cannot add include for element of type {0}\n valid element types are {1}'.format(element_type,elems)) + #end if + # check the requested placement + placements = ('before','on','after') + if not placement in placements: + self.error('cannot add include for element with placement {0}\n valid placements are {1}'.format(placement,list(placements))) + #end if + # check that the base element is a simulation + base = self.get_base() + if not isinstance(base,simulation): + self.error('an include can only be added to simulation\n attempted to add to {0}'.format(base.__class__.__name__)) + #end if + # gather a list of current qmcsystems + if 'qmcsystem' in base: + qslist = [(0,base.qmcsystem)] + del base.qmcsystem + elif 'qmcsystems' in base: + qslist = base.qmcsystems.pairlist() + del base.qmcsystems + else: + qslist = [] + #end if + # organize the elements of the qmcsystems + cur_elems = obj() + for elem in elems: + for place in placements: + cur_elems[elem,place] = None + #end for + #end for + for qskey,qs in qslist: + if isinstance(qs,include): + inc = qs + ekey = qskey.split('_')[1] + if not ekey in elems: + self.error('encountered invalid element key: {0}\n valid keys are: {1}'.format(ekey,elems)) + #end if + if cur_elems[ekey,'on'] is None: + cur_elems[ekey,'before'] = ekey,inc + else: + cur_elems[ekey,'after' ] = ekey,inc + #end if + elif not isinstance(qs,qmcsystem): + self.error('expected qmcsystem element, got {0}'.format(qs.__class__.__name__)) + else: + for elem in qmcsystem.elements: + elem_plural = elem+'s' + name = None + if elem in qs: + name = elem + elif elem_plural in qs: + name = elem_plural + #end if + if name!=None: + cur_elems[emap[elem],'on'] = name,qs[name] + del qs[name] + #end if + #end for + residue = qs.keys() + if len(residue)>0: + self.error('extra keys found in qmcsystem: {0}'.format(sorted(residue))) + #end if + #end if + #end for + for elem in elems: + pbef = cur_elems[elem,'before'] + pon = cur_elems[elem,'on' ] + paft = cur_elems[elem,'after' ] + if pon is None: + if not pbef is None and paft is None: + cur_elems[elem,'on' ] = pbef + cur_elems[elem,'before'] = None + elif not paft is None and pbef is None: + cur_elems[elem,'on' ] = paft + cur_elems[elem,'after' ] = None + #end if + #end if + #end for + # insert the new include + inc_name = 'include_'+element_type + inc_value = include(href=href) + cur_elems[element_type,placement] = inc_name,inc_value + # create a collection of qmcsystems + qmcsystems = collection() + qskey = '' + qs = qmcsystem() + for elem in elems: + for place in placements: + cur_elem = cur_elems[elem,place] + if cur_elem!=None: + name,value = cur_elem + if isinstance(value,include): + if len(qskey)>0: + qmcsystems.add(qs,key=qskey) + qskey = '' + qs = qmcsystem() + #end if + qmcsystems.add(value,key=name) + else: + qskey += elem[0] + qs[name] = value + #end if + #end if + #end for + #end for + if len(qskey)>0: + qmcsystems.add(qs,key=qskey) + #end if + # attach the collection to the input file + base.qmcsystems = qmcsystems + #end def add_include + + def get_output_info(self,*requests): project = self.simulation.project prefix = project.id