Skip to content

Commit 0e00e0d

Browse files
Leaving this so far, less ambitious refactor now
1 parent 49f3708 commit 0e00e0d

File tree

3 files changed

+130
-84
lines changed

3 files changed

+130
-84
lines changed

tidy3d/plugins/smatrix/component_modelers/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ def batch_data(self):
206206
"""The :class:`.BatchData` associated with the simulations run for this component modeler."""
207207
return self.batch.run(path_dir=self.path_dir)
208208

209-
def get_path_dir(self, path_dir: str) -> None:
209+
def get_path_dir(self, path_dir: str) -> str:
210210
"""Check whether the supplied 'path_dir' matches the internal field value."""
211211

212212
if path_dir != self.path_dir and path_dir != DEFAULT_DATA_DIR:

tidy3d/plugins/smatrix/component_modelers/terminal.py

Lines changed: 90 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
from __future__ import annotations
44

5-
import os
65
from typing import Optional, Union
76

87
import numpy as np
@@ -22,7 +21,6 @@
2221
from tidy3d.constants import C_0, OHM
2322
from tidy3d.exceptions import SetupError, Tidy3dError, Tidy3dKeyError, ValidationError
2423
from tidy3d.log import log
25-
from tidy3d.plugins.smatrix.component_modelers.base import DEFAULT_DATA_DIR
2624
from tidy3d.plugins.smatrix.data.terminal import PortDataArray, TerminalPortDataArray
2725
from tidy3d.plugins.smatrix.ports.base_lumped import AbstractLumpedPort
2826
from tidy3d.plugins.smatrix.ports.coaxial_lumped import CoaxialLumpedPort
@@ -327,41 +325,6 @@ def _source_time(self):
327325
fmin=min(self.freqs), fmax=max(self.freqs), remove_dc_component=self.remove_dc_component
328326
)
329327

330-
def _construct_smatrix(self) -> TerminalPortDataArray:
331-
"""Post process :class:`.BatchData` to generate scattering matrix."""
332-
return self._internal_construct_smatrix(batch_data=self.batch_data)
333-
334-
def _internal_construct_smatrix(self, batch_data) -> TerminalPortDataArray:
335-
"""Post process :class:`.BatchData` to generate scattering matrix, for internal use only."""
336-
337-
port_names = [port.name for port in self.ports]
338-
339-
values = np.zeros(
340-
(len(self.freqs), len(port_names), len(port_names)),
341-
dtype=complex,
342-
)
343-
coords = {
344-
"f": np.array(self.freqs),
345-
"port_out": port_names,
346-
"port_in": port_names,
347-
}
348-
a_matrix = TerminalPortDataArray(values, coords=coords)
349-
b_matrix = a_matrix.copy(deep=True)
350-
351-
# Tabulate the reference impedances at each port and frequency
352-
port_impedances = self._port_reference_impedances(batch_data=batch_data)
353-
354-
# loop through source ports
355-
for port_in in self.ports:
356-
sim_data = batch_data[self._task_name(port=port_in)]
357-
a, b = self.compute_power_wave_amplitudes_at_each_port(port_impedances, sim_data)
358-
indexer = {"f": a.f, "port_in": port_in.name, "port_out": a.port}
359-
a_matrix.loc[indexer] = a
360-
b_matrix.loc[indexer] = b
361-
362-
s_matrix = self.ab_to_s(a_matrix, b_matrix)
363-
return s_matrix
364-
365328
@pd.validator("simulation")
366329
def _validate_3d_simulation(cls, val):
367330
"""Error if :class:`.Simulation` is not a 3D simulation"""
@@ -453,60 +416,40 @@ def get_radiation_monitor_by_name(self, monitor_name: str) -> DirectivityMonitor
453416
return monitor
454417
raise Tidy3dKeyError(f"No radiation monitor named '{monitor_name}'.")
455418

