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

Introduce SubpixelSpec to allow for selecting subpixel averaging methods on different materials #1689

Merged
merged 1 commit into from
May 30, 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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- A batch of `ModeSolver` objects can be run concurrently using `tidy3d.plugins.mode.web.run_batch()`
- `RectangularWaveguide.plot_field` optionally draws geometry edges over fields.
- `RectangularWaveguide` supports layered cladding above and below core.
- `SubpixelSpec` accepted by `Simulation.subpixel` to select subpixel averaging methods separately for dielectric, metal, and PEC materials. Specifically, added support for conformal mesh methods near PEC structures that can be specified through the field `pec` in the `SubpixelSpec` class. Note: previously, `subpixel=False` was implementing staircasing for every material except PEC. Now, `subpixel=False` implements direct staircasing for all materials. For PEC, the behavior of `subpixel=False` in Tidy3D < 2.7 is now achieved through `subpixel=SubpixelSpec(pec=HeuristicPECStaircasing())`, while `subpixel=True` in Tidy3D < 2.7 is now achieved through `subpixel=SubpixelSpec(pec=Staircasing())`. The default is `subpixel=SubpixelSpec(pec=PECConformal())` for more accurate PEC modelling.

### Fixed
- `ModeSolver.plot_field` correctly returning the plot axes.
Expand Down Expand Up @@ -52,7 +53,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Introduces the `microwave` plugin which includes `ImpedanceCalculator` for computing the characteristic impedance of transmission lines.
- `Simulation` now accepts `LumpedElementType`, which currently only supports the `LumpedResistor` type. `LumpedPort` together with `LumpedResistor` make up the new `TerminalComponentModeler` in the `smatrix` plugin.
- Uniaxial medium Lithium Niobate to material library.
- Added support for conformal mesh methods near PEC structures that can be specified through the field `pec_conformal_mesh_spec` in the `Simulation` class. Note: previously, `subpixel=False` was implementing staircasing for every material except PEC. Now, `subpixel=False` implements direct staircasing for all materials. For PEC, the behavior of `subpixel=False` in Tidy3D < 2.7 is now achieved through `subpixel=True` and `pec_conformal_mesh_spec=HeuristicConformalMeshSpec()`, while `subpixel=True` in Tidy3D < 2.7 is now achieved through the default settings `subpixel=True` and `pec_conformal_mesh_spec=StaircasingConformalMeshSpec()`. Additionally, a new `BenklerConformalMeshSpec()` was introduced for more accurate PEC modelling.
- Properties `num_time_steps_adjoint` and `tmesh_adjoint` to `JaxSimulation` to estimate adjoint run time.
- Ability to add `path` to `updated_copy()` method to recursively update sub-components of a tidy3d model. For example `sim2 = sim.updated_copy(size=new_size, path="structures/0/geometry")` creates a recursively updated copy of `sim` where `sim.structures[0].geometry` is updated with `size=new_size`.
- Python 3.12 support. Python 3.8 deprecation. Updated dependencies.
Expand Down
11 changes: 0 additions & 11 deletions docs/api/discretization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,3 @@ Discretization
tidy3d.FieldGrid
tidy3d.YeeGrid
tidy3d.Grid

PEC Conformal Mesh Spec
-----------------------

.. autosummary::
:toctree: _autosummary/
:template: module.rst

tidy3d.StaircasingConformalMeshSpec
tidy3d.HeuristicConformalMeshSpec
tidy3d.BenklerConformalMeshSpec
2 changes: 2 additions & 0 deletions docs/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ API |:computer:|
mode
lumped_elements
discretization
subpixel_averaging
output_data
scene
logging
Expand All @@ -38,6 +39,7 @@ API |:computer:|
.. include:: /api/mode.rst
.. include:: /api/lumped_elements.rst
.. include:: /api/discretization.rst
.. include:: /api/subpixel_averaging.rst
.. include:: /api/output_data.rst
.. include:: /api/scene.rst
.. include:: /api/logging.rst
Expand Down
23 changes: 23 additions & 0 deletions docs/api/subpixel_averaging.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.. currentmodule:: tidy3d

Subpixel Averaging
==================

.. autosummary::
:toctree: _autosummary/
:template: module.rst

tidy3d.SubpixelSpec

