Skip to content

General 4×4 transfer-matrix method (TMM) for optical simulations of isotropic and anisotropic multilayer structures. C++ core with Python bindings.

License

Notifications You must be signed in to change notification settings

ardiloot/GeneralTmm

Repository files navigation

PyPI version Pytest Build and upload to PyPI

General 4×4 Transfer-Matrix Method (TMM)

A Python library for optical simulations of isotropic and anisotropic multilayer structures using the 4×4 transfer-matrix method (Hodgkinson, Kassam & Wu, 1997).

2D electromagnetic field map of surface plasmons

Table of Contents

Features

  • Isotropic and anisotropic (birefringent) layers — full 4×4 matrix for uniaxial/biaxial crystals with arbitrary orientation
  • Parameter sweeps — over wavelength, angle (β), layer thickness, refractive index, and crystal rotation angles
  • 1D and 2D electromagnetic field profiles — E and H field distributions through the structure
  • Field enhancement and optimization — built-in simplex optimizer to find resonance conditions (e.g. SPP)
  • Wavelength-dependent materials — interpolated from measured optical data
  • Cross-polarization coefficients — R₁₂, R₂₁, T₃₂, T₄₁ for polarization coupling in anisotropic media
  • High performance — C++ core (Eigen) with Cython bindings
  • Cross-platform wheels — Linux, Windows, macOS; Python 3.10–3.14

Installation

pip install GeneralTmm

Pre-built wheels are available for most platforms. A C++ compiler is only needed when installing from source.

API Overview

The library exposes two classes: Material and Tmm.

Class / method Purpose
Material(wls, ns) Wavelength-dependent material from arrays of λ and complex n
Material.Static(n) Constant refractive index (shortcut)
Tmm(wl=…, beta=…) Create a solver; wl = wavelength (m), beta = n sin θ
tmm.AddIsotropicLayer(d, mat) Append isotropic layer (d in m, inf for semi-infinite)
tmm.AddLayer(d, matX, matY, matZ, psi, xi) Append anisotropic layer with crystal orientation angles
tmm.Sweep(param, values) Solve for an array of values of any parameter; returns dict-like results (R11, R22, R12, T31, …)
tmm.CalcFields1D(xs, pol) E, H field profiles along the layer normal
tmm.CalcFields2D(xs, ys, pol) E, H on a 2-D grid
tmm.OptimizeEnhancement(…) Simplex optimizer for field enhancement

Coordinate system (Hodgkinson convention): x = layer normal / propagation direction, y and z = in-plane, plane of incidence = xz. Crystal rotation angles: ψ around z, ξ around x.

Examples

Total Internal Reflection — ExampleTIR.py

Simulate total internal reflection at a glass/air interface:

import numpy as np
from GeneralTmm import Tmm, Material

# Materials: glass prism and air
prism = Material.Static(1.5)
substrate = Material.Static(1.0)

# Set up TMM solver at 532 nm wavelength
tmm = Tmm(wl=532e-9)
tmm.AddIsotropicLayer(float("inf"), prism)      # semi-infinite prism
tmm.AddIsotropicLayer(float("inf"), substrate)   # semi-infinite air

# Sweep over effective mode index beta = n * sin(theta)
betas = np.linspace(0.0, 1.49, 100)
result = tmm.Sweep("beta", betas)

# Reflection coefficients for p- and s-polarization
R_p = result["R11"]  # p → p reflection
R_s = result["R22"]  # s → s reflection

Total internal reflection

Surface Plasmon Polaritons — ExampleSPP.py

Kretschmann configuration (glass | 50 nm Ag | air) with wavelength-dependent silver data (Johnson & Christy, 1972). Demonstrates reflection sweeps, enhancement optimization, and 1D/2D field visualization.

SPP reflection, enhancement, and 1D field profile

Dielectric Thin-Film Filters — ExampleFilter.py

