Skip to content

Commit 0d64dad

Browse files
another revision
1 parent dc4be8a commit 0d64dad

File tree

11 files changed

+292
-182
lines changed

11 files changed

+292
-182
lines changed

schemas/EMESimulation.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8168,6 +8168,10 @@
81688168
"minimum": 2,
81698169
"type": "integer"
81708170
},
8171+
"reduce_data": {
8172+
"default": false,
8173+
"type": "boolean"
8174+
},
81718175
"type": {
81728176
"default": "ModeInterpSpec",
81738177
"enum": [
@@ -8374,10 +8378,6 @@
83748378
"minLength": 1,
83758379
"type": "string"
83768380
},
8377-
"reduce_data": {
8378-
"default": false,
8379-
"type": "boolean"
8380-
},
83818381
"size": {
83828382
"anyOf": [
83838383
{

schemas/ModeSimulation.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7374,6 +7374,10 @@
73747374
"minimum": 2,
73757375
"type": "integer"
73767376
},
7377+
"reduce_data": {
7378+
"default": false,
7379+
"type": "boolean"
7380+
},
73777381
"type": {
73787382
"default": "ModeInterpSpec",
73797383
"enum": [
@@ -7812,10 +7816,6 @@
78127816
"minLength": 1,
78137817
"type": "string"
78147818
},
7815-
"reduce_data": {
7816-
"default": false,
7817-
"type": "boolean"
7818-
},
78197819
"size": {
78207820
"anyOf": [
78217821
{

schemas/Simulation.json

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11002,10 +11002,6 @@
1100211002
"minLength": 1,
1100311003
"type": "string"
1100411004
},
11005-
"reduce_data": {
11006-
"default": false,
11007-
"type": "boolean"
11008-
},
1100911005
"size": {
1101011006
"anyOf": [
1101111007
{
@@ -11344,6 +11340,10 @@
1134411340
"minimum": 2,
1134511341
"type": "integer"
1134611342
},
11343+
"reduce_data": {
11344+
"default": false,
11345+
"type": "boolean"
11346+
},
1134711347
"type": {
1134811348
"default": "ModeInterpSpec",
1134911349
"enum": [
@@ -11782,10 +11782,6 @@
1178211782
"minLength": 1,
1178311783
"type": "string"
1178411784
},
11785-
"reduce_data": {
11786-
"default": false,
11787-
"type": "boolean"
11788-
},
1178911785
"size": {
1179011786
"anyOf": [
1179111787
{

schemas/TerminalComponentModeler.json

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11344,10 +11344,6 @@
1134411344
"minLength": 1,
1134511345
"type": "string"
1134611346
},
11347-
"reduce_data": {
11348-
"default": false,
11349-
"type": "boolean"
11350-
},
1135111347
"size": {
1135211348
"anyOf": [
1135311349
{
@@ -11686,6 +11682,10 @@
1168611682
"minimum": 2,
1168711683
"type": "integer"
1168811684
},
11685+
"reduce_data": {
11686+
"default": false,
11687+
"type": "boolean"
11688+
},
1168911689
"type": {
1169011690
"default": "ModeInterpSpec",
1169111691
"enum": [
@@ -12124,10 +12124,6 @@
1212412124
"minLength": 1,
1212512125
"type": "string"
1212612126
},
12127-
"reduce_data": {
12128-
"default": false,
12129-
"type": "boolean"
12130-
},
1213112127
"size": {
1213212128
"anyOf": [
1213312129
{

tests/test_components/test_mode_interp.py

Lines changed: 137 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,22 @@ def test_interp_spec_valid_linear():
2727
spec = td.ModeInterpSpec(num_points=5, method="linear")
2828
assert spec.num_points == 5
2929
assert spec.method == "linear"
30+
assert not spec.reduce_data # default value
3031

3132

3233
def test_interp_spec_valid_cubic():
3334
"""Test creating valid ModeInterpSpec with cubic interpolation."""
3435
spec = td.ModeInterpSpec(num_points=10, method="cubic")
3536
assert spec.num_points == 10
3637
assert spec.method == "cubic"
38+
assert not spec.reduce_data # default value
3739

3840

3941
def test_interp_spec_default_method():
40-
"""Test that default method is 'linear'."""
42+
"""Test that default method is 'linear' and reduce_data is False."""
4143
spec = td.ModeInterpSpec(num_points=5)
4244
assert spec.method == "linear"
45+
assert not spec.reduce_data
4346

4447

4548
def test_interp_spec_cubic_needs_4_points():
@@ -117,6 +120,22 @@ def test_interp_spec_invalid_method():
117120
td.ModeInterpSpec(num_points=5, method="quadratic")
118121

119122

123+
def test_interp_spec_reduce_data_true():
124+
"""Test creating ModeInterpSpec with reduce_data=True."""
125+
spec = td.ModeInterpSpec(num_points=5, method="linear", reduce_data=True)
126+
assert spec.num_points == 5
127+
assert spec.method == "linear"
128+
assert spec.reduce_data
129+
130+
131+
def test_interp_spec_reduce_data_false():
132+
"""Test creating ModeInterpSpec with reduce_data=False (explicit)."""
133+
spec = td.ModeInterpSpec(num_points=5, method="linear", reduce_data=False)
134+
assert spec.num_points == 5
135+
assert spec.method == "linear"
136+
assert not spec.reduce_data
137+
138+
120139
def test_interp_spec_requires_tracking():
121140
"""Test that ModeMonitor with interp_spec requires track_freq."""
122141

@@ -291,12 +310,13 @@ def test_mode_solver_warns_num_points():
291310
plane = td.Box(center=(0, 0, 0), size=SIZE_2D)
292311

293312
with AssertLogLevel("WARNING", contains_str="Interpolation will be skipped"):
294-
ModeSolver(
313+
ms = ModeSolver(
295314
simulation=sim,
296315
plane=plane,
297316
freqs=FREQS_DENSE,
298317
mode_spec=mode_spec,
299318
)
319+
_ = ms.data_raw
300320

301321

302322
def test_mode_solver_interp_spec_none():
@@ -643,15 +663,19 @@ def test_mode_solver_data_interp_extrapolation_warning():
643663

644664

645665
def test_mode_solver_with_interp():
646-
"""Test that ModeSolver uses interpolation when interp_spec is provided."""
666+
"""Test that ModeSolver uses interpolation when interp_spec is provided.
667+
668+
With reduce_data=False (default), data_raw returns automatically interpolated data
669+
with all requested frequencies.
670+
"""
647671
sim = get_simple_sim()
648672

649-
# Create solver with 10 frequencies
673+
# Create solver with 10 frequencies, reduce_data=False (default)
650674
freqs = np.linspace(1e14, 2e14, 10)
651675
mode_spec = td.ModeSpec(
652676
num_modes=2,
653677
sort_spec=td.ModeSortSpec(track_freq="central"),
654-
interp_spec=td.ModeInterpSpec(num_points=3, method="linear"),
678+
interp_spec=td.ModeInterpSpec(num_points=3, method="linear", reduce_data=False),
655679
)
656680

657681
solver_with_interp = ModeSolver(
@@ -664,10 +688,11 @@ def test_mode_solver_with_interp():
664688
# The solver should have the original 10 frequencies
665689
assert len(solver_with_interp.freqs) == 10
666690

667-
# The returned data should have 10 frequencies
691+
# With reduce_data=False, data_raw automatically interpolates and returns all 10 frequencies
668692
data = solver_with_interp.data_raw
669693
assert len(data.monitor.freqs) == 10
670694
assert data.n_complex.shape[0] == 10
695+
assert not data.reduced_data # After interpolation, reduced_data is False
671696

672697

673698
def test_mode_solver_creates_reduced_freqs():
@@ -752,7 +777,7 @@ def test_mode_solver_interp_cheb():
752777
mode_spec = td.ModeSpec(
753778
num_modes=2,
754779
sort_spec=td.ModeSortSpec(track_freq="central"),
755-
interp_spec=td.ModeInterpSpec(num_points=5, method="cheb"),
780+
interp_spec=td.ModeInterpSpec(num_points=5, method="cheb", reduce_data=False),
756781
)
757782

758783
solver = ModeSolver(
@@ -762,6 +787,8 @@ def test_mode_solver_interp_cheb():
762787
mode_spec=mode_spec,
763788
)
764789

790+
_ = solver._data_on_yee_grid()
791+
765792
data = solver.data_raw
766793
assert len(data.monitor.freqs) == 20
767794
assert data.n_complex.shape[0] == 20
@@ -785,6 +812,44 @@ def test_mode_solver_without_interp_returns_full_data():
785812
data = solver.data_raw
786813
assert len(data.monitor.freqs) == 10
787814
assert data.n_complex.shape[0] == 10
815+
assert not data.reduced_data
816+
817+
818+
def test_mode_solver_with_reduce_data_true():
819+
"""Test that ModeSolver with reduce_data=True returns data at reduced frequencies.
820+
821+
With reduce_data=True, data_raw returns data computed only at the reduced set
822+
of frequencies. The monitor in the data also has only the reduced frequencies.
823+
"""
824+
sim = get_simple_sim()
825+
826+
# Create solver with 20 frequencies but reduce_data=True
827+
freqs = np.linspace(1e14, 2e14, 20)
828+
mode_spec = td.ModeSpec(
829+
num_modes=2,
830+
sort_spec=td.ModeSortSpec(track_freq="central"),
831+
interp_spec=td.ModeInterpSpec(num_points=5, method="linear", reduce_data=True),
832+
)
833+
834+
solver = ModeSolver(
835+
simulation=sim,
836+
plane=td.Box(center=(0, 0, 0), size=SIZE_2D),
837+
freqs=freqs,
838+
mode_spec=mode_spec,
839+
)
840+
841+
# With reduce_data=True, data_raw returns data at only 5 frequencies
842+
data = solver.data_raw
843+
assert len(data._stored_freqs) == 5 # Only the reduced frequencies
844+
assert len(data.monitor.freqs) == 20 # All frequencies
845+
assert data.n_complex.shape[0] == 5
846+
assert data.reduced_data
847+
848+
# interpolated_copy will interpolate to monitor.freqs, but since the monitor
849+
# only has the reduced frequencies, it just returns the same frequencies
850+
data_interpolated = data.interpolated_copy
851+
assert len(data_interpolated.monitor.freqs) == 20 # Still only 5 frequencies
852+
assert not data_interpolated.reduced_data # But now marked as non-reduced
788853

789854

790855
# ============================================================================
@@ -890,6 +955,71 @@ def test_mode_monitor_interp_spec_none():
890955
assert monitor.mode_spec.interp_spec is None
891956

892957

958+
def test_mode_solver_monitor_reduce_data_property():
959+
"""Test that ModeSolverMonitor.reduce_data property works correctly."""
960+
freqs = np.linspace(1e14, 2e14, 10)
961+
962+
# With reduce_data=True
963+
mode_spec = td.ModeSpec(
964+
num_modes=2,
965+
sort_spec=td.ModeSortSpec(track_freq="central"),
966+
interp_spec=td.ModeInterpSpec(num_points=3, method="linear", reduce_data=True),
967+
)
968+
monitor = td.ModeSolverMonitor(
969+
center=(0, 0, 0),
970+
size=SIZE_2D,
971+
freqs=freqs,
972+
mode_spec=mode_spec,
973+
name="test",
974+
)
975+
assert monitor.reduce_data
976+
977+
978+
def test_mode_solver_reduce_data_property():
979+
"""Test that ModeSolver.reduce_data property works correctly."""
980+
sim = get_simple_sim()
981+
freqs = np.linspace(1e14, 2e14, 10)
982+
plane = td.Box(center=(0, 0, 0), size=SIZE_2D)
983+
984+
# With reduce_data=True
985+
mode_spec_true = td.ModeSpec(
986+
num_modes=2,
987+
sort_spec=td.ModeSortSpec(track_freq="central"),
988+
interp_spec=td.ModeInterpSpec(num_points=3, method="linear", reduce_data=True),
989+
)
990+
solver_true = ModeSolver(
991+
simulation=sim,
992+
plane=plane,
993+
freqs=freqs,
994+
mode_spec=mode_spec_true,
995+
)
996+
assert solver_true.reduce_data
997+
998+
# With reduce_data=False
999+
mode_spec_false = td.ModeSpec(
1000+
num_modes=2,
1001+
sort_spec=td.ModeSortSpec(track_freq="central"),
1002+
interp_spec=td.ModeInterpSpec(num_points=3, method="linear", reduce_data=False),
1003+
)
1004+
solver_false = ModeSolver(
1005+
simulation=sim,
1006+
plane=plane,
1007+
freqs=freqs,
1008+
mode_spec=mode_spec_false,
1009+
)
1010+
assert not solver_false.reduce_data
1011+
1012+
# Without interp_spec
1013+
mode_spec_none = td.ModeSpec(num_modes=2, sort_spec=td.ModeSortSpec(track_freq="central"))
1014+
solver_none = ModeSolver(
1015+
simulation=sim,
1016+
plane=plane,
1017+
freqs=freqs,
1018+
mode_spec=mode_spec_none,
1019+
)
1020+
assert not solver_none.reduce_data
1021+
1022+
8931023
# ============================================================================
8941024
# WavePort interp_spec Tests
8951025
# ============================================================================

tidy3d/components/base.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,16 +1415,3 @@ def __getattribute__(self, name: str):
14151415

14161416
_LazyProxy.__name__ = proxy_name
14171417
return _LazyProxy
1418-
1419-
1420-
class InterpolatableMixin(Tidy3dBaseModel):
1421-
"""Mixin to add a `reduce_data` field to a model."""
1422-
1423-
reduce_data: bool = pydantic.Field(
1424-
False,
1425-
title="Reduce Data",
1426-
description="If `mode_spec.interp_spec` is defined, one can use this flag "
1427-
"to record fields and quatities only at interpolation source frequency points. "
1428-
"The :class:`.ModeMonitorData` at requested frequencies can be obtain through "
1429-
"the :attr:`.ModeMonitorData.interpolated_copy` property.",
1430-
)

0 commit comments

Comments
 (0)