solprop.nonlinear.mixtures#

Select nonlinear responses for the labelled populations of a mixture.

Functions

electronic_response(material, *, selection, ...)

Build a species' electronic third-order response under a selection's policy.

raman_temperature(mixture, label[, ...])

Return the temperature a component's rotational Raman populations take.

responses_for(mixture, *[, kerr, thg, ...])

Build responses bound to the ordered component labels of a mixture.

solprop.nonlinear.mixtures.electronic_response(material, *, selection, wavelength, thg, species=None)[source]#

Build a species’ electronic third-order response under a selection’s policy.

selection.electronic decides: the carrier policies ("recommended", "carrier-kerr") give a KerrResponse with the Kerr coefficient at the carrier, and the dispersive policies of SEP 6 (DISPERSIVE_POLICIES) a DispersiveKerrResponse of optmat’s whole hyperpolarizability model, with thg selecting its sector.

Parameters:
materialSpecies

The population’s species.

selectionMaterialSelection

The run’s material selection.

wavelengthfloat or None

The carrier in m, at which a carrier policy evaluates the coefficient.

thgbool

Retain the third harmonic: the full cubic, or for a dispersive policy its number-conserving sector when false.

speciesstr or None, optional

The component label the response is bound to.

Returns:
KerrResponse or DispersiveKerrResponse

The response.

Raises:
MaterialError

If the species has no Kerr data, or a dispersive policy meets a species without optmat’s hyperpolarizability model (a supplied species, air), which is refused by name rather than given a borrowed curve.

Examples

>>> from solprop.nonlinear.mixtures import electronic_response
>>> from solprop.physdata import MaterialSelection, species
>>> chosen = MaterialSelection(electronic="gas-polynomial")
>>> response = electronic_response(
...     species("Ar"), selection=chosen, wavelength=800e-9, thg=True
... )
>>> type(response).__name__, response.evaluator
('DispersiveKerrResponse', 'polynomial')
solprop.nonlinear.mixtures.raman_temperature(mixture, label, requested=None, *, length=None, warn=True, widths=False)[source]#

Return the temperature a component’s rotational Raman populations take.

The rotational populations are a Boltzmann ladder fixed per run: they cannot follow a temperature that varies along the fibre without new content at the kernel seam, which is not supported. A mixture whose temperature is a path therefore takes one reference temperature: requested (MolecularOptions.temperature) if given, otherwise the mean weighted by that species’ own number density

\[\bar T_s = \frac{\int_0^L \rho_s\,T\,\mathrm{d}z} {\int_0^L \rho_s\,\mathrm{d}z}\]

over the run [0, L] (length; without it, the species’ density span, which must then be finite), by adaptive quadrature across the breakpoints of both. The populations are the species’ own, so the positions where the species is are the ones that count: in independent populations one species can sit where the gas is cool and another where it is hot. The Raman linewidths are unchanged: they follow the density only. A constant temperature is returned as it is. The mean warns that the populations do not follow T(z); an explicit reference, the caller’s own choice, logs the same message at INFO instead.

An optmat response (SEP 3) is built for a mixture’s whole composition, so it names several labels: the weight is then their summed density, and the reference fixes the widths’ temperature laws as well as the populations (widths).

Parameters:
mixtureMixture

The fill.

labelstr or sequence of str

The component whose populations these are, or the components of a composition, whose summed density is the weight.

requestedfloat or None, optional

An explicit reference temperature in K, > 0; None takes the mean.

lengthfloat or None, optional

The run’s length in m, > 0: the mean is taken over [0, length], never beyond the fibre. None takes the species’ density span.

warnbool, optional

Whether to warn when the temperature varies and the reference is the mean. Default True.

widthsbool, optional

Whether the reference also fixes the linewidths’ temperature laws, as for an optmat response; the message says so. Default False.

Returns:
float

The reference temperature in K.

Raises:
MaterialError

If the label is unknown, or the mean is needed and there is no finite span to average over (an unbounded density and no length), or the species’ density vanishes there.

Warns:
RamanTemperatureWarning

When the temperature varies, the reference is the mean and warn is set, naming the species, the reference, the spread of T(z) over the run, and that the populations do not follow it.

Examples

>>> import warnings
>>> from solprop.nonlinear.mixtures import raman_temperature
>>> from solprop.physdata import Mixture
>>> from solprop.profiles import Linear
>>> mixture = Mixture.fill({"N2": 1.0}, 1.0, temperature=Linear(290.0, 310.0, 1.0))
>>> with warnings.catch_warnings():
...     warnings.simplefilter("ignore")
...     f"{raman_temperature(mixture, 'N2', length=1.0):.3f}"
'299.889'

At a constant pressure the density goes as 1/T (to the compressibility’s variation), so the mean is nearly the logarithmic mean 20 K / ln(310/290) = 299.889 K.

solprop.nonlinear.mixtures.responses_for(mixture, *, kerr=True, thg=None, plasma=False, raman=False, lambda0=None, envelope=False, length=None, selection=None, plasma_integration=None)[source]#

Build responses bound to the ordered component labels of a mixture.

Parameters:
mixtureMixture

Species and density paths; component preionisation and Raman options apply.

kerrbool, optional

Include every component’s electronic third-order response: under the selection’s electronic policy, the Kerr coefficient at the carrier or SEP 6’s dispersive response (electronic_response()). Missing data is an error naming that species, including at zero density.

thgbool or None, optional

Retain third harmonics; None follows the grid (off for envelopes).

plasmabool, IonisationRate or Mapping, optional

True selects each built-in gas’s rate from optmat under the selection (OptmatRate); a custom species’ rate must be given by label. A mapping selects rates by label; omitted labels are off. A bare rate must name the species to which it applies. Default False.

ramanbool, Sequence of str or Mapping, optional

True includes every available term and logs omissions. A sequence selects labels; a mapping selects labels and optional molecular terms. Explicit unavailable selections raise an error. Default False.

lambda0float or None, optional

Reference wavelength in m, the carrier: required by the default rate and by a species whose Kerr coefficient is optmat’s, which is evaluated there.

envelopebool, optional

Build cycle-averaged envelope plasma from instantaneous isotropic rates. Default False retains the real-field response.

lengthfloat or None, optional

The run’s length in m. Under a temperature path the rotational Raman populations take a reference temperature averaged over [0, length] (raman_temperature()); None averages over each species’ density span, which must then be finite.

selectionMaterialSelection or None, optional

The run’s material selection; None is MaterialSelection(). plasma=True takes optmat’s rate model for each component (OptmatRate, selection.ionisation), and refuses a custom species, whose rate must be given by label. The Raman response, too, is optmat’s when the mixture’s populations are built-in gases (SEP 3): one response for the whole composition, driven and damped by its summed density (solprop.nonlinear.optmat_raman.mixture_raman()), with the carrier lambda0 unless the selection names one; a mixture of supplied species keeps their per-component responses.

plasma_integration{‘band’, ‘trapezoid’} or None, optional

The running-integral rule of every field plasma response (SEP 18); None takes PlasmaResponse’s default. One problem’s channels share their current integrals, so one rule serves them all. Refused with envelope plasma.

Returns:
tuple

Declared responses in component order, with stable label bindings.

Raises:
MaterialError

If labels, rate bindings or required response data are unavailable, or a plasma integration rule is given beside envelope plasma.