Skip to content

Commit 69b085f

Browse files
committed
refactor by splitting the path integral specification away from the integral computation, now the path specification handles pretty much everything, except for the final integral computation and results preparation
1 parent 3b1911f commit 69b085f

File tree

11 files changed

+860
-667
lines changed

11 files changed

+860
-667
lines changed

tests/test_components/test_microwave.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from shapely.geometry import LineString, Polygon
1313
from shapely.plotting import plot_line, plot_polygon
1414
from tidy3d.components.data.monitor_data import FreqDataArray
15-
from tidy3d.components.microwave.data.monitor_data import AntennaMetricsData
15+
from tidy3d.components.microwave.auto_path_spec import AutoPathSpec
1616
from tidy3d.components.microwave.formulas.circuit_parameters import (
1717
capacitance_colinear_cylindrical_wire_segments,
1818
capacitance_rectangular_sheets,
@@ -200,8 +200,10 @@ def make_mw_sim(
200200
return sim
201201

202202

203-
def plot_auto_path_spec(path_spec: td.CompositePathSpec, geoms: list[Shapely], ax: Ax = None) -> Ax:
204-
"""Helper to plot composite path specificiations along with the Shapely geometries used to generate them."""
203+
def plot_auto_path_spec(
204+
path_spec: td.CompositeCurrentIntegralSpec, geoms: list[Shapely], ax: Ax = None
205+
) -> Ax:
206+
"""Helper to plot composite path specifications along with the Shapely geometries used to generate them."""
205207
if ax is None:
206208
_, ax = plt.subplots(1, 1, tight_layout=True, figsize=(15, 15))
207209

@@ -260,7 +262,7 @@ def test_antenna_parameters():
260262
f = directivity_data.coords["f"]
261263
power_inc = FreqDataArray(0.8 * np.ones(len(f)), coords={"f": f})
262264
power_refl = 0.25 * power_inc
263-
antenna_params = AntennaMetricsData.from_directivity_data(
265+
antenna_params = td.AntennaMetricsData.from_directivity_data(
264266
directivity_data, power_inc, power_refl
265267
)
266268

@@ -318,7 +320,7 @@ def test_auto_path_spec_canonical_shapes(colocate, tline_type):
318320
sim = make_mw_sim(False, colocate, tline_type)
319321
mode_monitor = sim.monitors[0]
320322
modal_plane = td.Box(center=mode_monitor.center, size=mode_monitor.size)
321-
comp_path_spec, geos = td.AutoPathSpec.create_current_path_specs(
323+
comp_path_spec, geos = AutoPathSpec.create_current_path_specs(
322324
modal_plane,
323325
sim.structures,
324326
sim.grid,
@@ -378,7 +380,7 @@ def test_auto_path_spec_advanced(use_2D, symmetry):
378380
mode_monitor = sim.monitors[0]
379381

380382
modal_plane = td.Box(center=mode_monitor.center, size=mode_monitor.size)
381-
comp_path_spec, geos = td.AutoPathSpec.create_current_path_specs(
383+
comp_path_spec, geos = AutoPathSpec.create_current_path_specs(
382384
modal_plane,
383385
sim.structures,
384386
sim.grid,
@@ -408,11 +410,11 @@ def test_auto_path_spec_validation():
408410
# First some quick sanity checks with the helper
409411
test_path = td.Box(center=(0, 0, 0), size=(0, 0.9, 0.1))
410412
test_shapely = [LineString([(-1, 0), (1, 0)])]
411-
assert td.AutoPathSpec._check_path_intersects_with_conductors(test_shapely, test_path)
413+
assert AutoPathSpec._check_path_intersects_with_conductors(test_shapely, test_path)
412414

413415
test_path = td.Box(center=(0, 0, 0), size=(0, 2.1, 0.1))
414416
test_shapely = [LineString([(-1, 0), (1, 0)])]
415-
assert not td.AutoPathSpec._check_path_intersects_with_conductors(test_shapely, test_path)
417+
assert not AutoPathSpec._check_path_intersects_with_conductors(test_shapely, test_path)
416418

417419
sim = make_mw_sim(False, False, "microstrip")
418420
coax = td.GeometryGroup(
@@ -432,7 +434,7 @@ def test_auto_path_spec_validation():
432434
mode_monitor = sim.monitors[0]
433435
modal_plane = td.Box(center=mode_monitor.center, size=mode_monitor.size)
434436
with pytest.raises(ValidationError):
435-
td.AutoPathSpec.create_current_path_specs(
437+
AutoPathSpec.create_current_path_specs(
436438
modal_plane,
437439
sim.structures,
438440
sim.grid,
@@ -445,16 +447,16 @@ def test_auto_path_spec_validation():
445447
def test_path_integral_creation():
446448
"""Check that path integrals are correctly constructed from path specifications."""
447449

448-
path_spec = td.AxisAlignedPathSpec(center=(1, 2, 3), size=(0, 0, 1), sign="-")
450+
path_spec = td.VoltageIntegralAxisAlignedSpec(center=(1, 2, 3), size=(0, 0, 1), sign="-")
449451
voltage_integral = make_voltage_integral(path_spec)
450452

451-
path_spec = td.AxisAlignedPathSpec(center=(1, 2, 3), size=(0, 1, 1), sign="-")
453+
path_spec = td.CurrentIntegralAxisAlignedSpec(center=(1, 2, 3), size=(0, 1, 1), sign="-")
452454
current_integral = make_current_integral(path_spec)
453455

454-
path_spec = td.PathSpec(vertices=[(0, 1), (0, 4)], axis=1, position=2)
456+
path_spec = td.CustomVoltageIntegral2DSpec(vertices=[(0, 1), (0, 4)], axis=1, position=2)
455457
voltage_integral = make_voltage_integral(path_spec)
456458

457-
path_spec = td.PathSpec(
459+
path_spec = td.CustomCurrentIntegral2DSpec(
458460
vertices=[
459461
(0, 1),
460462
(0, 4),
@@ -464,10 +466,10 @@ def test_path_integral_creation():
464466
axis=1,
465467
position=2,
466468
)
467-
current_integral = make_current_integral(path_spec)
469+
_ = make_current_integral(path_spec)
468470

469471
with pytest.raises(pd.ValidationError):
470-
path_spec = td.PathSpec(
472+
path_spec = td.CustomCurrentIntegral2DSpec(
471473
vertices=[
472474
(0, 1, 3),
473475
(0, 4, 5),

tidy3d/__init__.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@
1515
from tidy3d.components.microwave.data.monitor_data import (
1616
AntennaMetricsData,
1717
)
18-
from tidy3d.components.microwave.path_spec import AxisAlignedPathSpec, CompositePathSpec, PathSpec
18+
from tidy3d.components.microwave.path_spec import (
19+
CompositeCurrentIntegralSpec,
20+
CurrentIntegralAxisAlignedSpec,
21+
CustomCurrentIntegral2DSpec,
22+
CustomVoltageIntegral2DSpec,
23+
VoltageIntegralAxisAlignedSpec,
24+
)
1925
from tidy3d.components.microwave.terminal_spec import (
2026
TerminalSpec,
2127
)
@@ -698,8 +704,10 @@ def set_logging_level(level: str) -> None:
698704
"IsothermalSteadyChargeDCAnalysis",
699705
"ChargeToleranceSpec",
700706
"AntennaMetricsData",
701-
"AxisAlignedPathSpec",
702-
"CompositePathSpec",
703-
"PathSpec",
707+
"CurrentIntegralAxisAlignedSpec",
708+
"VoltageIntegralAxisAlignedSpec",
709+
"CustomCurrentIntegral2DSpec",
710+
"CustomVoltageIntegral2DSpec",
711+
"CompositeCurrentIntegralSpec",
704712
"TerminalSpec",
705713
]

tidy3d/components/microwave/auto_path_spec.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,19 @@
2323
from ..grid.grid import Grid
2424
from ..structure import Structure
2525
from ..types import Axis, Coordinate, Shapely, Symmetry
26-
from .path_spec import AxisAlignedPathSpec, CompositePathSpec
26+
from .path_spec import CompositeCurrentIntegralSpec, CurrentIntegralAxisAlignedSpec
2727

2828

2929
class AutoPathSpec(Tidy3dBaseModel):
3030
"""Automatically determines current integration paths based on structure geometry.
3131
3232
This class analyzes the geometry of conductors in a simulation cross-section to determine
33-
appropriate paths for computing current line integrals. These paths are used
34-
in terminal impedance calculations and mode solving.
33+
appropriate paths for computing current line integrals. These paths are typically used
34+
in terminal impedance calculations after mode solving.
3535
3636
The paths are chosen by:
3737
1. Finding and merging conductor surfaces that intersect with the plane
38-
2. Creating current paths that enclose individual conductors
38+
2. Creating current paths that enclose isolated conductors
3939
"""
4040

4141
@staticmethod
@@ -66,7 +66,7 @@ def create_current_path_specs(
6666
symmetry: tuple[Symmetry, Symmetry, Symmetry],
6767
sim_box: Box,
6868
field_data_colocated: bool = False,
69-
) -> tuple[CompositePathSpec, list[Shapely]]:
69+
) -> tuple[CompositeCurrentIntegralSpec, list[Shapely]]:
7070
"""Creates path specifications for path integrals that encompass each isolated conductor in the mode plane.
7171
7272
This method identifies isolated conductor geometries in the given plane and creates
@@ -139,12 +139,12 @@ def bounding_box_from_shapely(geom: Shapely, normal_axis, normal_center):
139139
boxes = AutoPathSpec._apply_symmetry(symmetry, sim_box.center, normal_axis, box)
140140
for box in boxes:
141141
box_snapped = snap_box_to_grid(grid, box, snap_spec)
142-
path_spec = AxisAlignedPathSpec(
142+
path_spec = CurrentIntegralAxisAlignedSpec(
143143
center=box_snapped.center,
144144
size=box_snapped.size,
145145
sign="+",
146146
extrapolate_to_endpoints=False,
147-
snap_path_to_grid=True,
147+
snap_contour_to_grid=True,
148148
)
149149
current_integral_specs.append(path_spec)
150150

@@ -156,7 +156,7 @@ def bounding_box_from_shapely(geom: Shapely, normal_axis, normal_center):
156156
"In the meantime, please specify the path specification manually for this structure."
157157
)
158158

159-
path_spec = CompositePathSpec(
159+
path_spec = CompositeCurrentIntegralSpec(
160160
center=mode_plane.center,
161161
size=mode_plane.size,
162162
path_specs=current_integral_specs,

tidy3d/components/microwave/path_integral_factory.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,18 @@
99
VoltageIntegralAxisAligned,
1010
VoltageIntegralTypes,
1111
)
12-
from .path_spec import AxisAlignedPathSpec, CompositePathSpec, PathSpec, PathSpecTypes
12+
from .path_spec import (
13+
CompositeCurrentIntegralSpec,
14+
CurrentIntegralAxisAlignedSpec,
15+
CurrentPathSpecTypes,
16+
CustomCurrentIntegral2DSpec,
17+
CustomVoltageIntegral2DSpec,
18+
VoltageIntegralAxisAlignedSpec,
19+
VoltagePathSpecTypes,
20+
)
1321

1422

15-
def make_voltage_integral(path_spec: PathSpecTypes) -> VoltageIntegralTypes:
23+
def make_voltage_integral(path_spec: VoltagePathSpecTypes) -> VoltageIntegralTypes:
1624
"""Create a voltage path integral from a path specification.
1725
1826
Parameters
@@ -27,14 +35,14 @@ def make_voltage_integral(path_spec: PathSpecTypes) -> VoltageIntegralTypes:
2735
Voltage path integral instance corresponding to the provided specification type.
2836
"""
2937
v_integral = None
30-
if isinstance(path_spec, AxisAlignedPathSpec):
38+
if isinstance(path_spec, VoltageIntegralAxisAlignedSpec):
3139
v_integral = VoltageIntegralAxisAligned(**path_spec.dict(exclude={"type"}))
32-
elif isinstance(path_spec, PathSpec):
40+
elif isinstance(path_spec, CustomVoltageIntegral2DSpec):
3341
v_integral = CustomVoltageIntegral2D(**path_spec.dict(exclude={"type"}))
3442
return v_integral
3543

3644

37-
def make_current_integral(path_spec: PathSpecTypes) -> CurrentIntegralTypes:
45+
def make_current_integral(path_spec: CurrentPathSpecTypes) -> CurrentIntegralTypes:
3846
"""Create a current path integral from a path specification.
3947
4048
Parameters
@@ -50,26 +58,23 @@ def make_current_integral(path_spec: PathSpecTypes) -> CurrentIntegralTypes:
5058
"""
5159
i_integral = None
5260
if path_spec is not None:
53-
if isinstance(path_spec, AxisAlignedPathSpec):
54-
snap = path_spec.snap_path_to_grid
55-
spec_dict = path_spec.dict(exclude={"type", "snap_path_to_grid"})
56-
spec_dict["snap_contour_to_grid"] = snap
57-
i_integral = CurrentIntegralAxisAligned(**spec_dict)
58-
elif isinstance(path_spec, PathSpec):
61+
if isinstance(path_spec, CurrentIntegralAxisAlignedSpec):
62+
i_integral = CurrentIntegralAxisAligned(**path_spec.dict(exclude={"type"}))
63+
elif isinstance(path_spec, CustomCurrentIntegral2DSpec):
5964
i_integral = CustomCurrentIntegral2D(**path_spec.dict(exclude={"type"}))
60-
elif isinstance(path_spec, CompositePathSpec):
61-
i_integral = _make_composite_current_integral(path_spec)
65+
elif isinstance(path_spec, CompositeCurrentIntegralSpec):
66+
i_integral = CompositeCurrentIntegral(**path_spec.dict(exclude={"type"}))
6267
return i_integral
6368

6469

6570
def _make_composite_current_integral(
66-
composite_path_spec: CompositePathSpec,
71+
composite_path_spec: CompositeCurrentIntegralSpec,
6772
) -> CompositeCurrentIntegral:
6873
"""Create a composite current path integral from a composite path specification.
6974
7075
Parameters
7176
----------
72-
composite_path_spec : CompositePathSpec
77+
composite_path_spec : CompositeCurrentIntegralSpec
7378
Specification defining the composite path for current integration.
7479
7580
Returns

0 commit comments

Comments
 (0)