Skip to content

Commit 055de12

Browse files
weiliangjin2021daquinteroflex
authored andcommitted
⚠️ Issue license warning for RF simulations
Co-authored-by: Dario Quintero <[email protected]>
1 parent f1bc896 commit 055de12

File tree

21 files changed

+234
-20
lines changed

21 files changed

+234
-20
lines changed

docs/api/microwave/index.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
Microwave |:satellite:|
22
=======================
33

4+
.. warning::
5+
6+
RF simulations are subject to new license requirements in the future. These components are within the RF scope.
7+
8+
49
.. toctree::
510
:hidden:
611

docs/api/plugins/microwave.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
Microwave
44
----------------------------
55

6+
.. warning::
7+
8+
RF simulations are subject to new license requirements in the future. These components are within the RF scope.
9+
10+
611
.. autosummary::
712
:toctree: ../_autosummary/
813
:template: module.rst

docs/api/plugins/smatrix.rst

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,21 @@ Scattering Matrix Calculator
1010
tidy3d.plugins.smatrix.ComponentModeler
1111
tidy3d.plugins.smatrix.Port
1212
tidy3d.plugins.smatrix.ModalPortDataArray
13+
14+
15+
.. warning::
16+
17+
RF simulations are subject to new license requirements in the future.
18+
The components below are within the RF scope.
19+
20+
21+
.. autosummary::
22+
:toctree: ../_autosummary/
23+
:template: module.rst
24+
1325
tidy3d.plugins.smatrix.TerminalComponentModeler
1426
tidy3d.plugins.smatrix.PortDataArray
1527
tidy3d.plugins.smatrix.TerminalPortDataArray
1628
tidy3d.plugins.smatrix.LumpedPort
1729
tidy3d.plugins.smatrix.CoaxialLumpedPort
18-
tidy3d.plugins.smatrix.WavePort
30+
tidy3d.plugins.smatrix.WavePort

tidy3d/components/data/monitor_data.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3469,9 +3469,9 @@ class DirectivityData(FieldProjectionAngleData):
34693469
>>> values = (1+1j) * np.random.random((len(r), len(theta), len(phi), len(f)))
34703470
>>> flux_data = FluxDataArray(np.random.random(len(f)), coords=coords_flux)
34713471
>>> scalar_field = FieldProjectionAngleDataArray(values, coords=coords)
3472-
>>> monitor = DirectivityMonitor(center=(1,2,3), size=(2,2,2), freqs=f, name='n2f_monitor', phi=phi, theta=theta)
3472+
>>> monitor = DirectivityMonitor(center=(1,2,3), size=(2,2,2), freqs=f, name='n2f_monitor', phi=phi, theta=theta) # doctest: +SKIP
34733473
>>> data = DirectivityData(monitor=monitor, flux=flux_data, Er=scalar_field, Etheta=scalar_field, Ephi=scalar_field,
3474-
... Hr=scalar_field, Htheta=scalar_field, Hphi=scalar_field, projection_surfaces=monitor.projection_surfaces)
3474+
... Hr=scalar_field, Htheta=scalar_field, Hphi=scalar_field, projection_surfaces=monitor.projection_surfaces) # doctest: +SKIP
34753475
"""
34763476

34773477
monitor: DirectivityMonitor = pd.Field(

tidy3d/components/eme/simulation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ class EMESimulation(AbstractYeeGridSimulation):
122122
>>> from tidy3d import Box, Medium, Structure, C_0, inf
123123
>>> from tidy3d import EMEModeSpec, EMEUniformGrid, GridSpec
124124
>>> from tidy3d import EMEFieldMonitor
125-
>>> lambda0 = 1
125+
>>> lambda0 = 1550e-9
126126
>>> freq0 = C_0 / lambda0
127127
>>> sim_size = 3*lambda0, 3*lambda0, 3*lambda0
128128
>>> waveguide_size = (lambda0/2, lambda0, inf)

tidy3d/components/lumped_element.py

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import numpy as np
1010
import pydantic.v1 as pd
1111

12+
from tidy3d.log import log
13+
1214
from ..components.grid.grid import Grid
1315
from ..components.medium import (
1416
PEC2D,
@@ -110,6 +112,14 @@ def to_structures(self, grid: Grid = None) -> list[Structure]:
110112
which are ready to be added to the :class:`.Simulation`"""
111113
return [self.to_structure(grid)]
112114

115+
@pd.root_validator(pre=False)
116+
def _warn_rf_license(cls, values):
117+
log.warning(
118+
"ℹ️ ⚠️ RF simulations are subject to new license requirements in the future. You are have instantiated at least one RF-specific component.",
119+
log_once=True,
120+
)
121+
return values
122+
113123

