From fb9111ed549445ce4b1564c9aab88e2dec388522 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Thu, 17 Aug 2023 11:05:20 -0600 Subject: [PATCH 1/8] Refactor the VASP collect_output() parser --- .../atomistics/structure/atoms.py | 118 ++++++++----- .../atomistics/structure/periodic_table.py | 35 ++-- pyiron_atomistics/dft/waves/electronic.py | 63 ++++--- pyiron_atomistics/vasp/base.py | 161 +++++++++++++----- pyiron_atomistics/vasp/outcar.py | 14 +- pyiron_atomistics/vasp/volumetric_data.py | 25 ++- 6 files changed, 288 insertions(+), 128 deletions(-) diff --git a/pyiron_atomistics/atomistics/structure/atoms.py b/pyiron_atomistics/atomistics/structure/atoms.py index 0fc49d6cf..da0f2d6f6 100644 --- a/pyiron_atomistics/atomistics/structure/atoms.py +++ b/pyiron_atomistics/atomistics/structure/atoms.py @@ -34,6 +34,7 @@ from pyiron_atomistics.atomistics.structure.periodic_table import ( PeriodicTable, ChemicalElement, + chemical_element_dict_to_hdf, ) from pyiron_base import state, deprecate from collections.abc import Sequence @@ -447,6 +448,52 @@ def copy(self): """ return self.__copy__() + def to_dict(self): + hdf_structure = { + "TYPE": str(type(self)), + "units": self.units, + "dimension": self.dimension, + "positions": self.positions, + "info": self.info, + } + for el in self.species: + if isinstance(el.tags, dict): + if "new_species" not in hdf_structure.keys(): + hdf_structure["new_species"] = {} + hdf_structure["new_species"][el.Abbreviation] = el.to_dict() + hdf_structure["species"] = [el.Abbreviation for el in self.species] + hdf_structure["indices"] = self.indices + + for tag, value in self.arrays.items(): + if tag in ["positions", "numbers", "indices"]: + continue + hdf_structure["tags"][tag] = value.tolist() + + if self.cell is not None: + # Convert ASE cell object to numpy array before storing + hdf_structure["cell"] = {"cell": np.array(self.cell), "pbc": self.pbc} + + if self.has("initial_magmoms"): + hdf_structure["spins"] = self.spins + # potentials with explicit bonds (TIP3P, harmonic, etc.) + if self.bonds is not None: + hdf_structure["explicit_bonds"] = self.bonds + + if self._high_symmetry_points is not None: + hdf_structure["high_symmetry_points"] = self._high_symmetry_points + + if self._high_symmetry_path is not None: + hdf_structure["high_symmetry_path"] = self._high_symmetry_path + + if self.calc is not None: + calc_dict = self.calc.todict() + calc_dict["label"] = self.calc.label + calc_dict["class"] = ( + self.calc.__class__.__module__ + "." + self.calc.__class__.__name__ + ) + hdf_structure["calculator"] = calc_dict + return hdf_structure + def to_hdf(self, hdf, group_name="structure"): """ Save the object in a HDF5 file @@ -457,53 +504,7 @@ def to_hdf(self, hdf, group_name="structure"): Group name with which the object should be stored. This same name should be used to retrieve the object """ - # import time - with hdf.open(group_name) as hdf_structure: - hdf_structure["TYPE"] = str(type(self)) - for el in self.species: - if isinstance(el.tags, dict): - with hdf_structure.open("new_species") as hdf_species: - el.to_hdf(hdf_species) - hdf_structure["species"] = [el.Abbreviation for el in self.species] - hdf_structure["indices"] = self.indices - - with hdf_structure.open("tags") as hdf_tags: - for tag, value in self.arrays.items(): - if tag in ["positions", "numbers", "indices"]: - continue - hdf_tags[tag] = value.tolist() - hdf_structure["units"] = self.units - hdf_structure["dimension"] = self.dimension - - if self.cell is not None: - with hdf_structure.open("cell") as hdf_cell: - # Convert ASE cell object to numpy array before storing - hdf_cell["cell"] = np.array(self.cell) - hdf_cell["pbc"] = self.pbc - - # hdf_structure["coordinates"] = self.positions # "Atomic coordinates" - hdf_structure["positions"] = self.positions # "Atomic coordinates" - if self.has("initial_magmoms"): - hdf_structure["spins"] = self.spins - # potentials with explicit bonds (TIP3P, harmonic, etc.) - if self.bonds is not None: - hdf_structure["explicit_bonds"] = self.bonds - - if self._high_symmetry_points is not None: - hdf_structure["high_symmetry_points"] = self._high_symmetry_points - - if self._high_symmetry_path is not None: - hdf_structure["high_symmetry_path"] = self._high_symmetry_path - - hdf_structure["info"] = self.info - - if self.calc is not None: - calc_dict = self.calc.todict() - calc_dict["label"] = self.calc.label - calc_dict["class"] = ( - self.calc.__class__.__module__ + "." + self.calc.__class__.__name__ - ) - hdf_structure["calculator"] = calc_dict + structure_dict_to_hdf(data_dict=self.to_dict(), hdf=hdf, group_name=group_name) def from_hdf(self, hdf, group_name="structure"): """ @@ -3439,3 +3440,26 @@ def __setitem__(self, key, value): ) for i, el in enumerate(replace_elements): self._structure[index_array[i]] = el + + +def structure_dict_to_hdf(data_dict, hdf, group_name="structure"): + with hdf.open(group_name) as hdf_structure: + for k, v in data_dict.items(): + if k not in ["new_species", "cell", "tags"]: + hdf_structure[k] = v + + if "new_species" in data_dict.keys(): + for el, el_dict in data_dict["new_species"].items(): + chemical_element_dict_to_hdf( + data_dict=el_dict, hdf=hdf, group_name="new_species/" + el + ) + + dict_group_to_hdf(data_dict=data_dict, hdf=hdf_structure, group="tags") + dict_group_to_hdf(data_dict=data_dict, hdf=hdf_structure, group="cell") + + +def dict_group_to_hdf(data_dict, hdf, group): + if group in data_dict.keys(): + with hdf.open(group) as hdf_tags: + for k, v in data_dict[group].items(): + hdf_tags[k] = v diff --git a/pyiron_atomistics/atomistics/structure/periodic_table.py b/pyiron_atomistics/atomistics/structure/periodic_table.py index e11a9b0fa..6c88b4b54 100644 --- a/pyiron_atomistics/atomistics/structure/periodic_table.py +++ b/pyiron_atomistics/atomistics/structure/periodic_table.py @@ -154,22 +154,27 @@ def add_tags(self, tag_dic): """ (self.sub["tags"]).update(tag_dic) + def to_dict(self): + hdf_el = {} + # TODO: save all parameters that are different from the parent (e.g. modified mass) + if self.Parent is not None: + self._dataset = {"Parameter": ["Parent"], "Value": [self.Parent]} + hdf_el["elementData"] = self._dataset + for key in self.tags.keys(): + hdf_el["tagData"][key] = self.tags[ + key + ] # "Dictionary of element tag static" + return hdf_el + def to_hdf(self, hdf): """ saves the element with his parameters into his hdf5 job file Args: hdf (Hdfio): Hdfio object which will be used """ - with hdf.open(self.Abbreviation) as hdf_el: # "Symbol of the chemical element" - # TODO: save all parameters that are different from the parent (e.g. modified mass) - if self.Parent is not None: - self._dataset = {"Parameter": ["Parent"], "Value": [self.Parent]} - hdf_el["elementData"] = self._dataset - with hdf_el.open( - "tagData" - ) as hdf_tag: # "Dictionary of element tag static" - for key in self.tags.keys(): - hdf_tag[key] = self.tags[key] + chemical_element_dict_to_hdf( + data_dict=self.to_dict(), hdf=hdf, group_name=self.Abbreviation + ) def from_hdf(self, hdf): """ @@ -424,3 +429,13 @@ def _get_periodic_table_df(file_name): + file_name + " supported file formats are csv, h5." ) + + +def chemical_element_dict_to_hdf(data_dict, hdf, group_name): + with hdf.open(group_name) as hdf_el: + if "elementData" in data_dict.keys(): + hdf_el["elementData"] = data_dict["elementData"] + with hdf_el.open("tagData") as hdf_tag: + if "tagData" in data_dict.keys(): + for k, v in data_dict["tagData"].items(): + hdf_tag[k] = v diff --git a/pyiron_atomistics/dft/waves/electronic.py b/pyiron_atomistics/dft/waves/electronic.py index 97de8747d..2f9ac59ba 100644 --- a/pyiron_atomistics/dft/waves/electronic.py +++ b/pyiron_atomistics/dft/waves/electronic.py @@ -6,7 +6,11 @@ import numpy as np -from pyiron_atomistics.atomistics.structure.atoms import Atoms +from pyiron_atomistics.atomistics.structure.atoms import ( + Atoms, + structure_dict_to_hdf, + dict_group_to_hdf, +) from pyiron_atomistics.dft.waves.dos import Dos __author__ = "Sudarsan Surendralal" @@ -481,24 +485,33 @@ def to_hdf(self, hdf, group_name="electronic_structure"): hdf: Path to the hdf5 file/group in the file group_name: Name of the group under which the attributes are o be stored """ - with hdf.open(group_name) as h_es: - h_es["TYPE"] = str(type(self)) - if self.structure is not None: - self.structure.to_hdf(h_es) - h_es["k_points"] = self.kpoint_list - h_es["k_weights"] = self.kpoint_weights - h_es["eig_matrix"] = self.eigenvalue_matrix - h_es["occ_matrix"] = self.occupancy_matrix - if self.efermi is not None: - h_es["efermi"] = self.efermi - with h_es.open("dos") as h_dos: - h_dos["energies"] = self.dos_energies - h_dos["tot_densities"] = self.dos_densities - h_dos["int_densities"] = self.dos_idensities - if self.grand_dos_matrix is not None: - h_dos["grand_dos_matrix"] = self.grand_dos_matrix - if self.resolved_densities is not None: - h_dos["resolved_densities"] = self.resolved_densities + electronic_structure_dict_to_hdf( + data_dict=self.to_dict(), hdf=hdf, group_name=group_name + ) + + def to_dict(self): + h_es = { + "TYPE": str(type(self)), + "k_points": self.kpoint_list, + "k_weights": self.kpoint_weights, + "eig_matrix": self.eigenvalue_matrix, + "occ_matrix": self.occupancy_matrix, + } + if self.structure is not None: + h_es["structure"] = self.structure.to_dict() + if self.efermi is not None: + h_es["efermi"] = self.efermi + + h_es["dos"] = { + "energies": self.dos_energies, + "tot_densities": self.dos_densities, + "int_densities": self.dos_idensities, + } + if self.grand_dos_matrix is not None: + h_es["dos"]["grand_dos_matrix"] = self.grand_dos_matrix + if self.resolved_densities is not None: + h_es["dos"]["resolved_densities"] = self.resolved_densities + return h_es def from_hdf(self, hdf, group_name="electronic_structure"): """ @@ -841,3 +854,15 @@ def resolved_dos_matrix(self): @resolved_dos_matrix.setter def resolved_dos_matrix(self, val): self._resolved_dos_matrix = val + + +def electronic_structure_dict_to_hdf(data_dict, hdf, group_name): + with hdf.open(group_name) as h_es: + for k, v in data_dict.items(): + if k not in ["structure", "dos"]: + h_es[k] = v + + if "structure" in data_dict.keys(): + structure_dict_to_hdf(data_dict=data_dict["structure"], hdf=h_es) + + dict_group_to_hdf(data_dict=data_dict, hdf=h_es, group="dos") diff --git a/pyiron_atomistics/vasp/base.py b/pyiron_atomistics/vasp/base.py index 62521f21c..92216cba0 100644 --- a/pyiron_atomistics/vasp/base.py +++ b/pyiron_atomistics/vasp/base.py @@ -16,7 +16,12 @@ Potcar, strip_xc_from_potential_name, ) -from pyiron_atomistics.atomistics.structure.atoms import Atoms, CrystalStructure +from pyiron_atomistics.atomistics.structure.atoms import ( + Atoms, + CrystalStructure, + structure_dict_to_hdf, + dict_group_to_hdf, +) from pyiron_base import state, GenericParameters, deprecate from pyiron_atomistics.vasp.outcar import Outcar from pyiron_atomistics.vasp.oszicar import Oszicar @@ -24,9 +29,15 @@ from pyiron_atomistics.vasp.structure import read_atoms, write_poscar, vasp_sorter from pyiron_atomistics.vasp.vasprun import Vasprun as Vr from pyiron_atomistics.vasp.vasprun import VasprunError, VasprunWarning -from pyiron_atomistics.vasp.volumetric_data import VaspVolumetricData +from pyiron_atomistics.vasp.volumetric_data import ( + VaspVolumetricData, + volumetric_data_dict_to_hdf, +) from pyiron_atomistics.vasp.potential import get_enmax_among_potentials -from pyiron_atomistics.dft.waves.electronic import ElectronicStructure +from pyiron_atomistics.dft.waves.electronic import ( + ElectronicStructure, + electronic_structure_dict_to_hdf, +) from pyiron_atomistics.dft.waves.bandstructure import Bandstructure from pyiron_atomistics.dft.bader import Bader import warnings @@ -376,8 +387,7 @@ def write_input(self): modified_elements=modified_elements, ) - # define routines that collect all output files - def collect_output(self): + def collect_output_parser(self): """ Collects the outputs and stores them to the hdf file """ @@ -431,7 +441,16 @@ def collect_output(self): self._output_parser.generic_output.dft_log_dict[ "bader_volumes" ] = volumes - self._output_parser.to_hdf(self._hdf5) + return self._output_parser.to_dict() + + # define routines that collect all output files + def collect_output(self): + """ + Collects the outputs and stores them to the hdf file + """ + output_dict_to_hdf( + data_dict=self.collect_output_parser(), hdf=self._hdf5, group_name="output" + ) if len(self._exclude_groups_hdf) > 0 or len(self._exclude_nodes_hdf) > 0: self.project_hdf5.rewrite_hdf5() @@ -2199,6 +2218,30 @@ def collect(self, directory=os.getcwd(), sorted_indices=None): ) self.generic_output.bands = self.electronic_structure + def to_dict(self): + hdf5_output = { + "description": self.description, + "generic": self.generic_output.to_dict(), + } + + if self._structure is not None: + hdf5_output["structure"] = self.structure.to_dict() + + if self.electrostatic_potential.total_data is not None: + hdf5_output[ + "electrostatic_potential" + ] = self.electrostatic_potential.to_dict() + + if self.charge_density.total_data is not None: + hdf5_output["charge_density"] = self.charge_density.to_dict() + + if len(self.electronic_structure.kpoint_list) > 0: + hdf5_output["electronic_structure"] = self.electronic_structure.to_dict() + + if len(self.outcar.parse_dict.keys()) > 0: + hdf5_output["outcar"] = self.outcar.to_dict_minimal() + return hdf5_output + def to_hdf(self, hdf): """ Save the object in a HDF5 file @@ -2207,34 +2250,7 @@ def to_hdf(self, hdf): hdf (pyiron_base.generic.hdfio.ProjectHDFio): HDF path to which the object is to be saved """ - with hdf.open("output") as hdf5_output: - hdf5_output["description"] = self.description - self.generic_output.to_hdf(hdf5_output) - try: - self.structure.to_hdf(hdf5_output) - except AttributeError: - pass - - # with hdf5_output.open("vasprun") as hvr: - # if self.vasprun.dict_vasprun is not None: - # for key, val in self.vasprun.dict_vasprun.items(): - # hvr[key] = val - - if self.electrostatic_potential.total_data is not None: - self.electrostatic_potential.to_hdf( - hdf5_output, group_name="electrostatic_potential" - ) - - if self.charge_density.total_data is not None: - self.charge_density.to_hdf(hdf5_output, group_name="charge_density") - - if len(self.electronic_structure.kpoint_list) > 0: - self.electronic_structure.to_hdf( - hdf=hdf5_output, group_name="electronic_structure" - ) - - if len(self.outcar.parse_dict.keys()) > 0: - self.outcar.to_hdf_minimal(hdf=hdf5_output, group_name="outcar") + output_dict_to_hdf(data_dict=self.to_dict(), hdf=hdf, group_name="output") def from_hdf(self, hdf): """ @@ -2297,15 +2313,19 @@ def to_hdf(self, hdf): hdf (pyiron_base.generic.hdfio.ProjectHDFio): HDF path to which the object is to be saved """ - with hdf.open("generic") as hdf_go: - # hdf_go["description"] = self.description - for key, val in self.log_dict.items(): - hdf_go[key] = val - with hdf_go.open("dft") as hdf_dft: - for key, val in self.dft_log_dict.items(): - hdf_dft[key] = val - if self.bands.eigenvalue_matrix is not None: - self.bands.to_hdf(hdf_dft, "bands") + generic_output_dict_to_hdf( + data_dict=self.to_dict(), hdf=hdf, group_name="generic" + ) + + def to_dict(self): + hdf_go = {} + for key, val in self.log_dict.items(): + hdf_go[key] = val + for key, val in self.dft_log_dict.items(): + hdf_go["dft"][key] = val + if self.bands.eigenvalue_matrix is not None: + hdf_go["bands"] = self.bands.to_dict() + return hdf_go def from_hdf(self, hdf): """ @@ -2527,3 +2547,58 @@ def get_k_mesh_by_cell(cell, kspace_per_in_ang=0.10): class VaspCollectError(ValueError): pass + + +def generic_output_dict_to_hdf(data_dict, hdf, group_name="generic"): + with hdf.open(group_name) as hdf_go: + for k, v in data_dict.items(): + if k not in ["dft"]: + hdf_go[k] = v + + with hdf_go.open("dft") as hdf_dft: + for k, v in data_dict["dft"].items(): + if k not in ["bands"]: + hdf_dft[k] = v + + if "bands" in data_dict["dft"].keys: + electronic_structure_dict_to_hdf( + data_dict=data_dict["dft"]["bands"], + hdf=hdf_dft, + group_name="bands", + ) + + +def output_dict_to_hdf(data_dict, hdf, group_name="output"): + with hdf.open(group_name) as hdf5_output: + for k, v in data_dict.items(): + if k not in ["structure"]: + hdf5_output[k] = v + + if "structure" in data_dict.keys(): + structure_dict_to_hdf( + data_dict=data_dict["structure"], + hdf=hdf5_output, + group_name="structure", + ) + + if "electrostatic_potential" in data_dict.keys(): + volumetric_data_dict_to_hdf( + data_dict=data_dict["electrostatic_potential"], + hdf=hdf5_output, + group_name="electrostatic_potential", + ) + + if "charge_density" in data_dict.keys(): + volumetric_data_dict_to_hdf( + data_dict=data_dict["charge_density"], + hdf=hdf5_output, + group_name="charge_density", + ) + + electronic_structure_dict_to_hdf( + data_dict=data_dict["electronic_structure"], + hdf=hdf5_output, + group_name="electronic_structure", + ) + + dict_group_to_hdf(data_dict=data_dict, hdf=hdf5_output, group="outcar") diff --git a/pyiron_atomistics/vasp/outcar.py b/pyiron_atomistics/vasp/outcar.py index be1844016..cd4619428 100644 --- a/pyiron_atomistics/vasp/outcar.py +++ b/pyiron_atomistics/vasp/outcar.py @@ -152,6 +152,12 @@ def to_hdf_minimal(self, hdf, group_name="outcar"): hdf (pyiron_base.generic.hdfio.FileHDFio): HDF5 group or file group_name (str): Name of the HDF5 group """ + with hdf.open(group_name) as hdf5_output: + for k, v in self.to_dict_minimal().items(): + hdf5_output[k] = v + + def to_dict_minimal(self): + hdf5_output = {} unique_quantities = [ "kin_energy_error", "broyden_mixing", @@ -162,10 +168,10 @@ def to_hdf_minimal(self, hdf, group_name="outcar"): "energy_components", "resources", ] - with hdf.open(group_name) as hdf5_output: - for key in self.parse_dict.keys(): - if key in unique_quantities: - hdf5_output[key] = self.parse_dict[key] + for key in self.parse_dict.keys(): + if key in unique_quantities: + hdf5_output[key] = self.parse_dict[key] + return hdf5_output def from_hdf(self, hdf, group_name="outcar"): """ diff --git a/pyiron_atomistics/vasp/volumetric_data.py b/pyiron_atomistics/vasp/volumetric_data.py index 86b1baa33..8f52898ac 100644 --- a/pyiron_atomistics/vasp/volumetric_data.py +++ b/pyiron_atomistics/vasp/volumetric_data.py @@ -277,6 +277,15 @@ def diff_data(self): def diff_data(self, val): self._diff_data = val + def to_dict(self): + volumetric_data_dict = { + "TYPE": str(type(self)), + "total": self.total_data, + } + if self.diff_data is not None: + volumetric_data_dict["diff"] = self.diff_data + return volumetric_data_dict + def to_hdf(self, hdf, group_name="volumetric_data"): """ Writes the data as a group to a HDF5 file @@ -286,11 +295,11 @@ def to_hdf(self, hdf, group_name="volumetric_data"): group_name (str): The name of the group under which the data must be stored as """ - with hdf.open(group_name) as hdf_vd: - hdf_vd["TYPE"] = str(type(self)) - hdf_vd["total"] = self.total_data - if self.diff_data is not None: - hdf_vd["diff"] = self.diff_data + volumetric_data_dict_to_hdf( + data_dict=self.to_dict(), + hdf=hdf, + group_name=group_name, + ) def from_hdf(self, hdf, group_name="volumetric_data"): """ @@ -308,3 +317,9 @@ def from_hdf(self, hdf, group_name="volumetric_data"): self._total_data = hdf_vd["total"] if "diff" in hdf_vd.list_nodes(): self._diff_data = hdf_vd["diff"] + + +def volumetric_data_dict_to_hdf(data_dict, hdf, group_name="volumetric_data"): + with hdf.open(group_name) as hdf_vd: + for k, v in data_dict.items(): + hdf_vd[k] = v From f92c4b7c5d50bd7aacecd61f83dcc8160b23cfd1 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Thu, 17 Aug 2023 11:25:15 -0600 Subject: [PATCH 2/8] some fixes --- pyiron_atomistics/atomistics/structure/atoms.py | 2 ++ .../atomistics/structure/periodic_table.py | 9 +++++---- pyiron_atomistics/vasp/base.py | 11 ++++++----- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/pyiron_atomistics/atomistics/structure/atoms.py b/pyiron_atomistics/atomistics/structure/atoms.py index da0f2d6f6..139e6b03a 100644 --- a/pyiron_atomistics/atomistics/structure/atoms.py +++ b/pyiron_atomistics/atomistics/structure/atoms.py @@ -467,6 +467,8 @@ def to_dict(self): for tag, value in self.arrays.items(): if tag in ["positions", "numbers", "indices"]: continue + if "tags" not in hdf_structure.keys(): + hdf_structure["tags"] = {} hdf_structure["tags"][tag] = value.tolist() if self.cell is not None: diff --git a/pyiron_atomistics/atomistics/structure/periodic_table.py b/pyiron_atomistics/atomistics/structure/periodic_table.py index 6c88b4b54..ee11db015 100644 --- a/pyiron_atomistics/atomistics/structure/periodic_table.py +++ b/pyiron_atomistics/atomistics/structure/periodic_table.py @@ -160,10 +160,11 @@ def to_dict(self): if self.Parent is not None: self._dataset = {"Parameter": ["Parent"], "Value": [self.Parent]} hdf_el["elementData"] = self._dataset - for key in self.tags.keys(): - hdf_el["tagData"][key] = self.tags[ - key - ] # "Dictionary of element tag static" + # "Dictionary of element tag static" + hdf_el["tagData"] = { + key: self.tags[key] + for key in self.tags.keys() + } return hdf_el def to_hdf(self, hdf): diff --git a/pyiron_atomistics/vasp/base.py b/pyiron_atomistics/vasp/base.py index 92216cba0..cf87aef84 100644 --- a/pyiron_atomistics/vasp/base.py +++ b/pyiron_atomistics/vasp/base.py @@ -2595,10 +2595,11 @@ def output_dict_to_hdf(data_dict, hdf, group_name="output"): group_name="charge_density", ) - electronic_structure_dict_to_hdf( - data_dict=data_dict["electronic_structure"], - hdf=hdf5_output, - group_name="electronic_structure", - ) + if "electronic_structure" in data_dict.keys(): + electronic_structure_dict_to_hdf( + data_dict=data_dict["electronic_structure"], + hdf=hdf5_output, + group_name="electronic_structure", + ) dict_group_to_hdf(data_dict=data_dict, hdf=hdf5_output, group="outcar") From 2a31f4a27a87a598c42d705a40087f59d73de404 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Thu, 17 Aug 2023 11:27:37 -0600 Subject: [PATCH 3/8] black formatting --- pyiron_atomistics/atomistics/structure/periodic_table.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pyiron_atomistics/atomistics/structure/periodic_table.py b/pyiron_atomistics/atomistics/structure/periodic_table.py index ee11db015..05c908170 100644 --- a/pyiron_atomistics/atomistics/structure/periodic_table.py +++ b/pyiron_atomistics/atomistics/structure/periodic_table.py @@ -161,10 +161,7 @@ def to_dict(self): self._dataset = {"Parameter": ["Parent"], "Value": [self.Parent]} hdf_el["elementData"] = self._dataset # "Dictionary of element tag static" - hdf_el["tagData"] = { - key: self.tags[key] - for key in self.tags.keys() - } + hdf_el["tagData"] = {key: self.tags[key] for key in self.tags.keys()} return hdf_el def to_hdf(self, hdf): From 36b7cb66b553be553cb5a505227c089994f92e7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Thu, 17 Aug 2023 22:41:42 -0600 Subject: [PATCH 4/8] bug fixes --- pyiron_atomistics/vasp/base.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pyiron_atomistics/vasp/base.py b/pyiron_atomistics/vasp/base.py index cf87aef84..2d1cc8003 100644 --- a/pyiron_atomistics/vasp/base.py +++ b/pyiron_atomistics/vasp/base.py @@ -2318,11 +2318,12 @@ def to_hdf(self, hdf): ) def to_dict(self): - hdf_go = {} + hdf_go, hdf_dft = {}, {} for key, val in self.log_dict.items(): hdf_go[key] = val for key, val in self.dft_log_dict.items(): - hdf_go["dft"][key] = val + hdf_dft[key] = val + hdf_go["dft"] = hdf_dft if self.bands.eigenvalue_matrix is not None: hdf_go["bands"] = self.bands.to_dict() return hdf_go @@ -2571,7 +2572,13 @@ def generic_output_dict_to_hdf(data_dict, hdf, group_name="generic"): def output_dict_to_hdf(data_dict, hdf, group_name="output"): with hdf.open(group_name) as hdf5_output: for k, v in data_dict.items(): - if k not in ["structure"]: + if k not in [ + "structure", + "electrostatic_potential", + "charge_density", + "electronic_structure", + "outcar", + ]: hdf5_output[k] = v if "structure" in data_dict.keys(): From ed8de03b2b2ac108d2f23835f3f8cf86980f1912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Thu, 17 Aug 2023 22:52:34 -0600 Subject: [PATCH 5/8] fix generic --- pyiron_atomistics/vasp/base.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pyiron_atomistics/vasp/base.py b/pyiron_atomistics/vasp/base.py index 2d1cc8003..d31938b84 100644 --- a/pyiron_atomistics/vasp/base.py +++ b/pyiron_atomistics/vasp/base.py @@ -2561,7 +2561,7 @@ def generic_output_dict_to_hdf(data_dict, hdf, group_name="generic"): if k not in ["bands"]: hdf_dft[k] = v - if "bands" in data_dict["dft"].keys: + if "bands" in data_dict["dft"].keys(): electronic_structure_dict_to_hdf( data_dict=data_dict["dft"]["bands"], hdf=hdf_dft, @@ -2573,6 +2573,7 @@ def output_dict_to_hdf(data_dict, hdf, group_name="output"): with hdf.open(group_name) as hdf5_output: for k, v in data_dict.items(): if k not in [ + "generic", "structure", "electrostatic_potential", "charge_density", @@ -2581,6 +2582,13 @@ def output_dict_to_hdf(data_dict, hdf, group_name="output"): ]: hdf5_output[k] = v + if "generic" in data_dict.keys(): + generic_output_dict_to_hdf( + data_dict=data_dict["generic"], + hdf=hdf5_output, + group_name="generic", + ) + if "structure" in data_dict.keys(): structure_dict_to_hdf( data_dict=data_dict["structure"], From 29ab36cfaa090f08abfafaf2d1785e3416fd1a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Thu, 17 Aug 2023 23:19:14 -0600 Subject: [PATCH 6/8] fix atoms --- pyiron_atomistics/atomistics/structure/atoms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyiron_atomistics/atomistics/structure/atoms.py b/pyiron_atomistics/atomistics/structure/atoms.py index 139e6b03a..9b24b481a 100644 --- a/pyiron_atomistics/atomistics/structure/atoms.py +++ b/pyiron_atomistics/atomistics/structure/atoms.py @@ -3453,7 +3453,7 @@ def structure_dict_to_hdf(data_dict, hdf, group_name="structure"): if "new_species" in data_dict.keys(): for el, el_dict in data_dict["new_species"].items(): chemical_element_dict_to_hdf( - data_dict=el_dict, hdf=hdf, group_name="new_species/" + el + data_dict=el_dict, hdf=hdf_structure, group_name="new_species/" + el ) dict_group_to_hdf(data_dict=data_dict, hdf=hdf_structure, group="tags") From 994bd476c8588de93bc5edc3b3c7449b72ce3739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Thu, 17 Aug 2023 23:29:31 -0600 Subject: [PATCH 7/8] fix bands --- pyiron_atomistics/vasp/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyiron_atomistics/vasp/base.py b/pyiron_atomistics/vasp/base.py index d31938b84..813e65357 100644 --- a/pyiron_atomistics/vasp/base.py +++ b/pyiron_atomistics/vasp/base.py @@ -2325,7 +2325,7 @@ def to_dict(self): hdf_dft[key] = val hdf_go["dft"] = hdf_dft if self.bands.eigenvalue_matrix is not None: - hdf_go["bands"] = self.bands.to_dict() + hdf_go["dft"]["bands"] = self.bands.to_dict() return hdf_go def from_hdf(self, hdf): From db0474b0c2d75ebf73b89e8f4bc7f50b45fb4151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Fri, 18 Aug 2023 00:00:51 -0600 Subject: [PATCH 8/8] compatibility to LAMMPS --- pyiron_atomistics/vasp/base.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/pyiron_atomistics/vasp/base.py b/pyiron_atomistics/vasp/base.py index 813e65357..7a0bd304e 100644 --- a/pyiron_atomistics/vasp/base.py +++ b/pyiron_atomistics/vasp/base.py @@ -387,20 +387,24 @@ def write_input(self): modified_elements=modified_elements, ) - def collect_output_parser(self): + def collect_output_parser(self, cwd): """ Collects the outputs and stores them to the hdf file """ if self.structure is None or len(self.structure) == 0: try: - self.structure = self.get_final_structure_from_file(filename="CONTCAR") + self.structure = self.get_final_structure_from_file( + cwd=cwd, filename="CONTCAR" + ) except IOError: - self.structure = self.get_final_structure_from_file(filename="POSCAR") + self.structure = self.get_final_structure_from_file( + cwd=cwd, filename="POSCAR" + ) self._sorted_indices = np.array(range(len(self.structure))) self._output_parser.structure = self.structure.copy() try: self._output_parser.collect( - directory=self.working_directory, sorted_indices=self.sorted_indices + directory=cwd, sorted_indices=self.sorted_indices ) except VaspCollectError: self.status.aborted = True @@ -408,15 +412,16 @@ def collect_output_parser(self): # Try getting high precision positions from CONTCAR try: self._output_parser.structure = self.get_final_structure_from_file( - filename="CONTCAR" + cwd=cwd, + filename="CONTCAR", ) except (IOError, ValueError, FileNotFoundError): pass # Bader analysis - if os.path.isfile( - os.path.join(self.working_directory, "AECCAR0") - ) and os.path.isfile(os.path.join(self.working_directory, "AECCAR2")): + if os.path.isfile(os.path.join(cwd, "AECCAR0")) and os.path.isfile( + os.path.join(cwd, "AECCAR2") + ): bader = Bader(self) try: charges_orig, volumes_orig = bader.compute_bader_charges() @@ -449,7 +454,9 @@ def collect_output(self): Collects the outputs and stores them to the hdf file """ output_dict_to_hdf( - data_dict=self.collect_output_parser(), hdf=self._hdf5, group_name="output" + data_dict=self.collect_output_parser(cwd=self.working_directory), + hdf=self._hdf5, + group_name="output", ) if len(self._exclude_groups_hdf) > 0 or len(self._exclude_nodes_hdf) > 0: self.project_hdf5.rewrite_hdf5() @@ -785,7 +792,7 @@ def reset_output(self): """ self._output_parser = Output() - def get_final_structure_from_file(self, filename="CONTCAR"): + def get_final_structure_from_file(self, cwd, filename="CONTCAR"): """ Get the final structure of the simulation usually from the CONTCAR file @@ -795,7 +802,7 @@ def get_final_structure_from_file(self, filename="CONTCAR"): Returns: pyiron.atomistics.structure.atoms.Atoms: The final structure """ - filename = posixpath.join(self.working_directory, filename) + filename = posixpath.join(cwd, filename) if self.structure is None: try: output_structure = read_atoms(filename=filename)