optmat.gas.ionisation_rates#

Strong-field ionisation rates of the noble gases (TC-652 to TC-662).

The rate at which an atom loses an electron in a linearly polarised field of amplitude \(F\) and angular frequency \(\omega\) is built here from three factors, each validated against its own references (the manual page Ionisation rates):

\[W(F, \omega) = N_\text{eff} \sum_c p_c\; w_c^\text{PPT}(F, \omega)\; S_c(F).\]
  • \(w^\text{PPT}\) is the rate of one electron in the orbital \((l, m = 0)\): Perelomov, Popov and Terent’ev’s rate in a short-range potential (their eq. 54) times a Coulomb factor (coulomb_factor()). The default’s is Perelomov and Popov’s (1967) static factor \((2F_0/F)^{2n^*}\), eq. (42), times \((1 + 2\gamma/e)^{-2n^* c s}\) with \(s = n^*\omega/2I_p\), fitted to one-electron calculations (frequency; TC-831, TC-848). For \(\omega \to 0\) it is the cycle average of the static tunnelling rate (tunnelling_rate_au()).

  • \(S\) is the correction of that rate at finite field, fitted by Tong and Lin (2005) or by Zhang, Lan and Lu (2014) to exact static rates of one electron in a model potential (tong_lin_factor(), zhang_factor()).

  • \(N_\text{eff}\) is the rate of the atom over that of the one electron, a constant per gas set from all-electron calculations and measurements (data/gas/ ionisation_rates.toml). Its weak-field limit is 2, the two electrons of the \(m = 0\) orbital (Tolstikhin, Madsen and Morishita 2014, section II G); at working fields it is 0.8 to 1.5: about 1 for argon, 1.35 for krypton, 1.5 for xenon, 1.47 for helium (TC-847, TC-848, TC-850).

  • The sum is over the fine-structure levels \(c\) of the ion a \(p\) shell leaves, \(^2P_{3/2}\) and \(^2P_{1/2}\), each with its own ionisation energy, with the weights \(p_c = 2/3\) and \(1/3\) of the \(m = 0\) orbital.

Atomic units throughout the functions whose names end in _au: \(\kappa = \sqrt{2 I_p}\), \(n^* = Z/\kappa\), \(F_0 = \kappa^3\), and the Keldysh parameter \(\gamma = \omega\kappa/F\). IonisationRateModel takes and returns SI: fields in V/m, rates in s-1, wavelengths in m.

Two rates are given, of the same model:

  • the cycle-averaged rate as a function of the field’s amplitude, which is what the theory defines (IonisationRateModel.cycle_averaged_rate());

  • the instantaneous rate as a function of the field itself, for a calculation that resolves the carrier (IonisationRateModel.instantaneous_rate()). Its average over a cycle is the cycle-averaged rate, to 4 %, at any Keldysh parameter (TC-662, TC-828), so that a pulse ionises the same fraction whichever rate is used; in a static field it is the static rate. It does not give the timing of the ionisation within the cycle at \(\gamma \gtrsim 1\).

What is not here, and why (the manual page has the evidence):

  • the factor \((1 + \gamma^2)^{-n^*}\) that Ilkov, Decker and Chin (1992, eq. 8) and Bergé et al. (2007, eq. B14) carry in the Coulomb term. No paper derives it, and it makes the rate too low by 2 at \(\gamma = 1\) and by 8 at \(\gamma = 3\) against time-dependent Schrödinger calculations. It is available (coulomb="ilkov"), as is Popruzhenko et al.’s factor ("popruzhenko"), to reproduce rates computed with them;

  • a Stark shift of the ionisation energy and a factor for the polarisation of the ion. For the active electron they are inside \(S\); for the rest of the atom they are inside \(N_\text{eff}\).

References#

  • A. M. Perelomov, V. S. Popov and M. V. Terent’ev, “Ionization of atoms in an alternating electric field”, Sov. Phys. JETP 23, 924 (1966).

  • A. M. Perelomov and V. S. Popov, “Ionization of atoms in an alternating electrical field. III”, Sov. Phys. JETP 25, 336 (1967).

  • A. M. Perelomov, V. S. Popov and V. P. Kuznetsov, “Allowance for the Coulomb interaction in multiphoton ionization”, Sov. Phys. JETP 27, 451 (1968).

  • S. F. J. Larochelle, A. Talebpour and S. L. Chin, “Coulomb effect in multiphoton ionization of rare-gas atoms”, J. Phys. B 31, 1215 (1998).

  • X. M. Tong, Z. X. Zhao and C. D. Lin, “Theory of molecular tunneling ionization”, Phys. Rev. A 66, 033402 (2002).

  • X. M. Tong and C. D. Lin, “Empirical formula for static field ionization rates of atoms and molecules by lasers in the barrier-suppression regime”, J. Phys. B 38, 2593 (2005).

  • Q. Zhang, P. Lan and P. Lu, “Empirical formula for over-barrier strong-field ionization”, Phys. Rev. A 90, 043410 (2014).

  • F. A. Ilkov, J. E. Decker and S. L. Chin, “Ionization of atoms in the tunnelling regime with experimental evidence using Hg atoms”, J. Phys. B 25, 4005 (1992).

  • L. Bergé, S. Skupin, R. Nuter, J. Kasparian and J.-P. Wolf, “Ultrashort filaments of light in weakly ionized, optically transparent media”, Rep. Prog. Phys. 70, 1633 (2007).

  • S. V. Popruzhenko, V. D. Mur, V. S. Popov and D. Bauer, “Strong field ionization rate for arbitrary laser frequencies”, Phys. Rev. Lett. 101, 193003 (2008).

  • O. I. Tolstikhin, L. B. Madsen and T. Morishita, “Weak-field asymptotic theory of tunneling ionization in many-electron atomic and molecular systems”, Phys. Rev. A 89, 013421 (2014).

  • M. V. Ammosov, N. B. Delone and V. P. Krainov, “Tunnel ionization of complex atoms and of atomic ions in an alternating electromagnetic field”, Sov. Phys. JETP 64, 1191 (1986).

