solprop.physdata.glasses#

Refractive-index models for glasses, crystals and metals, with exact derivatives.

Fused silica, which is what a hollow capillary is made of, the window crystals and glass of the offline optics of solprop.optics, and the metals of a waveguide wall. A glass is described by its complex refractive index n(omega) directly, not by a per-particle susceptibility: unlike a gas fill it has no density to scale, and the quantity a capillary mode needs is the cladding permittivity \(\varepsilon_{\rm cl} = n^2\) and its frequency derivative.

The sign convention is the package’s (docs/dev/conventions.md section 5): n = n' + i k with k >= 0 for loss.

Every built-in solid is optmat’s (SEP 3): OptmatGlass adapts optmat’s absolute index, relative to vacuum, with its exact frequency derivative and its qualified intervals, and the factories (fused_silica(), calcium_fluoride(), magnesium_fluoride(), bk7(), sapphire(), barium_fluoride(), glass()) return optmat’s recommended model or the one model= names. SellmeierGlass, TabulatedGlass and CompositeGlass remain for a caller’s own data.

Evaluating outside a model’s validity range emits MaterialRangeWarning, as the gas models do.

Module Attributes

TRANSPARENT_ABSORPTION_BOUND

Largest intensity absorption coefficient, 1/m, a transparent index drops quietly.

Functions

barium_fluoride(*[, model])

Return the index of barium fluoride.

bk7(*[, model])

Return the index of SCHOTT N-BK7.

calcium_fluoride(*[, model])

Return a refractive-index model for calcium fluoride.

fused_silica(*[, model])

Return a refractive-index model for fused silica.

glass(name, *[, model, axis])

Return a glass by name.

glass_names()

Return the names glass() accepts, lower case.

lossless_index(material)

Return the index a solve that admits no loss takes of a material.

magnesium_fluoride(*[, axis, model])

Return the index of magnesium fluoride, a uniaxial crystal.

sapphire(*[, axis, model])

Return the index of synthetic sapphire, a uniaxial crystal.

Classes

CompositeGlass(*, name, source, ...)

A glass index taking its real part and its absorption from different sources.

GlassIndex(*, name, source, ...)

A complex refractive-index model for one glass from one source.

OptmatGlass(*, name, source, ...[, ...])

Take a solid's complex refractive index from an optmat model.

SellmeierGlass(*, name, source, ...)

A real refractive index from a sum-of-poles Sellmeier expansion.

SilicaBundle(model[, digest])

Take fused silica's nonlinear response from optmat: total n2, f_R and h_R.

TabulatedGlass(*, name, source, ...)

A complex refractive index interpolated from a caller's data table.

class solprop.physdata.glasses.CompositeGlass(*, name, source, wavelength_range, citation, real_part, absorption)[source]#

Bases: GlassIndex

A glass index taking its real part and its absorption from different sources.

The two parts are evaluated independently and added, so the validity range is the intersection of theirs and the citation names both.

Attributes:
real_partGlassIndex

Supplies Re n and d(Re n)/d(omega).

absorptionGlassIndex

Supplies Im n and d(Im n)/d(omega).

absorption: GlassIndex#
real_part: GlassIndex#
class solprop.physdata.glasses.GlassIndex(*, name, source, wavelength_range, citation)[source]#

Bases: ABC

A complex refractive-index model for one glass from one source.

Subclasses supply the index and its analytic frequency derivative; this base class adds the permittivity forms the capillary cladding term needs and checks the validity range. Instances compare by identity rather than by value, because a tabulated model holds arrays.

Attributes:
namestr

The material, e.g. "SiO2".

sourcestr

The name used to select this model, e.g. "malitson".

wavelength_rangetuple of float

Shortest and longest wavelength in m over which the source is valid.

citationstr

Where the model comes from, including its stated validity range.

citation: str#
dindex_domega(omega)[source]#

Return the analytic frequency derivative of the complex refractive index.

Parameters:
omegaarray_like

Angular frequency in rad/s, >= 0.

Returns:
ndarray

dn/domega in s/rad. For a tabulated model this is the exact derivative of the interpolant, whose own accuracy is that of the tabulated data.

Warns:
MaterialRangeWarning

If any wavelength lies outside the validity range of the source.

Examples

>>> from solprop.physdata import fused_silica
>>> silica = fused_silica(model="malitson_1965/sellmeier")
>>> f"{complex(silica.dindex_domega(2.356e15)):.4e}"
'5.8781e-18+0.0000e+00j'
dpermittivity_domega(omega)[source]#

