Skip to content

Commit e0da22d

Browse files
committed
Merge branch 'master' of github.com:lkwagner/autogenv2
2 parents 152a2a4 + 7a15d50 commit e0da22d

File tree

3 files changed

+77
-106
lines changed

3 files changed

+77
-106
lines changed

Crystal.py

+34-104
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def __init__(self):
1818
#Electron model
1919
self.spin_polarized=True
2020
self.xml_name="BFD_Library.xml"
21-
self.functional={'exchange':'PBE','correlation':'PBE','hybrid':0}
21+
self.functional={'exchange':'PBE','correlation':'PBE','hybrid':0,'predefined':None}
2222
self.total_spin=0
2323

2424
#Numerical convergence parameters
@@ -27,7 +27,7 @@ def __init__(self):
2727
self.kmesh=[8,8,8]
2828
self.gmesh=16
2929
self.tolinteg=[8,8,8,8,18]
30-
self.dftgrid='XLGRID'
30+
self.dftgrid=''
3131

3232
#Memory
3333
self.biposize=100000000
@@ -41,7 +41,9 @@ def __init__(self):
4141
self.levshift=[]
4242
self.broyden=[0.01,60,15]
4343
self.diis=False
44-
self.smear=0.0001
44+
self.smear=0.0
45+
self.supercell= [[1.,0.,0.],[0.,1.,0.],[0.,0.,1.]]
46+
4547

4648
# Use the new crystal2qmc script. This should change soon!
4749
self.cryapi=True
@@ -55,7 +57,6 @@ def set_struct_fromcif(self,cifstr,primitive=True):
5557
self.primitive=primitive
5658
self.cif=cifstr
5759
self.struct=CifParser.from_string(self.cif).get_structures(primitive=self.primitive)[0].as_dict()
58-
self.supercell= [[1.,0.,0.],[0.,1.,0.],[0.,0.,1.]]
5960
self.boundary="3d"
6061
#-----------------------------------------------
6162

@@ -75,7 +76,7 @@ def set_options(self, d):
7576
selfdict[k]=d[k]
7677

7778
#-----------------------------------------------
78-
def crystal_input(self):
79+
def crystal_input(self,section4=[]):
7980

