Skip to content

Commit

Permalink
Refractored DirectivitData: radiation characteristics are computed vi…
Browse files Browse the repository at this point in the history
…a properties
  • Loading branch information
QimingFlex committed Jan 7, 2025
1 parent 3bd312e commit e3212ef
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 116 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added an option to simulate plane wave propagation at fixed angles by setting parameter `angular_spec=FixedAngleSpec()` when defining a `PlaneWave` source.
- The universal `tidy3d.web` can now also be used to handle `ModeSolver` simulations.
- Support for differentiation with respect to `PolySlab.slab_bounds`.
- `DirectivityMonitor` can now be used to decompose fields into circular polarization states.

### Changed
- Priority is given to `snapping_points` in `GridSpec` when close to structure boundaries, which reduces the chance of them being skipped.
Expand All @@ -51,6 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `estimate_cost` is now called at the end of every `web.upload` call.
- Internal refactor of adjoint shape gradients using `GradientSurfaceMesh`.
- Enhanced progress bar display in batch operations with better formatting, colors, and status tracking.
- The behavior of `DirectivityData` was changed, so that only far fields and flux are stored. Radiation characteristics (e.g., directivity, axial ratio) can be accessed through properties.

### Fixed
- Significant speedup for field projection computations.
Expand Down
24 changes: 7 additions & 17 deletions tests/test_data/test_data_arrays.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,21 +184,16 @@ def make_mode_index_data_array():
return td.ModeIndexDataArray(values, coords=dict(f=FS, mode_index=MODE_INDICES))


def make_far_field_data_array():
values = (1 + 1j) * np.random.random((len(PD), len(THETAS), len(PHIS), len(FS)))
return td.FieldProjectionAngleDataArray(values, coords=dict(r=PD, theta=THETAS, phi=PHIS, f=FS))


def make_flux_data_array():
values = np.random.random(len(FS))
return td.FluxDataArray(values, coords=dict(f=FS))


def make_directivity_data_array():
values = np.random.random((len(PD), len(THETAS), len(PHIS), len(FS)))
return td.DirectivityDataArray(values, coords=dict(r=PD, theta=THETAS, phi=PHIS, f=FS))


def make_axial_ratio_data_array():
values = np.random.random((len(PD), len(THETAS), len(PHIS), len(FS)))
return td.AxialRatioDataArray(values, coords=dict(r=PD, theta=THETAS, phi=PHIS, f=FS))


def make_flux_time_data_array():
values = np.random.random(len(TS))
return td.FluxTimeDataArray(values, coords=dict(t=TS))
Expand Down Expand Up @@ -261,13 +256,8 @@ def test_flux_time_data_array():
data = data.interp(t=1e-13)


def test_directivity_data_array():
data = make_directivity_data_array()
data = data.sel(f=1e14, phi=0)


def test_axial_ratio_data_array():
data = make_axial_ratio_data_array()
def test_far_field_data_array():
data = make_far_field_data_array()
data = data.sel(f=1e14, phi=0)


Expand Down
18 changes: 12 additions & 6 deletions tests/test_data/test_monitor_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@
PERMITTIVITY_MONITOR,
SIM,
SIM_SYM,
make_axial_ratio_data_array,
make_diffraction_data_array,
make_directivity_data_array,
make_far_field_data_array,
make_flux_data_array,
make_flux_time_data_array,
make_mode_amps_data_array,
Expand All @@ -54,9 +53,6 @@
GRID_CORRECTION = FreqModeDataArray(
1 + 0.01 * np.random.rand(*N_COMPLEX.shape), coords=N_COMPLEX.coords
)
DIRECTIVITY = make_directivity_data_array()
AXIALRATIO = make_axial_ratio_data_array()

""" Make the montor data """


Expand Down Expand Up @@ -190,8 +186,16 @@ def make_flux_data():


