solprop.physdata.raman_types#

The parameter records of a supplied Raman response.

The records a caller fills from their own data to build a Raman response with solprop.nonlinear.raman: a molecule’s rotational and vibrational constants (MolecularRaman) with their density-dependent linewidths, an amorphous solid’s intermediate-broadening line set (IntermediateBroadeningRaman) and the Lin–Agrawal two-part silica response (LinAgrawalRaman), with the dephasing and option types the response builders take. They carry no material data: since SEP 3 every built-in gas’s and fused silica’s response is optmat’s (solprop.nonlinear.optmat_raman, SilicaBundle).

Functions

linewidth_from_dephasing_time(dephasing_time)

Build a density-independent linewidth from a measured dephasing time.

Classes

Dephasing(linewidth)

The decay of a Raman coherence, as a function of the local number density.

IntermediateBroadeningRaman(frequencies, ...)

Raman lines of an amorphous solid in the intermediate-broadening model.

LinAgrawalRaman(tau1, tau2, tau_b, ...)

The two-part Raman response of fused silica, in the Lin--Agrawal form.

Linewidth([constant, inverse_density, density])

Density-dependent dephasing rate of a Raman transition.

MolecularOptions([temperature, rotation, ...])

Which parts of a molecular gas's Raman spectrum to build, and at what state.

MolecularRaman(gas, rotational, vibrational)

The Raman data of one gas: a rotational part, a vibrational part, or both.

RotationalRaman(b, d, degeneracy_odd, ...)

Constants of the rotational Raman spectrum of a linear molecule.

VibrationalRaman(frequency, ...)

Constants of one vibrational Raman mode.

class solprop.physdata.raman_types.Dephasing(linewidth)[source]#

Bases: object

The decay of a Raman coherence, as a function of the local number density.

A wrapper over solprop.physdata.raman_types.Linewidth that turns a full width at half maximum in hertz into the decay factor exp(-t / tau2) a response is damped by, and that is defined at every density including zero.

The zero-density limit has three cases, and which one applies is fixed by the linewidth’s own coefficients:

  • a gas with Dicke narrowing (inverse_density > 0) has a diverging linewidth as the density falls, so tau2 -> 0: no coherence at all;

  • a gas with only collisional broadening (constant and inverse_density both zero) has a vanishing linewidth, so tau2 -> inf: an undamped coherence;

  • a gas with a density-independent term keeps tau2 = 1 / (pi * constant).

All three are finite answers, for the vibrational model as for the rotational one, so a fill that starts from vacuum gives no NaN polarisation. The density multiplies the polarisation anyway, so the choice is invisible in the answer and visible only in whether the answer is a number.

Attributes:
linewidthLinewidth

The dephasing rate of the transition, in Hz per its own density terms.

Examples

>>> from solprop.constants import AMAGAT
>>> from solprop.nonlinear.raman import Dephasing
>>> from solprop.physdata import Linewidth
>>> dephasing = Dephasing(Linewidth(density=3.3e9))
>>> f"{dephasing.dephasing_time(AMAGAT):.4e}"
'9.6458e-11'
>>> dephasing.dephasing_time(0.0)
inf
damping(t, density)[source]#

Return the decay factor exp(-t / tau2) on a time axis.

Parameters:
tnumpy.ndarray

Times since the drive, s, shape (n_to,), non-negative.

densityfloat

Number density in m^-3, non-negative.

Returns:
numpy.ndarray

The factor in [0, 1], shape (n_to,). All ones for an undamped coherence and all zeros where the coherence has collapsed, rather than an exp(-0/0) NaN.

Raises:
MaterialError

If the density is negative.

Examples

>>> import numpy as np
>>> from solprop.nonlinear.raman import Dephasing
>>> from solprop.physdata import Linewidth
>>> dephasing = Dephasing(Linewidth(inverse_density=6.15e6))
>>> dephasing.damping(np.array([0.0, 1e-12]), 0.0).tolist()
[0.0, 0.0]
decay_rate(density)[source]#

Return the coherence decay rate at a number density.

The reciprocal of dephasing_time(), and the form the translation layer prefers: zero is the undamped limit and is an ordinary float, where the dephasing time it corresponds to is infinite.

Parameters:
densityfloat

Number density in m^-3, non-negative.

Returns:
float