8081
assert self.struct is not None,'Need to set "struct" first.'
8182
geomlines=self.geom()
@@ -99,15 +100,19 @@ def crystal_input(self):
99100
outlines+=["DFT"]
100101
if self.spin_polarized:
101102
outlines+=["SPIN"]
102-
outlines += [
103-
"EXCHANGE",
104-
self.functional['exchange'],
105-
"CORRELAT",
106-
self.functional['correlation'],
107-
"HYBRID",
108-
str(self.functional['hybrid']),
109-
self.dftgrid,
110-
"END",
103+
if self.functional['predefined']!=None:
104+
outlines+=[self.functional['predefined']]
105+
else:
106+
outlines += [
107+
"EXCHANGE",
108+
self.functional['exchange'],
109+
"CORRELAT",
110+
self.functional['correlation'],
111+
"HYBRID",
112+
str(self.functional['hybrid'])]
113+
if self.dftgrid!="":
114+
outlines+=[self.dftgrid]
115+
outlines+=["END",
111116
"SCFDIR",
112117
"BIPOSIZE",
113118
str(self.biposize),
@@ -121,10 +126,10 @@ def crystal_input(self):
121126
' '.join(map(str,self.tolinteg)),
122127
"MAXCYCLE",
123128
str(self.maxcycle),
124-
"SMEAR",
125-
str(self.smear),
126129
"SAVEWF"
127130
]
131+
if self.smear > 0:
132+
outlines+=["SMEAR",str(self.smear)]
128133
if self.spin_polarized:
129134
outlines+=['SPINLOCK',str(self.total_spin)+" 200"]
130135

@@ -134,7 +139,7 @@ def crystal_input(self):
134139
outlines+=["LEVSHIFT"," ".join(map(str,self.levshift))]
135140
else:
136141
outlines+=["BROYDEN"," ".join(map(str,self.broyden))]
137-
142+
outlines+=section4
138143
if self.restart:
139144
outlines+=["GUESSP"]
140145
outlines+=["END"]
@@ -262,19 +267,13 @@ def basis_section(self):
262267
elements.add(nm)
263268
basislines=[]
264269
elements = sorted(list(elements)) # Standardize ordering.
265-
if self.boundary=='3d':
266-
for e in elements:
267-
basislines+=self.generate_basis_3d(e)
268-
elif self.boundary=='0d':
269-
for e in elements:
270-
basislines+=self.generate_basis_0d(e)
271-
else:
272-
raise AssertionError("Invalid boundary value")
270+
for e in elements:
271+
basislines+=self.generate_basis(e)
273272
return basislines
274273

275274

276275
########################################################
277-
def generate_basis_3d(self,symbol):
276+
def generate_basis(self,symbol):
278277
"""
279278
Author: "Kittithat (Mick) Krongchon" <[email protected]> and Lucas K. Wagner
280279
Returns a string containing the basis section. It is modified according to a simple recipe:
@@ -360,75 +359,6 @@ def generate_basis_3d(self,symbol):
360359
ret+=["0 %i %i %g 1"%(basis_index[angular],1,0.0),line]
361360
ncontract+=1
362361

363-
return ["%i %i"%(Element(symbol).number+200,ncontract)] +\
364-
self.pseudopotential_section(symbol) +\
365-
ret
366-
367-
########################################################
368-
def generate_basis_0d(self,symbol):
369-
"""
370-
Author: "Kittithat (Mick) Krongchon" <[email protected]> and Lucas K. Wagner
371-
Returns a string containing the basis section. It is modified according to a simple recipe:
372-
Args:
373-
symbol (str): The symbol of the element to be specified in the
374-
D12 file.
375-
xml_name (str): The name of the XML pseudopotential and basis
376-
set database.
377-
Returns:
378-
str: The pseudopotential and basis section.
379-
"""
380-
381-
maxorb=3
382-
basis_name="vtz"
383-
maxcharge={"s":2,"p":6,"d":10,"f":15} #max charge on a basis function
384-
max_tot_charge={"s":2,"p":6,"d":10,"f":15} #max total charge in an angular momentum
385-
386-
basis_index={"s":0,"p":2,"d":3,"f":4}
387-
transition_metals=["Sc","Ti","V","Cr","Mn","Fe","Co","Ni","Cu","Zn"]
388-
if symbol in transition_metals:
389-
maxorb=4
390-
max_tot_charge['s']=4
391-
charge_sum={"s":0,"p":0,"d":0,"f":0}
392-
tree = ElementTree()
393-
tree.parse(self.xml_name)
394-
element = tree.find('./Pseudopotential[@symbol="{}"]'.format(symbol))
395-
atom_charge = int(element.find('./Effective_core_charge').text)
396-
if symbol in self.initial_charges.keys():
397-
atom_charge-=self.initial_charges[symbol]
398-
basis_path = './Basis-set[@name="{}"]/Contraction'.format(basis_name)
399-
found_orbitals = []
400-
totcharge=0
401-
ret=[]
402-
ncontract=0
403-
for contraction in element.findall(basis_path):
404-
angular = contraction.get('Angular_momentum')
405-
406-
#Figure out which coefficients to print out based on the minimal exponent
407-
nterms = 0
408-
basis_part=[]
409-
for basis_term in contraction.findall('./Basis-term'):
410-
exp = basis_term.get('Exp')
411-
coeff = basis_term.get('Coeff')
412-
basis_part += [' {} {}'.format(exp, coeff)]
413-
nterms+=1
414-
#now write the header
415-
if nterms > 0 and angular in basis_index.keys():
416-
found_orbitals.append(angular)
417-
charge=min(atom_charge-totcharge,maxcharge[angular])
418-
if charge_sum[angular] >= max_tot_charge[angular]:
419-
charge=0
420-
#put in a special case for transition metals:
421-
#depopulate the 4s if the atom is charged
422-
if symbol in transition_metals and symbol in self.initial_charges.keys() \
423-
and self.initial_charges[symbol] > 0 and found_orbitals.count(angular) > 1 \
424-
and angular=="s":
425-
charge=0
426-
totcharge+=charge
427-
charge_sum[angular]+=charge
428-
ret+=["0 %i %i %g 1"%(basis_index[angular],nterms,charge)] + basis_part
429-
ncontract+=1
430-
431-
432362
return ["%i %i"%(Element(symbol).number+200,ncontract)] +\
433363
self.pseudopotential_section(symbol) +\
434364
ret
@@ -495,7 +425,6 @@ def collect(self,outfilename):
495425
lines = f.readlines()
496426
for li,line in enumerate(lines):
497427
if 'SCF ENDED' in line:
498-
print(line)
499428
self.out['total_energy']=float(line.split()[8])
500429

501430
elif 'TOTAL ATOMIC SPINS' in line:
@@ -505,7 +434,8 @@ def collect(self,outfilename):
505434
moms += map(float,lines[li+shift].split())
506435
shift += 1
507436
self.out['mag_moments']=moms
508-
print(self.out)
437+
self.out['etots'] = [float(line.split()[3]) for line in lines if "DETOT" in line]
438+
509439
self.completed=True
510440
else:
511441
# Just to be sure/clear...
@@ -523,36 +453,36 @@ def write_summary(self):
523453
def check_outputfile(self,outfilename,acceptable_scf=10.0):
524454
""" Check output file.
525455
526-
Current return values:
456+
Return values:
527457
no_record, not_started, ok, too_many_cycles, finished (fall-back),
528458
scf_fail, not_enough_decrease, divergence, not_finished
529459
"""
530460
if os.path.isfile(outfilename):
531-
outf = open(outfilename,'r')
461+
outf = open(outfilename,'r',errors='ignore')
532462
else:
533463
return "not_started"
534464

535-
outlines = outf.read().split('\n')
465+
outlines = outf.readlines()
536466
reslines = [line for line in outlines if "ENDED" in line]
537467

538468
if len(reslines) > 0:
539469
if "CONVERGENCE" in reslines[0]:
540470
return "ok"
541471
elif "TOO MANY CYCLES" in reslines[0]:
542-
print("CrystalRunner: Too many cycles.")
472+
#print("CrystalRunner: Too many cycles.")
543473
return "too_many_cycles"
544474
else: # What else can happen?
545-
print("CrystalReader: Finished, but unknown state.")
475+
#print("CrystalReader: Finished, but unknown state.")
546476
return "finished"
547477

548478
detots = [float(line.split()[5]) for line in outlines if "DETOT" in line]
549479
if len(detots) == 0:
550-
print("CrystalRunner: Last run completed no cycles.")
480+
#print("CrystalRunner: Last run completed no cycles.")
551481
return "scf_fail"
552482

553483
detots_net = sum(detots[1:])
554484
if detots_net > acceptable_scf:
555-
print("CrystalRunner: Last run performed poorly.")
485+
#print("CrystalRunner: Last run performed poorly.")
556486
return "not_enough_decrease"
557487

558488
etots = [float(line.split()[3]) for line in outlines if "DETOT" in line]

crystal2qmc.py

+42
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,47 @@ def write_slater(basis,eigsys,kpt,base="qwalk",kfmt='coord'):
373373
outf.write("\n".join(outlines))
374374
return outlines # Might be confusing.
375375

376+
###############################################################################
377+
def write_orbplot(basis,eigsys,kpt,base="qwalk",kfmt='coord'):
378+
if kfmt == 'int': kbase = base + '_' + "{}".format(eigsys['kpt_index'][kpt])
379+
else: kbase = base + '_' + "{}{}{}".format(*kpt)
380+
ntot = basis['ntot']
381+
nmo = basis['nmo']
382+
nup = eigsys['nup']
383+
ndn = eigsys['ndn']
384+
uporbs = np.arange(nup)+1
385+
dnorbs = np.arange(ndn)+1
386+
if eigsys['nspin'] > 1:
387+
dnorbs += nmo
388+
if eigsys['ikpt_iscmpx'][kpt]: orbstr = "corbitals"
389+
else: orbstr = "orbitals"
390+
uporblines = ["{:5d}".format(orb) for orb in uporbs]
391+
width = 10
392+
for i in reversed(range(width,len(uporblines),width)):
393+
uporblines.insert(i,"\n ")
394+
dnorblines = ["{:5d}".format(orb) for orb in dnorbs]
395+
for i in reversed(range(width,len(dnorblines),width)):
396+
dnorblines.insert(i,"\n ")
397+
outlines_prefix = [
398+
"method { ",
399+
"plot",
400+
"{0} {{".format(orbstr),
401+
"cutoff_mo",
402+
" magnify 1",
403+
" nmo {0}".format(dnorbs[-1]),
404+
" orbfile {0}.orb".format(kbase),
405+
" include {0}.basis".format(base),
406+
" centers { useglobal }",
407+
"}",
408+
"plotorbitals {",
409+
]
410+
outlines_postfix= ["}","}","include "+kbase+".sys"]
411+
with open(kbase+".up.plot",'w') as outf:
412+
outf.write("\n".join(outlines_prefix+ [" ".join(uporblines)] + outlines_postfix))
413+
with open(kbase+".dn.plot",'w') as outf:
414+
outf.write("\n".join(outlines_prefix+ [" ".join(dnorblines)] + outlines_postfix))
415+
416+
376417
###############################################################################
377418
# f orbital normalizations are from
378419
# <http://winter.group.shef.ac.uk/orbitron/AOs/4f/equations.html>
@@ -727,6 +768,7 @@ def convert_crystal(
727768
for kpt in eigsys['kpt_coords']:
728769
if eigsys['ikpt_iscmpx'][kpt] and kset=='real': continue
729770
write_slater(basis,eigsys,kpt,base,kfmt)
771+
write_orbplot(basis,eigsys,kpt,base,kfmt)
730772
normalize_eigvec(eigsys,basis,kpt)
731773
write_orb(eigsys,basis,ions,kpt,base,kfmt)
732774
write_sys(lat_parm,basis,eigsys,pseudo,ions,kpt,base,kfmt)

example/make_crystal_plan.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
dft_opts={
1111
'xml_name':os.getcwd()+'/../BFD_Library.xml',
12-
'basis_params':[0.2,0,3],
1312
'cutoff':0.0,
1413
'dftgrid':'LGRID',
1514
'spin_polarized':False
@@ -29,7 +28,7 @@
2928

3029
pbc_opts={
3130
'xml_name':os.getcwd()+'/../BFD_Library.xml',
32-
'basis_params':[0.4,1,3],
31+
'basis_params':[0.2,2,3],
3332
'cutoff':0.2,
3433
'dftgrid':'LGRID',
3534
'spin_polarized':False,

0 commit comments

Comments
 (0)