@@ -1533,36 +1533,37 @@ def _override_structures_along_axis(
1533
1533
if refinement_structures [0 ].dl [self .axis ] <= dl :
1534
1534
override_structures += refinement_structures
1535
1535
return override_structures
1536
-
1536
+
1537
1537
def _find_vertical_intersections (self , x , y , vertices ):
1538
1538
"""Detect intersection points of single polygon and vertical grid lines."""
1539
1539
1540
1540
cells_ij = []
1541
1541
cells_dy = []
1542
1542
h_inds = np .argmax (x [:, None ] > vertices [None , :, 0 ], axis = 0 )
1543
1543
h_inds [vertices [:, 0 ] > x [- 1 ]] = len (x )
1544
- for ind_beg , ind_end , v_beg , v_end in zip (h_inds , np .roll (h_inds , - 1 ), vertices , np .roll (vertices , axis = 0 , shift = - 1 )):
1544
+ for ind_beg , ind_end , v_beg , v_end in zip (
1545
+ h_inds , np .roll (h_inds , - 1 ), vertices , np .roll (vertices , axis = 0 , shift = - 1 )
1546
+ ):
1545
1547
# sort vertices in ascending order
1546
1548
if ind_beg > ind_end :
1547
1549
ind_beg , ind_end , v_beg , v_end = ind_end , ind_beg , v_end , v_beg
1548
-
1550
+
1549
1551
if ind_end > ind_beg :
1550
-
1551
1552
# x coordinates are simply grid x points that are covered by each segment
1552
1553
h_x = x [ind_beg :ind_end ]
1553
-
1554
+
1554
1555
# y coordinates can be found from line equation
1555
1556
h_y = v_beg [1 ] + (v_end [1 ] - v_beg [1 ]) / (v_end [0 ] - v_beg [0 ]) * (h_x - v_beg [0 ])
1556
-
1557
+
1557
1558
# however, we need to see which ones are actually inside along y axis
1558
1559
inds_inside_grid = np .logical_and (h_y >= y [0 ], h_y <= y [- 1 ])
1559
-
1560
+
1560
1561
h_y = h_y [inds_inside_grid ]
1561
-
1562
+
1562
1563
# find cell j coordinates which contain these intersections
1563
1564
cell_is = np .arange (ind_beg , ind_end )[inds_inside_grid ]
1564
1565
cell_js = np .searchsorted (y , h_y ) - 1
1565
-
1566
+
1566
1567
# find local dy
1567
1568
dy = h_y - y [cell_js ]
1568
1569
@@ -1576,7 +1577,7 @@ def _find_vertical_intersections(self, x, y, vertices):
1576
1577
cells_dy = np .concatenate (cells_dy )
1577
1578
1578
1579
return cells_ij , cells_dy
1579
-
1580
+
1580
1581
def _process_poly (self , x , y , vertices ):
1581
1582
"""Detect intersection points of single polygon and grid lines."""
1582
1583
v_cells_ij , v_cells_dy = self ._find_vertical_intersections (x , y , vertices )
@@ -1585,7 +1586,7 @@ def _process_poly(self, x, y, vertices):
1585
1586
if len (h_cells_ij ) > 0 :
1586
1587
h_cells_ij = np .roll (h_cells_ij , axis = 1 , shift = 1 )
1587
1588
return v_cells_ij , v_cells_dy , h_cells_ij , h_cells_dx
1588
-
1589
+
1589
1590
def _process_slice (self , x , y , merged_geos ):
1590
1591
"""Detect intersection points of geometries boundaries and grid lines."""
1591
1592
v_cells_ij = []
@@ -1600,15 +1601,15 @@ def _process_slice(self, x, y, merged_geos):
1600
1601
for poly in polygon_list :
1601
1602
poly = poly .normalize ().buffer (0 )
1602
1603
data = self ._process_poly (x , y , np .array (poly .exterior .coords )[:- 1 ])
1603
-
1604
+
1604
1605
if len (data [0 ]) > 0 :
1605
1606
v_cells_ij .append (data [0 ])
1606
1607
v_cells_dy .append (data [1 ])
1607
1608
1608
1609
if len (data [2 ]) > 0 :
1609
1610
h_cells_ij .append (data [2 ])
1610
1611
h_cells_dx .append (data [3 ])
1611
-
1612
+
1612
1613
# in case the polygon has holes
1613
1614
for poly_inner in poly .interiors :
1614
1615
data = self ._process_poly (x , y , np .array (poly_inner .coords )[:- 1 ])
@@ -1633,13 +1634,14 @@ def _process_slice(self, x, y, merged_geos):
1633
1634
h_cells_dx = np .concatenate (h_cells_dx )
1634
1635
1635
1636
return v_cells_ij , v_cells_dy , h_cells_ij , h_cells_dx
1636
-
1637
1637
1638
1638
def _resolve_gaps (self , structures : List , grid : Grid ):
1639
1639
"""Detect underresolved gaps and place snapping lines in them. Also return the detected minimal gap width."""
1640
1640
1641
1641
# get merged pec structures on plane
1642
- plane_slice = CornerFinderSpec ._merged_pec_on_plane (coord = self .center_axis , normal_axis = self .axis , structure_list = structures )
1642
+ plane_slice = CornerFinderSpec ._merged_pec_on_plane (
1643
+ coord = self .center_axis , normal_axis = self .axis , structure_list = structures
1644
+ )
1643
1645
1644
1646
_ , tan_dims = Box .pop_axis ([0 , 1 , 2 ], self .axis )
1645
1647
x = grid .boundaries .to_list [tan_dims [0 ]]
@@ -1654,7 +1656,9 @@ def _resolve_gaps(self, structures: List, grid: Grid):
1654
1656
snapping_lines_y = []
1655
1657
if len (v_cells_ij ) > 0 :
1656
1658
# add number of intersections
1657
- ind_unique , counts = np .unique (v_cells_ij [:, 0 ] * len (y ) + v_cells_ij [:, 1 ], return_counts = True )
1659
+ ind_unique , counts = np .unique (
1660
+ v_cells_ij [:, 0 ] * len (y ) + v_cells_ij [:, 1 ], return_counts = True
1661
+ )
1658
1662
ind_unique_j = ind_unique % len (y )
1659
1663
for ind_j in np .unique (ind_unique_j ):
1660
1664
max_count = np .max (counts [ind_unique_j == ind_j ])
@@ -1669,7 +1673,9 @@ def _resolve_gaps(self, structures: List, grid: Grid):
1669
1673
snapping_lines_x = []
1670
1674
if len (h_cells_ij ) > 0 :
1671
1675
# add number of intersections
1672
- ind_unique , counts = np .unique (h_cells_ij [:, 0 ] * len (y ) + h_cells_ij [:, 1 ], return_counts = True )
1676
+ ind_unique , counts = np .unique (
1677
+ h_cells_ij [:, 0 ] * len (y ) + h_cells_ij [:, 1 ], return_counts = True
1678
+ )
1673
1679
ind_unique_i = ind_unique // len (y )
1674
1680
for ind_i in np .unique (ind_unique_i ):
1675
1681
max_count = np .max (counts [ind_unique_i == ind_i ])
@@ -1680,7 +1686,9 @@ def _resolve_gaps(self, structures: List, grid: Grid):
1680
1686
snapping_lines_x .append (x [ind_i ] + 0.5 * (min_dx + max_dx ))
1681
1687
detected_gap_width = min (detected_gap_width , max_dy - min_dy )
1682
1688
1683
- return [Box .unpop_axis (X , (None , None ), axis = tan_dims [0 ]) for X in snapping_lines_x ] + [Box .unpop_axis (Y , (None , None ), axis = tan_dims [1 ]) for Y in snapping_lines_y ], detected_gap_width
1689
+ return [Box .unpop_axis (X , (None , None ), axis = tan_dims [0 ]) for X in snapping_lines_x ] + [
1690
+ Box .unpop_axis (Y , (None , None ), axis = tan_dims [1 ]) for Y in snapping_lines_y
1691
+ ], detected_gap_width
1684
1692
1685
1693
1686
1694
class GridSpec (Tidy3dBaseModel ):
@@ -2067,7 +2075,7 @@ def get_wavelength(self, sources: List[SourceType]) -> float:
2067
2075
wavelength = self .wavelength_from_sources (sources )
2068
2076
log .info (f"Auto meshing using wavelength { wavelength :1.4f} defined from sources." )
2069
2077
return wavelength
2070
-
2078
+
2071
2079
def make_grid (
2072
2080
self ,
2073
2081
structures : List [Structure ],
@@ -2118,15 +2126,19 @@ def make_grid(
2118
2126
)
2119
2127
2120
2128
if len (self .layer_refinement_specs ) > 0 :
2121
- num_iters = max (layer_spec .gap_meshing_iters for layer_spec in self .layer_refinement_specs )
2122
-
2129
+ num_iters = max (
2130
+ layer_spec .gap_meshing_iters for layer_spec in self .layer_refinement_specs
2131
+ )
2132
+
2123
2133
snapping_lines = []
2124
2134
min_gap_width = inf
2125
2135
for ind in range (num_iters ):
2126
2136
new_snapping_lines = []
2127
2137
for layer_spec in self .layer_refinement_specs :
2128
2138
if layer_spec .gap_meshing_iters > ind :
2129
- one_layer_snapping_lines , gap_width = layer_spec ._resolve_gaps (structures , old_grid )
2139
+ one_layer_snapping_lines , gap_width = layer_spec ._resolve_gaps (
2140
+ structures , old_grid
2141
+ )
2130
2142
new_snapping_lines = new_snapping_lines + one_layer_snapping_lines
2131
2143
if layer_spec .dl_min_from_gap_width :
2132
2144
min_gap_width = min (min_gap_width , gap_width )
@@ -2158,7 +2170,6 @@ def make_grid(
2158
2170
old_grid = new_grid
2159
2171
2160
2172
return old_grid
2161
-
2162
2173
2163
2174
def _make_grid_one_iteration (
2164
2175
self ,
0 commit comments