def load_data_local(self): info = self.info if info.load_jastrow: self.load_jastrow_data() elif 'filepath' in info: qxml = QmcpackInput(info.filepath) wavefunction = qxml.get('wavefunction') wavefunction = wavefunction.get_single('psi0') self.info.wfn_xml = wavefunction #end if if not info.load_jastrow: self.info.wfn_xml.pluralize()
def load_data_local(self): info = self.info if info.load_jastrow: self.load_jastrow_data() elif 'filepath' in info: try: qxml = QmcpackInput(info.filepath) wavefunction = qxml.get('wavefunction') wavefunction = wavefunction.get_single('psi0') info.wfn_xml = wavefunction except: info.wfn_xml = None info.fail = True #end try #end if if not info.load_jastrow and not info.fail: info.wfn_xml.pluralize()
def incorporate_result(self,result_name,result,sim): input = self.input system = self.system if result_name=='orbitals': if isinstance(sim,Pw2qmcpack) or isinstance(sim,Wfconvert): h5file = result.h5file wavefunction = input.get('wavefunction') if isinstance(wavefunction,collection): wavefunction = wavefunction.get_single('psi0') #end if wf = wavefunction if 'sposet_builder' in wf and wf.sposet_builder.type=='bspline': orb_elem = wf.sposet_builder elif 'sposet_builders' in wf and 'bspline' in wf.sposet_builders: orb_elem = wf.sposet_builders.bspline elif 'sposet_builders' in wf and 'einspline' in wf.sposet_builders: orb_elem = wf.sposet_builders.einspline elif 'determinantset' in wf and wf.determinantset.type in ('bspline','einspline'): orb_elem = wf.determinantset else: self.error('could not incorporate pw2qmcpack/wfconvert orbitals\nbspline sposet_builder and determinantset are both missing') #end if if 'href' in orb_elem and isinstance(orb_elem.href,str) and os.path.exists(orb_elem.href): # user specified h5 file for orbitals, bypass orbital dependency orb_elem.href = os.path.relpath(orb_elem.href,self.locdir) else: orb_elem.href = os.path.relpath(h5file,self.locdir) if system.structure.folded_structure!=None: orb_elem.tilematrix = array(system.structure.tmatrix) #end if #end if defs = obj( #twistnum = 0, meshfactor = 1.0 ) for var,val in defs.iteritems(): if not var in orb_elem: orb_elem[var] = val #end if #end for has_twist = 'twist' in orb_elem has_twistnum = 'twistnum' in orb_elem if not has_twist and not has_twistnum: orb_elem.twistnum = 0 #end if system = self.system structure = system.structure nkpoints = len(structure.kpoints) if nkpoints==0: self.error('system must have kpoints to assign twistnums') #end if if not os.path.exists(h5file): self.error('wavefunction file not found: \n'+h5file) #end if twistnums = range(len(structure.kpoints)) if self.should_twist_average: self.twist_average(twistnums) elif not has_twist and orb_elem.twistnum is None: orb_elem.twistnum = twistnums[0] #end if elif isinstance(sim,Sqd): h5file = os.path.join(result.dir,result.h5file) h5file = os.path.relpath(h5file,self.locdir) sqdxml_loc = os.path.join(result.dir,result.qmcfile) sqdxml = QmcpackInput(sqdxml_loc) #sqd sometimes puts the wrong ionic charge # rather than setting Z to the number of electrons # set it to the actual atomic number g = sqdxml.qmcsystem.particlesets.atom.group elem = g.name if not elem in periodic_table.elements: self.error(elem+' is not an element in the periodic table') #end if g.charge = periodic_table.elements[elem].atomic_number input = self.input s = input.simulation qsys_old = s.qmcsystem del s.qmcsystem s.qmcsystem = sqdxml.qmcsystem if 'jastrows' in qsys_old.wavefunction: s.qmcsystem.wavefunction.jastrows = qsys_old.wavefunction.jastrows for jastrow in s.qmcsystem.wavefunction.jastrows: if 'type' in jastrow: jtype = jastrow.type.lower().replace('-','_') if jtype=='one_body': jastrow.source = 'atom' #end if #end if #end for #end if s.qmcsystem.hamiltonian = hamiltonian( name='h0',type='generic',target='e', pairpots = [ pairpot(name='ElecElec',type='coulomb',source='e',target='e'), pairpot(name='Coulomb' ,type='coulomb',source='atom',target='e'), ] ) s.init = init(source='atom',target='e') abset = input.get('atomicbasisset') abset.href = h5file elif isinstance(sim,Convert4qmc): res = QmcpackInput(result.location) qs = input.simulation.qmcsystem oldwfn = qs.wavefunction newwfn = res.qmcsystem.wavefunction dset = newwfn.determinantset if 'jastrows' in newwfn: del newwfn.jastrows #end if if 'jastrows' in oldwfn: newwfn.jastrows = oldwfn.jastrows #end if if input.cusp_correction(): dset.cuspcorrection = True #end if if 'orbfile' in result: orb_h5file = result.orbfile if not os.path.exists(orb_h5file) and 'href' in dset: orb_h5file = os.path.join(sim.locdir,dset.href) #end if if not os.path.exists(orb_h5file): self.error('orbital h5 file from convert4qmc does not exist\nlocation checked: {}'.format(orb_h5file)) #end if orb_path = os.path.relpath(orb_h5file,self.locdir) dset.href = orb_path detlist = dset.get('detlist') if detlist is not None and 'href' in detlist: detlist.href = orb_path #end if #end if qs.wavefunction = newwfn else: self.error('incorporating orbitals from '+sim.__class__.__name__+' has not been implemented') #end if elif result_name=='jastrow': if isinstance(sim,Qmcpack): opt_file = result.opt_file opt = QmcpackInput(opt_file) wavefunction = input.get('wavefunction') optwf = opt.qmcsystem.wavefunction def process_jastrow(wf): if 'jastrow' in wf: js = [wf.jastrow] elif 'jastrows' in wf: js = wf.jastrows.values() else: js = [] #end if jd = dict() for j in js: jtype = j.type.lower().replace('-','_').replace(' ','_') jd[jtype] = j #end for return jd #end def process_jastrow if wavefunction==None: qs = input.get('qmcsystem') qs.wavefunction = optwf.copy() else: jold = process_jastrow(wavefunction) jopt = process_jastrow(optwf) jnew = list(jopt.values()) for jtype in jold.keys(): if not jtype in jopt: jnew.append(jold[jtype]) #end if #end for if len(jnew)==1: wavefunction.jastrow = jnew[0].copy() else: wavefunction.jastrows = collection(jnew) #end if #end if del optwf elif isinstance(sim,Sqd): wavefunction = input.get('wavefunction') jastrows = [] if 'jastrows' in wavefunction: for jastrow in wavefunction.jastrows: jname = jastrow.name if jname!='J1' and jname!='J2': jastrows.append(jastrow) #end if #end for del wavefunction.jastrows #end if ionps = input.get_ion_particlesets() if ionps is None or len(ionps)==0: self.error('ion particleset does not seem to exist') elif len(ionps)==1: ionps_name = list(ionps.keys())[0] else: self.error('multiple ion species not supported for atomic calculations') #end if jastrows.extend([ generate_jastrow('J1','bspline',8,result.rcut,iname=ionps_name,system=self.system), generate_jastrow('J2','pade',result.B) ]) wavefunction.jastrows = collection(jastrows) else: self.error('incorporating jastrow from '+sim.__class__.__name__+' has not been implemented') #end if elif result_name=='particles': if isinstance(sim,Convert4qmc): ptcl_file = result.location qi = QmcpackInput(ptcl_file) self.input.simulation.qmcsystem.particlesets = qi.qmcsystem.particlesets else: self.error('incorporating particles from '+sim.__class__.__name__+' has not been implemented') # end if elif result_name=='structure': relstruct = result.structure.copy() relstruct.change_units('B') self.system.structure = relstruct self.system.remove_folded() self.input.incorporate_system(self.system) elif result_name=='cuspcorr': ds = self.input.get('determinantset') ds.cuspcorrection = True try: # multideterminant ds.sposets['spo-up'].cuspinfo = os.path.relpath(result.spo_up_cusps,self.locdir) ds.sposets['spo-dn'].cuspinfo = os.path.relpath(result.spo_dn_cusps,self.locdir) except: # single determinant sd = ds.slaterdeterminant sd.determinants['updet'].cuspinfo = os.path.relpath(result.updet_cusps,self.locdir) sd.determinants['downdet'].cuspinfo = os.path.relpath(result.dndet_cusps,self.locdir) # end try elif result_name=='wavefunction': if not isinstance(sim,Qmcpack): self.error('incorporating wavefunction from '+sim.__class__.__name__+' has not been implemented') #end if print ' getting optimal wavefunction from: '+result.opt_file opt = QmcpackInput(result.opt_file) qs = input.get('qmcsystem') qs.wavefunction = opt.qmcsystem.wavefunction.copy() else: self.error('ability to incorporate result '+result_name+' has not been implemented')
def incorporate_result(self, result_name, result, sim): input = self.input system = self.system if result_name == 'orbitals': if isinstance(sim, Pw2qmcpack): h5file = result.h5file wavefunction = input.get('wavefunction') if isinstance(wavefunction, collection): wavefunction = wavefunction.get_single('psi0') #end if wf = wavefunction if 'sposet_builder' in wf and wf.sposet_builder.type == 'bspline': orb_elem = wf.sposet_builder elif 'sposet_builders' in wf and 'bspline' in wf.sposet_builders: orb_elem = wf.sposet_builders.bspline elif 'sposet_builders' in wf and 'einspline' in wf.sposet_builders: orb_elem = wf.sposet_builders.einspline elif 'determinantset' in wf and wf.determinantset.type in ( 'bspline', 'einspline'): orb_elem = wf.determinantset else: self.error( 'could not incorporate pw2qmcpack orbitals\nbspline sposet_builder and determinantset are both missing' ) #end if if 'href' in orb_elem and isinstance( orb_elem.href, str) and os.path.exists(orb_elem.href): # user specified h5 file for orbitals, bypass orbital dependency orb_elem.href = os.path.relpath(orb_elem.href, self.locdir) else: orb_elem.href = os.path.relpath(h5file, self.locdir) if system.structure.folded_structure != None: orb_elem.tilematrix = array(system.structure.tmatrix) #end if #end if defs = obj( #twistnum = 0, meshfactor=1.0) for var, val in defs.items(): if not var in orb_elem: orb_elem[var] = val #end if #end for has_twist = 'twist' in orb_elem has_twistnum = 'twistnum' in orb_elem if not has_twist and not has_twistnum: orb_elem.twistnum = 0 #end if system = self.system structure = system.structure nkpoints = len(structure.kpoints) if nkpoints == 0: self.error('system must have kpoints to assign twistnums') #end if if not os.path.exists(h5file): self.error('wavefunction file not found:\n' + h5file) #end if twistnums = list(range(len(structure.kpoints))) if self.should_twist_average: self.twist_average(twistnums) elif not has_twist and orb_elem.twistnum is None: orb_elem.twistnum = twistnums[0] #end if elif isinstance(sim, Convert4qmc): res = QmcpackInput(result.location) qs = input.simulation.qmcsystem oldwfn = qs.wavefunction newwfn = res.qmcsystem.wavefunction dset = newwfn.determinantset if 'jastrows' in newwfn: del newwfn.jastrows #end if if 'jastrows' in oldwfn: newwfn.jastrows = oldwfn.jastrows #end if if input.cusp_correction(): dset.cuspcorrection = True #end if if 'orbfile' in result: orb_h5file = result.orbfile if not os.path.exists(orb_h5file) and 'href' in dset: orb_h5file = os.path.join(sim.locdir, dset.href) #end if if not os.path.exists(orb_h5file): self.error( 'orbital h5 file from convert4qmc does not exist\nlocation checked: {}' .format(orb_h5file)) #end if orb_path = os.path.relpath(orb_h5file, self.locdir) dset.href = orb_path detlist = dset.get('detlist') if detlist is not None and 'href' in detlist: detlist.href = orb_path #end if #end if qs.wavefunction = newwfn else: self.error('incorporating orbitals from ' + sim.__class__.__name__ + ' has not been implemented') #end if elif result_name == 'jastrow': if isinstance(sim, Qmcpack): opt_file = result.opt_file opt = QmcpackInput(opt_file) wavefunction = input.get('wavefunction') optwf = opt.qmcsystem.wavefunction def process_jastrow(wf): if 'jastrow' in wf: js = [wf.jastrow] elif 'jastrows' in wf: js = list(wf.jastrows.values()) else: js = [] #end if jd = dict() for j in js: jtype = j.type.lower().replace('-', '_').replace(' ', '_') key = jtype # take care of multiple jastrows of the same type if key in jd: # use name to distinguish key += j.name if key in jd: # if still duplicate then error out msg = 'duplicate jastrow in ' + self.__class__.__name__ self.error(msg) #end if #end if jd[key] = j #end for return jd #end def process_jastrow if wavefunction == None: qs = input.get('qmcsystem') qs.wavefunction = optwf.copy() else: jold = process_jastrow(wavefunction) jopt = process_jastrow(optwf) jnew = list(jopt.values()) for jtype in jold.keys(): if not jtype in jopt: jnew.append(jold[jtype]) #end if #end for if len(jnew) == 1: wavefunction.jastrow = jnew[0].copy() else: wavefunction.jastrows = collection(jnew) #end if #end if del optwf elif result_name == 'particles': if isinstance(sim, Convert4qmc): ptcl_file = result.location qi = QmcpackInput(ptcl_file) self.input.simulation.qmcsystem.particlesets = qi.qmcsystem.particlesets else: self.error('incorporating particles from ' + sim.__class__.__name__ + ' has not been implemented') # end if elif result_name == 'structure': relstruct = result.structure.copy() relstruct.change_units('B') self.system.structure = relstruct self.system.remove_folded() self.input.incorporate_system(self.system) elif result_name == 'cuspcorr': ds = self.input.get('determinantset') ds.cuspcorrection = True try: # multideterminant ds.sposets['spo-up'].cuspinfo = os.path.relpath( result.spo_up_cusps, self.locdir) ds.sposets['spo-dn'].cuspinfo = os.path.relpath( result.spo_dn_cusps, self.locdir) except: # single determinant sd = ds.slaterdeterminant sd.determinants['updet'].cuspinfo = os.path.relpath( result.updet_cusps, self.locdir) sd.determinants['downdet'].cuspinfo = os.path.relpath( result.dndet_cusps, self.locdir) #end try elif result_name == 'wavefunction': if isinstance(sim, Qmcpack): opt = QmcpackInput(result.opt_file) qs = input.get('qmcsystem') qs.wavefunction = opt.qmcsystem.wavefunction.copy() elif isinstance(sim, PyscfToAfqmc): if not self.input.is_afqmc_input(): self.error( 'incorporating wavefunction from {} is only supported for AFQMC calculations' .format(sim.__class__.__name__)) #end if h5_file = os.path.relpath(result.h5_file, self.locdir) wfn = self.input.simulation.wavefunction ham = self.input.simulation.hamiltonian wfn.filename = h5_file wfn.filetype = 'hdf5' if 'filename' not in ham or ham.filename == 'MISSING.h5': ham.filename = h5_file ham.filetype = 'hdf5' #end if if 'xml' in result: xml = QmcpackInput(result.xml) info_new = xml.simulation.afqmcinfo.copy() info = self.input.simulation.afqmcinfo info.set_optional(**info_new) # override particular inputs set by default if 'generation_info' in input._metadata: g = input._metadata.generation_info if 'walker_type' not in g: walker_type = xml.get('walker_type') walkerset = input.get('walkerset') if walker_type is not None and walkerset is not None: walkerset.walker_type = walker_type #end if #end if #end if #end if else: self.error('incorporating wavefunction from ' + sim.__class__.__name__ + ' has not been implemented') #end if elif result_name == 'gc_occupation': from pwscf import Pwscf from qmcpack_converters import gcta_occupation if not isinstance(sim, Pw2qmcpack): msg = 'grand-canonical occupation require Pw2qmcpack' self.error(msg) #endif # step 1: extract Fermi energy for each spin from nscf nscf = None npwdep = 0 for dep in sim.dependencies: if isinstance(dep.sim, Pwscf): nscf = dep.sim npwdep += 1 if npwdep != 1: msg = 'need exactly 1 scf/nscf calculation for Fermi energy' msg += '\n found %d' % npwdep self.error(msg) #end if na = nscf.load_analyzer_image() Ef_list = na.fermi_energies # step 2: analyze ESH5 file for states below Fermi energy pa = sim.load_analyzer_image() if 'wfh5' not in pa: pa.analyze(Ef_list=Ef_list) sim.save_analyzer_image(pa) #end if # step 3: count the number of up/dn electrons at each supertwist s1 = self.system.structure ntwist = len(s1.kpoints) nelecs_at_twist = gcta_occupation(pa.wfh5, ntwist) self.nelecs_at_twist = nelecs_at_twist else: self.error('ability to incorporate result ' + result_name + ' has not been implemented')
def init_sub_analyzers(self,request=None): own_request = request==None if request==None: request = self.info.request #end if group_num = request.group_num #determine if the run was bundled if request.source.endswith('.xml'): self.info.type = 'single' else: self.info.type = 'bundled' self.bundle(request.source) return #end if self.vlog('reading input file: '+request.source,n=1) input = QmcpackInput(request.source) input.pluralize() input.unroll_calculations() calculations = input.simulation.calculations self.info.set( input = input, ordered_input = input.read_xml(request.source) ) project,wavefunction = input.get('project','wavefunction') wavefunction = wavefunction.get_single('psi0') subindent = self.subindent() self.wavefunction = WavefunctionAnalyzer(wavefunction,nindent=subindent) self.vlog('project id: '+project.id,n=1) file_prefix = project.id if group_num!=None: group_ext = '.g'+str(group_num).zfill(3) if not file_prefix.endswith(group_ext): file_prefix += group_ext #end if elif self.info.type=='single': resdir,infile = os.path.split(request.source) ifprefix = infile.replace('.xml','') ls = os.listdir(resdir) for filename in ls: if filename.startswith(ifprefix) and filename.endswith('.qmc'): group_tag = filename.split('.')[-2] #file_prefix = 'qmc.'+group_tag file_prefix = project.id+'.'+group_tag break #end if #end for #end if if 'series' in project: series_start = int(project.series) else: series_start = 0 #end if self.vlog('data file prefix: '+file_prefix,n=1) run_info = obj( file_prefix = file_prefix, series_start = series_start, source_path = os.path.split(request.source)[0], group_num = group_num, system = input.return_system() ) self.info.transfer_from(run_info) self.set_global_info() if len(request.calculations)==0: request.calculations = set(series_start+arange(len(calculations))) #end if method_aliases = dict() for method in self.opt_methods: method_aliases[method]='opt' #end for for method in self.vmc_methods: method_aliases[method]='vmc' #end for for method in self.dmc_methods: method_aliases[method]='dmc' #end for method_objs = ['qmc','opt','vmc','dmc'] for method in method_objs: self[method] = QAanalyzerCollection() #end for for index,calc in calculations.iteritems(): method = calc.method if method in method_aliases: method_type = method_aliases[method] else: self.error('method '+method+' is unrecognized') #end if if method_type in request.methods: series = series_start + index if series in request.calculations: if method in self.opt_methods: qma = OptAnalyzer(series,calc,input,nindent=subindent) self.opt[series] = qma elif method in self.vmc_methods: qma = VmcAnalyzer(series,calc,input,nindent=subindent) self.vmc[series] = qma elif method in self.dmc_methods: qma = DmcAnalyzer(series,calc,input,nindent=subindent) self.dmc[series] = qma #end if self.qmc[series] = qma #end if #end if #end for for method in method_objs: if len(self[method])==0: del self[method] #end if #end for #Check for multi-qmc results such as # optimization or timestep studies results = QAanalyzerCollection() if 'opt' in self and len(self.opt)>0: optres = OptimizationAnalyzer(input,self.opt,nindent=subindent) results.optimization = optres #end if if 'dmc' in self and len(self.dmc)>1: maxtime = 0 times = dict() for series,dmc in self.dmc.iteritems(): blocks,steps,timestep = dmc.info.method_input.list('blocks','steps','timestep') times[series] = blocks*steps*timestep maxtime = max(times[series],maxtime) #end for dmc = QAanalyzerCollection() for series,time in times.iteritems(): if abs(time-maxtime)/maxtime<.5: dmc[series] = self.dmc[series] #end if #end for if len(dmc)>1: results.timestep_study = TimestepStudyAnalyzer(dmc,nindent=subindent) #end if #end if if len(results)>0: self.results = results #end if self.unset_global_info()
def post_analyze(self,analyzer): if not self.has_generic_input(): calctypes = self.input.get_output_info('calctypes') opt_run = calctypes!=None and 'opt' in calctypes if opt_run: opt_file = analyzer.results.optimization.optimal_file if opt_file is None: self.failed = True #end if #end if exc_run = 'excitation' in self if exc_run: exc_failure = False edata = self.read_einspline_dat() exc_input = self.excitation exc_spin,exc_type,exc_spins,exc_types,exc1,exc2 = check_excitation_type(exc_input) elns = self.input.get_electron_particle_set() if exc_type==exc_types.band: # Band Index 'tw1 band1 tw2 band2'. Eg., '0 45 3 46' # Check that tw1,band1 is no longer in occupied set tw1,bnd1 = exc2.split()[0:2] tw2,bnd2 = exc2.split()[2:4] if exc1 in ('up','down'): spin_channel = exc1 dsc = edata[spin_channel] for idx,(tw,bnd) in enumerate(zip(dsc.TwistIndex,dsc.BandIndex)): if tw == int(tw1) and bnd == int(bnd1): # This orbital should no longer be in the set of occupied orbitals if idx<elns.groups[spin_channel[0]].size: msg = 'WARNING: You requested \'{}\' excitation of type \'{}\',\n' msg += ' however, the first orbital \'{} {}\' is still occupied (see einspline file).\n' msg += ' Please check your input.' msg = msg.format(spin_channel,exc_input[1],tw1,bnd1) exc_failure = True #end if elif tw == int(tw2) and bnd == int(bnd2): # This orbital should be in the set of occupied orbitals if idx>=elns.groups[spin_channel[0]].size: msg = 'WARNING: You requested \'{}\' excitation of type \'{}\',\n' msg += ' however, the second orbital \'{} {}\' is not occupied (see einspline file).\n' msg += ' Please check your input.' msg = msg.format(spin_channel,exc_input[1],tw2,bnd2) exc_failure = True #end if #end if #end for else: self.warn('No check for \'{}\' excitation of type \'{}\' was done. When this path is possible, then a check should be written.'.format(exc_input[0],exc_input[1])) #end if elif exc_type in (exc_types.energy,exc_types.lowest): # Lowest or Energy Index '-orbindex1 +orbindex2'. Eg., '-4 +5' if exc_type==exc_types.lowest: if exc_spin==exc_spins.down: orb1 = elns.groups.d.size else: orb1 = elns.groups.u.size #end if orb2 = orb1+1 else: orb1 = int(exc_input[1].split()[0][1:]) orb2 = int(exc_input[1].split()[1][1:]) #end if if exc1 in ('up','down'): spin_channel = exc1 nelec = elns.groups[spin_channel[0]].size eigs_spin = edata[spin_channel].Energy # Construct the correct set of occupied orbitals by hand based on # orb1 and orb2 values that were input by the user excited = eigs_spin order = eigs_spin.argsort() ground = excited[order] # einspline orbital ordering for excited state excited = excited[:nelec] # hand-crafted orbital order for excited state # ground can be list or ndarray, but we'll convert it to list # so we can concatenate with list syntax ground = np.asarray(ground).tolist() # After concatenating, convert back to ndarray hc_excited = np.array(ground[:orb1-1]+[ground[orb2-1]]+ground[orb1:nelec]) etol = 1e-6 if np.abs(hc_excited-excited).max() > etol: msg = 'WARNING: You requested \'{}\' excitation of type \'{}\',\n' msg += ' however, the second orbital \'{}\' is not occupied (see einspline file).\n' msg += ' Please check your input.' msg = msg.format(spin_channel,exc_input[1],orb1) exc_failure = True #end if elif exc1 in ('singlet','triplet'): wf = self.input.get('wavefunction') occ = wf.determinantset.multideterminant.detlist.csf.occ if occ[int(orb1)-1]!='1': msg = 'WARNING: You requested \'{}\' excitation of type \'{}\',\n' msg += ' however, this is inconsistent with the occupations in detlist \'{}\'.\n' msg += ' Please check your input.' msg = msg.format(spin_channel,exc_input[1],occ) exc_failure = True #end if if occ[int(orb2)-1]!='1': msg = 'WARNING: You requested \'{}\' excitation of type \'{}\',\n' msg += ' however, this is inconsistent with the occupations in detlist \'{}\'.\n' msg += ' Please check your input.' msg = msg.format(spin_channel,exc_input[1],occ) exc_failure = True #end if #end if else: # The format is: 'gamma vb z cb' if exc1 in ('singlet','triplet'): self.warn('No check for \'{}\' excitation of type \'{}\' was done. When this path is possible, then a check should be written.'.format(exc_input[0],exc_input[1])) else: # assume excitation of form 'gamma vb k cb' or 'gamma vb-1 k cb+1' excitation = exc2.upper().split(' ') k_1, band_1, k_2, band_2 = excitation tilematrix = self.system.structure.tilematrix() wf = self.input.get('wavefunction') if exc_spin==exc_spins.up: sdet = wf.determinantset.get('updet') else: sdet = wf.determinantset.get('downdet') #end if from numpy import linalg,where,isclose vb = int(sdet.size / abs(linalg.det(tilematrix))) -1 # Separate for each spin channel cb = vb+1 # Convert band_1, band_2 to band indexes bands = [band_1, band_2] for bnum, b in enumerate(bands): b = b.lower() if 'cb' in b: if '-' in b: b = b.split('-') bands[bnum] = cb - int(b[1]) elif '+' in b: b = b.split('+') bands[bnum] = cb + int(b[1]) else: bands[bnum] = cb #end if elif 'vb' in b: if '-' in b: b = b.split('-') bands[bnum] = vb - int(b[1]) elif '+' in b: b = b.split('+') bands[bnum] = vb + int(b[1]) else: bands[bnum] = vb #end if else: QmcpackInput.class_error('{0} in excitation has the wrong formatting'.format(b)) #end if #end for band_1, band_2 = bands # Convert k_1 k_2 to wavevector indexes structure = self.system.structure.get_smallest().copy() structure.change_units('A') from structure import get_kpath kpath = get_kpath(structure=structure) kpath_label = array(kpath['explicit_kpoints_labels']) kpath_rel = kpath['explicit_kpoints_rel'] k1_in = k_1 k2_in = k_2 if k_1 in kpath_label and k_2 in kpath_label: k_1 = kpath_rel[where(kpath_label == k_1)][0] k_2 = kpath_rel[where(kpath_label == k_2)][0] kpts = structure.kpoints_unit() found_k1 = False found_k2 = False for knum, k in enumerate(kpts): if isclose(k_1, k).all(): k_1 = knum found_k1 = True #end if if isclose(k_2, k).all(): k_2 = knum found_k2 = True #end if #end for if not found_k1 or not found_k2: QmcpackInput.class_error('Requested special kpoint is not in the tiled cell\nRequested "{}", present={}\nRequested "{}", present={}\nAvailable kpoints: {}'.format(k1_in,found_k1,k2_in,found_k2,sorted(set(kpath_label)))) #end if else: QmcpackInput.class_error('Excitation wavevectors are not found in the kpath\nlabels requested: {} {}\nlabels present: {}'.format(k_1,k_2,sorted(set(kpath_label)))) #end if tw1,bnd1 = (k_1,band_1) tw2,bnd2 = (k_2,band_2) spin_channel = exc1 dsc = edata[spin_channel] for idx,(tw,bnd) in enumerate(zip(dsc.TwistIndex,dsc.BandIndex)): if tw == int(tw1) and bnd == int(bnd1): # This orbital should no longer be in the set of occupied orbitals if idx<elns.groups[spin_channel[0]].size: msg = 'WARNING: You requested \'{}\' excitation of type \'{}\',\n' msg += ' however, the first orbital \'{} {}\' is still occupied (see einspline file).\n' msg += ' Please check your input.' msg = msg.format(spin_channel,exc_input[1],tw1,bnd1) exc_failure = True #end if elif tw == int(tw2) and bnd == int(bnd2): # This orbital should be in the set of occupied orbitals if idx>=elns.groups[spin_channel[0]].size: msg = 'WARNING: You requested \'{}\' excitation of type \'{}\',\n' msg += ' however, the second orbital \'{} {}\' is not occupied (see einspline file).\n' msg += ' Please check your input.' msg = msg.format(spin_channel,exc_input[1],tw2,bnd2) exc_failure = True #end if #end if #end for #end if if exc_failure: self.failed = True self.warn(msg) filename = self.identifier+'_errors.txt' open(os.path.join(self.locdir,filename),'w').write(msg)
def init_sub_analyzers(self, request=None): own_request = request == None if request == None: request = self.info.request #end if group_num = request.group_num #determine if the run was bundled if request.source.endswith('.xml'): self.info.type = 'single' else: self.info.type = 'bundled' self.bundle(request.source) return #end if self.vlog('reading input file: ' + request.source, n=1) input = QmcpackInput(request.source) input.pluralize() input.unroll_calculations() calculations = input.simulation.calculations self.info.set(input=input, ordered_input=input.read_xml(request.source)) project, wavefunction = input.get('project', 'wavefunction') wavefunction = wavefunction.get_single('psi0') subindent = self.subindent() self.wavefunction = WavefunctionAnalyzer(wavefunction, nindent=subindent) self.vlog('project id: ' + project.id, n=1) file_prefix = project.id if group_num != None: group_ext = '.g' + str(group_num).zfill(3) if not file_prefix.endswith(group_ext): file_prefix += group_ext #end if elif self.info.type == 'single': resdir, infile = os.path.split(request.source) #ifprefix = infile.replace('.xml','') ifprefix = infile.replace('.xml', '.') ls = os.listdir(resdir) for filename in ls: if filename.startswith(ifprefix) and filename.endswith('.qmc'): group_tag = filename.split('.')[-2] #file_prefix = 'qmc.'+group_tag file_prefix = project.id + '.' + group_tag break #end if #end for #end if if 'series' in project: series_start = int(project.series) else: series_start = 0 #end if self.vlog('data file prefix: ' + file_prefix, n=1) run_info = obj(file_prefix=file_prefix, series_start=series_start, source_path=os.path.split(request.source)[0], group_num=group_num, system=input.return_system()) self.info.transfer_from(run_info) self.set_global_info() if len(request.calculations) == 0: request.calculations = set(series_start + arange(len(calculations))) #end if method_aliases = dict() for method in self.opt_methods: method_aliases[method] = 'opt' #end for for method in self.vmc_methods: method_aliases[method] = 'vmc' #end for for method in self.dmc_methods: method_aliases[method] = 'dmc' #end for method_objs = ['qmc', 'opt', 'vmc', 'dmc'] for method in method_objs: self[method] = QAanalyzerCollection() #end for for index, calc in calculations.iteritems(): method = calc.method if method in method_aliases: method_type = method_aliases[method] else: self.error('method ' + method + ' is unrecognized') #end if if method_type in request.methods: series = series_start + index if series in request.calculations: if method in self.opt_methods: qma = OptAnalyzer(series, calc, input, nindent=subindent) primary = self.opt elif method in self.vmc_methods: qma = VmcAnalyzer(series, calc, input, nindent=subindent) primary = self.vmc elif method in self.dmc_methods: qma = DmcAnalyzer(series, calc, input, nindent=subindent) primary = self.dmc #end if primary[series] = qma self.qmc[series] = qma #end if #end if #end for for method in method_objs: if len(self[method]) == 0: del self[method] #end if #end for #Check for multi-qmc results such as # optimization or timestep studies results = QAanalyzerCollection() if 'opt' in self and len(self.opt) > 0: optres = OptimizationAnalyzer(input, self.opt, nindent=subindent) results.optimization = optres #end if if 'dmc' in self and len(self.dmc) > 1: maxtime = 0 times = dict() for series, dmc in self.dmc.iteritems(): blocks, steps, timestep = dmc.info.method_input.list( 'blocks', 'steps', 'timestep') times[series] = blocks * steps * timestep maxtime = max(times[series], maxtime) #end for dmc = QAanalyzerCollection() for series, time in times.iteritems(): if abs(time - maxtime) / maxtime < .5: dmc[series] = self.dmc[series] #end if #end for if len(dmc) > 1: results.timestep_study = TimestepStudyAnalyzer( dmc, nindent=subindent) #end if #end if if len(results) > 0: self.results = results #end if self.unset_global_info()
def incorporate_result(self,result_name,result,sim): input = self.input system = self.system if result_name=='orbitals': if isinstance(sim,Pw2qmcpack) or isinstance(sim,Wfconvert): h5file = result.h5file wavefunction = input.get('wavefunction') if isinstance(wavefunction,collection): wavefunction = wavefunction.get_single('psi0') #end if wf = wavefunction if 'sposet_builder' in wf and wf.sposet_builder.type=='bspline': orb_elem = wf.sposet_builder elif 'sposet_builders' in wf and 'bspline' in wf.sposet_builders: orb_elem = wf.sposet_builders.bspline elif 'determinantset' in wf and wf.determinantset.type in ('bspline','einspline'): orb_elem = wf.determinantset else: self.error('could not incorporate pw2qmcpack/wfconvert orbitals\n bspline sposet_builder and determinantset are both missing') #end if orb_elem.href = os.path.relpath(h5file,self.locdir) if system.structure.folded_structure!=None: orb_elem.tilematrix = array(system.structure.tmatrix) #end if defs = obj( twistnum = 0, meshfactor = 1.0 ) for var,val in defs.iteritems(): if not var in orb_elem: orb_elem[var] = val #end if #end for system = self.system structure = system.structure nkpoints = len(structure.kpoints) if nkpoints==0: self.error('system must have kpoints to assign twistnums') #end if if not os.path.exists(h5file): self.error('wavefunction file not found: \n'+h5file) #end if twistnums = range(len(structure.kpoints)) if self.should_twist_average: self.twist_average(twistnums) elif orb_elem.twistnum is None: orb_elem.twistnum = twistnums[0] #end if elif isinstance(sim,Sqd): h5file = os.path.join(result.dir,result.h5file) h5file = os.path.relpath(h5file,self.locdir) sqdxml_loc = os.path.join(result.dir,result.qmcfile) sqdxml = QmcpackInput(sqdxml_loc) #sqd sometimes puts the wrong ionic charge # rather than setting Z to the number of electrons # set it to the actual atomic number g = sqdxml.qmcsystem.particlesets.atom.group elem = g.name if not elem in periodic_table.elements: self.error(elem+' is not an element in the periodic table') #end if g.charge = periodic_table.elements[elem].atomic_number input = self.input s = input.simulation qsys_old = s.qmcsystem del s.qmcsystem s.qmcsystem = sqdxml.qmcsystem if 'jastrows' in qsys_old.wavefunction: s.qmcsystem.wavefunction.jastrows = qsys_old.wavefunction.jastrows for jastrow in s.qmcsystem.wavefunction.jastrows: if 'type' in jastrow: jtype = jastrow.type.lower().replace('-','_') if jtype=='one_body': jastrow.source = 'atom' #end if #end if #end for #end if s.qmcsystem.hamiltonian = hamiltonian( name='h0',type='generic',target='e', pairpots = [ pairpot(name='ElecElec',type='coulomb',source='e',target='e'), pairpot(name='Coulomb' ,type='coulomb',source='atom',target='e'), ] ) s.init = init(source='atom',target='e') abset = input.get('atomicbasisset') abset.href = h5file else: self.error('incorporating orbitals from '+sim.__class__.__name__+' has not been implemented') #end if elif result_name=='jastrow': if isinstance(sim,Qmcpack): opt_file = result.opt_file opt = QmcpackInput(opt_file) wavefunction = input.get('wavefunction') optwf = opt.qmcsystem.wavefunction def process_jastrow(wf): if 'jastrow' in wf: js = [wf.jastrow] elif 'jastrows' in wf: js = wf.jastrows.values() else: js = [] #end if jd = dict() for j in js: jtype = j.type.lower().replace('-','_').replace(' ','_') jd[jtype] = j #end for return jd #end def process_jastrow if wavefunction==None: qs = input.get('qmcsystem') qs.wavefunction = optwf.copy() else: jold = process_jastrow(wavefunction) jopt = process_jastrow(optwf) jnew = list(jopt.values()) for jtype in jold.keys(): if not jtype in jopt: jnew.append(jold[jtype]) #end if #end for if len(jnew)==1: wavefunction.jastrow = jnew[0].copy() else: wavefunction.jastrows = collection(jnew) #end if #end if del optwf elif isinstance(sim,Sqd): wavefunction = input.get('wavefunction') jastrows = [] if 'jastrows' in wavefunction: for jastrow in wavefunction.jastrows: jname = jastrow.name if jname!='J1' and jname!='J2': jastrows.append(jastrow) #end if #end for del wavefunction.jastrows #end if ionps = input.get_ion_particlesets() if ionps is None or len(ionps)==0: self.error('ion particleset does not seem to exist') elif len(ionps)==1: ionps_name = list(ionps.keys())[0] else: self.error('multiple ion species not supported for atomic calculations') #end if jastrows.extend([ generate_jastrow('J1','bspline',8,result.rcut,iname=ionps_name,system=self.system), generate_jastrow('J2','pade',result.B) ]) wavefunction.jastrows = collection(jastrows) else: self.error('incorporating jastrow from '+sim.__class__.__name__+' has not been implemented') #end if elif result_name=='structure': structure = self.system.structure relstruct = result.structure structure.set( pos = relstruct.positions, atoms = relstruct.atoms ) self.input.incorporate_system(self.system) else: self.error('ability to incorporate result '+result_name+' has not been implemented')
def test_incorporate_result(): import os import shutil from subprocess import Popen, PIPE from numpy import array from generic import NexusError, obj from nexus_base import nexus_core from test_vasp_simulation import setup_vasp_sim as get_vasp_sim from test_vasp_simulation import pseudo_inputs as vasp_pseudo_inputs from test_qmcpack_converter_simulations import get_pw2qmcpack_sim from test_qmcpack_converter_simulations import get_convert4qmc_sim from test_qmcpack_converter_simulations import get_pyscf_to_afqmc_sim pseudo_inputs = obj(vasp_pseudo_inputs) tpath = testing.setup_unit_test_output_directory( 'qmcpack_simulation', 'test_incorporate_result', **pseudo_inputs) nexus_core.runs = '' nexus_core.results = '' # incorporate vasp structure sim = get_qmcpack_sim(identifier='qmc_vasp_structure', tiling=(2, 2, 2)) vasp_struct = get_vasp_sim(tpath, identifier='vasp_structure', files=True) assert (sim.locdir.strip('/') == tpath.strip('/')) pc_file = 'diamond_POSCAR' cc_file = vasp_struct.identifier + '.CONTCAR' shutil.copy2(os.path.join(tpath, pc_file), os.path.join(tpath, cc_file)) result = vasp_struct.get_result('structure', None) ion0 = sim.input.get('ion0') c = ion0.groups.C cp0 = c.position[0].copy() s = result.structure.copy() s.change_units('B') rp0 = s.pos[0] zero = array([0, 0, 0], dtype=float) assert (value_eq(c.position[0], cp0, atol=1e-8)) c.position[0] += 0.1 assert (not value_eq(c.position[0], cp0, atol=1e-8)) assert (not value_eq(c.position[0], rp0, atol=1e-8)) sim.incorporate_result('structure', result, vasp_struct) ion0 = sim.input.get('ion0') c = ion0.groups.C assert (value_eq(c.position[0], rp0, atol=1e-8)) # incorporate pw2qmcpack orbitals sim = get_qmcpack_sim(identifier='qmc_p2q_orbitals') p2q_orb = get_pw2qmcpack_sim(identifier='p2q_orbitals') result = p2q_orb.get_result('orbitals', None) p2q_output_path = os.path.join(tpath, 'pwscf_output') if not os.path.exists(p2q_output_path): os.makedirs(p2q_output_path) #end if p2q_h5file = os.path.join(p2q_output_path, 'pwscf.pwscf.h5') f = open(p2q_h5file, 'w') f.write('') f.close() assert (os.path.exists(p2q_h5file)) spo = sim.input.get('bspline') assert (spo.href == 'MISSING.h5') sim.incorporate_result('orbitals', result, p2q_orb) assert (spo.href == 'pwscf_output/pwscf.pwscf.h5') # incorporate convert4qmc orbitals sim = get_qmcpack_sim(identifier='qmc_c4q_orbitals') c4q_orb = get_convert4qmc_sim(identifier='c4q_orbitals') result = c4q_orb.get_result('orbitals', None) wfn_file = os.path.join(tpath, 'c4q_orbitals.wfj.xml') wfn_file2 = os.path.join(tpath, 'c4q_orbitals.orbs.h5') input = sim.input.copy() dset = input.get('determinantset') dset.href = 'orbs.h5' qs = input.simulation.qmcsystem del input.simulation input.qmcsystem = qs input.write(wfn_file) assert (os.path.exists(wfn_file)) open(wfn_file2, 'w').write('fake') assert (os.path.exists(wfn_file2)) from qmcpack_input import QmcpackInput inp = QmcpackInput(wfn_file) dset = sim.input.get('determinantset') assert ('href' not in dset) sim.incorporate_result('orbitals', result, c4q_orb) dset = sim.input.get('determinantset') assert (dset.href == 'c4q_orbitals.orbs.h5') # incorporate qmcpack jastrow sim = get_qmcpack_sim(identifier='qmc_jastrow') qa_files_path = testing.unit_test_file_path('qmcpack_analyzer', 'diamond_gamma/opt') command = 'rsync -a {} {}'.format(qa_files_path, tpath) process = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, close_fds=True) out, err = process.communicate() opt_path = os.path.join(tpath, 'opt') opt_infile = os.path.join(opt_path, 'opt.in.xml') assert (os.path.exists(opt_infile)) opt_file = os.path.join(opt_path, 'opt.s004.opt.xml') assert (os.path.exists(opt_file)) result = obj(opt_file=opt_file) sim.incorporate_result('jastrow', result, sim) j = sim.input.get('jastrow') j_text = j.write().replace('"', ' " ') j_text_ref = ''' <jastrow type="Two-Body" name="J2" function="bspline" print="yes"> <correlation speciesA="u" speciesB="u" size="8" rcut="2.3851851232"> <coefficients id="uu" type="Array"> 0.2576630369 0.1796686015 0.1326653657 0.09407180823 0.06267013118 0.03899100023 0.02070235604 0.009229775746 </coefficients> </correlation> <correlation speciesA="u" speciesB="d" size="8" rcut="2.3851851232"> <coefficients id="ud" type="Array"> 0.4385891515 0.3212399072 0.2275448261 0.1558506324 0.1009589176 0.06108433554 0.03154274436 0.01389485975 </coefficients> </correlation> </jastrow> '''.replace('"', ' " ') assert (text_eq(j_text, j_text_ref)) # incorporate qmcpack wavefunction sim = get_qmcpack_sim(identifier='qmc_wavefunction') sim.incorporate_result('wavefunction', result, sim) j = sim.input.get('jastrow') j_text = j.write().replace('"', ' " ') assert (text_eq(j_text, j_text_ref)) # incorporate qmcpack wavefunction afqmc sim = get_qmcpack_sim(type='afqmc', identifier='qmc_wf_afqmc') p2a_wf = get_pyscf_to_afqmc_sim(identifier='p2a_wavefunction') result = p2a_wf.get_result('wavefunction', None) del result.xml wfn = sim.input.get('wavefunction') ham = sim.input.get('hamiltonian') assert (wfn.filename == 'MISSING.h5') assert (ham.filename == 'MISSING.h5') sim.incorporate_result('wavefunction', result, p2a_wf) assert (wfn.filename == 'p2a_wavefunction.afqmc.h5') assert (ham.filename == 'p2a_wavefunction.afqmc.h5') clear_all_sims() restore_nexus()