Skip to content

Commit d23f936

Browse files
committed
add doctests
1 parent b4d0536 commit d23f936

28 files changed

+220
-222
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2121
### Changed
2222
- `LayerRefinementSpec` defaults to assuming structures made of different materials are interior-disjoint for more efficient mesh generation.
2323
- Removal of the Adjoint plugin.
24+
- All RF and microwave specific components now inherit from `MicrowaveBaseModel`.
2425

2526
### Fixed
2627
- Stricter validation for `bend_radius` in mode simulations, preventing the bend center from coinciding with the simulation boundary.

schemas/EMESimulation.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2368,7 +2368,6 @@
23682368
"type": "object"
23692369
},
23702370
"axis": {
2371-
"default": 2,
23722371
"enum": [
23732372
0,
23742373
1,
@@ -2391,6 +2390,7 @@
23912390
}
23922391
},
23932392
"required": [
2393+
"axis",
23942394
"position",
23952395
"vertices"
23962396
],
@@ -2404,7 +2404,6 @@
24042404
"type": "object"
24052405
},
24062406
"axis": {
2407-
"default": 2,
24082407
"enum": [
24092408
0,
24102409
1,
@@ -2427,6 +2426,7 @@
24272426
}
24282427
},
24292428
"required": [
2429+
"axis",
24302430
"position",
24312431
"vertices"
24322432
],

schemas/ModeSimulation.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2411,7 +2411,6 @@
24112411
"type": "object"
24122412
},
24132413
"axis": {
2414-
"default": 2,
24152414
"enum": [
24162415
0,
24172416
1,
@@ -2434,6 +2433,7 @@
24342433
}
24352434
},
24362435
"required": [
2436+
"axis",
24372437
"position",
24382438
"vertices"
24392439
],
@@ -2447,7 +2447,6 @@
24472447
"type": "object"
24482448
},
24492449
"axis": {
2450-
"default": 2,
24512450
"enum": [
24522451
0,
24532452
1,
@@ -2470,6 +2469,7 @@
24702469
}
24712470
},
24722471
"required": [
2472+
"axis",
24732473
"position",
24742474
"vertices"
24752475
],

schemas/Simulation.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2788,7 +2788,6 @@
27882788
"type": "object"
27892789
},
27902790
"axis": {
2791-
"default": 2,
27922791
"enum": [
27932792
0,
27942793
1,
@@ -2811,6 +2810,7 @@
28112810
}
28122811
},
28132812
"required": [
2813+
"axis",
28142814
"position",
28152815
"vertices"
28162816
],
@@ -2824,7 +2824,6 @@
28242824
"type": "object"
28252825
},
28262826
"axis": {
2827-
"default": 2,
28282827
"enum": [
28292828
0,
28302829
1,
@@ -2847,6 +2846,7 @@
28472846
}
28482847
},
28492848
"required": [
2849+
"axis",
28502850
"position",
28512851
"vertices"
28522852
],

schemas/TerminalComponentModeler.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3197,7 +3197,6 @@
31973197
"type": "object"
31983198
},
31993199
"axis": {
3200-
"default": 2,
32013200
"enum": [
32023201
0,
32033202
1,
@@ -3220,6 +3219,7 @@
32203219
}
32213220
},
32223221
"required": [
3222+
"axis",
32233223
"position",
32243224
"vertices"
32253225
],
@@ -3233,7 +3233,6 @@
32333233
"type": "object"
32343234
},
32353235
"axis": {
3236-
"default": 2,
32373236
"enum": [
32383237
0,
32393238
1,
@@ -3256,6 +3255,7 @@
32563255
}
32573256
},
32583257
"required": [
3258+
"axis",
32593259
"position",
32603260
"vertices"
32613261
],
@@ -3269,7 +3269,6 @@
32693269
"type": "object"
32703270
},
32713271
"axis": {
3272-
"default": 2,
32733272
"enum": [
32743273
0,
32753274
1,
@@ -3292,6 +3291,7 @@
32923291
}
32933292
},
32943293
"required": [
3294+
"axis",
32953295
"position",
32963296
"vertices"
32973297
],
@@ -3305,7 +3305,6 @@
33053305
"type": "object"
33063306
},
33073307
"axis": {
3308-
"default": 2,
33093308
"enum": [
33103309
0,
33113310
1,
@@ -3328,6 +3327,7 @@
33283327
}
33293328
},
33303329
"required": [
3330+
"axis",
33313331
"position",
33323332
"vertices"
33333333
],

