Révision 1d8c374e modules/formats.py
b/modules/formats.py | ||
---|---|---|
166 | 166 |
force_eval = cp2k.CP2K_INPUT.FORCE_EVAL_list[0] |
167 | 167 |
raw_coords = force_eval.SUBSYS.COORD.Default_keyword |
168 | 168 |
symbols = [atom.split()[0] for atom in raw_coords] |
169 |
positions = np.array([atom.split()[1:] for atom in raw_coords]) |
|
169 |
positions = np.array([[float(coord) for coord in atom.split()[1:]] |
|
170 |
for atom in raw_coords]) |
|
170 | 171 |
if len(spec_atoms) > 0: |
171 | 172 |
add_special_atoms(spec_atoms) |
172 | 173 |
return Atoms(symbols=symbols, positions=positions) |
... | ... | |
190 | 191 |
return ase.io.read(file) |
191 | 192 |
|
192 | 193 |
|
193 |
def collect_coords(conf_list, code, run_type, spec_atms=tuple()): |
|
194 |
"""Directs the reading of coordinates on a set of subdirectories. |
|
195 |
|
|
196 |
Given a dockonsurf directory hierarchy: project/run_type/conf_X |
|
197 |
(run_type = ['isolated', 'screening' or 'refinement']) with finished |
|
198 |
calculations produced by a given code, stored in every conf_X subdirectory, |
|
199 |
it collects the coordinates of the specified conf_X subdirectories in a |
|
200 |
single run_type by calling the adequate function (depending on the code) and |
|
201 |
returns a list of ase.Atoms objects. |
|
202 |
|
|
203 |
@param conf_list: List of directories where to read the coords from. |
|
204 |
@param code: the code that produced the calculation results files. |
|
205 |
@param run_type: the type of calculation (and also the name of the folder) |
|
206 |
containing the calculation subdirectories. |
|
207 |
@param spec_atms: List of tuples containing pairs of new/traditional |
|
208 |
chemical symbols. |
|
209 |
@return: list of ase.Atoms objects. |
|
210 |
""" |
|
211 |
from glob import glob |
|
212 |
atoms_list = [] |
|
213 |
for conf in conf_list: |
|
214 |
if code == 'cp2k': |
|
215 |
atoms_list.append(read_coords_cp2k(glob(f"{run_type}/{conf}/*-1" |
|
216 |
f".restart")[0], spec_atms)) |
|
217 |
elif code == 'vasp': |
|
218 |
atoms_list.append(read_coords_vasp(f"{run_type}/{conf}/OUTCAR", |
|
219 |
spec_atms)) |
|
220 |
else: |
|
221 |
err_msg = f"Collect coordinates not implemented for '{code}'." |
|
222 |
logger.error(err_msg) |
|
223 |
raise NotImplementedError(err_msg) |
|
224 |
return atoms_list |
|
225 |
|
|
226 |
|
|
227 | 194 |
def read_energy_cp2k(file): |
228 |
"""Reads the CP2K out file and returns its final energy. |
|
195 |
"""Reads the CP2K output file and returns its final energy.
|
|
229 | 196 |
|
230 | 197 |
@param file: The file from which the energy should be read. |
231 |
@return: The last energy on the out file. |
|
198 |
@return: The last energy on the out file in eV.
|
|
232 | 199 |
""" |
233 | 200 |
out_fh = open(file, 'r') |
234 | 201 |
energy = None |
... | ... | |
239 | 206 |
return energy |
240 | 207 |
|
241 | 208 |
|
242 |
def collect_energies(conf_list, code, run_type):
|
|
243 |
"""Directs the reading of energies on a set of subdirectories.
|
|
209 |
def collect_confs(dir_list, code, run_type, spec_atms=tuple()):
|
|
210 |
"""Reads the coordinates and energies of a list of finished calculations.
|
|
244 | 211 |
|
245 | 212 |
Given a dockonsurf directory hierarchy: project/run_type/conf_X |
246 |
(run_type = ['isolated', 'screening' or 'refinement']) with finished |
|
247 |
calculations produced by a given code, stored in every conf_X subdirectory, |
|
248 |
it collects the energies of the specified conf_X subdirectories in a |
|
249 |
single run_type by calling the adequate function (depending on the code) and |
|
250 |
returns a list of energies. |
|
251 |
|
|
252 |
@param conf_list: List of directories where to read the energy. |
|
253 |
@param code: The code that produced the calculation output files. |
|
254 |
@param run_type: The type of calculation (and also the name of the folder) |
|
255 |
containing the calculation subdirectories. |
|
256 |
@return: List of energies |
|
213 |
(run_type = ['isolated', 'screening' or 'refinement']) it reads the |
|
214 |
coordinates of each conf_X, it assigns its total energy from the calculation |
|
215 |
and assigns the conf_X label to track its origin. Finally it returns the |
|
216 |
ase.Atoms object. |
|
217 |
|
|
218 |
@param dir_list: List of directories where to read the coords from. |
|
219 |
@param code: the code that produced the calculation results files. |
|
220 |
@param run_type: the type of calculation (and also the name of the folder) |
|
221 |
containing the calculation subdirectories. |
|
222 |
@param spec_atms: List of tuples containing pairs of new/traditional |
|
223 |
chemical symbols. |
|
224 |
@return: list of ase.Atoms objects. |
|
257 | 225 |
""" |
258 | 226 |
from glob import glob |
259 |
import numpy as np |
|
260 |
|
|
261 |
energies = [] |
|
262 |
for conf in conf_list: |
|
227 |
import os |
|
228 |
from modules.utilities import is_binary |
|
229 |
atoms_list = [] |
|
230 |
for conf_dir in dir_list: |
|
231 |
conf_path = f"{run_type}/{conf_dir}/" |
|
263 | 232 |
if code == 'cp2k': |
264 |
energies.append(read_energy_cp2k( |
|
265 |
glob(f"{run_type}/{conf}/*.out")[0])) |
|
233 |
ase_atms = read_coords_cp2k(glob(f"{conf_path}/*-1.restart")[0], |
|
234 |
spec_atms) |
|
235 |
# Assign energy |
|
236 |
for fil in os.listdir(conf_path): |
|
237 |
if is_binary(conf_path+fil): |
|
238 |
continue |
|
239 |
conf_energy = read_energy_cp2k(conf_path+fil) |
|
240 |
if conf_energy is not None: |
|
241 |
ase_atms.info["energy"] = conf_energy |
|
242 |
break |
|
243 |
ase_atms.info[run_type[:3]] = conf_dir |
|
244 |
atoms_list.append(ase_atms) |
|
245 |
elif code == 'vasp': |
|
246 |
ase_atms = read_coords_vasp(f"{conf_path}/OUTCAR", spec_atms) |
|
247 |
ase_atms.info["energy"] = ase_atms.get_total_energy() * 27.2113845 |
|
248 |
ase_atms.info[run_type[:3]] = conf_dir |
|
249 |
atoms_list.append(ase_atms) |
|
266 | 250 |
else: |
267 |
err_msg = f"Collect energies not implemented for '{code}'."
|
|
251 |
err_msg = f"Collect coordinates not implemented for '{code}'."
|
|
268 | 252 |
logger.error(err_msg) |
269 | 253 |
raise NotImplementedError(err_msg) |
254 |
return atoms_list |
|
270 | 255 |
|
271 |
if len(energies) == 0: |
|
272 |
err = f"No results found on {run_type}" |
|
273 |
logger.error(err) |
|
274 |
raise FileNotFoundError(err) |
|
275 |
|
|
276 |
return np.array(energies) |
Formats disponibles : Unified diff