Module Attributes

EVALUATION_VERSION

The version of this module's evaluation code, in the identity of every model that evaluates through it; raised whenever the code changes its output (OEP 1, section 4.8).

IONISATION_RATES_FILE

The named rate models and their constants per gas, each with its reason.

CoulombFactor

The Coulomb factor of the rate (coulomb_factor()).

StaticCorrection

The correction of the one-electron static rate at finite field.

Averaging

How the cycle-averaged and the instantaneous rate are related.

ChannelSum

How the sum over the above-threshold channels is taken (channel_factor()).

Structure

Where the asymptotic coefficient of the orbital comes from.

Functions

channel_factor(m, gamma[, threshold, tolerance])

Return \(A_m(\omega, \gamma)\), the factor of the above-threshold channels.

channel_function(m, x)

Return \(w_m(x)\), the weight of one above-threshold channel.

circular_enhancement(field_au, omega_au, ...)

Return the rate of a shell in a circular field over its adiabatic limit.

circular_saddle_point(gamma)

Return the saddle point \(\zeta_0(\gamma)\) of a circularly polarised field.

coulomb_factor(field_au, omega_au, ...[, ...])

Return the factor by which the Coulomb field of the ion raises the rate.

cycle_average(slope, curvature)

Return the average over a cycle of a rate, over the rate at the amplitude.

cycle_average_factor(field_au, ...)

Return \((3F/\pi F_0)^{1/2}\), the cycle average in the tunnelling limit.

ionisation_rate_coverage()

Return the gases each atomic rate model covers, building none of them.

ionisation_rate_model(gas, wavelength[, model])

Return the ionisation rate of a gas at a wavelength.

ionisation_rate_models()

Return every named model of every gas it covers, at 800 nm.

keldysh_parameter(field_au, omega_au, ...)

Return the Keldysh parameter \(\gamma = \omega\kappa / F\).

power_law_average(slope)

Return the average over a cycle of a rate that goes as a power of the field.

ppt_exponent_function(gamma)

Return \(g(\gamma)\) of the exponent of the rate.

short_range_rate_au(field_au, omega_au, ...)

Return the cycle-averaged rate of one electron in a short-range potential.

tong_lin_factor(field_au, ...[, charge])

Return Tong and Lin's correction of the tunnelling rate at finite field.

tunnelling_rate_au(field_au, ...[, m, charge])

Return the static tunnelling rate of one electron, to leading order.

zhang_factor(field_au, ionization_energy_au, ...)

Return Zhang, Lan and Lu's correction of the tunnelling rate.

Classes

Channel(label, ionization_energy, weight, source)

One level of the ion that the ionisation can leave, with its weight.

IonisationRateModel(gas, wavelength, model, ...)

The ionisation rate of a gas at one wavelength, in one named model.

optmat.gas.ionisation_rates.Averaging#

How the cycle-averaged and the instantaneous rate are related.

consistent: the average of the instantaneous rate over a cycle is the cycle-averaged rate, at any Keldysh parameter (the averages over a cycle computed by quadrature; TC-662, TC-828). tunnelling: the two differ by the factor of the tunnelling limit, cycle_average_factor(), as in the literature’s forms.

alias of Literal[‘consistent’, ‘tunnelling’]

class optmat.gas.ionisation_rates.Channel(label, ionization_energy, weight, source)[source]#

Bases: object

One level of the ion that the ionisation can leave, with its weight.

Attributes:
labelstr

The level, as the source names it.

ionization_energyfloat

Energy of the level above the atom’s ground state, J.

weightfloat

Share of the ionising orbital that leaves the ion in this level; the weights of a model’s channels sum to 1.

sourcestr

The curated datasets the energy comes from.

ionization_energy: float#
property ionization_energy_au: float#

The channel’s ionisation energy in hartree.

Returns:
float

ionization_energy / E_h.

label: str#
source: str#
weight: float#
optmat.gas.ionisation_rates.ChannelSum#

How the sum over the above-threshold channels is taken (channel_factor()).

alias of Literal[‘integral’, ‘sum’]

optmat.gas.ionisation_rates.CoulombFactor#

The Coulomb factor of the rate (coulomb_factor()).

alias of Literal[‘static’, ‘ilkov’, ‘popruzhenko’, ‘frequency’]

optmat.gas.ionisation_rates.EVALUATION_VERSION: Final = 2#

The version of this module’s evaluation code, in the identity of every model that evaluates through it; raised whenever the code changes its output (OEP 1, section 4.8).

optmat.gas.ionisation_rates.IONISATION_RATES_FILE: Final = PosixPath('/home/docs/checkouts/optmat/checkouts/7/src/optmat/data/gas/ionisation_rates.toml')#

The named rate models and their constants per gas, each with its reason.

class optmat.gas.ionisation_rates.IonisationRateModel(gas, wavelength, model, channels, orbital_l, structure, structure_coefficient, electrons, coulomb, static_correction, static_constants, channel_sum, averaging, uncertainty_factor, sources=<factory>, reasons=<factory>, *, status='user', status_reason='', modified=(), base='')[source]#

Bases: Identified

The ionisation rate of a gas at one wavelength, in one named model.

Built by ionisation_rate_model() from the curated parameters, or by from_parameters() from a caller’s; the attributes say what the model is made of. with_parameters() rebuilds it with any of INPUTS changed (OEP 1, section 6.3). Every field is an amplitude or an instantaneous value of a linearly polarised field.

Attributes:
gasGas or str

The gas, or a custom species’ name.

wavelengthfloat

Vacuum wavelength of the field, m; math.inf for a static field.

modelstr

The model’s name in ionisation_rates.toml, or "user".

