Source code for solarwindpy.core.units_constants

#!/usr/bin/env python
"""Definitions of common units and physical constants.

The values are derived from :mod:`scipy.constants`. All quantities stored in
the :class:`~solarwindpy.core.plasma.Plasma` object have a corresponding entry
in :class:`Constants` and can be converted using :class:`Units`.
"""

from dataclasses import dataclass, field

import pandas as pd

from scipy import constants
from scipy.constants import physical_constants

# We rely on views via DataFrame.xs to reduce memory size and do not
# `.copy(deep=True)`, so we want to make sure that this doesn't
# accidentally cause a problem.

_misc_constants = {
    "e0": constants.epsilon_0,
    "mu0": constants.mu_0,
    "c": constants.c,
    #     "gamma": 5.0 / 3.0,
    "hbar": physical_constants["Planck constant over 2 pi"][0],
    "1AU [m]": constants.au,
    "Re [m]": 6378.1e3,  # Earth Radius in meters
    "Rs [m]": 695.508e6,  # Sun Radius in meters
    "gas constant": constants.R,
}

_kBoltzmann = {
    "J": constants.k,
    "eV": physical_constants["Boltzmann constant in eV/K"][0],
}

_polytropic_index = dict(par=3.0, per=2.0, scalar=5.0 / 3.0)

_m_in_mp = {
    "p": 1.0,
    "p1": 1.0,
    "p2": 1.0,
    "pm": 1.0,
    "p_bimax": 1.0,
    "a": physical_constants["alpha particle-proton mass ratio"][0],
    "a1": physical_constants["alpha particle-proton mass ratio"][0],
    "a2": physical_constants["alpha particle-proton mass ratio"][0],
    "a_bimax": physical_constants["alpha particle-proton mass ratio"][0],
    "e": physical_constants["electron-proton mass ratio"][0],
}

_charges = {
    "e": -constants.e,
    "p": constants.e,
    "p1": constants.e,
    "p2": constants.e,
    "pm": constants.e,
    "p_bimax": constants.e,
    "a": 2.0 * constants.e,
    "a1": 2.0 * constants.e,
    "a2": 2.0 * constants.e,
    "a_bimax": 2.0 * constants.e,
}

_charge_states = {
    "e": -1.0,
    "p": 1.0,
    "p1": 1.0,
    "p2": 1.0,
    "pm": 1.0,
    "p_bimax": 1.0,
    "a": 2.0,
    "a1": 2.0,
    "a2": 2.0,
    "a_bimax": 2.0,
}

_masses = {
    "e": constants.m_e,
    "p": constants.m_p,
    "p1": constants.m_p,
    "p2": constants.m_p,
    "pm": constants.m_p,  # proton moment
    "p_bimax": constants.m_p,
    "a_bimax": physical_constants["alpha particle mass"][0],
    "a": physical_constants["alpha particle mass"][0],
    "a1": physical_constants["alpha particle mass"][0],
    "a2": physical_constants["alpha particle mass"][0],
}

_m_amu = {
    "a": physical_constants["alpha particle mass in u"][0],
    "a1": physical_constants["alpha particle mass in u"][0],
    "a2": physical_constants["alpha particle mass in u"][0],
    "a_bimax": physical_constants["alpha particle mass in u"][0],
    "p": physical_constants["proton mass in u"][0],
    "p1": physical_constants["proton mass in u"][0],
    "p2": physical_constants["proton mass in u"][0],
    "pm": physical_constants["proton mass in u"][0],
    "p_bimax": physical_constants["proton mass in u"][0],
    "e": physical_constants["electron mass in u"][0],
}


[docs] @dataclass class Constants: """Physical constants useful for solar wind calculations.""" misc: pd.Series = field(default_factory=lambda: pd.Series(_misc_constants)) kb: pd.Series = field(default_factory=lambda: pd.Series(_kBoltzmann)) m_in_mp: pd.Series = field(default_factory=lambda: pd.Series(_m_in_mp)) m: pd.Series = field(default_factory=lambda: pd.Series(_masses)) m_amu: pd.Series = field( default_factory=lambda: pd.Series(_m_amu), metadata={"doc": "Masses in amu."}, ) charges: pd.Series = field(default_factory=lambda: pd.Series(_charges)) charge_states: pd.Series = field(default_factory=lambda: pd.Series(_charge_states)) polytropic_index: pd.Series = field( default_factory=lambda: pd.Series(_polytropic_index), metadata={"doc": "Polytropic index for various cases."}, ) def __post_init__(self) -> None: """Validate the shapes of series.""" for s in ( self.misc, self.kb, self.m_in_mp, self.m, self.m_amu, self.charges, self.charge_states, self.polytropic_index, ): if not isinstance(s, pd.Series): raise TypeError("Constant values must be pandas Series")
[docs] @dataclass class Units: r"""Common unit conversion factors. Attributes ---------- bfield : float Magnetic field units :math:`[\mathrm{nT}]`. v : float Velocity units :math:`[\mathrm{km\,s^{-1}}]`. pth : float Thermal pressure units :math:`[\mathrm{pPa}]`. temperature : float Temperature units :math:`[10^{5}\,\mathrm{K}]`. n : float Number density units :math:`[\mathrm{cm^{-3}}]`. beta : float Dimensionless beta units. lnlambda : float Dimensionless Coulomb log units. nuc : float Collision frequency units :math:`[10^{-7}\,\mathrm{Hz}]`. nc : float Dimensionless count units. qpar : float Parallel heat flux units :math:`[\mathrm{mW\,cm^{-2}}]`. distance2sun : float Distance to sun units ``[m]``. """ bfield: float = 1e-9 b: float = field(init=False) v: float = 1e3 w: float = field(init=False) dv: float = field(init=False) ca: float = field(init=False) cs: float = field(init=False) cfms: float = field(init=False) pth: float = 1e-12 temperature: float = 1e5 n: float = 1e6 rho: float = field(init=False) beta: float = 1.0 lnlambda: float = 1.0 nuc: float = 1e-7 nc: float = 1.0 qpar: float = 1e-7 distance2sun: float = 1.0 specific_entropy: float = field(init=False) def __post_init__(self) -> None: """Compute derived unit conversions.""" self.b = self.bfield self.w = self.v self.dv = self.v self.ca = self.v self.cs = self.v self.cfms = self.v self.rho = self.n * constants.m_p self.specific_entropy = 1e4 / constants.e