114124
class RectangularLumpedElement(LumpedElement, Box):
115125
"""Class representing a rectangular element with zero thickness. A :class:`RectangularLumpedElement`
@@ -543,6 +553,14 @@ def complex_permittivity(a: tuple[float, ...], b: tuple[float, ...], freqs: np.n
543553
sigma = NetworkConversions.complex_conductivity(a, b, freqs)
544554
return 1j * sigma / (2 * np.pi * freqs * EPSILON_0)
545555

556+
@pd.root_validator(pre=False)
557+
def _warn_rf_license(cls, values):
558+
log.warning(
559+
"ℹ️ ⚠️ RF simulations are subject to new license requirements in the future. You are have instantiated at least one RF-specific component.",
560+
log_once=True,
561+
)
562+
return values
563+
546564

547565
class RLCNetwork(Tidy3dBaseModel):
548566
"""Class for representing a simple network consisting of a resistor, capacitor, and inductor.
@@ -564,7 +582,7 @@ class RLCNetwork(Tidy3dBaseModel):
564582
>>> RL_series = RLCNetwork(resistance=75,
565583
... inductance=1e-9,
566584
... network_topology="series"
567-
... )
585+
... ) # doctest: +SKIP
568586
569587
"""
570588

@@ -794,6 +812,14 @@ def _validate_single_element(cls, val, values):
794812
raise ValueError("At least one element must be defined in the 'RLCNetwork'.")
795813
return val
796814

815+
@pd.root_validator(pre=False)
816+
def _warn_rf_license(cls, values):
817+
log.warning(
818+
"ℹ️ ⚠️ RF simulations are subject to new license requirements in the future. You are have instantiated at least one RF-specific component.",
819+
log_once=True,
820+
)
821+
return values
822+
797823

798824
class AdmittanceNetwork(Tidy3dBaseModel):
799825
"""Class for representing a network consisting of an arbitrary number of resistors,
@@ -839,7 +865,7 @@ class AdmittanceNetwork(Tidy3dBaseModel):
839865
>>> b = (R, 0)
840866
>>> RC_parallel = AdmittanceNetwork(a=a,
841867
... b=b
842-
... )
868+
... ) # doctest: +SKIP
843869
844870
"""
845871

@@ -871,6 +897,14 @@ def _as_admittance_function(self) -> tuple[tuple[float, ...], tuple[float, ...]]
871897
"""
872898
return (self.a, self.b)
873899

900+
@pd.root_validator(pre=False)
901+
def _warn_rf_license(cls, values):
902+
log.warning(
903+
"ℹ️ ⚠️ RF simulations are subject to new license requirements in the future. You are have instantiated at least one RF-specific component.",
904+
log_once=True,
905+
)
906+
return values
907+
874908

875909
class LinearLumpedElement(RectangularLumpedElement):
876910
"""Lumped element representing a network consisting of resistors, capacitors, and inductors.
@@ -893,14 +927,15 @@ class LinearLumpedElement(RectangularLumpedElement):
893927
>>> RL_series = RLCNetwork(resistance=75,
894928
... inductance=1e-9,
895929
... network_topology="series"
896-
... )
930+
... ) # doctest: +SKIP
897931
>>> linear_element = LinearLumpedElement(
898932
... center=[0, 0, 0],
899933
... size=[2, 0, 3],
900934
... voltage_axis=0,
901935
... network=RL_series,
902936
... name="LumpedRL"
903-
... )
937+
... ) # doctest: +SKIP
938+
904939
905940
See Also
906941
--------

tidy3d/components/microwave/data/monitor_data.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from tidy3d.components.data.data_array import FieldProjectionAngleDataArray, FreqDataArray
1111
from tidy3d.components.data.monitor_data import DirectivityData
1212
from tidy3d.components.types import PolarizationBasis
13+
from tidy3d.log import log
1314

1415

1516
class AntennaMetricsData(DirectivityData):
@@ -36,8 +37,8 @@ class AntennaMetricsData(DirectivityData):
3637
... name="rad_monitor",
3738
... phi=phi,
3839
... theta=theta
39-
... )
40-
>>> power_data = FreqDataArray(np.random.random(len(f)), coords=coords_flux)
40+
... ) # doctest: +SKIP
41+
>>> power_data = FreqDataArray(np.random.random(len(f)), coords=coords_flux) # doctest: +SKIP
4142
>>> data = AntennaMetricsData(
4243
... monitor=monitor,
4344
... projection_surfaces=monitor.projection_surfaces,
@@ -50,7 +51,7 @@ class AntennaMetricsData(DirectivityData):
5051
... Hphi=scalar_field,
5152
... power_incident=power_data,
5253
... power_reflected=power_data
53-
... )
54+
... ) # doctest: +SKIP
5455
5556
Notes
5657
-----
@@ -194,3 +195,11 @@ def realized_gain(self) -> FieldProjectionAngleDataArray:
194195
"""The realized gain figure of merit for antennas. Realized gain is dimensionless."""
195196
partial_G = self.partial_realized_gain()
196197
return partial_G.Gtheta + partial_G.Gphi
198+
199+
@pd.root_validator(pre=False)
200+
def _warn_rf_license(cls, values):
201+
log.warning(
202+
"ℹ️ ⚠️ RF simulations are subject to new license requirements in the future. You are have instantiated at least one RF-specific component.",
203+
log_once=True,
204+
)
205+
return values

tidy3d/components/mode/simulation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class ModeSimulation(AbstractYeeGridSimulation):
8383
Example
8484
-------
8585
>>> from tidy3d import C_0, ModeSpec, BoundarySpec, Boundary
86-
>>> lambda0 = 1
86+
>>> lambda0 = 1550e-9
8787
>>> freq0 = C_0 / lambda0
8888
>>> freqs = [freq0]
8989
>>> sim_size = lambda0, lambda0, 0

tidy3d/components/monitor.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,14 @@ def storage_size(self, num_cells: int, tmesh: ArrayFloat1D) -> int:
12061206
self.freqs
12071207
) * 6 + BYTES_REAL * len(self.freqs)
12081208

1209+
@pydantic.root_validator(pre=False)
1210+
def _warn_rf_license(cls, values):
1211+
log.warning(
1212+
"ℹ️ ⚠️ RF simulations are subject to new license requirements in the future. You are have instantiated at least one RF-specific component.",
1213+
log_once=True,
1214+
)
1215+
return values
1216+
12091217

12101218
class FieldProjectionCartesianMonitor(AbstractFieldProjectionMonitor):
12111219
""":class:`Monitor` that samples electromagnetic near fields in the frequency domain

