Skip to content

Commit

Permalink
Validate that bend radius is not smaller than half the mode plane size
Browse files Browse the repository at this point in the history
  • Loading branch information
momchil-flex committed Nov 4, 2024
1 parent b0a92fd commit 1ae70ab
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 2 deletions.
18 changes: 18 additions & 0 deletions tests/test_components/test_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,24 @@ def test_monitor_num_modes(log_capture, num_modes, log_level):
assert_log_level(log_capture, log_level)


def test_mode_bend_radius():
"""Test that small bend radius fails."""

with pytest.raises(ValueError):
mnt = td.ModeMonitor(
size=(5, 0, 1),
freqs=np.linspace(1e14, 2e14, 100),
name="test",
mode_spec=td.ModeSpec(num_modes=1, bend_radius=1, bend_axis=1),
)
_ = td.Simulation(
size=(2, 2, 2),
run_time=1e-12,
monitors=[mnt],
grid_spec=td.GridSpec.uniform(dl=0.1),
)


def test_diffraction_validators():
# ensure error if boundaries are not periodic
boundary_spec = td.BoundarySpec(
Expand Down
16 changes: 16 additions & 0 deletions tests/test_components/test_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@ def test_dir_vector():
assert DirectionalSource._dir_vector.fget(S) is None


def test_mode_bend_radius():
"""Test that small bend radius fails."""

with pytest.raises(ValueError):
src = td.ModeSource(
size=(1, 0, 5),
source_time=ST,
mode_spec=td.ModeSpec(num_modes=1, bend_radius=1, bend_axis=0),
)
_ = td.Simulation(
size=(2, 2, 2),
run_time=1e-12,
sources=[src],
)


def test_UniformCurrentSource():
g = td.GaussianPulse(freq0=1e12, fwidth=0.1e12)

Expand Down
11 changes: 11 additions & 0 deletions tests/test_plugins/test_mode_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -1034,3 +1034,14 @@ def test_modes_eme_sim(mock_remote_api, local):
_ = msweb.run(solver.to_fdtd_mode_solver())

_ = solver.reduced_simulation_copy


def test_mode_bend_radius():
"""Test that small bend radius fails."""

with pytest.raises(ValueError):
ms = ModeSolver(
plane=PLANE,
freqs=np.linspace(1e14, 2e14, 100),
mode_spec=td.ModeSpec(num_modes=1, bend_radius=1, bend_axis=0),
)
24 changes: 23 additions & 1 deletion tidy3d/components/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,11 @@
from .structure import MeshOverrideStructure, Structure
from .subpixel_spec import SubpixelSpec
from .types import TYPE_TAG_STR, Ax, Axis, FreqBound, InterpMethod, Literal, Symmetry, annotate_type
from .validators import assert_objects_in_sim_bounds, validate_mode_objects_symmetry
from .validators import (
assert_objects_in_sim_bounds,
validate_mode_objects_symmetry,
validate_mode_plane_radius,
)
from .viz import (
PlotParams,
add_ax_if_none,
Expand Down Expand Up @@ -3245,6 +3249,24 @@ def _post_init_validators(self) -> None:
self._validate_tfsf_nonuniform_grid()
self._validate_nonlinear_specs()
self._validate_custom_source_time()
self._validate_mode_object_bends()

def _validate_mode_object_bends(self) -> None:
"""Error if any mode sources or monitors with bends have a radius that is too small."""
for imnt, monitor in enumerate(self.monitors):
if isinstance(monitor, AbstractModeMonitor):
validate_mode_plane_radius(
mode_spec=monitor.mode_spec,
plane=monitor.geometry,
msg_prefix=f"Monitors[{imnt}] ",
)
for isrc, source in enumerate(self.sources):
if isinstance(source, ModeSource):
validate_mode_plane_radius(
mode_spec=source.mode_spec,
plane=source.geometry,
msg_prefix=f"Sources[{isrc}] ",
)

def _validate_custom_source_time(self):
"""Warn if all simulation times are outside CustomSourceTime definition range."""
Expand Down
18 changes: 18 additions & 0 deletions tidy3d/components/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,3 +396,21 @@ def freqs_not_empty(cls, val):
return val

return freqs_not_empty


def validate_mode_plane_radius(mode_spec: "ModeSpec", plane: "Box", msg_prefix: str): # noqa: F821
"""Validate that the radius of a mode spec with a bend is not smaller than half the size of
the plane along the radial direction."""

if not mode_spec.bend_radius:
return

# radial axis is the plane axis that is not the bend axis
_, plane_axs = plane.pop_axis([0, 1, 2], plane.size.index(0.0))
radial_ax = plane_axs[(mode_spec.bend_axis + 1) % 2]

if np.abs(mode_spec.bend_radius) < plane.size[radial_ax] / 2:
raise ValueError(
f"{msg_prefix} bend radius is smaller than half the mode plane size "
"along the radial axis, which can produce wrong results."
)
11 changes: 10 additions & 1 deletion tidy3d/plugins/mode/mode_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@
PlotScale,
Symmetry,
)
from ...components.validators import validate_freqs_min, validate_freqs_not_empty
from ...components.validators import (
validate_freqs_min,
validate_freqs_not_empty,
validate_mode_plane_radius,
)
from ...components.viz import make_ax, plot_params_pml
from ...constants import C_0
from ...exceptions import SetupError, ValidationError
Expand Down Expand Up @@ -173,6 +177,11 @@ def plane_in_sim_bounds(cls, val, values):
raise SetupError("'ModeSolver.plane' must intersect 'ModeSolver.simulation'.")
return val

def _post_init_validators(self) -> None:
validate_mode_plane_radius(
mode_spec=self.mode_spec, plane=self.plane, msg_prefix="Mode solver"
)

@cached_property
def normal_axis(self) -> Axis:
"""Axis normal to the mode plane."""
Expand Down

0 comments on commit 1ae70ab

Please sign in to comment.