3.1. Modes of antiresonant fibers#

Antiresonant fibers (ARF) are microstructured hollow-core fibers that confine light in an air core using a ring of thin glass capillary tubes. Light of free-space wavelength \(\lambda\) impinging on a capillary wall of thickness \(t\) and index \(n\) is strongly transmitted (and thus lost from the core) at the resonant wavelengths

\[ \lambda_m = \frac{2t}{m}\sqrt{n^2-1}, \qquad m = 1, 2, \ldots, \]

and strongly reflected in the antiresonant windows between them — the ARROW (antiresonant reflecting optical waveguide) mechanism. Since the core is air, such fibers offer low nonlinearity and high damage thresholds; their price is that all core modes are leaky: as in the step-index and Bragg notebooks, propagation constants \(\beta\) are complex, and the confinement loss (CL) in dB/m is computable from \(\operatorname{Im}\beta\).

The ARF class provides the six-capillary geometry of [Poletti (2014)] by default, and the eight-capillary geometry of [Kolyadin et al (2013)] by name='kolyadin'.

import ngsolve as ng
import numpy as np
from ngsolve.webgui import Draw
from fibermode import ARF

Constructing ARF objects#

The constructor builds the geometry and mesh. By default the capillary tubes are embedded into the glass cladding sheath (pass freecapil=True for the unphysical free-standing tubes geometry). Updatable lengths (core radius, capillary radii and thickness, cladding and PML thicknesses) can be overridden by keyword arguments in micrometers.

a = ARF()   # 6-tube Poletti geometry, embedded capillaries
print(a)
  Generating new mesh.
  Refining ARF mesh uniformly 0 times: each element split into four
  Elements/wavelength revised:3 (capillary), 0.48 (air), 1.2 (inner core)
  Elements/wavelength revised: 0.363636 (glass), 0.06 (outer)
ModeSolver: Checking if mesh has required regions
Mesh has  9948  elements,  4987  points,  and  14934  edges.
ARF Physical Parameters:
  Rc = 1 x 15 x 1e-6 meters
  tclad = 0.666667 x 15 x 1e-6 meters
  touter = 3.33333 x 15 x 1e-6 meters
  t = 0.028 x 15 x 1e-6 meters
  d = 0.14 x 15 x 1e-6 meters
  Rti = 12.48 x 15 x 1e-6 meters
  Rto = 12.9 x 15 x 1e-6 meters
  Wavelength = 1.8e-06 meters
  Refractive indices: 1.00028 (air), 1.44087 (Si)
Nondimensional Computational Parameters:
  Divide all lengths above by 15 x 1e-6
  to get the actual computational lengths used.
  Cladding starts at Rcladi = 2.71833
  PML starts at R = 4.05167 and ends at Rout = 7.385
  Mesh sizes: 0.04 (capillary), 0.25 (air), 0.1 (inner core)
  Mesh sizes: 0.33 (glass), 2 (outer)
  Elements/wavelength:3 (capillary), 0.48 (air), 1.2 (inner core)
  Elements/wavelength: 0.363636 (glass), 0.06 (outer)
  With embedded capillaries, e/t = 0.0595238.
Draw(a.mesh);

The operating wavelength is an attribute (1800 nm by default for this geometry); resetting it updates the nondimensional material coefficients automatically.

a.wavelength
1.8e-06

The constructor of ARF takes many more arguments, including a generic **kwargs, so your best bet to find out how to tweak the geometry defaults is by following the constructor’s docstring comments, which you can view using ARF.__init__?.

Computing leaky modes#

As in the Bragg fiber notebook, we use the FEAST eigensolver together with a frequency-dependent PML, which poses the leaky mode problem as a polynomial eigenproblem in the nondimensional resonance value \(Z\) (not \(Z^2\)). The contour below encloses the \(Z\)-value of the LP01-like fundamental core mode of this geometry.

p = 2       # finite element degree
Z, y, yl, beta, P, extras = a.leakymode(
    p,
    ctr=2.24,       # contour center in the Z-plane
    rad=0.02,       # contour radius
    alpha=5,        # PML strength
    nspan=4,
    npts=4,
    seed=1,
    niterations=50,
    nrestarts=0,
)
ModeSolver.leakymode called on object with these settings:
 ARF Physical Parameters:
  Rc = 1 x 15 x 1e-6 meters
  tclad = 0.666667 x 15 x 1e-6 meters
  touter = 3.33333 x 15 x 1e-6 meters
  t = 0.028 x 15 x 1e-6 meters
  d = 0.14 x 15 x 1e-6 meters
  Rti = 12.48 x 15 x 1e-6 meters
  Rto = 12.9 x 15 x 1e-6 meters
  Wavelength = 1.8e-06 meters
  Refractive indices: 1.00028 (air), 1.44087 (Si)
