Tidy3DComponent crashes when using layer tuples
thanojo opened this issue · comments
Describe the bug
Even when the resulting components are pretty much identical, the Tidy3DComponent
does not plot the simulation geometry and instead crashes when using a Layer
tuple as the layer
argument in a cross section function. The bug is not present when using a str
to access the layer from the activated generic PDK, though I am also struggling with this when defining own PDKs (actually, this is where this becomes really weird and messy but it would be too much to include here).
To Reproduce
from functools import partial
import gdsfactory as gf
from gdsfactory.technology import LayerLevel, LayerStack
import gplugins.tidy3d as gt
# Define a layer map
Layer = tuple[int, int]
class LAYER(gf.LayerEnum):
kcl = gf.constant(gf.kcl)
WAFER: Layer = (0, 0)
WG_new: Layer = (1, 0)
gf.kcl.layers = LAYER # this doesn't seem to make a difference
# Create a layer stack
LAYER_STACK = LayerStack(
layers=dict(
substrate=LayerLevel(
layer=(0,0),
thickness=1,
zmin=-1,
material="sio2",
info={"mesh_order": 99},
),
core=LayerLevel(
layer=(1,0),
thickness=0.5,
zmin=0,
material="si",
info={"mesh_order": 99},
)
)
)
# Create a waveguide cross section
strip_PASSES = partial(gf.cross_section.strip, layer = 'WG')
strip_FAILS = partial(gf.cross_section.strip, layer = LAYER.WG_new)
strip_ALSO_FAILS = partial(gf.cross_section.strip, layer = (1,0))
# Create a component
MMIPASS = gf.components.mmi2x2(width = 0.5, cross_section= strip_PASSES)
MMI1 = gf.components.mmi2x2(width = 0.5, cross_section= strip_FAILS)
MMI2 = gf.components.mmi2x2(width = 0.5, cross_section= strip_ALSO_FAILS)
MMI1.show()
# Define PDK
pdk1 = gf.Pdk(name="fab1", layers=LAYER, cross_sections={'WG_new': strip_PASSES})
pdk1.activate()
# Define further cross sections depending on the PDK
strip_PDK_FAILS = partial(gf.cross_section.strip, layer = pdk1.get_layer("WG_new"))
strip_PDK_PASSES = partial(gf.cross_section.strip, layer = 'WG_new')
# Compare the layers
MMI3 = gf.components.mmi2x2(width = 0.5, cross_section= strip_PDK_FAILS) # PDK
MMIPASS_PDK = gf.components.mmi2x2(width = 0.5, cross_section= strip_PDK_PASSES) # PDK
print(MMIPASS.layers, MMI1.layers, MMI2.layers, MMI3.layers, MMIPASS_PDK.layers)
print(MMIPASS.layers == MMI1.layers == MMI2.layers == MMI3.layers == MMIPASS_PDK.layers )
# Setup the tidy3d component
c = gt.Tidy3DComponent(
component=MMI1,
layer_stack=LAYER_STACK,
material_mapping= gt.material_name_to_medium,
pad_xy_inner=2.0,
pad_xy_outer=2.0,
pad_z_inner=0,
pad_z_outer=0,
extend_ports=2.0,
)
# Check the simulation geometry
c.plot_slice(z="core")
Depending on which MMI or cross section is used, the simulation geometry is successfully plotted (MMIPASS
or MMIPASS_PDK
) or python crashes. The error message is the following:
--- Logging error in Loguru Handler #1 ---
Record was: {'elapsed': datetime.timedelta(seconds=5, microseconds=790321), 'exception': (type=<class 'pydantic_core._pydantic_core.ValidationError'>, value=2 validation errors for Section
layer.tuple[int, int]
Input should be a valid tuple [type=tuple_type, input_value=1, input_type=int]
For further information visit https://errors.pydantic.dev/2.8/v/tuple_type
layer.str
Input should be a valid string [type=string_type, input_value=1, input_type=int]
For further information visit https://errors.pydantic.dev/2.8/v/string_type, traceback=<traceback object at 0x00000189D21BAC40>), 'extra': {'stack': '<frozen runpy>:_run_module_as_main:198 > <frozen runpy>:_run_code:88 > ...\test_envs\\test_gplugins_bugs\\.venv\\Lib\\site-packages\\ipykernel_launcher.py:<module>:18 > ....\test_envs\\test_gplugins_bugs\\.
... (full report attached)
Expected behavior
The simulation geometry should be plotted (and any ensuing simulation steps should work).
Suggested fix
I am not sure what is causing the error, but will post a workaround if I find one.
This could just be the tidy3d
plugin, but it could also go deep into the gdsfactory.technology
.
The weirdest part is that when defining own PDKs and importing them from elsewhere (as opposed to the above), this behaviour becomes seemingly non-deterministic, sometimes passing and sometimes not in subsequent executions.
Versions
- gdsfactory version: gdsfactory==8.5.6
- gplugins version: gplugins==1.0.2
- fresh python 3.11.2 venv with only gdsfactory and gplugins (and deps) installed via
pip install gdsfactory --upgrade pip install "gplugins[devsim,femwell,gmsh,schematic,meow,meshwell,ray,sax,tidy3d]" --upgrade
From the error message it looks like a Section is getting passed an int
somewhere instead of a LayerSpec
(tuple[int, int] | str
).
Seems like a gdsfactory internal issue to me / not a tidy3d bug.
Okay, thanks for the update.
If you want to, I can try to get to the bottom of this in terms of gdsfactory, and if I find something, then close this issue and create the corresponding issue in https://github.com/gdsfactory/gdsfactory/issues .
But I feel like this may be fixed 'automatically' through the continuing improvements on gdsfactory8