# The Clear BSD License
#
# Copyright (c) 2026 Tobias Heibges
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted (subject to the limitations in the disclaimer
# below) provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
# THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
"""
Dispersion Model Functions
Provides functions for computing wavelength-dependent refractive indices
using standard dispersion models (Sellmeier, Cauchy).
"""
import math
[docs]
def sellmeier_refractive_index(
wavelength: float,
B1: float = 1.03961212,
B2: float = 0.231792344,
B3: float = 1.01046945,
C1: float = 6.00069867e-3,
C2: float = 2.00179144e-2,
C3: float = 1.03560653e2,
) -> float:
"""
Compute refractive index using Sellmeier equation.
The Sellmeier equation is an empirical formula that accurately models
the dispersion of optical glasses.
Parameters
----------
wavelength : float
Wavelength in meters.
B1, B2, B3 : float
Sellmeier B coefficients (dimensionless).
Defaults are for N-BK7 glass.
C1, C2, C3 : float
Sellmeier C coefficients in μm².
Defaults are for N-BK7 glass.
Returns
-------
n : float
Refractive index at given wavelength.
Notes
-----
Sellmeier equation:
n² - 1 = B₁λ²/(λ² - C₁) + B₂λ²/(λ² - C₂) + B₃λ²/(λ² - C₃)
where λ is in micrometers.
Default coefficients are for Schott N-BK7 glass, valid 300-2500 nm.
References
----------
.. [1] Sellmeier, W. (1871). Ann. Phys. Chem., 143, 271.
.. [2] Schott AG. Technical Information TIE-29.
Examples
--------
>>> n_589nm = sellmeier_refractive_index(589e-9)
>>> print(f"n = {n_589nm:.6f}") # ~1.5168
"""
# Convert wavelength to micrometers
wl_um = wavelength * 1e6
wl2 = wl_um * wl_um
# Sellmeier equation
n2_minus_1 = B1 * wl2 / (wl2 - C1) + B2 * wl2 / (wl2 - C2) + B3 * wl2 / (wl2 - C3)
return math.sqrt(1.0 + n2_minus_1)
[docs]
def cauchy_refractive_index(
wavelength: float,
A: float = 1.458,
B: float = 3.54e-3,
C: float = 0.0,
) -> float:
"""
Compute refractive index using Cauchy equation.
The Cauchy equation is a simple empirical dispersion formula,
valid in regions of normal dispersion (away from absorption bands).
Parameters
----------
wavelength : float
Wavelength in meters.
A : float
Constant term (refractive index at infinite wavelength).
Default is for typical crown glass.
B : float
First-order dispersion coefficient in μm².
Default is for typical crown glass.
C : float
Second-order dispersion coefficient in μm⁴.
Default is 0.
Returns
-------
n : float
Refractive index at given wavelength.
Notes
-----
Cauchy equation:
n(λ) = A + B/λ² + C/λ⁴
where λ is in micrometers.
Suitable for glasses and transparent materials in visible range.
Less accurate than Sellmeier near absorption edges.
References
----------
.. [1] Cauchy, A.-L. (1836). Bull. Sci. Math., 14, 6-10.
Examples
--------
>>> n_550nm = cauchy_refractive_index(550e-9, A=1.5, B=0.004)
>>> print(f"n = {n_550nm:.4f}")
"""
# Convert to micrometers
wl_um = wavelength * 1e6
wl2 = wl_um * wl_um
return A + B / wl2 + C / (wl2 * wl2)