Skip to content

Commit e12f1a7

Browse files
committed
add test for sim validation and improved doc strings
1 parent 4abc665 commit e12f1a7

File tree

5 files changed

+197
-56
lines changed

5 files changed

+197
-56
lines changed

tests/test_components/test_simulation.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3629,3 +3629,54 @@ def test_create_sim_multiphysics_with_incompatibilities():
36293629
),
36303630
],
36313631
)
3632+
3633+
3634+
def test_validate_terminal_spec_generation():
3635+
"""Test that auto generation of path specs is correctly validated for currently unsupported structures."""
3636+
freq0 = 10e9
3637+
mm = 1e3
3638+
run_time_spec = td.RunTimeSpec(quality_factor=3.0)
3639+
size = (10 * mm, 10 * mm, 10 * mm)
3640+
size_mon = (0, 8 * mm, 8 * mm)
3641+
3642+
# Currently limited to generation of axis aligned boxes around conductors,
3643+
# so the path may intersect other nearby conductors, like in this coaxial cable
3644+
coaxial = td.Structure(
3645+
geometry=td.GeometryGroup(
3646+
geometries=(
3647+
td.ClipOperation(
3648+
operation="difference",
3649+
geometry_a=td.Cylinder(
3650+
axis=0, radius=2.5 * mm, center=(0, 0, 0), length=td.inf
3651+
),
3652+
geometry_b=td.Cylinder(
3653+
axis=0, radius=1.3 * mm, center=(0, 0, 0), length=td.inf
3654+
),
3655+
),
3656+
td.Cylinder(axis=0, radius=1 * mm, center=(0, 0, 0), length=td.inf),
3657+
)
3658+
),
3659+
medium=td.PEC,
3660+
)
3661+
mode_spec = td.ModeSpec(num_modes=2, target_neff=1.8, terminal_spec=td.TerminalSpec())
3662+
3663+
mode_mon = td.ModeMonitor(
3664+
center=(0, 0, 0),
3665+
size=size_mon,
3666+
freqs=[freq0],
3667+
name="mode_1",
3668+
colocate=False,
3669+
mode_spec=mode_spec,
3670+
)
3671+
sim = td.Simulation(
3672+
run_time=run_time_spec,
3673+
size=size,
3674+
sources=[],
3675+
structures=[coaxial],
3676+
grid_spec=td.GridSpec.uniform(dl=0.1 * mm),
3677+
monitors=[mode_mon],
3678+
)
3679+
3680+
# check that validation error is caught
3681+
with pytest.raises(SetupError):
3682+
sim._validate_terminal_specs()

tidy3d/components/geometry/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@
4040

4141

4242
def flatten_shapely_geometries(
43-
geoms: Union[Shapely, Iterable[Shapely]], keep_types: tuple[type, ...] = (Polygon)
43+
geoms: Union[Shapely, Iterable[Shapely]], keep_types: tuple[type, ...] = (Polygon,)
4444
) -> list[Shapely]:
4545
"""
46-
Flatten nested geometries into a flat list of specified types.
46+
Flatten nested geometries into a flat list, while only keeping the specified types.
4747
4848
Recursively extracts and returns non-empty geometries of the given types from input geometries,
4949
expanding any GeometryCollections or Multi* types.

tidy3d/components/microwave/path_spec.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""Specifications for defining path integrals."""
1+
"""Module containing specifications for voltage and current path integrals."""
22

33
from __future__ import annotations
44

@@ -118,7 +118,7 @@ def _vertices_2D(self, axis: Axis) -> tuple[Coordinate2D, Coordinate2D]:
118118

119119

120120
class VoltageIntegralAxisAlignedSpec(AxisAlignedPathIntegralSpec):
121-
"""Class for computing the voltage between two points defined by an axis-aligned line."""
121+
"""Class for specifying the voltage calculation between two points defined by an axis-aligned line."""
122122