Return the analytic frequency derivative of the relative permittivity.

Parameters:
omegaarray_like

Angular frequency in rad/s, >= 0.

Returns:
ndarray

depsilon/domega = 2 n dn/domega in s/rad.

Warns:
MaterialRangeWarning

If any wavelength lies outside the validity range of the source.

Examples

>>> from solprop.physdata import fused_silica
>>> silica = fused_silica(model="malitson_1965/sellmeier")
>>> f"{complex(silica.dpermittivity_domega(2.356e15)):.4e}"
'1.7090e-17+0.0000e+00j'
index(omega)[source]#

Return the complex refractive index.

Parameters:
omegaarray_like

Angular frequency in rad/s, >= 0.

Returns:
ndarray

n = n' + i k with k >= 0 for loss. 0-d for scalar input, otherwise the shape of omega.

Warns:
MaterialRangeWarning

If any wavelength lies outside the validity range of the source.

Examples

>>> from solprop.physdata import fused_silica
>>> silica = fused_silica(model="malitson_1965/sellmeier")
>>> f"{complex(silica.index(2.356e15)):.6f}"
'1.453722+0.000000j'
name: str#
permittivity(omega)[source]#

Return the complex relative permittivity n^2.

Parameters:
omegaarray_like

Angular frequency in rad/s, >= 0.

Returns:
ndarray

epsilon = n^2, dimensionless.

Warns:
MaterialRangeWarning

If any wavelength lies outside the validity range of the source.

Examples

>>> from solprop.physdata import fused_silica
>>> silica = fused_silica(model="malitson_1965/sellmeier")
>>> f"{complex(silica.permittivity(2.356e15)):.6f}"
'2.113309+0.000000j'
source: str#
wavelength_range: tuple[float, float]#
class solprop.physdata.glasses.OptmatGlass(*, name, source, wavelength_range, citation, model, transparent=False, absorption_bound=100.0)[source]#

Bases: GlassIndex

Take a solid’s complex refractive index from an optmat model.

The index is optmat’s absolute n + i k (relative to vacuum, k >= 0 for absorption, never conjugated: optmat’s sign is solprop’s), with its exact frequency derivative: analytic for the Sellmeier and fitted models, the interpolant’s own for a tabulated metal. A band outside the model’s qualified intervals is evaluated all the same and warns once per evaluation context (MaterialRangeWarning); a metal table holds its end values there.

as_transparent() takes the real part of the index, as a recorded approximation within a declared domain. A route that solves only a lossless problem (the step-index modes, a general modal guide’s material laws) takes that approximation itself, through lossless_index(), and never refuses an absorbing index (SEP 3, Q3). The transparent adapter records the largest extinction and absorption coefficient it has dropped (transparency), and warns when the absorption coefficient exceeds its bound, TRANSPARENT_ABSORPTION_BOUND by default: once per run inside a run, once per adapter outside one.

The adapter keeps its last few evaluations by frequency array (the bridge’s EvaluationCache): a frequency array equal to an earlier one takes the stored index, bitwise the same, and raises and records what the first evaluation did.

Two adapters are equal, and hash alike, when they compute the same index: the same model by its identity digest, under the same transparent approximation and bound (SEP 3, Q26). Two default walls or cores built separately are therefore one material, as two modes of one guide require; what each adapter has evaluated and dropped is its own measurement and does not enter the comparison.

Attributes:
modelOptmatModel

The optmat solid model: a registry model, or one from with_parameters, FormulaModel.sellmeier or TabulatedModel.from_arrays.

transparentbool

Whether the index is the model’s real part only, a declared approximation.

absorption_boundfloat

For a transparent index, the largest intensity absorption coefficient 4 pi k / lambda in 1/m it drops without a warning; positive.

Examples

>>> from solprop.physdata import fused_silica
>>> silica = fused_silica(model="recommended")
>>> silica.source
'fit/SiO2'
>>> f"{float(silica.index(2.356e15).real):.6f}"
'1.453719'
absorption_bound: float = 100.0#
as_transparent(absorption_bound=100.0)[source]#

Return the same model with its index taken as real, a recorded approximation.

Parameters:
absorption_boundfloat, optional

The intensity absorption coefficient 4 pi k / lambda in 1/m up to which k is dropped quietly; beyond it the adapter warns once.

Returns:
OptmatGlass

