StarCoupler

class awg_designer.all.StarCoupler

The StarCoupler is a combination of the MultiAperture and the free propagation region. The StarCoupler places the MultiAperture cells and generates the free propagation region in between. The CircuitModel view is capable of simulating the full star coupler. This is done by getting the field output of the input apertures, propagating it in the free propagation region, and performing mode overlaps to collect the fields at the output apertures. Set simulation_wavelengths to the desired wavelength grid in order to calculate the physical model for the star coupler at those exact wavelengths. The model will interpolate and extrapolate from those wavelengths. If a single wavelength is specified, the model will be wavelength independent.

Parameters:
aperture_out: PCell, required

(Multi) output aperture

aperture_in: PCell, required

(Multi) input aperture

aperture_out_ports: List with type restriction, allowed types: <class ‘str’>

list of the output aperture port names that are connected to the outside world. The order of this list will determine the numbering of the output ports

aperture_in_ports: List with type restriction, allowed types: <class ‘str’>

List of the input aperture port names that are connected to the outside world. The order of this list will determine the numbering of the input ports

external_port_names: str

Map of the free instance terms/ports to the names of external terms/ports.Format is a dict {‘inst:term’ : ‘new_term_name’}.If a term/port is not listed, the format instname_portname will be used

slab_template: PCell and SlabTemplate

template for free propagation region

name: String that contains only ISO/IEC 8859-1 (extended ASCII py3) or pure ASCII (py2) characters

The unique name of the pcell

Other Parameters:
child_cells: locked
scatterers: locked
apertures: locked
free_propagation_region: PCell and _FreePropagationRegion, locked

unpatterned slab section. This subcomponent is generated automatically to connect elements together.

links: locked
n_outputs: locked

number of output ports

n_inputs: locked

number of input ports

Views

class Layout
Parameters:
hull_stub_width: float and number > 0
hull_growth: float and Real, number and number >= 0
hull_extension: float and Real, number and number >= 0
aperture_out_transformation: GenericNoDistortTransform
aperture_in_transformation: GenericNoDistortTransform
contour: Shape

Contour of the Free propagation Region

flyline_width: float and number > 0

line width of the flylines

flyline_layer: ( __Layer__ ), *None allowed*

layer to draw flylines of physically unconnected links

netlist_view: NetlistView

Netlist view in the same cell on which this Layout is based. Normally no need to manually override.

view_name: String that contains only alphanumeric characters from the ASCII set or contains _$. ASCII set is extended on PY3.

The name of the view

Other Parameters:
scatterer_transformations: locked
aperture_transformations: locked
child_transformations: locked
class SlabFieldModel
Parameters:
layout_view: _LayoutView
n_o_passes: int and number > 0

number of simulation passes

space: _SlabPropagationEngine.Space

Space with all the elements representing the PCell

engine: _SlabPropagationEngine

Slab simulation engine

slab_modes: SlabModeDict

dict of Slab Modes

view_name: String that contains only alphanumeric characters from the ASCII set or contains _$. ASCII set is extended on PY3.

The name of the view

class CircuitModel

Circuit model for the star coupler. Simulates the apertures and the slab region. The CircuitModel of the StarCoupler simulates the following cells:

  • Apertures: the apertures are by default simulated using eigenmode expansion (camfr). See for example, OpenWireWgAperture. The results is a mode profile at the output aperture, and the transmission (amplitude/phase) from the input port to the aperture.

  • Slab region: The slab region is simulated by default using a Rayleigh-Sommerfeld engine. The input is the field profiles from the apertures. Then, RS is used to propagate the fields in the slab. Then, a modal overlap is performed of the fields at the location of the output apertures with the output aperture mode.

Parameters:
simulation_wavelengths: ( list<Real, number and number > 0> ), *None allowed*

Wavelengths for which to simulate the underlying physical model.Defaults to None, in which case a physical simulation will be done for each requested wavelength.If a single wavelength is specified, the model will be wavelength independent.If multiple wavelengths are given, only these wavelengths are valid.

layout_view: ( _LayoutView ), *None allowed*
netlist_view: ( NetlistView ), *None allowed*
view_name: String that contains only alphanumeric characters from the ASCII set or contains _$. ASCII set is extended on PY3.

