# Physical device simulation¶

An important aspect in the photonics design flow is the ability to run physical simulations of (electro-)optical devices. Typical use cases are device exploration and optimizing a component for certain specifications (for example, maximal transmission, reflection below a certain dB).

In IPKISS we start from an IPKISS Component to automatically drive a simulation in a third-party simulation tool. This has the big benefit that we don’t have to rebuild the component manually in the third party tool, saving us time and reducing translation errors. In addition, Python allows another layer of automation, which means it becomes easy to perform sweeps / optimizations of these devices.

## General concept¶

The concept of the IPKISS device simulation flow is depicted below:

First, you define the simulation specifications, which consist of 3 parts:

1. The simulation geometry, defined by the layout, a virtual fabrication process, and simulation-specific settings.
2. The expected outputs (results) of the simulation, e.g. S Parameters.
3. Solver-specific settings and commands, for using the full power of the solver you want to use.

From this complete specification, IPKISS generates the input to the solver in an automated way and uses that to drive the solver. The solver generates the requested results and IPKISS ensures this output can be used further. Finally, you can use the results to generate or improve circuit models. For instance, you could fit an interpolating model to the discrete S-parameter data returned by an FDTD solver.

## API example¶

Note

All samples are available in your sample directory, under <USER_HOME_FOLDER>\luceda\samples\<IPKISS_VERSION>\samples\device_sim.

The generic workflow is the following: you start from a layout cell in IPKISS:

crossing = Crossing()
lay = crossing.Layout()


From this layout we create a simulation geometry:

sim_geom = i3.device_sim.SimulationGeometry(layout=lay)


Then, we define the outputs that we want to retrieve. For example, to do a SMatrix sweep, you can define this as follows:

output = [i3.device_sim.SMatrixOutput(name='smatrix', wavelength_range=(1.5, 1.6, 101))]


Now you can define a simulation job, which combines all information and provides routines to interact with the solvers:

# i3.device_sim.CSTTDSimulation / i3.device_sim.LumericalFDTDSimulation supported.
simulation_job = i3.device_sim.CSTTDSimulation(
geometry=sim_geom,
outputs=outputs
)

# 'inspect': this will launch the tool itself, so you can check if everything is set up properly.
simulation_job.inspect()

# 'get_result': retrieve results from the tool
S = simulation_job.get_result(name='smatrix')


## Supported tools¶

Below we link to more in-depth tutorials for the tools that we support:

CST Studio Suite Lumerical FDTD Solutions