solprop.nonlinear.optmat_rates#

Ionisation rates from optmat’s rate models, on solprop’s rate protocol (SEP 3).

solprop keeps no ionisation-rate formula of its own for an optmat-backed run (SEP 3, D1): OptmatRate adapts one of optmat’s rate models to the IonisationRate protocol, which the translation layer tabulates into the existing RateTable unchanged. An atom’s rate comes from optmat.gas.ionisation_rates and a molecule’s from optmat.gas.molecular_ionisation_rates; each refuses the other’s species. The adapter converts and records; the physics is optmat’s.

What the adapter adds, and nothing else:

  • a threshold: the field below which optmat’s instantaneous rate is under a declared negligible rate (NEGLIGIBLE_RATE), found by bisection in the logarithm of the field. Below it the rate is exactly zero, which the plasma loss term I W (1 - f) / E relies on;

  • the ceiling MAX_RATE, a numerical safety cap that no physical rate reaches;

  • the energy per event the plasma loss pays (SEP 3, D8). optmat’s rate-weighted energy I(E) = L(E) / W(E) moves with the field between the channels of a noble gas; solprop’s kernel carries one energy per population, so the loss takes the constant I(E_ref) at a reference field – the input’s peak field, which the capillary driver binds (bind_reference_field()) – clipped to the tabulated fields, and the largest relative departure of I(E) from it over the tabulated fields at which the rate is not negligible is recorded as its bound. A one-channel model, every molecular one among them, is exact. Without a reference field the energy is the weak-field limit, the lowest channel’s;

  • the maximum field: optmat warns at every evaluation above it, and a rate table routinely extends there. Above it optmat’s instantaneous rate is outside its fit and turns over, falling towards zero within a decade of field, so the adapter holds the rate at its value at the maximum field and a table is built up to it (solprop.translate.ionisation.build_rate_table()). A direct evaluation above it is recorded in the run’s material log rather than warned at every call; OptmatRate.check_input() warns when the input’s own peak exceeds it, and whether a run reached it is peak_field_report()’s to say, after the run.

The manual page is docs/guide/media/ionisation.md, section “Rates from optmat”.

Module Attributes

NEGLIGIBLE_RATE

Rate in s^-1 below which an optmat rate is taken as exactly zero.

ENERGY_LOSS

The plasma energy-loss convention: the rate-weighted energy at a reference field.

LINEAR_POLARISATION_TOLERANCE

Circular share |S3| / S0 at the peak below which a field counts as linear.

Functions

bind_reference_field(responses, ...)

Bind every unbound optmat rate of a run's plasma responses to its peak field.

peak_field_report(rate, peak_rate, *, label)

Return the largest field a population saw, from its recorded peak rate.

selected_rate(material, selection, wavelength, *)

Return the rate a selection means for a species: optmat's, never solprop's.

Classes

OptmatRate(source[, wavelength, model, ...])

Take an ionisation rate from optmat, on solprop's rate protocol.

PeakFieldReport(label, species, model, ...)

Report the largest field one population's rate saw in a run.

solprop.nonlinear.optmat_rates.ENERGY_LOSS: Final = 'peak-weighted'#

The plasma energy-loss convention: the rate-weighted energy at a reference field.

solprop.nonlinear.optmat_rates.LINEAR_POLARISATION_TOLERANCE: Final[float] = 1e-06#

Circular share |S3| / S0 at the peak below which a field counts as linear.

The analytic signal of a linearly polarised field has S3 = 0 to rounding; a millionth of circular polarisation changes no rate this package carries.

solprop.nonlinear.optmat_rates.NEGLIGIBLE_RATE: Final[float] = 1e-30#

Rate in s^-1 below which an optmat rate is taken as exactly zero.

Over a picosecond it ionises one atom in 1e42, and in a 30 ps window one in 3e40: no statistic a run reports can see it. It is the same floor the envelope plasma’s cycle tables compare against (solprop.translate.envelope_plasma).

class solprop.nonlinear.optmat_rates.OptmatRate(source, wavelength=None, *, model='recommended', reference_field=None, field_range=None, negligible_rate=1e-30, maximum=4.134137333517015e+16)[source]#

Bases: object

Take an ionisation rate from optmat, on solprop’s rate protocol.