1 / tau2 in s^-1. Zero for an undamped coherence and inf where the Dicke term diverges at zero density.

Raises:
MaterialError

If the density is negative.

Examples

>>> from solprop.nonlinear.raman import Dephasing
>>> from solprop.physdata import Linewidth
>>> Dephasing(Linewidth(inverse_density=6.15e6)).decay_rate(0.0)
inf
dephasing_time(density)[source]#

Return the coherence dephasing time at a number density.

Parameters:
densityfloat

Number density in m^-3, non-negative.

Returns:
float

tau2 in s. inf for an undamped coherence and 0.0 where the Dicke term diverges at zero density.

Raises:
MaterialError

If the density is negative.

Examples

>>> from solprop.nonlinear.raman import Dephasing
>>> from solprop.physdata import Linewidth
>>> Dephasing(Linewidth(constant=8220e6)).dephasing_time(0.0)
3.872...e-11
linewidth: Linewidth#
class solprop.physdata.raman_types.IntermediateBroadeningRaman(frequencies, amplitudes, gaussian_widths, lorentzian_widths, citation)[source]#

Bases: object

Raman lines of an amorphous solid in the intermediate-broadening model.

Each line contributes A exp(-gamma t) exp(-Gamma^2 t^2 / 4) sin(omega t) to the response: a damped sinusoid whose Lorentzian width gamma is the homogeneous dephasing and whose Gaussian width Gamma is the inhomogeneous spread of the disordered network. Neither width depends on density – a glass has no density path – so this model carries its own damping, unlike the molecular ones.

The response is a shape: its amplitudes are relative, and the caller fixes the magnitude, normally as a Raman fraction of the medium’s third-order susceptibility.

Attributes:
frequenciestuple of float

Line centres in rad/s.

amplitudestuple of float

Relative line strengths, dimensionless.

gaussian_widthstuple of float

Inhomogeneous (Gaussian) widths in rad/s.

lorentzian_widthstuple of float

Homogeneous (Lorentzian) widths in rad/s.

citationstr

Where the line set comes from.

Raises:
MaterialError

If the four sequences do not have the same length, or there are no lines.

References

D. Hollenbeck and C. D. Cantrell, “Multiple-vibrational-mode model for fiber-optic Raman gain spectrum and response function”, J. Opt. Soc. Am. B 19, 2886 (2002), doi:10.1364/JOSAB.19.002886.

Examples

>>> from solprop.physdata import IntermediateBroadeningRaman
>>> lines = IntermediateBroadeningRaman(
...     frequencies=(8.2e13,),
...     amplitudes=(1.0,),
...     gaussian_widths=(9.6e12,),
...     lorentzian_widths=(3.0e12,),
...     citation="one illustrative line",
... )
>>> lines.n_lines
1
amplitudes: tuple[float, ...]#
citation: str#
frequencies: tuple[float, ...]#
gaussian_widths: tuple[float, ...]#
lorentzian_widths: tuple[float, ...]#
property n_lines: int[source]#

Return the number of lines.

Returns:
int

The common length of the four sequences.

class solprop.physdata.raman_types.LinAgrawalRaman(tau1, tau2, tau_b, isotropic_weight, boson_weight, anisotropic_weight, fraction, citation)[source]#

Bases: object

The two-part Raman response of fused silica, in the Lin–Agrawal form.

The delayed nuclear response of Lin and Agrawal’s vector theory, whose isotropic and anisotropic parts are separate functions of delay:

\[\begin{split}h_a(t) &= \frac{\tau_1^2 + \tau_2^2}{\tau_1\tau_2^2} e^{-t/\tau_2}\sin(t/\tau_1), \\ h_b(t) &= \frac{2\tau_b - t}{\tau_b^2} e^{-t/\tau_b},\end{split}\]

each integrating to one over the positive axis: \(h_a\) is the damped vibrational response of the Blow–Wood model and \(h_b\) the boson peak of the disordered network. The paper’s two response functions are then

\[a(\tau) = w_a h_a(\tau), \qquad b(\tau) = w_b h_b(\tau) + w_{ab} h_a(\tau),\]

with \(\int a = w_a\) and \(\int b = w_b + w_{ab}\), and the pair multiplies \(f_R\chi^{(3)}\) once. Like IntermediateBroadeningRaman this record is data: the response that evaluates it is solprop.nonlinear.raman.SilicaTensorResponse.

