Skip to content

Commit 619a2e7

Browse files
committed
fix: validation of 'freqs' in component modelers
1 parent 9a9f1f5 commit 619a2e7

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2222
- Improved the robustness of batch jobs. The batch state, including all `task_ids`, is now saved to `batch.hdf5` immediately after upload. This fixes an issue where an interrupted batch (e.g., due to a kernel crash or network loss) would be unrecoverable.
2323
- Fixed warning for running symmetric adjoint simulations by port to not trigger when there is a single port.
2424
- Bug in `CoaxialLumpedPort` where source injection is off when the `normal_axis` is not `z`.
25+
- Validation of `freqs` in the `ComponentModeler` and `TerminalComponentModeler`.
2526

2627
## [2.9.0] - 2025-08-04
2728

tests/test_plugins/smatrix/test_terminal_component_modeler.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,28 @@ def test_validate_no_sources(tmp_path):
8787
_ = modeler.copy(update={"simulation": sim_w_source})
8888

8989

90+
def test_validate_freqs():
91+
"""Ensure the 'freqs' array is strictly increasing and length of at least 2."""
92+
modeler = make_component_modeler(planar_pec=False)
93+
freqs = np.array([1.0])
94+
with pytest.raises(pd.ValidationError):
95+
_ = modeler.updated_copy(freqs=freqs)
96+
freqs = np.array([-1.0, 5])
97+
with pytest.raises(pd.ValidationError):
98+
_ = modeler.updated_copy(freqs=freqs)
99+
freqs = np.array([1, 2, 1.9])
100+
with pytest.raises(pd.ValidationError):
101+
_ = modeler.updated_copy(freqs=freqs)
102+
103+
# Test case with non-unique value
104+
f_min, f_max = (0.5e9, 1.5e9)
105+
f0 = (f_min + f_max) / 2
106+
f_target = 1.35e9
107+
freqs = np.sort(np.append(np.linspace(f_min, f_max, 21), f_target))
108+
with pytest.raises(pd.ValidationError):
109+
_ = modeler.updated_copy(freqs=freqs)
110+
111+
90112
def test_validate_3D_sim(tmp_path):
91113
modeler = make_component_modeler(planar_pec=False, path_dir=str(tmp_path))
92114
sim = td.Simulation(

tidy3d/plugins/smatrix/component_modelers/base.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,26 @@ def _warn_deprecation_2_10(cls, values):
147147
def _sim_has_no_sources(cls, val):
148148
"""Make sure simulation has no sources as they interfere with tool."""
149149
if len(val.sources) > 0:
150-
raise SetupError("'AbstractComponentModeler.simulation' must not have any sources.")
150+
raise SetupError(f"'{cls.__name__}.simulation' must not have any sources.")
151+
return val
152+
153+
@pd.validator("freqs", always=True)
154+
def _validate_freqs(cls, val):
155+
"""The array of frequencies must be sorted, unique and non-negative."""
156+
if len(val) < 2:
157+
raise SetupError(f"You must supply at least 2 entries for '{cls.__name__}.freqs'.")
158+
np_val = np.array(val)
159+
if not np.all(np_val >= 0):
160+
raise SetupError(f"'{cls.__name__}.freqs' must be an array of non-negative numbers.")
161+
# Ensure freqs is sorted
162+
diff = np.diff(np_val)
163+
if not np.all(diff > 0):
164+
violations = np.where(diff <= 0)[0] + 1
165+
raise SetupError(
166+
f"'{cls.__name__}.freqs' must be strictly increasing (unique values sorted "
167+
"in ascending order). "
168+
f"The entries at the following indices violated this requirement: {violations}."
169+
)
151170
return val
152171

153172
@pd.validator("ports", always=True)

0 commit comments

Comments
 (0)