Skip to content

Commit 0418b53

Browse files
fix: _stored_freqs in MicrowaveModeSolverMonitor
1 parent 3797b69 commit 0418b53

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

tests/test_components/test_mode_interp.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,112 @@ def test_mode_solver_with_reduce_data_but_small_num_freqs():
885885
assert data.interpolated_copy == data
886886

887887

888+
@pytest.mark.parametrize(
889+
"num_freqs,num_points,reduce_data,expected_stored_len",
890+
[
891+
# No interp_spec (num_points=None)
892+
(10, None, None, 10),
893+
# interp_spec with reduce_data=False
894+
(10, 5, False, 10),
895+
(10, 8, False, 10),
896+
# interp_spec with reduce_data=True and num_points < len(monitor.freqs)
897+
(20, 5, True, 5),
898+
(20, 10, True, 10),
899+
# interp_spec with reduce_data=True and num_points >= len(monitor.freqs)
900+
(10, 10, True, 10),
901+
(10, 15, True, 10),
902+
(5, 10, True, 5),
903+
],
904+
)
905+
@pytest.mark.parametrize("rf", [False, True])
906+
def test_mode_solver_data_stored_freqs(num_freqs, num_points, reduce_data, expected_stored_len, rf):
907+
"""Test that _stored_freqs in ModeSolverData is correct based on interp_spec.
908+
909+
Cases tested:
910+
1. No interp_spec: _stored_freqs matches monitor.freqs
911+
2. interp_spec with reduce_data=False: _stored_freqs matches monitor.freqs
912+
3. interp_spec with reduce_data=True and num_points < len(monitor.freqs):
913+
len(_stored_freqs) == num_points
914+
4. interp_spec with reduce_data=True and num_points >= len(monitor.freqs):
915+
_stored_freqs matches monitor.freqs
916+
"""
917+
from tidy3d.components.data.data_array import ModeIndexDataArray
918+
919+
from ..test_data.test_data_arrays import SIM, make_scalar_mode_field_data_array
920+
921+
freqs = np.linspace(1e14, 2e14, num_freqs)
922+
923+
# Create mode_spec based on parameters
924+
if num_points is None:
925+
# No interp_spec
926+
mode_spec = td.ModeSpec(
927+
num_modes=2,
928+
sort_spec=td.ModeSortSpec(track_freq="central"),
929+
)
930+
else:
931+
# With interp_spec
932+
mode_spec = td.ModeSpec(
933+
num_modes=2,
934+
sort_spec=td.ModeSortSpec(track_freq="central"),
935+
interp_spec=td.ModeInterpSpec.uniform(
936+
num_points=num_points, method="linear", reduce_data=reduce_data
937+
),
938+
)
939+
940+
# Create monitor
941+
monitor = td.ModeSolverMonitor(
942+
center=(0, 0, 0),
943+
size=SIZE_2D,
944+
freqs=freqs,
945+
mode_spec=mode_spec,
946+
name="test_monitor",
947+
colocate=False,
948+
)
949+
950+
# Create n_complex with the expected stored frequencies
951+
mode_indices = np.arange(2)
952+
n_complex_values = (1.5 + 0.1j) * np.ones((expected_stored_len, 2))
953+
n_complex = ModeIndexDataArray(
954+
n_complex_values,
955+
coords={"f": np.linspace(1e14, 2e14, expected_stored_len), "mode_index": mode_indices},
956+
)
957+
958+
# Create ModeSolverData
959+
data = td.ModeSolverData(
960+
monitor=monitor,
961+
Ex=make_scalar_mode_field_data_array("Ex", symmetry=False),
962+
Ey=make_scalar_mode_field_data_array("Ey", symmetry=False),
963+
Ez=make_scalar_mode_field_data_array("Ez", symmetry=False),
964+
Hx=make_scalar_mode_field_data_array("Hx", symmetry=False),
965+
Hy=make_scalar_mode_field_data_array("Hy", symmetry=False),
966+
Hz=make_scalar_mode_field_data_array("Hz", symmetry=False),
967+
n_complex=n_complex,
968+
symmetry=(0, 0, 0),
969+
symmetry_center=(0, 0, 0),
970+
grid_expanded=SIM.discretize_monitor(monitor),
971+
)
972+
973+
if rf:
974+
mode_spec = td.MicrowaveModeSpec(**mode_spec.dict(exclude={"type"}))
975+
monitor = td.MicrowaveModeSolverMonitor(
976+
**monitor.dict(exclude={"type", "mode_spec"}), mode_spec=mode_spec
977+
)
978+
data = td.ModeSolverData(**data.dict(exclude={"type", "monitor"}), monitor=monitor)
979+
980+
# Check _stored_freqs length
981+
assert len(data.monitor._stored_freqs) == expected_stored_len, (
982+
f"Expected _stored_freqs length {expected_stored_len}, "
983+
f"got {len(data.monitor._stored_freqs)}"
984+
)
985+
986+
# Check that monitor.freqs always matches original freqs
987+
assert len(data.monitor.freqs) == num_freqs
988+
assert np.allclose(data.monitor.freqs, freqs)
989+
990+
# Check data shape matches _stored_freqs
991+
assert data.n_complex.shape[0] == expected_stored_len
992+
993+
888994
# ============================================================================
889995
# Monitor Integration Tests (Phase 6)
890996
# ============================================================================

tidy3d/components/microwave/monitor.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,8 @@ class MicrowaveModeSolverMonitor(MicrowaveModeMonitor, ModeSolverMonitor):
6868
... mode_spec=mode_spec,
6969
... name='mode_monitor')
7070
"""
71+
72+
@property
73+
def _stored_freqs(self) -> list[float]:
74+
"""Return actually stored frequencies of the data."""
75+
return self.mode_spec._sampling_freqs_mode_solver_data(freqs=self.freqs)

0 commit comments

Comments
 (0)