Skip to content

Commit 5d1927c

Browse files
weiliangjin2021momchil-flex
authored andcommitted
Fix PolySlab intersections when bounds contain inf
1 parent 05e33a3 commit 5d1927c

File tree

3 files changed

+36
-16
lines changed

3 files changed

+36
-16
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1818
### Fixed
1919
- `tidy3d.plugins.design.Results` store the `BatchData` for batch runs in the `.batch_data` field.
2020
- Prompting user to check solver log when loading solver data if warnings were found in the log, or if the simulation diverged or errored.
21+
- Bug in PolySlab intersection if slab bounds are `inf` on one side.
2122

2223
### Changed
2324
- Slightly reorganized `web.run` logging when `verbose=True` to make it clearer.

tests/test_components/test_geometry.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import warnings
1212

1313
import tidy3d as td
14+
from tidy3d.constants import LARGE_NUMBER
1415
from tidy3d.exceptions import SetupError, Tidy3dKeyError, ValidationError
1516
from tidy3d.components.geometry.base import Planar
1617
from tidy3d.components.geometry.utils import flatten_groups, traverse_geometries
@@ -710,6 +711,22 @@ def test_polyslab_axis(axis):
710711
assert not ps.intersects_plane(x=plane_coord[0], y=plane_coord[1], z=plane_coord[2])
711712

712713

714+
def test_polyslab_intersection_inf_bounds():
715+
"""Test if intersection returns correct shapes when one of the slab_bounds is Inf."""
716+
# 1) [0, inf]
717+
poly = td.PolySlab(
718+
vertices=[[2, -1], [-2, -1], [-2, 1], [2, 1]],
719+
slab_bounds=[0, td.inf],
720+
)
721+
assert len(poly.intersections_plane(x=0)) == 1
722+
assert poly.intersections_plane(x=0)[0] == shapely.box(-1, 0.0, 1, LARGE_NUMBER)
723+
724+
# 2) [-inf, 0]
725+
poly = poly.updated_copy(slab_bounds=[-td.inf, 0])
726+
assert len(poly.intersections_plane(x=0)) == 1
727+
assert poly.intersections_plane(x=0)[0] == shapely.box(-1, -LARGE_NUMBER, 1, 0)
728+
729+
713730
def test_from_shapely():
714731
ring = shapely.LinearRing([(-16, 9), (-8, 9), (-12, 2)])
715732
poly = shapely.Polygon([(-2, 0), (-10, 0), (-6, 7)])

tidy3d/components/geometry/polyslab.py

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from ..types import MatrixReal4x4, Shapely
1717
from ...log import log
1818
from ...exceptions import SetupError, ValidationError
19-
from ...constants import MICROMETER, fp_eps
19+
from ...constants import MICROMETER, fp_eps, LARGE_NUMBER
2020
from ...packaging import verify_packages_import
2121

2222
from . import base
@@ -353,6 +353,8 @@ def center_axis(self) -> float:
353353
zmin, zmax = self.slab_bounds
354354
if np.isneginf(zmin) and np.isposinf(zmax):
355355
return 0.0
356+
zmin = max(zmin, -LARGE_NUMBER)
357+
zmax = min(zmax, LARGE_NUMBER)
356358
return (zmax + zmin) / 2.0
357359

358360
@property
@@ -386,7 +388,7 @@ def middle_polygon(self) -> np.ndarray:
386388
The vertices of the polygon at the middle.
387389
"""
388390

389-
dist = self._extrusion_length_to_offset_distance(self.length_axis / 2)
391+
dist = self._extrusion_length_to_offset_distance(self.finite_length_axis / 2)
390392
if self.reference_plane == "bottom":
391393
return self._shift_vertices(self.reference_polygon, dist)[0]
392394
if self.reference_plane == "top":
@@ -405,7 +407,7 @@ def base_polygon(self) -> np.ndarray:
405407
"""
406408
if self.reference_plane == "bottom":
407409
return self.reference_polygon
408-
dist = self._extrusion_length_to_offset_distance(-self.length_axis / 2)
410+
dist = self._extrusion_length_to_offset_distance(-self.finite_length_axis / 2)
409411
return self._shift_vertices(self.middle_polygon, dist)[0]
410412

