Source code for atoMEC

"""
atoMEC: Average-atom code for matter under extreme conditions.

Copyright (c) 2021 (in alphabetical order), Tim Callow, Attila Cangi, Eli Kraisler.
All rights reserved.

atoMEC is a python-based average-atom code for simulations of high energy density
phenomena such as in warm dense matter.
Please see the README or the project wiki (https://atomec-project.github.io/atoMEC/)
for more information.

Classes
-------
* :class:`Atom` : the main object for atoMEC calculations, containing information \
                  about physical material properties
"""

__version__ = "1.4.0"

# standard libraries
from math import pi

# global imports
from . import config
from . import check_inputs
from . import writeoutput


[docs] class Atom: r""" The principal object in atoMEC calculations which defines the material properties. The `Atom` contains key information about the physical properties of the material such as temperature, density, and charge. It does not contain any information \ about approximations or choices of model. Parameters ---------- species : str The chemical symbol for the atomic species, eg "He" temp : float The electronic temperature in hartree, eV or Kelvin radius : float, optional The radius of the Wigner-Seitz sphere, defined as 0.5*a_i, where a_i is the average inter-atomic distance density : float, optional The mass density of the material in :math:`\mathrm{g\ cm}^{-3}` charge : int, optional The overall net charge units_temp : str, optional The units of temperature, must be one of "ha", "ev" or "k" units_radius : str, optional The units of radius, must be one of "ang" or "bohr" units_density : str, optional The units of density, currently only "g/cm3" is supported write_output : bool, optional Whether to print atomic information, defaults True """ def __init__( self, species, temp, radius=-1, density=-1, charge=0, units_temp="ha", units_radius="bohr", units_density="g/cm3", write_info=True, ): # print the initial spiel if write_info: print("\n" + "Welcome to atoMEC! \n") # input variables are checked later with getter / setter functions self.species = species self.units_temp = units_temp self.temp = temp self.charge = charge self.units_radius = units_radius self.units_density = units_density # radius and density need a special check to ensure compatibility radius_check, density_check = check_inputs.Atom().check_rad_dens_init( self, radius, density, self.units_radius, self.units_density, ) self.radius = radius_check self.density = density_check if write_info: print(self.info) # below are the getter and setter attributes for all the class attributes @property def species(self): """str: the chemical symbol for the atomic species.""" return self._species @species.setter def species(self, species): self._species = check_inputs.Atom().check_species(species) @property def at_chrg(self): """int: the atomic charge Z.""" chrg = self.species.atomic_number config.Z = chrg return chrg @property def at_mass(self): """float: the atomic mass (in a.u.).""" return self.species.atomic_weight @property def nvalence(self): """int: the number of valence electrons.""" return self.species.nvalence() @property def units_temp(self): """str: the units of temperature.""" return self._units_temp @units_temp.setter def units_temp(self, units_temp): self._units_temp = check_inputs.Atom().check_units_temp(units_temp) @property def temp(self): """float: the electronic temperature in Hartree.""" return self._temp @temp.setter def temp(self, temp): self._temp = check_inputs.Atom().check_temp(temp, self.units_temp) config.temp = self._temp config.beta = 1.0 / self._temp @property def charge(self): """int: the net charge of the atom.""" return self._charge @charge.setter def charge(self, charge): self._charge = check_inputs.Atom().check_charge(charge) @property def nele(self): """int: the number of electrons in the atom. The total electron number is given by the sum of :obj:`at_chrg` and :obj:`charge`. """ return self.at_chrg + self._charge @property def units_radius(self): """str: the units of the atomic radius.""" return self._units_radius @units_radius.setter def units_radius(self, units_radius): self._units_radius = check_inputs.Atom().check_units_radius(units_radius) @property def units_density(self): """str: the units of the atomic density.""" return self._units_density @units_density.setter def units_density(self, units_density): self._units_density = check_inputs.Atom().check_units_density(units_density) @property def radius(self): r"""float: radius of the Voronoi sphere. The radius is defined as :math:`a_i /2`, where :math:`a_i` is the average inter-atomic distance. """ return self._radius @radius.setter def radius(self, radius): self._radius = check_inputs.Atom().check_radius(radius, self.units_radius) self._density = check_inputs.Atom().radius_to_dens(self, self._radius) config.r_s = self._radius config.sph_vol = (4.0 * pi * self._radius**3.0) / 3.0 @property def density(self): r"""float: the mass density of the material in :math:`\mathrm{g\ cm}^{-3}`.""" return self._density @density.setter def density(self, density): self._density = check_inputs.Atom().check_density(density) self._radius = check_inputs.Atom().dens_to_radius(self, self._density) config.r_s = self._radius config.sph_vol = (4.0 * pi * self._radius**3.0) / 3.0 @property def WS_radius(self): r"""float: the Wigner-Seitz radius, or the electron coupling parameter. The Wigner-Seitz radius differs from the Voronoi radius because it depends on the free electron density, defined in atoMEC as the valence electron density. """ return self.radius * self.nvalence ** (-1.0 / 3.0) @property def E_Fermi(self): r"""float: the Fermi energy.""" return 0.5 * (9.0 * pi / 4.0) ** (2.0 / 3.0) * self.WS_radius**-2.0 @property def gamma_ion(self): r"""float: the ionic coupling parameter.""" return self.at_chrg**2.0 / (2.0 * self.radius * self.temp) @property def theta_e(self): r"""float: the electron degeneracy parameter.""" return self.temp / self.E_Fermi @property def info(self): """str: formatted information about the :obj:`Atom`'s attributes.""" # write output info return writeoutput.write_atomic_data(self)