Skip to content

Commit

Permalink
added electrode document models
Browse files Browse the repository at this point in the history
  • Loading branch information
jmmshn committed Dec 18, 2020
1 parent 0d0150e commit 56593fe
Showing 1 changed file with 178 additions and 0 deletions.
178 changes: 178 additions & 0 deletions emmet-core/emmet/core/electrode.py
@@ -0,0 +1,178 @@
from datetime import datetime
from typing import Dict, List

from monty.json import MontyDecoder
from pydantic import BaseModel, Field, validator
from pymatgen import Structure
from pymatgen.apps.battery.battery_abc import AbstractElectrode
from pymatgen.apps.battery.insertion_battery import InsertionElectrode
from pymatgen.core.periodic_table import ElementBase
from pymatgen.entries.computed_entries import ComputedEntry


class WorkingIon(ElementBase):
Li = "Li"
Ca = "Ca"
Mg = "Mg"


class VoltagePairDoc(BaseModel):
"""
Data for individual voltage steps.
Note: Each voltage step is represented as a sub_electrode (ConversionElectrode/InsertionElectrode)
object to gain access to some basic statistics about the voltage step
"""

max_delta_volume: str = Field(
None,
description="Volume changes in % for a particular voltage step using: "
"max(charge, discharge) / min(charge, discharge) - 1",
)

average_voltage: float = Field(
None, description="The average voltage in V for a particular voltage step.",
)

capacity_grav: float = Field(None, description="Gravimetric capacity in mAh/g.")

capacity_vol: float = Field(None, description="Volumetric capacity in mAh/cc.")

energy_grav: float = Field(
None, description="Gravimetric energy (Specific energy) in Wh/kg."
)

energy_vol: float = Field(
None, description="Volumetric energy (Energy Density) in Wh/l."
)

fracA_charge: float = Field(
None, description="Atomic fraction of the working ion in the charged state."
)
fracA_discharge: float = Field(
None, description="Atomic fraction of the working ion in the discharged state."
)

@classmethod
def from_voltage_pair_from_sub_electrode(
cls, sub_electrode: AbstractElectrode, **kwargs
):
"""
Convert A pymatgen electrode object to a document
"""
return cls(**sub_electrode.get_summary_dict(), **kwargs)


class InsertionVoltagePairDoc(VoltagePairDoc):
"""
Features specific to insertion electrode
"""

stability_charge: float = Field(
None, description="The energy above hull of the charged material."
)

stability_discharge: float = Field(
None, description="The energy above hull of the discharged material."
)


class InsertionElectrodeDoc(InsertionVoltagePairDoc):
"""
Insertion electrode
"""

task_id: str = Field(None, description="The id for this battery document.")

framework_formula: str = Field(
None, description="The id for this battery document."
)

host_structure: Structure = Field(
None, description="Host structure (structure without the working ion)",
)

adj_pairs: List[InsertionVoltagePairDoc] = Field(
None, description="Returns all the Voltage Steps",
)

working_ion: WorkingIon = Field(
None, description="The working ion as an Element object",
)

num_steps: float = Field(
None,
description="The number of distinct voltage steps in from fully charge to "
"discharge based on the stable intermediate states",
)

max_voltage_step: float = Field(
None, description="Maximum absolute difference in adjacent voltage steps"
)

last_updated: datetime = Field(
None,
description="Timestamp for the most recent calculation for this Material document",
)

# Make sure that the datetime field is properly formatted
@validator("last_updated", pre=True)
def last_updated_dict_ok(cls, v):
return MontyDecoder().process_decoded(v)

@classmethod
def from_entries(
cls,
grouped_entries: List[ComputedEntry],
working_ion_entry: ComputedEntry,
task_id: str,
host_structure: Structure,
):
ie = InsertionElectrode.from_entries(
entries=grouped_entries, working_ion_entry=working_ion_entry
)
ie.get_summary_dict()
d = ie.get_summary_dict()
d["num_steps"] = d.pop("nsteps", None)
return cls(task_id=task_id, host_structure=host_structure, **d)


# class ConversionVoltagePairDoc(VoltagePairDoc):
# """
# Features specific to conversion electrode
# """
#
# reactions: Dict = Field(
# None, description="The reaction the characterizes that particular voltage step."
# )
#
#
# class ConversionElectrode(ConversionVoltagePairDoc):
# task_id: str = Field(None, description="The id for this battery document.")
#
# adj_pairs: List[ConversionVoltagePairDoc] = Field(
# None, description="Returns all the adjacent Voltage Steps",
# )
#
# working_ion: WorkingIon = Field(
# None, description="The working ion as an Element object",
# )
#
# num_steps: float = Field(
# None,
# description="The number of distinct voltage steps in from fully charge to "
# "discharge based on the stable intermediate states",
# )
#
# max_voltage_step: float = Field(
# None, description="Maximum absolute difference in adjacent voltage steps"
# )
#
# last_updated: datetime = Field(
# None,
# description="Timestamp for the most recent calculation for this Material document",
# )
#
# # Make sure that the datetime field is properly formatted
# @validator("last_updated", pre=True)
# def last_updated_dict_ok(cls, v):
# return MontyDecoder().process_decoded(v)

0 comments on commit 56593fe

Please sign in to comment.