The built-in silica responses are optmat’s bundles (SilicaBundle); this record is for a caller’s own parameters.

Attributes:
tau1float

Inverse of the vibrational frequency of \(h_a\), s, positive.

tau2float

Damping time of \(h_a\), s, positive.

tau_bfloat

Time constant of the boson peak \(h_b\), s, positive.

isotropic_weightfloat

\(w_a\), the weight of \(h_a\) in the isotropic response \(a\), non-negative.

boson_weightfloat

\(w_b\), the weight of \(h_b\) in the anisotropic response \(b\), non-negative.

anisotropic_weightfloat

\(w_{ab}\), the weight of \(h_a\) in \(b\), non-negative.

fractionfloat

The Raman fraction \(f_R\) of the medium’s third-order susceptibility, in (0, 1].

citationstr

Where the numbers come from.

Raises:
MaterialError

If a time constant is not positive and finite, a weight is negative, the three weights do not sum to one, or the fraction is outside (0, 1].

References

Q. Lin and G. P. Agrawal, “Vector theory of stimulated Raman scattering and its application to fiber-based Raman amplifiers”, J. Opt. Soc. Am. B 20, 1616 (2003), doi:10.1364/JOSAB.20.001616, Eqs. (2.2) and (2.5), for the tensor structure; Q. Lin and G. P. Agrawal, “Raman response function for silica fibers”, Opt. Lett. 31, 3086 (2006), doi:10.1364/OL.31.003086, for these parameters.

Examples

The 2006 letter’s parameters, as a caller would supply them:

>>> from solprop.physdata import LinAgrawalRaman
>>> silica = LinAgrawalRaman(
...     tau1=12.2e-15,
...     tau2=32.0e-15,
...     tau_b=96.0e-15,
...     isotropic_weight=0.75,
...     boson_weight=0.21,
...     anisotropic_weight=0.04,
...     fraction=0.245,
...     citation="Lin and Agrawal, Opt. Lett. 31, 3086 (2006)",
... )
>>> round(silica.isotropic_weight + silica.boson_weight
...       + silica.anisotropic_weight, 12)
1.0
anisotropic_weight: float#
boson_weight: float#
citation: str#
fraction: float#
isotropic_weight: float#
tau1: float#
tau2: float#
tau_b: float#
class solprop.physdata.raman_types.Linewidth(constant=0.0, inverse_density=0.0, density=0.0)[source]#

Bases: object

Density-dependent dephasing rate of a Raman transition.

The full width at half maximum (FWHM) in hertz is constant + inverse_density / n + density * n with n the number density in amagat, so the dephasing time is tau2 = 1 / (pi * fwhm). The middle term is Dicke narrowing, which makes lines narrower as the density rises until collisional broadening takes over; a gas with only a measured dephasing time at one density is represented by the constant term alone.

Attributes:
constantfloat

Density-independent term in Hz.

inverse_densityfloat

Dicke-narrowing coefficient in Hz amagat.

densityfloat

Collisional broadening coefficient in Hz/amagat.

constant: float = 0.0#
density: float = 0.0#
dephasing_time(density_amagat)[source]#

Return the dephasing time at a given density.

Parameters:
density_amagatfloat

Number density in amagat (multiples of the Loschmidt constant, solprop.constants.AMAGAT), > 0.

Returns:
float

Dephasing time tau2 in s.

Raises:
MaterialError

If the density is not positive, where the Dicke term diverges.

inverse_density: float = 0.0#
class solprop.physdata.raman_types.MolecularOptions(temperature=None, rotation=None, vibration=None, min_j=0, max_j=50)[source]#

Bases: object

Which parts of a molecular gas’s Raman spectrum to build, and at what state.

Grouped because solprop.nonlinear.raman.response_for() would otherwise take more arguments than the project allows loose (AGENTS.md, “Functions and modules”).

Each term flag has three states: None (the default) takes the term when the species has a model for it and silently goes without otherwise, True requires it and is refused by species name when no model exists, False leaves it out. So MolecularOptions() means every term the species has, and only a term the caller named can fail. The temperature likewise defaults to the run’s or the mixture’s own, and to solprop.constants.ROOM_TEMPERATURE for a bare solprop.nonlinear.raman.response_for() call.