Nondimensional Computational Parameters:
  Divide all lengths above by 15 x 1e-6
  to get the actual computational lengths used.
  Cladding starts at Rcladi = 2.71833
  PML starts at R = 4.05167 and ends at Rout = 7.385
  Mesh sizes: 0.04 (capillary), 0.25 (air), 0.1 (inner core)
  Mesh sizes: 0.33 (glass), 2 (outer)
  Elements/wavelength:3 (capillary), 0.48 (air), 1.2 (inner core)
  Elements/wavelength: 0.363636 (glass), 0.06 (outer)
  With embedded capillaries, e/t = 0.0595238.
Set freq-dependent PML with p= 2  alpha= 5 and thickness=3.333

SpectralProj: Setting shifted trapezoidal rule quadrature on circular contour
SpectralProj: Radius=0.02, Center=2.24+0j
SpectralProjNGPoly: Checking if A[d] is nonzero & Hermitian.
SpectralProjNG: Checking if inverse.H works for umfpack
SpectralProjNGPoly: Computing resolvents along the contour using
                    inverse type umfpack (installed default umfpack)
SpectralProjNGPoly: Factorizing 19921x19921 system at z =  +2.254 +0.014j
SpectralProjNGPoly: Factorizing 19921x19921 system at z =  +2.226 +0.014j
SpectralProjNGPoly: Factorizing 19921x19921 system at z =  +2.226 -0.014j
SpectralProjNGPoly: Factorizing 19921x19921 system at z =  +2.254 -0.014j

=========== Starting FEAST iterations ===========
Trying with 4 vectors:

 ITERATION 1 with 4 vectors and 4 left vectors
   During kernel cleaning singular values of B-Gram:
   [3.939e+02 1.464e-05 1.505e-11 9.858e-13]
   Removing ew#[2, 3]
   Real part of computed eigenvalues:
   [2.24773208 2.32266722]
   Imag part of computed eigenvalues:
   [-6.85397287e-09 -1.40374758e-04]
   Relative Hausdorff distance from prior iterate: 4.464e+99

 ITERATION 2 with 2 vectors and 2 left vectors
   During kernel cleaning singular values of B-Gram:
   [9.568e-01 1.166e-05]
   Real part of computed eigenvalues:
   [2.24773208 2.32266713]
   Imag part of computed eigenvalues:
   [-6.85404708e-09 -1.40541248e-04]
   Relative Hausdorff distance from prior iterate: 8.509e-08

 ITERATION 3 with 2 vectors and 2 left vectors
   During kernel cleaning singular values of B-Gram:
   [9.568e-01 1.166e-05]
   Real part of computed eigenvalues:
   [2.24773208 2.32266713]
   Imag part of computed eigenvalues:
   [-6.85404716e-09 -1.40541248e-04]
   Relative Hausdorff distance from prior iterate: 7.433e-14

   Removing ew#[1] not enclosed by contour

***FEAST converged with:
	Relative Hausdorff distance = 7.433e-14

============= FEAST iterations done =============
   Normalizing by M-norms: max=3.0e-01, min=3.0e-01
   Normalizing by M-norms: max=3.6e+01, min=3.6e+01
Results:
 Z: [2.24773208-6.85404716e-09j]
 beta: [3488409.02531372+1.9628256e-05j]
 CL dB/m: [0.00017049]
Mode boundary L² norm = 2.4e-08

The physical propagation constants and confinement loss follow from the computed \(Z\):

print('beta      =', beta)
print('CL [dB/m] =', 20 * beta.imag / np.log(10))
beta      = [3488409.02531372+1.9628256e-05j]
CL [dB/m] = [0.00017049]

The fundamental mode intensity is concentrated in the hollow core, shielded by the capillary ring:

Draw(ng.Norm(y.gridfun())**2, a.mesh);

Higher-order core modes#

For this geometry at 1800 nm, the following contour centers (radius 0.02) capture the labeled mode groups:

Mode

\(Z\)-center

LP01

2.24

LP11

3.57

LP21

4.75

LP02

5.09

For example, the LP11-like mode group:

Z11, y11, yl11, beta11, P11, _ = a.leakymode(
    p, ctr=3.57, rad=0.02, alpha=5, nspan=4, npts=4,
    seed=1, niterations=50, nrestarts=0)
