Skip to content
Draft
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 @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Introduced `BroadbandPulse` for exciting simulations across a wide frequency spectrum.
- Added `interp_spec` in `ModeSpec` to allow downsampling and interpolation of waveguide modes in frequency.
- Added warning if port mesh refinement is incompatible with the `GridSpec` in the `TerminalComponentModeler`.
- Added support of `TriangleMesh` for autograd.

### Breaking Changes
- Edge singularity correction at PEC and lossy metal edges defaults to `True`.
Expand Down
3 changes: 2 additions & 1 deletion docs/api/geometry.rst
Original file line number Diff line number Diff line change
Expand Up @@ -295,5 +295,6 @@ Use the ``from_stl()`` class method to import from an external STL file, or ``fr
+ `Importing STL files <../notebooks/STLImport.html>`_
+ `Defining complex geometries using trimesh <../notebooks/CreatingGeometryUsingTrimesh.html>`_

~~~~
Shape gradients for ``TriangleMesh`` geometries are supported through the autograd workflow. When a mesh participates in an adjoint optimization, boundary sensitivities are evaluated on the triangle faces. The cost of the surface integral scales with the number of mesh faces; very fine meshes may require additional sampling to converge gradients, so consider simplifying or coarsening meshes when possible, or adjusting the autograd configuration to trade off accuracy and runtime.

~~~~
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@

import tidy3d as td
import tidy3d.web as web
from tidy3d import config

config.local_cache.enabled = True

WL_UM = 0.65
FREQ0 = td.C_0 / WL_UM
Expand Down Expand Up @@ -41,6 +44,29 @@
sys.stdout = sys.stderr


def angled_overlap_deg(v1, v2):
# zero-out tiny vectors elementwise
thresh = 1e-6
v1 = np.where(np.abs(v1) < thresh, 0.0, v1)
v2 = np.where(np.abs(v2) < thresh, 0.0, v2)

norm_v1 = np.linalg.norm(v1)
norm_v2 = np.linalg.norm(v2)

# handle degenerate vectors
if norm_v1 < thresh or norm_v2 < thresh:
# one is effectively zero, the other is not → undefined angle
if not (norm_v1 < thresh and norm_v2 < thresh):
return np.inf

return 0.0

dot = np.minimum(1.0, np.sum((v1 / np.linalg.norm(v1)) * (v2 / np.linalg.norm(v2))))
angle_deg = np.arccos(dot) * 180.0 / np.pi

return angle_deg


def case_identifier(is_3d: bool, infinite_dim_2d: int | None, shift_box_center: bool) -> str:
geometry_tag = "3d" if is_3d else f"2d_infinite_dim_{infinite_dim_2d}"
shift_tag = "shifted" if shift_box_center else "centered"
Expand Down Expand Up @@ -213,12 +239,12 @@ def run_parameter_simulations(
medium=td.Medium(permittivity=PERMITTIVITY),
)

sim = base_sim.updated_copy(structures=[structure])
sim = base_sim.updated_copy(structures=[structure], validate=False)
simulation_dict[f"sim_{idx}"] = sim

if len(simulation_dict) == 1:
key, sim = next(iter(simulation_dict.items()))
result_path = output_dir / f"{key}.hdf5"
result_path = output_dir / f"{sim._hash_self()}.hdf5"
sim_data = web.run(
sim,
task_name=key,
Expand Down Expand Up @@ -422,21 +448,6 @@ def test_box_and_polyslab_gradients_match(
)
np.savez(npz_path, **test_data)

def angled_overlap_deg(v1, v2):
norm_v1 = np.linalg.norm(v1)
norm_v2 = np.linalg.norm(v2)

if np.isclose(norm_v1, 0.0) or np.isclose(norm_v2, 0.0):
if not (np.isclose(norm_v1, 0.0) and np.isclose(norm_v2, 0.0)):
return np.inf

return 0.0

dot = np.minimum(1.0, np.sum((v1 / np.linalg.norm(v1)) * (v2 / np.linalg.norm(v2))))
angle_deg = np.arccos(dot) * 180.0 / np.pi

return angle_deg

box_polyslab_overlap_deg = angled_overlap_deg(box_grad_filtered, polyslab_grad_filtered)
fd_overlap_deg = angled_overlap_deg(fd_box, fd_polyslab)
box_fd_adj_overlap_deg = angled_overlap_deg(box_grad_filtered, fd_box)
Expand All @@ -448,17 +459,14 @@ def angled_overlap_deg(v1, v2):
print(f"Box Finite Difference vs. Adjoint: {box_fd_adj_overlap_deg}")
print(f"PolySlab Finite Difference vs. Adjoint: {polyslab_fd_adj_overlap_deg}")

assert box_polyslab_overlap_deg < ANGLE_OVERLAP_THRESH_DEG, (
"Autograd gradients for Box and PolySlab disagree"
)
assert fd_overlap_deg < ANGLE_OVERLAP_THRESH_DEG, (
"Finite-difference gradients for Box and PolySlab disagree"
)

if COMPARE_TO_FINITE_DIFFERENCE:
assert box_fd_adj_overlap_deg < ANGLE_OVERLAP_FD_ADJ_THRESH_DEG, (
"Autograd and finite-difference gradients for the Box geometry disagree"
"Autograd and finite-difference gradients for the Box geometry disagree: "
f"angle = {box_fd_adj_overlap_deg:.2f} deg, "
f"threshold = {ANGLE_OVERLAP_FD_ADJ_THRESH_DEG:.2f} deg"
)
assert polyslab_fd_adj_overlap_deg < ANGLE_OVERLAP_FD_ADJ_THRESH_DEG, (
"Autograd and finite-difference gradients for the PolySlab geometry disagree"
"Autograd and finite-difference gradients for the PolySlab geometry disagree: "
f"angle = {polyslab_fd_adj_overlap_deg:.2f} deg, "
f"threshold = {ANGLE_OVERLAP_FD_ADJ_THRESH_DEG:.2f} deg"
)
Loading