Skip to content

Commit

Permalink
Merge pull request #1356 from pyiron/atomistics_dict
Browse files Browse the repository at this point in the history
AtomisticGenericJob, Lammps and Vasp: Implement from_dict()
  • Loading branch information
jan-janssen authored Apr 2, 2024
2 parents dd2196d + 96b6258 commit eb0dc01
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 87 deletions.
76 changes: 48 additions & 28 deletions pyiron_atomistics/atomistics/job/atomistic.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,18 @@ def calc_minimize(
"f_tol is deprecated as of vers. 0.3.0. It is not guaranteed to be in service in vers. 0.4.0"
)
self._generic_input["calc_mode"] = "minimize"
self._generic_input["max_iter"] = max_iter
self._generic_input["pressure"] = pressure
if max_iter is not None:
self._generic_input["max_iter"] = int(max_iter)
else:
self._generic_input["max_iter"] = max_iter
if isinstance(pressure, list):
self._generic_input["pressure"] = [
float(p) if p is not None else p for p in pressure
]
elif pressure is not None:
self._generic_input["pressure"] = float(pressure)
else:
self._generic_input["pressure"] = pressure
self._generic_input.remove_keys(
["temperature", "n_ionic_steps", "n_print", "velocity"]
)
Expand Down Expand Up @@ -256,42 +266,41 @@ def calc_md(
langevin=False,
):
self._generic_input["calc_mode"] = "md"
self._generic_input["temperature"] = temperature
self._generic_input["n_ionic_steps"] = n_ionic_steps
self._generic_input["n_print"] = n_print
self._generic_input["temperature_damping_timescale"] = (
if isinstance(temperature, list):
self._generic_input["temperature"] = [float(t) for t in temperature]
elif temperature is not None:
self._generic_input["temperature"] = float(temperature)
else:
self._generic_input["temperature"] = temperature
self._generic_input["n_ionic_steps"] = int(n_ionic_steps)
self._generic_input["n_print"] = int(n_print)
self._generic_input["temperature_damping_timescale"] = float(
temperature_damping_timescale
)
if pressure is not None:
self._generic_input["pressure"] = pressure
if isinstance(pressure, list):
self._generic_input["pressure"] = [
float(p) if p is not None else p for p in pressure
]
elif pressure is not None:
self._generic_input["pressure"] = float(pressure)
if pressure_damping_timescale is not None:
self._generic_input["pressure_damping_timescale"] = (
self._generic_input["pressure_damping_timescale"] = float(
pressure_damping_timescale
)
if time_step is not None:
self._generic_input["time_step"] = time_step
self._generic_input["time_step"] = int(time_step)
self._generic_input.remove_keys(["max_iter"])

def from_hdf(self, hdf=None, group_name=None):
"""
Recreates instance from the hdf5 file
Args:
hdf (str): Path to the hdf5 file
group_name (str): Name of the group which contains the object
"""
super(AtomisticGenericJob, self).from_hdf(hdf=hdf, group_name=group_name)
with self._hdf5.open("input") as hdf5_input:
try:
self._generic_input.from_hdf(hdf5_input)
except ValueError:
pass
def from_dict(self, job_dict):
super().from_dict(job_dict=job_dict)
self._generic_input.from_dict(obj_dict=job_dict["input"]["generic"])

def to_dict(self):
data_dict = super(AtomisticGenericJob, self).to_dict()
data_dict.update(
job_dict = super(AtomisticGenericJob, self).to_dict()
job_dict.update(
{"input/generic/" + k: v for k, v in self._generic_input.to_dict().items()}
)
return data_dict
return job_dict

def store_structure(self):
"""
Expand Down Expand Up @@ -803,6 +812,15 @@ def _structure_to_dict(self):
else:
return None

def _structure_from_dict(self, job_dict):
if (
"structure" in job_dict["input"].keys()
and self._generic_input["structure"] == "atoms"
):
self.structure = Atoms().from_dict(
atoms_dict=job_dict["input"]["structure"]
)

def _structure_to_hdf(self):
data_dict = self._structure_to_dict()
if data_dict is not None:
Expand All @@ -814,8 +832,10 @@ def _structure_from_hdf(self):
"structure" in self.project_hdf5["input"].list_groups()
and self._generic_input["structure"] == "atoms"
):
with self.project_hdf5.open("input") as hdf5_input:
self.structure = Atoms().from_hdf(hdf5_input)
with self.project_hdf5.open("input/structure") as hdf5_input:
self.structure = Atoms().from_dict(
hdf5_input.read_dict_from_hdf(recursive=True)
)

def _write_chemical_formular_to_database(self):
if self.structure:
Expand Down
19 changes: 4 additions & 15 deletions pyiron_atomistics/lammps/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -728,21 +728,10 @@ def to_dict(self):
data_dict.update({"input/" + k: v for k, v in lammps_dict.items()})
return data_dict

# define hdf5 output
def from_hdf(self, hdf=None, group_name=None): # TODO: group_name should be removed
"""
Args:
hdf:
group_name:
Returns:
"""
super(LammpsBase, self).from_hdf(hdf=hdf, group_name=group_name)
self._structure_from_hdf()
with self.project_hdf5.open("input") as hdf_input:
self.input.from_dict(data_dict=hdf_input.read_dict_from_hdf(recursive=True))
def from_dict(self, job_dict):
super().from_dict(job_dict=job_dict)
self._structure_from_dict(job_dict=job_dict)
self.input.from_dict(data_dict=job_dict["input"])

def write_restart_file(self, filename="restart.out"):
"""
Expand Down
74 changes: 30 additions & 44 deletions pyiron_atomistics/vasp/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,17 @@ def stop_calculation(self, next_electronic_step=False):
else:
f.write("LABORT =.TRUE.\n")

def to_dict(self):
job_dict = super().to_dict()
job_dict.update({"input/" + k: v for k, v in self._structure_to_dict().items()})
job_dict.update({"input/" + k: v for k, v in self.input.to_dict().items()})
return job_dict

def from_dict(self, job_dict):
super().from_dict(job_dict=job_dict)
self._structure_from_dict(job_dict=job_dict)
self.input.from_dict(input_dict=job_dict["input"])

def to_hdf(self, hdf=None, group_name=None):
"""
Stores the instance attributes into the hdf5 file
Expand All @@ -778,8 +789,6 @@ def to_hdf(self, hdf=None, group_name=None):
"""
super(VaspBase, self).to_hdf(hdf=hdf, group_name=group_name)
self._structure_to_hdf()
self.input.to_hdf(self._hdf5)
self._output_parser.to_hdf(self._hdf5)
if _vasp_generic_energy_free_affected(self):
self.logger.warn(
Expand All @@ -799,8 +808,6 @@ def from_hdf(self, hdf=None, group_name=None):
"""
super(VaspBase, self).from_hdf(hdf=hdf, group_name=group_name)
self._structure_from_hdf()
self.input.from_hdf(self._hdf5)
if (
"output" in self.project_hdf5.list_groups()
and "structure" in self["output"].list_groups()
Expand Down Expand Up @@ -1910,47 +1917,26 @@ def write(self, structure, modified_elements, directory=None):
write_species=not do_not_write_species,
)

def to_hdf(self, hdf):
"""
Save the object in a HDF5 file
Args:
hdf (pyiron_base.generic.hdfio.ProjectHDFio): HDF path to which the object is to be saved
"""

with hdf.open("input") as hdf5_input:
self.incar.to_hdf(hdf5_input)
self.kpoints.to_hdf(hdf5_input)
self.potcar.to_hdf(hdf5_input)

if "vasp_dict" in hdf5_input.list_nodes():
vasp_dict = hdf5_input["vasp_dict"]
vasp_dict.update({"eddrmm_handling": self._eddrmm})
hdf5_input["vasp_dict"] = vasp_dict
else:
vasp_dict = {"eddrmm_handling": self._eddrmm}
hdf5_input["vasp_dict"] = vasp_dict

def from_hdf(self, hdf):
"""
Reads the attributes and reconstructs the object from a hdf file
def to_dict(self):
input_dict = {"vasp_dict/eddrmm_handling": self._eddrmm}
input_dict.update({"incar/" + k: v for k, v in self.incar.to_dict().items()})
input_dict.update(
{"kpoints/" + k: v for k, v in self.kpoints.to_dict().items()}
)
input_dict.update({"potcar/" + k: v for k, v in self.potcar.to_dict().items()})
return input_dict

Args:
hdf: The hdf5 instance
"""
with hdf.open("input") as hdf5_input:
self.incar.from_hdf(hdf5_input)
self.kpoints.from_hdf(hdf5_input)
self.potcar.from_hdf(hdf5_input)

self._eddrmm = "ignore"
if "vasp_dict" in hdf5_input.list_nodes():
vasp_dict = hdf5_input["vasp_dict"]
if "eddrmm_handling" in vasp_dict.keys():
self._eddrmm = self._eddrmm_backwards_compatibility(
vasp_dict["eddrmm_handling"]
)
def from_dict(self, input_dict):
self.incar.from_dict(obj_dict=input_dict["incar"])
self.kpoints.from_dict(obj_dict=input_dict["kpoints"])
self.potcar.from_dict(obj_dict=input_dict["potcar"])
self._eddrmm = "ignore"
if "vasp_dict" in input_dict.keys():
vasp_dict = input_dict["vasp_dict"]
if "eddrmm_handling" in vasp_dict.keys():
self._eddrmm = self._eddrmm_backwards_compatibility(
vasp_dict["eddrmm_handling"]
)

@staticmethod
def _eddrmm_backwards_compatibility(eddrmm_value):
Expand Down

0 comments on commit eb0dc01

Please sign in to comment.