123123
sign: Direction = pd.Field(
124124
...,
@@ -152,13 +152,13 @@ def from_terminal_positions(
152152
z : float = None
153153
Position in z direction, only two of x,y,z can be specified to define line.
154154
extrapolate_to_endpoints: bool = True
155-
Passed directly to :class:`VoltageIntegralAxisAligned`
155+
Passed directly to :class:`VoltageIntegralAxisAlignedSpec`
156156
snap_path_to_grid: bool = True
157-
Passed directly to :class:`VoltageIntegralAxisAligned`
157+
Passed directly to :class:`VoltageIntegralAxisAlignedSpec`
158158
159159
Returns
160160
-------
161-
VoltageIntegralAxisAligned
161+
VoltageIntegralAxisAlignedSpec
162162
The created path integral for computing voltage between the two terminals.
163163
"""
164164
axis_positions = Geometry.parse_two_xyz_kwargs(x=x, y=y, z=z)
@@ -237,7 +237,7 @@ def plot(
237237

238238

239239
class CurrentIntegralAxisAlignedSpec(AbstractAxesRH, Box):
240-
"""Class for computing conduction current via Ampère's circuital law on an axis-aligned loop."""
240+
"""Class for specifying the computation of conduction current via Ampère's circuital law on an axis-aligned loop."""
241241

242242
_plane_validator = assert_plane()
243243

@@ -270,7 +270,7 @@ def main_axis(self) -> Axis:
270270
def _to_path_integral_specs(
271271
self, h_horizontal=None, h_vertical=None
272272
) -> tuple[AxisAlignedPathIntegralSpec, ...]:
273-
"""Returns four ``AxisAlignedPathIntegral`` instances, which represent a contour
273+
"""Returns four ``AxisAlignedPathIntegralSpec`` instances, which represent a contour
274274
integral around the surface defined by ``self.size``."""
275275
ax1 = self.remaining_axes[0]
276276
ax2 = self.remaining_axes[1]
@@ -427,7 +427,7 @@ def plot(
427427

428428

429429
class CustomPathIntegral2DSpec(AbstractAxesRH):
430-
"""Class for defining a custom path integral defined as a curve on an axis-aligned plane.
430+
"""Class for specifying a custom path integral defined as a curve on an axis-aligned plane.
431431
432432
Notes
433433
-----
@@ -486,7 +486,7 @@ def from_circular_path(
486486
radius : float
487487
The radius of the circle.
488488
num_points : int
489-
THe number of equidistant points to use along the perimeter of the circle.
489+
The number of equidistant points to use along the perimeter of the circle.
490490
normal_axis : Axis
491491
The axis normal to the defined circle.
492492
clockwise : bool
@@ -495,7 +495,7 @@ def from_circular_path(
495495
496496
Returns
497497
-------
498-
:class:`.CustomPathIntegral2D`
498+
:class:`.CustomPathIntegral2DSpec`
499499
A path integral defined on a circular path.
500500
"""
501501

@@ -545,7 +545,7 @@ def _correct_shape(cls, val):
545545
# overall shape of vertices
546546
if val.shape[1] != 2:
547547
raise SetupError(
548-
"'CustomPathIntegral2D.vertices' must be a 2 dimensional array shaped (N, 2). "
548+
"'CustomPathIntegral2DSpec.vertices' must be a 2 dimensional array shaped (N, 2). "
549549
f"Given array with shape of '{val.shape}'."
550550
)
551551
return val
@@ -574,13 +574,13 @@ def sign(self) -> Direction:
574574

575575

576576
class CustomVoltageIntegral2DSpec(CustomPathIntegral2DSpec):
577-
"""Class for computing the voltage between two points defined by a custom path.
577+
"""Class for specfying the computation of voltage between two points defined by a custom path.
578578
Computed voltage is :math:`V=V_b-V_a`, where position b is the final vertex in the supplied path.
579579
580580
Notes
581581
-----
582582
583-
Use :class:`.VoltageIntegralAxisAligned` if possible, since interpolation
583+
Use :class:`.VoltageIntegralAxisAlignedSpec` if possible, since interpolation
584584
near conductors will not be accurate.
585585
586586
.. TODO Improve by including extrapolate_to_endpoints field, non-trivial extension."""
@@ -636,7 +636,7 @@ def plot(
636636

637637

638638
class CustomCurrentIntegral2DSpec(CustomPathIntegral2DSpec):
639-
"""Class for computing conduction current via Ampère's circuital law on a custom path.
639+
"""Class for specifying the computation of conduction current via Ampère's circuital law on a custom path.
640640
To compute the current flowing in the positive ``axis`` direction, the vertices should be
641641
ordered in a counterclockwise direction."""
642642

@@ -720,9 +720,11 @@ class CompositeCurrentIntegralSpec(Box):
720720
sum_spec: Literal["sum", "split"] = pd.Field(
721721
...,
722722
title="Sum Specification",
723-
description="Determines the method used to combine the currents calculated by the different current integrals defined by ``path_specs``."
724-
"``sum`` simply adds all currents, while ``split`` keeps contributions with opposite phase separate, which allows for isolating "
725-
"the current flowing in opposite directions. In ``split`` version, the current returned is the maximum of the two contributions.",
723+
description="Determines the method used to combine the currents calculated by the different "
724+
"current integrals defined by ``path_specs``. ``sum`` simply adds all currents, while ``split`` "
725+
"keeps contributions with opposite phase separate, which allows for isolating the current "
726+
"flowing in opposite directions. In ``split`` version, the current returned is the maximum "
727+
"of the two contributions.",
726728
)
727729

728730
@add_ax_if_none

0 commit comments

Comments
 (0)