channelstuple of Channel

The levels of the ion and their weights.

orbital_lint

Orbital angular momentum of the ionising electron; \(m = 0\).

structurestr

tong_2002: the coefficient \(C_l\) of Tong et al. (2002), Table II. hartree: Ammosov et al.’s (1986) eq. (19) with \(l^* = n^* - 1\).

structure_coefficientfloat or None

\(C_l\) in Tong et al.’s normalisation; None for hartree.

electronsfloat

\(N_\text{eff}\), the rate of the atom over that of one electron.

coulombstr

The Coulomb factor (coulomb_factor()).

static_correctionstr

tong-lin, zhang or none.

static_constantstuple of float

Tong and Lin’s \(\alpha\), or Zhang et al.’s \(a_1, a_2, a_3\).

channel_sumstr

integral (smooth) or sum (channel_factor()).

averagingstr

consistent or tunnelling: how the cycle-averaged and the instantaneous rate are related (Averaging).

uncertainty_factorfloat

The factor within which the rate is expected to be right between \(10^{-6}\) of saturation and saturation, at the wavelengths of wavelength_range: a judgement from the comparisons of the manual page, not a statistical interval.

sourcesdict of str to str

The curated dataset or decision behind each constant.

reasonsdict of str to str

Why each choice was made (from ionisation_rates.toml).

Examples

>>> model = ionisation_rate_model("Ar", 800e-9)
>>> f"{float(model.cycle_averaged_rate(2.744e10)):.3e}"  # 1e14 W/cm^2
'6.112e+11'
>>> f"{float(model.instantaneous_rate(2.744e10)):.3e}"
'2.576e+12'
EVALUATES_THROUGH: ClassVar[tuple[str, ...]] = ('optmat.gas.ionisation_rates',)#
EVALUATION_VERSION: ClassVar[int] = 1#
IDENTITY_KIND: ClassVar[str] = 'ionisation_rate'#
INPUTS: ClassVar[tuple[str, ...]] = ('averaging', 'channel_sum', 'channels', 'coulomb', 'electrons', 'ionization_energy', 'orbital_l', 'static_constants', 'static_correction', 'structure', 'structure_coefficient', 'uncertainty_factor')#

The parameters with_parameters() may change.

at_wavelength(wavelength)[source]#

Return the same model at another wavelength.

Parameters:
wavelengthfloat

Vacuum wavelength, m; math.inf for a static field.

Returns:
IonisationRateModel

The model at that wavelength.

averaging: str#
property barrier_suppression_field: float#

The field at which the barrier falls to the lowest channel’s level.

\(F_b = I_p^2 / 4Z\) in atomic units (Tong and Lin 2005, eq. 1, as \(\kappa^4/16Z\)).

Returns:
float

The field, V/m.

channel_rates(field_strength)[source]#

Return each channel’s instantaneous rate; they sum to the rate.

For a linearly polarised field: along an elliptical trajectory the instantaneous rate is a quasi-static approximation optmat does not validate.

Parameters:
field_strengtharray_like

The field, V/m; its sign is ignored.

Returns:
numpy.ndarray

Rates per atom, 1/s, shape (len(channels),) + shape(field); 0 at zero field.

Warns:
ModelRangeWarning

If a field exceeds maximum_field.

Examples

>>> argon = ionisation_rate_model("Ar", 800e-9)
>>> argon.channel_rates([2e10, 5e10]).shape
(2, 2)
channel_sum: str#
channels: tuple[Channel, ...]#
circular_rate(field_strength)[source]#

Return the rate in a circularly polarised field of a given magnitude.

The field of circular polarisation turns at constant magnitude \(F = (I/\varepsilon_0 c)^{1/2}\), so the rate is the same at every instant. Each channel’s static rate (its tunnelling rate with its coefficient, the static correction and the effective number of electrons, as for linear polarisation) is multiplied by the factor by which the field’s turning raises the shell’s short-range rate, circular_enhancement() (Barth & Smirnova 2013), and by the model’s Coulomb factor over its static limit. In a static field it is instantaneous_rate() at the magnitude (TC-820).

Parameters:
field_strengtharray_like

Magnitude of the turning field, V/m.

Returns:
numpy.ndarray

Rate per atom, 1/s, with the shape of field_strength; 0 at zero field.

Warns:
ModelRangeWarning

If a field exceeds maximum_field.

Examples

Argon at 800 nm, 2e14 W/cm^2 in circular polarisation, over the static rate at the same magnitude of the field:

>>> model = ionisation_rate_model("Ar", 800e-9)
>>> static = ionisation_rate_model("Ar", float("inf"))
>>> field = (2e18 / (8.8541878128e-12 * 299792458.0)) ** 0.5
>>> ratio = model.circular_rate(field) / static.instantaneous_rate(field)
>>> f"{float(ratio):.2f}"
'2.85'
property citation: str#

The references of the model as it is set.

Returns:
str

One line naming the papers of each factor.

coulomb: str#
cycle_averaged_rate(amplitude)[source]#

Return the rate averaged over a cycle of a field of constant amplitude.

Parameters:
amplitudearray_like

Amplitude of the field, V/m, \((2I/\varepsilon_0 c)^{1/2}\) for an intensity \(I\); its sign is ignored.

Returns:
numpy.ndarray

Rate per atom, 1/s, with the shape of amplitude; 0 at zero field.

Warns:
ModelRangeWarning

If a field exceeds maximum_field.

Examples

Helium at 800 nm and 1e15 W/cm2:

>>> model = ionisation_rate_model("He", 800e-9)
>>> f"{float(model.cycle_averaged_rate(8.68e10)):.3e}"
'1.568e+13'
electrons: float#
property energy_kind: str#

The kind of the ionisation energies the exponent uses.

Returns:
str

adiabatic or vertical as the curated dataset states it (the two coincide for an atom); not stated for a custom species or an overridden energy.