tests/test_components/test_geometry.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,10 +1202,10 @@ def test_snap_box_to_grid_strict_behaviors():
12021202
expanded_box = snap_box_to_grid(grid, box_coincident, snap_spec_strict_expand)
12031203

12041204
# StrictExpand should move bounds outwards even when already on grid
1205-
assert expanded_box.bounds[0][0] < 0.1 # Left bound moved left from 0.1
1206-
assert expanded_box.bounds[1][0] > 0.1 # Right bound moved right from 0.1
1207-
assert expanded_box.bounds[0][1] < 0.2 # Bottom bound moved down from 0.2
1208-
assert expanded_box.bounds[1][1] > 0.2 # Top bound moved up from 0.2
1205+
assert np.isclose(expanded_box.bounds[0][0], 0.0) # Left bound moved left from 0.1
1206+
assert np.isclose(expanded_box.bounds[1][0], 0.2) # Right bound moved right from 0.1
1207+
assert np.isclose(expanded_box.bounds[0][1], 0.1) # Bottom bound moved down from 0.2
1208+
assert np.isclose(expanded_box.bounds[1][1], 0.3) # Top bound moved up from 0.2
12091209

12101210
# Test StrictContract: should always move endpoints inwards, even if coincident
12111211
box_large = td.Box(center=(0.5, 0.5, 0.5), size=(0.4, 0.4, 0.4)) # Spans multiple grid cells

tidy3d/components/data/monitor_data.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1655,7 +1655,7 @@ class ModeData(ModeSolverDataset, ElectromagneticFieldData):
16551655
None,
16561656
title="Microwave Mode Dataset",
16571657
description="Additional data relevant to RF and microwave applications, like characteristic impedance. "
1658-
"This field is populated when a :class:`MicrowaveModeSpec` has been provided to the :class:`ModeSpec`.",
1658+
"This field is populated when a :class:`MicrowaveModeSpec` has been used to set up the monitor or mode solver.",
16591659
)
16601660

