Skip to content

Commit

Permalink
clean up add generator function
Browse files Browse the repository at this point in the history
  • Loading branch information
shyamd committed Sep 29, 2020
1 parent 348b7ff commit 0425132
Showing 1 changed file with 63 additions and 10 deletions.
73 changes: 63 additions & 10 deletions emmet-core/emmet/core/thermo.py
@@ -1,14 +1,15 @@
""" Core definition of a Thermo Document """
from datetime import datetime
from typing import ClassVar, Dict, List
from enum import Enum
from typing import ClassVar, Dict, List

from pydantic import BaseModel, Field
from pymatgen.analysis.phase_diagram import PhaseDiagram, PhaseDiagramError
from pymatgen.core.periodic_table import Element

from emmet.core.material import PropertyDoc
from emmet.core.structure import StructureMetadata
from emmet.stubs import ComputedEntry, Composition
from emmet.stubs import Composition, ComputedEntry


class DecompositionProduct(BaseModel):
Expand All @@ -29,7 +30,7 @@ class DecompositionProduct(BaseModel):
)


class Thermo(PropertyDoc):
class ThermoDoc(PropertyDoc):
"""
A thermo entry document
"""
Expand All @@ -39,11 +40,11 @@ class Thermo(PropertyDoc):
)

uncorrected_energy_per_atom: float = Field(
None, description="The total DFT energy of this material per atom in eV/atom"
..., description="The total DFT energy of this material per atom in eV/atom"
)

energy_per_atom: float = Field(
None,
...,
description="The total corrected DFT energy of this material per atom in eV/atom",
)

Expand All @@ -54,14 +55,15 @@ class Thermo(PropertyDoc):
formation_energy_per_atom: float = Field(
None, description="The formation energy per atom in eV/atom"
)
e_above_hull: float = Field(
None, description="The energy above the hull in eV/Atom"

energy_above_hull: float = Field(
..., description="The energy above the hull in eV/Atom"
)
is_stable: bool = Field(
None,
False,
description="Flag for whether this material is on the hull and therefore stable",
)
equillibrium_reaction_energy_per_atmo: float = Field(
equillibrium_reaction_energy_per_atom: float = Field(
None,
description="The reaction energy of a stable entry from the neighboring equilibrium stable materials in eV."
" Also known as the inverse distance to hull.",
Expand All @@ -73,7 +75,7 @@ class Thermo(PropertyDoc):
)

energy_type: str = Field(
None,
...,
description="The type of calculation this energy evaluation comes from. TODO: Convert to enum?",
)

Expand All @@ -86,3 +88,54 @@ class Thermo(PropertyDoc):
description="List of all entries that are valid for this material."
" The keys for this dictionary are names of various calculation types",
)

@classmethod
def from_entries(cls, entries: List[ComputedEntry], sandboxes=None):

pd = PhaseDiagram(entries)

docs = []

for e in entries:
(decomp, ehull) = pd.get_decomp_and_e_above_hull(e)

d = {
"material_id": e.entry_id,
"uncorrected_energy_per_atom": e.uncorrected_energy
/ e.composition.num_atoms,
"energy_per_atom": e.uncorrected_energy / e.composition.num_atoms,
"formation_energy_per_atom": pd.get_form_energy_per_atom(e),
"energy_above_hull": ehull,
"is_stable": e in pd.stable_entries,
"sandboxes": sandboxes,
}

if "last_updated" in e.data:
d["last_updated"] = e.data["last_updated"]

# Store different info if stable vs decomposes
if d["is_stable"]:
d[
"equillibrium_reaction_energy_per_atom"
] = pd.get_equilibrium_reaction_energy(e)
else:
d["decomposes_to"] = [
{
"material_id": de.entry_id,
"formula": de.composition.formula,
"amount": amt,
}
for de, amt in decomp.items()
]

d["energy_type"] = e.parameters["run_type"]

elsyms = sorted(set([el.symbol for el in e.composition.elements]))
d["chemsys"] = "-".join(elsyms)
d["nelements"] = len(elsyms)
d["elements"] = list(elsyms)
d["last_updated"] = e.data["last_updated"]

docs.append(ThermoDoc(**d))

return docs

0 comments on commit 0425132

Please sign in to comment.