solprop.translate.ionisation#
Ionisation rates as converged, clipped, log-spaced spline tables.
Evaluating a rate model directly – optmat’s, through
solprop.nonlinear.optmat_rates.OptmatRate – costs of order a microsecond per
sample, special functions per point, per stage. A propagation
evaluates the rate once per sample of the fine time grid on every column of every stage,
so the rate has to be a table. This module builds it.
Three properties of the table matter:
Log-spaced knots.
log Wis nearly linear inlog Eat the low-field turn-on and flattens at high field, so uniform knots inlog Eput the samples where the curvature is and let one table span four decades. Knots uniform inEover the same span reach only about one per cent.A converged knot count. The count doubles until the interpolant meets the requested relative tolerance against direct evaluation everywhere, rather than being fixed in advance.
Clipping rather than throwing. A rate that raised above its maximum field would stop a run in the middle of a propagation. Here the table is exactly zero below
field_min– which the plasma loss termIp W (1-f) / Erelies on – and holds its last value abovefield_max, so a diverged step cannot extrapolate a cubic inlog Winto an overflow (docs/dev/stepper.mdsection 10, trap 9).
The manual page is docs/guide/media/ionisation.md; the kernel’s view of the table is
docs/dev/kernel-contract.md section 5.
Module Attributes
Version of the table layout, part of the cache key. |
|
Default bound on the relative error of the table against direct evaluation. |
|
Knot intervals tried first; the count doubles until the tolerance is met. |
|
Knot budget before the build gives up. |
Functions
|
Build a converged spline table of an ionisation rate. |
Forget every table built in this process. |
|
|
Return the deterministic cache key of a table. |
Classes
|
A cubic-spline table of |
- solprop.translate.ionisation.DEFAULT_INTERVALS: Final = 256#
Knot intervals tried first; the count doubles until the tolerance is met.
- solprop.translate.ionisation.DEFAULT_RTOL: Final = 1e-06#
Default bound on the relative error of the table against direct evaluation.
- solprop.translate.ionisation.MAX_KNOTS: Final = 1048576#
Knot budget before the build gives up.
A million knots over four decades is a spacing of 1e-5 in
log E; needing more means the rate is not smooth, which for these models means a kink, not a fine feature.
- class solprop.translate.ionisation.RateTable(log_rate, coefficients, log_field_min, d_log_field, field_min, field_max, rate_max, error, key, convention='unspecified', species_identity=None, ionisation_potential=None)[source]#
Bases:
objectA cubic-spline table of
log Wagainstlog E, on uniform log-spaced knots.Knots are uniform in
log E, so locating one is arithmetic rather than a search:i = floor((log|E| - log_field_min) / d_log_field). On intervalithe value issum_j coefficients[j, i] t^(3-j)witht = log|E| - log_field_min - i d_log_field, which is howscipy.interpolate.CubicSplinestores it. The coefficients rather than a spline object are the table, because they are what crosses into the kernel contract.- Attributes:
- log_field_minfloat
Natural logarithm of
field_min, with the field in V/m.- d_log_fieldfloat
Knot spacing in
log E, positive.- log_ratenumpy.ndarray
Natural logarithm of the rate at each knot, shape
(n_table,), s^-1. Diagnostic: evaluation goes through the coefficients.- coefficientsnumpy.ndarray
Spline coefficients, shape
(n_deg, n_intervals), highest power first.- field_minfloat
Field amplitude in V/m below which the table is exactly zero.
- field_maxfloat
Field amplitude in V/m above which the table holds
rate_max.- rate_maxfloat
The rate at
field_max, s^-1, and the value returned above it.- errorfloat
The largest relative deviation from direct evaluation measured during the build.
- keystr
A digest of the rate’s parameters and the build settings, stable across processes. Names a cache entry; two tables with the same key are the same table.
- conventionstr
Optical-cycle convention retained from the source rate. Legacy manually constructed tables default to
'unspecified'.- species_identitystr or None
Chemical species name, when declared by the source rate.
- ionisation_potentialfloat or None
First ionisation potential in J, when declared by the source rate.
- Raises:
- TranslationError
If the knot spacing is not positive, the coefficient array does not have four rows and one column per interval, the field range is not increasing, or anything stored is not finite.
Examples
>>> from solprop.nonlinear.optmat_rates import OptmatRate >>> from solprop.translate.ionisation import build_rate_table >>> table = build_rate_table(OptmatRate("Ar", 800e-9), (1e9, 5e10), rtol=1e-4) >>> float(table(1e6)) 0.0 >>> abs(float(table(3e10)) / float(OptmatRate("Ar", 800e-9)(3e10)) - 1.0) < 1e-4 True
- coefficients: Float[ndarray, 'n_deg n_intervals']#
- property field: Float[ndarray, 'n_table'][source]#
Return the knot positions as field amplitudes.
- Returns:
- numpy.ndarray
Geometrically spaced field amplitudes in V/m, shape
(n_table,).
- log_evaluate(log_field)[source]#
Return the interpolated
log Wat logarithmic field amplitudes.This is the interpolant itself, without the clipping and without the exponential. The build measures its error here rather than on the rate, because a difference of logarithms is the relative error and does not underflow where the rate is 1e-300.
- Parameters:
- log_fieldnumpy.ndarray
Natural logarithms of field amplitudes in V/m, shape
(n_probe,), inside[log(field_min), log(field_max)].
- Returns:
- numpy.ndarray
Interpolated
log Wwith the rate in s^-1, shape(n_probe,).
- property log_field: Float[ndarray, 'n_table'][source]#
Return the knot positions in
log E.- Returns:
- numpy.ndarray
Uniformly spaced logarithms of the field amplitude, shape
(n_table,).
- log_rate: Float[ndarray, 'n_table']#
- property n_knots: int[source]#
Return the number of knots.
- Returns:
- int
The knot count, one more than the number of intervals.
- property plasma_energy: float | None[source]#
Return the energy per ionisation event the source rate declared, in J.
A table keeps the species and the energy of the rate it tabulates, so that a plasma response built on the table pays the same energy as one built on the rate (
solprop.nonlinear.ionisation.bind_rate_energy(), SEP 3, D8).- Returns:
- float or None
ionisation_potentialwhen the source rate named its species and energy;Noneotherwise.
- solprop.translate.ionisation.SCHEMA_VERSION: Final = 2#
Version of the table layout, part of the cache key.
Bump it when the knot placement, the spline convention or the clipping changes, so that a table built by an older version can never be mistaken for one built by this one.
- solprop.translate.ionisation.build_rate_table(rate, field_range, *, rtol=1e-06, n_intervals=256, max_knots=1048576, use_cache=True)[source]#
Build a converged spline table of an ionisation rate.
The knot count doubles until the interpolant is within
rtolof direct evaluation at every probe point, which is what makes the table’s accuracy a stated property rather than a consequence of a fixed sample count.- Parameters:
- rateIonisationRate
The rate to tabulate, in s^-1 for a field amplitude in V/m.
- field_rangetuple of float
Lower and upper field amplitude in V/m. The lower end is raised to the rate’s threshold and the upper end lowered below any clipping; see the table’s
field_minandfield_maxfor what was used.- rtolfloat, optional
Bound on the relative deviation from direct evaluation, measured as the largest absolute difference of logarithms.
- n_intervalsint, optional
Knot intervals to try first.
- max_knotsint, optional
Knot budget before the build gives up.
- use_cachebool, optional
Reuse a table already built in this process for the same key, and record this one under it.
- Returns:
- RateTable
The converged table.
- Raises:
- TranslationError
If the arguments are inconsistent, nothing is left of the field range, or the tolerance is not reached within
max_knots.
Examples
>>> from solprop.nonlinear.optmat_rates import OptmatRate >>> from solprop.translate.ionisation import build_rate_table >>> table = build_rate_table(OptmatRate("Ar", 800e-9), (1e9, 5e10), rtol=1e-6) >>> table.error < 1e-6 True
- solprop.translate.ionisation.clear_rate_table_cache()[source]#
Forget every table built in this process.
The cache exists so that two responses sharing a rate share its table; it is a memo, not a store, and nothing is written to disk. Tests that count builds clear it first.
Examples
>>> from solprop.translate.ionisation import clear_rate_table_cache >>> clear_rate_table_cache()
- solprop.translate.ionisation.rate_table_key(rate, field_range, rtol)[source]#
Return the deterministic cache key of a table.
Every setting that changes the table appears once, in name order, so the key cannot depend on the order in which the rate’s keyword arguments were written: the same settings in a different order give the same cache file.
- Parameters:
- rateIonisationRate
The rate to tabulate.
- field_rangetuple of float
Lower and upper field amplitude in V/m.
- rtolfloat
Requested relative tolerance.
- Returns:
- tuple
A hashable key, beginning with the schema version.
Examples
>>> from solprop.nonlinear.optmat_rates import OptmatRate >>> from solprop.translate.ionisation import rate_table_key >>> first = OptmatRate("Ar", 800e-9) >>> second = OptmatRate("Ar", 800e-9) >>> rate_table_key(first, (1e9, 1e11), 1e-6) == rate_table_key( ... second, (1e9, 1e11), 1e-6 ... ) True