Skip to content

Commit 0a6c2f8

Browse files
Ok ready to review
1 parent 20d1c16 commit 0a6c2f8

File tree

2 files changed

+38
-9
lines changed

2 files changed

+38
-9
lines changed

tidy3d/plugins/smatrix/component_modelers/terminal.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,14 +288,14 @@ def get_radiation_monitor_by_name(self, monitor_name: str) -> DirectivityMonitor
288288
return monitor
289289
raise Tidy3dKeyError(f"No radiation monitor named '{monitor_name}'.")
290290

291+
##### Backwards compatibility methods, should be external functions really#####
291292
def run(self, path_dir: str = DEFAULT_DATA_DIR):
292293
"""Solves for the scattering matrix of the system."""
293294
from tidy3d.plugins.smatrix.local_run import run
294295

295296
terminal_component_modeler_data = run(simulation=self, path_dir=path_dir)
296297
return terminal_component_modeler_data
297298

298-
##### Backwards compatibility methods, should be used within TerminalComponentModelerData really#####
299299
@staticmethod
300300
def _check_port_impedance_sign(Z_numpy: np.ndarray):
301301
"""Sanity check for consistent sign of real part of Z for each port across all frequencies."""
@@ -329,6 +329,10 @@ def _monitor_data_at_port_amplitude(
329329
monitor_data: MonitorData,
330330
a_port: Union[FreqDataArray, complex],
331331
) -> MonitorData:
332+
"""Normalize the monitor data to a desired complex amplitude of a port,
333+
represented by ``a_port``, where :math:`\\frac{1}{2}|a|^2` is the power
334+
incident from the port into the system.
335+
"""
332336
from tidy3d.plugins.smatrix.local_run import run
333337

334338
terminal_component_modeler_data = run(simulation=self)
@@ -476,6 +480,28 @@ def get_antenna_metrics_data(
476480
port_amplitudes: Optional[dict[str, complex]] = None,
477481
monitor_name: Optional[str] = None,
478482
) -> AntennaMetricsData:
483+
"""Calculate antenna parameters using superposition of fields from multiple port excitations.
484+
485+
The method computes the radiated far fields and port excitation power wave amplitudes
486+
for a superposition of port excitations, which can be used to analyze antenna radiation
487+
characteristics.
488+
489+
Parameters
490+
----------
491+
port_amplitudes : dict[str, complex] = None
492+
Dictionary mapping port names to their desired excitation amplitudes. For each port,
493+
:math:`\\frac{1}{2}|a|^2` represents the incident power from that port into the system.
494+
If None, uses only the first port without any scaling of the raw simulation data.
495+
monitor_name : str = None
496+
Name of the :class:`.DirectivityMonitor` to use for calculating far fields.
497+
If None, uses the first monitor in `radiation_monitors`.
498+
499+
Returns
500+
-------
501+
:class:`.AntennaMetricsData`
502+
Container with antenna parameters including directivity, gain, and radiation efficiency,
503+
computed from the superposition of fields from all excited ports.
504+
"""
479505
from tidy3d.plugins.smatrix.local_run import run
480506

481507
terminal_component_modeler_data = run(simulation=self)

tidy3d/plugins/smatrix/local_run.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111

1212
from __future__ import annotations
1313

14-
import typing
15-
1614
import numpy as np
1715

1816
from tidy3d.components.data.sim_data import SimulationData
@@ -28,17 +26,18 @@
2826
from tidy3d.plugins.smatrix.data.data_array import PortDataArray, TerminalPortDataArray
2927
from tidy3d.plugins.smatrix.ports.wave import WavePort
3028
from tidy3d.plugins.smatrix.utils import check_port_impedance_sign, compute_F, compute_port_VI
29+
from tidy3d.web import BatchData
3130

3231

3332
def run(
3433
simulation: TerminalComponentModeler,
35-
batch_data: typing.Any = None,
34+
batch_data: BatchData = None,
3635
path_dir: str = DEFAULT_DATA_DIR,
3736
) -> TerminalComponentModelerData:
3837
_ = simulation.get_path_dir(path_dir)
3938

4039
if batch_data is None:
41-
# Remove once fully decoupled simulation from batch_data
40+
# TODO Remove once fully decoupled simulation from batch_data
4241
batch_data = simulation.batch_data
4342

4443
terminal_port_data = construct_smatrix(simulation=simulation)
@@ -54,7 +53,7 @@ def run(
5453

5554

5655
def construct_smatrix(
57-
simulation: TerminalComponentModeler, batch_data: typing.Any = None
56+
simulation: TerminalComponentModeler, batch_data: BatchData = None
5857
) -> TerminalPortDataArray:
5958
"""Post process :class:`.BatchData` to generate scattering matrix."""
6059
if batch_data is None:
@@ -91,11 +90,15 @@ def construct_smatrix(
9190
return s_matrix
9291

9392

94-
def port_reference_impedances(simulation: TerminalComponentModeler) -> PortDataArray:
93+
def port_reference_impedances(
94+
simulation: TerminalComponentModeler, batch_data: BatchData = None
95+
) -> PortDataArray:
9596
"""Tabulates the reference impedance of each port at each frequency using the
9697
supplied :class:`.BatchData`.
9798
"""
98-
# TODO properly refactor, plugins data types should not have web methods.
99+
if batch_data is None:
100+
# TODO Remove once fully decoupled simulation from batch_data
101+
batch_data = simulation.batch_data
99102

100103
port_names = [port.name for port in simulation.ports]
101104

@@ -108,7 +111,7 @@ def port_reference_impedances(simulation: TerminalComponentModeler) -> PortDataA
108111
for port in simulation.ports:
109112
if isinstance(port, WavePort):
110113
# Mode solver data for each wave port is stored in its associated SimulationData
111-
sim_data_port = simulation.batch_data[simulation._task_name(port=port)]
114+
sim_data_port = batch_data[simulation._task_name(port=port)]
112115
# WavePorts have a port impedance calculated from its associated modal field distribution
113116
# and is frequency dependent.
114117
impedances = port.compute_port_impedance(sim_data_port).values

0 commit comments

Comments
 (0)