Attributes:
temperaturefloat or None, optional

Gas temperature in K, positive; sets the rotational populations. None takes the temperature of the run or mixture the options are used in.

rotationbool or None, optional

Whether to include the rotational ladder. None takes it when available.

vibrationbool or None, optional

Whether to include the vibrational mode. None takes it when available.

min_jint, optional

Lowest rotational quantum number, non-negative. Default 0.

max_jint, optional

Highest rotational quantum number before truncation. Default 50.

Examples

>>> from solprop.nonlinear.raman import MolecularOptions
>>> MolecularOptions(rotation=False).vibration is None
True
>>> MolecularOptions().resolved(300.0).temperature
300.0
max_j: int = 50#
min_j: int = 0#
resolved(temperature)[source]#

Return the options with an unset temperature taken from the caller.

Parameters:
temperaturefloat

The run’s or mixture’s temperature in K.

Returns:
MolecularOptions

The same options, with the temperature filled in when it was None.

rotation: bool | None = None#
temperature: float | None = None#
vibration: bool | None = None#
class solprop.physdata.raman_types.MolecularRaman(gas, rotational, vibrational, missing='')[source]#

Bases: object

The Raman data of one gas: a rotational part, a vibrational part, or both.

Attributes:
gasGas or str

The species.

rotationalRotationalRaman or None

The rotational spectrum, or None for a spherical top, which has none.

vibrationalVibrationalRaman or None

The vibrational mode, or None if there is no usable data.

missingstr, optional

Explanation of unavailable terms; no physical constants are inferred from it.

gas: Gas | str#
missing: str = ''#
rotational: RotationalRaman | None#
vibrational: VibrationalRaman | None#
class solprop.physdata.raman_types.RotationalRaman(b, d, degeneracy_odd, degeneracy_even, polarisability_anisotropy, linewidth, citation)[source]#

Bases: object

Constants of the rotational Raman spectrum of a linear molecule.

Attributes:
bfloat

Rotational constant in m^-1.

dfloat

Centrifugal distortion constant in m^-1.

degeneracy_oddint

Nuclear spin statistical weight of odd rotational states.

degeneracy_evenint

Nuclear spin statistical weight of even rotational states.

polarisability_anisotropyfloat

Anisotropy of the molecular volume polarisability in m^3; multiply by 4 pi epsilon_0 to obtain the SI polarisability anisotropy.

linewidthLinewidth

Dephasing rate of the rotational coherences.

citationstr

Where each constant comes from.

b: float#
citation: str#
d: float#
degeneracy_even: int#
degeneracy_odd: int#
linewidth: Linewidth#
polarisability_anisotropy: float#
class solprop.physdata.raman_types.VibrationalRaman(frequency, polarisability_derivative, reduced_mass, linewidth, citation)[source]#

Bases: object

Constants of one vibrational Raman mode.

Attributes:
frequencyfloat

Angular frequency of the mode in rad/s.

polarisability_derivativefloat

Derivative of the mean volume polarisability with respect to a displacement coordinate, m^2. For a diatomic molecule the coordinate is bond length, paired with its reduced mass. A mass-weighted derivative uses a different convention and must first be converted consistently.

reduced_massfloat

Effective mass of that displacement coordinate in kg; the reduced mass for a diatomic bond coordinate.

linewidthLinewidth

Dephasing rate of the vibrational coherence.

citationstr

Where each constant comes from.

citation: str#
frequency: float#
linewidth: Linewidth#
polarisability_derivative: float#
reduced_mass: float#
solprop.physdata.raman_types.linewidth_from_dephasing_time(dephasing_time)[source]#

Build a density-independent linewidth from a measured dephasing time.

A module-level function rather than a classmethod: the runtime type checking installed in the test session resolves annotations while the class body is still executing, so a method cannot name its own class in its return annotation.

Parameters:
dephasing_timefloat

Dephasing time tau2 in s, > 0.

Returns:
Linewidth

A linewidth whose only term is 1 / (pi tau2).

Raises:
MaterialError

If the dephasing time is not positive.

Examples

>>> from solprop.physdata import linewidth_from_dephasing_time
>>> f"{linewidth_from_dephasing_time(6e-12).dephasing_time(1.0):.3e}"
'6.000e-12'