Skip to content

Commit d13703c

Browse files
caseyflexmomchil-flex
authored andcommitted
Automatically use periodic boundary on zero-size dimensions
1 parent 46d7d5b commit d13703c

File tree

6 files changed

+27
-37
lines changed

6 files changed

+27
-37
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4040
- Improved performance of `tidy3d.web.delete_old()` for large folders.
4141
- Upon initialization, an FDTD `Simulation` will now try to create all `ModeSolver` objects associated to `ModeSource`-s and `ModeMonitor`-s so they can be validated.
4242
- `tidy3d.plugins.autograd.interpolate_spline()` and `tidy3d.plugins.autograd.add_at()` can now be called with keyword arguments during tracing.
43+
- Zero-size dimensions automatically receive periodic boundary conditions instead of raising an error.
4344

4445
## [2.8.4] - 2025-05-15
4546

tests/test_components/test_mode.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ def test_validation_from_simulation():
151151
size=(0, 5, 5),
152152
mode_spec=td.ModeSpec(angle_rotation=True, angle_theta=np.pi / 4),
153153
freqs=[td.C_0],
154-
boundary_spec=td.BoundarySpec.all_sides(td.Periodic()),
155154
)
156155

157156
with pytest.raises(SetupError):
@@ -160,7 +159,6 @@ def test_validation_from_simulation():
160159
size=(0, 5, 5),
161160
mode_spec=td.ModeSpec(angle_rotation=True, angle_theta=np.pi / 4),
162161
freqs=[td.C_0],
163-
boundary_spec=td.BoundarySpec.all_sides(td.Periodic()),
164162
)
165163

166164

@@ -169,16 +167,12 @@ def get_mode_sim():
169167
permittivity_monitor = td.PermittivityMonitor(
170168
size=(1, 1, 0), center=(0, 0, 0), name="eps", freqs=FS
171169
)
172-
boundary_spec = td.BoundarySpec(
173-
x=td.Boundary.pml(), y=td.Boundary.periodic(), z=td.Boundary.pml()
174-
)
175170
sim = td.ModeSimulation(
176171
size=SIZE_2D,
177172
freqs=FS,
178173
mode_spec=mode_spec,
179174
grid_spec=td.GridSpec.auto(wavelength=td.C_0 / FS[0]),
180175
monitors=[permittivity_monitor],
181-
boundary_spec=boundary_spec,
182176
)
183177
return sim
184178

tests/test_components/test_simulation.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -563,16 +563,19 @@ def test_validate_zero_dim_boundaries():
563563
pol_angle=0.0,
564564
)
565565

566-
with pytest.raises(pydantic.ValidationError):
567-
td.Simulation(
568-
size=(1, 1, 0),
569-
run_time=1e-12,
570-
sources=[src],
571-
boundary_spec=td.BoundarySpec(
572-
x=td.Boundary.periodic(),
573-
y=td.Boundary.periodic(),
574-
z=td.Boundary.pml(),
575-
),
566+
with AssertLogLevel("WARNING", contains_str="Periodic"):
567+
assert (
568+
td.Simulation(
569+
size=(1, 1, 0),
570+
run_time=1e-12,
571+
sources=[src],
572+
boundary_spec=td.BoundarySpec(
573+
x=td.Boundary.periodic(),
574+
y=td.Boundary.periodic(),
575+
z=td.Boundary.pml(),
576+
),
577+
).boundary_spec.z
578+
== td.Boundary.periodic()
576579
)
577580

578581
# zero-dim simulation with an absorbing boundary any other direction should not error

tidy3d/components/eme/simulation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1183,4 +1183,4 @@ def _cell_index_pairs(self) -> list[pd.NonNegativeInt]:
11831183
pairs = set(self.eme_grid_spec._cell_index_pairs)
11841184
return list(pairs)
11851185

1186-
_boundaries_for_zero_dims = validate_boundaries_for_zero_dims()
1186+
_boundaries_for_zero_dims = validate_boundaries_for_zero_dims(warn_on_change=False)

tidy3d/components/mode/simulation.py

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import pydantic.v1 as pd
99

1010
from tidy3d.components.base import cached_property
11-
from tidy3d.components.boundary import Boundary, BoundarySpec
11+
from tidy3d.components.boundary import BoundarySpec
1212
from tidy3d.components.geometry.base import Box
1313
from tidy3d.components.grid.grid import Grid
1414
from tidy3d.components.grid.grid_spec import GridSpec
@@ -213,18 +213,6 @@ def plane_in_sim_bounds(cls, val, values):
213213
raise SetupError("'ModeSimulation.plane' must intersect 'ModeSimulation.geometry.")
214214
return val
215215

216-
@pd.validator("boundary_spec", always=True)
217-
def boundaries_for_zero_dims(cls, val, values):
218-
"""Replace with periodic boundary along zero-size dimensions."""
219-
boundaries = [val.x, val.y, val.z]
220-
size = values.get("size")
221-
222-
for dim, size_dim in enumerate(size):
223-
if size_dim == 0:
224-
boundaries[dim] = Boundary.periodic()
225-
226-
return BoundarySpec(x=boundaries[0], y=boundaries[1], z=boundaries[2])
227-
228216
def _post_init_validators(self) -> None:
229217
"""Call validators taking `self` that get run after init."""
230218
ModeSolver._validate_mode_plane_radius(
@@ -524,4 +512,4 @@ def plot_pml_mode_plane(
524512
def validate_pre_upload(self, source_required: bool = False):
525513
self._mode_solver.validate_pre_upload(source_required=source_required)
526514

527-
_boundaries_for_zero_dims = validate_boundaries_for_zero_dims()
515+
_boundaries_for_zero_dims = validate_boundaries_for_zero_dims(warn_on_change=False)

tidy3d/components/simulation.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@
173173
RF_FREQ_WARNING = 300e9
174174

175175

176-
def validate_boundaries_for_zero_dims():
176+
def validate_boundaries_for_zero_dims(warn_on_change: bool = True):
177177
"""Error if absorbing boundaries, bloch boundaries, unmatching pec/pmc, or symmetry is used along a zero dimension."""
178178

179179
@pydantic.validator("boundary_spec", allow_reuse=True, always=True)
@@ -192,11 +192,15 @@ def boundaries_for_zero_dims(cls, val, values):
192192
num_bloch_bdries = sum(isinstance(bnd, BlochBoundary) for bnd in boundary)
193193

194194
if num_absorbing_bdries > 0:
195-
raise SetupError(
196-
f"The simulation has zero size along the {axis} axis, so "
197-
"using a PML or absorbing boundary along that axis is incorrect. "
198-
f"Use either 'Periodic' or 'BlochBoundary' along {axis}."
199-
)
195+
pbc = Boundary(minus=Periodic(), plus=Periodic())
196+
val = val.updated_copy(**{axis: pbc})
197+
if warn_on_change:
198+
log.warning(
199+
f"The simulation has zero size along the {axis} axis, so "
200+
"using a PML or absorbing boundary along that axis is incorrect. "
201+
f"Use either 'Periodic' or 'BlochBoundary' along {axis}. "
202+
"Using 'Periodic' boundary by default."
203+
)
200204

201205
if num_bloch_bdries > 0:
202206
raise SetupError(

0 commit comments

Comments
 (0)