16611661
@pd.validator("eps_spec", always=True)
@@ -3556,9 +3556,9 @@ class DirectivityData(FieldProjectionAngleData):
35563556
>>> values = (1+1j) * np.random.random((len(r), len(theta), len(phi), len(f)))
35573557
>>> flux_data = FluxDataArray(np.random.random(len(f)), coords=coords_flux)
35583558
>>> scalar_field = FieldProjectionAngleDataArray(values, coords=coords)
3559-
>>> monitor = DirectivityMonitor(center=(1,2,3), size=(2,2,2), freqs=f, name='n2f_monitor', phi=phi, theta=theta) # doctest: +SKIP
3559+
>>> monitor = DirectivityMonitor(center=(1,2,3), size=(2,2,2), freqs=f, name='n2f_monitor', phi=phi, theta=theta)
35603560
>>> data = DirectivityData(monitor=monitor, flux=flux_data, Er=scalar_field, Etheta=scalar_field, Ephi=scalar_field,
3561-
... Hr=scalar_field, Htheta=scalar_field, Hphi=scalar_field, projection_surfaces=monitor.projection_surfaces) # doctest: +SKIP
3561+
... Hr=scalar_field, Htheta=scalar_field, Hphi=scalar_field, projection_surfaces=monitor.projection_surfaces)
35623562
"""
35633563

35643564
monitor: DirectivityMonitor = pd.Field(

tidy3d/components/lumped_element.py

Lines changed: 10 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@
1616
from tidy3d.components.validators import assert_line_or_plane, assert_plane, validate_name_str
1717
from tidy3d.constants import EPSILON_0, FARAD, HENRY, MICROMETER, OHM, fp_eps
1818
from tidy3d.exceptions import ValidationError
19-
from tidy3d.log import log
2019

21-
from .base import Tidy3dBaseModel, cached_property, skip_if_fields_missing
20+
from .base import cached_property, skip_if_fields_missing
2221
from .geometry.base import Box, ClipOperation, Geometry, GeometryGroup
2322
from .geometry.primitives import Cylinder
2423
from .geometry.utils import (
@@ -29,6 +28,7 @@
2928
snap_point_to_grid,
3029
)
3130
from .geometry.utils_2d import increment_float
31+
from .microwave.base import MicrowaveBaseModel
3232
from .microwave.formulas.circuit_parameters import (
3333
capacitance_colinear_cylindrical_wire_segments,
3434
capacitance_rectangular_sheets,
@@ -50,7 +50,7 @@
5050
LOSS_FACTOR_INDUCTOR = 1e6
5151

5252

53-
class LumpedElement(Tidy3dBaseModel, ABC):
53+
class LumpedElement(MicrowaveBaseModel, ABC):
5454
"""Base class describing the interface all lumped elements obey."""
5555

5656
name: str = pd.Field(
@@ -104,14 +104,6 @@ def to_structures(self, grid: Grid = None) -> list[Structure]:
104104
which are ready to be added to the :class:`.Simulation`"""
105105
return [self.to_structure(grid)]
106106

107-
@pd.root_validator(pre=False)
108-
def _warn_rf_license(cls, values):
109-
log.warning(
110-
"ℹ️ ⚠️ RF simulations are subject to new license requirements in the future. You have instantiated at least one RF-specific component.",
111-
log_once=True,
112-
)
113-
return values
114-
115107