456-
def run(self, path_dir: str = DEFAULT_DATA_DIR) -> TerminalComponentModelerData:
457-
"""Solves for the scattering matrix of the system."""
458-
_ = self.get_path_dir(path_dir)
459-
_ = self._upload_terminal_modeler()
460-
_ = self._construct_smatrix()
461-
462-
@cached_property
463-
def _terminal_modeler_path(self) -> str:
464-
"""Where we store the for this :class:`TerminalComponentModeler` instance after the run."""
465-
return os.path.join(self.path_dir, "tcp_" + str(hash(self)) + ".hdf5")
419+
# Backwards compatible methods
420+
@staticmethod
421+
def compute_port_VI(
422+
port_out: TerminalPortType, sim_data: SimulationData
423+
) -> tuple[FreqDataArray, FreqDataArray]:
424+
return compute_port_VI(port_out=port_out, sim_data=sim_data)
466425

467-
def _upload_terminal_modeler(self):
468-
# TODO properly refactor, plugins data types should not have web methods.
469-
from tidy3d.web.api.container import Job
470-
471-
# first try loading the terminal_component_modeler from file, if it exists
472-
terminal_modeler_path = self._terminal_modeler_path
473-
474-
if os.path.exists(terminal_modeler_path):
475-
return Job.from_file(fname=terminal_modeler_path)
476-
477-
return Job(
478-
simulation=self,
479-
task_name=self.name,
480-
folder_name=self.folder_name,
481-
callback_url=self.callback_url,
482-
verbose=self.verbose,
483-
solver_version=self.solver_version,
484-
simulation_type="microwave",
426+
def compute_power_wave_amplitudes_at_each_port(
427+
self, port_reference_impedances: PortDataArray, sim_data: SimulationData
428+
) -> tuple[PortDataArray, PortDataArray]:
429+
return TerminalComponentModelerData().compute_power_wave_amplitudes_at_each_port(
430+
port_reference_impedances=port_reference_impedances, sim_data=sim_data
485431
)
486432

433+
def _construct_smatrix(self) -> TerminalPortDataArray:
434+
pass
435+
436+
def _internal_construct_smatrix(self, batch_data: BatchData) -> TerminalPortDataArray:
437+
pass
438+
487439
@cached_property
488440
def batch(self):
489441
""":class:`.Batch` associated with this component modeler."""
490-
# TODO properly refactor, plugins data types should not have web methods.
491-
from tidy3d.web.api.container import Batch
492-
493-
if self.batch_cached is not None:
494-
return self.batch_cached
442+
from tidy3d.plugins.smatrix.web import batch
495443

496-
# first try loading the batch from file, if it exists
497-
batch_path = self._batch_path
444+
return batch(self)
498445

499-
if os.path.exists(batch_path):
500-
return Batch.from_file(fname=batch_path)
446+
@cached_property
447+
def batch_path(self) -> str:
448+
"""Path to the batch saved to file."""
501449

502-
return Batch(
503-
simulations=self.sim_dict,
504-
folder_name=self.folder_name,
505-
callback_url=self.callback_url,
506-
verbose=self.verbose,
507-
solver_version=self.solver_version,
508-
simulation_type="microwave",
509-
)
450+
@cached_property
451+
def batch_data(self):
452+
"""The :class:`.BatchData` associated with the simulations run for this component modeler."""
510453

511454

512455
class SMatrixData:
@@ -741,10 +684,74 @@ def compute_power_wave_amplitudes_at_each_port(
741684
V_numpy = np.where(negative_real_Z, -V_numpy, V_numpy)
742685
Z_numpy = np.where(negative_real_Z, -Z_numpy, Z_numpy)
743686

744-
F_numpy = TerminalComponentModeler._compute_F(Z_numpy)
687+
F_numpy = _compute_F(Z_numpy)
745688

746689
# Equation 4.67 - Pozar - Microwave Engineering 4ed
747690
a.values = F_numpy * (V_numpy + Z_numpy * I_numpy)
748691
b.values = F_numpy * (V_numpy - np.conj(Z_numpy) * I_numpy)
749692

750693
return a, b
694+
695+
696+
def _construct_smatrix(batch_data) -> TerminalPortDataArray:
697+
"""Post process :class:`.BatchData` to generate scattering matrix."""
698+
return _internal_construct_smatrix(batch_data=batch_data)
699+
700+
701+
def _internal_construct_smatrix(simulation: TerminalComponentModeler) -> TerminalPortDataArray:
702+
"""Post process :class:`.BatchData` to generate scattering matrix, for internal use only."""
703+
704+
port_names = [port.name for port in simulation.ports]
705+
706+
values = np.zeros(
707+
(len(simulation.freqs), len(port_names), len(port_names)),
708+
dtype=complex,
709+
)
710+
coords = {
711+
"f": np.array(simulation.freqs),
712+
"port_out": port_names,
713+
"port_in": port_names,
714+
}
715+
a_matrix = TerminalPortDataArray(values, coords=coords)
716+
b_matrix = a_matrix.copy(deep=True)
717+
718+
# Tabulate the reference impedances at each port and frequency
719+
port_impedances = simulation._port_reference_impedances(batch_data=batch_data)
720+
721+
# loop through source ports
722+
for port_in in simulation.ports:
723+
sim_data = batch_data[simulation._task_name(port=port_in)]
724+
a, b = compute_power_wave_amplitudes_at_each_port(port_impedances, sim_data)
725+
indexer = {"f": a.f, "port_in": port_in.name, "port_out": a.port}
726+
a_matrix.loc[indexer] = a
727+
b_matrix.loc[indexer] = b
728+
729+
s_matrix = ab_to_s(a_matrix, b_matrix)
730+
return s_matrix
731+
732+
733+
# @cached_property
734+
# def _terminal_modeler_path(self) -> str:
735+
# """Where we store the for this :class:`TerminalComponentModeler` instance after the run."""
736+
# return os.path.join(self.path_dir, "tcp_" + str(hash(self)) + ".hdf5")
737+
#
738+
#
739+
# def _upload_terminal_modeler(self):
740+
# # TODO properly refactor, plugins data types should not have web methods.
741+
# from tidy3d.web.api.container import Job
742+
#
743+
# # first try loading the terminal_component_modeler from file, if it exists
744+
# terminal_modeler_path = self._terminal_modeler_path
745+
#
746+
# if os.path.exists(terminal_modeler_path):
747+
# return Job.from_file(fname=terminal_modeler_path)
748+
#
749+
# return Job(
750+
# simulation=self,
751+
# task_name=self.name,
752+
# folder_name=self.folder_name,
753+
# callback_url=self.callback_url,
754+
# verbose=self.verbose,
755+
# solver_version=self.solver_version,
756+
# simulation_type="microwave",
757+
# )

tidy3d/plugins/smatrix/web.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from __future__ import annotations
2+
3+
4+
def run_local(
5+
simulation: TerminalComponentModeler, path_dir: str = DEFAULT_DATA_DIR
6+
) -> TerminalComponentModelerData:
7+
"""Solves for the scattering matrix of the system."""
8+
path_dir = simulation.get_path_dir(path_dir)
9+
batch_data = batch(simulation)
10+
smatrix_batch_data = _construct_smatrix(batch_data)
11+
smatrix_data = SMatrixData(a=smatrix_batch_data)
12+
terminal_component_modeler_data = TerminalComponentModelerData(
13+
simulation=simulation, data=(smatrix_data,)
14+
)
15+
return terminal_component_modeler_data
16+
17+
18+
def batch(simulation: TerminalComponentModeler):
19+
""":class:`.Batch` associated with this component modeler."""
20+
# TODO properly refactor, plugins data types should not have web methods.
21+
from tidy3d.web.api.container import Batch
22+
23+
if simulation.batch_cached is not None:
24+
return simulation.batch_cached
25+
26+
# first try loading the batch from file, if it exists
27+
batch_path = simulation._batch_path
28+
29+
if os.path.exists(batch_path):
30+
return Batch.from_file(fname=batch_path)
31+
32+
return Batch(
33+
simulations=simulation.sim_dict,
34+
folder_name=simulation.folder_name,
35+
callback_url=simulation.callback_url,
36+
verbose=simulation.verbose,
37+
solver_version=simulation.solver_version,
38+
simulation_type="microwave",
39+
)

0 commit comments

Comments
 (0)