def make_directivity_data():
data = make_far_field_data_array()
return DirectivityData(
monitor=DIRECTIVITY_MONITOR, directivity=DIRECTIVITY.copy(), axial_ratio=AXIALRATIO.copy()
monitor=DIRECTIVITY_MONITOR,
flux=FLUX.copy(),
Er=data,
Etheta=data,
Ephi=data,
Hr=data,
Htheta=data,
Hphi=data,
)


Expand Down Expand Up @@ -337,6 +341,8 @@ def test_directivity_data():
data = make_directivity_data()
_ = data.directivity
_ = data.axial_ratio
_ = data.left_polarization
_ = data.right_polarization


def test_diffraction_data():
Expand Down
4 changes: 0 additions & 4 deletions tidy3d/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,9 @@

# data
from .components.data.data_array import (
AxialRatioDataArray,
CellDataArray,
ChargeDataArray,
DiffractionDataArray,
DirectivityDataArray,
EMECoefficientDataArray,
EMEModeIndexDataArray,
EMEScalarFieldDataArray,
Expand Down Expand Up @@ -417,8 +415,6 @@ def set_logging_level(level: str) -> None:
"FieldProjectionCartesianDataArray",
"FieldProjectionKSpaceDataArray",
"DiffractionDataArray",
"DirectivityDataArray",
"AxialRatioDataArray",
"HeatDataArray",
"ChargeDataArray",
"FieldDataset",
Expand Down
51 changes: 0 additions & 51 deletions tidy3d/components/data/data_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -921,55 +921,6 @@ class FieldProjectionAngleDataArray(DataArray):
_data_attrs = {"long_name": "radiation vectors"}


class DirectivityDataArray(DataArray):
"""Directivity in the frequency domain as a function of angles theta and phi.
Directivity is a dimensionless quantity defined as the ratio of the radiation
intensity in a given direction to the average radiation intensity over all directions.
Example
-------
>>> f = np.linspace(1e14, 2e14, 10)
>>> r = np.atleast_1d(5)
>>> theta = np.linspace(0, np.pi, 10)
>>> phi = np.linspace(0, 2*np.pi, 20)
>>> coords = dict(r=r, theta=theta, phi=phi, f=f)
>>> values = np.random.random((len(r), len(theta), len(phi), len(f)))
>>> data = DirectivityDataArray(values, coords=coords)
"""

__slots__ = ()
_dims = ("r", "theta", "phi", "f")
_data_attrs = {"long_name": "radiation intensity"}


class AxialRatioDataArray(DataArray):
"""Axial Ratio (AR) in the frequency domain as a function of angles theta and phi.
AR is a dimensionless quantity defined as the ratio of the major axis to the minor
axis of the polarization ellipse.
Note
----
The axial ratio computation is based on:
Balanis, Constantine A., "Antenna Theory: Analysis and Design,"
John Wiley & Sons, Chapter 2.12 (2016).
Example
-------
>>> f = np.linspace(1e14, 2e14, 10)
>>> r = np.atleast_1d(5)
>>> theta = np.linspace(0, np.pi, 10)
>>> phi = np.linspace(0, 2*np.pi, 20)
>>> coords = dict(r=r, theta=theta, phi=phi, f=f)
>>> values = np.random.random((len(r), len(theta), len(phi), len(f)))
>>> data = AxialRatioDataArray(values, coords=coords)
"""

__slots__ = ()
_dims = ("r", "theta", "phi", "f")
_data_attrs = {"long_name": "axial ratio"}


class FieldProjectionCartesianDataArray(DataArray):
"""Far fields in frequency domain as a function of local x and y coordinates.
Expand Down Expand Up @@ -1267,8 +1218,6 @@ class IndexedDataArray(DataArray):
FieldProjectionCartesianDataArray,
FieldProjectionKSpaceDataArray,
DiffractionDataArray,
DirectivityDataArray,
AxialRatioDataArray,
FreqModeDataArray,
FreqDataArray,
TimeDataArray,
Expand Down
Loading

0 comments on commit e3212ef

Please sign in to comment.