From 3134435a617f89b87f88055e46d4cc8f3ff382ff Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Fri, 19 Nov 2021 15:31:52 -0500 Subject: [PATCH 01/35] First, fix small bug --- nexus/lib/qmcpack_input.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nexus/lib/qmcpack_input.py b/nexus/lib/qmcpack_input.py index 1684973cee..b44a54974e 100644 --- a/nexus/lib/qmcpack_input.py +++ b/nexus/lib/qmcpack_input.py @@ -4874,7 +4874,7 @@ def generate_determinantset_old(type = 'bspline', sposets = sposet_list, multideterminant = multideterminant( optimize = 'no', - spo_up='spu_u' if down_spin else 'spo_ud', + spo_up='spo_u' if down_spin else 'spo_ud', spo_dn='spo_d' if down_spin else 'spo_ud', detlist = detlist( size = '1', From e91ed3ad894ad5263aff91d98bbd6fc68e33ac69 Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Fri, 19 Nov 2021 16:20:20 -0500 Subject: [PATCH 02/35] small change --- nexus/lib/qmcpack_input.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nexus/lib/qmcpack_input.py b/nexus/lib/qmcpack_input.py index b44a54974e..4d6d7c9e99 100644 --- a/nexus/lib/qmcpack_input.py +++ b/nexus/lib/qmcpack_input.py @@ -4804,8 +4804,12 @@ def generate_determinantset_old(type = 'bspline', #1. excitation=['up','0 45 3 46'] #2. excitation=['up','-215 216'] #3. excitation=['up', 'L vb F cb'] - if len(excitation) == 2: #Type 1 or 2 - if 'cb' not in excitation[1] and 'vb' not in excitation[1]: + #4. excitation=['up', 'homo lumo'] OR excitation=['up', 'homo-N lumo+M'] + if len(excitation) == 2: #Type 1, 2, 3, or 4 + if 'homo' in excitation[1] and 'lumo' in excitation[1]: + print('HERE') + quit() + elif 'cb' not in excitation[1] and 'vb' not in excitation[1]: try: tmp = array(excitation[1].split(),dtype=int) except: From 6de45e6290646d33275b4b5fcbc4bc23c5431184 Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Fri, 19 Nov 2021 16:28:31 -0500 Subject: [PATCH 03/35] small change --- nexus/lib/qmcpack_input.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/nexus/lib/qmcpack_input.py b/nexus/lib/qmcpack_input.py index 4d6d7c9e99..ca5397dbf1 100644 --- a/nexus/lib/qmcpack_input.py +++ b/nexus/lib/qmcpack_input.py @@ -4807,8 +4807,16 @@ def generate_determinantset_old(type = 'bspline', #4. excitation=['up', 'homo lumo'] OR excitation=['up', 'homo-N lumo+M'] if len(excitation) == 2: #Type 1, 2, 3, or 4 if 'homo' in excitation[1] and 'lumo' in excitation[1]: - print('HERE') - quit() + try: + tmp = array(excitation[1].split(),dtype=str) + if tmp[0][:4]!='homo' or tmp[1][:4]: + format_failed = True + else: + print('pass') + quit() + except: + format_failed = True + #end try elif 'cb' not in excitation[1] and 'vb' not in excitation[1]: try: tmp = array(excitation[1].split(),dtype=int) From 5af39efbdd88ffa7c59fb93585385c66535cdb01 Mon Sep 17 00:00:00 2001 From: Workshop Date: Mon, 22 Nov 2021 10:14:36 -0500 Subject: [PATCH 04/35] Adding prints for exploration reasons --- nexus/lib/qmcpack.py | 10 ++++++++++ nexus/lib/qmcpack_input.py | 13 +++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index 29876e110d..9106ccc67a 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -611,6 +611,16 @@ def write_prep(self): def generate_qmcpack(**kwargs): sim_args,inp_args = Qmcpack.separate_inputs(kwargs) + #print('================================================== SIM ARGS') + #print(sim_args) + #print('================================================== INP ARGS') + #print(inp_args) + #print('================================================== SIM ARGS: sim_agrs.dependencies') + print(sim_args.dependencies[0]['ordered_dependencies'][0]['result_names']) + print(sim_args.dependencies[0]['ordered_dependencies'][0]['sim'].keys()) + print(sim_args.dependencies[0]['ordered_dependencies'][0]['sim']['imlocdir']) + print(sim_args.dependencies[0]['ordered_dependencies'][0]['sim']['analyzer_image']) + quit() if 'input' not in sim_args: sim_args.input = generate_qmcpack_input(**inp_args) diff --git a/nexus/lib/qmcpack_input.py b/nexus/lib/qmcpack_input.py index ca5397dbf1..7a3bb33590 100644 --- a/nexus/lib/qmcpack_input.py +++ b/nexus/lib/qmcpack_input.py @@ -4807,16 +4807,21 @@ def generate_determinantset_old(type = 'bspline', #4. excitation=['up', 'homo lumo'] OR excitation=['up', 'homo-N lumo+M'] if len(excitation) == 2: #Type 1, 2, 3, or 4 if 'homo' in excitation[1] and 'lumo' in excitation[1]: + print(system) + print('=================================== SELF ========================================') + print(self) + quit() + print('HERE') try: tmp = array(excitation[1].split(),dtype=str) - if tmp[0][:4]!='homo' or tmp[1][:4]: + if (tmp[0][:4]!='homo' or tmp[1][:4]!='lumo') or (not is_int(tmp[0][4:]) or not is_int(tmp[1][4:])): format_failed = True - else: - print('pass') - quit() + #end if except: format_failed = True #end try + print(format_failed) + quit() elif 'cb' not in excitation[1] and 'vb' not in excitation[1]: try: tmp = array(excitation[1].split(),dtype=int) From 2decee46172ad217968803f368276be1e4624b4b Mon Sep 17 00:00:00 2001 From: Workshop Date: Mon, 22 Nov 2021 16:39:54 -0500 Subject: [PATCH 05/35] Adding excitation checks to post_analyze --- nexus/lib/qmcpack.py | 147 ++++++++++++++++++++++++++++++++++--- nexus/lib/qmcpack_input.py | 15 ++-- 2 files changed, 145 insertions(+), 17 deletions(-) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index 9106ccc67a..b56c74b966 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -41,6 +41,7 @@ from debug import ci,ls,gs from developer import unavailable from nexus_base import nexus_core +from copy import deepcopy try: import h5py except: @@ -176,6 +177,7 @@ def incorporate_result(self,result_name,result,sim): h5file = result.h5file wavefunction = input.get('wavefunction') + print(wavefunction) if isinstance(wavefunction,collection): wavefunction = wavefunction.get_single('psi0') #end if @@ -509,6 +511,89 @@ def post_analyze(self,analyzer): self.failed = True #end if #end if + exc_run = 'excitation' in self + if exc_run: + edata = self.read_einspline_dat() + exc_input = self.excitation + + print(exc_input) + exc_failure = False + if 'cb' not in exc_input[1] and 'vb' not in exc_input[1] and len(exc_input[1].split())==4: + # Band Index 'tw1 band1 tw2 band2'. Eg., '0 45 3 46' + # Check that tw1,band1 is no longer in occupied set + tw1,bnd1 = exc_input[1].split()[0:2] + tw2,bnd2 = exc_input[1].split()[2:4] + if exc_input[0] in ('up','dn'): + spinchan = exc_input[0] + for idx,(tw,bnd) in enumerate(zip(edata[spinchan]['TwistIndex'],edata[spinchan]['BandIndex'])): + if tw == int(tw1) and bnd == int(bnd1): + # This orbital should no longer be in the set of occupied orbitals + if idx=self.input.simulation.qmcsystem.particlesets.e.groups[spinchan[0]].size: + msg='WARNING: You requested \'{}\' excitation of type \'{}\', however, the second orbital \'{} {}\' is not occupied (see einspline file).\nPlease check your input.'.format(spinchan,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 len(exc_input[1].split()) == 2: + # Energy Index '-orbindex1 +orbindex2'. Eg., '-4 +5' + orb1 = exc_input[1].split()[0][1:] + orb2 = exc_input[1].split()[1][1:] + if exc_input[0] in ('up','dn'): + + + spinchan = exc_input[0] + nelec = self.input.simulation.qmcsystem.particlesets.e.groups[spinchan[0]].size + + orb1_eig = sorted(edata[spinchan]['Energy'])[int(orb1)-1] + orb2_eig = sorted(edata[spinchan]['Energy'])[int(orb2)-1] + + + if orb1_eig not in edata[spinchan]['Energy'][nelec:]: + msg='WARNING: You requested \'{}\' excitation of type \'{}\', however, the first orbital \'{}\' is still occupied (see einspline file).\nPlease check your input.'.format(spinchan,exc_input[1],orb1) + exc_failure = True + elif orb2_eig not in edata[spinchan]['Energy'][:nelec]: + msg='WARNING: You requested \'{}\' excitation of type \'{}\', however, the first orbital \'{}\' is still occupied (see einspline file).\nPlease check your input.'.format(spinchan,exc_input[1],orb2) + exc_failure = True + + + elif exc_input[0] 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 \'{}\', however, this is inconsistent with the occupations in detlist \'{}\'.\nPlease check your input.'.format(spinchan,exc_input[1],occ) + exc_failure = True + #end if + if occ[int(orb2)-1]!='1': + msg='WARNING: You requested \'{}\' excitation of type \'{}\', however, this is inconsistent with the occupations in detlist \'{}\'.\nPlease check your input.'.format(spinchan,exc_input[1],occ) + exc_failure = True + #end if + + #end if + + elif exc_input[1] == 'lowest': + + + #end if + + # exc_input interpretation code + # if multidet + # wf = self.input.get('wavefunction') + # exc checking code based on edata + # if problems + # msg = '' + # self.warn(msg) + # filename = self.identifier+'_errors.txt' + # open(os.path.join(self.lodcir,filename),'w').write(msg) + #end if #end if #end def post_analyze @@ -605,28 +690,70 @@ def write_prep(self): #end if #end if #end def write_prep + + + def read_einspline_dat(self): + + edata = obj() + + import glob + for einpath in glob.glob(self.locdir+'/einsplin*'): + ftokens = einpath.split('.') + fspin = int(ftokens[-5][5]) + if fspin==0: + spinlab = 'up' + else: + spinlab = 'dn' + #end if + edata[spinlab] = obj() + with open(einpath) as f: + data = array(f.read().split()[1:]) + data.shape = len(data)//12,12 + data = data.T + for darr in data: + if darr[0][0]=='K' or darr[0][0]=='E': + edata[spinlab][darr[0]] = array(list(map(float,darr[1:]))) + else: + edata[spinlab][darr[0]] = array(list(map(int,darr[1:]))) + + #end if + #end for + #end with + #end for + + return edata + + #end def read_einspline_dat #end class Qmcpack def generate_qmcpack(**kwargs): sim_args,inp_args = Qmcpack.separate_inputs(kwargs) - #print('================================================== SIM ARGS') - #print(sim_args) - #print('================================================== INP ARGS') - #print(inp_args) - #print('================================================== SIM ARGS: sim_agrs.dependencies') - print(sim_args.dependencies[0]['ordered_dependencies'][0]['result_names']) - print(sim_args.dependencies[0]['ordered_dependencies'][0]['sim'].keys()) - print(sim_args.dependencies[0]['ordered_dependencies'][0]['sim']['imlocdir']) - print(sim_args.dependencies[0]['ordered_dependencies'][0]['sim']['analyzer_image']) - quit() + + exc = None + if 'excitation' in inp_args: + exc = deepcopy(inp_args.excitation) + #end if + + spp = None + if 'spin_polarized' in inp_args: + spp = deepcopy(inp_args.spin_polarized) + #end if if 'input' not in sim_args: sim_args.input = generate_qmcpack_input(**inp_args) #end if qmcpack = Qmcpack(**sim_args) + if exc is not None: + qmcpack.excitation = exc + #end if + + if spp is not None: + qmcpack.spin_polarized = spp + #end if + return qmcpack #end def generate_qmcpack diff --git a/nexus/lib/qmcpack_input.py b/nexus/lib/qmcpack_input.py index 7a3bb33590..381e7b00f4 100644 --- a/nexus/lib/qmcpack_input.py +++ b/nexus/lib/qmcpack_input.py @@ -4794,6 +4794,7 @@ def generate_determinantset_old(type = 'bspline', dset.slaterdeterminant.delay_rank = delay_rank #end if if excitation is not None: + print('SET UP EXCITATION') format_failed = False if not isinstance(excitation,(tuple,list)): QmcpackInput.class_error('excitation must be a tuple or list\nyou provided type: {0}\nwith value: {1}'.format(excitation.__class__.__name__,excitation)) @@ -4807,10 +4808,10 @@ def generate_determinantset_old(type = 'bspline', #4. excitation=['up', 'homo lumo'] OR excitation=['up', 'homo-N lumo+M'] if len(excitation) == 2: #Type 1, 2, 3, or 4 if 'homo' in excitation[1] and 'lumo' in excitation[1]: - print(system) - print('=================================== SELF ========================================') - print(self) - quit() + #print(system) + #print('=================================== SELF ========================================') + #print(self) + #quit() print('HERE') try: tmp = array(excitation[1].split(),dtype=str) @@ -4820,8 +4821,8 @@ def generate_determinantset_old(type = 'bspline', except: format_failed = True #end try - print(format_failed) - quit() + #print(format_failed) + #quit() elif 'cb' not in excitation[1] and 'vb' not in excitation[1]: try: tmp = array(excitation[1].split(),dtype=int) @@ -4864,7 +4865,7 @@ def generate_determinantset_old(type = 'bspline', spos = '' ), sposet(name = 'spo_d', - spindataset = 0, + spindataset = 1, size = elns.up_electron.count+1, occupation = section(mode='ground'), coefficient = section(spindataset=1), From c9d8f6965d816491b3969aa661c4df9ef4ee89f7 Mon Sep 17 00:00:00 2001 From: Workshop Date: Tue, 23 Nov 2021 10:20:30 -0500 Subject: [PATCH 06/35] Near final --- nexus/lib/qmcpack.py | 77 ++++++++++++++++++------------------- nexus/lib/qmcpack_input.py | 78 ++++++++++++++++++++------------------ 2 files changed, 79 insertions(+), 76 deletions(-) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index b56c74b966..603395d721 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -177,7 +177,6 @@ def incorporate_result(self,result_name,result,sim): h5file = result.h5file wavefunction = input.get('wavefunction') - print(wavefunction) if isinstance(wavefunction,collection): wavefunction = wavefunction.get_single('psi0') #end if @@ -516,26 +515,25 @@ def post_analyze(self,analyzer): edata = self.read_einspline_dat() exc_input = self.excitation - print(exc_input) exc_failure = False if 'cb' not in exc_input[1] and 'vb' not in exc_input[1] and len(exc_input[1].split())==4: # Band Index 'tw1 band1 tw2 band2'. Eg., '0 45 3 46' # Check that tw1,band1 is no longer in occupied set tw1,bnd1 = exc_input[1].split()[0:2] tw2,bnd2 = exc_input[1].split()[2:4] - if exc_input[0] in ('up','dn'): - spinchan = exc_input[0] - for idx,(tw,bnd) in enumerate(zip(edata[spinchan]['TwistIndex'],edata[spinchan]['BandIndex'])): + if exc_input[0] in ('up','down'): + spin_channel = exc_input[0] + for idx,(tw,bnd) in enumerate(zip(edata[spin_channel]['TwistIndex'],edata[spin_channel]['BandIndex'])): if tw == int(tw1) and bnd == int(bnd1): # This orbital should no longer be in the set of occupied orbitals - if idx=self.input.simulation.qmcsystem.particlesets.e.groups[spinchan[0]].size: - msg='WARNING: You requested \'{}\' excitation of type \'{}\', however, the second orbital \'{} {}\' is not occupied (see einspline file).\nPlease check your input.'.format(spinchan,exc_input[1],tw2,bnd2) + if idx>=self.input.simulation.qmcsystem.particlesets.e.groups[spin_channel[0]].size: + msg='WARNING: You requested \'{}\' excitation of type \'{}\', however, the second orbital \'{} {}\' is not occupied (see einspline file).\nPlease check your input.'.format(spin_channel,exc_input[1],tw2,bnd2) exc_failure = True #end if #end if @@ -543,56 +541,55 @@ def post_analyze(self,analyzer): 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 len(exc_input[1].split()) == 2: - # Energy Index '-orbindex1 +orbindex2'. Eg., '-4 +5' - orb1 = exc_input[1].split()[0][1:] - orb2 = exc_input[1].split()[1][1:] - if exc_input[0] in ('up','dn'): - - - spinchan = exc_input[0] - nelec = self.input.simulation.qmcsystem.particlesets.e.groups[spinchan[0]].size + elif len(exc_input[1].split()) == 2 or exc_input[1]=='lowest': + # Lowest or Energy Index '-orbindex1 +orbindex2'. Eg., '-4 +5' + if exc_input[1]=='lowest': + if exc_input[0]=='down': + orb1 = self.input.simulation.qmcsystem.particlesets.e.groups.d.size + else: + orb1 = self.input.simulation.qmcsystem.particlesets.e.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 exc_input[0] in ('up','down'): - orb1_eig = sorted(edata[spinchan]['Energy'])[int(orb1)-1] - orb2_eig = sorted(edata[spinchan]['Energy'])[int(orb2)-1] + spin_channel = exc_input[0] + nelec = self.input.simulation.qmcsystem.particlesets.e.groups[spin_channel[0]].size + orb1_eig = sorted(edata[spin_channel]['Energy'])[orb1-1] + orb2_eig = sorted(edata[spin_channel]['Energy'])[orb2-1] - if orb1_eig not in edata[spinchan]['Energy'][nelec:]: - msg='WARNING: You requested \'{}\' excitation of type \'{}\', however, the first orbital \'{}\' is still occupied (see einspline file).\nPlease check your input.'.format(spinchan,exc_input[1],orb1) + if orb1_eig not in edata[spin_channel]['Energy'][nelec:]: + msg='WARNING: You requested \'{}\' excitation of type \'{}\', however, the first orbital \'{}\' is still occupied (see einspline file).\nPlease check your input.'.format(spin_channel,exc_input[1],orb1) exc_failure = True - elif orb2_eig not in edata[spinchan]['Energy'][:nelec]: - msg='WARNING: You requested \'{}\' excitation of type \'{}\', however, the first orbital \'{}\' is still occupied (see einspline file).\nPlease check your input.'.format(spinchan,exc_input[1],orb2) + elif orb2_eig not in edata[spin_channel]['Energy'][:nelec]: + msg='WARNING: You requested \'{}\' excitation of type \'{}\', however, the first orbital \'{}\' is still occupied (see einspline file).\nPlease check your input.'.format(spin_channel,exc_input[1],orb2) exc_failure = True - elif exc_input[0] 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 \'{}\', however, this is inconsistent with the occupations in detlist \'{}\'.\nPlease check your input.'.format(spinchan,exc_input[1],occ) + msg='WARNING: You requested \'{}\' excitation of type \'{}\', however, this is inconsistent with the occupations in detlist \'{}\'.\nPlease check your input.'.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 \'{}\', however, this is inconsistent with the occupations in detlist \'{}\'.\nPlease check your input.'.format(spinchan,exc_input[1],occ) + msg='WARNING: You requested \'{}\' excitation of type \'{}\', however, this is inconsistent with the occupations in detlist \'{}\'.\nPlease check your input.'.format(spin_channel,exc_input[1],occ) exc_failure = True #end if - #end if - elif exc_input[1] == 'lowest': - + #end if + if exc_failure: + self.warn(msg) + filename = self.identifier+'_errors.txt' + open(os.path.join(self.locdir,filename),'w').write(msg) #end if - # exc_input interpretation code - # if multidet - # wf = self.input.get('wavefunction') - # exc checking code based on edata - # if problems - # msg = '' - # self.warn(msg) - # filename = self.identifier+'_errors.txt' - # open(os.path.join(self.lodcir,filename),'w').write(msg) #end if #end if #end def post_analyze @@ -703,7 +700,7 @@ def read_einspline_dat(self): if fspin==0: spinlab = 'up' else: - spinlab = 'dn' + spinlab = 'down' #end if edata[spinlab] = obj() with open(einpath) as f: diff --git a/nexus/lib/qmcpack_input.py b/nexus/lib/qmcpack_input.py index 381e7b00f4..007a4873ae 100644 --- a/nexus/lib/qmcpack_input.py +++ b/nexus/lib/qmcpack_input.py @@ -4794,36 +4794,21 @@ def generate_determinantset_old(type = 'bspline', dset.slaterdeterminant.delay_rank = delay_rank #end if if excitation is not None: - print('SET UP EXCITATION') format_failed = False if not isinstance(excitation,(tuple,list)): QmcpackInput.class_error('excitation must be a tuple or list\nyou provided type: {0}\nwith value: {1}'.format(excitation.__class__.__name__,excitation)) elif excitation[0] not in ('up','down','singlet','triplet') or not isinstance(excitation[1],str): format_failed = True else: - #There are three types of input: - #1. excitation=['up','0 45 3 46'] - #2. excitation=['up','-215 216'] - #3. excitation=['up', 'L vb F cb'] - #4. excitation=['up', 'homo lumo'] OR excitation=['up', 'homo-N lumo+M'] + # There are three types of input: + # 1. excitation=['up','0 45 3 46'] + # 2. excitation=['up','-215 216'] + # 3. excitation=['up', 'L vb F cb'] + # 4. excitation=['up', 'lowest'] + # Note: Any of the types can use up or down for the first element. + # Type 2 and 4 can also use singlet and triplet for the first element. if len(excitation) == 2: #Type 1, 2, 3, or 4 - if 'homo' in excitation[1] and 'lumo' in excitation[1]: - #print(system) - #print('=================================== SELF ========================================') - #print(self) - #quit() - print('HERE') - try: - tmp = array(excitation[1].split(),dtype=str) - if (tmp[0][:4]!='homo' or tmp[1][:4]!='lumo') or (not is_int(tmp[0][4:]) or not is_int(tmp[1][4:])): - format_failed = True - #end if - except: - format_failed = True - #end try - #print(format_failed) - #quit() - elif 'cb' not in excitation[1] and 'vb' not in excitation[1]: + if 'cb' not in excitation[1] and 'vb' not in excitation[1] and 'lowest' not in excitation[1]: try: tmp = array(excitation[1].split(),dtype=int) except: @@ -4846,7 +4831,9 @@ def generate_determinantset_old(type = 'bspline', sdet = dset.get('downdet') elif spin_channel=='singlet' or spin_channel=='triplet': - # Is multi-det WF appropriate? + # Are there an equal number of up and down electrons? + # If no, then exit. Currently, singlet and triplet + # excitations are assumed to have ms = 0. if elns.down_electron.count != elns.up_electron.count: QmcpackInput.class_error('The \'singlet\' and \'triplet\' excitation types currently assume number of up and down electrons is the same for the reference ground state. Otherwise, one should use \'up\' or \'down\' types.\nFor your system: Nup={} and Ndown={}.\nWe plan to expand to additional cases in the future.'.format(elns.up_electron.count,elns.down_electron.count)) #end if @@ -4923,11 +4910,19 @@ def generate_determinantset_old(type = 'bspline', ) ) - if '-' in excitation or '+' in excitation: #Type 2 - # assume excitation of form '-216 +217' - exc_orbs = array(excitation.split(),dtype=int) - exc_orbs[0] *= -1 - nel = elns.up_electron.count + if 'cb' not in excitation and 'vb' not in excitation and (len(excitation.split())==2 or excitation=='lowest'): + # Type 2 or Type 4 + + nup = elns.up_electron.count + if excitation=='lowest': + # Type 4 + exc_orbs = [nup,nup+1] + else: + # Type 2 + # assume excitation of form '-216 +217' or '-216 217' + exc_orbs = array(excitation.split(),dtype=int) + exc_orbs[0] *= -1 + #end if for sp in dset.sposets: sp.size=exc_orbs[1] @@ -4935,18 +4930,20 @@ def generate_determinantset_old(type = 'bspline', dset.multideterminant.detlist.nstates = exc_orbs[1] - dset.multideterminant.detlist.csf.occ = '2'*nel+'0'*(exc_orbs[1]-nel-1)+'1' + dset.multideterminant.detlist.csf.occ = '2'*nup+'0'*(exc_orbs[1]-nup-1)+'1' dset.multideterminant.detlist.csf.occ = dset.multideterminant.detlist.csf.occ[:exc_orbs[0]-1]+'1'+dset.multideterminant.detlist.csf.occ[exc_orbs[0]:] - dset.multideterminant.detlist.csf.dets[0].alpha = '1'*(exc_orbs[0]-1)+'0'+'1'*(nel-exc_orbs[0])+'0'*(exc_orbs[1]-nel-1)+'1' - dset.multideterminant.detlist.csf.dets[0].beta = '1'*nel+'0'*(exc_orbs[1]-nel) + dset.multideterminant.detlist.csf.dets[0].alpha = '1'*(exc_orbs[0]-1)+'0'+'1'*(nup-exc_orbs[0])+'0'*(exc_orbs[1]-nup-1)+'1' + dset.multideterminant.detlist.csf.dets[0].beta = '1'*nup+'0'*(exc_orbs[1]-nup) - dset.multideterminant.detlist.csf.dets[1].alpha = '1'*nel+'0'*(exc_orbs[1]-nel) - dset.multideterminant.detlist.csf.dets[1].beta = '1'*(exc_orbs[0]-1)+'0'+'1'*(nel-exc_orbs[0])+'0'*(exc_orbs[1]-nel-1)+'1' + dset.multideterminant.detlist.csf.dets[1].alpha = '1'*nup+'0'*(exc_orbs[1]-nup) + dset.multideterminant.detlist.csf.dets[1].beta = '1'*(exc_orbs[0]-1)+'0'+'1'*(nup-exc_orbs[0])+'0'*(exc_orbs[1]-nup-1)+'1' - elif 'cb' not in excitation and 'vb' not in excitation: #Type 1 + elif 'cb' not in excitation and 'vb' not in excitation: + # Type 1 QmcpackInput.class_error('{} excitation is not yet available for band type'.format(spin_channel)) - else: + else: + # Type 3 QmcpackInput.class_error('{} excitation is not yet available for type 3'.format(spin_channel)) #end if return dset @@ -5038,6 +5035,15 @@ def generate_determinantset_old(type = 'bspline', elif '-' in excitation or '+' in excitation: #Type 2 # assume excitation of form '-216 +217' occ.format = 'energy' + elif excitation=='lowest': # Type 4 + occ.format = 'energy' + if spin_channel=='up': + nel = elns.up_electron.count + else: + nel = elns.down_electron.count + #end if + excitation = '-{} +{}'.format(nel,nel+1) + occ.contents = '\n'+excitation+'\n' else: #Type 1 # assume excitation of form '6 36 6 37' occ.format = 'band' From 485795d0f7ab15531849951a70440f6e01ebc2cf Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Tue, 23 Nov 2021 10:50:23 -0500 Subject: [PATCH 07/35] Cleaning up string definitions --- nexus/lib/qmcpack.py | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index 603395d721..2904a4ca80 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -527,13 +527,19 @@ def post_analyze(self,analyzer): if tw == int(tw1) and bnd == int(bnd1): # This orbital should no longer be in the set of occupied orbitals if idx=self.input.simulation.qmcsystem.particlesets.e.groups[spin_channel[0]].size: - msg='WARNING: You requested \'{}\' excitation of type \'{}\', however, the second orbital \'{} {}\' is not occupied (see einspline file).\nPlease check your input.'.format(spin_channel,exc_input[1],tw2,bnd2) + 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 @@ -563,21 +569,34 @@ def post_analyze(self,analyzer): orb2_eig = sorted(edata[spin_channel]['Energy'])[orb2-1] if orb1_eig not in edata[spin_channel]['Energy'][nelec:]: - msg='WARNING: You requested \'{}\' excitation of type \'{}\', however, the first orbital \'{}\' is still occupied (see einspline file).\nPlease check your input.'.format(spin_channel,exc_input[1],orb1) + 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],orb1) exc_failure = True elif orb2_eig not in edata[spin_channel]['Energy'][:nelec]: - msg='WARNING: You requested \'{}\' excitation of type \'{}\', however, the first orbital \'{}\' is still occupied (see einspline file).\nPlease check your input.'.format(spin_channel,exc_input[1],orb2) + 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],orb2) exc_failure = True + #end if elif exc_input[0] 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 \'{}\', however, this is inconsistent with the occupations in detlist \'{}\'.\nPlease check your input.'.format(spin_channel,exc_input[1],occ) + 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 \'{}\', however, this is inconsistent with the occupations in detlist \'{}\'.\nPlease check your input.'.format(spin_channel,exc_input[1],occ) + 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 From e30fe9b6b832d9805d25c1a533ff413592cf3feb Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Tue, 23 Nov 2021 11:29:09 -0500 Subject: [PATCH 08/35] Small mod --- nexus/lib/qmcpack_input.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nexus/lib/qmcpack_input.py b/nexus/lib/qmcpack_input.py index 007a4873ae..89fa0f2b8c 100644 --- a/nexus/lib/qmcpack_input.py +++ b/nexus/lib/qmcpack_input.py @@ -4995,7 +4995,11 @@ def generate_determinantset_old(type = 'bspline', band_1, band_2 = bands # Convert k_1 k_2 to wavevector indexes - structure = system.structure.folded_structure.copy() + if system.structure.has_folded(): + structure = system.structure.folded_structure.copy() + else: + structure = system.structure.copy() + #end if structure.change_units('A') kpath = get_kpath(structure=structure) kpath_label = array(kpath['explicit_kpoints_labels']) From ac39210fc88899a504444b9a148b1a943bb11cac Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Tue, 23 Nov 2021 12:00:20 -0500 Subject: [PATCH 09/35] Add last format --- nexus/lib/qmcpack.py | 92 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index 2904a4ca80..ee830212f1 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -601,6 +601,98 @@ def post_analyze(self,analyzer): #end if #end if + else: + # The format is: 'gamma vb z cb' + if exc_input[0] 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 = exc_input[1].upper().split(' ') + k_1, band_1, k_2, band_2 = excitation + tilematrix = self.input.get('structure').tilematrix() + quit() + + if exc_input[0]=='up': + sdet = wf.determinantset.get('updet') + else; + sdet = wf.determinantset.get('downdet') + #end if + 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): + 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 + if system.structure.has_folded(): + structure = system.structure.folded_structure.copy() + else: + structure = system.structure.copy() + #end if + structure.change_units('A') + 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 = nscf.input.k_points.kpoints + 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 + + #Write everything in band (ti,bi) format + occ.contents = '\n'+str(k_1)+' '+str(band_1)+' '+str(k_2)+' '+str(band_2)+'\n' + occ.format = 'band' + + #end if + #end if if exc_failure: From e9c44e212d00c3d905670f7a6cd1ebf9bb12f6c6 Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Tue, 23 Nov 2021 12:01:48 -0500 Subject: [PATCH 10/35] Typo --- nexus/lib/qmcpack.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index ee830212f1..a5152de48b 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -615,7 +615,7 @@ def post_analyze(self,analyzer): if exc_input[0]=='up': sdet = wf.determinantset.get('updet') - else; + else: sdet = wf.determinantset.get('downdet') #end if vb = int(sdet.size / abs(linalg.det(tilematrix))) -1 # Separate for each spin channel From 5366254b33910281cf9ae7b823c27820e25a9b2a Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Tue, 23 Nov 2021 12:06:04 -0500 Subject: [PATCH 11/35] Small change --- nexus/lib/qmcpack.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index a5152de48b..2673732aff 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -610,7 +610,7 @@ def post_analyze(self,analyzer): # assume excitation of form 'gamma vb k cb' or 'gamma vb-1 k cb+1' excitation = exc_input[1].upper().split(' ') k_1, band_1, k_2, band_2 = excitation - tilematrix = self.input.get('structure').tilematrix() + tilematrix = self.system.structure.tilematrix() quit() if exc_input[0]=='up': From c93bddab27b5ade93a38fcb3875f67ee98fcd4d1 Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Tue, 23 Nov 2021 12:08:04 -0500 Subject: [PATCH 12/35] Test --- nexus/lib/qmcpack.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index 2673732aff..e7a5fc1901 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -611,7 +611,6 @@ def post_analyze(self,analyzer): excitation = exc_input[1].upper().split(' ') k_1, band_1, k_2, band_2 = excitation tilematrix = self.system.structure.tilematrix() - quit() if exc_input[0]=='up': sdet = wf.determinantset.get('updet') @@ -688,8 +687,11 @@ def post_analyze(self,analyzer): #end if #Write everything in band (ti,bi) format - occ.contents = '\n'+str(k_1)+' '+str(band_1)+' '+str(k_2)+' '+str(band_2)+'\n' - occ.format = 'band' + print() + print('\n'+str(k_1)+' '+str(band_1)+' '+str(k_2)+' '+str(band_2)+'\n') + quit() + #occ.contents = '\n'+str(k_1)+' '+str(band_1)+' '+str(k_2)+' '+str(band_2)+'\n' + #occ.format = 'band' #end if From fe87a92bacd6569e0b99fc554c18d2791bc7c02d Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Tue, 23 Nov 2021 12:09:46 -0500 Subject: [PATCH 13/35] Small change --- nexus/lib/qmcpack.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index e7a5fc1901..493ab71b55 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -612,6 +612,7 @@ def post_analyze(self,analyzer): k_1, band_1, k_2, band_2 = excitation tilematrix = self.system.structure.tilematrix() + wf = self.input.get('wavefunction') if exc_input[0]=='up': sdet = wf.determinantset.get('updet') else: From b9052d17f7b01f375c56dd6d39541bfed8c598de Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Tue, 23 Nov 2021 12:11:23 -0500 Subject: [PATCH 14/35] Small change --- nexus/lib/qmcpack.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index 493ab71b55..5f5e8cc787 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -618,6 +618,7 @@ def post_analyze(self,analyzer): else: sdet = wf.determinantset.get('downdet') #end if + from numpy import linalg 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 From a8db912602ce953a86b387b7dbf7e574eadc9593 Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Tue, 23 Nov 2021 12:12:26 -0500 Subject: [PATCH 15/35] Small change --- nexus/lib/qmcpack.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index 5f5e8cc787..783f70a7b4 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -651,10 +651,10 @@ def post_analyze(self,analyzer): band_1, band_2 = bands # Convert k_1 k_2 to wavevector indexes - if system.structure.has_folded(): - structure = system.structure.folded_structure.copy() + if self.system.structure.has_folded(): + structure = self.system.structure.folded_structure.copy() else: - structure = system.structure.copy() + structure = self.system.structure.copy() #end if structure.change_units('A') kpath = get_kpath(structure=structure) From 5b6dfc0088f5aff3046375c4345d95b839c87524 Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Tue, 23 Nov 2021 12:13:43 -0500 Subject: [PATCH 16/35] Small change --- nexus/lib/qmcpack.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index 783f70a7b4..a29ccfb7cf 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -657,6 +657,8 @@ def post_analyze(self,analyzer): structure = self.system.structure.copy() #end if 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'] From cccfb5cab40d2c3431c80dcf6bb7bc279e924106 Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Tue, 23 Nov 2021 12:15:00 -0500 Subject: [PATCH 17/35] Small change --- nexus/lib/qmcpack.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index a29ccfb7cf..844e42075e 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -618,7 +618,7 @@ def post_analyze(self,analyzer): else: sdet = wf.determinantset.get('downdet') #end if - from numpy import linalg + from numpy import linalg,where 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 From f06fd718d5bb0767c3eafff45dd3d37b1c3d5490 Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Tue, 23 Nov 2021 12:15:50 -0500 Subject: [PATCH 18/35] Yet Another Small change --- nexus/lib/qmcpack.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index 844e42075e..cbffade955 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -618,7 +618,7 @@ def post_analyze(self,analyzer): else: sdet = wf.determinantset.get('downdet') #end if - from numpy import linalg,where + 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 From 5a9b6bc8396f83542af1af13a32639ee8828ff4f Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Tue, 23 Nov 2021 12:19:41 -0500 Subject: [PATCH 19/35] Wrap up last check --- nexus/lib/qmcpack.py | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index cbffade955..4c49973147 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -690,14 +690,36 @@ def post_analyze(self,analyzer): 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 - #Write everything in band (ti,bi) format - print() - print('\n'+str(k_1)+' '+str(band_1)+' '+str(k_2)+' '+str(band_2)+'\n') + print("WE ARE CHECKING THE LAST CASE") + tw1,bnd1 = (k_1,band_1) + tw2,bnd2 = (k_2,band_2) + spin_channel = exc_input[0] + for idx,(tw,bnd) in enumerate(zip(edata[spin_channel]['TwistIndex'],edata[spin_channel]['BandIndex'])): + if tw == int(tw1) and bnd == int(bnd1): + # This orbital should no longer be in the set of occupied orbitals + if idx=self.input.simulation.qmcsystem.particlesets.e.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 + + + print('DID IT FAIL?') + print(exc_failure) quit() - #occ.contents = '\n'+str(k_1)+' '+str(band_1)+' '+str(k_2)+' '+str(band_2)+'\n' - #occ.format = 'band' - - #end if #end if From 60658bec33d26e2cdf09a87f9a130f13221b8dce Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Tue, 23 Nov 2021 12:21:02 -0500 Subject: [PATCH 20/35] Ready to submit --- nexus/lib/qmcpack.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index 4c49973147..3dc0b52347 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -690,7 +690,6 @@ def post_analyze(self,analyzer): 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 - print("WE ARE CHECKING THE LAST CASE") tw1,bnd1 = (k_1,band_1) tw2,bnd2 = (k_2,band_2) spin_channel = exc_input[0] @@ -716,11 +715,6 @@ def post_analyze(self,analyzer): #end if #end for - - print('DID IT FAIL?') - print(exc_failure) - quit() - #end if if exc_failure: From e256efefc6cf320963999c4b244be09e4416269b Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Mon, 29 Nov 2021 09:03:13 -0500 Subject: [PATCH 21/35] Add excitation alternatives examples --- .../excited/vmc_excitation_alternatives.py | 355 ++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100755 nexus/examples/qmcpack/rsqmc_misc/excited/vmc_excitation_alternatives.py diff --git a/nexus/examples/qmcpack/rsqmc_misc/excited/vmc_excitation_alternatives.py b/nexus/examples/qmcpack/rsqmc_misc/excited/vmc_excitation_alternatives.py new file mode 100755 index 0000000000..a916c7e283 --- /dev/null +++ b/nexus/examples/qmcpack/rsqmc_misc/excited/vmc_excitation_alternatives.py @@ -0,0 +1,355 @@ +#! /usr/bin/env python3 + +from nexus import settings,job,run_project +from nexus import generate_physical_system +from nexus import generate_pwscf +from nexus import generate_pw2qmcpack +from nexus import generate_qmcpack,vmc +from structure import * + +''' +This nexus example shows a variety of ways that excitations can be specified. +''' + +settings( + pseudo_dir = '../../pseudopotentials', + runs = './runs_excitation_alternatives' + status_only = 0, + generate_only = 0, + sleep = 3, + machine = 'ws16' + ) + +#Input structure +dia = generate_physical_system( + units = 'A', + axes = [[ 1.785, 1.785, 0. ], + [ 0. , 1.785, 1.785], + [ 1.785, 0. , 1.785]], + elem = ['C','C'], + pos = [[ 0. , 0. , 0. ], + [ 0.8925, 0.8925, 0.8925]], + C = 4 + ) + +kg = dia.structure.kgrid_from_kspacing(0.3) # Get SCF kmesh from k-spacing + +scf = generate_pwscf( + identifier = 'scf', + path = 'diamond/scf', + job = job(nodes=1,app='pw.x',hours=1), + input_type = 'generic', + calculation = 'scf', + nspin = 2, + input_dft = 'lda', + ecutwfc = 200, + conv_thr = 1e-8, + nosym = False, + wf_collect = False, + system = dia, + tot_magnetization = 0, + kgrid = kg, + kshift = (0,0,0), + pseudos = ['C.BFD.upf'], + ) + +nscf = generate_pwscf( + identifier = 'nscf', + path = 'diamond/nscf', + job = job(nodes=1,app='pw.x',hours=1), + input_type = 'generic', + calculation = 'nscf', + input_dft = 'lda', + ecutwfc = 200, + nspin = 2, + conv_thr = 1e-8, + nosym = True, + wf_collect = True, + system = dia, + nbnd = 8, #a sensible nbnd value can be given + verbosity = 'high', #verbosity must be set to high + pseudos = ['C.BFD.upf'], + dependencies = (scf,'charge_density'), + ) + +conv = generate_pw2qmcpack( + identifier = 'conv', + path = 'diamond/nscf', + job = job(cores=1,app='pw2qmcpack.x', hours = 1), + write_psir = False, + dependencies = (nscf,'orbitals'), + ) + +opt = generate_qmcpack( + identifier = 'opt', + path = 'diamond/opt', + job = job(cores=16,threads=16,app='qmcpack', hours = 1), + input_type = 'basic', + system = dia, + pseudos = ['C.BFD.xml'], + twistnum = 0, + J2 = True, # Add a 2-body B-spline Jastrow + spin_polarized = True, + qmc = 'opt', # Do a wavefunction optimization + minmethod = 'oneshift', # Optimization algorithm (assumes energy minimization) + init_cycles = 4, # First 4 iterations allow large parameter changes + cycles = 10, # 8 subsequent iterations with smaller parameter changes + warmupsteps = 8, # First 8 steps are not recorded + blocks = 100, # Number of blocks to write in the .scalar.dat file + timestep = 0.4, # MC step size (nothing to do with time for VMC) + init_minwalkers = 0.01, # Smaller values -> bigger parameter change + minwalkers = 0.5, # + samples = 5000, # VMC samples per iteration + use_nonlocalpp_deriv = False, + dependencies = (conv,'orbitals'), + ) + +################################################################################ +############ Ground State at Gamma ############################################# +################################################################################ +qmc_ground = generate_qmcpack( + det_format = 'old', + identifier = 'vmc', + path = 'diamond/vmc_ground', + job = job(cores=16,threads=16,app='qmcpack', hours = 1), + input_type = 'basic', + spin_polarized = True, + twistnum = 0, + system = dia, + pseudos = ['C.BFD.xml'], + jastrows = [], + calculations = [ + vmc( + warmupsteps = 20, + blocks = 2400, + steps = 25, + substeps = 2, + timestep = .4, + ) + ], + dependencies = [(conv,'orbitals'), + (opt,'jastrow')], + ) + +################################################################################ +############ Single Determinant Excitations #################################### +################################################################################ + +# up channel, gamma vb gamma cb +qmc_optical = generate_qmcpack( + det_format = 'old', + identifier = 'vmc', + path = 'diamond/vmc_optical_up_g-vb-g-cb', + job = job(cores=16,threads=16,app='qmcpack', hours = 1), + input_type = 'basic', + spin_polarized = True, + system = dia, + twistnum = 0, + excitation = ['up', 'gamma vb gamma cb'], + pseudos = ['C.BFD.xml'], + jastrows = [], + calculations = [ + vmc( + warmupsteps = 20, + blocks = 2400, + steps = 25, + substeps = 2, + timestep = .4, + ) + ], + dependencies = [(conv,'orbitals'), + (opt,'jastrow')], + ) + +# up channel, band index +qmc_optical = generate_qmcpack( + det_format = 'old', + identifier = 'vmc', + path = 'diamond/vmc_optical_up_band-index', + job = job(cores=16,threads=16,app='qmcpack', hours = 1), + input_type = 'basic', + spin_polarized = True, + system = dia, + twistnum = 0, + excitation = ['up', '0 3 0 4'], + pseudos = ['C.BFD.xml'], + jastrows = [], + calculations = [ + vmc( + warmupsteps = 20, + blocks = 2400, + steps = 25, + substeps = 2, + timestep = .4, + ) + ], + dependencies = [(conv,'orbitals'), + (opt,'jastrow')], + ) + +# up channel, energy index +qmc_optical = generate_qmcpack( + det_format = 'old', + identifier = 'vmc', + path = 'diamond/vmc_optical_up_energy-index', + job = job(cores=16,threads=16,app='qmcpack', hours = 1), + input_type = 'basic', + spin_polarized = True, + system = dia, + twistnum = 0, + excitation = ['up', '-4 +5'], + pseudos = ['C.BFD.xml'], + jastrows = [], + calculations = [ + vmc( + warmupsteps = 20, + blocks = 2400, + steps = 25, + substeps = 2, + timestep = .4, + ) + ], + dependencies = [(conv,'orbitals'), + (opt,'jastrow')], + ) + +# up channel, lowest index +qmc_optical = generate_qmcpack( + skip_submit = 0, + det_format = 'old', + identifier = 'vmc', + path = 'diamond/vmc_optical_up_lowest', + job = job(cores=16,threads=16,app='qmcpack', hours = 1), + input_type = 'basic', + spin_polarized = True, + system = dia, + twistnum = 0, + excitation = ['up', 'lowest'], + pseudos = ['C.BFD.xml'], + jastrows = [], + calculations = [ + vmc( + warmupsteps = 20, + blocks = 2400, + steps = 25, + substeps = 2, + timestep = .4, + ) + ], + dependencies = [(conv,'orbitals'), + (opt,'jastrow')], + ) + +################################################################################ +############ Triplet Excitations ############################################### +################################################################################ + +# triplet, energy index +qmc_optical = generate_qmcpack( + det_format = 'old', + identifier = 'vmc', + path = 'diamond/vmc_optical_triplet_energy-index', + job = job(cores=16,threads=16,app='qmcpack', hours = 1), + input_type = 'basic', + spin_polarized = True, + system = dia, + twistnum = 0, + excitation = ['triplet', '-4 +5'], + pseudos = ['C.BFD.xml'], + jastrows = [], + calculations = [ + vmc( + warmupsteps = 20, + blocks = 2400, + steps = 25, + substeps = 2, + timestep = .4, + ) + ], + dependencies = [(conv,'orbitals'), + (opt,'jastrow')], + ) + +# triplet, lowest +qmc_optical = generate_qmcpack( + det_format = 'old', + identifier = 'vmc', + path = 'diamond/vmc_optical_triplet_lowest', + job = job(cores=16,threads=16,app='qmcpack', hours = 1), + input_type = 'basic', + spin_polarized = True, + system = dia, + twistnum = 0, + excitation = ['triplet', 'lowest'], + pseudos = ['C.BFD.xml'], + jastrows = [], + calculations = [ + vmc( + warmupsteps = 20, + blocks = 2400, + steps = 25, + substeps = 2, + timestep = .4, + ) + ], + dependencies = [(conv,'orbitals'), + (opt,'jastrow')], + ) + +################################################################################ +############ Singlet Excitations ############################################### +################################################################################ + +# singlet, energy index +qmc_optical = generate_qmcpack( + det_format = 'old', + identifier = 'vmc', + path = 'diamond/vmc_optical_singlet_energy-index', + job = job(cores=16,threads=16,app='qmcpack', hours = 1), + input_type = 'basic', + spin_polarized = True, + system = dia, + twistnum = 0, + excitation = ['singlet', '-4 +5'], + pseudos = ['C.BFD.xml'], + jastrows = [], + calculations = [ + vmc( + warmupsteps = 20, + blocks = 2400, + steps = 25, + substeps = 2, + timestep = .4, + ) + ], + dependencies = [(conv,'orbitals'), + (opt,'jastrow')], + ) + +# singlet, lowest +qmc_optical = generate_qmcpack( + det_format = 'old', + identifier = 'vmc', + path = 'diamond/vmc_optical_singlet_lowest', + job = job(cores=16,threads=16,app='qmcpack', hours = 1), + input_type = 'basic', + spin_polarized = True, + system = dia, + twistnum = 0, + excitation = ['singlet', 'lowest'], + pseudos = ['C.BFD.xml'], + jastrows = [], + calculations = [ + vmc( + warmupsteps = 20, + blocks = 2400, + steps = 25, + substeps = 2, + timestep = .4, + ) + ], + dependencies = [(conv,'orbitals'), + (opt,'jastrow')], + ) + +run_project() From ea1f36dbfd858d4b0ed8cd2d7d22c3d85ad21ad3 Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Mon, 29 Nov 2021 09:23:37 -0500 Subject: [PATCH 22/35] CHecking .rst rendering --- nexus/sphinx_docs/examples.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/nexus/sphinx_docs/examples.rst b/nexus/sphinx_docs/examples.rst index 559d2de0cd..be82ec1ef8 100644 --- a/nexus/sphinx_docs/examples.rst +++ b/nexus/sphinx_docs/examples.rst @@ -1498,7 +1498,7 @@ The files for this example are found in: .. code:: rest - /your_download_path/nexus/examples/qmcpack/excited + /your_download_path/nexus/examples/qmcpack/rsqmc_misc/excited Please study `Lab 5`_ in QMCPACK manual for an in-depth discussion of the excited states calculations. The primitive cell for a structure is not @@ -1516,9 +1516,13 @@ optical excitations. Compared to the ground state bulk calculations, a tiling matrix that is commensurate with the wavevectors involved in the excitation must be chosen. This process has been automatized in Nexus using the "get_band_tiling" function. There are two VMC scripts in this -lab: ``vmc.py`` script uses a non-optimal tiling matrix from Lab 5 in -QMCPACK, whereas ``vmc-opt-tiling.py`` uses the "get_band_tiling" -function. In this example, we will use ``vmc-opt-tiling.py``. +lab that generate the tiling matrix in different ways: ``vmc.py`` script +uses a non-optimal tiling matrix from Lab 5 in QMCPACK, whereas +``vmc-opt-tiling.py`` uses the "get_band_tiling" function. In this +example, we will use ``vmc-opt-tiling.py``. Note, there is also an +additional VMC script included ``vmc_excitation_alternatives.py`` which +does not use a tiling matrix but includes a variety of ways that +excitations can be specified. In `Lab 5 `_ of the QMCPACK manual we found that VBM is located at :math:`\Gamma` and the CBM is located at :math:`\Delta` ([0.377, 0., From 6f48b8e84d1863621af5c1b64f0834519e2a5034 Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Mon, 29 Nov 2021 09:34:16 -0500 Subject: [PATCH 23/35] Checking .rst rendering --- nexus/sphinx_docs/examples.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/nexus/sphinx_docs/examples.rst b/nexus/sphinx_docs/examples.rst index be82ec1ef8..024f4c26e2 100644 --- a/nexus/sphinx_docs/examples.rst +++ b/nexus/sphinx_docs/examples.rst @@ -1522,7 +1522,7 @@ uses a non-optimal tiling matrix from Lab 5 in QMCPACK, whereas example, we will use ``vmc-opt-tiling.py``. Note, there is also an additional VMC script included ``vmc_excitation_alternatives.py`` which does not use a tiling matrix but includes a variety of ways that -excitations can be specified. +excitations can be specified with Nexus. In `Lab 5 `_ of the QMCPACK manual we found that VBM is located at :math:`\Gamma` and the CBM is located at :math:`\Delta` ([0.377, 0., @@ -1546,6 +1546,11 @@ k-point grid density in one dimension. "excitation = [’up’, ’-11 +12’]". Band/twist index and energy indexes of the orbitals can be found in "einspline" files or they can be determined after parsing the "nscf.out" file using PwscfAnalyzer. + In addition to these options, "excitation = ['up','lowest']" can also + be specified which will execute a homo-lumo excitation based on the + energetic ordering of the orbitals. Nexus also allows singlet and + triplet excitation types. Please refer to ``vmc_excitation_alternatives.py`` + for examples using the various excitation types. Examples on how to do are provided in Lab 5 of the QMCPACK manual. :: @@ -1699,3 +1704,4 @@ k-point grid density in one dimension. ) run_project(scf,nscf,conv,qmc) + From 2869889049544a01e2ce304d064d220194d3c63b Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Mon, 29 Nov 2021 11:40:15 -0500 Subject: [PATCH 24/35] Add function to check excitation format --- nexus/lib/qmcpack_input.py | 98 ++++++++++++++++++++++++++++++++++ nexus/sphinx_docs/examples.rst | 2 +- 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/nexus/lib/qmcpack_input.py b/nexus/lib/qmcpack_input.py index 89fa0f2b8c..42b13b8a44 100644 --- a/nexus/lib/qmcpack_input.py +++ b/nexus/lib/qmcpack_input.py @@ -4727,6 +4727,104 @@ def generate_determinantset(up = 'u', #end def generate_determinantset +def check_excitation_type(excitation): + + # Possible spin channels or spin states + exc_spins = obj( + up = 1, # 'up' + down = 2, # 'down' + singlet = 3, # 'singlet' + triplet = 4, # 'triplet' + ) + # Possible orbital excitation types + exc_types = obj( + band = 1, # '0 45 3 46' # Type 1 + energy = 2, # '-215 +216' # Type 2 + kpoint = 3, # 'L vb F cb' # Type 3 + lowest = 4, # 'lowest' # Type 4 + ) + + exc_spin = None + exc_type = None + + # Check that 'excitation' is correctly formated + format_failed = False + # Extract elements form excitation + if not isinstance(excitation,(tuple,list)) or len(excitation) != 2: + format_failed = True + else: + exc1,exc2 = excitation + if not isinstance(exc1,str) or not isinstance(exc2,str): + format_failed = True + #end if + #end if + + # Check first element + if not format_failed: + if exc1.lower() not in ('up','down','singlet','triplet'): + format_failed = True + else: + exc_spin = exc_spins[exc1.lower()] + #end if + #end if + + # Check second element + if not format_failed: + if any(substr in exc2.lower() for substr in ('vb','cb','lowest')): + if exc2.lower()=='lowest': + exc_type = exc_types.lowest + elif len(exc2.split())!=4: + format_failed = True + else: + exc_type = exc_types.kpoint + #end if + else: + tmp = None + try: + tmp = array(exc2.split(),dtype=int) + except: + format_failed = True + #end try + if tmp not None: + if len(tmp)==4: + # '0 45 3 46' + if not tmp[0]>=0 or not tmp[1]>=0 or not tmp[2]>=0 or not tmp[3]>=0: + format_failed = True + #end if + exc_type = exc_types.band + elif len(tmp)==2: + # '-215 +216' + if not tmp[0]<0 or not tmp[1]>0: + format_failed = True + #end if + exc_type = exc_types.energy + else: + format_failed = True + #end if + #end if + #end if + #end if + + if format_failed: + + msg = 'excitation must be a tuple or list with with two elements.\n' + msg += 'The first element must be either "up", "down", "singlet", or "triplet"\n' + msg += 'and the second element must be a band format (e.g. "0 45 3 46"),\n' + msg += 'energy format (e.g. "-215 +216"), kpoint format (e.g. "L vb F cb"),\n' + msg += 'or lowest format (e.g. "lowest").\n' + msg += 'You Provided: {0}' + msg = msg.format(excitation) + + QmcpackInput.class_error(msg) + + #end if + + return exc_spin,exc_type,exc_spins,exc_types + + +#end def check_excitation_type + + def generate_determinantset_old(type = 'bspline', meshfactor = 1.0, precision = 'float', diff --git a/nexus/sphinx_docs/examples.rst b/nexus/sphinx_docs/examples.rst index 024f4c26e2..b636e01444 100644 --- a/nexus/sphinx_docs/examples.rst +++ b/nexus/sphinx_docs/examples.rst @@ -1551,7 +1551,7 @@ k-point grid density in one dimension. energetic ordering of the orbitals. Nexus also allows singlet and triplet excitation types. Please refer to ``vmc_excitation_alternatives.py`` for examples using the various excitation types. - Examples on how to do are provided in Lab 5 of the QMCPACK manual. + Examples are also provided in Lab 5 of the QMCPACK manual. :: From be96436ac5faf2957319e2fe27c89dfe925e0f93 Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Mon, 29 Nov 2021 11:42:55 -0500 Subject: [PATCH 25/35] Small change --- nexus/lib/qmcpack_input.py | 32 ++------------------------------ 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/nexus/lib/qmcpack_input.py b/nexus/lib/qmcpack_input.py index 42b13b8a44..a81a2b7507 100644 --- a/nexus/lib/qmcpack_input.py +++ b/nexus/lib/qmcpack_input.py @@ -4892,37 +4892,9 @@ def generate_determinantset_old(type = 'bspline', dset.slaterdeterminant.delay_rank = delay_rank #end if if excitation is not None: - format_failed = False - if not isinstance(excitation,(tuple,list)): - QmcpackInput.class_error('excitation must be a tuple or list\nyou provided type: {0}\nwith value: {1}'.format(excitation.__class__.__name__,excitation)) - elif excitation[0] not in ('up','down','singlet','triplet') or not isinstance(excitation[1],str): - format_failed = True - else: - # There are three types of input: - # 1. excitation=['up','0 45 3 46'] - # 2. excitation=['up','-215 216'] - # 3. excitation=['up', 'L vb F cb'] - # 4. excitation=['up', 'lowest'] - # Note: Any of the types can use up or down for the first element. - # Type 2 and 4 can also use singlet and triplet for the first element. - if len(excitation) == 2: #Type 1, 2, 3, or 4 - if 'cb' not in excitation[1] and 'vb' not in excitation[1] and 'lowest' not in excitation[1]: - try: - tmp = array(excitation[1].split(),dtype=int) - except: - format_failed = True - #end try - #end if - else: - format_failed = True - #end if - #end if - if format_failed: - #Should be modified - QmcpackInput.class_error('excitation must be a tuple or list with with two elements\nthe first element must be either "up" or "down"\nand the second element must be integers separated by spaces, e.g. "-216 +217"\nyou provided: {0}'.format(excitation)) - #end if - spin_channel,excitation = excitation + exc_spin,exc_type,exc_spins,exc_types = check_excitation_type(excitation) + if spin_channel=='up': sdet = dset.get('updet') elif spin_channel=='down': From cd8d460b53734412eafc6a8aaabb2e86cb634c57 Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Mon, 29 Nov 2021 14:20:30 -0500 Subject: [PATCH 26/35] Nearly finished --- nexus/lib/qmcpack.py | 36 ++++++++++++++++++--------------- nexus/lib/qmcpack_input.py | 41 ++++++++++++++++++-------------------- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index 3dc0b52347..ab1d53e728 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -36,6 +36,7 @@ from qmcpack_input import loop,linear,cslinear,vmc,dmc,collection,determinantset,hamiltonian,init,pairpot,bspline_builder from qmcpack_input import generate_jastrows,generate_jastrow,generate_jastrow1,generate_jastrow2,generate_jastrow3 from qmcpack_input import generate_opt,generate_opts +from qmcpack_input import check_excitation_type from qmcpack_analyzer import QmcpackAnalyzer from qmcpack_converters import Pw2qmcpack,Convert4qmc,PyscfToAfqmc from debug import ci,ls,gs @@ -512,17 +513,20 @@ def post_analyze(self,analyzer): #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) - exc_failure = False - if 'cb' not in exc_input[1] and 'vb' not in exc_input[1] and len(exc_input[1].split())==4: + 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 = exc_input[1].split()[0:2] - tw2,bnd2 = exc_input[1].split()[2:4] - if exc_input[0] in ('up','down'): - spin_channel = exc_input[0] + tw1,bnd1 = exc2.split()[0:2] + tw2,bnd2 = exc2.split()[2:4] + if exc1 in ('up','down'): + spin_channel = exc1 for idx,(tw,bnd) in enumerate(zip(edata[spin_channel]['TwistIndex'],edata[spin_channel]['BandIndex'])): if tw == int(tw1) and bnd == int(bnd1): # This orbital should no longer be in the set of occupied orbitals @@ -547,10 +551,10 @@ def post_analyze(self,analyzer): 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 len(exc_input[1].split()) == 2 or exc_input[1]=='lowest': + elif exc_type in (exc_types.energy,exc_types.lowest): # Lowest or Energy Index '-orbindex1 +orbindex2'. Eg., '-4 +5' - if exc_input[1]=='lowest': - if exc_input[0]=='down': + if exc_type==exc_types.lowest: + if exc_spin==exc_spins.down: orb1 = self.input.simulation.qmcsystem.particlesets.e.groups.d.size else: orb1 = self.input.simulation.qmcsystem.particlesets.e.groups.u.size @@ -560,9 +564,9 @@ def post_analyze(self,analyzer): orb1 = int(exc_input[1].split()[0][1:]) orb2 = int(exc_input[1].split()[1][1:]) #end if - if exc_input[0] in ('up','down'): + if exc1 in ('up','down'): - spin_channel = exc_input[0] + spin_channel = exc1 nelec = self.input.simulation.qmcsystem.particlesets.e.groups[spin_channel[0]].size orb1_eig = sorted(edata[spin_channel]['Energy'])[orb1-1] @@ -582,7 +586,7 @@ def post_analyze(self,analyzer): exc_failure = True #end if - elif exc_input[0] in ('singlet','triplet'): + elif exc1 in ('singlet','triplet'): wf = self.input.get('wavefunction') occ = wf.determinantset.multideterminant.detlist.csf.occ if occ[int(orb1)-1]!='1': @@ -603,17 +607,17 @@ def post_analyze(self,analyzer): else: # The format is: 'gamma vb z cb' - if exc_input[0] in ('singlet','triplet'): + 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 = exc_input[1].upper().split(' ') + 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_input[0]=='up': + if exc_spin==exc_spins.up: sdet = wf.determinantset.get('updet') else: sdet = wf.determinantset.get('downdet') @@ -692,7 +696,7 @@ def post_analyze(self,analyzer): tw1,bnd1 = (k_1,band_1) tw2,bnd2 = (k_2,band_2) - spin_channel = exc_input[0] + spin_channel = exc1 for idx,(tw,bnd) in enumerate(zip(edata[spin_channel]['TwistIndex'],edata[spin_channel]['BandIndex'])): if tw == int(tw1) and bnd == int(bnd1): # This orbital should no longer be in the set of occupied orbitals diff --git a/nexus/lib/qmcpack_input.py b/nexus/lib/qmcpack_input.py index a81a2b7507..0b5798b1ce 100644 --- a/nexus/lib/qmcpack_input.py +++ b/nexus/lib/qmcpack_input.py @@ -4819,7 +4819,7 @@ def check_excitation_type(excitation): #end if - return exc_spin,exc_type,exc_spins,exc_types + return exc_spin,exc_type,exc_spins,exc_types,exc1,exc2 #end def check_excitation_type @@ -4893,13 +4893,13 @@ def generate_determinantset_old(type = 'bspline', #end if if excitation is not None: - exc_spin,exc_type,exc_spins,exc_types = check_excitation_type(excitation) + exc_spin,exc_type,exc_spins,exc_types,exc1,exc2 = check_excitation_type(excitation) - if spin_channel=='up': + if exc_spin==exc_spins.up: sdet = dset.get('updet') - elif spin_channel=='down': + elif exc_spin==exc_spins.down: sdet = dset.get('downdet') - elif spin_channel=='singlet' or spin_channel=='triplet': + elif exc_spin in (exc_spins.singlet,exc_spins.triplet): # Are there an equal number of up and down electrons? # If no, then exit. Currently, singlet and triplet @@ -4909,7 +4909,7 @@ def generate_determinantset_old(type = 'bspline', #end if coeff_sign = '' - if spin_channel=='triplet': + if exc_spin==exc_spins.triplet: coeff_sign = '-' #end if @@ -4980,17 +4980,14 @@ def generate_determinantset_old(type = 'bspline', ) ) - if 'cb' not in excitation and 'vb' not in excitation and (len(excitation.split())==2 or excitation=='lowest'): - # Type 2 or Type 4 + if exc_type in (exc_types.energy,exc_types.lowest): nup = elns.up_electron.count - if excitation=='lowest': - # Type 4 + if exc_type==exc_types.lowest: exc_orbs = [nup,nup+1] else: - # Type 2 # assume excitation of form '-216 +217' or '-216 217' - exc_orbs = array(excitation.split(),dtype=int) + exc_orbs = array(exc2.split(),dtype=int) exc_orbs[0] *= -1 #end if @@ -5009,14 +5006,14 @@ def generate_determinantset_old(type = 'bspline', dset.multideterminant.detlist.csf.dets[1].alpha = '1'*nup+'0'*(exc_orbs[1]-nup) dset.multideterminant.detlist.csf.dets[1].beta = '1'*(exc_orbs[0]-1)+'0'+'1'*(nup-exc_orbs[0])+'0'*(exc_orbs[1]-nup-1)+'1' - elif 'cb' not in excitation and 'vb' not in excitation: - # Type 1 - QmcpackInput.class_error('{} excitation is not yet available for band type'.format(spin_channel)) + elif exc_type == exc_types.kpoint: + QmcpackInput.class_error('{} excitation is not yet available for kpoint type'.format(exc1)) else: - # Type 3 - QmcpackInput.class_error('{} excitation is not yet available for type 3'.format(spin_channel)) + QmcpackInput.class_error('{} excitation is not yet available for band type'.format(exc1)) #end if + return dset + #end if occ = sdet.occupation @@ -5024,9 +5021,9 @@ def generate_determinantset_old(type = 'bspline', occ.mode = 'excited' occ.contents = '\n'+excitation+'\n' # add new input format - if 'cb' in excitation or 'vb' in excitation: #Type 3 + if exc_type == exc_types.band: # assume excitation of form 'gamma vb k cb' or 'gamma vb-1 k cb+1' - excitation = excitation.upper().split(' ') + excitation = exc2.upper().split(' ') if len(excitation) == 4: k_1, band_1, k_2, band_2 = excitation else: @@ -5106,12 +5103,12 @@ def generate_determinantset_old(type = 'bspline', occ.contents = '\n'+str(k_1)+' '+str(band_1)+' '+str(k_2)+' '+str(band_2)+'\n' occ.format = 'band' - elif '-' in excitation or '+' in excitation: #Type 2 + elif exc_type == exc_types.energy: # assume excitation of form '-216 +217' occ.format = 'energy' - elif excitation=='lowest': # Type 4 + elif exc_type == exc_types.lowest: # Type 4 occ.format = 'energy' - if spin_channel=='up': + if exc_type == exc_types.up: nel = elns.up_electron.count else: nel = elns.down_electron.count From df87ea04e888f12f7dded9f65a2fdf4dd55b0cb2 Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Mon, 29 Nov 2021 14:24:38 -0500 Subject: [PATCH 27/35] Small typo --- nexus/lib/qmcpack_input.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nexus/lib/qmcpack_input.py b/nexus/lib/qmcpack_input.py index 0b5798b1ce..bfefcb867f 100644 --- a/nexus/lib/qmcpack_input.py +++ b/nexus/lib/qmcpack_input.py @@ -4785,7 +4785,7 @@ def check_excitation_type(excitation): except: format_failed = True #end try - if tmp not None: + if not tmp is None: if len(tmp)==4: # '0 45 3 46' if not tmp[0]>=0 or not tmp[1]>=0 or not tmp[2]>=0 or not tmp[3]>=0: From c5c0bf464b5db011200d1d7bded1db3f91eee53c Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Mon, 29 Nov 2021 14:26:41 -0500 Subject: [PATCH 28/35] Small typo --- nexus/lib/qmcpack_input.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nexus/lib/qmcpack_input.py b/nexus/lib/qmcpack_input.py index bfefcb867f..23affebc5f 100644 --- a/nexus/lib/qmcpack_input.py +++ b/nexus/lib/qmcpack_input.py @@ -5019,7 +5019,7 @@ def generate_determinantset_old(type = 'bspline', occ = sdet.occupation occ.pairs = 1 occ.mode = 'excited' - occ.contents = '\n'+excitation+'\n' + occ.contents = '\n'+exc2+'\n' # add new input format if exc_type == exc_types.band: # assume excitation of form 'gamma vb k cb' or 'gamma vb-1 k cb+1' From 39b8f58d56dffa040eead83ef2df21c5e5dd0ae5 Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Mon, 29 Nov 2021 14:31:59 -0500 Subject: [PATCH 29/35] Small error --- nexus/lib/qmcpack_input.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nexus/lib/qmcpack_input.py b/nexus/lib/qmcpack_input.py index 23affebc5f..ae403045c5 100644 --- a/nexus/lib/qmcpack_input.py +++ b/nexus/lib/qmcpack_input.py @@ -5034,6 +5034,7 @@ def generate_determinantset_old(type = 'bspline', cb = vb+1 # Convert band_1, band_2 to band indexes bands = [band_1, band_2] + print(bands) for bnum, b in enumerate(bands): if 'CB' in b: if '-' in b: From f236fa03965a061473b131f45ad88aee0c36bb19 Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Mon, 29 Nov 2021 15:09:10 -0500 Subject: [PATCH 30/35] Adding get_electron_particle_sets function --- nexus/lib/qmcpack.py | 16 +++++++++------- nexus/lib/qmcpack_input.py | 11 +++++++++-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index ab1d53e728..47a5a6688d 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -519,6 +519,8 @@ def post_analyze(self,analyzer): 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' @@ -530,7 +532,7 @@ def post_analyze(self,analyzer): for idx,(tw,bnd) in enumerate(zip(edata[spin_channel]['TwistIndex'],edata[spin_channel]['BandIndex'])): if tw == int(tw1) and bnd == int(bnd1): # This orbital should no longer be in the set of occupied orbitals - if idx=self.input.simulation.qmcsystem.particlesets.e.groups[spin_channel[0]].size: + 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.' @@ -555,9 +557,9 @@ def post_analyze(self,analyzer): # Lowest or Energy Index '-orbindex1 +orbindex2'. Eg., '-4 +5' if exc_type==exc_types.lowest: if exc_spin==exc_spins.down: - orb1 = self.input.simulation.qmcsystem.particlesets.e.groups.d.size + orb1 = elns.groups.d.size else: - orb1 = self.input.simulation.qmcsystem.particlesets.e.groups.u.size + orb1 = elns.groups.u.size #end if orb2 = orb1+1 else: @@ -567,7 +569,7 @@ def post_analyze(self,analyzer): if exc1 in ('up','down'): spin_channel = exc1 - nelec = self.input.simulation.qmcsystem.particlesets.e.groups[spin_channel[0]].size + nelec = elns.groups[spin_channel[0]].size orb1_eig = sorted(edata[spin_channel]['Energy'])[orb1-1] orb2_eig = sorted(edata[spin_channel]['Energy'])[orb2-1] @@ -700,7 +702,7 @@ def post_analyze(self,analyzer): for idx,(tw,bnd) in enumerate(zip(edata[spin_channel]['TwistIndex'],edata[spin_channel]['BandIndex'])): if tw == int(tw1) and bnd == int(bnd1): # This orbital should no longer be in the set of occupied orbitals - if idx=self.input.simulation.qmcsystem.particlesets.e.groups[spin_channel[0]].size: + 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.' diff --git a/nexus/lib/qmcpack_input.py b/nexus/lib/qmcpack_input.py index ae403045c5..7beb9278b5 100644 --- a/nexus/lib/qmcpack_input.py +++ b/nexus/lib/qmcpack_input.py @@ -3866,6 +3866,13 @@ def incorporate_system(self,system): #end if #end def incorporate_system + def get_electron_particle_set(self): + + input = self.copy() + input.pluralize() + return input.get('particlesets').get_electrons() + + #end def get_electron_particle_set def return_system(self,structure_only=False): input = self.copy() @@ -5021,7 +5028,7 @@ def generate_determinantset_old(type = 'bspline', occ.mode = 'excited' occ.contents = '\n'+exc2+'\n' # add new input format - if exc_type == exc_types.band: + if exc_type == exc_types.kpoint: # assume excitation of form 'gamma vb k cb' or 'gamma vb-1 k cb+1' excitation = exc2.upper().split(' ') if len(excitation) == 4: @@ -5109,7 +5116,7 @@ def generate_determinantset_old(type = 'bspline', occ.format = 'energy' elif exc_type == exc_types.lowest: # Type 4 occ.format = 'energy' - if exc_type == exc_types.up: + if exc_spin == exc_spins.up: nel = elns.up_electron.count else: nel = elns.down_electron.count From 879c0ff31d31f95839bed261554b1c3b8bd31619 Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Mon, 29 Nov 2021 15:21:11 -0500 Subject: [PATCH 31/35] Ready for review --- nexus/lib/qmcpack_input.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nexus/lib/qmcpack_input.py b/nexus/lib/qmcpack_input.py index 7beb9278b5..938631152e 100644 --- a/nexus/lib/qmcpack_input.py +++ b/nexus/lib/qmcpack_input.py @@ -3870,7 +3870,7 @@ def get_electron_particle_set(self): input = self.copy() input.pluralize() - return input.get('particlesets').get_electrons() + return input.get('particlesets').e #end def get_electron_particle_set From ea1d7869bfce2856c99fd78bf7dc553f6936c5c8 Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Mon, 29 Nov 2021 15:28:09 -0500 Subject: [PATCH 32/35] Remove print --- nexus/lib/qmcpack_input.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nexus/lib/qmcpack_input.py b/nexus/lib/qmcpack_input.py index 938631152e..3f4249304c 100644 --- a/nexus/lib/qmcpack_input.py +++ b/nexus/lib/qmcpack_input.py @@ -5041,7 +5041,6 @@ def generate_determinantset_old(type = 'bspline', cb = vb+1 # Convert band_1, band_2 to band indexes bands = [band_1, band_2] - print(bands) for bnum, b in enumerate(bands): if 'CB' in b: if '-' in b: From 2dfcbb406321075fb3482700cebd320130120a9e Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Thu, 2 Dec 2021 16:08:53 -0500 Subject: [PATCH 33/35] Add additional changes for review --- nexus/lib/qmcpack.py | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index 47a5a6688d..14ee9a3b5a 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -529,7 +529,8 @@ def post_analyze(self,analyzer): tw2,bnd2 = exc2.split()[2:4] if exc1 in ('up','down'): spin_channel = exc1 - for idx,(tw,bnd) in enumerate(zip(edata[spin_channel]['TwistIndex'],edata[spin_channel]['BandIndex'])): + 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 Date: Thu, 2 Dec 2021 16:27:14 -0500 Subject: [PATCH 34/35] Additional review items --- .../excited/vmc_excitation_alternatives.py | 12 ++++++++++++ nexus/lib/qmcpack.py | 5 +++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/nexus/examples/qmcpack/rsqmc_misc/excited/vmc_excitation_alternatives.py b/nexus/examples/qmcpack/rsqmc_misc/excited/vmc_excitation_alternatives.py index a916c7e283..688fcd500d 100755 --- a/nexus/examples/qmcpack/rsqmc_misc/excited/vmc_excitation_alternatives.py +++ b/nexus/examples/qmcpack/rsqmc_misc/excited/vmc_excitation_alternatives.py @@ -135,6 +135,10 @@ ############ Single Determinant Excitations #################################### ################################################################################ +# In each of the following 4 examples, an optical excitation is performed in the up-channel +# corresponding to the homo-lumo gap at the gamma k-point. All 4 examples lead to the same +# excitation, but show the various ways that the excitation can be specfified + # up channel, gamma vb gamma cb qmc_optical = generate_qmcpack( det_format = 'old', @@ -244,6 +248,10 @@ ############ Triplet Excitations ############################################### ################################################################################ +# In each of the following 2 examples, an optical excitation is performed for a triplet state +# corresponding to the homo-lumo gap at the gamma k-point. Both examples lead to the same +# excitation, but show the various ways that the excitation can be specfified + # triplet, energy index qmc_optical = generate_qmcpack( det_format = 'old', @@ -300,6 +308,10 @@ ############ Singlet Excitations ############################################### ################################################################################ +# In each of the following 2 examples, an optical excitation is performed for a singlet state +# corresponding to the homo-lumo gap at the gamma k-point. Both examples lead to the same +# excitation, but show the various ways that the excitation can be specfified + # singlet, energy index qmc_optical = generate_qmcpack( det_format = 'old', diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index 14ee9a3b5a..42723583f8 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -571,9 +571,10 @@ def post_analyze(self,analyzer): spin_channel = exc1 nelec = elns.groups[spin_channel[0]].size + eigs_spin = edata[spin_channel].Energy - orb1_eig = sorted(edata[spin_channel].Energy)[orb1-1] - orb2_eig = sorted(edata[spin_channel].Energy)[orb2-1] + orb1_eig = sorted(eigs_spin)[orb1-1] + orb2_eig = sorted(eigs_spin)[orb2-1] if orb1_eig not in edata[spin_channel]['Energy'][nelec:]: msg = 'WARNING: You requested \'{}\' excitation of type \'{}\',\n' From 35b7207cacb902eb11ff69dfa72ffa36b43086cc Mon Sep 17 00:00:00 2001 From: "M. Chandler Bennett" Date: Thu, 2 Dec 2021 17:41:13 -0500 Subject: [PATCH 35/35] Additional review items --- nexus/lib/qmcpack.py | 31 +++++++++++++++++-------------- nexus/lib/qmcpack_input.py | 13 ++++--------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/nexus/lib/qmcpack.py b/nexus/lib/qmcpack.py index 42723583f8..f9885827b2 100644 --- a/nexus/lib/qmcpack.py +++ b/nexus/lib/qmcpack.py @@ -25,6 +25,7 @@ import os +import numpy as np from numpy import array,dot,pi from numpy.linalg import inv,norm from generic import obj @@ -573,21 +574,23 @@ def post_analyze(self,analyzer): nelec = elns.groups[spin_channel[0]].size eigs_spin = edata[spin_channel].Energy - orb1_eig = sorted(eigs_spin)[orb1-1] - orb2_eig = sorted(eigs_spin)[orb2-1] - - if orb1_eig not in edata[spin_channel]['Energy'][nelec:]: + # 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 + hc_excited = ground[:orb1]+ground[orb2-1]+ground[orb1+1:nelec] + + etol = 1e-6 + if np.abs(hc_excited-excited).max() > tol: msg = 'WARNING: You requested \'{}\' excitation of type \'{}\',\n' - msg += ' however, the first orbital \'{}\' is still occupied (see einspline file).\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 - elif orb2_eig not in edata[spin_channel]['Energy'][:nelec]: - 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],orb2) - exc_failure = True #end if elif exc1 in ('singlet','triplet'): @@ -632,7 +635,8 @@ def post_analyze(self,analyzer): # Convert band_1, band_2 to band indexes bands = [band_1, band_2] for bnum, b in enumerate(bands): - if 'CB' in b: + b = b.lower() + if 'cb' in b: if '-' in b: b = b.split('-') bands[bnum] = cb - int(b[1]) @@ -642,7 +646,7 @@ def post_analyze(self,analyzer): else: bands[bnum] = cb #end if - elif 'VB' in b: + elif 'vb' in b: if '-' in b: b = b.split('-') bands[bnum] = vb - int(b[1]) @@ -673,7 +677,6 @@ def post_analyze(self,analyzer): k_1 = kpath_rel[where(kpath_label == k_1)][0] k_2 = kpath_rel[where(kpath_label == k_2)][0] - #kpts = nscf.input.k_points.kpoints kpts = structure.kpoints_unit() found_k1 = False found_k2 = False diff --git a/nexus/lib/qmcpack_input.py b/nexus/lib/qmcpack_input.py index 3f4249304c..e2711b09f6 100644 --- a/nexus/lib/qmcpack_input.py +++ b/nexus/lib/qmcpack_input.py @@ -4827,8 +4827,6 @@ def check_excitation_type(excitation): #end if return exc_spin,exc_type,exc_spins,exc_types,exc1,exc2 - - #end def check_excitation_type @@ -5042,7 +5040,8 @@ def generate_determinantset_old(type = 'bspline', # Convert band_1, band_2 to band indexes bands = [band_1, band_2] for bnum, b in enumerate(bands): - if 'CB' in b: + b = b.lower() + if 'cb' in b: if '-' in b: b = b.split('-') bands[bnum] = cb - int(b[1]) @@ -5052,7 +5051,7 @@ def generate_determinantset_old(type = 'bspline', else: bands[bnum] = cb #end if - elif 'VB' in b: + elif 'vb' in b: if '-' in b: b = b.split('-') bands[bnum] = vb - int(b[1]) @@ -5069,11 +5068,7 @@ def generate_determinantset_old(type = 'bspline', band_1, band_2 = bands # Convert k_1 k_2 to wavevector indexes - if system.structure.has_folded(): - structure = system.structure.folded_structure.copy() - else: - structure = system.structure.copy() - #end if + structure = system.structure.get_smallest().copy() structure.change_units('A') kpath = get_kpath(structure=structure) kpath_label = array(kpath['explicit_kpoints_labels'])