Skip to content

Commit ceb2158

Browse files
Add taper support to AntennaArrayCalculator and refactor array factor calculation
- Implemented taper integration to allow amplitude weighting in antenna arrays - Refactored array factor computation for improved clarity and efficiency - Updated relevant tests and documentation accordingly
1 parent 15d1342 commit ceb2158

File tree

4 files changed

+627
-35
lines changed

4 files changed

+627
-35
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## [Unreleased]
99

1010
### Added
11+
- Added rectangular and radial taper support to `RectangularAntennaArrayCalculator` for phased array amplitude weighting; refactored array factor calculation for improved clarity and performance.
1112
- Selective simulation capabilities to `TerminalComponentModeler` via `run_only` and `element_mappings` fields, allowing users to run fewer simulations and extract only needed scattering matrix elements.
1213
- Added KLayout plugin, with DRC functionality for running design rule checks in `plugins.klayout.drc`. Supports running DRC on GDS files as well as `Geometry`, `Structure`, and `Simulation` objects.
1314

tests/test_plugins/test_array_factor.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,3 +722,94 @@ def test_rectangular_array_calculator_simulation_data_from_array_factor():
722722

723723
sim_data_from_array_factor = array_calculator.simulation_data_from_array_factor(sim_data)
724724
assert len(sim_data_from_array_factor.data) == 2
725+
726+
727+
def test_rectangular_array_calculator_array_factor_taper():
728+
"""Test the array factor for a rectangular array."""
729+
730+
n_x = 1
731+
n_y = 2
732+
n_z = 3
733+
734+
d_x = 0.4
735+
d_y = 0.5
736+
d_z = 0.6
737+
738+
phi_x = np.pi / 6
739+
phi_y = np.pi / 4
740+
phi_z = np.pi / 3
741+
742+
window = mw.TaylorWindow(sll=35, nbar=5)
743+
744+
with pytest.raises(pydantic.ValidationError):
745+
# Test invalid window type
746+
taper = mw.RadialTaper(window=window)
747+
748+
window = mw.TaylorTaperc(sll=35, nbar=5)
749+
750+
with pytest.raises(pydantic.ValidationError):
751+
# Test invalid window type
752+
taper = mw.RectangularTaper(window=window)
753+
754+
array_calculator = mw.RectangularAntennaArrayCalculator(
755+
array_size=(n_x, n_y, n_z),
756+
spacings=(d_x, d_y, d_z),
757+
phase_shifts=(phi_x, phi_y, phi_z),
758+
taper=None,
759+
)
760+
761+
# Test basic array factor calculation
762+
theta = np.linspace(0, np.pi, 10)
763+
phi = np.linspace(0, 2 * np.pi, 10)
764+
theta_grid, phi_grid = np.meshgrid(theta, phi)
765+
theta_grid = theta_grid.flatten()
766+
phi_grid = phi_grid.flatten()
767+
medium = td.Medium(permittivity=1)
768+
freqs = np.array([1e9, 2e9, 3e9])
769+
770+
af = array_calculator.array_factor(theta_grid, phi_grid, freqs, medium)
771+
assert af.shape == (100, 3)
772+
773+
af_exact = analytical_array_factor(
774+
(n_x, n_y, n_z), (d_x, d_y, d_z), (phi_x, phi_y, phi_z), theta_grid, phi_grid, freqs, medium
775+
)
776+
777+
assert np.allclose(np.abs(af), np.abs(af_exact))
778+
779+
cheb_window = mw.ChebWindow(at=45)
780+
taper = mw.RectangularTaper(window=cheb_window)
781+
782+
# Test array factor with amplitude multipliers
783+
array_calculator_amps = mw.RectangularAntennaArrayCalculator(
784+
array_size=(n_x, n_y, n_z),
785+
spacings=(d_x, d_y, d_z),
786+
phase_shifts=(phi_x, phi_y, phi_z),
787+
taper=taper,
788+
)
789+
af_amps = array_calculator_amps.array_factor(theta_grid, phi_grid, freqs, medium)
790+
assert af_amps.shape == (100, 3)
791+
792+
window = mw.TaylorTaperc(sll=35, nbar=5)
793+
taper = mw.RadialTaper(window=window)
794+
795+
# Test array factor with radial taper
796+
n_x = 5
797+
n_y = 8
798+
n_z = 9
799+
array_calculator_amps_nonuniform = mw.RectangularAntennaArrayCalculator(
800+
array_size=(n_x, n_y, n_z),
801+
spacings=(d_x, d_y, d_z),
802+
phase_shifts=(phi_x, phi_y, phi_z),
803+
taper=taper,
804+
)
805+
806+
af_amps_nonuniform = array_calculator_amps_nonuniform.array_factor(
807+
theta_grid, phi_grid, freqs, medium
808+
)
809+
810+
assert af_amps_nonuniform.shape == (100, 3)
811+
812+
# Test validation
813+
with pytest.raises(ValueError):
814+
# Test mismatched theta/phi lengths
815+
array_calculator_amps_nonuniform.array_factor(theta, phi[:5], freqs, medium)

tidy3d/plugins/microwave/__init__.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,17 @@
44

55
from . import models
66
from .array_factor import (
7+
BlackmanHarrisWindow,
8+
BlackmanWindow,
9+
ChebWindow,
10+
HammingWindow,
11+
HannWindow,
12+
KaiserWindow,
13+
RadialTaper,
714
RectangularAntennaArrayCalculator,
15+
RectangularTaper,
16+
TaylorTaperc,
17+
TaylorWindow,
818
)
919
from .auto_path_integrals import path_integrals_from_lumped_element
1020
from .custom_path_integrals import (
@@ -23,14 +33,24 @@
2333

2434
__all__ = [
2535
"AxisAlignedPathIntegral",
36+
"BlackmanHarrisWindow",
37+
"BlackmanWindow",
38+
"ChebWindow",
2639
"CurrentIntegralAxisAligned",
2740
"CurrentIntegralTypes",
2841
"CustomCurrentIntegral2D",
2942
"CustomPathIntegral2D",
3043
"CustomVoltageIntegral2D",
44+
"HammingWindow",
45+
"HannWindow",
3146
"ImpedanceCalculator",
47+
"KaiserWindow",
3248
"LobeMeasurer",
49+
"RadialTaper",
3350
"RectangularAntennaArrayCalculator",
51+
"RectangularTaper",
52+
"TaylorTaperc",
53+
"TaylorWindow",
3454
"VoltageIntegralAxisAligned",
3555
"VoltageIntegralTypes",
3656
"models",

0 commit comments

Comments
 (0)