diff --git a/.changelog.d/766.fixed b/.changelog.d/766.fixed new file mode 100644 index 00000000..42cc542b --- /dev/null +++ b/.changelog.d/766.fixed @@ -0,0 +1 @@ +Lumerical port waveguides now extend beyond the FDTD PML when simulation margins are configured. diff --git a/gplugins/lumerical/tests/test_write_sparameters_lumerical.py b/gplugins/lumerical/tests/test_write_sparameters_lumerical.py index d465ed6e..7584b694 100644 --- a/gplugins/lumerical/tests/test_write_sparameters_lumerical.py +++ b/gplugins/lumerical/tests/test_write_sparameters_lumerical.py @@ -10,6 +10,8 @@ class _Session: def __init__(self) -> None: self.ports = 0 + self.fdtd_settings: dict[str, object] = {} + self.gdspath: str | None = None def newproject(self) -> None: pass @@ -27,10 +29,10 @@ def setnamed(self, *args: object) -> None: pass def addfdtd(self, **kwargs: object) -> None: - pass + self.fdtd_settings = kwargs def gdsimport(self, *args: object) -> None: - pass + self.gdspath = str(args[0]) def addport(self) -> None: self.ports += 1 @@ -76,3 +78,30 @@ def test_keeps_ports_on_layers_not_in_layer_stack(monkeypatch, tmp_path) -> None assert result is session assert session.ports == 2 + + +def test_port_extension_reaches_beyond_pml(monkeypatch, tmp_path) -> None: + monkeypatch.setitem(sys.modules, "lumapi", ModuleType("lumapi")) + component = gf.components.straight(length=10, cross_section="strip") + layer_stack = LayerStack( + layers={ + "core": LayerLevel(layer=(1, 0), thickness=0.22, zmin=0, material="sio2") + } + ) + session = _Session() + + write_sparameters_lumerical( + component, + session=session, + run=False, + dirpath=tmp_path, + layer_stack=layer_stack, + xmargin=2, + ymargin=0, + port_extension=1, + ) + + assert session.gdspath is not None + exported_component = gf.import_gds(session.gdspath) + assert exported_component.xmin < session.fdtd_settings["x_min"] * 1e6 + assert exported_component.xmax > session.fdtd_settings["x_max"] * 1e6 diff --git a/gplugins/lumerical/write_sparameters_lumerical.py b/gplugins/lumerical/write_sparameters_lumerical.py index 17b1cfce..d54903a3 100644 --- a/gplugins/lumerical/write_sparameters_lumerical.py +++ b/gplugins/lumerical/write_sparameters_lumerical.py @@ -306,8 +306,14 @@ def write_sparameters_lumerical( if not ports: raise ValueError(f"{component.name!r} does not have any optical ports") + # The FDTD bounds add the requested margins around ``component_extended``. + # Include that headroom in the physical extension so every waveguide reaches + # beyond the PML, regardless of port orientation. + port_extension_beyond_pml = ss.port_extension + max( + xmargin_left, xmargin_right, ymargin_top, ymargin_bot + ) component_extended_beyond_pml = gf.components.extension.extend_ports( - component=component_extended, length=ss.port_extension + component=component_extended, length=port_extension_beyond_pml ) component_extended_beyond_pml = component_extended_beyond_pml.copy() component_extended_beyond_pml.flatten()