Skip to content

Commit 783c4c3

Browse files
committed
init
0 parents  commit 783c4c3

25 files changed

+1286
-0
lines changed

ORCA_ipfitting.py

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
#!/usr/bin/env python3
2+
3+
def orca_ipfitting(orca_input, omega_l, omega_r, omega_tol=1.0e-3, maxiter=20):
4+
import os, re, subprocess, shutil
5+
6+
inp_omega_decimal = 6
7+
inp_omega_fmt = '%%.%df' % (inp_omega_decimal,)
8+
9+
omegas = []
10+
types = []
11+
E0s = []
12+
E1s = []
13+
IPs = []
14+
kIPs = []
15+
16+
def inp_acc_omega(omega):
17+
return round(omega, inp_omega_decimal)
18+
19+
def nearest_omega(omega, min_diff=None):
20+
old_omega = None
21+
for og in omegas:
22+
diff = abs(og - omega)
23+
if min_diff is None or diff < min_diff:
24+
old_omega, min_diff = og, diff
25+
return old_omega
26+
27+
def gen_fgbw_suffix(omega):
28+
return '_' + inp_omega_fmt % (omega,)
29+
30+
def gen_inp(chg, spin, omega, finp):
31+
with open(orca_input, 'r') as f:
32+
txt = f.read()
33+
xyz, xyzfile = True, True
34+
txt_new, na = re.subn('\*\s*xyzfile\s+-?[0-9]+\s+-?[0-9]+', '*xyzfile %d %d' % (chg, spin), txt, re.I)
35+
if na == 0:
36+
txt_new, nb = re.subn('\*\s*xyz\s+-?[0-9]+\s+-?[0-9]+', '*xyz %d %d' % (chg, spin), txt, re.I)
37+
if nb == 0:
38+
raise ValueError('Fail to renew charge and spin!')
39+
txt_new, n = re.subn('RangeSepMu\s+[^\s]*', 'RangeSepMu %.6f' % (omega), txt_new, re.I)
40+
if n == 0:
41+
raise ValueError('Fail to renew omega!')
42+
with open(finp, 'w') as f:
43+
f.write(txt_new)
44+
45+
def get_tote(flog):
46+
tote = None
47+
with open(flog, 'r') as f:
48+
for line in f.readlines():
49+
if line.startswith('FINAL SINGLE POINT ENERGY'):
50+
tote = float(line.strip().split()[-1])
51+
break
52+
return tote
53+
54+
def get_homo(flog):
55+
homo = None
56+
with open(flog, 'r') as f:
57+
lines = f.readlines()
58+
start = None
59+
for i, line in enumerate(lines):
60+
if line.startswith('ORBITAL ENERGIES'):
61+
start = i + 4
62+
break
63+
occ, lastocc, e, laste = 0.0, 0.0, 0.0, 0.0
64+
for i, line in enumerate(lines[start:]):
65+
occ, e = [float(x) for x in line.strip().split()[1:3]]
66+
if round(occ) == 0 and round(lastocc) == 2:
67+
homo = laste
68+
break
69+
lastocc, laste = occ, e
70+
return homo
71+
72+
def calc_neutral(omega):
73+
finp, flog, fgbw = 'neutral.inp', 'neutral.log', 'neutral.gbw'
74+
gen_inp(0, 1, omega, finp)
75+
old_omega = nearest_omega(omega)
76+
if old_omega is not None:
77+
old_fgbw = fgbw + gen_fgbw_suffix(old_omega)
78+
shutil.copyfile(old_fgbw, fgbw)
79+
with open(flog, 'w') as f:
80+
exitcode = subprocess.call([orca_exec, finp], stdout=f, stderr=f)
81+
if exitcode != 0:
82+
raise RuntimeError('ORCA terminated abnormally!')
83+
E, E_HOMO = get_tote(flog), get_homo(flog)
84+
new_fgbw = fgbw + gen_fgbw_suffix(omega)
85+
shutil.copyfile(fgbw, new_fgbw)
86+
87+
return E, E_HOMO
88+
89+
def calc_cation(omega):
90+
finp, flog, fgbw = 'cation.inp', 'cation.log', 'cation.gbw'
91+
gen_inp(1, 2, omega, finp)
92+
old_omega = nearest_omega(omega, min_diff=0.05)
93+
if old_omega is not None:
94+
old_fgbw = fgbw + gen_fgbw_suffix(old_omega)
95+
else:
96+
old_fgbw = 'neutral.gbw'
97+
shutil.copyfile(old_fgbw, fgbw)
98+
with open(flog, 'w') as f:
99+
exitcode = subprocess.call([orca_exec, finp], stdout=f, stderr=f)
100+
if exitcode != 0:
101+
raise RuntimeError('ORCA terminated abnormally!')
102+
103+
E = get_tote(flog)
104+
new_fgbw = fgbw + gen_fgbw_suffix(omega)
105+
shutil.copyfile(fgbw, new_fgbw)
106+
107+
return E
108+
109+
orca_root = os.environ.get('ORCA_ROOT', None)
110+
if orca_root is None:
111+
raise ValueError('"ORCA_ROOT" is not set!')
112+
orca_exec = orca_root + '/orca'
113+
if not os.access(orca_exec, os.X_OK):
114+
raise ValueError('"%s" is not executable!')
115+
116+
E0r, E_HOMOr = calc_neutral(omega_r)
117+
E1r = calc_cation(omega_r)
118+
119+
IPr, kIPr = E1r - E0r, -E_HOMOr
120+
delta_r = IPr - kIPr
121+
122+
if IPr > kIPr:
123+
raise ValueError("""\n***IP Fitting Error: Right Omega limit should have kIP > IP: {} !> {}""".format(kIPr, IPr))
124+
125+
omegas.append(omega_r)
126+
types.append('Right Limit')
127+
E0s.append(E0r)
128+
E1s.append(E1r)
129+
IPs.append(IPr)
130+
kIPs.append(kIPr)
131+
132+
E0l, E_HOMOl = calc_neutral(omega_l)
133+
E1l = calc_cation(omega_l)
134+
135+
IPl, kIPl = E1l - E0l, -E_HOMOl
136+
delta_l = IPl - kIPl
137+
138+
if IPl < kIPl:
139+
raise ValueError("""\n***IP Fitting Error: Left Omega limit should have kIP < IP: {} !< {}""".format(kIPl, IPl))
140+
141+
omegas.append(omega_l)
142+
types.append('Left Limit')
143+
E0s.append(E0l)
144+
E1s.append(E1l)
145+
IPs.append(IPl)
146+
kIPs.append(kIPl)
147+
148+
converged = False
149+
repeat_l = 0
150+
repeat_r = 0
151+
for step in range(maxiter):
152+
# Regula Falsi (modified)
153+
if repeat_l > 1:
154+
delta_l /= 2.0
155+
if repeat_r > 1:
156+
delta_r /= 2.0
157+
omega = - (omega_r - omega_l) / (delta_r - delta_l) * delta_l + omega_l
158+
if inp_acc_omega(omega) == inp_acc_omega(omega_r) or inp_acc_omega(omega) == inp_acc_omega(omega_l):
159+
converged = True
160+
break
161+
162+
E0, E_HOMO = calc_neutral(omega)
163+
E1 = calc_cation(omega)
164+
165+
IP, kIP = E1 - E0, -E_HOMO
166+
delta = IP - kIP
167+
168+
if kIP > IP:
169+
omega_r = omega
170+
E0r = E0
171+
E1r = E1
172+
IPr = IP
173+
kIPr = kIP
174+
delta_r = delta
175+
repeat_r = 0
176+
repeat_l += 1
177+
else:
178+
omega_l = omega
179+
E0l = E0
180+
E1l = E1
181+
IPl = IP
182+
kIPl = kIP
183+
delta_l = delta
184+
repeat_l = 0
185+
repeat_r += 1
186+
187+
omegas.append(omega)
188+
types.append('Regula-Falsi')
189+
E0s.append(E0)
190+
E1s.append(E1)
191+
IPs.append(IP)
192+
kIPs.append(kIP)
193+
194+
# Termination
195+
if abs(omega_l - omega_r) < omega_tol:
196+
converged = True
197+
break
198+
199+
print(""" => Regula Falsi Iterations <=\n""")
200+
print(""" %3s %10s %14s %14s %14s %s""" % ('N','Omega','IP','kIP','Delta','Type'))
201+
for k in range(len(omegas)):
202+
print(""" %3d %10.6F %14.6E %14.6E %14.6E %s""" %
203+
(k + 1, omegas[k], IPs[k], kIPs[k], IPs[k] - kIPs[k], types[k]))
204+
205+
if converged:
206+
print("""\n IP Fitting Converged""")
207+
print(""" Final omega = %10.6F""" % ((omega_l + omega_r) / 2))
208+
209+
else:
210+
raise ValueError("""IP Fitting """, step + 1)
211+
212+
return ((omega_l + omega_r) / 2)
213+
214+
if __name__ == '__main__':
215+
import argparse
216+
217+
parser = argparse.ArgumentParser()
218+
parser.add_argument('--input', type=str, required=True, help='sample input file')
219+
parser.add_argument('--min', type=float, required=True, help='minimum omega')
220+
parser.add_argument('--max', type=float, required=True, help='maximum omega')
221+
parser.add_argument('--tol', type=float, required=False, help='tolerance of omega', default=0.001)
222+
parser.add_argument('--maxiter', type=int, required=False, help='max number of iterations', default=20)
223+
224+
args = parser.parse_args()
225+
226+
orca_ipfitting(args.input, args.min, args.max, args.tol, args.maxiter)
227+