energy_loss_rate(field_strength)[source]#

Return the energy the ionisation takes from the field, per atom and second.

L = sum_c I_c Gamma_c, the quantity a consumer averages over a cycle beside the rate (OEP 1, section 4.6). For a linearly polarised field.

Parameters:
field_strengtharray_like

The field, V/m; its sign is ignored.

Returns:
numpy.ndarray

The energy-loss rate, W per atom, the shape of the field; 0 at zero field.

Warns:
ModelRangeWarning

If a field exceeds maximum_field.

energy_per_event(field_strength)[source]#

Return the mean ionisation energy of an event, L / Gamma.

The rate-weighted mean of the channels’ energies, from the logarithms of their terms, so that it is defined where the rates underflow: the lowest channel’s energy at zero field. For a linearly polarised field.

Parameters:
field_strengtharray_like

The field, V/m; its sign is ignored.

Returns:
numpy.ndarray

The energy, J, the shape of the field.

Warns:
ModelRangeWarning

If a field exceeds maximum_field.

Examples

>>> from optmat.constants import E_CHARGE
>>> argon = ionisation_rate_model("Ar", 800e-9)
>>> [f"{e / E_CHARGE:.3f}" for e in argon.energy_per_event([5e9, 5e10])]
['15.798', '15.814']
classmethod from_parameters(species, wavelength, *, ionization_energy, orbital_l, electrons, structure='hartree', structure_coefficient=None, coulomb='static', static_correction='tong-lin', static_constants=(), channels=None, channel_sum='integral', averaging='consistent', uncertainty_factor=nan, citation='', model='user', sources=None, reasons=None)[source]#

Return a rate model from explicit parameters, checked as a curated one is.

The curated models are built through it (ionisation_rate_model()).

Parameters:
speciesGas or str

A curated gas, or a custom species’ name, the identity’s material.

wavelengthfloat

Vacuum wavelength of the field, m; math.inf for a static field.

ionization_energyfloat

The lowest channel’s ionisation energy, J. Given channels are moved to it, keeping their splittings.

orbital_lint

The ionising orbital’s l.

electronsfloat

The effective number of electrons.

structurestr, optional

hartree (the default) or tong_2002, with structure_coefficient.

structure_coefficientfloat or None, optional

Tong et al.’s C_l.

coulombstr, optional

The Coulomb factor, static by default.

static_correctionstr, optional

tong-lin (the default, with its alpha), zhang or none.

static_constantstuple of float, optional

The correction’s constants.

channelstuple of Channel or None, optional

The ion’s levels and weights; one ground channel by default.

channel_sumstr, optional

integral or sum.

averagingstr, optional

consistent or tunnelling.

uncertainty_factorfloat, optional

A stated uncertainty factor; NaN (none) by default.

citationstr, optional

Where the parameters come from.

modelstr, optional

The model’s name, "user" by default.

sourcesMapping or None, optional

The source of each constant.

reasonsMapping or None, optional

Why each choice was made.

Returns:
IonisationRateModel

The model, status user.

Raises:
ValueError

As the model’s checks do.

Examples

>>> from optmat.constants import E_CHARGE
>>> model = IonisationRateModel.from_parameters(
...     "Ar*", 800e-9, ionization_energy=15.76 * E_CHARGE, orbital_l=1,
...     electrons=2.0, static_constants=(9.0,), citation="a test")
>>> model.identity.material, model.identity.status
('Ar*', 'user')
gas: Gas | str#
instantaneous_rate(field_strength)[source]#

Return the rate at the instantaneous value of a carrier-resolved field.

The cycle-averaged rate at an amplitude equal to the instantaneous field, divided by the average over a cycle that turned the rate into it: with the default averaging = "consistent", the model’s own average (the average over a cycle, by quadrature, of its rate as a function of the field; TC-828); with averaging = "tunnelling", cycle_average_factor() (TC-733). The Keldysh parameter is that of the instantaneous field.

Parameters:
field_strengtharray_like

The field, V/m; its sign is ignored.

Returns:
numpy.ndarray

Rate per atom, 1/s, with the shape of field_strength; 0 at zero field.

Warns:
ModelRangeWarning

If a field exceeds maximum_field.

Examples

>>> model = ionisation_rate_model("He", 800e-9)
>>> f"{float(model.instantaneous_rate(8.68e10)):.3e}"
'5.968e+13'
keldysh(field_strength)[source]#

Return the Keldysh parameter of the lowest channel.

Parameters:
field_strengtharray_like

Field amplitude, V/m; its sign is ignored.

Returns:
numpy.ndarray

\(\gamma\), with the shape of field_strength; inf at zero field.

Examples

>>> model = ionisation_rate_model("Ar", 800e-9)
>>> f"{float(model.keldysh(2.744e10)):.3f}"
'1.149'
property maximum_field: float#

The largest field at which the static correction was fitted.

Returns:
float

V/m: twice the barrier-suppression field for Tong and Lin’s factor, 4.5 times for Zhang et al.’s, and the barrier-suppression field itself without a correction.

model: str#
property omega_au: float#

The angular frequency of the field in atomic units.

Returns:
float

2 pi c / wavelength over the atomic unit of angular frequency; 0 for a static field.

orbital_l: int#
reasons: Mapping[str, str]#
sources: Mapping[str, str]#
static_constants: tuple[float, ...]#
static_correction: str#
structure: str#
structure_coefficient: float | None#
uncertainty_factor: float#
wavelength: float#
property wavelength_range: tuple[float, float]#

The wavelengths over which the model was compared with references.

Returns:
tuple of (float, float)

The shortest and the longest wavelength, m (the longest is a static field).

optmat.gas.ionisation_rates.StaticCorrection#

The correction of the one-electron static rate at finite field.

alias of Literal[‘tong-lin’, ‘zhang’, ‘none’]

optmat.gas.ionisation_rates.Structure#

