forked from KIT-Workflows/DFT-VASP
-
Notifications
You must be signed in to change notification settings - Fork 0
/
incar.py
253 lines (213 loc) · 10.2 KB
/
incar.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
#import pymatgen
from pymatgen.core import Structure, Lattice
from pymatgen.io.vasp import Incar, Poscar, Potcar, Kpoints
from ase import io
from ase.io.vasp import read_vasp, write_vasp
#from pymatgen.io.vasp.sets import MPRelaxSet
import os, yaml
def get_VASP_inputs(structure):
#poscar = Poscar(structure)
incar_dict = dict( SYSTEM = structure.formula, # Name of the system
## Electronic relaxation:
ENCUT = 500., # 500. eV, value for carbon atom
NELMIN = 6, # Minimum number of eletronic selfconsistency (SC) steps
NELM = 1000, # Maximum number of electronic SC steps
NELMDL = -12, # Number of NON-selfconsistency steps
EDIFF = 1.0E-6, # Global-break condition for the electronic SC-loop (ELM)
## Calculation mode:
PREC = 'NORMAL', # Calcululation level (Changes FFT-grids)
ISPIN = 2, # spin-polarized calculations
ADDGRID = '.TRUE.', # level of precision
IVDW = 0, # no vdW corrections
## Ionic relaxation:
NSW = 150, # Maximum number of ionic steps
EDIFFG = -0.020, # stop if all forces are smaller than |EDIFFG|
IBRION = 2,
ISIF = 3, # Controls the computation of stress tensor. 3 computes everything
POTIM = 0.010,
## Integration over the Brillouin zone (BZ):
ISMEAR = 0, # Gaussian smearing scheme. Use 0 for insulators, as suggested by VASPWIKI
SIGMA = 0.10,
# LREAL = 'Auto', # Should projections be done in real space? Let VASP decide
# ALGO = 'ALL',
## DOS calculation:
LORBIT = 10, # Calculate the DOS without providing the Wigner Seitz radius
NEDOS = 101, # Number of points to calculate the DOS
## OUTCAR size:
NWRITE = 1, # Determines how much information will be written in OUTCAR
LCHARG = '.FALSE.', # Write charge densities?
LWAVE = '.FALSE.', # write out the wavefunctions?
LASPH = '.TRUE.', # non-spherical elements in the PAW method
# NKRED = 8,
## Key for parallel mode calculation:
NCORE = 4,
LPLANE = '.TRUE.' # Plane distribution of FFT coefficients. Reduces communications in FFT.
)
#incar = Incar.from_dict(incar_dict )
#incar.write_file('INCAR')
return incar_dict
def check_IVDW(dict_INCAR):
var_value = dict_INCAR.get("IVDW")
ivdw_data = {"D2": 10, "D3": 11, "D3BJ": 12, "dDsC": 4, "TSSCS": 20, "TSHP": 21, "MBDSC": 202, "MBDFI": 263, "None": 0}
dict_INCAR['IVDW'] = ivdw_data[var_value]
dict_INCAR['ADDGRID'] = '.FALSE.'
dict_INCAR['LASPH'] = '.FALSE.'
return dict_INCAR
def check_vdw_functional(dict_INCAR):
var_value = dict_INCAR.get('GGA')
if var_value == "optPBE-vdw":
dict_INCAR['GGA'] = "OR"
dict_INCAR['LUSE_VDW'] = ".TRUE."
dict_INCAR['AGGAC'] = 0.0000
dict_INCAR['LASPH'] = ".TRUE."
elif var_value == "optB88-vdw":
dict_INCAR['GGA'] = "BO"
dict_INCAR['PARAM1'] = 0.1833333333
dict_INCAR['PARAM2'] = 0.2200000000
dict_INCAR['LUSE_VDW'] = ".TRUE."
dict_INCAR['AGGAC'] = 0.0000
dict_INCAR['LASPH'] = ".TRUE."
elif var_value == "optB86b-vdw":
dict_INCAR['GGA'] = "MK"
dict_INCAR['PARAM1'] = 0.1234
dict_INCAR['PARAM2'] = 1.0000
dict_INCAR['LUSE_VDW'] = ".TRUE."
dict_INCAR['AGGAC'] = 0.0000
dict_INCAR['LASPH'] = ".TRUE."
elif var_value == "SCAN+rVV10":
dict_INCAR['METAGGA'] = "SCAN"
dict_INCAR['LUSE_VDW'] = ".TRUE."
dict_INCAR['BPARAM'] = 6.3 # default but can be overwritten by this tag
dict_INCAR['CPARAM'] = 0.0093 # default but can be overwritten by this tag
dict_INCAR['LASPH'] = ".TRUE."
del dict_INCAR["GGA"]
else:
dict_INCAR['GGA'] = var_value
dict_INCAR = check_IVDW(dict_INCAR)
return dict_INCAR
def check_hybrid_functionals(dict_INCAR):
var_value = dict_INCAR.get('GGA')
if var_value == 'HSE03':
dict_INCAR['GGA'] = "PE"
dict_INCAR['LHFCALC'] = ".TRUE."
dict_INCAR['HFSCREEN'] = 0.3000
elif var_value == 'HSE06':
dict_INCAR['GGA'] = 'PE'
dict_INCAR['LHFCALC'] = '.TRUE.'
dict_INCAR['HFSCREEN'] = 0.2000
else:
dict_INCAR['GGA'] = var_value
return dict_INCAR
def check_SOC(dict_INCAR):
if "SOC" in dict_INCAR.keys() and dict_INCAR["SOC"] == True:
dict_INCAR["LASPH"] = ".TRUE."
dict_INCAR["LSORBIT"] = ".TRUE."
dict_INCAR["GGA_COMPAT"] = ".TRUE."
dict_INCAR["SAXIS"] = "0 0 1"
dict_INCAR["ISYM"] = 0
del dict_INCAR["SOC"]
return dict_INCAR
def check_MD(dict_INCAR):
if "MD" in dict_INCAR.keys() and dict_INCAR["MD"] == True:
dict_INCAR["ISYM"] = 0
dict_INCAR["IBRION"] = 0
dict_INCAR["ISMEAR"] = 0
dict_INCAR["ALGO"] = "Very Fast"
dict_INCAR["LWAVE"] = ".FALSE."
dict_INCAR["LCHARG"] = ".FALSE."
if dict_INCAR["CPMD"]["Ensemble"] == "NVE":
dict_INCAR["MDALGO"] = 1
dict_INCAR["ANDERSEN_PROB"] = 0.0
dict_INCAR["ISIF"] = 2
dict_INCAR["SMASS"] = -3 # Nose-Hoover thermostat
else:
dict_INCAR["MDALGO"] = 2
dict_INCAR["ISIF"] = 2
dict_INCAR["SMASS"] = 0
dict_INCAR["SMASS"] = -3 # Nose Hoover thermostat
dict_INCAR["TEBEG"] = dict_INCAR["CPMD"]["TEBEG"] # Init temperature
dict_INCAR["TEEND"] = dict_INCAR["CPMD"]["TEEND"] # End temperature
print(dict_INCAR["CPMD"]["Ensemble"])
del dict_INCAR["MD"]
del dict_INCAR["CPMD"]
else:
del dict_INCAR["MD"]
del dict_INCAR["CPMD"]
return dict_INCAR
def check_Bader(dict_Analysis, dict_INCAR):
if "Bader" in dict_Analysis.keys() and dict_Analysis["Bader"] == True:
print('here2')
dict_INCAR["LCHARG"] = ".TRUE."
dict_INCAR["LAECHG"] = ".TRUE."
dict_INCAR["LREAL"] = "AUTO"
dict_INCAR["NGXF"] = dict_Analysis["Mesh"].get("NGXF")
dict_INCAR["NGYF"] = dict_Analysis["Mesh"].get("NGYF")
dict_INCAR["NGZF"] = dict_Analysis["Mesh"].get("NGZF")
return dict_INCAR
def check_DOS(dict_Analysis, dict_INCAR):
if "DOS" in dict_Analysis.keys() and dict_Analysis["DOS"] == True:
dict_INCAR["LORBIT"] = dict_Analysis["dos_calculation"].get("LORBIT")
dict_INCAR["NEDOS"] = dict_Analysis["dos_calculation"].get("NEDOS")
dict_INCAR["LORBIT"] = dict_Analysis["dos_calculation"].get("LORBIT")
dict_INCAR["NSW"] = dict_Analysis["dos_calculation"].get("NSW")
#dict_INCAR["ISMEAR"] = dict_Analysis["dos_calculation"].get("ISMEAR")
dict_INCAR["PREC"] = dict_Analysis["dos_calculation"].get("PREC")
return dict_INCAR
def check_Band_structure(dict_Analysis, dict_INCAR):
if "Band_Structure" in dict_Analysis.keys() and dict_Analysis["Band_Structure"] == True:
dict_INCAR["IBRION"] = dict_Analysis["band"].get("IBRION")
dict_INCAR["ICHARG"] = dict_Analysis["band"].get("ICHARG")
dict_INCAR["LORBIT"] = dict_Analysis["band"].get("LORBIT")
dict_INCAR["NSW"] = dict_Analysis["band"].get("NSW")
dict_INCAR["PREC"] = dict_Analysis["band"].get("PREC")
return dict_INCAR
if __name__ == '__main__':
with open('rendered_wano.yml') as file:
wano_file = yaml.full_load(file)
##############################################################################
label_var = wano_file["TABS"]["Files-Run"]["Title"]
structure = io.read("POSCAR")
write_vasp('POSCAR', structure, label=None, direct=True, vasp5=True, long_format=True)
# Create bash file
file_name = "run_vasp.sh"
with open(file_name, 'w') as f:
f.write('#!/bin/bash\n')
f.write('. /etc/profile.d/lmod.sh\n')
f.write('set -e\n')
f.write('module purge\n')
f.write('module load vasp prun\n')
f.write('\n')
if wano_file["TABS"]["INCAR"]["SOC"]:
f.write('prun vasp_ncl\n')
else:
f.write('prun ' + wano_file["TABS"]["Files-Run"]["prun_vasp"])
os.system("chmod +x " + file_name)
if os.path.isfile('INCAR'):
print("INCAR already loaded")
exit
else:
structure = Structure.from_file("POSCAR")
dict_INCAR = get_VASP_inputs(structure)
# Reading the inputs for INCAR file
for var_key, var_value in wano_file["TABS"]["INCAR"].items():
if var_key in dict_INCAR.keys():
dict_INCAR[var_key] = var_value
print(var_key, var_value)
else:
dict_INCAR[var_key] = var_value
dict_Analysis = {}
for var_key, var_value in wano_file["TABS"]["Analysis"].items():
if var_key == 'ENCUT':
var_value = float(var_value)
dict_Analysis[var_key] = var_value
dict_INCAR = check_vdw_functional(dict_INCAR)
dict_INCAR = check_hybrid_functionals(dict_INCAR)
dict_INCAR = check_SOC(dict_INCAR)
dict_INCAR = check_MD(dict_INCAR)
# Analysis in INCAR file
dict_INCAR = check_Bader(dict_Analysis, dict_INCAR)
dict_INCAR = check_DOS(dict_Analysis, dict_INCAR)
dict_INCAR = check_Band_structure(dict_Analysis, dict_INCAR)
incar = Incar.from_dict(dict_INCAR)
incar.write_file('INCAR')
print("INCAR successfully created")