print('CL [dB/m] =', 20 * beta11.imag / np.log(10))
ModeSolver.leakymode called on object with these settings:
 ARF Physical Parameters:
  Rc = 1 x 15 x 1e-6 meters
  tclad = 0.666667 x 15 x 1e-6 meters
  touter = 3.33333 x 15 x 1e-6 meters
  t = 0.028 x 15 x 1e-6 meters
  d = 0.14 x 15 x 1e-6 meters
  Rti = 12.48 x 15 x 1e-6 meters
  Rto = 12.9 x 15 x 1e-6 meters
  Wavelength = 1.8e-06 meters
  Refractive indices: 1.00028 (air), 1.44087 (Si)
Nondimensional Computational Parameters:
  Divide all lengths above by 15 x 1e-6
  to get the actual computational lengths used.
  Cladding starts at Rcladi = 2.71833
  PML starts at R = 4.05167 and ends at Rout = 7.385
  Mesh sizes: 0.04 (capillary), 0.25 (air), 0.1 (inner core)
  Mesh sizes: 0.33 (glass), 2 (outer)
  Elements/wavelength:3 (capillary), 0.48 (air), 1.2 (inner core)
  Elements/wavelength: 0.363636 (glass), 0.06 (outer)
  With embedded capillaries, e/t = 0.0595238.
Set freq-dependent PML with p= 2  alpha= 5 and thickness=3.333

SpectralProj: Setting shifted trapezoidal rule quadrature on circular contour
SpectralProj: Radius=0.02, Center=3.57+0j
SpectralProjNGPoly: Checking if A[d] is nonzero & Hermitian.
SpectralProjNG: Checking if inverse.H works for umfpack
SpectralProjNGPoly: Computing resolvents along the contour using
                    inverse type umfpack (installed default umfpack)
SpectralProjNGPoly: Factorizing 19921x19921 system at z =  +3.584 +0.014j
SpectralProjNGPoly: Factorizing 19921x19921 system at z =  +3.556 +0.014j
SpectralProjNGPoly: Factorizing 19921x19921 system at z =  +3.556 -0.014j
SpectralProjNGPoly: Factorizing 19921x19921 system at z =  +3.584 -0.014j

=========== Starting FEAST iterations ===========
Trying with 4 vectors:

 ITERATION 1 with 4 vectors and 4 left vectors
   During kernel cleaning singular values of B-Gram:
   [6.233e-01 1.318e-01 1.449e-10 9.184e-12]
   Removing ew#[2, 3]
   Real part of computed eigenvalues:
   [3.56737582 3.56747277]
   Imag part of computed eigenvalues:
   [-8.94468459e-08 -1.52842527e-07]
   Relative Hausdorff distance from prior iterate: 2.801e+99

 ITERATION 2 with 2 vectors and 2 left vectors
   During kernel cleaning singular values of B-Gram:
   [0.98 0.98]
   Real part of computed eigenvalues:
   [3.56737582 3.56747278]
   Imag part of computed eigenvalues:
   [-8.87658655e-08 -1.53190807e-07]
   Relative Hausdorff distance from prior iterate: 4.161e-10


***FEAST converged with:
	Relative Hausdorff distance = 4.161e-10

============= FEAST iterations done =============
   Normalizing by M-norms: max=5.3e-07, min=7.0e-08
   Normalizing by M-norms: max=3.1e-02, min=1.4e-03
Results:
 Z: [3.56747278-1.53190807e-07j 3.56737582-8.87658655e-08j]
 beta: [3483516.66584703+0.00069726j 3483517.10714719+0.00040401j]
 CL dB/m: [0.0060563 0.0035092]
Mode boundary L² norm = 1.2e-06
*** Mode boundary L2 norm > 1e-6!
PML decay estimates boundary norm ~ 1.1e-06
CL [dB/m] = [0.0060563 0.0035092]
Draw(ng.Norm(y11.gridfun())**2, a.mesh);

Note how much lossier the higher-order modes are than the fundamental: this differential loss is exactly what makes ARFs behave as effectively single-mode fibers over long lengths.

Cross-checking with other formulations#

The same modes can be computed by the standard frequency-independent PML, which yields a linear eigenproblem in \(Z^2\) (so contour parameters must be specified in the \(Z^2\)-plane — a factor worth double-checking whenever results look off):

zsqr, Y2, Yl2, beta2, P2 = a.leakymode_auto(
    p, centerZ2=2.24**2, radiusZ2=0.1, alpha=5,
    npts=4, nspan=4, seed=1, niterations=50, nrestarts=0)
