Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
465 changes: 465 additions & 0 deletions schemas/Simulation.json

Large diffs are not rendered by default.

465 changes: 465 additions & 0 deletions schemas/TerminalComponentModeler.json

Large diffs are not rendered by default.

14 changes: 13 additions & 1 deletion tests/test_components/test_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,14 @@ def test_diffraction_validators():
FREQS = np.array([1, 2, 3]) * 1e12


def test_gaussian_overlap_monitors_basic():
g = td.GaussianOverlapMonitor(size=(1, 1, 0), name="g", freqs=FREQS)
a = td.AstigmaticGaussianOverlapMonitor(size=(1, 1, 0), name="a", freqs=FREQS)
for m in (g, a):
s = m.storage_size(num_cells=10, tmesh=[0.0, 1.0])
assert isinstance(s, int) and s > 0


def test_monitor():
size = (1, 2, 3)
center = (1, 2, 3)
Expand Down Expand Up @@ -381,10 +389,14 @@ def test_monitor():
m10 = td.PermittivityMonitor(size=size, center=center, freqs=FREQS, name="perm")
m11 = td.AuxFieldTimeMonitor(size=size, center=center, name="aux_field_time", fields=("Nfx",))
m12 = td.MediumMonitor(size=size, center=center, freqs=FREQS, name="mat")
m13 = td.GaussianOverlapMonitor(size=(1, 1, 0), center=center, freqs=FREQS, name="gauss")
m14 = td.AstigmaticGaussianOverlapMonitor(
size=(1, 1, 0), center=center, freqs=FREQS, name="astigauss"
)

tmesh = np.linspace(0, 1, 10)

for m in [m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m12]:
for m in [m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14]:
m.storage_size(num_cells=100, tmesh=tmesh)

for m in [m2, m4]:
Expand Down
16 changes: 16 additions & 0 deletions tests/test_data/test_monitor_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
DiffractionData,
DirectivityData,
FieldData,
FieldOverlapData,
FieldTimeData,
FluxData,
FluxTimeData,
Expand Down Expand Up @@ -223,6 +224,16 @@ def make_mode_data():
return ModeData(monitor=MODE_MONITOR, amps=AMPS.copy(), n_complex=N_COMPLEX.copy())


def make_field_overlap_data():
monitor = td.GaussianOverlapMonitor(
size=(0, 2, 2),
freqs=[1e14, 1.1e14],
name="gaussian_overlap_monitor",
store_fields_direction="+",
)
return FieldOverlapData(monitor=monitor, amps=AMPS)


def make_flux_data():
return FluxData(monitor=FLUX_MONITOR, flux=FLUX.copy())

Expand Down Expand Up @@ -412,6 +423,11 @@ def test_mode_data():
_ = data.k_eff


def test_overlap_data():
data = make_field_overlap_data()
_ = data.amps


def test_flux_data():
data = make_flux_data()
_ = data.flux
Expand Down
45 changes: 36 additions & 9 deletions tests/test_plugins/smatrix/test_component_modeler.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@
import tidy3d as td
from tidy3d import SimulationDataMap
from tidy3d.exceptions import SetupError, Tidy3dKeyError
from tidy3d.plugins.smatrix import ModalComponentModeler, ModalComponentModelerData, Port
from tidy3d.plugins.smatrix import (
AstigmaticGaussianPort,
GaussianPort,
ModalComponentModeler,
ModalComponentModelerData,
Port,
)
from tidy3d.web.api.container import Batch

from ...utils import run_emulated
Expand Down Expand Up @@ -144,6 +150,7 @@ def offset(u):

def make_ports():
sim = make_coupler()

# source
src_pos = sim.size[0] / 2 - straight_wg_length / 2

Expand Down Expand Up @@ -179,7 +186,28 @@ def make_ports():
name="left_bot",
)

return [port_right_top, port_right_bot, port_left_top, port_left_bot]
# Gaussian ports on top and bottom
port_z_bot = AstigmaticGaussianPort(
center=[0, 0, wg_height + 0.1],
size=(10, 10, 0),
direction="-",
name="z_top",
angle_theta=0.0,
angle_phi=0.0,
pol_angle=0.0,
)

port_z_top = GaussianPort(
center=[0, 0, -0.1],
size=(10, 10, 0),
direction="+",
name="z_bot",
angle_theta=0.0,
angle_phi=0.0,
pol_angle=0.0,
)

return [port_right_top, port_right_bot, port_left_top, port_left_bot, port_z_bot, port_z_top]


def make_component_modeler(**kwargs):
Expand Down Expand Up @@ -283,13 +311,12 @@ def test_run_component_modeler(monkeypatch):
s_matrix = modeler_data.smatrix()

for port_in in modeler.ports:
for mode_index_in in range(port_in.mode_spec.num_modes):
for mode_index_in in range(port_in.num_modes):
for port_out in modeler.ports:
for mode_index_out in range(port_out.mode_spec.num_modes):
for mode_index_out in range(port_out.num_modes):
coords_in = {"port_in": port_in.name, "mode_index_in": mode_index_in}
coords_out = {"port_out": port_out.name, "mode_index_out": mode_index_out}

