Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: flux and poynting properties for FieldProjectionCartesianData #1874

Merged
merged 1 commit into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `autograd` gradient calculations can be performed on the server by passing `local_gradient = False` into `web.run()` or `web.run_async()`.
- Automatic differentiation with `autograd` supports multiple frequencies through single, broadband adjoint simulation when the objective function can be formulated as depending on a single dataset in the output `SimulationData` with frequency dependence only.
- Convenience method `EMESimulation.subsection` to create a new EME simulation based on a subregion of an existing one.
- Added `flux` and `poynting` properties to `FieldProjectionCartesianData`.

### Changed
- Error if field projection monitors found in 2D simulations, except `FieldProjectionAngleMonitor` with `far_field_approx = True`. Support for other monitors and for exact field projection will be coming in a subsequent Tidy3D version.
Expand Down
4 changes: 4 additions & 0 deletions tests/test_components/test_field_projection.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ def test_proj_clientside():
far_fields_cartesian.fields_cartesian
far_fields_cartesian.radar_cross_section
far_fields_cartesian.power
far_fields_cartesian.poynting
far_fields_cartesian.flux
for val in far_fields_cartesian.field_components.values():
val.sel(f=f0)
far_fields_cartesian.renormalize_fields(proj_distance=5e6)
Expand All @@ -366,6 +368,8 @@ def test_proj_clientside():
exact_fields_cartesian.fields_cartesian
exact_fields_cartesian.radar_cross_section
exact_fields_cartesian.power
exact_fields_cartesian.poynting
exact_fields_cartesian.flux
for val in exact_fields_cartesian.field_components.values():
val.sel(f=f0)
with pytest.raises(DataError):
Expand Down
29 changes: 29 additions & 0 deletions tidy3d/components/data/monitor_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -2465,6 +2465,35 @@ def z(self) -> np.ndarray:
"""Z positions."""
return self.Etheta.z.values

@property
def tangential_dims(self):
tangential_dims = ["x", "y", "z"]
tangential_dims.pop(self.monitor.proj_axis)
return tangential_dims

@property
def poynting(self) -> xr.DataArray:
"""Time-averaged Poynting vector for field data associated to a Cartesian field projection monitor."""
fc = self.fields_cartesian
dim1, dim2 = self.tangential_dims

e1 = fc["E" + dim1]
e2 = fc["E" + dim2]
h1 = fc["H" + dim1]
h2 = fc["H" + dim2]

e1_h2 = e1 * h2.conj()
e2_h1 = e2 * h1.conj()

e_x_h_star = e1_h2 - e2_h1
return 0.5 * np.real(e_x_h_star)

@cached_property
def flux(self) -> FluxDataArray:
"""Flux for projecteded field data corresponding to a Cartesian field projection monitor."""
flux = self.poynting.integrate(self.tangential_dims)
return FluxDataArray(flux)

def renormalize_fields(self, proj_distance: float) -> FieldProjectionCartesianData:
"""Return a :class:`.FieldProjectionCartesianData` with fields re-normalized to a new
projection distance, by applying a phase factor based on ``proj_distance``.
Expand Down
Loading