Where the asymptotic coefficient of the orbital comes from.

alias of Literal[‘tong_2002’, ‘hartree’]

optmat.gas.ionisation_rates.channel_factor(m, gamma, threshold=None, *, tolerance=1e-06)[source]#

Return \(A_m(\omega, \gamma)\), the factor of the above-threshold channels.

Perelomov et al. (1966), eq. (55):

\[A_m(\omega, \gamma) = \frac{4}{\sqrt{3\pi}} \frac{1}{|m|!} \frac{\gamma^2}{1 + \gamma^2} \sum_{n \ge \nu} e^{-\alpha (n - \nu)}\, w_m\!\left(\sqrt{\beta (n - \nu)} \right), \qquad \nu = \frac{I_p}{\omega} \left(1 + \frac{1}{2\gamma^2}\right),\]

which tends to 1 for \(\gamma \to 0\). With threshold (\(\nu\)) the sum is taken term by term. It then has a step wherever \(\nu\) passes an integer (a channel closes as the ponderomotive energy grows). Without it the sum is replaced by its integral over the number of photons, which is smooth:

\[\int_0^\infty e^{-\alpha x}\, w_m(\sqrt{\beta x})\, dx = \frac{\sqrt\pi}{2}\, |m|!\, \frac{\beta^{|m|}}{(\alpha + \beta)^{|m| + 1}} \sqrt{\frac{\beta}{\alpha}}.\]

The integral is within 10 % of the sum for \(\gamma < 1.5\) and within 50 % up to \(\gamma = 3\) (TC-654).

Parameters:
mint

Magnetic quantum number.

gammanumpy.ndarray

Keldysh parameter, > 0.

thresholdnumpy.ndarray or None, optional

\(\nu\), the threshold in photons, with the shape of gamma: take the sum. None: take the integral.

tolerancefloat, optional

Relative bound on the truncated remainder of the sum.

Returns:
numpy.ndarray

\(A_m\), with the shape of gamma.

Examples

The tunnelling limit of the integral:

>>> import numpy as np
>>> f"{float(channel_factor(0, np.array(1e-3))):.4f}"
'1.0000'
optmat.gas.ionisation_rates.channel_function(m, x)[source]#

Return \(w_m(x)\), the weight of one above-threshold channel.

Perelomov et al. (1966), eq. (56):

\[w_m(x) = e^{-x^2} \int_0^x e^{y^2} (x^2 - y^2)^{|m|}\, dy.\]

For \(m = 0\) it is Dawson’s integral. For any \(m\) the integral is \(\tfrac{\sqrt\pi}{2} \tfrac{|m|!}{\Gamma(|m| + 3/2)} x^{2|m|+1} \,{}_1F_1(\tfrac12; |m| + \tfrac32; x^2)\), and Kummer’s transformation, \(e^{-z}\,{}_1F_1(a; b; z) = {}_1F_1(b - a; b; -z)\), removes the exponential, so that nothing overflows at large \(x\).

Parameters:
mint

Magnetic quantum number; only \(|m|\) enters.

xnumpy.ndarray

Argument, >= 0.

Returns:
numpy.ndarray

\(w_m(x)\), which rises as \(x^{2|m|+1}\) and falls as \(|m|!/(2x)\).

Examples

>>> import numpy as np
>>> f"{float(channel_function(0, np.array(1.0))):.6f}"
'0.538080'
optmat.gas.ionisation_rates.circular_enhancement(field_au, omega_au, ionization_energy_au, l)[source]#

Return the rate of a shell in a circular field over its adiabatic limit.

The short-range rate of Barth & Smirnova (2013, eqs. 100 to 105), summed over the shell’s orbitals, at the frequency over the same at zero frequency and the same magnitude of the field: the factor by which the field’s turning raises the rate above the static rate at its magnitude. It tends to 1 for \(\gamma \to 0\) (TC-820).

Parameters:
field_auarray_like

Magnitude of the turning field, atomic units, > 0.

omega_aufloat

Angular frequency, atomic units.

ionization_energy_aufloat

Ionisation energy, hartree.

lint

0 (s) or 1 (p).

Returns:
numpy.ndarray

The factor, with the shape of field_au.

Examples

Argon at 800 nm and 2e14 W/cm^2 (a turning field of 0.0534 au):

>>> f"{float(circular_enhancement(0.0534, 0.05695, 0.5792, 1)):.3f}"
'3.709'
optmat.gas.ionisation_rates.circular_saddle_point(gamma)[source]#

Return the saddle point \(\zeta_0(\gamma)\) of a circularly polarised field.

The root in \((0, 1)\) of Barth & Smirnova’s (2013) eq. (94),

\[\operatorname{artanh} u = \frac{u}{1 - \zeta_0}, \qquad u = \sqrt{\frac{\zeta_0^2 + \gamma^2}{1 + \gamma^2}},\]

found by bisection; \(\zeta_0 \approx \gamma^2/3\) for \(\gamma \ll 1\) (their Appendix F). It fixes the photon number of the most probable n-photon process, \(2 n_0/(1 + \zeta_0)\).

Parameters:
gammaarray_like

Keldysh parameter, > 0.

Returns:
numpy.ndarray

\(\zeta_0\), with the shape of gamma.

Examples

>>> f"{float(circular_saddle_point(0.05)) / (0.05**2 / 3):.4f}"
'0.9984'
optmat.gas.ionisation_rates.coulomb_factor(field_au, omega_au, ionization_energy_au, form='static', charge=1.0)[source]#

Return the factor by which the Coulomb field of the ion raises the rate.

Three forms are in the literature (TC-653), and a fourth is optmat’s fit:

static

