Tutorial 1d - Material Database Tutorial

This tutorial demonstrates how to use the material database in Optiland to compute optical properties, including refractive index and extinction coefficient versus wavelength. In Optiland, materials are properties of surfaces and are used to determine optical behavior at their interfaces. Optiland’s material database is built on top of the refractiveindex.info database.

We will demonstrate how to generate three material types:

  1. IdealMaterial: Fixed refractive index and extinction coefficient.

  2. AbbeMaterial: Ideal glass parameterized by refractive index at the Fraunhofer d-line (587.56 nm) and the Abbe number. Valid only over the visible spectrum.

  3. Material: Generic material that provides interface to the refractiveindex.info database.

We will show how to compute the refractive index for various materials, from glasses and chemicals to organic materials and gases.

[1]:
import matplotlib.pyplot as plt
import numpy as np

from optiland.materials import AbbeMaterial, AbbeMaterialE, IdealMaterial, Material

1. Ideal Material

The IdealMaterial class represents a material with a fixed refractive index and extinction coefficient. This is useful for simulations that require simple, constant parameters.

[2]:
ideal_material = IdealMaterial(n=1.5, k=0)

wavelengths = [0.48, 0.55, 0.65]

for wavelength in wavelengths:
    print(f"Refractive Index at {wavelength} µm: {ideal_material.n(wavelength)}")
    print(
        f"Extinction Coefficient at {wavelength} µm: {ideal_material.k(wavelength)}",
        end="\n\n",
    )
Refractive Index at 0.48 µm: 1.5
Extinction Coefficient at 0.48 µm: 0.0

Refractive Index at 0.55 µm: 1.5
Extinction Coefficient at 0.55 µm: 0.0

Refractive Index at 0.65 µm: 1.5
Extinction Coefficient at 0.65 µm: 0.0

2. Abbe Material

The AbbeMaterial class generates a model optical glass material in the visible spectrum. The material is defined by its refractive index at a reference wavelength and its Abbe number. Optiland supports two distinct definitions:

  1. Standard d-line (:math:`V_d`):

    • Reference (:math:`n_d`): Helium d-line at 587.56 nm.

    • Abbe Number (:math:`V_d`): Calculated using Hydrogen F (486.1 nm) and C (656.3 nm) lines.

    • Models: “buchdahl” (Recommended) and “polynomial” (Legacy).

  2. e-line (:math:`V_e`):

    • Reference (:math:`n_e`): Mercury e-line at 546.07 nm.

    • Abbe Number (:math:`V_e`): Calculated using Cadmium F’ (480.0 nm) and C’ (643.8 nm) lines.

    • Model: AbbeMaterialE class.

The extinction coefficient is set to zero for these models but can be overwritten manually.

[3]:
# Create instances of the different Abbe models

# 1. Buchdahl Model (d-line) - The new recommended default
# Input: Index at 587.56 nm, Abbe number Vd (using F/C lines)
abbe_buchdahl = AbbeMaterial(n=1.5, abbe=65.0, model="buchdahl")

# 2. Legacy Polynomial Model (d-line)
# Input: Index at 587.56 nm, Abbe number Vd (using F/C lines)
abbe_poly = AbbeMaterial(n=1.5, abbe=65.0, model="polynomial")

# 3. AbbeMaterialE (e-line)
# Input: Index at 546.07 nm, Abbe number Ve (using F'/C' lines)
# Note: Ve is typically slightly different from Vd for the same physical glass.
abbe_e = AbbeMaterialE(n=1.5, abbe=65.0)

# Define wavelength range for plotting
wavelengths = np.linspace(0.4, 0.75, 500)

# Calculate refractive indices
n_buchdahl = abbe_buchdahl.n(wavelengths)
n_poly = abbe_poly.n(wavelengths)
n_e = abbe_e.n(wavelengths)

# Plot the results
plt.figure(figsize=(10, 6))
plt.plot(wavelengths, n_buchdahl, label='Buchdahl (d-line: 587nm, F/C)', linestyle='-')
plt.plot(wavelengths, n_poly, label='Polynomial (Legacy)', linestyle='--')
plt.plot(wavelengths, n_e, label='Buchdahl (e-line: 546nm, F\'/C\')', linestyle='-.')

plt.xlabel("Wavelength (µm)")
plt.ylabel("Refractive Index")
plt.title("Comparison of Abbe Material Models (n=1.5, V=65.0)")
plt.legend()
plt.grid(alpha=0.25)
plt.show()
../_images/examples_Tutorial_1d_Material_Database_6_0.png

3. Material Class (RefractiveIndex.info Integration)

The Material class connects to refractiveindex.info to access real-world material data. It uses string matching to find the closest match for a given material name.

Example 1: A common glass type

[4]:
glass = Material("N-SF5")

n_sf5 = glass.n(wavelengths)

plt.plot(wavelengths, n_sf5, "C1")
plt.xlabel("Wavelength (µm)")
plt.ylabel("Refractive Index")
plt.title("Refractive Index of N-SF5 vs. Wavelength")
plt.grid(alpha=0.25)
plt.show()
../_images/examples_Tutorial_1d_Material_Database_9_0.png

Note that you may also pass a reference name to the material, which narrows down the material selection if there are multiple matches for the given material name. The reference can include e.g., the glass manufacturer, the author name, year of publication, etc.

[5]:
glass = Material("N-SF5", reference="Schott")

Example 2: Organic material (DNA)

[6]:
DNA = Material("DNA")

wavelength = 0.26

# call `.item()` to get the value as a scalar
print(f"Refractive Index of DNA at {wavelength} µm: {DNA.n(wavelength).item():.5f}")
Refractive Index of DNA at 0.26 µm: 1.65214

Example 3: Others materials (AgCl & toluene)

[7]:
silver_chloride = Material("AgCl")
toluene = Material("toluene")

wavelength = 0.55

print(
    f"Refractive Index of AgCl at {wavelength} µm: {silver_chloride.n(wavelength).item():.5f}",
)
print(
    f"Refractive Index of toluene at {wavelength} µm: {toluene.n(wavelength).item():.5f}"
)
Refractive Index of AgCl at 0.55 µm: 2.07748
Refractive Index of toluene at 0.55 µm: 1.50006

Example 4: Gases (helium)

[8]:
he = Material("He")

wavelength = 0.612

print(f"Refractive Index of He at {wavelength} µm: {he.n(wavelength).item():.7f}")
Refractive Index of He at 0.612 µm: 1.0000344

Conclusion:

This tutorial showcased the key features of the Optiland material database. By leveraging IdealMaterial, AbbeMaterial, and Material, users can simulate a wide variety of optical systems with realistic material properties.