Examples using RCWA

These examples can all be found in the examples folder in the main rcwa package on github.

Bragg Mirror Reflection Spectra

# Author: Jordan Edmunds, Ph.D. Student, UC Berkeley
# Contact: jordan.e@berkeley.edu
# Creation Date: 11/01/2019
#
from rcwa import Layer, LayerStack, Source, Solver, Plotter
import numpy as np
from matplotlib import pyplot as plt

def solve_system():
    designWavelength = 1.3
    startWavelength = 0.6
    stopWavelength = 2.2
    stepWavelength = 0.005

    n1 = 3.5 # refractive index of layer 1 (Si)
    n2 = 1.45 # refractive index of layer 2 (SiO2)
    t1 = designWavelength/4/n1
    t2 = designWavelength/4/n2

    reflectionLayer = Layer(n=1)
    transmissionLayer = Layer(n=n1)
    layer0 = Layer(n=n1, thickness=t1)
    layer1 = Layer(n=n2, thickness=t2)
    layer2 = Layer(n=n1, thickness=t1)
    layer3 = Layer(n=n2, thickness=t2)
    layer4 = Layer(n=n1, thickness=t1)
    layer5 = Layer(n=n2, thickness=t2)
    layer6 = Layer(n=n1, thickness=t1)
    layer7 = Layer(n=n2, thickness=t2)
    layer8 = Layer(n=n1, thickness=t1)
    layer9 = Layer(n=n2, thickness=t2)
    layer10 = Layer(n=n1, thickness=t1)
    stack = LayerStack(layer0, layer1, layer2, layer3, layer4, layer5, layer6, layer7, layer8, layer9, layer10,
                       incident_layer=reflectionLayer, transmission_layer=transmissionLayer)
    source = Source(wavelength=designWavelength)

    print("Solving system...")
    TMMSolver = Solver(stack, source, 1)
    wavelengths = np.arange(startWavelength, stopWavelength + stepWavelength,
            stepWavelength)

    results = TMMSolver.solve(wavelength=wavelengths)
    return results


if __name__ == '__main__':
    results = solve_system()
    fig, ax = results.plot(x='wavelength', y=['RTot', 'TTot', 'conservation'])
    plt.show()

Reflection from a Dispersive Interface (Silicon)

# Author: Jordan Edmunds, Ph.D. Student, UC Berkeley
# Contact: jordan.e@berkeley.edu
# Creation Date: 11/01/2019
#
from rcwa import Material, Layer, LayerStack, Source, Solver, Plotter

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt

def solve_system():
        startWavelength = 0.25
        stopWavelength = 0.8
        stepWavelength = 0.001

        # Setup the source
        source = Source(wavelength=startWavelength)

        # Setup the materials and geometry
        si = Material(name='Si')

        # Setup the interface
        reflectionLayer = Layer(n=1) # Free space
        transmissionLayer = Layer(material=si)
        stack = LayerStack(incident_layer=reflectionLayer, transmission_layer=transmissionLayer)

        # Setup the solver
        TMMSolver = Solver(stack, source, (1, 1))

        # Setup and run the sweep
        wavelengths = np.arange(startWavelength, stopWavelength + stepWavelength,
                stepWavelength)
        results = TMMSolver.solve(wavelength=wavelengths)
        return results


if __name__ == '__main__':
        results = solve_system()
        results.plot(x='wavelength', y=['RTot', 'TTot', 'conservation'])
        plt.show()

Reflection from a Dispersive Interface (SiO2)

# Author: Jordan Edmunds, Ph.D. Student, UC Berkeley
# Contact: jordan.e@berkeley.edu
# Creation Date: 11/01/2019
#
from rcwa import Material, Layer, LayerStack, Source, Solver, Plotter
import numpy as np
from matplotlib import pyplot as plt

def solve_system():
        startWavelength = 0.25
        stopWavelength = 0.85
        stepWavelength = 0.001

        source = Source(wavelength=startWavelength)
        siO2 = Material('SiO2')

        reflectionLayer = Layer(n=1) # Free space
        transmissionLayer = Layer(material=siO2)
        stack = LayerStack(incident_layer=reflectionLayer, transmission_layer=transmissionLayer)

        TMMSolver = Solver(stack, source, (1, 1))
        wavelengths = np.arange(startWavelength, stopWavelength + stepWavelength,
                stepWavelength)

        results = TMMSolver.solve(wavelength=wavelengths)
        return results


if __name__ == '__main__':
        results = solve_system()
        fig, ax = results.plot(x='wavelength', y=['RTot', 'TTot', 'conservation'])
        plt.show()

Ellipsometry of bare Si wafer [BROKEN]

# Author: Jordan Edmunds, Ph.D. Student, UC Berkeley
# Contact: jordan.e@berkeley.edu
# Creation Date: 11/01/2019
#
from rcwa import Material, Layer, LayerStack, Source, Solver, Plotter
import numpy as np
from matplotlib import pyplot as plt