\(Q = (2F_0/F)^{2n^*}\): Perelomov and Popov (1967), eq. (42), for linear polarisation, of which they write that “the dependence … on the frequency has dropped out”; Perelomov, Popov and Kuznetsov (1968), eqs. (1) and (11), that it “does not depend on \(\gamma\) at all”. It holds while the Coulomb field does not distort the path of the electron under the barrier, \(\gamma \ll \gamma_k = 2I_p/n^*\omega\) (their eq. 20; 22 for argon and 43 for helium at 800 nm), and more exactly while \(n^*\omega/2I_p\) is below a critical value that falls with \(\gamma\) (their Table I; TC-670). It was the default until TC-848. Against time-dependent Schrödinger calculations of one electron it is the closest of the three below a Keldysh parameter of about 1 but too high above it, by 1.1 to 1.7 for argon at 800 nm, 1.4 to 3.9 at 400 nm, 1.75 to 2.2 for krypton and xenon at 800 nm and, with Tong and Lin’s static correction, 1.1 to 1.5 for hydrogen at 1200 to 600 nm (TC-812, TC-824, TC-825, TC-827); for the helium atom it agrees with Parker et al. (2007) at 780 nm.

ilkov

\(Q\,(1 + \gamma^2)^{-n^*}\): the form of Ilkov et al. (1992), eq. (8), and Bergé et al. (2007), eq. (B14), in which the field of the Coulomb factor is multiplied by \(\sqrt{1 + \gamma^2}\) together with that of the short-range rate. No paper derives it.

popruzhenko

\(Q\,(1 + 2\gamma/e)^{-2n^*}\): Popruzhenko et al. (2008), eq. (5), derived for any \(\gamma\). Against the one-electron calculations it is too low above \(\gamma \approx 1\), by 2 to 4.

frequency

\(Q\,(1 + 2\gamma/e)^{-2n^* c s}\) with \(s = n^*\omega/2I_p\), the parameter of the static factor’s range of validity (Perelomov, Popov and Kuznetsov 1968), and \(c = 5.25\) fitted to one-electron calculations of argon at 400, 800 and 1030 nm: an empirical form, not a derived one. Every first-order Coulomb correction of the theory depends on \(\gamma\) alone; the calculations’ excess over the static factor also grows with the frequency at fixed \(\gamma\), as a term of order \(s\) would. It tends to the static factor as \(\omega \to 0\) (TC-831). It is the default (TC-848).

Parameters:
field_aunumpy.ndarray

Field amplitude, atomic units, > 0.

omega_aufloat

Angular frequency, atomic units, >= 0.

ionization_energy_aufloat

Ionisation energy, hartree, > 0.

form{“static”, “ilkov”, “popruzhenko”, “frequency”}, optional

The form.

chargefloat, optional

Charge \(Z\) of the ion left behind.

Returns:
numpy.ndarray

The factor, with the shape of field_au.

Raises:
ValueError

If the form is not one of the four.

Examples

At \(\gamma = 1\) the other two forms are below the static one:

>>> import numpy as np
>>> field, omega, energy = np.array(0.05), 0.05, 0.5
>>> static = coulomb_factor(field, omega, energy)
>>> f"{float(coulomb_factor(field, omega, energy, 'ilkov') / static):.4f}"
'0.5000'
>>> f"{float(coulomb_factor(field, omega, energy, 'popruzhenko') / static):.4f}"
'0.3319'
>>> f"{float(coulomb_factor(field, omega, energy, 'frequency') / static):.4f}"
'0.7486'
optmat.gas.ionisation_rates.cycle_average(slope, curvature)[source]#

Return the average over a cycle of a rate, over the rate at the amplitude.

