<jupyter_start><jupyter_text>FDTD Lumericalgdsfactory provides you with a Lumerical FDTD interface to calculate Sparameters automatically  (without you having to click around the Lumerical GUI)The function `gdsfactory.simulation.lumerical.write_sparameters_lumerical` brings up a GUI, runs simulation and then writes the Sparameters both in .CSV and .DAT (Lumerical interconnect / simphony) file formats, as well as the simulation settings in YAML format.In the CSV format each Sparameter will have 2 columns, `s12m` where `m` stands for magnitude and `s12a` where `a` stands for angle in radians.For the simulation to wor well, your components need to have ports, that will be extended automatically to go over the PML.![lum GUI](https://i.imgur.com/dHAzZRw.png)The script calls internally the lumerical python API `lumapi` so you will need to make sure that you can run this from python.```pythonimport lumapisession = luampi.FDTD()```In linux that may require you to export the PYTHONPATH variable in your shell environment.You can add one line into your `.bashrc` in your Linux machine. ```bash[ -d "/opt/lumerical" ] && export PATH=$PATH:/opt/lumerical/$(ls /opt/lumerical)/bin && export PYTHONPATH=/opt/lumerical/$(ls /opt/lumerical)/api/python```Finally, You can chain the Sparameters to calculate solve of larger circuits using a circuit solver such as:- Lumerical interconnect- [simphony (open source)](https://simphonyphotonics.readthedocs.io/en/latest/)- [sax (open source)](https://sax.readthedocs.io/en/latest/index.html)<jupyter_code>import gdsfactory as gf
import gdsfactory.simulation.lumerical as sim

gf.tech.SIMULATION_SETTINGS
sim.write_sparameters_lumerical?
# NBVAL_SKIP
import gdsfactory as gf
import gdsfactory.simulation.lumerical as sim
import lumapi

s = lumapi.FDTD()
gf.components.factory.keys()
components = [
    "bend_euler",
    "bend_s",
    "coupler",
    "coupler_ring",
    "crossing",
    "mmi1x2",
    "mmi2x2",
    "taper",
    "straight",
]
need_review = []

for component_name in components:
    component = gf.components.factory[component_name]()
    sim.write_sparameters_lumerical(component, run=False, session=s)
    response = input(f"does the simulation for {component_name} look good? (y/n)")
    if response.upper()[0] == "N":
        need_review.append(componnent_name)<jupyter_output><empty_output><jupyter_text>Modify layer stackAll layers information is passed to the Lumerical simulator through the layer_stack Layer thicknessYou can modify the thickness of any specific layer of the stack. For example lets increase the core thickness to `230 nm`<jupyter_code>from gdsfactory.tech import LAYER_STACK
LAYER_STACK
layer_stack2 = LAYER_STACK
nm = 1e-3
layer_stack2['core'].thickness = 230 * nm
layer_stack2['core'].thickness
sim.write_sparameters_lumerical(gf.components.mmi1x2(), layer_stack=layer_stack2, run=False, session=s)<jupyter_output><empty_output><jupyter_text>You will be able to see the layer thickness increase in the lumerical GUI![thickness](https://i.imgur.com/Hxe7BuC.png)  Layer material or indexYou can also modify the material refractive index or material name from the Lumerical Material database<jupyter_code>LAYER_STACK
material_name_to_lumerical = dict(si=3.6) 

sim.write_sparameters_lumerical(gf.components.mmi1x2(), layer_stack=layer_stack2, run=False, session=s, material_name_to_lumerical=material_name_to_lumerical)<jupyter_output><empty_output><jupyter_text>![stack](https://i.imgur.com/ywfnH6h.png)<jupyter_code>material_name_to_lumerical = dict(si='InP - Palik') 

sim.write_sparameters_lumerical(gf.components.mmi1x2(), layer_stack=layer_stack2, run=False, session=s, material_name_to_lumerical=material_name_to_lumerical)<jupyter_output><empty_output><jupyter_text>![extra](https://i.imgur.com/75IR6fa.png) gdsfactory can also compute the Sparameters of a component that have not been simulated before.<jupyter_code>sim.write_sparameters_lumerical(gf.components.mmi1x2()) 
sim.plot.plot_sparameters(gf.components.mmi1x2(), keys=["S23m", "S13m"], logscale=True)<jupyter_output><empty_output><jupyter_text>As well as a group of components<jupyter_code># NBVAL_SKIP

components = [
    gf.components.coupler_ring(gap=gap, radius=radius)
    for gap in [0.15, 0.2, 0.3]
    for radius in [5, 10]
]

for c in components:
    c.show()
    print(c)
    sim.write_sparameters_lumerical(c)<jupyter_output><empty_output><jupyter_text>To debug a simulation you can create a Lumerical session outside the simulator, pass it to the simulator, and use `run=False` flag<jupyter_code># NBVAL_SKIP
import lumapi
import gdsfactory as gf

s = lumapi.FDTD()
c = gf.components.straight()
sim.write_sparameters_lumerical(c, run=False, session=s)<jupyter_output><empty_output><jupyter_text>By default gdsfactory uses the generic LayerStack for 0.22um height silicon layer.You can also define any LayerStack<jupyter_code>import gdsfactory as gf

def get_layer_stack():
    return gf.tech.LayerStack(wg=gf.tech.LayerLevel(layer=(1, 0), thickness=400e-3, zmin=0.0, material="sin"))

layer_stack = get_layer_stack()
# NBVAL_SKIP
import gdsfactory as gf
import gdsfactory.simulation.lumerical as sim

c = gf.components.straight()
s = sim.write_sparameters_lumerical(c, layer_stack=layer_stack, run=False, session=s)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09913305691669808, 'fraction_numerical': 0.012438748586505842, 'mean_word_length': 6.210597826086956, 'pattern_counts': {'":': 1, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '268107', 'license': 'MIT', 'n_tokens_mistral': 1861, 'n_tokens_neox': 1769, 'n_words': 464, 'path': 'docs/notebooks/plugins/lumerical/1_fdtd_sparameters.ipynb', 'repo_name': 'jorgepadilla19/gdsfactory', 'size': '5306'}