def solve_system():
        startWavelength = 0.25
        stopWavelength = 0.850
        stepWavelength = 0.001
        incident_angle = np.radians(75)

        source = Source(wavelength=startWavelength, theta=incident_angle)
        si = Material('Si')

        reflectionLayer = Layer(n=1) # Free space
        transmissionLayer = Layer(material=si)
        stack = LayerStack(incident_layer=reflectionLayer, transmission_layer=transmissionLayer)

        TMMSolver = Solver(stack, source)
        wavelengths = np.arange(startWavelength, stopWavelength + stepWavelength,
                stepWavelength)

        TMMSolver.solve(wavelength=wavelengths)

        tan_psi_predicted = TMMSolver.results['tanPsi']
        cos_delta_predicted = TMMSolver.results['cosDelta']

        fig, ax = plt.subplots()
        ax.plot(wavelengths, tan_psi_predicted)
        ax.plot(wavelengths, cos_delta_predicted)
        ax.legend([r'$Tan(\Psi)$', r'$Cos(\Delta)$'])

        return fig, ax


if __name__ == '__main__':
        fig, ax = solve_system()
        plt.show()

Rectangular Lattice Photonic Crystal with Triangular Shape

from rcwa import Source, Layer, LayerStack, Crystal, Solver, example_dir
from rcwa.shorthand import complexArray
import numpy as np
import os


def solve_system():
    data_path = os.path.join(example_dir, 'triangleData.csv')
    devicePermittivityCellData = np.transpose(np.loadtxt(data_path, delimiter=','))
    devicePermeabilityCellData = 1 + 0 * devicePermittivityCellData

    reflectionLayer = Layer(er=2.0, ur=1.0)
    transmissionLayer = Layer(er=9.0, ur=1.0)

    wavelength = 2
    deg = np.pi / 180
    k0 = 2*np.pi/wavelength
    theta = 60 * deg
    phi = 30*deg
    pTEM = 1/np.sqrt(2)*complexArray([1,1j])
    source = Source(wavelength=wavelength, theta=theta, phi=phi, pTEM=pTEM, layer=reflectionLayer)
    t1, t2 = complexArray([1.75, 0, 0]), complexArray([0, 1.5, 0])

    crystalThickness = 0.5

    numberHarmonics = (3, 3)

    deviceCrystal = Crystal(t1, t2, er=devicePermittivityCellData, ur=devicePermeabilityCellData)
    layer1 = Layer(crystal=deviceCrystal, thickness=crystalThickness)
    layerStack = LayerStack(layer1, incident_layer=reflectionLayer, transmission_layer=transmissionLayer)

    rcwa_solver = Solver(layerStack, source, numberHarmonics)
    results = rcwa_solver.solve()
    return results


if __name__ == '__main__':
    results = solve_system()
    # Get the amplitude reflection and transmission coefficients
    (rxCalculated, ryCalculated, rzCalculated) = (results['rx'], results['ry'], results['rz'])
    (txCalculated, tyCalculated, tzCalculated) = (results['tx'], results['ty'], results['tz'])

    # Get the diffraction efficiencies R and T and overall reflection and transmission coefficients R and T
    (R, T, RTot, TTot) = (results['R'], results['T'], results['RTot'], results['TTot'])
    print(RTot, TTot, RTot + TTot)

Rectangular Diffraction Grating

from rcwa import Source, Layer, LayerStack, Crystal, Solver, RectangularGrating
from rcwa.shorthand import complexArray
import numpy as np


def solve_system():

    reflection_layer = Layer(er=1.0, ur=1.0)
    transmission_layer = Layer(er=9.0, ur=1.0)

    wavelength = 0.5
    deg = np.pi / 180
    k0 = 2*np.pi/wavelength
    theta = 60 * deg
    phi = 1*deg
    pTEM = 1/np.sqrt(2)*complexArray([1,1j])
    source = Source(wavelength=wavelength, theta=theta, phi=phi, pTEM=pTEM, layer=reflection_layer)

    crystal_thickness = 0.5

    N_harmonics = 11

    grating_layer = RectangularGrating(period=2, thickness=0.5, n=4, n_void=1, nx=500)
    layer_stack = LayerStack(grating_layer, incident_layer=reflection_layer, transmission_layer=transmission_layer)

    solver_1d = Solver(layer_stack, source, N_harmonics)
    results = solver_1d.solve()

    return results

if __name__ == '__main__':
    results = solve_system()

    # Get the amplitude reflection and transmission coefficients
    (rxCalculated, ryCalculated, rzCalculated) = (results['rx'], results['ry'], results['rz'])
    (txCalculated, tyCalculated, tzCalculated) = (results['tx'], results['ty'], results['tz'])

    # Get the diffraction efficiencies R and T and overall reflection and transmission coefficients R and T
    (R, T, RTot, TTot) = (results['R'], results['T'], results['RTot'], results['TTot'])
    print(RTot, TTot, RTot+TTot)