Built from a species name and a carrier wavelength – an atom through optmat’s ionisation_rate_model, a molecule through molecular_rate_model – or from an optmat rate model taken as it is: one made by with_parameters (an override, status user) or by from_parameters (a custom species). The rate is optmat’s instantaneous rate of the field’s magnitude,

\[W(E) = \min\left(W_\text{optmat}(\min(|E|, E_m)), W_\text{max}\right) \quad (|E| \ge E_t), \qquad W(E) = 0 \quad (|E| < E_t),\]

with the threshold \(E_t\) the field at which optmat’s rate reaches negligible_rate and \(E_m\) the model’s maximum field, above which the rate is held: optmat’s rate is outside its fit there, and turns over. optmat’s rates are for linear polarisation; along an elliptical field the instantaneous rate is a quasi-static approximation (SEP 3, D12).

Attributes:
sourcestr or object

A species name optmat curates a rate for ("Ar", "N2", a Gas), or an optmat rate model.

wavelengthfloat or None

Vacuum carrier wavelength in m, positive and finite; required with a name. With a model it is the model’s own, and a different one is refused.

modelstr, optional

"recommended" (optmat’s default model of the species), or a named literature form: "ppt_ilkov", "ppt_larochelle", "ppt_popruzhenko" for an atom; "moadk_zhao_2010", "moadk_tong_2002", "moadk_zhao_2017", "ppt_talebpour", "ppt_talebpour_ilkov", "adk_hydrogenic" for a molecule. Only with a name.

reference_fieldfloat or None, optional

Field amplitude in V/m at which the constant energy per event is taken: the input’s peak, which the capillary driver binds. It is clipped to the span the energy is defined over. None takes the weak-field limit, the lowest channel’s energy.

field_rangetuple of float or None, optional

The field amplitudes in V/m the run tabulates the rate over; the energy’s bound is taken over its part above the threshold. None takes the span from the threshold to the model’s maximum field.

negligible_ratefloat, optional

Rate in s^-1 below which the rate is zero, NEGLIGIBLE_RATE by default.

maximumfloat, optional

Ceiling on the rate in s^-1.

Raises:
MaterialError

If optmat has no rate for the species or the form is not of its family, a model object is given with a model name or another wavelength, or a number is not positive and finite.

Warns:
MaterialStatusWarning

Once per run, for a provisional or untested model (SF6’s).

MaterialRangeWarning

Once per run, translating optmat’s warning for a carrier below the wavelengths its rates were compared at (350 nm).

Examples

>>> from solprop.nonlinear.optmat_rates import OptmatRate
>>> rate = OptmatRate("Ar", 800e-9)
>>> rate.convention, float(rate(0.0)), float(rate(0.5 * rate.threshold))
('instantaneous-isotropic', 0.0, 0.0)
>>> rate.material_records[0].kind
'ionisation_rate'
bound(reference_field, field_range=None)[source]#

Return the rate with its energy taken at a reference field.

Parameters:
reference_fieldfloat

Field amplitude in V/m, the input’s peak.

field_rangetuple of float or None, optional

The field amplitudes in V/m the run tabulates; None keeps this rate’s.

Returns:
OptmatRate

The same model, its energy per event at the reference field, clipped to the tabulated fields above the threshold, and its bound over them.

Examples

>>> from solprop.nonlinear.optmat_rates import OptmatRate
>>> rate = OptmatRate("Ar", 800e-9).bound(2.7e10, (2.7e7, 8.1e11))
>>> rate.effective_reference_field
27000000000.0
check_input(peak_field, *, circular=0.0)[source]#

Warn about an input outside what the rate is defined for, once per run.

Parameters:
peak_fieldfloat

The input’s peak field amplitude in V/m.

circularfloat, optional

The circular share |S3| / S0 of the field at its peak, in [0, 1].

Warns:
MaterialRangeWarning

If the peak exceeds the model’s maximum field, or the field is not linearly polarised (LINEAR_POLARISATION_TOLERANCE) and the Keldysh parameter at the peak exceeds one, where elliptic and orbital-resolved theories depart from the quasi-static average (D12).

property citation: str[source]#

Return the model’s references and the adapter’s settings.

Returns:
str

The model’s citation as optmat gives it, its name and digest, the threshold and the energy convention.

property convention: Literal['instantaneous-isotropic', 'cycle-averaged', 'unspecified'][source]#

