solprop.physdata.sellmeier#
Refractive-index models for gases, with analytic frequency derivatives.
A gas is described by its per-particle susceptibility gamma(omega), in m^3, so
that the linear susceptibility at a number density rho is simply
and the refractive index is n = sqrt(1 + chi). Keeping the density outside the model
is what lets n - 1 be formed directly rather than as (1 + x) - 1
(docs/dev/conventions.md section 5), and it makes a pressure gradient a scalar
multiplier on one fixed spectral profile.
Every built-in gas’s law is optmat’s polarizability (OptmatSusceptibility,
SEP 3), with its exact frequency derivative and its qualified wavelength intervals;
gamma() returns it and the accessors below evaluate it at a state, with optmat’s
equation of state. A model variant is chosen with a
MaterialSelection, never a separate pseudo-gas.
The formula types (PoleSumSusceptibility, InversePoleIndex,
WavenumberPoleIndex) are for a caller’s own published expression: each is a
rational function of 1 / lambda^2, so its derivative with respect to angular
frequency is available in closed form. That is a requirement, not a convenience: the
co-moving frame needs beta_1 to about 1e-10 and a finite-difference derivative of a
Sellmeier expression has a roughness floor near 5e-8 (see docs/dev/decisions.md).
Each carries the wavelength range over which its source is valid, the state at which
it reports its refractivity (ReferenceState) and a citation. Evaluating outside
that range emits MaterialRangeWarning once per call.
Functions
|
Return the linear susceptibility of a gas. |
|
Return the analytic frequency derivative of the linear susceptibility. |
|
Return the analytic frequency derivative of the refractive index. |
|
Return the per-particle susceptibility model for a gas: optmat's. |
|
Return the refractive index of a gas. |
|
Return |
Classes
|
A per-particle linear susceptibility model for one gas from one source. |
|
A refractivity written as a sum of poles in |
|
Take a gas's per-particle susceptibility from optmat's polarizability. |
|
A susceptibility written directly as a sum of poles in |
|
The thermodynamic state at which a measured refractivity was reported. |
|
A model whose source publishes the refractivity |
|
A refractivity written as one pole in the squared wavenumber. |
- class solprop.physdata.sellmeier.GasSusceptibility(*, gas, source, reference_state, wavelength_range, citation)[source]#
Bases:
ABCA per-particle linear susceptibility model for one gas from one source.
Subclasses supply the published expression and its derivative with respect to
u = 1 / lambda^2(lambda in microns) at the source’s reference state; this base class turns that into the per-particle quantitygamma(omega)in m^3 and its analytic derivative, and checks the validity range.- Attributes:
- gasGas
The species the coefficients describe.
- sourcestr
The name used to select this model in
gamma().- reference_stateReferenceState
The state at which the source reports its refractivity.
- wavelength_rangetuple of float
Shortest and longest wavelength in m over which the source is valid.
- citationstr
Where the coefficients come from, including the validity range and any deviation from the source.
- property absorbing: bool[source]#
Return whether the model has an imaginary part anywhere.
- Returns:
- bool
False: a refractivity fit is real by construction.
- dsusceptibility_domega(omega)[source]#
Return the analytic frequency derivative of the per-particle susceptibility.
- Parameters:
- omegaarray_like
Angular frequency in rad/s, >= 0.
- Returns:
- ndarray
dgamma/domegain m^3 s/rad, exact to rounding rather than to a finite-difference floor.
- Warns:
- MaterialRangeWarning
If any wavelength lies outside the validity range of the source.
Examples
The derivative is positive: these gases are normally dispersive.
>>> from solprop.physdata import Gas, gamma >>> float(gamma(Gas.Ar).dsusceptibility_domega(2.356e15)) > 0.0 True
- property reference_density: float[source]#
Return the number density at the reference state of the source.
- Returns:
- float
Number density in m^-3.
- reference_state: ReferenceState#
- susceptibility(omega)[source]#
Return the per-particle susceptibility.
- Parameters:
- omegaarray_like
Angular frequency in rad/s, >= 0. Zero gives the static limit.
- Returns:
- ndarray
gamma(omega)in m^3, such thatchi1 = gamma * rho. 0-d for scalar input, otherwise the shape of omega.
- Warns:
- MaterialRangeWarning
If any wavelength lies outside the validity range of the source.
Examples
>>> from solprop.physdata import Gas, gamma >>> model = gamma(Gas.Ar) >>> f"{float(model.susceptibility(2.356e15)):.6e}" '2.079791e-29'
- class solprop.physdata.sellmeier.InversePoleIndex(*, gas, source, reference_state, wavelength_range, citation, offset, b, c)[source]#
Bases:
RefractivitySusceptibilityA refractivity written as a sum of poles in
1 / lambda^2.n - 1 = offset + sum_i b_i / (c_i - 1 / lambda^2)with lambda in microns, the form used by Peck and Huang for hydrogen, by Zhang for oxygen (with a non-zero offset) and by Bideau-Mehu for the noble gases in the vacuum ultraviolet.- Attributes:
- offsetfloat
Constant term of the refractivity at the reference state, dimensionless.
- btuple of float
Pole strengths in um^-2.
- ctuple of float
Pole positions in um^-2, one per entry of b.
- class solprop.physdata.sellmeier.OptmatSusceptibility(*, gas, source, reference_state, wavelength_range, citation, model)[source]#
Bases:
GasSusceptibilityTake a gas’s per-particle susceptibility from optmat’s polarizability.
The susceptibility per particle is \(\gamma = \alpha / \varepsilon_0\), with optmat’s SI refractive polarizability \(\alpha(\omega)\) (C m^2/V, magnetic contribution included), so that
chi = gamma * rhois linear density scaling, the dilute limit of optmat’s own Lorentz–Lorenz law (dilute_scaling_error()measures the difference). The derivative is optmat’s exact \(\partial_\omega\alpha\), taken at fixed state.The model holds over its qualified
intervalsof vacuum wavelength. A band outside them is evaluated all the same and warns once per evaluation context (MaterialRangeWarning), naming the parts outside and the reasons of any gaps. A transparent model returns a real susceptibility; an absorbing one a complex one with a non-negative imaginary part. Build one withresolve(). The adapter keeps its last few evaluations by frequency array, asOptmatGlassdoes, and two adapters of one model compare equal by its identity digest (SEP 3, Q26).- Attributes:
- modelOptmatModel
The optmat dispersion model: a registry model, an
AirModel, or a model fromwith_parameters.
Examples
>>> from solprop.physdata.sellmeier import OptmatSusceptibility >>> argon = OptmatSusceptibility.resolve("Ar") >>> argon.source 'fit/Ar' >>> f"{float(argon.susceptibility(2.356e15)):.4e}" '2.0798e-29'
- property absorbing: bool[source]#
Return whether the optmat model carries an imaginary polarizability.
- Returns:
- bool
The model’s own
absorbing, or any constituent’s for an air model.
- dilute_scaling_error(density, temperature, omega)[source]#
Compare linear density scaling with optmat’s finite-density index law.
(n - 1)from \(\chi = N\alpha/\varepsilon_0\) and \(n - 1 = \chi/(\sqrt{1+\chi}+1)\) is compared with optmat’srefractivity(Lorentz–Lorenz with the refractivity virial) at the same number density. The comparison is made at the density itself: the state handed to optmat is the ideal-gas one,p = N k_B Twithideal=True, whose density is density exactly, so no equation of state or its inverse is consulted. Wavelengths outside the model’s qualified intervals are left out, unless none is inside.- Parameters:
- densityfloat
Number density in m^-3, > 0.
- temperaturefloat
Temperature in K, > 0.
- omeganumpy.ndarray
Angular frequencies in rad/s of the band, > 0.
- Returns:
- tuple of float
The relative error
(n-1)_dilute / (n-1)_optmat - 1of largest magnitude over the band, and the vacuum wavelength in m where it is.
- Raises:
- MaterialError
If optmat refuses the evaluation, or the band is empty.
Examples
>>> import numpy as np >>> from solprop.physdata.sellmeier import OptmatSusceptibility >>> argon = OptmatSusceptibility.resolve("Ar") >>> error, _ = argon.dilute_scaling_error(2.47e26, 293.15, np.array([2.356e15])) >>> f"{error:.2e}" '-1.88e-03'
- dsusceptibility_domega(omega)[source]#
Return optmat’s exact frequency derivative of the susceptibility.
- Parameters:
- omegaarray_like
Angular frequency in rad/s, >= 0.
- Returns:
- ndarray
dgamma/domegain m^3 s/rad.
- Warns:
- MaterialRangeWarning
If the band leaves the model’s qualified intervals.
- property material_records: tuple[MaterialRecord, ...][source]#
Return the record of the optmat model, for a run’s manifest.
- Returns:
- tuple of MaterialRecord
The dispersion model’s identity.
- model: OptmatModel#
- property reference_density: float[source]#
Return the density of the reference state, the dilute limit.
- Returns:
- float
0.0 m^-3.
- classmethod resolve(gas, model='recommended')[source]#
Resolve a gas’s optmat dispersion model and adapt it.
- Parameters:
- gasGas or str
The species.
Gas.Airis optmat’s named composition’s summed polarizabilities,"dry air (N2, O2, Ar)"by default.- modelstr or OptmatModel, optional
"recommended", an optmat model name (for air, a composition name), or an optmat model object for gas, taken as it is.
- Returns:
- OptmatSusceptibility
The adapted model.
- Raises:
- MaterialError
If the gas is unknown, optmat has no such model, or the model describes another gas.
- Warns:
- MaterialStatusWarning
If the model is
provisionaloruntested.
- susceptibility(omega)[source]#
Return the per-particle susceptibility
alpha / eps0.- Parameters:
- omegaarray_like
Angular frequency in rad/s, >= 0. Zero gives the static limit.
- Returns:
- ndarray
gamma(omega)in m^3, such thatchi1 = gamma * rho; complex, withIm gamma >= 0, for an absorbing model.
- Warns:
- MaterialRangeWarning
If the band leaves the model’s qualified intervals.
- class solprop.physdata.sellmeier.PoleSumSusceptibility(*, gas, source, reference_state, wavelength_range, citation, b, c)[source]#
Bases:
GasSusceptibilityA susceptibility written directly as a sum of poles in
lambda^2.chi(lambda) = sum_i b_i lambda^2 / (lambda^2 - c_i)with lambda in microns, the form used by Börzsönyi’s two-pole fits and by the three-pole fits extended into the vacuum ultraviolet. In terms ofu = 1 / lambda^2this issum_i b_i / (1 - c_i u), which stays finite at zero frequency.- Attributes:
- btuple of float
Pole strengths, dimensionless, being the susceptibility at the reference state.
- ctuple of float
Pole positions in um^2, one per entry of b. A negative entry is a fitting parameter with no resonance, not a physical pole.
- class solprop.physdata.sellmeier.ReferenceState(pressure_bar, temperature)[source]#
Bases:
objectThe thermodynamic state at which a measured refractivity was reported.
A published Sellmeier expression gives the refractivity of a gas at one temperature and pressure. Dividing by the number density there turns it into the per-particle quantity this module works with, so getting the state right matters: 1 bar against 1 atm is a 1.3 % error in every susceptibility.
- Attributes:
- pressure_barfloat
Absolute pressure of the reported measurement, in bar.
- temperaturefloat
Temperature of the reported measurement, in K.
- class solprop.physdata.sellmeier.RefractivitySusceptibility(*, gas, source, reference_state, wavelength_range, citation)[source]#
Bases:
GasSusceptibilityA model whose source publishes the refractivity
n - 1rather thanchi.The susceptibility follows as
chi = (1 + (n - 1))^2 - 1. Keeping that step in one place is deliberate: omitting either the subtraction or the squaring when implementing the He et al. expression is an easy error, and omitting both is wrong by a factor of about 1200.
- class solprop.physdata.sellmeier.WavenumberPoleIndex(*, gas, source, reference_state, wavelength_range, citation, a, b, c)[source]#
Bases:
RefractivitySusceptibilityA refractivity written as one pole in the squared wavenumber.
(n - 1) * 1e8 = a + b / (c - nu^2)with the wavenumbernu = 1e4 / lambda[um]in cm^-1, the form used by He et al. (2021) for methane, nitrous oxide and sulfur hexafluoride.- Attributes:
- afloat
Constant term of
(n - 1) * 1e8at the reference state.- bfloat
Pole strength in cm^-2.
- cfloat
Pole position in cm^-2.
- solprop.physdata.sellmeier.chi1(gas, omega, *, pressure, temperature=293.15)[source]#
Return the linear susceptibility of a gas.
chi1 = gamma(omega) * rho, with the number density from the equation of state.- Parameters:
- gasGas or str
The species.
- omegaarray_like
Angular frequency in rad/s, >= 0.
- pressurefloat
Absolute pressure in bar (the documented non-SI user-interface unit), >= 0.
- temperaturefloat, optional
Temperature in K, > 0. Defaults to 293.15 K.
- Returns:
- ndarray
Dimensionless susceptibility, 0-d for scalar input.
- Warns:
- MaterialRangeWarning
If any wavelength lies outside the validity range of the source.
Examples
>>> from solprop.physdata import Gas, chi1 >>> f"{float(chi1(Gas.Ar, 2.356e15, pressure=1.0)):.6e}" '5.142114e-04'
- solprop.physdata.sellmeier.dchi1_domega(gas, omega, *, pressure, temperature=293.15)[source]#
Return the analytic frequency derivative of the linear susceptibility.
- Parameters:
- gasGas or str
The species.
- omegaarray_like
Angular frequency in rad/s, >= 0.
- pressurefloat
Absolute pressure in bar, >= 0.
- temperaturefloat, optional
Temperature in K, > 0. Defaults to 293.15 K.
- Returns:
- ndarray
dchi1/domegain s/rad, 0-d for scalar input.
- Warns:
- MaterialRangeWarning
If any wavelength lies outside the validity range of the source.
Examples
>>> from solprop.physdata import Gas, dchi1_domega >>> f"{float(dchi1_domega(Gas.Ar, 2.356e15, pressure=1.0)):.6e}" '3.630134e-21'
- solprop.physdata.sellmeier.drefractive_index_domega(gas, omega, *, pressure, temperature=293.15)[source]#
Return the analytic frequency derivative of the refractive index.
dn/domega = (dchi1/domega) / (2 n). Together withnthis gives the group index and the group delay per unit length,beta_1 = (n + omega dn/domega) / c, which the co-moving frame needs to about 1e-10.- Parameters:
- gasGas or str
The species.
- omegaarray_like
Angular frequency in rad/s, >= 0.
- pressurefloat
Absolute pressure in bar (the documented non-SI user-interface unit), >= 0.
- temperaturefloat, optional
Temperature in K, > 0. Defaults to 293.15 K.
- Returns:
- ndarray
dn/domegain s/rad, 0-d for scalar input.
- Warns:
- MaterialRangeWarning
If any wavelength lies outside the validity range of the source.
Examples
>>> from solprop.physdata import Gas, drefractive_index_domega >>> f"{float(drefractive_index_domega(Gas.Ar, 2.356e15, pressure=1.0)):.6e}" '1.814601e-21'
- solprop.physdata.sellmeier.gamma(gas, *, model='recommended')[source]#
Return the per-particle susceptibility model for a gas: optmat’s.
The returned object exposes
susceptibility(omega)in m^3, its exact derivativedsusceptibility_domega(omega), thewavelength_rangeits qualified intervals span, and thecitation.- Parameters:
- gasGas or str
The species.
- modelstr or OptmatModel, optional
"recommended"(the default), an optmat model name of this gas, such as"borzsonyi_2008/sellmeier_Ar", or an optmat model object.
- Returns:
- GasSusceptibility
The
OptmatSusceptibility.
- Raises:
- MaterialError
If the gas is unknown, optmat has no such model, or it describes another gas.
Examples
>>> from solprop.physdata import Gas, gamma >>> gamma(Gas.Kr).source 'fit/Kr' >>> gamma(Gas.Kr, model="borzsonyi_2008/sellmeier_Kr").source 'borzsonyi_2008/sellmeier_Kr'
- solprop.physdata.sellmeier.refractive_index(gas, omega, *, pressure, temperature=293.15)[source]#
Return the refractive index of a gas.
n = sqrt(1 + chi1), real: these models carry no absorption. Where the quantity of interest isn - 1, userefractive_index_minus_one(), which avoids the cancellation.- Parameters:
- gasGas or str
The species.
- omegaarray_like
Angular frequency in rad/s, >= 0.
- pressurefloat
Absolute pressure in bar (the documented non-SI user-interface unit), >= 0.
- temperaturefloat, optional
Temperature in K, > 0. Defaults to 293.15 K.
- Returns:
- ndarray
Refractive index, 0-d for scalar input.
- Warns:
- MaterialRangeWarning
If any wavelength lies outside the validity range of the source.
Examples
Argon at 800 nm and 1 bar.
>>> from solprop.physdata import Gas, refractive_index >>> f"{float(refractive_index(Gas.Ar, 2.356e15, pressure=1.0)):.9f}" '1.000257073'
- solprop.physdata.sellmeier.refractive_index_minus_one(gas, omega, *, pressure, temperature=293.15)[source]#
Return
n - 1for a gas, without cancellation.Computed as
chi1 / (1 + sqrt(1 + chi1)), which is exact for the small susceptibilities of a gas; formingsqrt(1 + chi1) - 1instead would lose about four significant figures at 1 bar (docs/dev/conventions.mdsection 5).- Parameters:
- gasGas or str
The species.
- omegaarray_like
Angular frequency in rad/s, >= 0.
- pressurefloat
Absolute pressure in bar (the documented non-SI user-interface unit), >= 0.
- temperaturefloat, optional
Temperature in K, > 0. Defaults to 293.15 K.
- Returns:
- ndarray
n - 1, 0-d for scalar input.
- Warns:
- MaterialRangeWarning
If any wavelength lies outside the validity range of the source.
Examples
>>> from solprop.physdata import Gas, refractive_index_minus_one >>> f"{float(refractive_index_minus_one(Gas.Ar, 2.356e15, pressure=1.0)):.6e}" '2.570726e-04'