Skip to content

Chiral slab

A 50 nm slab with permittivity 12.4 + 1i, permeability 1 + 0.1i and chirality parameter 0.5 + 0.05i lies between vacuum below and a medium with permittivity 2 and permeability 2 above. Light comes from the vacuum side at 30 degrees, with k_y = k0 / 2. The chirality makes the slab transmit the two helicities differently, by up to 0.07 in the table. Lengths are in nm; the frequency column is k0 / 2π, the inverse vacuum wavelength in 1/nm.

"""A chiral slab between vacuum and a dense medium: transmission and reflection."""

import numpy as np

import treams_rs as tr

# Enlarge for a full spectrum: treams uses 50 frequencies.
FREQUENCIES = 6

k0s = 2 * np.pi * np.linspace(1 / 1000, 1 / 300, FREQUENCIES)
material = tr.Material(12.4 + 1j, 1 + 0.1j, 0.5 + 0.05j)
thickness = 50

# power[0] holds (T, R) for positive helicity, power[1] for negative helicity.
power = np.zeros((2, FREQUENCIES, 2))
for i, k0 in enumerate(k0s):
    # One direction with k_y = k0 / 2; its channels list positive helicity first.
    ports = tr.PlaneWavePorts.default([0, 0.5 * k0])
    slab = tr.slab(
        k0=k0,
        basis=ports,
        thickness=thickness,
        material=material,
        negative_medium=1,
        positive_medium=tr.Material(2, 2),
    )
    # Amplitudes per channel: light enters from the vacuum side.
    power[0, i] = slab.power([1, 0])
    power[1, i] = slab.power([0, 1])

if __name__ == "__main__":
    print("Transmission T and reflection R for each helicity")
    print(f"{'k0/(2 pi)':>13}{'T+':>13}{'R+':>13}{'T-':>13}{'R-':>13}")
    for k0, (plus, minus) in zip(k0s, power.transpose(1, 0, 2), strict=True):
        values = "".join(f"{v:>13.6g}" for v in (*plus, *minus))
        print(f"{k0 / (2 * np.pi):>13.6g}{values}")
# Source: https://github.com/tfp-photonics/treams/blob/1f5d0d6ebb007288f28bc9e16f6d266e8b55dc39/docs/examples/slab.py
# Adapted: reduced sizes, plotting removed.
# MIT license, copyright Dominik Beutel; see LICENSE.treams.
import numpy as np
import treams

k0s = 2 * np.pi * np.linspace(1 / 1000, 1 / 300, 6)
materials = [(), (12.4 + 1j, 1 + 0.1j, 0.5 + 0.05j), (2, 2)]
thickness = 50
tr = np.zeros((2, len(k0s), 2))
for i, k0 in enumerate(k0s):
    pwb = treams.PlaneWaveBasisByComp.default([0, 0.5 * k0])
    slab = treams.SMatrices.slab(thickness, pwb, k0, materials)
    tr[0, i, :] = slab.tr([1, 0])
    tr[1, i, :] = slab.tr([0, 1])

Output

Transmission T and reflection R for each helicity
    k0/(2 pi)           T+           R+           T-           R-
        0.001     0.279128     0.598877     0.297164     0.598625
   0.00146667     0.224121     0.621188     0.245478     0.621066
   0.00193333     0.244593     0.519387       0.2756     0.519456
       0.0024     0.322132     0.274759     0.373643      0.27504
   0.00286667     0.356154    0.0908653      0.42591    0.0905176
   0.00333333     0.255123     0.264371     0.314296     0.263607

Differences from the treams version

  • slab names the media on both sides: negative_medium below the slab and positive_medium above it. treams takes one list of three materials.
  • SMatrix is the S-matrix of the whole two-port network, which treams calls SMatrices. PlaneWavePorts is treams' PlaneWaveBasisByComp.
  • power(amplitudes) returns the named fractions transmission and reflection, plus absorption; treams' tr returns a pair.
  • The results are called power, because tr names the treams-rs module.