-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVaspGeneralCalc.py
More file actions
168 lines (125 loc) · 8.18 KB
/
VaspGeneralCalc.py
File metadata and controls
168 lines (125 loc) · 8.18 KB
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
# This is the Script for Regulate the VASP Calculation Input files [INCAR] [KPOINTS]
# The General Calculation like: Single-Point Energy Calculation; Geometry Optimisation Calculation for Bulk and Slab; Cell Optimisation for Determining Relaxed Lattice Parameters; Nudeged-Elastic Band Calculations;
# To be Continued ...
# Author: Bingxin Li
# Date: 09/08/2024
# Contact: b.li@mpie.de
import numpy as np
import copy as cp
from pyiron.project import Project
class VaspInput():
"""
Class for inputing essential parameters for VASP Calculations
Attributes:
"""
def __init__(self,proj,basis,name,jobtype,cell_sys='bulk/pri_slab'):
'''
@proj:input the Pyiron project
@basis:input the structure generated by the Pyiron modules
@name:input the name for the submitting job
@jobtype:which type of calculation is: single-point energy calculation ("single_point"); geometry optimisation ("geo_opt"); cell relaxation ("vc_relax"); molecular dynamics ("md"); nudged-elastic band calculation
@cell_sys:system is a bulk or slab
'''
self.proj = proj
self.basis =cp.deepcopy(basis)
self.name = name
self.jobtype = jobtype # At present job type could be single_point, geo_opt, vc_relax
self.cell_sys = cell_sys
return
# Define a function to create a Pyiron-Vasp job
def JobCreator(self,pyironjob,jobres=False):
# IDK why they use ham but guess this represents hamiltonian
# Here we set-up a VASP-based calculation
self.ham = self.proj.create_job(pyironjob.job_type.Vasp, self.name, delete_existing_job=jobres)
self.ham.structure = self.basis
return(self.ham)
# Define a function to control some tricky parameters for Vasp calculation
def JobControl(self,ncore=1,kpar=1,irestart=0):
self.ham.input.incar['NCORE'] = ncore # Determines the number of compute cores that work on an individual orbital
self.ham.input.incar['KPAR'] = kpar # Determines the number of k-points that are to be treated in parallel
self.ham.input.incar['ISTART'] = irestart # Determines whether or not to read the WAVECAR file 0-not read 1-read
# Define a function to set-up the general input parameters for Vasp calcualtion
def JobGeneral(self,wave_function='F',charge_density='F',local_pot='T',elf='.FALSE.',dos=False,sym_precision=1e-8, gga_compact='.FALSE.'):
self.ham.input.incar['LWAVE'] = wave_function # Write wavefunctions
self.ham.input.incar['LCHARG'] = charge_density # Write charge densities
self.ham.input.incar['LVHAR'] = local_pot # Write the local potential, which contains hartree, ionic and xc
self.ham.input.incar['LELF'] = elf # Write the electron localisation distribution
self.ham.input.incar['SYMPREC'] = sym_precision # Determine to which accuracy the positions in the POSCAR
if dos != False:
self.ham.input.incar['LORBIT'] = dos # Wether to print DOSCAR/PROCAR/PROOUT
return(self.ham)
# Define a function to set-up the electronic relaxation parameters for Vasp calcualtion
def EleRelaxPara(self,elec_step_max=200,elec_step_min=3,elec_precision=1e-7,ener_cutoff=500, vdW=False):
self.vdW = vdW
self.ham.input.incar['NELM'] = elec_step_max # Max number for electronic optimisation
self.ham.input.incar['NELMIN'] = elec_step_min # Minimum number for electronic optimisation
self.ham.input.incar['EDIFF'] = elec_precision # Convergence criteria for electronic step
self.ham.input.incar['ENCUT'] = ener_cutoff # Energy Cutoff for the Calculation
self.ham.input.incar['PREC'] = 'A' # Precision preset
self.ham.input.incar['ALGO'] = 'N' # Normal Algorithm
self.ham.input.incar['IDIAG'] = 'T' # Sub-space diagonalisation
self.ham.input.incar['LREAL'] = 'F' # Automatic for real-space projection
if self.vdW == True:
self.ham.input.incar['IVDW'] = 11 # Consider dispersion correction: using DFT-D3 method for Grimme with Zero-damping function
self.ham.input.incar["VDW_RADIUS"] = 10 # Parameters used by previous calculation for Pt(111)-Water system
return(self.ham)
# Define a function to set-up the ionic (including geo-opt and cell-relax) relaxation parameters for Vasp calcualtion
def IonRelaxPara(self,relax_al=2,ionic_step=500,step_width=0.5,force_correction=True,force_threshold=-0.001,md_tmp=300,md_algo=3):
self.ham.input.incar['NSW'] = ionic_step # Number of ionic step
self.ham.input.incar['POTIM'] = step_width # Step-width in ionic relaxation
self.ham.input.incar['LCORR'] = force_correction # Harris correction to forces
self.ham.input.incar['IBRION'] = relax_al # Ionic Relax: 0-MD, 1-Quasi-Newton, 2-CG
# After the structure is relaxed to its local minimum, IBRION could be shifted from 2 to 1 to accelerate the convergence.
if self.jobtype == 'single_point':
self.ham.input.incar['NSW'] = 0
self.ham.input.incar['IBRION'] = -1 # No update for ion's position
elif self.jobtype == 'geo_opt':
self.ham.input.incar['ISIF'] = 2
self.ham.input.incar['EDIFFG'] = force_threshold
elif self.jobtype == 'vc_relax':
self.ham.input.incar['ISIF'] = 3
self.ham.input.incar['EDIFFG'] = force_threshold
elif self.jobtype == 'md':
self.ham.input.incar['ISIF'] = 2
self.ham.input.incar['EDIFFG'] = force_threshold
self.ham.input.incar['SMASS'] = 3 # Controls the velocities during an ab-initio molecular-dynamics run, SMASS > 0, a canonical ensemble is simulated using the algorithm of Nosé
self.ham.input.incar['TEBEG'] = md_tmp # Sets the starting temperature (in K) for an ab-initio molecular dynamics run
self.ham.input.incar['MDALGO'] = md_algo # Specifies the molecular-dynamics-simulation protocol: 1-Andersen thermostat; 2-Nose-Hoover thermostat; 3-Langevin thermostat
if md_algo == 3:
self.ham.input.incar["LANGEVIN_GAMMA"] = "0.5 0.5 0.5 0.5"
self.ham.input.incar['ISYM'] = 0 # VASP does not use symmetry. This value should be set for molecular dynamics
return(self.ham)
# Define a function to set-up the dipole-correction for the asymmetric slab calculations
def DipoleCorr(self,dipole_axis=3):
center_cell = [0., 0., (np.min(self.basis.get_scaled_positions()[:, 2]) +
np.max(self.basis.get_scaled_positions()[:, 2])) / 2.]
self.center_cell = " ".join([str(c) for c in center_cell])
if self.cell_sys == 'slab_ad':
self.ham.input.incar['LDIPOL'] = ".TRUE."
self.ham.input.incar['IDIPOL'] = dipole_axis # Which axis the dipole correction is on
self.ham.input.incar['DIPOL'] = self.center_cell # Center of mass of the atoms(slabs) in the unit cell
return(self.ham)
# Define a function to set-up the smearing parameters for Vasp calcualtion
def Smearing(self,smear_method=0,sigma=0.1):
self.ham.input.incar['ISMEAR'] = smear_method # Smearing method: 0-Gaussian method -1-Fermi Smearing
self.ham.input.incar['SIGMA'] = sigma # Smearing Parameters
return(self.ham)
# Define a function to set-up the K-Points for Vasp calcualtion
def KpoinsSetting(self,mesh=[2,2,2]):
if mesh == "GP":
# Only the Gamma point
self.ham.set_kpoints(scheme="GP")
elif len(mesh) == 3:
self.ham.set_kpoints(mesh=mesh)
return(self.ham)
# Define a function to set-up the pseudopotentials/functionals used for Vasp calcualtion
def Functionals(self,functional='PBE',gga=False):
self.ham.input.potcar["xc"] = functional
if gga == True:
self.ham.input.incar["GGA"] = "RP"
return(self.ham)
# Define a function to set-up the vasp_version for Vasp calcualtion
def ChooseVASP_Version(self,version='5.4.4_mpi'):
self.ham.executable.version = version
return(self.ham)
##### Todo: 1) Function for Accelerate/Parallel Setup VASP Calculation 2) Function for Setting up General Ab Initio Molecular Dynamics VASP Calculation #####