A new adapter, transparent=True, whose dropped loss is tracked afresh.

Raises:
MaterialError

If the bound is not positive.

property axis: str[source]#

Return the crystal axis the model describes.

Returns:
str

"o" or "e" for a uniaxial crystal, empty otherwise.

classmethod from_model(model, *, transparent=False, absorption_bound=100.0)[source]#

Adapt any optmat solid model, taken as it is.

Parameters:
modelOptmatModel

The optmat solid model.

transparentbool, optional

Take the real part of the index only, as a recorded approximation.

absorption_boundfloat, optional

For a transparent index, the absorption coefficient in 1/m beyond which dropping k warns.

Returns:
OptmatGlass

The adapted model, named by optmat’s material and model name.

Warns:
MaterialStatusWarning

If the model is provisional or untested.

property largest_dropped_absorption: float[source]#

Return the largest absorption coefficient a transparent index has dropped.

Returns:
float

max 4 pi k / lambda over every band evaluated so far, in 1/m.

property largest_dropped_extinction: float[source]#

Return the largest extinction coefficient a transparent index has dropped.

Returns:
float

max k over every band evaluated so far, dimensionless; 0 for a model that is not transparent or has not been evaluated.

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

Return the record of the optmat model, for a run’s manifest.

Returns:
tuple of MaterialRecord

The solid model’s identity.

model: OptmatModel#
run_transparency(log)[source]#

Return the record of the transparent approximation within one run.

Parameters:
logMaterialLog or None

The run’s evaluation log; None gives transparency, what the adapter has dropped over its life.

Returns:
collections.abc.Mapping

As transparency, with the largest dropped extinction and absorption those of the run’s own evaluations (SEP 3, Q28).

Examples

>>> from solprop.physdata import fused_silica
>>> from solprop.physdata.selection import MaterialLog
>>> window = fused_silica(model="recommended").as_transparent()
>>> log = MaterialLog()
>>> window.run_transparency(log)["largest_dropped_absorption"]
0.0
property transparency: Mapping[str, float | bool | None][source]#

Return the record of the transparent approximation, for a run’s manifest.

Returns:
collections.abc.Mapping

transparent, the absorption_bound in 1/m, the largest dropped extinction and absorption coefficient (1/m) with its wavelength in m (None before any is dropped), and whether the bound was exceeded.

transparent: bool = False#
class solprop.physdata.glasses.SellmeierGlass(*, name, source, wavelength_range, citation, poles)[source]#

Bases: GlassIndex

A real refractive index from a sum-of-poles Sellmeier expansion.

The expansion is the standard form

\[n^2 = 1 + \sum_j \frac{B_j\lambda^2}{\lambda^2 - \lambda_j^2}\]

with the wavelength in microns. Written in u = 1/lambda^2 it is rational, n^2 = 1 + sum_j B_j / (1 - lambda_j^2 u), so the frequency derivative follows in closed form and no finite difference is needed.

The expansion has no constant term: every entry carried so far has a leading coefficient of zero in its source. A fit with one (Li’s 1980 fluorides have 0.2762 and 0.33973) cannot be represented here and must not be transcribed by dropping it.

Below the shortest pole n^2 turns negative; the square root is taken in the complex plane there, so the deep ultraviolet returns an evanescent index rather than a NaN.

Attributes:
polestuple of tuple of float

One (B_j, lambda_j) pair per pole, with lambda_j in microns.

poles: tuple[tuple[float, float], ...]#
class solprop.physdata.glasses.SilicaBundle(model, digest='')[source]#

Bases: object

Take fused silica’s nonlinear response from optmat: total n2, f_R and h_R.

optmat’s silica bundle (optmat.solid.bundle) is the triple a propagation code in the \(n_0 = 1\) convention of the GNLSE takes, so that its parts cannot be mismatched: the Kerr fit’s total long-pulse \(n_2(\lambda)\) (kerr/SiO2), a Raman shape \(h_R\) of unit integral, and that shape’s own Raman fraction \(f_R\). The electronic part is \((1 - f_R)\,n_2\) and the delayed one \(f_R\,n_2\) convolved with \(h_R\), so a scalar and a vector run that hold the same total agree for long pulses (SEP 3, section 4.5).

  • "default": Hollenbeck and Cantrell’s shape with the Kerr fit’s \(f_R = 0.2188\), paired with it; copolarised only.

  • "tensor": Lin and Agrawal’s shape with their own \(f_R = 0.245\), which has Hellwarth’s isotropic part \(a\) and anisotropic part \(b\) (\(a + b = h_R\)).