assert np.all(s_matrix.sel(**coords_in) != 0), (
assert np.all(s_matrix.sel(**coords_in).sel(mode_index_out=0) != 0), (
"source index not present in S matrix"
)
assert np.all(s_matrix.sel(**coords_in).sel(**coords_out) != 0), (
Expand All @@ -309,7 +336,7 @@ def test_component_modeler_run_only(monkeypatch):
coords_in_run_only = {"port_in": port_run_only, "mode_index_in": mode_index_run_only}

# make sure the run only mappings are non-zero
assert np.all(s_matrix.sel(**coords_in_run_only) != 0)
assert np.all(s_matrix.sel(**coords_in_run_only).sel(mode_index_out=0) != 0)

# make sure if we zero out the run_only mappings, everythging is zero
s_matrix.loc[coords_in_run_only] = 0
Expand Down Expand Up @@ -370,7 +397,7 @@ def test_mapping_exclusion(monkeypatch):

# add a mapping to each element in the row of EXCLUDE_INDEX
for port in ports:
for mode_index in range(port.mode_spec.num_modes):
for mode_index in range(port.num_modes):
row_index = (port.name, mode_index)
if row_index != EXCLUDE_INDEX:
mapping = ((row_index, row_index), (row_index, EXCLUDE_INDEX), +1)
Expand Down Expand Up @@ -400,7 +427,7 @@ def test_mapping_with_run_only():
run_only = []
# add a mapping to each element in the row of EXCLUDE_INDEX
for port in ports:
for mode_index in range(port.mode_spec.num_modes):
for mode_index in range(port.num_modes):
# Test that providing a list is properly handled
row_index = [port.name, mode_index]
run_only.append(row_index)
Expand Down
39 changes: 39 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,43 @@ def make_mode_data(monitor: td.ModeMonitor) -> td.ModeData:
**field_cmps,
)

# New: Gaussian-like overlap monitor data
def make_gaussian_overlap_data(monitor: td.GaussianOverlapMonitor) -> td.FieldOverlapData:
"""Random FieldOverlapData from a GaussianOverlapMonitor."""
grid = simulation.discretize_monitor(monitor)
coords_amps = {
"direction": ["+", "-"],
"f": list(monitor.freqs),
"mode_index": [0], # singleton for Gaussian ports
}
amps = make_data(coords=coords_amps, data_array_type=td.ModeAmpsDataArray, is_complex=True)
return td.FieldOverlapData(
monitor=monitor,
amps=amps,
symmetry=(0, 0, 0),
symmetry_center=simulation.center,
grid_expanded=grid,
)

def make_astig_gaussian_overlap_data(
monitor: td.AstigmaticGaussianOverlapMonitor,
) -> td.FieldOverlapData:
"""Random FieldOverlapData from an AstigmaticGaussianOverlapMonitor."""
grid = simulation.discretize_monitor(monitor)
coords_amps = {
"direction": ["+", "-"],
"f": list(monitor.freqs),
"mode_index": [0], # singleton for Gaussian ports
}
amps = make_data(coords=coords_amps, data_array_type=td.ModeAmpsDataArray, is_complex=True)
return td.FieldOverlapData(
monitor=monitor,
amps=amps,
symmetry=(0, 0, 0),
symmetry_center=simulation.center,
grid_expanded=grid,
)

def make_flux_data(monitor: td.FluxMonitor) -> td.FluxData:
"""make a random ModeData from a ModeMonitor."""

Expand Down Expand Up @@ -1480,6 +1517,8 @@ def make_flux_time_data(monitor: td.FluxTimeMonitor) -> td.FluxTimeData:
td.FieldProjectionKSpaceMonitor: make_field_projection_kspace_data,
td.AuxFieldTimeMonitor: make_aux_field_time_data,
td.FluxTimeMonitor: make_flux_time_data,
td.GaussianOverlapMonitor: make_gaussian_overlap_data,
td.AstigmaticGaussianOverlapMonitor: make_astig_gaussian_overlap_data,
}

data = [MONITOR_MAKER_MAP[type(mnt)](mnt) for mnt in simulation.monitors]
Expand Down
6 changes: 6 additions & 0 deletions tidy3d/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@
DiffractionData,
DirectivityData,
FieldData,
FieldOverlapData,
FieldProjectionAngleData,
FieldProjectionCartesianData,
FieldProjectionKSpaceData,
Expand Down Expand Up @@ -345,6 +346,7 @@

# monitors
from .components.monitor import (
AstigmaticGaussianOverlapMonitor,
AuxFieldTimeMonitor,
DiffractionMonitor,
DirectivityMonitor,
Expand All @@ -356,6 +358,7 @@
FieldTimeMonitor,
FluxMonitor,
FluxTimeMonitor,
GaussianOverlapMonitor,
MediumMonitor,
ModeMonitor,
ModeSolverMonitor,
Expand Down Expand Up @@ -492,6 +495,7 @@ def set_logging_level(level: str) -> None:
"ApodizationSpec",
"AstigmaticGaussianBeam",
"AstigmaticGaussianBeamProfile",
"AstigmaticGaussianOverlapMonitor",
"AugerRecombination",
"AutoGrid",
"AutoImpedanceSpec",
Expand Down Expand Up @@ -600,6 +604,7 @@ def set_logging_level(level: str) -> None:
"FieldDataset",
"FieldGrid",
"FieldMonitor",
"FieldOverlapData",
"FieldProjectionAngleData",
"FieldProjectionAngleDataArray",
"FieldProjectionAngleMonitor",
Expand Down Expand Up @@ -631,6 +636,7 @@ def set_logging_level(level: str) -> None:
"GaussianBeam",
"GaussianBeamProfile",
"GaussianDoping",
"GaussianOverlapMonitor",
"GaussianPulse",
"Geometry",
"GeometryGroup",
Expand Down
Loading