411413
@cached_property
@@ -419,7 +421,7 @@ def top_polygon(self) -> np.ndarray:
419421
"""
420422
if self.reference_plane == "top":
421423
return self.reference_polygon
422-
dist = self._extrusion_length_to_offset_distance(self.length_axis / 2)
424+
dist = self._extrusion_length_to_offset_distance(self.finite_length_axis / 2)
423425
return self._shift_vertices(self.middle_polygon, dist)[0]
424426

425427
@cached_property
@@ -461,7 +463,7 @@ def inside(
461463

462464
z0 = self.center_axis
463465
dist_z = np.abs(z - z0)
464-
inside_height = dist_z <= (self.length_axis / 2)
466+
inside_height = dist_z <= (self.finite_length_axis / 2)
465467

466468
# avoid going into face checking if no points are inside slab bounds
467469
if not np.any(inside_height):
@@ -646,14 +648,14 @@ def _intersections_side(self, position, axis) -> list:
646648

647649
# find out all z_i where the plane will intersect the vertex
648650
z0 = self.center_axis
649-
z_base = z0 - self.length_axis / 2
651+
z_base = z0 - self.finite_length_axis / 2
650652

651653
axis_ordered = self._order_axis(axis)
652654
height_list = self._find_intersecting_height(position, axis_ordered)
653655
polys = []
654656

655657
# looping through z_i to assemble the polygons
656-
height_list = np.append(height_list, self.length_axis)
658+
height_list = np.append(height_list, self.finite_length_axis)
657659
h_base = 0.0
658660
for h_top in height_list:
659661
# length within between top and bottom
@@ -670,7 +672,7 @@ def _intersections_side(self, position, axis) -> list:
670672
)
671673
else:
672674
# for slanted sidewall, move up by `fp_eps` in case vertices are degenerate at the base.
673-
dist = -(h_base - self.length_axis / 2 + fp_eps) * self._tanq
675+
dist = -(h_base - self.finite_length_axis / 2 + fp_eps) * self._tanq
674676
vertices = self._shift_vertices(self.middle_polygon, dist)[0]
675677
ints_y, ints_angle = self._find_intersecting_ys_angle_slant(
676678
vertices, position, axis_ordered
@@ -744,14 +746,14 @@ def _find_intersecting_height(self, position: float, axis: int) -> np.ndarray:
744746

745747
# distance to the plane in the direction of vertex shifting
746748
distance = self.middle_polygon[:, axis] - position
747-
height = distance / self._tanq / shift_val + self.length_axis / 2
749+
height = distance / self._tanq / shift_val + self.finite_length_axis / 2
748750
height = np.unique(height)
749751
# further filter very close ones
750752
is_not_too_close = np.insert((np.diff(height) > fp_eps), 0, True)
751753
height = height[is_not_too_close]
752754

753755
height = height[height > fp_eps]
754-
height = height[height < self.length_axis - fp_eps]
756+
height = height[height < self.finite_length_axis - fp_eps]
755757
return height
756758

757759
def _find_intersecting_ys_angle_vertical(
@@ -955,11 +957,11 @@ def bounds(self) -> Bound:
955957
max_offset = self.dilation
956958
if not isclose(self.sidewall_angle, 0):
957959
if self.reference_plane == "bottom":
958-
max_offset += max(0, -self._tanq * self.length_axis)
960+
max_offset += max(0, -self._tanq * self.finite_length_axis)
959961
elif self.reference_plane == "top":
960-
max_offset += max(0, self._tanq * self.length_axis)
962+
max_offset += max(0, self._tanq * self.finite_length_axis)
961963
elif self.reference_plane == "middle":
962-
max_offset += max(0, abs(self._tanq) * self.length_axis / 2)
964+
max_offset += max(0, abs(self._tanq) * self.finite_length_axis / 2)
963965

964966
# special care when dilated
965967
if max_offset > 0:
@@ -1513,7 +1515,7 @@ def _dilation_length(self) -> List[float]:
15131515
"""dilation length from reference plane to the top/bottom of the polyslab."""
15141516

15151517
# for "bottom", only needs to compute the offset length to the top
1516-
dist = [self._extrusion_length_to_offset_distance(self.length_axis)]
1518+
dist = [self._extrusion_length_to_offset_distance(self.finite_length_axis)]
15171519
# reverse the dilation value if the reference plane is on the top
15181520
if self.reference_plane == "top":
15191521
dist = [-dist[0]]
@@ -1527,9 +1529,9 @@ def _dilation_value_at_reference_to_coord(self, dilation: float) -> float:
15271529

15281530
z_coord = -dilation / self._tanq + self.slab_bounds[0]
15291531
if self.reference_plane == "middle":
1530-
return z_coord + self.length_axis / 2
1532+
return z_coord + self.finite_length_axis / 2
15311533
if self.reference_plane == "top":
1532-
return z_coord + self.length_axis
1534+
return z_coord + self.finite_length_axis
15331535
# bottom case
15341536
return z_coord
15351537

0 commit comments

Comments
 (0)