Return the optical-cycle convention of the rate.

Returns:
str

'instantaneous-isotropic': optmat’s instantaneous rate of the field’s magnitude, which an envelope averages over the polarisation ellipse.

property effective_reference_field: float | None[source]#

Return the field the constant energy is taken at, after clipping.

Returns:
float or None

Field in V/m, or None for the weak-field limit.

property energy_bound: float[source]#

Return the bound of the constant energy over the span it is defined on.

Returns:
float

max |I(E) / I_ref - 1| over the tabulated fields above the threshold (energy_span), dimensionless; zero for a one-channel model.

property energy_kind: str[source]#

Return the kind of the energies the rate’s exponent uses.

Returns:
str

'adiabatic', 'vertical' or 'not stated', as optmat states it.

energy_per_event(field_amplitude)[source]#

Return optmat’s rate-weighted energy per event, L(E) / W(E).

Parameters:
field_amplitudearray_like or float

Field amplitude in V/m; the sign is ignored.

Returns:
numpy.ndarray

Energy in J, with the shape of the field; the lowest channel’s at zero field. Above the maximum field it is held at its value there, as the rate is.

property energy_span: tuple[float, float][source]#

Return the fields the bound is taken over.

Returns:
tuple of float

Lowest and highest field in V/m.

field_range: tuple[float, float] | None = None#
property ionisation_potential: float[source]#

Return the constant energy per ionisation event the plasma loss pays.

Returns:
float

The rate-weighted energy at the reference field, in J, or the weak-field limit without one.

keldysh(field_amplitude)[source]#

Return the model’s Keldysh parameter at a field.

Parameters:
field_amplitudefloat

Field amplitude in V/m, positive.

Returns:
float

The Keldysh parameter of the model’s lowest channel, dimensionless.

manifest_entry()[source]#

Return the rate’s entry in a run’s material manifest.

Returns:
dict

The species, model and digest, the threshold policy, the energy convention with its reference field, constant and bound, the maximum field, the uncertainty factor and the polarisation approximation.

property material_records: tuple[MaterialRecord, ...][source]#

Return the record of the optmat model.

Returns:
tuple of MaterialRecord

One record.

maximum: float = 4.134137333517015e+16#
property maximum_field: float[source]#

Return the largest field at which optmat gives the rate without a warning.

Returns:
float

Field in V/m.

model: str = 'recommended'#
negligible_rate: float = 1e-30#
property optmat_model: Any[source]#

Return the optmat rate model the adapter evaluates.

Returns:
Any

The model, for direct comparison with its own methods. Typed loosely, as the bridge types every optmat object (solprop.physdata._optmat).

property parameters: tuple[tuple[str, float | int | bool | str], ...][source]#

Return every setting that changes the rate, name-sorted and hashable.

Returns:
tuple

The model’s identity digest, the species, the carrier, the threshold and its negligible rate, the ceiling and the energy convention.

property plasma_energy: float[source]#

Return the energy per event a plasma response pays, the same constant.

Returns:
float

ionisation_potential, J; declaring it is what makes a response take it (solprop.nonlinear.ionisation.bind_rate_energy()).

reference_field: float | None = None#
source: object#
property species_identity: str[source]#

Return the species the model describes.

Returns:
str

The gas’s name, or a custom species’ name as its model gives it.

property status: str[source]#

Return the model’s optmat status.

Returns:
str

'validated', 'provisional', 'untested', 'comparison' or 'user'.

property threshold: float[source]#

Return the field amplitude below which the rate is exactly zero.

Returns:
float

Field in V/m at which optmat’s rate reaches negligible_rate, to a relative 1e-12 from above.

property uncertainty_factor: float[source]#

Return the factor within which optmat expects the rate to be right.

Returns:
float

Dimensionless; NaN for a literature form or an override, which state none.

wavelength: float | None = None#
class solprop.nonlinear.optmat_rates.PeakFieldReport(label, species, model, peak_rate, largest_field, reached_maximum, maximum_field, energy_at_largest, constant_energy, departure)[source]#

Bases: object

Report the largest field one population’s rate saw in a run.

Attributes:
labelstr

The population.

speciesstr

Its species.

modelstr

optmat’s model name.

peak_ratefloat

The largest rate the run recorded at its save planes, s^-1.