The name of the view

Other Parameters:
solver: str and String that contains only ISO/IEC 8859-1 (extended ASCII py3) or pure ASCII (py2) characters, locked

circuit solver to use

Examples

import si_fab.all as pdk  # noqa: F401
from ipkiss3 import all as i3
from pysics.basics.environment import Environment
from awg_designer.all import (
    OpenWireWgAperture,
    StarCoupler,
    get_star_coupler_apertures,
    get_star_coupler_extended_contour,
    SimpleSlabMode,
    SlabTemplate,
)
import numpy
import pylab as plt

# Template for the free propagation region
# This defines the layers, slab modes, etc.
slab_t = SlabTemplate()
slab_t.Layout(slab_layers=[i3.PPLayer(i3.TECH.PROCESS.WG, i3.TECH.PURPOSE.DF_AREA)])
slab_t.SlabModes(modes=[SimpleSlabMode(name="TE0", n_eff=2.8, n_g=3.2, polarization="TE")])

# Specify the wavelength of interest
environment = Environment(wavelength=1.55)

# Make an aperture consisting of a transition between two trace templates
ap = OpenWireWgAperture(slab_template=slab_t)
ap_lo = ap.Layout(aperture_core_width=3.0, aperture_edge_width=0.3, transition_length=10.0)
# ap_lo.visualize()

# Get the field profile at the aperture
# this will execute a CAMFR simulation
ap_sm = ap.FieldModelFromCamfr()
f = ap_sm.get_fields(environment=environment)  # noqa:F841
# f.visualize()

# Plot the full field inside the waveguide aperture:
f2d = ap_sm.get_aperture_fields2d(environment=environment)  # noqa:F841
# f2d.visualize()

# Show the far field
ff = ap_sm.get_far_field(environment=environment)
# ff.visualize()

div_angle = ff.divergence_angle()
print("1/e2 divergence angle of aperture mode", div_angle)

# Make a multi-aperture consisting of 16 apertures like these, arranged in a circle,
# and get the transformations of the individual apertures
N = 16
angle = 2 * div_angle  # spread angle
angles = numpy.linspace(-0.5 * angle, 0.5 * angle, N)
radius = ap_lo.width * N / numpy.radians(angle)

apm, _, trans_arms, trans_ports = get_star_coupler_apertures(
    apertures_arms=[ap] * N,
    apertures_ports=[ap],
    angles_arms=angles,
    angles_ports=[0],
    radius=radius,
    mounting="rowland",
    input=True,
)

# Make a star coupler
sc = StarCoupler(aperture_in=ap, aperture_out=apm)

sc_lo = sc.Layout(
    contour=get_star_coupler_extended_contour(
        apertures_in=[ap],
        apertures_out=[ap] * N,
        trans_in=trans_ports,
        trans_out=trans_arms,
        radius_in=radius / 2.0,
        radius_out=radius,
        extension_angles=(10, 10),
    )
)
sc_lo.visualize()

# Circuit Model: Calculate the S-matrix of the star coupler
sc_cm = sc.CircuitModel(simulation_wavelengths=None)
wavelengths = numpy.linspace(1.5, 1.6, 6)
s_matrix = sc_cm.get_smatrix(wavelengths=wavelengths)

# Plot transmission in the outputs
plt.figure()
for i_wl, wl in enumerate(wavelengths):
    t_outputs = [s_matrix["in1", "out{}".format(i)][i_wl] for i in range(1, N + 1)]
    plt.plot(range(1, N + 1), 10 * numpy.log10(numpy.abs(t_outputs)), "o-", label="{}um".format(wl))
plt.xlabel("Output #")
plt.ylabel("Transmission [dB]")
plt.legend()
plt.show()
../../../../../_images/awg_designer-all-StarCoupler-1_00_00.png
../../../../../_images/awg_designer-all-StarCoupler-1_00_01.png
# Full field simulation
sc_sm = sc.SlabFieldModel()
sim = sc_sm.get_field_simulation(environment, "in1", grid=(0.5, 0.5))
sim.run()
sim.monitors["fields"].get_result().visualize(overlays=[sim.space])
../../../../../_images/awg_designer-all-StarCoupler-1_01_00.png