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

Reorganizing grid correction application #1139

Merged
merged 1 commit into from
Sep 6, 2023
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
7 changes: 6 additions & 1 deletion tests/test_data/test_sim_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,12 @@ def test_intensity(monitor_name):
@pytest.mark.parametrize("monitor_name", ["field", "field_time", "mode_solver"])
def test_poynting(monitor_name):
sim_data = make_sim_data()
_ = sim_data.get_poynting_vector(monitor_name)
mnt_data = sim_data[monitor_name]
poynting = sim_data.get_poynting_vector(monitor_name)
zero_dims = mnt_data.monitor.zero_dims
if len(zero_dims) == 1:
comp = f"S{'xyz'[zero_dims[0]]}"
assert np.allclose(np.squeeze(poynting[comp].real), mnt_data.poynting)


def test_final_decay():
Expand Down
22 changes: 15 additions & 7 deletions tidy3d/components/data/monitor_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,14 +237,14 @@ def _tangential_dims(self) -> List[str]:

@property
def _in_plane(self) -> Dict[str, DataArray]:
"""Dictionary of field components with finite grid correction factors applied and symmetry
"""Dictionary of field components with monitor-normal direction dropped and symmetry
expanded."""
if len(self.monitor.zero_dims) != 1:
raise DataError("Data must be 2D to apply grid corrections.")

normal_dim = "xyz"[self.monitor.zero_dims[0]]
fields = {}
for field_name, field in self.grid_corrected_copy.field_components.items():
for field_name, field in self.symmetry_expanded_copy.field_components.items():
fields[field_name] = field.squeeze(dim=normal_dim, drop=True)
return fields

Expand Down Expand Up @@ -345,7 +345,11 @@ def _tangential_corrected(self, fields: Dict[str, DataArray]) -> Dict[str, DataA
such that the third component would be the normal axis. This just means that the H field
gets an extra minus sign if the normal axis is ``"y"``. Raise if any of the tangential
field components is missing.

The finite grid correction is also applied, so the intended use of these fields is in
poynting, flux, and dot-like methods.
"""

# Tangential field components
tan_dims = self._tangential_dims
components = [fname + dim for fname in "EH" for dim in tan_dims]
Expand All @@ -357,11 +361,19 @@ def _tangential_corrected(self, fields: Dict[str, DataArray]) -> Dict[str, DataA
if component not in fields:
raise DataError(f"Tangential field component '{component}' missing in field data.")

# sign correction to H
if normal_dim == "y" and component[0] == "H":
tan_fields[component] = -fields[component]
else:
tan_fields[component] = fields[component]

# finite grid correction to all fields
eig_val = self.symmetry_eigenvalues[component](normal_dim)
if eig_val < 0:
tan_fields[component] *= self.grid_dual_correction
else:
tan_fields[component] *= self.grid_primal_correction

return tan_fields

@property
Expand All @@ -379,11 +391,7 @@ def _tangential_fields(self) -> Dict[str, DataArray]:
@property
def _colocated_fields(self) -> Dict[str, DataArray]:
"""For a 2D monitor data, get all E and H fields colocated to the cell boundaries in the 2D
plane grid.

Note
----
The finite grid correction factors are applied and symmetry is expanded.
plane grid, with symmetries expanded.
"""

field_components = self._in_plane
Expand Down
9 changes: 7 additions & 2 deletions tidy3d/components/data/sim_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,7 @@ def get_poynting_vector(self, field_monitor_name: str) -> xr.Dataset:
DataArray containing the Poynting vector calculated based on the field components
colocated at the center locations of the Yee grid.
"""
# Fields from 2D monitors need a correction factor
mon_data = self.load_field_monitor(field_monitor_name).grid_corrected_copy
mon_data = self.load_field_monitor(field_monitor_name)
field_dataset = self._at_boundaries(mon_data)

time_domain = isinstance(self.monitor_data[field_monitor_name], FieldTimeData)
Expand All @@ -308,6 +307,12 @@ def get_poynting_vector(self, field_monitor_name: str) -> xr.Dataset:
else 0.5 * (e_1 * h_2.conj() - e_2 * h_1.conj())
)

# 2D monitors have grid correction factors that can be different from 1. For Poynting,
# it is always the product of a primal-located field and dual-located field, so the
# total grid correction factor is the product of the two
grid_correction = mon_data.grid_dual_correction * mon_data.grid_primal_correction
poynting_components["S" + dim] *= grid_correction

return xr.Dataset(poynting_components)

@staticmethod
Expand Down