optmat’s raman_coefficient and electronic_susceptibility include its silica \(n_0^2\); solprop’s GNLSE calibration and vacuum-normalised amplitudes take \(n_0 = 1\), so only \(n_2\), \(f_R\) and the normalised \(h_R\) are taken from here, never those two.

Attributes:
modelOptmatModel

The optmat bundle (SilicaNonlinearBundle); kept out of a run’s configuration record, which names it by digest.

digeststr

Its identity digest, filled in from the model.

Raises:
MaterialError

If the model is not an optmat silica bundle, or digest is not its own.

Examples

>>> from solprop.physdata.glasses import SilicaBundle
>>> bundle = SilicaBundle.resolve()
>>> bundle.name, f"{bundle.raman_fraction:.4f}", bundle.has_tensor
('silica_bundle/default', '0.2188', False)
>>> SilicaBundle.resolve(tensor=True).raman_fraction
0.245
digest: str = ''#
h_r(t, component='parallel')[source]#

Return the normalised Raman response or one of its tensor parts.

Parameters:
tnumpy.ndarray

Delays in s, shape (n_to,); zero and negative delays give zero.

component{‘parallel’, ‘a’, ‘b’}, optional

"parallel", the copolarised \(h_R = a + b\) of unit integral, or Hellwarth’s isotropic "a" and anisotropic "b".

Returns:
numpy.ndarray

The response in 1/s, shape (n_to,).

Raises:
MaterialError

If a tensor part is asked of a copolarised-only shape, naming it.

property has_tensor: bool[source]#

Return whether the shape has Hellwarth’s isotropic and anisotropic parts.

Returns:
bool

True for Lin and Agrawal’s shape; False for a copolarised-only one.

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

Return the records of the bundle, its Kerr fit and its Raman shape.

Returns:
tuple of MaterialRecord

The bundle’s first.

model: OptmatModel#
n2(wavelength)[source]#

Return the total long-pulse nonlinear index at a carrier wavelength.

Parameters:
wavelengthfloat

Vacuum wavelength in m, positive and finite.

Returns:
float

The Kerr fit’s total n2 in m^2/W.

Raises:
MaterialError

If the wavelength is not positive and finite.

Warns:
MaterialRangeWarning

Once per evaluation context, outside the Kerr fit’s 350 nm to 3.5 um.

property name: str[source]#

Return the bundle’s optmat name.

Returns:
str

For example "silica_bundle/default".

property paired: bool[source]#

Return whether f_R is the one the Kerr fit found with this shape.

Returns:
bool

True for the default bundle.

property raman_fraction: float[source]#

Return the shape’s own Raman fraction, the delayed share of the total n2.

Returns:
float

f_R, in (0, 1).

classmethod resolve(choice='recommended', *, tensor=False)[source]#

Resolve a silica bundle by selection name, optmat name or object.

Parameters:
choicestr or OptmatModel, optional

"recommended", the curated default (RAMAN_POLICIES): optmat’s "default" bundle, or its "tensor" bundle when tensor is set. "provisional" is a gas policy and is refused by name. Any other name is an optmat bundle name ("default", "tensor", "lin_2006", "blow_1989", …); an object is taken as it is.

tensorbool, optional

Whether the run needs the isotropic and anisotropic parts: a vector run.

Returns:
SilicaBundle

The adapter.

Raises:
MaterialError

If optmat has no bundle of that name, the name is the gas policy "provisional", or the object is not a bundle.

Warns:
MaterialStatusWarning

If the bundle is provisional or untested.

property shape: str[source]#

Return the name of the bundle’s Raman shape.

Returns:
str

For example "hollenbeck_2002".

solprop.physdata.glasses.TRANSPARENT_ABSORPTION_BOUND: Final = 100.0#

Largest intensity absorption coefficient, 1/m, a transparent index drops quietly.

A transparent optmat index (OptmatGlass.as_transparent()) keeps the real part and drops k; beyond this bound on alpha = 4 pi k / lambda it warns once. The bound is chosen from fused silica (fit/SiO2, optmat 0.1.0): across its transparent window, 200 nm to 2.5 um, alpha stays below 60 /m (1.9 /m at 200 nm, 60 /m in the 2.2 um band, 25 /m at 2.5 um); its ultraviolet edge passes 100 /m near 176 nm (510 /m at 170 nm, 1e8 /m at 120 nm) and its OH band at 2.73 um reaches 2800 /m. 100 /m, an e-folding of the intensity over a centimetre, therefore passes the window and fails the edges.