cry2cif.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/usr/bin/env python3
2+
3+
from sys import argv
4+
import numpy as np
5+
6+
def SkipLines(fd, nline):
7+
for i in range(nline):
8+
fd.readline()
9+
10+
def WriteCif(param, atomsymbol, factcoor, filename = 'naphthalene'):
11+
outp = []
12+
atomamount = {}
13+
atomformat = ' {0:<8s}1.0{1[0]:15.10f}{1[1]:15.10f}{1[2]:15.10f} Biso{2:15.10f} {3:2s}\n'.format
14+
outp.append('#' * 70 + '\n')
15+
outp.append('#' + ' ' * 68 + '#\n')
16+
outp.append('#' + ' ' * 23 + 'Optimized Crystal Data' + ' ' * 23 + '#\n')
17+
outp.append('#' + ' ' * 68 + '#\n')
18+
outp.append('#' + ' ' * 68 + '#\n')
19+
outp.append('#' * 70 + '\n')
20+
outp.append('\ndata_%s\n\n' % filename)
21+
outp.append('%-38s%-15s\n' % ('_cell_length_a', param[0]))
22+
outp.append('%-38s%-15s\n' % ('_cell_length_b', param[1]))
23+
outp.append('%-38s%-15s\n' % ('_cell_length_c', param[2]))
24+
outp.append('%-38s%-15s\n' % ('_cell_angle_alpha', param[3]))
25+
outp.append('%-38s%-15s\n' % ('_cell_angle_beta', param[4]))
26+
outp.append('%-38s%-15s\n' % ('_cell_angle_gamma', param[5]))
27+
outp.append('%-38s%-15s\n' % ('_symmetry_space_group_name_H-M', "'P 1'"))
28+
outp.append('%-38s%-15s\n\n' % ('_symmetry_Int_Tables_number', '1'))
29+
outp.append("loop_\n_symmetry_equiv_pos_as_xyz\n 'x, y, z'\n\nloop_\n")
30+
outp.append(' _atom_site_label\n _atom_site_occupancy\n')
31+
outp.append(' _atom_site_fract_x\n _atom_site_fract_y\n _atom_site_fract_z\n')
32+
outp.append(' _atom_site_adp_type\n _atom_site_B_iso_or_equiv\n _atom_site_type_symbol\n')
33+
for symbol, coor in zip(atomsymbol, factcoor):
34+
atomamount[symbol] = atomamount.get(symbol, 0) + 1
35+
atomname = symbol + str(atomamount[symbol])
36+
outp.append(atomformat(atomname, coor, 1.0, symbol))
37+
with open(filename + '.cif', 'w') as f:
38+
f.write(''.join(outp))
39+
40+
factcoor = [] # Fractional coordinates
41+
lattice = [] # Lattice vectors of supercell
42+
43+
if len(argv) != 2:
44+
print("Usage: cry2cif.py xx.out")
45+
elif argv[1][-4 :] == '.out':
46+
readf = False
47+
f = open(argv[1], 'r')
48+
print('Reading ' + argv[1] + '...')
49+
while True:
50+
try:
51+
line = f.readline()
52+
except UnicodeDecodeError:
53+
continue
54+
if line[: 25] == ' FINAL OPTIMIZED GEOMETRY':
55+
atomsymbol, factcoor = [], []
56+
SkipLines(f, 5)
57+
param = f.readline().split() #lattice parameters
58+
SkipLines(f, 4)
59+
while True:
60+
line = f.readline()
61+
if line == '\n': break
62+
sline = line.split()
63+
atomsymbol.append(sline[3])
64+
factcoor.append(sline[4 :])
65+
readf = True
66+
break
67+
if not readf:
68+
raise IOError('Final optimized geometry not found!')
69+
f.close()
70+
factcoor = np.array(factcoor, dtype = 'double')
71+
WriteCif(param, atomsymbol, factcoor, argv[1].split('.')[0]) # Write cif for visualization
72+
else:
73+
raise ValueError('Only output file of CRYSTAL17 named "xx.out" is supported!')

