Analytical mode solver for cylindrical step-index fibers
Project description
Anafibre is an analytical mode solver for cylindrical step-index optical fibres. It computes guided modes by solving dispersion relations and evaluating corresponding electromagnetic fields analytically.
Features
- 🔬 Analytical solutions for guided modes in cylindrical fibres
- 🌈 Mode visualisation with plotting utilities for field components
- 📊 Dispersion analysis helpers and effective index calculations
- ⚡ Fast computation of propagation constants with SciPy-based root finding
- 🎯 Flexible materials support via fixed indices, callables or refractiveindex.info database
- 📐 Optional unit support through Astropy
Installation
Install from PyPI
pip install anafibre
Optional extras
- Units support using
astropy.units.Quantitypip install "anafibre[units]"
- refractiveindex.info database support
pip install "anafibre[refractiveindex]"
- All optional features (units + refractiveindex.info)
pip install "anafibre[all]"
Core API Overview
Anafibre has two main objects:
StepIndexFibre— defines the waveguide (geometry + materials)GuidedMode— represents a single solved eigenmode
The typical workflow is:
# Set up the fibre
fibre = fib.StepIndexFibre(core_radius=250e-9, n_core=2.00, n_clad=1.33)
# Set up the fundamental mode (here with x polarisation)
HE11 = fibre.HE(ell=1, n=1, wl=700e-9, a_plus=1/np.sqrt(2), a_minus=1/np.sqrt(2))
# Construct the grid
x = np.linspace(-2*fibre.core_radius, 2*fibre.core_radius, 100)
y = np.linspace(-2*fibre.core_radius, 2*fibre.core_radius, 100)
X, Y = np.meshgrid(x, y)
# Evaluate the field on the grid
E = mode.E(x=X, y=Y)
StepIndexFibre
Defines the fibre geometry and material parameters and provides dispersion utilities.
Required inputs
core_radius(float in meters orastropy.units.Quantity)- One of:
core,cladasRefractiveIndexMaterialn_core,n_clad(float or callable λ→ε(λ))eps_core,eps_clad(float or callable λ→ε(λ))
Optional inputs
mu_core,mu_clad(float or callable λ→ε(λ))
Example
fibre = fib.StepIndexFibre(core_radius=250e-9, n_core=2.00, n_clad=1.33)
# Or with astropy.units imported as u and with refractiveindex installed:
fibre = fib.StepIndexFibre(
core_radius = 250*u.nm,
core = fib.RefractiveIndexMaterial('main','Si3N4','Luke'),
clad = fib.RefractiveIndexMaterial('main','H2O','Hale'))
Provides
-
Mode constructors for HEℓn , EHℓn , TE0n , and TM0n modes
fibre.HE(ell, n, wl, a_plus=..., a_minus=...) fibre.EH(...) fibre.TE(n, wl, a=...) fibre.TM(...)
Each returns a
GuidedModeobject. -
Dispersion utilities to find V, b, kz , and neff and the dispersion function F for given parameters
fibre.V(wavelength) fibre.b(ell, m, V=..., wavelength=..., mode_type=...) fibre.kz(...) fibre.neff(...) fibre.F(ell, b, V=..., wavelength=..., mode_type=...)
-
Geometry and material properties as attributes
fibre.core_radius fibre.n_core(wavelength) fibre.n_clad(...) fibre.eps_core(...) fibre.eps_clad(...) fibre.mu_core(...) fibre.mu_clad(...)
-
Maximum mode order supported for a given wavelength
fibre.ell_max(wavelength, m=1, mode_type=...) fibre.m_max(ell, wavelength, mode_type=...)
GuidedMode
Represents a guided mode with methods to calculate fields and properties. It is created using StepIndexFibre mode constructors.
Provides
- Field evaluation in (ρ,ϕ,z) or (x,y,z) coordinates, when z is not provided z=0 is assumed
E = mode.E(rho=Rho, phi=Phi, z=Z) H = mode.H(rho=Rho, phi=Phi, z=Z) E = mode.E(x=X, y=Y, z=Z) H = mode.H(x=X, y=Y, z=Z)
Both return arrays with a shape (..., 3) corresponding to the Cartesian vector components. Note that if a grid is passed to the function then it is cached, so subsequent calls with the same grid (for example to get magnetic field) will be much faster.
- Jacobians (gradients) of the fields
J_E = mode.gradE(rho=Rho, phi=Phi, z=Z) J_H = mode.gradH(rho=Rho, phi=Phi, z=Z) J_E = mode.gradE(x=X, y=Y, z=Z) J_H = mode.gradH(x=X, y=Y, z=Z)
Both return arrays with a shape of (..., 3, 3), corresponding to the Cartesian tensor components.
- Power evaluated via numerical integration
P = mode.Power()
Visualisation
The package ships with a built-in plotting utility that creates time-resolved animations of the electromagnetic field in the transverse cross-section of the fibre. There are two options for using it:
- Option A − Passing the mode(s) with weights to the
animate_fields_xyfunction directly:anim = fib.animate_fields_xy( modes=None, # GuidedMode or list[GuidedMode] weights=None, # complex or list[complex] (amplitudes/relative phases), default 1 n_radii=2.0, # grid half-size in units of core radius (when building grid) Np=200, # grid resolution per axis ...)
- Option B − Passing fields with their own ω:
anim = fib.animate_fields_xy( fields=None, # list of tuples (E, H, omega) with E/H phasors on same X,Y grid X=None, Y=None, # grid for Option B (required if fields given) z=0.0, # z-slice to evaluate modes at (ignored if fields given) ...)
Whichever way you choose, the resulting anim object is a standard Matplotlib animation and can be displayed in Jupyter notebooks or saved to file. One can also specify which field components to show (E, H, or both) and figure size instead of ... in the above snippets.
anim = fib.animate_fields_xy(
...,
show=("E", "H"), # any subset of {"E","H"}
n_frames=60, # number of frames in the animation
interval=50, # delay between frames in ms
figsize=(8, 4.5)) # figure size in inches (width, height)
Finally, the animation can be displayed in a Jupyter notebook using the display_anim helper function:
fib.display_anim(anim)
or saved to file using the standard Matplotlib API:
# Save as mp4 (requires ffmpeg)
anim.save("mode_animation.mp4", writer="ffmpeg", fps=30)
# Or as a gif
anim.save("mode_animation.gif", writer="pillow", fps=15)
Citation
If Anafibre contributes to work that you publish, please cite the software and the associated paper:
@misc{anafibre2026,
author = {Golat, Sebastian},
title = {{Anafibre: Analytical mode solver for cylindrical step-index fibres}},
year = {2026},
note = {{Python package}},
url = {https://github.com/Sevastienn/anafibre},
version = {0.1.0}}
@misc{golat2026anafibre,
title = {A robust and efficient method to calculate electromagnetic modes on a cylindrical step-index nanofibre},
author = {Sebastian Golat and Francisco J. Rodríguez-Fortuño},
year = {2026},
eprint = {2602.14930},
archivePrefix = {arXiv},
primaryClass = {physics.optics},
url = {https://arxiv.org/abs/2602.14930}}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file anafibre-0.1.0.tar.gz.
File metadata
- Download URL: anafibre-0.1.0.tar.gz
- Upload date:
- Size: 6.9 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a64f7ab78c2e3e18b906aa4628e80ce68c6c2c068546b646108bceba3662bf1
|
|
| MD5 |
b55134c3e8ef5a6307d6feea948a357b
|
|
| BLAKE2b-256 |
e1c6600cff860911d4edf74dfb978e6fafecf4895f247d7edc99761fe2e8595a
|
File details
Details for the file anafibre-0.1.0-py3-none-any.whl.
File metadata
- Download URL: anafibre-0.1.0-py3-none-any.whl
- Upload date:
- Size: 43.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ae9f9885f0a80626337b5a56d76ab5315890be056ff1828c24def267d5c3e26
|
|
| MD5 |
8a6d53120d963163049e76298555c8fa
|
|
| BLAKE2b-256 |
a1090dfe9dfb523154b92bf5078ff40cae3bc60c189ed3f0098c0fc068fee1f3
|