Skip to content

Commit 6c2e2c6

Browse files
committed
Warn when mode solver pml covers a significant portion of the mode plane
1 parent 4721d51 commit 6c2e2c6

File tree

4 files changed

+327
-63
lines changed

4 files changed

+327
-63
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
- Compatibility with `xarray>=2025.03`.
1818
- Inaccurate gradient when auto-grabbing permittivities for structures using `td.PolySlab` when using dispersive material models.
1919
- Fixed scaling for adjoint sources when differentiating with respect to `FieldData` to account for the mesh size of the monitor and thus the created source. This aligns adjoint gradient magnitudes with numerical finite difference gradients for field data.
20+
- Warn when mode solver pml covers a significant portion of the mode plane.
2021

2122
## [2.8.1] - 2025-03-20
2223

tests/test_components/test_simulation.py

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from tidy3d.components.scene import MAX_GEOMETRY_COUNT, MAX_NUM_MEDIUMS
1515
from tidy3d.components.simulation import MAX_NUM_SOURCES
1616
from tidy3d.exceptions import SetupError, Tidy3dError, Tidy3dKeyError
17+
from tidy3d.plugins.mode import ModeSolver
1718

1819
from ..utils import (
1920
SIM_FULL,
@@ -2749,7 +2750,11 @@ def test_sim_subsection(unstructured, nz):
27492750
sim_red = SIM_FULL.subsection(
27502751
region=region, boundary_spec=td.BoundarySpec.all_sides(td.Periodic())
27512752
)
2752-
sim_red = SIM_FULL.subsection(region=region, sources=[], grid_spec=td.GridSpec.uniform(dl=20))
2753+
sim_red = SIM_FULL.subsection(
2754+
region=region,
2755+
sources=[],
2756+
grid_spec=td.GridSpec.uniform(dl=20),
2757+
)
27532758
assert len(sim_red.sources) == 0
27542759
sim_red = SIM_FULL.subsection(region=region, monitors=[])
27552760
assert len(sim_red.monitors) == 0
@@ -3291,6 +3296,87 @@ def test_validate_sources_monitors_in_bounds():
32913296
)
32923297

32933298

3299+
def test_mode_pml_warning():
3300+
sim_size = (3, 3, 3)
3301+
lambda0 = 1.55
3302+
freq0 = td.C_0 / lambda0
3303+
si = td.material_library["cSi"]["Li1993_293K"]
3304+
sio2 = td.material_library["SiO2"]["Horiba"]
3305+
wg = td.Structure(geometry=td.Box(size=(0.22, 0.5, td.inf)), medium=si)
3306+
mode_plane = td.Box(size=(2, 2, 0))
3307+
mode_spec = td.ModeSpec(num_pml=(22, 22))
3308+
grid_spec = td.GridSpec.auto(wavelength=lambda0, min_steps_per_wvl=30)
3309+
symmetry = (0, 0, 0)
3310+
with AssertLogLevel(None):
3311+
sim = td.Simulation(
3312+
size=sim_size,
3313+
medium=sio2,
3314+
structures=[wg],
3315+
grid_spec=grid_spec,
3316+
run_time=1e-30,
3317+
monitors=[
3318+
td.ModeSolverMonitor(
3319+
size=(2, 2, 0),
3320+
name="mode",
3321+
freqs=[freq0],
3322+
mode_spec=mode_spec.updated_copy(num_pml=(10, 10)),
3323+
)
3324+
],
3325+
symmetry=symmetry,
3326+
)
3327+
with AssertLogLevel("WARNING", contains_str="covers more than"):
3328+
sim = td.Simulation(
3329+
size=sim_size,
3330+
medium=sio2,
3331+
structures=[wg],
3332+
grid_spec=grid_spec,
3333+
run_time=1e-30,
3334+
monitors=[
3335+
td.ModeSolverMonitor(
3336+
size=(2, 2, 0), name="mode", freqs=[freq0], mode_spec=mode_spec
3337+
)
3338+
],
3339+
symmetry=symmetry,
3340+
)
3341+
with AssertLogLevel("WARNING", contains_str="covers more than"):
3342+
sim = td.Simulation(
3343+
size=sim_size,
3344+
medium=sio2,
3345+
structures=[wg],
3346+
grid_spec=grid_spec,
3347+
run_time=1e-30,
3348+
sources=[
3349+
td.ModeSource(
3350+
size=(2, 2, 0),
3351+
direction="+",
3352+
source_time=td.GaussianPulse(freq0=freq0, fwidth=0.1 * freq0),
3353+
mode_spec=mode_spec,
3354+
)
3355+
],
3356+
symmetry=symmetry,
3357+
)
3358+
with AssertLogLevel("WARNING", contains_str="covers more than"):
3359+
mode_solver = ModeSolver(
3360+
simulation=sim, plane=mode_plane, mode_spec=mode_spec, freqs=[freq0]
3361+
)
3362+
size = mode_solver._mode_plane_size(simulation=sim, plane=mode_plane)
3363+
size_no_pml = mode_solver._mode_plane_size_no_pml(
3364+
simulation=sim, plane=mode_plane, mode_spec=mode_spec
3365+
)
3366+
for i in [0, 1]:
3367+
assert size_no_pml[i] / size[i] < 0.5
3368+
with AssertLogLevel("WARNING", contains_str="covers more than"):
3369+
mode_sim = td.ModeSimulation(
3370+
size=sim_size,
3371+
medium=sio2,
3372+
structures=[wg],
3373+
grid_spec=grid_spec,
3374+
plane=mode_plane,
3375+
mode_spec=mode_spec,
3376+
freqs=[freq0],
3377+
)
3378+
3379+
32943380
def test_fixed_angle_sim():
32953381
wvl_um = 1.0
32963382
freq0 = td.C_0 / wvl_um

0 commit comments

Comments
 (0)