class solprop.physdata.glasses.TabulatedGlass(*, name, source, wavelength_range, citation, provenance, _real, _log_extinction, _log_wavelength_limits)[source]#

Bases: GlassIndex

A complex refractive index interpolated from a caller’s data table.

The real part is splined against log lambda, on which the data are close to uniformly sampled; the extinction coefficient is splined as log k on a floored copy of the data, so that exponentiating the interpolant can never return a negative k. Both derivatives follow from the spline derivative and d(log lambda)/d(omega) = -1/omega, so they are exact for the interpolant.

Beyond the ends of the table the index is held constant, with a zero derivative, and MaterialRangeWarning is raised: a cubic extrapolated over nine decades is meaningless, so it is not done silently.

Attributes:
provenancecollections.abc.Mapping

The table’s provenance as the caller records it: its source record, citation, licence and checksum. A built-in table is optmat’s (TabulatedModel, adapted by OptmatGlass).

provenance: Mapping[str, str]#
solprop.physdata.glasses.barium_fluoride(*, model=None)[source]#

Return the index of barium fluoride.

Parameters:
modelstr or OptmatModel or None, optional

None or "recommended" is optmat’s malitson_1964/sellmeier, made absolute; an optmat model name or object selects another (OptmatGlass).

Returns:
GlassIndex

A lossless Sellmeier model, 265 nm to 10.3 um.

Raises:
MaterialError

If the optmat model is unknown or not BaF2.

Examples

>>> from solprop.physdata import barium_fluoride
>>> barium_fluoride().source
'malitson_1964/sellmeier'
solprop.physdata.glasses.bk7(*, model=None)[source]#

Return the index of SCHOTT N-BK7.

Parameters:
modelstr or OptmatModel or None, optional

None or "recommended" is optmat’s schott_2023/sellmeier, lossless; an optmat model name or object selects another (OptmatGlass).

Returns:
GlassIndex

A lossless Sellmeier model, 300 nm to 2.5 um.

Raises:
MaterialError

If the optmat model is unknown or not N-BK7.

Examples

>>> from solprop.physdata import bk7
>>> bk7().source
'schott_2023/sellmeier'
solprop.physdata.glasses.calcium_fluoride(*, model=None)[source]#

Return a refractive-index model for calcium fluoride.

Parameters:
modelstr or OptmatModel or None, optional

None or "recommended" is optmat’s daimon_2002/sellmeier_20C, made absolute from its nitrogen reference; an optmat model name or object selects another (OptmatGlass).

Returns:
GlassIndex

A lossless Sellmeier model with an analytic frequency derivative.

Raises:
MaterialError

If the optmat model is unknown or not CaF2.

Examples

>>> from solprop.physdata import calcium_fluoride
>>> f"{float(calcium_fluoride().index(2.356e15).real):.5f}"
'1.43096'
>>> calcium_fluoride(model="malitson_1963/sellmeier").source
'malitson_1963/sellmeier'
solprop.physdata.glasses.fused_silica(*, model=None)[source]#

Return a refractive-index model for fused silica.

The default is optmat’s recommended silica, fit/SiO2: Franta’s universal dispersion model refitted to absolute refractometry, causal and absorbing from 24.8 nm to 125 um, with its exact frequency derivative (OptmatGlass). It is what a capillary cladding wants: one coherent law for the real index and the ultraviolet and mid-infrared absorption that the Marcatili loss term needs at the edges of a broad spectrum. A lossless-only route takes its transparent approximation itself (lossless_index()).

Parameters:
modelstr or OptmatModel or None, optional

None or "recommended" is optmat’s recommended silica; an optmat model name or object selects another (OptmatGlass).

Returns:
GlassIndex

The model, exposing index, dindex_domega, permittivity and dpermittivity_domega.

Raises:
MaterialError

If the optmat model is unknown or not silica.

Examples

>>> from solprop.physdata import fused_silica
>>> silica = fused_silica()
>>> silica.source
'fit/SiO2'
>>> f"{float(silica.index(2.356e15).real):.6f}"
'1.453719'
>>> fused_silica(model="malitson_1965/sellmeier").source
'malitson_1965/sellmeier'
solprop.physdata.glasses.glass(name, *, model=None, axis=None)[source]#

