Source code for qmpy.materials.element

# qmpy/materials/element

"""
Django models representing elements and species.
"""

from django.db import models

from qmpy.db.custom import DictField
from qmpy.utils import *


[docs]class Element(models.Model): """ Core model for an element. Relationships: | :mod:`~qmpy.Atom` via atom_set | :mod:`~qmpy.Species` via species_set | :mod:`~qmpy.Structure` via structure_set | :mod:`~qmpy.Entry` via entry_set | :mod:`~qmpy.Composition` via composition_set | :mod:`~qmpy.Calculation` via calculation_set | :mod:`~qmpy.Potential` via potential_set | :mod:`~qmpy.Hubbard` via hubbards | :mod:`~qmpy.HubbardCorrection` via hubbardcorrection_set | :mod:`~qmpy.ReferenceEnergy` via referenceenergy_set Attributes: | **Identification** | z: atomic number | name: full atomic name | symbol: atomic symbol | group: group in the periodic table | period: period in the periodic table | | **Physical properties** | mass: Atomic mass, in AMU (float) | density: Density at STP, in g/cm^3 (float) | volume: Atomic volume at STP, in A^3/atom (float) | atomic_radii: in A (float) | van_der_waals radii: in A (float) | covalent_radii: in A (float) | scattering_factors: A dictionary of scattering factor coeffs. | | **Thermodynamic properties** | melt: melting point in K | boil: boiling point in K | specific_heat: C_p in J/K | | **Electronic properties** | electronegativity: Pauling electronegativity | ion_energy: First ionization energy. (eV) | s_elec: # of s electrons | p_elec: # of p electrons | d_elec: # of d electrons | f_elec: # of f electrons | | **Additional information** | production: Annual tons of element produced. | abundance: Amount in earths crust (ppm) | radioactive: Are all isotopes unstable? | HHI_P: Herfindahl-Hirschman Index for production. | HHI_R: Herfindahl-Hirschman Index for reserve Note: HHI values from Gaultois, M. et al. Chem. Mater. 25, 2911-2920 (2013). """ ### Identification z = models.IntegerField() name = models.CharField(max_length=20) symbol = models.CharField(max_length=9, primary_key=True) ### Periodic table group = models.IntegerField() period = models.IntegerField() ### Phyical characteristics mass = models.FloatField() density = models.FloatField() volume = models.FloatField() atomic_radii = models.IntegerField() van_der_waals_radii = models.IntegerField() covalent_radii = models.IntegerField() scattering_factors = DictField() ### Thermodynamics melt = models.FloatField() boil = models.FloatField() specific_heat = models.FloatField() ### Electonic structure electronegativity = models.FloatField() first_ionization_energy = models.FloatField() s_elec = models.IntegerField() p_elec = models.IntegerField() d_elec = models.IntegerField() f_elec = models.IntegerField() ### misc HHI_P = models.FloatField(default=0) HHI_R = models.FloatField(default=0) production = models.FloatField(default=0) radioactive = models.BooleanField(default=False) class Meta: app_label = "qmpy" db_table = "elements" # builtins def __str__(self): return self.symbol # accessor
[docs] @classmethod def get(cls, value): """ Return an element object. Accepts symbols and atomic numbers, or a list of symbols/atomic numbers. Examples:: >>> Element.get('Fe') >>> Element.get(26) >>> Element.get(['Fe', 'O']) """ if isinstance(value, cls): return value elif isinstance(value, list): return [cls.get(v) for v in value] elif isinstance(value, int): return cls.objects.get(z=value) elif isinstance(value, str): return cls.objects.get(symbol=value)
# methods def species_distribution(self): counts = {} for s in self.species_set.all(): counts[s.ox] = s.structure_set.count() return counts
[docs]class Species(models.Model): """ Base model for an atomic species. (Element + charge state). Relationships: | :mod:`~qmpy.Element` via element | :mod:`~qmpy.Entry` via entry_set | :mod:`~qmpy.Structure` via structure_set Attributes: | name: Species name. e.g. Fe3+, O2- | ox: Oxidation state (float) """ name = models.CharField(max_length=8, primary_key=True) element = models.ForeignKey( Element, blank=True, null=True, on_delete=models.CASCADE ) ox = models.FloatField(blank=True, null=True) class Meta: app_label = "qmpy" db_table = "species" # builtins def __str__(self): return str(self.name) # accessor
[docs] @classmethod def get(cls, value): """ Gets or creates the specified species. Arguments: value: Accepts multiple input types. Can be a string, e.g. Fe3+ or a tuple of (symbol, oxidation state) pairs, e.g. (Fe, 3). Return: A :mod:`~qmpy.Species` or list of :mod:`~qmpy.Species`. Examples:: >>> Species.get('Fe3+') >>> Species.get('Fe3') >>> Species.get(('Fe', 3)) >>> Species.get([ 'Fe3+', 'O2-', 'Li1+']) """ if isinstance(value, cls): return value elif isinstance(value, str): spec, new = cls.objects.get_or_create(name=value) if new: elt, ox = parse_species(value) spec.element_id = elt spec.ox = ox spec.save() return spec elif isinstance(value, list): return [cls.get(value) for value in list]
@property def ox_format(self): if self.ox is None: return 0 elif is_integer(self.ox): return int(self.ox) else: return float(round(self.ox, 3))