print('beta (auto PML) =', beta2)
ModeSolver.leakymode called on object with these settings:
 ARF Physical Parameters:
  Rc = 1 x 15 x 1e-6 meters
  tclad = 0.666667 x 15 x 1e-6 meters
  touter = 3.33333 x 15 x 1e-6 meters
  t = 0.028 x 15 x 1e-6 meters
  d = 0.14 x 15 x 1e-6 meters
  Rti = 12.48 x 15 x 1e-6 meters
  Rto = 12.9 x 15 x 1e-6 meters
  Wavelength = 1.8e-06 meters
  Refractive indices: 1.00028 (air), 1.44087 (Si)
Nondimensional Computational Parameters:
  Divide all lengths above by 15 x 1e-6
  to get the actual computational lengths used.
  Cladding starts at Rcladi = 2.71833
  PML starts at R = 4.05167 and ends at Rout = 7.385
  Mesh sizes: 0.04 (capillary), 0.25 (air), 0.1 (inner core)
  Mesh sizes: 0.33 (glass), 2 (outer)
  Elements/wavelength:3 (capillary), 0.48 (air), 1.2 (inner core)
  Elements/wavelength: 0.363636 (glass), 0.06 (outer)
  With embedded capillaries, e/t = 0.0595238.
Set NGSolve automatic PML with p= 2  alpha= 5 and thickness=3.333

SpectralProj: Setting shifted trapezoidal rule quadrature on circular contour
SpectralProj: Radius=0.1, Center=5.0176+0j

SpectralProjNG: Computing resolvents using umfpack
SpectralProjNG:   Factorizing at z =  +5.088 +0.071j
SpectralProjNG:   Factorizing at z =  +4.947 +0.071j
SpectralProjNG:   Factorizing at z =  +4.947 -0.071j
SpectralProjNG:   Factorizing at z =  +5.088 -0.071j
=========== Starting FEAST iterations ===========
Trying with 4 vectors:

 ITERATION 1 with 4 vectors and 4 left vectors
   During kernel cleaning singular values of B-Gram:
   [3.134e+00 5.204e-11 1.692e-12 1.009e-12]
   Removing ew#[1, 2, 3]
   Real part of computed eigenvalues:
   [5.05233313]
   Imag part of computed eigenvalues:
   [-2.70613006e-08]
   Relative Hausdorff distance from prior iterate: 1.993e+99

 ITERATION 2 with 1 vectors and 1 left vectors
   During kernel cleaning singular values of B-Gram:
   [0.972]
   Real part of computed eigenvalues:
   [5.05233313]
   Imag part of computed eigenvalues:
   [-2.71014803e-08]
   Relative Hausdorff distance from prior iterate: 2.004e-11


***FEAST converged with:
	Relative Hausdorff distance = 2.004e-11

============= FEAST iterations done =============
Results:
 Z²: [5.05233313-2.71014803e-08j]
 beta: [3488409.00389219+1.7264464e-05j]
 CL dB/m: [0.00014996]
Mode boundary L² norm = 4.2e-07
beta (auto PML) = [3488409.00389219+1.7264464e-05j]

Agreement of beta between the two formulations (to a tolerance consistent with the discretization) is a useful sanity check, since the two solvers use different PMLs and different eigensolver linearizations.

The eight-capillary fiber of Kolyadin et al#

The name='kolyadin' geometry has eight, larger, capillaries. For finite element degrees \(p \geq 3\), refine the mesh at least once, and use the mode table from demos/arf/arf_kolyadin_mode.py (LP01 at \(Z \approx 2.29\)):

b = ARF(name='kolyadin', 
        capillary_maxhs=0.2, 
        freecapil=False)
b.refine()
Draw(b.mesh);
  Generating new mesh.
  Refining ARF mesh uniformly 0 times: each element split into four
  Elements/wavelength revised:0.483193 (capillary), 0.483193 (air), 0.966387 (inner core)
  Elements/wavelength revised: 0.241597 (glass), 0.193277 (outer)
ModeSolver: Checking if mesh has required regions
Mesh has  1703  elements,  880  points,  and  2582  edges.
  Refining ARF mesh uniformly 1 times: each element split into four
  Elements/wavelength revised:0.966387 (capillary), 0.966387 (air), 1.93277 (inner core)
  Elements/wavelength revised: 0.483193 (glass), 0.386555 (outer)
Zk, yk, ylk, betak, Pk, _ = b.leakymode(
    3, ctr=2.29, rad=0.02, alpha=5, nspan=4, npts=4,
    seed=1, niterations=50, nrestarts=0)