cryproperties.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
import re
5+
import numpy as np
6+
from io import StringIO
7+
from itertools import accumulate
8+
from functools import reduce
9+
from phonopy.units import Hartree
10+
11+
for file in os.listdir(os.getcwd()):
12+
if os.path.isfile(file):
13+
if file[-4:] == '.out':
14+
fout = file
15+
elif file[-5:] == '.BAND':
16+
fband = file
17+
elif file[-5:] == '.DOSS':
18+
fdoss = file
19+
20+
with open(fout, 'r') as f:
21+
outStr = f.read()
22+
kp = re.findall(r'LINE\s{0,}[0-9]+\s{0,}\((.*)\) IN TERMS OF PRIMITIVE LATTICE VECTORS\n\s{0,}([0-9]+)', outStr)
23+
paths = [re.sub(':', ' ---> ', p[0]) for p in kp]
24+
nums = [int(p[1]) for p in kp]
25+
accuNums = [0,] + list(accumulate(nums))
26+
efermi = max(float(e) for e in re.findall(r'TOP OF VALENCE BANDS.*EIG(.*)AU', outStr))
27+
28+
with open(fband, 'r') as f:
29+
bandStr = f.read()
30+
ticks = [float(t) for t in re.findall(r'@ XAXIS TICK\b.+,\s{0,}(.*)', bandStr)]
31+
lens = []
32+
for i in range(1, len(ticks)):
33+
lens.append(ticks[i] - ticks[i - 1])
34+
band = np.loadtxt(StringIO(bandStr), comments=['#', '@'])[:, 1:] * Hartree
35+
36+
print('%d paths as follow:' % len(paths))
37+
[print(' %s' % p) for p in paths]
38+
inp = input('please input the output order: ')
39+
order = [int(n) for n in inp.strip().split()]
40+
src = 0
41+
index, xaxis = [], []
42+
for n in order:
43+
n_abs = abs(n)
44+
index_tmp = list(range(accuNums[n_abs - 1], accuNums[n_abs]))
45+
if n < 0:
46+
index_tmp.reverse()
47+
index += index_tmp
48+
dst = src + lens[n_abs - 1]
49+
xaxis.append(np.linspace(src, dst, nums[n_abs - 1]))
50+
print('%9.6f ---> %9.6f' % (src, dst))
51+
src = dst
52+
xaxis = np.column_stack([x.reshape(1, -1) for x in xaxis]).flatten()
53+
np.savetxt('band.dat', np.column_stack((xaxis, band[index, :])), fmt='%12.6f')
54+
55+
doss = (np.loadtxt(fdoss, comments=['#', '@']) - np.array([efermi, 0])) * np.array([Hartree, 1 / Hartree])
56+
np.savetxt('doss.dat', doss, fmt='%12.6f')

daemon

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env bash
2+
3+
nohup ${*} &> /dev/null &

delpage.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env python3
2+
3+
from PyPDF2 import PdfFileReader, PdfFileWriter
4+
from sys import argv
5+
6+
pageindex = int(argv[1])
7+
files = argv[2:]
8+
9+
for file in files:
10+
output = PdfFileWriter()
11+
with open(file, 'rb') as infile:
12+
input = PdfFileReader(infile)
13+
for i in range(input.numPages):
14+
if i != pageindex:
15+
output.addPage(input.getPage(i))
16+
with open('output-' + file, 'wb') as outfile:
17+
output.write(outfile)

0 commit comments

Comments
 (0)