Types of Subpixel Averaging Methods
-----------------------------------

.. autosummary::
:toctree: _autosummary/
:template: module.rst

tidy3d.Staircasing
tidy3d.VolumetricAveraging
tidy3d.HeuristicPECStaircasing
tidy3d.PolarizedAveraging
tidy3d.PECConformal
Binary file modified tests/sims/simulation_sample.h5
Binary file not shown.
4 changes: 0 additions & 4 deletions tests/sims/simulation_sample.json
Original file line number Diff line number Diff line change
Expand Up @@ -2722,9 +2722,5 @@
"courant": 0.8,
"normalize_index": 0,
"shutoff": 0.0001,
"pec_conformal_mesh_spec": {
"attrs": {},
"type": "StaircasingConformalMeshSpec"
},
"run_time": 1e-12
}
22 changes: 12 additions & 10 deletions tests/test_components/test_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1969,30 +1969,32 @@ def test_dt():


def test_conformal_dt():
"""make sure dt is reduced when BenklerConformalMeshSpec is applied."""
"""make sure dt is reduced when PEC structures are present and PECConformal is used."""
box = td.Structure(
geometry=td.Box(size=(1, 1, 1)),
medium=td.PECMedium(),
)
sim = td.Simulation(
size=(2.0, 2.0, 2.0),
run_time=1e-12,
structures=[box],
grid_spec=td.GridSpec.uniform(dl=0.1),
subpixel=td.SubpixelSpec(pec=td.Staircasing()),
)
dt = sim.dt

# Benkler
sim_conformal = sim.updated_copy(pec_conformal_mesh_spec=td.BenklerConformalMeshSpec())
# Conformal
sim_conformal = sim.updated_copy(subpixel=td.SubpixelSpec(pec=td.PECConformal()))
assert sim_conformal.dt < dt

# Benkler: same courant
# Conformal: same courant
sim_conformal2 = sim.updated_copy(
pec_conformal_mesh_spec=td.BenklerConformalMeshSpec(timestep_reduction=0)
subpixel=td.SubpixelSpec(pec=td.PECConformal(timestep_reduction=0))
)
assert sim_conformal2.dt == dt

# staircasing
sim_staircasing = sim.updated_copy(pec_conformal_mesh_spec=td.StaircasingConformalMeshSpec())
assert sim_staircasing.dt == dt

# heuristic
sim_heuristic = sim.updated_copy(pec_conformal_mesh_spec=td.StaircasingConformalMeshSpec())
sim_heuristic = sim.updated_copy(subpixel=td.SubpixelSpec(pec=td.HeuristicPECStaircasing()))
assert sim_heuristic.dt == dt


Expand Down
16 changes: 11 additions & 5 deletions tidy3d/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
# grid
from .components.grid.grid import Grid, Coords
from .components.grid.grid_spec import GridSpec, UniformGrid, CustomGrid, AutoGrid
from .components.grid.grid_spec import BenklerConformalMeshSpec, StaircasingConformalMeshSpec
from .components.grid.grid_spec import HeuristicConformalMeshSpec

# subpixel
from .components.subpixel_spec import SubpixelSpec, Staircasing
from .components.subpixel_spec import VolumetricAveraging, PolarizedAveraging
from .components.subpixel_spec import HeuristicPECStaircasing, PECConformal

# geometry
from .components.geometry.base import Box, Transformed, ClipOperation, GeometryGroup
Expand Down Expand Up @@ -352,9 +355,12 @@ def set_logging_level(level: str) -> None:
"TriangularGridDataset",
"TetrahedralGridDataset",
"medium_from_nk",
"BenklerConformalMeshSpec",
"StaircasingConformalMeshSpec",
"HeuristicConformalMeshSpec",
"SubpixelSpec",
"Staircasing",
"VolumetricAveraging",
"PolarizedAveraging",
"HeuristicPECStaircasing",
"PECConformal",
"EMESimulation",
"EMESimulationData",
"EMEMonitor",
Expand Down
7 changes: 0 additions & 7 deletions tidy3d/components/eme/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,6 @@ class EMESimulation(AbstractYeeGridSimulation):
validate_default=True,
)