116108
class RectangularLumpedElement(LumpedElement, Box):
117109
"""Class representing a rectangular element with zero thickness. A :class:`RectangularLumpedElement`
@@ -464,7 +456,7 @@ def geometry(self) -> ClipOperation:
464456
return self.to_geometry()
465457

466458

467-
class NetworkConversions(Tidy3dBaseModel):
459+
class NetworkConversions(MicrowaveBaseModel):
468460
"""Helper functionality for directly computing complex conductivity and permittivities using
469461
equations in _`[1]`. Useful for testing the direct translations of lumped network parameters into
470462
an equivalent PoleResidue medium.
@@ -546,16 +538,8 @@ def complex_permittivity(a: tuple[float, ...], b: tuple[float, ...], freqs: np.n
546538
sigma = NetworkConversions.complex_conductivity(a, b, freqs)
547539
return 1j * sigma / (2 * np.pi * freqs * EPSILON_0)
548540

549-
@pd.root_validator(pre=False)
550-
def _warn_rf_license(cls, values):
551-
log.warning(
552-
"ℹ️ ⚠️ RF simulations are subject to new license requirements in the future. You have instantiated at least one RF-specific component.",
553-
log_once=True,
554-
)
555-
return values
556-
557541

558-
class RLCNetwork(Tidy3dBaseModel):
542+
class RLCNetwork(MicrowaveBaseModel):
559543
"""Class for representing a simple network consisting of a resistor, capacitor, and inductor.
560544
Provides additional functionality for representing the network as an equivalent medium.
561545
@@ -575,7 +559,7 @@ class RLCNetwork(Tidy3dBaseModel):
575559
>>> RL_series = RLCNetwork(resistance=75,
576560
... inductance=1e-9,
577561
... network_topology="series"
578-
... ) # doctest: +SKIP
562+
... )
579563
580564
"""
581565

@@ -804,16 +788,8 @@ def _validate_single_element(cls, val, values):
804788
raise ValueError("At least one element must be defined in the 'RLCNetwork'.")
805789
return val
806790

807-
@pd.root_validator(pre=False)
808-
def _warn_rf_license(cls, values):
809-
log.warning(
810-
"ℹ️ ⚠️ RF simulations are subject to new license requirements in the future. You have instantiated at least one RF-specific component.",
811-
log_once=True,
812-
)
813-
return values
814-
815791

816-
class AdmittanceNetwork(Tidy3dBaseModel):
792+
class AdmittanceNetwork(MicrowaveBaseModel):
817793
"""Class for representing a network consisting of an arbitrary number of resistors,
818794
capacitors, and inductors. The network is represented in the Laplace domain
819795
as an admittance function. Provides additional functionality for representing the network
@@ -857,7 +833,7 @@ class AdmittanceNetwork(Tidy3dBaseModel):
857833
>>> b = (R, 0)
858834
>>> RC_parallel = AdmittanceNetwork(a=a,
859835
... b=b
860-
... ) # doctest: +SKIP
836+
... )
861837
862838
"""
863839

@@ -889,14 +865,6 @@ def _as_admittance_function(self) -> tuple[tuple[float, ...], tuple[float, ...]]
889865
"""
890866
return (self.a, self.b)
891867

892-
@pd.root_validator(pre=False)
893-
def _warn_rf_license(cls, values):
894-
log.warning(
895-
"ℹ️ ⚠️ RF simulations are subject to new license requirements in the future. You have instantiated at least one RF-specific component.",
896-
log_once=True,
897-
)
898-
return values
899-
900868

901869
class LinearLumpedElement(RectangularLumpedElement):
902870
"""Lumped element representing a network consisting of resistors, capacitors, and inductors.
@@ -919,14 +887,14 @@ class LinearLumpedElement(RectangularLumpedElement):
919887
>>> RL_series = RLCNetwork(resistance=75,
920888
... inductance=1e-9,
921889
... network_topology="series"
922-
... ) # doctest: +SKIP
890+
... )
923891
>>> linear_element = LinearLumpedElement(
924892
... center=[0, 0, 0],
925893
... size=[2, 0, 3],
926894
... voltage_axis=0,
927895
... network=RL_series,
928896
... name="LumpedRL"
929-
... ) # doctest: +SKIP
897+
... )
930898
931899
932900
See Also
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""Mixin for RF license warning."""
2+
3+
from __future__ import annotations
4+
5+
import sys
6+
7+
import pydantic.v1 as pd
8+
9+
from tidy3d.components.base import Tidy3dBaseModel
10+
from tidy3d.log import log
11+
12+
13+
def is_running_doctest():
14+
"""Detect if we're in a doctest environment (works with pytest)."""
15+
# Check for pytest's doctest plugin
16+
if "_pytest.doctest" in sys.modules:
17+
return True
18+
19+
# Check for standard doctest module execution
20+
if "doctest" in sys.modules:
21+
doctest_mod = sys.modules["doctest"]
22+
# Check if doctest.master exists (indicates active doctest run)
23+
if hasattr(doctest_mod, "master") and doctest_mod.master is not None:
24+
return True
25+
26+
return False
27+
28+
29+
class MicrowaveBaseModel(Tidy3dBaseModel):
30+
"""Base model that all RF and microwave specific components inherit from."""
31+
32+
@pd.root_validator(pre=False)
33+
def _warn_rf_license(cls, values):
34+
# Skip warning during doctest runs
35+
if not is_running_doctest():
36+
log.warning(
37+
"ℹ️ ⚠️ RF simulations are subject to new license requirements in the future. You have instantiated at least one RF-specific component.",
38+
log_once=True,
39+
)
40+
return values

0 commit comments

Comments
 (0)