k = 2 * np.pi / b.wavelength
print('effective index =', betak / k)
ModeSolver.leakymode called on object with these settings:
 ARF Physical Parameters:
  Rc = 1 x 59.5 x 1e-6 meters
  tclad = 0.514286 x 59.5 x 1e-6 meters
  touter = 1.68067 x 59.5 x 1e-6 meters
  t = 0.10084 x 59.5 x 1e-6 meters
  d = 0.111738 x 59.5 x 1e-6 meters
  Rti = 25.5 x 59.5 x 1e-6 meters
  Rto = 31.5 x 59.5 x 1e-6 meters
  Wavelength = 5.75e-06 meters
  Refractive indices: 1.00028 (air), 1.28334 (Si)
Nondimensional Computational Parameters:
  Divide all lengths above by 59.5 x 1e-6
  to get the actual computational lengths used.
  Cladding starts at Rcladi = 2.02521
  PML starts at R = 3.05378 and ends at Rout = 4.73445
  Mesh sizes: 0.2 (capillary), 0.2 (air), 0.1 (inner core)
  Mesh sizes: 0.4 (glass), 0.5 (outer)
  Elements/wavelength:0.966387 (capillary), 0.966387 (air), 1.93277 (inner core)
  Elements/wavelength: 0.483193 (glass), 0.386555 (outer)
  Uniformly refined 1 times.
  With embedded capillaries, e/t = 0.333333.
Set freq-dependent PML with p= 3  alpha= 5 and thickness=1.681

SpectralProj: Setting shifted trapezoidal rule quadrature on circular contour
SpectralProj: Radius=0.02, Center=2.29+0j
SpectralProjNGPoly: Checking if A[d] is nonzero & Hermitian.
SpectralProjNG: Checking if inverse.H works for umfpack
SpectralProjNGPoly: Computing resolvents along the contour using
                    inverse type umfpack (installed default umfpack)
SpectralProjNGPoly: Factorizing 30820x30820 system at z =  +2.304 +0.014j
SpectralProjNGPoly: Factorizing 30820x30820 system at z =  +2.276 +0.014j
SpectralProjNGPoly: Factorizing 30820x30820 system at z =  +2.276 -0.014j
SpectralProjNGPoly: Factorizing 30820x30820 system at z =  +2.304 -0.014j
=========== Starting FEAST iterations ===========
Trying with 4 vectors:

 ITERATION 1 with 4 vectors and 4 left vectors
   During kernel cleaning singular values of B-Gram:
   [5.674e+01 2.180e-06 7.004e-12 3.542e-13]
   Removing ew#[2, 3]
   Real part of computed eigenvalues:
   [2.15628841 2.26081281]
   Imag part of computed eigenvalues:
   [-1.86022137e-02 -1.75367516e-06]
   Relative Hausdorff distance from prior iterate: 4.367e+99

 ITERATION 2 with 2 vectors and 2 left vectors
   During kernel cleaning singular values of B-Gram:
   [3.263e-02 2.318e-07]
   Real part of computed eigenvalues:
   [2.15628732 2.26081281]
   Imag part of computed eigenvalues:
   [-1.86035005e-02 -1.75368041e-06]
   Relative Hausdorff distance from prior iterate: 7.383e-07

 ITERATION 3 with 2 vectors and 2 left vectors
   During kernel cleaning singular values of B-Gram:
   [3.263e-02 2.318e-07]
   Real part of computed eigenvalues:
   [2.15628732 2.26081281]
   Imag part of computed eigenvalues:
   [-1.86035005e-02 -1.75368041e-06]
   Relative Hausdorff distance from prior iterate: 1.160e-12


***FEAST converged with:
	Relative Hausdorff distance = 1.160e-12

============= FEAST iterations done =============
   Normalizing by M-norms: max=2.1e+00, min=3.1e-01
   Normalizing by M-norms: max=5.8e+03, min=1.3e+02
Results:
 Z: [2.26081281-1.75368041e-06j 2.15628732-1.86035005e-02j]
 beta: [1092370.11195761+1.02520641e-03j 1092429.84843661+1.03722699e+01j]
 CL dB/m: [8.90482978e-03 9.00923919e+01]
Mode boundary L² norm = 4.2e-07
effective index = [0.99967259+9.38208345e-10j 0.99972726+9.49208867e-06j]
Draw(ng.Norm(yk.gridfun())**2, b.mesh);

References#

  • F. Poletti. Nested antiresonant nodeless hollow core fiber. Optics Express, 22:23807-23828, 2014.

  • A. D. Kolyadin, A. F. Kosolapov, A. D. Pryamikov, A. S. Biriukov, V. G. Plotnichenko, and E. M. Dianov. Light transmission in negative curvature hollow core fiber in extremely high material loss region. Optics Express, 21:9514-9519, 2013.

  • W. Belardi and J. C. Knight. Hollow antiresonant fibers with reduced attenuation. Optics Letters, 39:1853-1856, 2014.