subpixel: bool = pd.Field(
True,
title="Subpixel Averaging",
description="If ``True``, uses subpixel averaging of the permittivity "
"based on structure definition, resulting in much higher accuracy for a given grid size.",
)

store_port_modes: bool = pd.Field(
True,
title="Store Port Modes",
Expand Down
57 changes: 1 addition & 56 deletions tidy3d/components/grid/grid_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from .grid import Coords1D, Coords, Grid
from .mesher import GradedMesher, MesherType
from ..base import Tidy3dBaseModel, cached_property
from ..base import Tidy3dBaseModel
from ..types import Axis, Symmetry, annotate_type, TYPE_TAG_STR
from ..source import SourceType
from ..structure import Structure, StructureType
Expand All @@ -18,61 +18,6 @@
from ...exceptions import SetupError
from ...constants import MICROMETER, C_0, fp_eps

# Default Courant number reduction rate in Benkler's scheme
DEFAULT_COURANT_REDUCTION_BENKLER = 0.3


class ConformalMeshSpec(Tidy3dBaseModel, ABC):
"""Base class defining conformal mesh specifications."""

@cached_property
def courant_ratio(self) -> float:
"""The scaling ratio applied to Courant number so that the courant number
in the simulation is ``sim.courant * courant_ratio``.
"""
return 1.0


class StaircasingConformalMeshSpec(ConformalMeshSpec):
"""Simple staircasing scheme based on
[Taflove, The Electrical Engineering Handbook 3.629-670 (2005): 15.].
"""


class HeuristicConformalMeshSpec(ConformalMeshSpec):
"""Slightly different from the staircasing scheme: the field component near PEC
is considered to be outside PEC if it's substantially normal to the interface.
"""


class BenklerConformalMeshSpec(ConformalMeshSpec):
"""Conformal mesh scheme based on
[S. Benkler, IEEE Transactions on Antennas and Propagation 54.6, 1843 (2006)], which is similar
to the approach described in [S. Dey, R. Mittra, IEEE Microwave and Guided Wave Letters 7.9, 273 (1997)].
"""

timestep_reduction: float = pd.Field(
DEFAULT_COURANT_REDUCTION_BENKLER,
title="Time Step Size Reduction Rate",
description="Reduction factor between 0 and 1 such that the simulation's time step size "
"will be ``1 - timestep_reduction`` times its default value. "
"Accuracy can be improved with a smaller time step size; but simulation time increased as well.",
lt=1,
ge=0,
)

@cached_property
def courant_ratio(self) -> float:
"""The scaling ratio applied to Courant number so that the courant number
in the simulation is ``sim.courant * courant_ratio``.
"""
return 1 - self.timestep_reduction


ConformalMeshSpecType = Union[
BenklerConformalMeshSpec, StaircasingConformalMeshSpec, HeuristicConformalMeshSpec
]


class GridSpec1d(Tidy3dBaseModel, ABC):

Expand Down
10 changes: 5 additions & 5 deletions tidy3d/components/medium.py
Original file line number Diff line number Diff line change
Expand Up @@ -1107,9 +1107,9 @@ class AbstractCustomMedium(AbstractMedium, ABC):
subpixel: bool = pd.Field(
False,
title="Subpixel averaging",
description="If ``True`` and simulation's ``subpixel`` is also ``True``, "
"applies subpixel averaging of the permittivity "
"on the interface of the structure, including exterior boundary and "
description="If ``True``, apply the subpixel averaging method specified by "
"``Simulation``'s field ``subpixel`` for this type of material on the "
"interface of the structure, including exterior boundary and "
"intersection interfaces with other structures.",
)

Expand Down Expand Up @@ -5249,8 +5249,8 @@ class AbstractPerturbationMedium(ABC, Tidy3dBaseModel):
True,
title="Subpixel averaging",
description="This value will be transferred to the resulting custom medium. That is, "
"if ``True``, the subpixel averaging will be applied to the custom medium provided "
"the corresponding ``Simulation``'s field ``subpixel`` is set to ``True`` as well. "
"if ``True``, the subpixel averaging will be applied to the custom medium. The type "
"of subpixel averaging method applied is specified in ``Simulation``'s field ``subpixel``. "
"If the resulting medium is not a custom medium (no perturbations), this field does not "
"have an effect.",
)
Expand Down
Loading
Loading