-
Notifications
You must be signed in to change notification settings - Fork 0
/
QE_jobs.py
162 lines (131 loc) · 5.76 KB
/
QE_jobs.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
import os
import subprocess
import yaml
from ase.build import bulk
from ase.io import read, write
def load_pseudopotentials_dict(pseudopotentials_path):
"""
Loads the dictionary of pseudopotentials from a specified path.
Parameters:
pseudopotentials_path (str): The path to the directory containing the pseudopotentials.yml file.
Returns:
dict: A dictionary where keys are element symbols and values are corresponding pseudopotential filenames.
"""
os.environ['ESPRESSO_PSEUDO'] = pseudopotentials_path
with open(os.path.join(pseudopotentials_path, "pseudopotentials.yml"), "r") as file:
pseudopotentials_dict = yaml.safe_load(file)
return pseudopotentials_dict
def run_quantum_espresso(input_file, output_file, pseudopotentials_path):
"""
Executes a Quantum ESPRESSO calculation using the specified input and output files.
Parameters:
input_file (str): The name of the Quantum ESPRESSO input file (e.g., 'output.pwi').
output_file (str): The name of the Quantum ESPRESSO output file (e.g., 'output.pwo').
pseudopotentials_path (str): The path to the directory containing pseudopotentials.
"""
os.environ['ESPRESSO_PSEUDO'] = pseudopotentials_path
command = ["mpirun", "-np", "1", "pw.x", "-in", input_file]
with open(output_file, 'w') as file:
subprocess.run(command, stdout=file, stderr=subprocess.STDOUT)
def create_relax_pwi(element, lattice_param, cubic, kpts, output_filename,
pseudopotentials_path, pseudopotentials_dict):
"""
Creates a Quantum ESPRESSO input file ('output.pwi') for a crystal structure relaxation.
Parameters:
element (str): The chemical symbol of the element to create the bulk structure.
lattice_param (float): The lattice parameter for the bulk structure.
cubic (bool): Flag to determine if the structure should be cubic.
kpts (tuple): A tuple representing the k-points grid (e.g., (3, 3, 3)).
pseudopotentials_path (str): The path to the directory containing pseudopotentials.
pseudopotentials_dict (dict): Dictionary of element-symbol to pseudopotential filename mappings.
"""
os.environ['ESPRESSO_PSEUDO'] = pseudopotentials_path
pseudopotential_file = pseudopotentials_dict[element]
pseudopotentials = {element: pseudopotential_file}
structure = bulk(element, a=lattice_param, cubic=cubic)
input_data_relax = {
'calculation': 'vc-relax',
'cell_dofree': 'ibrav',
}
write(
output_filename,
structure,
kpts=kpts,
input_data=input_data_relax,
pseudopotentials=pseudopotentials,
tstress=True,
tprnfor=True
)
def write_input_file(element, file_pattern, output_filename, kpts, pseudopotentials_path,
pseudopotentials_dict):
"""
Writes the input file for strain calculation or other type of calculation.
Parameters:
element (str): The chemical symbol of the structure's element.
file_pattern (str): File pattern for reading the strained structure files (not used in this template).
output_filename (str): Path to the output file for PWscf input strain ('output.pwi').
kpts (tuple): A tuple representing the k-points grid.
pseudopotentials_path (str): The path to the directory containing pseudopotentials.
pseudopotentials_dict (dict): Dictionary of element-symbol to pseudopotential filename mappings.
"""
os.environ['ESPRESSO_PSEUDO'] = pseudopotentials_path
pseudopotential_file = pseudopotentials_dict[element]
pseudopotentials = {element: pseudopotential_file}
input_data_static = {'calculation': 'scf'}
structure_strain = read(file_pattern)
write(
output_filename,
structure_strain,
kpts=kpts,
input_data=input_data_static,
pseudopotentials=pseudopotentials,
tstress=True,
tprnfor=True
)
def read_structure_xyz(xyz_file):
"""
Reads a structure from a .xyz file and extracts the element, lattice parameters and whether it's cubic.
Parameters:
xyz_file (str): The path to the .xyz file containing the structure information.
Returns:
Atoms object: The first structure read from the .xyz file.
"""
atoms = read(xyz_file, index=0)
return atoms
if __name__ == '__main__':
with open("rendered_wano.yml", "r") as file:
params = yaml.safe_load(file)
kpts = tuple(map(int, params['kpts'].split(',')))
structure_file = "structure.xyz"
atoms = read_structure_xyz(structure_file)
lattice_param = atoms.cell.lengths()[0]
cubic = True if len(set(atoms.cell.lengths())) == 1 else False
element = atoms.get_chemical_symbols()[0]
pseudopotentials_path = '/home/ws/aj3373/pseudopotentials'
pseudopotentials_dict = load_pseudopotentials_dict(pseudopotentials_path)
calculation_mode = params.get('Type of job')
if calculation_mode == 'Relaxation':
create_relax_pwi(
element=element,
lattice_param=lattice_param,
cubic=cubic,
output_filename='output.pwi',
kpts=kpts,
pseudopotentials_path=pseudopotentials_path,
pseudopotentials_dict=pseudopotentials_dict
)
input_file = 'output.pwi'
elif calculation_mode == 'Calculation energy':
write_input_file(
element=element,
kpts=kpts,
file_pattern='structure_strain.traj',
output_filename='output.pwi',
pseudopotentials_path=pseudopotentials_path,
pseudopotentials_dict=pseudopotentials_dict
)
input_file = 'output.pwi'
else:
raise ValueError("Unsupported mode specified in 'rendered_wano.yml'.")
output_file = "output.pwo"
run_quantum_espresso(input_file, output_file, pseudopotentials_path)