Return a glass by name.

Parameters:
namestr

One of glass_names(), in any case: "SiO2", "silica", "CaF2", "MgF2", "BK7", "sapphire", "Al2O3", "BaF2".

modelstr or OptmatModel or None, optional

None or "recommended" is optmat’s recommended model of the glass; an optmat model name or an optmat model object selects another (OptmatGlass).

axis{‘o’, ‘e’} or None, optional

The ray of a uniaxial crystal (MgF2, sapphire); required with optmat’s recommended model, refused for an isotropic glass.

Returns:
GlassIndex

The model.

Raises:
MaterialError

If the name, the axis or the optmat model is unknown or does not fit the glass, or a uniaxial crystal’s recommended model is asked for without its ray.

Examples

>>> from solprop.physdata import glass
>>> glass("CaF2").source
'daimon_2002/sellmeier_20C'
>>> glass("sapphire", axis="o").source
'weber_2003/sellmeier_o'
>>> glass("CaF2", model="malitson_1963/sellmeier").source
'malitson_1963/sellmeier'
solprop.physdata.glasses.glass_names()[source]#

Return the names glass() accepts, lower case.

Returns:
tuple of str

Every accepted spelling, aliases included.

Examples

>>> from solprop.physdata import glass_names
>>> "caf2" in glass_names() and "silica" in glass_names()
True
solprop.physdata.glasses.lossless_index(material)[source]#

Return the index a solve that admits no loss takes of a material.

An absorbing optmat index on a lossless-only route – the step-index modes, a general modal guide’s material laws – is taken through its transparent approximation, never refused (SEP 3, Q3): the real part of the index and its real derivative, with the dropped k recorded and a MaterialRangeWarning once per run where the dropped absorption 4 pi k / lambda exceeds TRANSPARENT_ABSORPTION_BOUND. Every lossless route of one adapter takes one counterpart, so two modes of one guide still share their material and its record is one. A model with k = 0 everywhere drops nothing. Any other material, a transparent optmat index included, is returned as it is: a complex index of solprop’s own keeps each route’s existing handling.

Parameters:
materialGlassIndex, float or complex

The material a lossless route was given.

Returns:
GlassIndex, float or complex

The transparent counterpart of an absorbing-capable optmat index, otherwise material itself.

Examples

>>> from solprop.physdata import fused_silica
>>> from solprop.physdata.glasses import lossless_index
>>> silica = fused_silica(model="recommended")
>>> lossless = lossless_index(silica)
>>> lossless.transparent, lossless_index(silica) is lossless
(True, True)
>>> lossless_index(1.45)
1.45
solprop.physdata.glasses.magnesium_fluoride(*, axis=None, model=None)[source]#

Return the index of magnesium fluoride, a uniaxial crystal.

Parameters:
axis{‘o’, ‘e’} or None, optional

The ray: "o" (ordinary), which a c-cut window presents at normal incidence, or "e" (extraordinary). optmat’s models are per ray, so the default needs it; a named model names its own.

modelstr or OptmatModel or None, optional

None or "recommended" is optmat’s dodge_1984/sellmeier_o or _e, made absolute; an optmat model name or object selects another (OptmatGlass).

Returns:
GlassIndex

A lossless Sellmeier model, 200 nm to 7 um.

Raises:
MaterialError

If the axis is not a ray, or is missing for optmat’s recommended model, or the optmat model is unknown, not MgF2 or of the other ray.

Examples

>>> from solprop.physdata import magnesium_fluoride
>>> extraordinary = magnesium_fluoride(axis="e")
>>> f"{float(extraordinary.index(2.356e15).real):.5f}"
'1.38713'
solprop.physdata.glasses.sapphire(*, axis=None, model=None)[source]#

Return the index of synthetic sapphire, a uniaxial crystal.

Parameters:
axis{‘o’, ‘e’} or None, optional

The ray, "o" or "e"; optmat’s models are per ray, so the default needs it. A named model names its own.

modelstr or OptmatModel or None, optional

None or "recommended" is optmat’s weber_2003/sellmeier_o or _e, made absolute; an optmat model name or object selects another (OptmatGlass).

Returns:
GlassIndex

A lossless Sellmeier model, 200 nm to 5 um.

Raises:
MaterialError

As magnesium_fluoride(), for sapphire.

Examples

>>> from solprop.physdata import sapphire
>>> sapphire(axis="o").source
'weber_2003/sellmeier_o'