tidy3d/components/simulation.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
except ImportError:
1616
pass
1717

18+
1819
import pydantic.v1 as pydantic
1920
import xarray as xr
2021

@@ -174,6 +175,9 @@
174175
# additional (safety) time step reduction factor for fixed angle simulations
175176
FIXED_ANGLE_DT_SAFETY_FACTOR = 0.9
176177

178+
# RF frequency warning
179+
RF_FREQ_WARNING = 1e12
180+
177181

178182
def validate_boundaries_for_zero_dims():
179183
"""Error if absorbing boundaries, bloch boundaries, unmatching pec/pmc, or symmetry is used along a zero dimension."""
@@ -3596,6 +3600,41 @@ def _post_init_validators(self) -> None:
35963600
self._validate_custom_source_time()
35973601
self._validate_mode_object_bends()
35983602
self._warn_mode_object_pml()
3603+
self._warn_rf_license()
3604+
3605+
def _warn_rf_license(self):
3606+
"""
3607+
Warn about new licensing requirements for RF simulations. This function details all the conditions in which a
3608+
simulation is categorised as RF simulation at the backend.
3609+
"""
3610+
# RF component messages
3611+
rf_component_breakdown_msg = ""
3612+
3613+
# 1) lossy metal
3614+
for mat in self.scene.mediums:
3615+
if isinstance(mat, LossyMetalMedium):
3616+
rf_component_breakdown_msg += "\n - Contains a 'LossyMetalMedium'."
3617+
break
3618+
3619+
# 2) lumped elements
3620+
if len(self.lumped_elements) > 0:
3621+
rf_component_breakdown_msg += "\n - Contains a 'LumpedElement'."
3622+
3623+
# 3) source frequency is in RF range
3624+
if (self.frequency_range[0] < RF_FREQ_WARNING) & (self.frequency_range[0] != 0):
3625+
rf_component_breakdown_msg += "\n - Contains sources defined for RF wavelengths."
3626+
3627+
# 4) monitor frequency is in RF range
3628+
for monitor in self.monitors:
3629+
if isinstance(monitor, FreqMonitor) and monitor.frequency_range[0] < RF_FREQ_WARNING:
3630+
rf_component_breakdown_msg += "\n - Contains monitors defined for RF wavelengths."
3631+
break
3632+
3633+
# issue warning
3634+
if rf_component_breakdown_msg != "":
3635+
msg = " ℹ️ ⚠️ RF simulations are subject to new license requirements in the future. You are using RF-specific components in this simulation."
3636+
msg += rf_component_breakdown_msg
3637+
log.warning(msg, log_once=True)
35993638

36003639
def _warn_mode_object_pml(self) -> None:
36013640
"""Warn if any mode objects have large pml."""

0 commit comments

Comments
 (0)