Quarter-wave stacks of TiO₂ / SiO₂ on BK7 glass at normal incidence. A Bragg mirror (HL)⁷H gives > 99.8 % reflectance across a ~160 nm stop band centered at 550 nm. Adding a half-wave SiO₂ cavity between two such mirrors creates a Fabry-Perot bandpass filter with a narrow transmission peak.

Dielectric Bragg mirror and Fabry-Perot bandpass filter

Wave Plates — ExampleAnisotropic.py

Half-wave and quarter-wave plates simulated as birefringent slabs (Δn = 0.1) at normal incidence. Sweeps the plate rotation angle ξ to show how a HWP fully converts p- to s-polarization at 45°, while a QWP produces circular polarization. A textbook result verified with the full 4×4 method.

Half-wave and quarter-wave plate polarization conversion

Cholesteric Liquid Crystal — ExampleCholesteric.py

A helical stack of birefringent layers acts as a circular-polarization-selective Bragg reflector: one handedness is reflected in a well-defined wavelength band while the other is transmitted. This is the mechanism behind structurally colored beetle shells and cholesteric LC displays. Also a good stress test of the 4×4 method with hundreds of anisotropic layers.

Cholesteric liquid crystal Bragg reflector

Leaky Dyakonov SPP — ExampleDSPP.py

A Kretschmann-coupled surface plasmon polariton at an Ag / KTP birefringent-crystal interface. When the crystal optic axis is tilted past a critical angle φc ≈ 67°, the extraordinary wave begins to propagate and up to 36 % of the incident p-polarized light tunnels through the 60 nm silver film — the "leaky Dyakonov SPP" regime (Loot & Hizhnyakov, 2016).

Leaky Dyakonov surface plasmon polaritons

References

Hodgkinson, I. J., Kassam, S., & Wu, Q. H. (1997). Eigenequations and Compact Algorithms for Bulk and Layered Anisotropic Optical Media: Reflection and Refraction at a Crystal-Crystal Interface. Journal of Computational Physics, 133(1), 75–83.

Johnson, P. B., & Christy, R. W. (1972). Optical Constants of the Noble Metals. Physical Review B, 6(12), 4370–4379.

Loot, A., & Hizhnyakov, V. (2016). Leaky Dyakonov surface plasmon polaritons for birefringent crystals. Applied Physics A, 122, 327.

Development

Setup

git clone https://github.com/ardiloot/GeneralTmm.git
cd GeneralTmm

# Install uv if not already installed:
# https://docs.astral.sh/uv/getting-started/installation/

# Create venv, build the C++ extension, and install all dependencies
uv sync

Running tests

uv run pytest -v

Code formatting and linting

Pre-commit hooks are configured to enforce formatting (ruff, clang-format) and catch common issues. To install the git hook locally:

uvx pre-commit install

To run all checks manually:

uvx pre-commit run --all-files

Regenerating README images

uv run python docs/generate_images.py

CI overview

Workflow Trigger What it does
Pytest Push to master / PRs Tests on {ubuntu, windows, macos} × Python {3.10 – 3.14}
Pre-commit Push to master / PRs Runs ruff, clang-format, and other checks
Publish to PyPI Release published Builds wheels + sdist via cibuildwheel, uploads to PyPI
Dependabot Weekly Keeps GitHub Actions and pip dependencies up to date

Releasing

Versioning is handled automatically by setuptools-scm from git tags.

  1. Ensure CI is green on the master branch.
  2. Create a new release on GitHub:
    • Go to ReleasesDraft a new release
    • Create a new tag following PEP 440 (e.g. v1.2.0)
    • Target the master branch (or a specific commit on master)
    • Click Generate release notes for auto-generated changelog
    • For pre-releases (e.g. v1.2.0rc1), check Set as a pre-release — these upload to TestPyPI instead of PyPI
  3. Publish the release — the workflow builds wheels for Linux (x86_64 + aarch64), Windows (AMD64 + ARM64), and macOS (ARM64) and uploads to PyPI.

License

MIT

About

General 4×4 transfer-matrix method (TMM) for optical simulations of isotropic and anisotropic multilayer structures. C++ core with Python bindings.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •