Skip to content

Commit 6b987dd

Browse files
committed
improve validation when using power waves
1 parent 86b866d commit 6b987dd

File tree

2 files changed

+97
-6
lines changed

2 files changed

+97
-6
lines changed

tests/test_plugins/smatrix/test_terminal_component_modeler.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,6 +1147,58 @@ def test_run_only_and_element_mappings(monkeypatch, tmp_path):
11471147
assert len(modeler_with_mappings.sim_dict) == 2
11481148

11491149

1150+
def test_validate_S_def():
1151+
"""Test that the S_def field is validated correctly, especially when it is set to 'power'."""
1152+
# Create a base modeler using the existing convenience function
1153+
modeler = make_component_modeler(planar_pec=True)
1154+
1155+
port0_idx = modeler.network_index(modeler.ports[0])
1156+
port1_idx = modeler.network_index(modeler.ports[1])
1157+
S11 = (port0_idx, port0_idx)
1158+
S21 = (port1_idx, port0_idx)
1159+
S12 = (port0_idx, port1_idx)
1160+
S22 = (port1_idx, port1_idx)
1161+
element_mappings = ((S11, S22, 1),)
1162+
1163+
# S_def="pseudo" is the most flexible choice when running a subset of simulations
1164+
modeler_pseudo = (
1165+
modeler.updated_copy(
1166+
S_def="pseudo",
1167+
assume_ideal_excitation=True,
1168+
run_only=(modeler.ports[0].name,),
1169+
),
1170+
)
1171+
1172+
# S_def="power" with assume_ideal_excitation=True should fail
1173+
with pytest.raises(pd.ValidationError):
1174+
modeler.updated_copy(
1175+
S_def="power",
1176+
assume_ideal_excitation=True,
1177+
)
1178+
1179+
# S_def="power" with run_only not None should fail
1180+
with pytest.raises(pd.ValidationError):
1181+
modeler.updated_copy(
1182+
S_def="power",
1183+
run_only=(modeler.ports[0].name,),
1184+
)
1185+
1186+
# S_def="power" with element_mappings not empty should fail
1187+
with pytest.raises(pd.ValidationError):
1188+
modeler.updated_copy(
1189+
S_def="power",
1190+
element_mappings=element_mappings,
1191+
)
1192+
1193+
# S_def="power" with all valid settings should pass
1194+
modeler_power_valid = modeler.updated_copy(
1195+
S_def="power",
1196+
assume_ideal_excitation=False,
1197+
run_only=None,
1198+
element_mappings=(),
1199+
)
1200+
1201+
11501202
def test_internal_construct_smatrix_with_port_vi(monkeypatch):
11511203
"""Test _internal_construct_smatrix method by monkeypatching compute_port_VI
11521204
with precomputed voltage and current values and comparing the final S-matrix to expected results.

tidy3d/plugins/smatrix/component_modelers/terminal.py

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@ class TerminalComponentModeler(AbstractComponentModeler[NetworkIndex, NetworkEle
7272
title="Assume Ideal Excitation",
7373
description="If ``True``, only the excited port is assumed to have a nonzero incident wave "
7474
"amplitude power. This choice simplifies the calculation of the scattering matrix. "
75-
"If ``False``, every entry in the vector of incident power wave "
76-
"amplitudes (a) is calculated explicitly. This choice requires a matrix inversion when "
77-
"calculating the scattering matrix, but may lead to more accurate scattering parameters "
78-
"when there are reflections from simulation boundaries. ",
75+
"If ``False``, every entry in the vector of incident wave amplitudes (a) is calculated "
76+
"explicitly. This choice requires a matrix inversion when calculating the scattering "
77+
"matrix, but may lead to more accurate scattering parameters when there are "
78+
"reflections from simulation boundaries. ",
7979
)
8080

8181
S_def: SDef = pd.Field(
@@ -92,6 +92,45 @@ def _warn_rf_license(cls, values):
9292
)
9393
return values
9494

95+
@pd.validator("S_def", always=True)
96+
def _validate_S_def(cls, S_def, values):
97+
"""
98+
Check that the scattering parameter computation is set up correctly for the power wave definition.
99+
"""
100+
101+
if S_def == "pseudo":
102+
return S_def
103+
104+
assume_ideal_excitation = values.get("assume_ideal_excitation")
105+
if assume_ideal_excitation is True:
106+
raise SetupError(
107+
"Setting `assume_ideal_excitation` to ``True`` is incompatible with "
108+
"using the power wave definition of scattering parameters. "
109+
"Either use the pseudo wave definition by setting 'S_def' to 'pseudo', "
110+
"or set 'assume_ideal_excitation' to ``False``. "
111+
)
112+
113+
run_only = values.get("run_only")
114+
if run_only is not None:
115+
raise SetupError(
116+
"Computing scattering parameters using the power wave definition "
117+
"requires running a number of simulations equal to the number of ports. "
118+
"Either use the pseudo wave definition by setting 'S_def' to 'pseudo', "
119+
"or ensure all simulations are run by setting 'run_only' to 'None'. "
120+
)
121+
122+
element_mappings = values.get("element_mappings")
123+
if len(element_mappings) != 0:
124+
raise SetupError(
125+
"Computing scattering parameters using the power wave definition "
126+
"requires running a number of simulations equal to the number of ports. "
127+
"Either use the pseudo wave definition by setting 'S_def' to 'pseudo', "
128+
"or ensure all simulations are run by keeping 'element_mappings' as its "
129+
"default value of an empty 'tuple'. "
130+
)
131+
132+
return S_def
133+
95134
@equal_aspect
96135
@add_ax_if_none
97136
def plot_sim(
@@ -132,15 +171,15 @@ def plot_sim_eps(
132171

133172
@staticmethod
134173
def network_index(port: TerminalPortType, mode_index: Optional[int] = None) -> NetworkIndex:
135-
"""Converts the port, and a ``mode_index`` when the port is a :class:`.WavePort``, to a unique string specifier.
174+
"""Converts the port, and a ``mode_index`` when the port is a :class:`.WavePort`, to a unique string specifier.
136175
137176
Parameters
138177
----------
139178
port : ``TerminalPortType``
140179
The port to convert to an index.
141180
mode_index : Optional[int]
142181
Selects a single mode from those supported by the ``port``, which is only used when
143-
the ``port`` is a :class:`.WavePort``
182+
the ``port`` is a :class:`.WavePort`
144183
145184
Returns
146185
-------

0 commit comments

Comments
 (0)