Source code for solprop.physdata.gases

# SPDX-FileCopyrightText: 2026 John C. Travers and contributors
#
# SPDX-License-Identifier: GPL-3.0-or-later

"""The gas species solprop knows about.

Every built-in gas is a name here, and every material quantity of it comes from optmat
(SEP 3): the linear law, the equation of state and transport, the Kerr coefficient,
the Raman response and the ionisation rate all key off :class:`Gas`. A model variant is
not a separate gas; it is chosen with a
:class:`~solprop.physdata.selection.MaterialSelection`.
"""

from enum import StrEnum

from solprop.exceptions import MaterialError

__all__ = ["Gas", "as_gas", "is_molecule"]


[docs] class Gas(StrEnum): """A gas species, spelled as its chemical formula. The members are :class:`str` subclasses, so ``Gas.He == "He"`` and a plain string may be used anywhere a gas is expected; :func:`as_gas` performs the conversion and raises :class:`~solprop.exceptions.MaterialError` for anything unknown. Examples -------- >>> from solprop.physdata import Gas >>> Gas.N2O.value 'N2O' >>> Gas("Ar") is Gas.Ar True """ Air = "Air" He = "He" Ne = "Ne" Ar = "Ar" Kr = "Kr" Xe = "Xe" N2 = "N2" H2 = "H2" D2 = "D2" O2 = "O2" CH4 = "CH4" SF6 = "SF6" N2O = "N2O"
[docs] def as_gas(gas: Gas | str) -> Gas: """Coerce a gas name to a :class:`Gas` member. Parameters ---------- gas : Gas or str A :class:`Gas` member or its exact name, e.g. ``"He"``. The lookup is case-sensitive: an explicit error beats a silent coercion. Returns ------- Gas The matching member. Raises ------ MaterialError If `gas` is not one of the known species. Examples -------- >>> from solprop.physdata import as_gas >>> as_gas("Kr") <Gas.Kr: 'Kr'> """ try: return Gas(gas) except ValueError as exc: known = ", ".join(member.value for member in Gas) raise MaterialError(f"unknown gas {gas!r}; solprop knows {known}") from exc
#: The species whose particles are single atoms. Everything else in :class:`Gas` is #: molecular, including ``Air``, which is a mixture of diatomic molecules. _MONATOMIC = frozenset({Gas.He, Gas.Ne, Gas.Ar, Gas.Kr, Gas.Xe})
[docs] def is_molecule(gas: Gas | str) -> bool: """Return whether the species is molecular rather than a single atom. ``Air`` counts as molecular: it is a mixture of diatomic molecules, not a monatomic gas. The predicate is chemical only; which ionisation rate and which Raman response a gas has is optmat's (:mod:`solprop.nonlinear.optmat_rates`, :mod:`solprop.nonlinear.optmat_raman`). Parameters ---------- gas : Gas or str A :class:`Gas` member or its exact name. Returns ------- bool True for a molecular species, False for a noble gas. Raises ------ MaterialError If `gas` is not one of the known species. Examples -------- >>> from solprop.physdata import is_molecule >>> is_molecule("He"), is_molecule("N2"), is_molecule("Air") (False, True, True) """ return as_gas(gas) not in _MONATOMIC