solprop.physdata.nonlinear_data#
Third-order nonlinear data for gases: the Kerr coefficient at the carrier.
The nonlinearity is held as a per-particle quantity, exactly as the linear
susceptibility is: gamma3() returns the third-order hyperpolarisability
\(\gamma^{(3)}\) in m5/V2, and
So the Kerr response of a gas is strictly linear in number density, and a pressure gradient scales it without re-deriving anything.
The nonlinear index follows from the susceptibility by
with \(n_0\) the linear index at the carrier. n2_from_chi3() and
chi3_from_n2() are that relation and its inverse, in the same convention as
docs/dev/conventions.md section 4: an intensity \(I\) shifts the index by
\(n_2 I\).
The coefficient is optmat’s (SEP 3, section 4.3): OptmatKerr adapts optmat’s
fitted electronic hyperpolarizability, which is dispersive, and evaluates its Kerr
process at the run’s carrier wavelength – one number per species and run, the
carrier-kerr approximation, never a universal constant. The Taylor convention of
the fit, \(p^{(3)} = \gamma_T E^3/6\), gives
\(\gamma^{(3)} = \gamma_T/(6\varepsilon_0)\), which optmat’s public
gamma3("kerr", wavelength) returns; optmat’s own gas n2, taken with
\(n_0 = 1\), is never imported, so that n2_from_chi3() applies the exact
\(n_0^2\). Air has no hyperpolarizability of its own: its populations each carry
theirs.
SEP 6’s dispersive electronic policies take the whole fit instead:
DispersiveKerrModel is optmat’s model of one gas in SI, with the per-leg bound
and the band edges solprop derives from optmat’s support record, and
ElectronicRegions classifies a run’s band against them (SEP 6, section 4.10).
Functions
|
Return whether two carrier wavelengths are the same, to rounding. |
|
Return the third-order susceptibility of a gas at a carrier. |
|
Convert a nonlinear index to a third-order susceptibility. |
|
Return a gas's per-particle Kerr coefficient at a carrier wavelength. |
|
Return the nonlinear index of a gas at a carrier. |
|
Convert a third-order susceptibility to a nonlinear index. |
|
Return the carrier a selection's Kerr coefficient is evaluated at. |
Classes
|
Record one gas's Kerr coefficient at the carrier, and what it leaves out. |
|
Hold one gas's dispersive hyperpolarizability in SI, with its leg bound. |
|
Classify a run's band against one gas's hyperpolarizability support. |
|
Take a gas's electronic Kerr coefficient from optmat, at the carrier. |
- class solprop.physdata.nonlinear_data.CarrierKerr(material, model, digest, carrier_wavelength, gamma3, gamma3_thg, thg_ratio, thg_reason='')[source]#
Bases:
objectRecord one gas’s Kerr coefficient at the carrier, and what it leaves out.
The
carrier-kerrapproximation (SEP 3, section 4.3) freezes the dispersive electronic response at one wavelength and uses it for every process the cubic term drives, the third harmonic included. optmat’s distinct third-harmonic coefficient measures what that costs: the record keeps both, and their ratio where optmat evaluates the third harmonic within its fitted data.- Attributes:
- materialstr
The gas.
- modelstr
optmat’s model name,
"hyperpolarizability/<gas>".- digeststr
Its digest.
- carrier_wavelengthfloat
The vacuum carrier wavelength in m.
- gamma3float
The Kerr coefficient there, m^5/V^2 per particle: what the run uses.
- gamma3_thgfloat
optmat’s third-harmonic coefficient at the same fundamental, m^5/V^2.
- thg_ratiofloat or None
gamma3_thg / gamma3;Nonewhere optmat’s third-harmonic evaluation leaves its fitted data, so that the ratio would only compare extrapolations.- thg_reasonstr
Empty for a reported ratio; otherwise optmat’s range warning.
- class solprop.physdata.nonlinear_data.DispersiveKerrModel(material, gamma3_static, a, b, b_prime, leg_bound, band_edge_linear, band_edge_any, material_records)[source]#
Bases:
objectHold one gas’s dispersive hyperpolarizability in SI, with its leg bound.
optmat’s fit of the Taylor-convention second hyperpolarizability over a quartet of signed vacuum wavenumbers \(\nu_j = \omega_j/(2\pi c)\), output first and counted negative, so that the four sum to zero (SEP 6, section 4.5):
\[\gamma^{(3)} = \gamma^{(3)}_0\,[1 + a S_2 + b S_2^2 + b' S_4], \qquad S_2 = \sum_j \nu_j^2,\ S_4 = \sum_j \nu_j^4,\]with \(\gamma^{(3)}_0 = \gamma_{0,\rm au}\,\mathrm{au}/(6\varepsilon_0)\) solprop’s per-particle coefficient in m^5/V^2 (section 4.2), and optmat’s
Ain 1e-10 cm^2 andB,B'in 1e-20 cm^4 taken to m^2 and m^4. Every leg enters through its bounded weight \(\tilde d(\nu) = \min(\nu^2, \nu_c^2)\), the rule of section 4.10, which changes no quartet within the fitted sums.The leg bound and the band edges are derived from optmat’s support record of the model (optmat’s OEP 5): \(\nu_c = \sqrt{3 W_{2,\max}/4}\) (
support.leg_max_in_w2) and \(\min(E_1, E_2/2)\) for one or for any polarisation (support.band_edge). solprop hard-codes none of them.- Attributes:
- materialstr
The gas.
- gamma3_staticfloat
\(\gamma^{(3)}_0\), the static per-particle coefficient, m^5/V^2.
- afloat
The quadratic coefficient, m^2.
- bfloat
The coefficient of \(S_2^2\), m^4.
- b_primefloat
The coefficient of \(S_4\), m^4.
- leg_boundfloat
\(\nu_c\), m^-1, positive.
- band_edge_linearfloat or None
The band edge for one linear polarisation, m^-1;
Nonewhere optmat’s record leaves it undefined (CO2, CH4, SF6, N2O and O3 at optmat 0.4).- band_edge_anyfloat or None
The band edge for any polarisation, m^-1, or
None.- material_recordstuple of MaterialRecord
The records of optmat’s hyperpolarizability model and of its support record, in that order.
- Raises:
- MaterialError
If a coefficient is not finite, the static coefficient or the leg bound is not positive, or the Kerr diagonal is not positive up to the leg bound, where its fourth root would not be real.
Examples
>>> from solprop.physdata.nonlinear_data import OptmatKerr >>> argon = OptmatKerr("Ar").dispersive_model() >>> round(1e9 / argon.leg_bound, 1), round(1e9 / argon.band_edge(vector=False), 1) (215.9, 189.4)
- band_edge(*, vector)[source]#
Return the band edge a run takes, m^-1.
- Parameters:
- vectorbool
Whether the run carries two polarisation components, which takes the any-polarisation edge.
- Returns:
- float or None
The edge, or
Nonewhere it is undefined.
- classmethod from_optmat(model)[source]#
Build the SI model of an optmat hyperpolarizability model.
- Parameters:
- modeloptmat.gas.nonlinear.HyperpolarizabilityModel
Any gas’s model, one solprop builds as a species or not.
- Returns:
- DispersiveKerrModel
The model in SI with its leg bound and band edges.
- Raises:
- MaterialError
If the model carries no four dispersion parameters or no support record, or its support record describes another model.
- gamma3(legs)[source]#
Return the bounded per-particle coefficient of quartets, m^5/V^2.
- Parameters:
- legsnumpy.ndarray
Signed vacuum wavenumbers in m^-1, the last axis the quartet’s four legs; only their squares enter.
- Returns:
- numpy.ndarray
\(\gamma^{(3)}_0[1 + a S_2 + b S_2^2 + b' S_4]\) with every leg’s square bounded at \(\nu_c^2\).
- kerr_ratio(weight)[source]#
Return the Kerr diagonal over its static value at a leg weight.
- Parameters:
- weightnumpy.ndarray
Leg weights \(\tilde d = \nu^2\), m^-2, any shape.
- Returns:
- numpy.ndarray
\(1 + 4 a \tilde d + (16 b + 4 b')\tilde d^2\), the diagonal \(S_2 = 4\tilde d\), \(S_4 = 4\tilde d^2\).
- leg_weight(omega)[source]#
Return the bounded leg weight at angular frequencies, m^-2.
- Parameters:
- omeganumpy.ndarray
Angular frequencies in rad/s, of either sign, any shape.
- Returns:
- numpy.ndarray
\(\min((\omega/2\pi c)^2, \nu_c^2)\).
- material_records: tuple[MaterialRecord, ...]#
- property model_digest: str[source]#
Return the digest of optmat’s hyperpolarizability model.
- Returns:
- str
Sixty-four hexadecimal digits.
- regions(omega_low, omega_high, *, vector)[source]#
Classify a band of angular frequencies (SEP 6, section 4.10).
- Parameters:
- omega_lowfloat
The lowest angular frequency of the band in rad/s, positive.
- omega_highfloat
The highest, in rad/s, above omega_low.
- vectorbool
Whether the run carries two polarisation components, which takes the any-polarisation band edge.
- Returns:
- ElectronicRegions
The supported, bounded and best-effort parts of the band.
- Raises:
- MaterialError
If the band is not a positive, finite, increasing pair.
Examples
>>> import math >>> from solprop.constants import C >>> from solprop.physdata.nonlinear_data import OptmatKerr >>> helium = OptmatKerr("He").dispersive_model() >>> omega = [2 * math.pi * C / wavelength for wavelength in (4e-6, 90e-9)] >>> regions = helium.regions(*omega, vector=False) >>> [round(x * 1e9, 1) for x in regions.bounded] [120.3, 151.9] >>> regions.best_effort is not None True
- class solprop.physdata.nonlinear_data.ElectronicRegions(material, polarisation, band, leg_bound, band_edge, supported, bounded, best_effort)[source]#
Bases:
objectClassify a run’s band against one gas’s hyperpolarizability support.
SEP 6, section 4.10, as qualified by its Phase 0 report. Every leg of a dispersive evaluator is held at the gas’s leg bound \(\nu_c\), and the run is never refused for the frequencies its field occupies; what is recorded is which part of the band falls in which region:
supported: every leg within \(\nu_c\) and inside the band edge, where the bound changes no quartet within the fitted sums;
bounded: beyond \(\nu_c\) and inside the band edge, where the legs are held at the bound – a bounded estimate, which can underestimate a response that rises below resonance but is not a certified bound on it;
best effort: beyond the band edge, or beyond \(\nu_c\) for a gas whose edge is undefined (no curated two-photon limit), where no off-resonant model is valid and the response is held at its value at the edge of the data.
Each region is one interval of vacuum wavelength, since the classification is monotonic in frequency.
- Attributes:
- materialstr
The gas.
- polarisation{‘linear’, ‘any’}
Which band edge applied: one linear polarisation, or any (a vector run).
- bandtuple of float
The classified band, shortest and longest vacuum wavelength in m.
- leg_boundfloat
\(\nu_c\), m^-1.
- band_edgefloat or None
The band edge that applied, m^-1;
Nonewhere optmat’s record leaves it undefined.- supportedtuple of float or None
Shortest and longest wavelength in m of the supported part, or
None.- boundedtuple of float or None
The same of the bounded part.
- best_efforttuple of float or None
The same of the best-effort part.
- property beyond_support: bool[source]#
Return whether any part of the band is bounded or best effort.
- Returns:
- bool
True when a run’s legs reach beyond the gas’s leg bound or band edge.
- class solprop.physdata.nonlinear_data.OptmatKerr(gas)[source]#
Bases:
objectTake a gas’s electronic Kerr coefficient from optmat, at the carrier.
optmat fits each gas’s second hyperpolarizability \(\gamma_T(\omega)\) in the Taylor convention, \(p^{(3)} = \gamma_T E^3/6\), so that solprop’s per-particle coefficient in \(P^{(3)} = \varepsilon_0\gamma^{(3)}N E^3\) is
\[\gamma^{(3)}(\lambda_c) = \frac{\gamma_{T,\rm Kerr}(\lambda_c)} {6\varepsilon_0},\]evaluated at the carrier \(\lambda_c\) (optmat’s public
gamma3("kerr", wavelength)). The adapter holds the model, not a number: the carrier is the run’s, so one species serves runs at any carrier. No Raman amplitude is multiplied by it, and no local-field factor is added (SEP 3, section 4.3).- Attributes:
- gasGas or str
The species; optmat has a model for every built-in gas but air, whose populations each carry their own.
- Raises:
- MaterialError
If optmat has no hyperpolarizability model of the gas.
Examples
>>> from solprop.physdata.nonlinear_data import OptmatKerr >>> argon = OptmatKerr("Ar") >>> f"{argon.gamma3(800e-9):.6e}" '1.476195e-51'
- at_carrier(wavelength)[source]#
Return the carrier record: the coefficient used and the THG discrepancy.
- Parameters:
- wavelengthfloat
Vacuum carrier wavelength in m, positive and finite.
- Returns:
- CarrierKerr
The Kerr coefficient at the carrier, optmat’s third-harmonic one at the same fundamental, and their ratio where the latter is within optmat’s fitted data.
- Raises:
- MaterialError
If the wavelength is not positive and finite.
Examples
>>> from solprop.physdata.nonlinear_data import OptmatKerr >>> record = OptmatKerr("Ar").at_carrier(800e-9) >>> f"{record.thg_ratio:.3f}" '1.177'
- dispersive_model()[source]#
Return the whole fit in SI, for a dispersive electronic policy (SEP 6).
- Returns:
- DispersiveKerrModel
The gas’s optmat model in SI, with its leg bound and band edges.
- Raises:
- MaterialError
If optmat’s model of the gas carries no dispersion parameters or support record.
- Warns:
- MaterialStatusWarning
Once per evaluation context, for a provisional or untested model or support record.
Examples
>>> from solprop.physdata.nonlinear_data import OptmatKerr >>> f"{OptmatKerr('He').dispersive_model().gamma3_static:.6e}" '5.064575e-53'
- gamma3(wavelength)[source]#
Return the per-particle Kerr coefficient at a carrier wavelength.
- Parameters:
- wavelengthfloat
Vacuum carrier wavelength in m, positive and finite.
- Returns:
- float
gamma3in m^5/V^2, such thatchi3 = gamma3 * rho.
- Raises:
- MaterialError
If the wavelength is not positive and finite.
- Warns:
- MaterialRangeWarning
Once per evaluation context, outside the model’s fitted wavelengths (400 nm to 20 um for the built-in gases).
- property material_records: tuple[MaterialRecord, ...][source]#
Return the record of the hyperpolarizability model.
- Returns:
- tuple of MaterialRecord
One record.
- solprop.physdata.nonlinear_data.carriers_agree(first, second)[source]#
Return whether two carrier wavelengths are the same, to rounding.
- Parameters:
- firstfloat
A vacuum wavelength in m.
- secondfloat
Another, in m.
- Returns:
- bool
True when they differ by at most 1e-12 relative: a wavelength computed back from an angular frequency is the same carrier.
Examples
>>> from solprop.physdata.nonlinear_data import carriers_agree >>> carriers_agree(800e-9, 800e-9 * (1 + 1e-15)), carriers_agree(800e-9, 1030e-9) (True, False)
- solprop.physdata.nonlinear_data.chi3(gas, *, pressure, temperature=293.15, selection=None, wavelength=None)[source]#
Return the third-order susceptibility of a gas at a carrier.
chi3 = gamma3 * rho: strictly linear in number density, with optmat’s Kerr coefficient at the carrier (OptmatKerr) and optmat’s equation of state.- Parameters:
- gasGas or str
The species.
- pressurefloat
Absolute pressure in bar (the documented non-SI user-interface unit), >= 0.
- temperaturefloat, optional
Temperature in K, > 0. Defaults to 293.15 K.
- selectionMaterialSelection or None, optional
NoneisMaterialSelection(); itscarrier_wavelengthmay name the carrier.- wavelengthfloat or None, optional
The carrier wavelength in m; it must agree with the selection’s
carrier_wavelengthwhen both are given, and one of the two is required.
- Returns:
- float
Third-order susceptibility in m^2/V^2.
- Raises:
- MaterialError
If the gas is unknown or has no Kerr coefficient (air), or there is no carrier.
Examples
>>> from solprop.physdata import Gas, chi3 >>> f"{chi3(Gas.Ar, pressure=1.0, wavelength=800e-9):.6e}" '3.649772e-26'
- solprop.physdata.nonlinear_data.chi3_from_n2(n2_value, index)[source]#
Convert a nonlinear index to a third-order susceptibility.
The inverse of
n2_from_chi3().- Parameters:
- n2_valuefloat
Nonlinear index in m^2/W.
- indexfloat
Linear refractive index at the wavelength of interest, > 0.
- Returns:
- float
Third-order susceptibility in m^2/V^2.
Examples
>>> from solprop.physdata import chi3_from_n2, n2_from_chi3 >>> f"{chi3_from_n2(n2_from_chi3(3e-26, 1.0003), 1.0003):.12e}" '3.000000000000e-26'
- solprop.physdata.nonlinear_data.gamma3(gas, *, wavelength)[source]#
Return a gas’s per-particle Kerr coefficient at a carrier wavelength.
optmat’s electronic hyperpolarizability evaluated at the carrier (
OptmatKerr); the coefficient is dispersive, so the carrier is required.- Parameters:
- gasGas or str
A built-in gas other than air.
- wavelengthfloat
Vacuum carrier wavelength in m, positive and finite.
- Returns:
- float
gamma3in m^5/V^2, such thatchi3 = gamma3 * rho.
- Raises:
- MaterialError
If the gas is unknown or is air, or the wavelength is not positive and finite.
- Warns:
- MaterialRangeWarning
Outside the model’s fitted wavelengths.
Examples
>>> from solprop.physdata import Gas, gamma3 >>> f"{gamma3(Gas.Ar, wavelength=800e-9):.6e}" '1.476195e-51'
- solprop.physdata.nonlinear_data.n2(gas, *, pressure, temperature=293.15, wavelength=None, selection=None)[source]#
Return the nonlinear index of a gas at a carrier.
The exact
n2 = 3 chi3 / (4 eps0 c n0^2)with optmat’s Kerr coefficient, its density and its linear indexn0, all at the carrier; optmat’s own gasn2, which takesn0 = 1, is not used.- Parameters:
- gasGas or str
The species.
- pressurefloat
Absolute pressure in bar (the documented non-SI user-interface unit), >= 0.
- temperaturefloat, optional
Temperature in K, > 0. Defaults to 293.15 K.
- wavelengthfloat or None, optional
The carrier wavelength in m at which the dispersive Kerr coefficient and
n0are evaluated: it, or the selection’scarrier_wavelength, is required, and the two must agree when both are given.- selectionMaterialSelection or None, optional
NoneisMaterialSelection().
- Returns:
- float
Nonlinear index in m^2/W.
- Raises:
- MaterialError
If the gas is unknown or has no Kerr coefficient, or the carriers disagree or are both missing.
- Warns:
- MaterialRangeWarning
If the carrier lies outside the qualified range of the gas’s models.
Examples
Helium at 1 bar and 800 nm.
>>> from solprop.physdata import Gas, n2 >>> f"{n2(Gas.He, pressure=1.0, wavelength=800e-9):.3e}" '3.635e-25'
- solprop.physdata.nonlinear_data.n2_from_chi3(chi3_value, index)[source]#
Convert a third-order susceptibility to a nonlinear index.
n2 = 3 chi3 / (4 eps0 c n0^2).- Parameters:
- chi3_valuefloat
Third-order susceptibility in m^2/V^2.
- indexfloat
Linear refractive index at the wavelength of interest, > 0.
- Returns:
- float
Nonlinear index in m^2/W, in the convention where an intensity
Ishifts the refractive index byn2 * I.
Examples
>>> from solprop.physdata import n2_from_chi3 >>> f"{n2_from_chi3(3e-26, 1.0003):.6e}" '8.471348e-24'
- solprop.physdata.nonlinear_data.selected_carrier(selection, wavelength)[source]#
Return the carrier a selection’s Kerr coefficient is evaluated at.
- Parameters:
- selectionMaterialSelection
The selection; its
carrier_wavelengthmay beNone.- wavelengthfloat or None
The caller’s wavelength in m, or
None.
- Returns:
- float
The one carrier in m both name.
- Raises:
- MaterialError
If neither names one, or the two disagree.
Examples
>>> from solprop.physdata import MaterialSelection >>> from solprop.physdata.nonlinear_data import selected_carrier >>> selected_carrier(MaterialSelection(carrier_wavelength=1030e-9), None) 1.03e-06