With \(L(\ln F) = \ln W\), its slope \(s = L'\) and its curvature \(q = L''\), and \(u = \ln|\cos\varphi|\),

\[\frac{\overline{W}}{W(F)} = \frac{2}{\pi} \int_0^{\pi/2} e^{s u + q u^2/2 + \dots}\, d\varphi \approx c(s) \left[1 + \frac{q}{2}\, \frac{c''(s)}{c(s)}\right],\]

with \(c\) of power_law_average(), whose derivatives with respect to \(s\) are the moments of \(u\). For the tunnelling rate \(q = -s\) and the bracket is \(1 - 3/8s\). The average of the default model’s instantaneous rate over a cycle is its cycle-averaged rate to 1 % up to the barrier-suppression field (TC-662). The models no longer use it: where the rate bends sharply the expansion fails, 24 % low for argon’s average at twice the barrier-suppression field, and they average by quadrature instead (TC-828).

Parameters:
slopenumpy.ndarray

\(d\ln W/d\ln F\), > 0.

curvaturenumpy.ndarray

\(d^2\ln W/d(\ln F)^2\).

Returns:
numpy.ndarray

The ratio, in (0, 1].

Examples

A power law has no curvature:

>>> import numpy as np
>>> f"{float(cycle_average(np.array(2.0), np.array(0.0))):.4f}"
'0.5000'
optmat.gas.ionisation_rates.cycle_average_factor(field_au, ionization_energy_au)[source]#

Return \((3F/\pi F_0)^{1/2}\), the cycle average in the tunnelling limit.

Perelomov et al. (1966), eq. (7): for \(\omega \ll \omega_t\) the rate in a field of amplitude \(F\) is the static rate at \(F\) times this factor, the average of \(w_\text{stat}(F |\cos\omega t|)\) over a cycle.

Parameters:
field_aunumpy.ndarray

Field amplitude, atomic units, > 0.

ionization_energy_aufloat

Ionisation energy, hartree, > 0.

Returns:
numpy.ndarray

The factor, with the shape of field_au.

Examples

>>> import numpy as np
>>> f"{float(cycle_average_factor(np.array(0.05), 0.5)):.6f}"
'0.218510'
optmat.gas.ionisation_rates.ionisation_rate_coverage()[source]#

Return the gases each atomic rate model covers, building none of them.

Returns:
dict of str to tuple of Gas

Each model of ionisation_rate_models() and its gases, in file order, read from ionisation_rates.toml alone; the default model’s are the atoms optmat gives an ionisation rate for.

Examples

>>> [gas.value for gas in ionisation_rate_coverage()["default"]]
['He', 'Ne', 'Ar', 'Kr', 'Xe']
optmat.gas.ionisation_rates.ionisation_rate_model(gas, wavelength, model='default')[source]#

Return the ionisation rate of a gas at a wavelength.

Parameters:
gasGas or str

The gas: He, Ne, Ar, Kr or Xe.

wavelengthfloat

Vacuum wavelength of the field, m; math.inf for a static field.

modelstr, optional

A model of data/gas/ionisation_rates.toml. default is the validated one; the others reproduce forms of the literature, for comparison.

Returns:
IonisationRateModel

The model.

Raises:
DataError

If the model does not exist or does not cover the gas.

Warns:
ModelRangeWarning

If the wavelength is below the range over which the rates were compared.

Examples

The static rate of helium at 0.1 au, in atomic units (Parker et al.’s two-electron calculation gives 2.94e-6):

>>> import math
>>> from optmat.constants import AU_ANGULAR_FREQUENCY, AU_FIELD
>>> model = ionisation_rate_model("He", math.inf)
>>> rate = model.instantaneous_rate(0.1 * AU_FIELD) / AU_ANGULAR_FREQUENCY
>>> f"{float(rate):.2e}"
'2.79e-06'
optmat.gas.ionisation_rates.ionisation_rate_models()[source]#

Return every named model of every gas it covers, at 800 nm.

Returns:
dict of str to dict of Gas to IonisationRateModel

The models by name and gas; IonisationRateModel.at_wavelength() moves one to another wavelength.

optmat.gas.ionisation_rates.keldysh_parameter(field_au, omega_au, ionization_energy_au)[source]#

Return the Keldysh parameter \(\gamma = \omega\kappa / F\).

Perelomov et al. (1966), after eq. (1): the ratio of the field’s frequency to the frequency of tunnelling, \(\omega_t = F/\kappa\).

Parameters:
field_aunumpy.ndarray

Field amplitude, atomic units, > 0.

omega_aufloat

Angular frequency of the field, atomic units, >= 0.

ionization_energy_aufloat

Ionisation energy, hartree, > 0.

Returns:
numpy.ndarray

\(\gamma\), with the shape of field_au.

Examples

Argon at 800 nm and 1e14 W/cm2 (0.05338 au):

>>> import numpy as np
>>> gamma = keldysh_parameter(np.array(0.05338), 0.056954, 0.57916)
>>> f"{float(gamma):.3f}"
'1.148'
optmat.gas.ionisation_rates.power_law_average(slope)[source]#

Return the average over a cycle of a rate that goes as a power of the field.

For \(W \propto F^s\), the average of \(W(F|\cos\omega t|)\) over a cycle is \(c(s)\, W(F)\) with

\[c(s) = \frac{2}{\pi} \int_0^{\pi/2} \cos^s\varphi\, d\varphi = \frac{\Gamma\!\left(\frac{s + 1}{2}\right)} {\sqrt\pi\, \Gamma\!\left(\frac{s}{2} + 1\right)} \approx \sqrt{\frac{2}{\pi s}} .\]

A rate that is steep in the field is a power law over the part of the cycle that contributes, with the local slope \(s = d\ln W/d\ln F\); for the tunnelling rate \(s \to 2F_0/3F\) and \(c \to (3F/\pi F_0)^{1/2}\), Perelomov et al.’s (1966) eq. (7). cycle_average() adds the curvature.

Parameters:
slopenumpy.ndarray

Logarithmic slope of the rate, > -1.

Returns:
numpy.ndarray

\(c(s)\), in (0, 1].

Examples

>>> import numpy as np
>>> f"{float(power_law_average(np.array(2.0))):.4f}"
'0.5000'
optmat.gas.ionisation_rates.ppt_exponent_function(gamma)[source]#

Return \(g(\gamma)\) of the exponent of the rate.

Perelomov et al. (1966), eq. (33):

\[g(\gamma) = \frac{3}{2\gamma} \left[ \left(1 + \frac{1}{2\gamma^2}\right) \operatorname{arsinh}\gamma - \frac{\sqrt{1 + \gamma^2}}{2\gamma} \right],\]

so that the rate is proportional to \(\exp[-(2F_0/3F)\, g(\gamma)]\). It is 1 in the tunnelling limit, where it has the series \(1 - \gamma^2/10 + 9\gamma^4/280\) (their eq. 59 gives the first two terms).

Parameters:
gammanumpy.ndarray

Keldysh parameter, >= 0.

Returns:
numpy.ndarray

\(g(\gamma)\), in (0, 1].

Examples

>>> import numpy as np
>>> f"{float(ppt_exponent_function(np.array(1.0))):.6f}"
'0.922430'
optmat.gas.ionisation_rates.short_range_rate_au(field_au, omega_au, ionization_energy_au, coefficient_squared, l, m=0, *, channel_sum='integral')[source]#

Return the cycle-averaged rate of one electron in a short-range potential.

Perelomov et al. (1966), eq. (54):

\[w_{lm}(F, \omega) = I_p\, |C_{\kappa l}|^2 \sqrt{\frac{6}{\pi}}\, f(l, m) \left(\frac{F \sqrt{1 + \gamma^2}}{2F_0}\right)^{|m| + 3/2} A_m(\omega, \gamma)\, \exp\left[-\frac{2F_0}{3F}\, g(\gamma)\right].\]

Ilkov et al. (1992) print the prefactor of their eq. (8) as \((3/2\pi)^{1/2}\), which is half of this and does not reduce to their own eq. (2) (TC-656); Larochelle et al.’s eq. (10) and Bergé et al.’s (B14) agree with Perelomov et al.

Parameters:
field_aunumpy.ndarray

Field amplitude, atomic units, > 0.

omega_aufloat

Angular frequency, atomic units, > 0.

ionization_energy_aufloat

Ionisation energy, hartree, > 0.

coefficient_squaredfloat

\(|C_{\kappa l}|^2\).

lint

Orbital angular momentum of the electron.

mint, optional

Its magnetic quantum number along the field.

channel_sum{“integral”, “sum”}, optional

How channel_factor() takes the sum over channels.

Returns:
numpy.ndarray

Rate, atomic units, with the shape of field_au.

Examples

In the tunnelling limit it is the cycle average of the static rate without its Coulomb factor \((2F_0/F)^{2n^*}\); for hydrogen at \(\gamma = 0.002\):

>>> import numpy as np
>>> field = np.array(0.05)
>>> short = short_range_rate_au(field, 1e-4, 0.5, 4.0, 0)
>>> static = tunnelling_rate_au(field, 0.5, 4.0, 0) / (2 / 0.05) ** 2
>>> f"{float(short / (static * cycle_average_factor(field, 0.5))):.4f}"
'1.0000'
optmat.gas.ionisation_rates.tong_lin_factor(field_au, ionization_energy_au, alpha, charge=1.0)[source]#

Return Tong and Lin’s correction of the tunnelling rate at finite field.

Tong and Lin (2005), eq. (2):

\[S(F) = \exp\left(-\alpha\, \frac{Z^2}{I_p}\, \frac{F}{\kappa^3}\right),\]

with \(\alpha\) fitted to exact static rates of one electron in a model potential (their Table 2: 7 for He, 9 for Ne and Ar), relative to the tunnelling rate with Tong et al.’s (2002) coefficient \(C_l\) and \(m = 0\). With \(\alpha = 9\) it reproduces Zhang et al.’s (2014) exact rates of argon in Tong and Lin’s potential within 7 % up to 1.7 times the barrier-suppression field (TC-655). The name “barrier suppression” misleads: the factor is 0.5 for argon at 0.64 of that field, and is needed at every field.

Parameters:
field_aunumpy.ndarray

Field, atomic units, >= 0.

ionization_energy_aufloat

Ionisation energy, hartree, > 0.

alphafloat

Tong and Lin’s constant.

chargefloat, optional

Charge \(Z\) of the ion left behind.

Returns:
numpy.ndarray

The factor, in (0, 1].

Examples

Argon at 1e14 W/cm2:

>>> import numpy as np
>>> f"{float(tong_lin_factor(np.array(0.05338), 0.57916, 9.0)):.3f}"
'0.514'
optmat.gas.ionisation_rates.tunnelling_rate_au(field_au, ionization_energy_au, coefficient_squared, l, m=0, charge=1.0)[source]#

Return the static tunnelling rate of one electron, to leading order.

Perelomov et al. (1966), eq. (4):

\[w_\text{stat}(F) = I_p\, |C_{\kappa l}|^2\, f(l, m) \left(\frac{2F_0}{F}\right)^{2n^* - |m| - 1} \exp\left(-\frac{2F_0}{3F}\right),\]

with the orbital’s asymptotic form \(\psi \to C_{\kappa l}\, \kappa^{3/2} (\kappa r)^{n^* - 1} e^{-\kappa r}\, Y_{lm}\) (their eq. 6). Tong, Zhao and Lin’s (2002) eq. (7) is the same rate with their coefficient \(C_l = C_{\kappa l}\, \kappa^{n^* + 1/2}\). It is exact for \(F \to 0\) and too high at any field of practical interest: by 1.9 for argon at 0.64 of the barrier-suppression field (TC-655).

Parameters:
field_aunumpy.ndarray

Static field, atomic units, > 0.

ionization_energy_aufloat

Ionisation energy, hartree, > 0.

coefficient_squaredfloat

\(|C_{\kappa l}|^2\), in Perelomov et al.’s normalisation.

lint

Orbital angular momentum of the electron.

mint, optional

Its magnetic quantum number along the field.

chargefloat, optional

Charge \(Z\) of the ion left behind.

Returns:
numpy.ndarray

Rate, atomic units, with the shape of field_au.

Examples

Hydrogen (\(C = 2\)) gives \((4/F) e^{-2/3F}\):

>>> import numpy as np
>>> w = tunnelling_rate_au(np.array(0.05), 0.5, 4.0, 0)
>>> f"{float(w) / (4 / 0.05 * np.exp(-2 / 0.15)):.12f}"
'1.000000000000'
optmat.gas.ionisation_rates.zhang_factor(field_au, ionization_energy_au, coefficients, charge=1.0)[source]#

Return Zhang, Lan and Lu’s correction of the tunnelling rate.

Zhang et al. (2014), eq. (8), with the sign their own Table IX requires (the equation is printed with a minus sign before the polynomial; TC-509):

\[S(F) = \exp\left(a_1 x^2 + a_2 x + a_3\right), \qquad x = F / F_b, \quad F_b = \frac{I_p^2}{4 Z},\]

fitted for \(0.5 \le x \le 4.5\). The polynomial is positive at small \(x\) for every gas but neon, where a correction of a rate that is already exact must be 1; the factor is held at 1 there, which leaves a corner in the rate.

Parameters:
field_aunumpy.ndarray

Field, atomic units, >= 0.

ionization_energy_aufloat

Ionisation energy, hartree, > 0.

coefficientstuple of float

\(a_1, a_2, a_3\) (their Table XI).

chargefloat, optional

Charge \(Z\) of the ion left behind.

Returns:
numpy.ndarray

The factor, in (0, 1].

Examples

Argon at its barrier-suppression field:

>>> import numpy as np
>>> barrier = 0.57916**2 / 4
>>> coefficients = (0.16178, -1.50441, 0.32127)
>>> f"{float(zhang_factor(np.array(barrier), 0.57916, coefficients)):.3f}"
'0.360'