largest_fieldfloat or None

The field in V/m at which the rate is the peak rate; the maximum field, a lower bound, when the run reached it (reached_maximum); None when no ionisation was recorded.

reached_maximumbool

Whether the run reached the model’s maximum field, above which the rate is held, so that the largest field is at least that.

maximum_fieldfloat

The model’s maximum field, V/m.

energy_at_largestfloat or None

optmat’s rate-weighted energy at the largest field, J.

constant_energyfloat

The constant energy the run’s loss paid, J.

departurefloat or None

energy_at_largest / constant_energy - 1, dimensionless.

constant_energy: float#
departure: float | None#
energy_at_largest: float | None#
label: str#
largest_field: float | None#
maximum_field: float#
model: str#
peak_rate: float#
reached_maximum: bool#
species: str#
to_dict()[source]#

Return the report as plain values, for a run’s manifest.

Returns:
dict

Every field.

solprop.nonlinear.optmat_rates.bind_reference_field(responses, reference_field, field_range)[source]#

Bind every unbound optmat rate of a run’s plasma responses to its peak field.

Parameters:
responsessequence

The run’s responses.

reference_fieldfloat

The input’s peak field amplitude in V/m.

field_rangetuple of float or None

The field amplitudes in V/m the run tabulates the rates over.

Returns:
tuple

The responses, each plasma response whose rate is an OptmatRate without a reference field rebuilt with the bound rate (and so the bound energy); every other response as it was.

solprop.nonlinear.optmat_rates.peak_field_report(rate, peak_rate, *, label, average=None)[source]#

Return the largest field a population saw, from its recorded peak rate.

The recorded rate rises with the field below the maximum field, so the field is its inverse there, found by bisection in the logarithm of the field. A field grid’s statistic is the tabulated rate of |E|, inverted through the rate itself. An envelope’s is cycle-averaged, and is inverted through the average the run itself took: the caller passes it as average, the run’s cycle integrals at linear polarisation (solprop.translate.envelope_plasma.cycle_moments), the quadrature its statistic comes from. optmat’s own cycle_averaged_rate would not do: above the barrier-suppression field it departs from that average (by 35 % for argon at its maximum field). The statistic is recorded at the save planes, so the field between them is not seen. A peak rate at the recorded rate of the maximum field, to the table’s tolerance, means the run reached it: the rate is held above it, so how far the field went beyond is not known.

Parameters:
rateOptmatRate

The population’s rate.

peak_ratefloat

The largest rate recorded, s^-1, non-negative.

labelstr

The population.

averagecallable or None, optional

The recorded rate in s^-1 at an envelope amplitude in V/m, for an envelope run; None (a field grid) takes the rate itself.

Returns:
PeakFieldReport

The largest field, whether it reached the maximum field, and the rate-weighted energy there against the constant the loss paid.

Examples

>>> from solprop.nonlinear.optmat_rates import OptmatRate, peak_field_report
>>> rate = OptmatRate("Ar", 800e-9)
>>> report = peak_field_report(rate, float(rate(3e10)), label="Ar")
>>> f"{report.largest_field:.6e}", report.reached_maximum
('3.000000e+10', False)
solprop.nonlinear.optmat_rates.selected_rate(material, selection, wavelength, *, label=None)[source]#

Return the rate a selection means for a species: optmat’s, never solprop’s.

Parameters:
materialSpecies

A built-in gas, carrying optmat’s ionisation energy unchanged.

selectionMaterialSelection

The run’s selection; its ionisation names the model ("recommended", a literature form) or is an optmat rate model for this species.

wavelengthfloat or None

The run’s reference wavelength in m; selection.carrier_wavelength takes precedence when given.

labelstr or None, optional

The population, for messages.

Returns:
OptmatRate

The rate, unbound to a reference field.

Raises:
MaterialError

If the species is custom (not built in, or with its own ionisation data), which needs an explicit rate (D1), or there is no carrier, or a model object describes another species.

Examples

>>> from solprop.nonlinear.optmat_rates import selected_rate
>>> from solprop.physdata import species
>>> from solprop.physdata.selection import MaterialSelection
>>> selection = MaterialSelection(ionisation="moadk_zhao_2010")
>>> selected_rate(species("N2"), selection, 800e-9).status
'comparison'