52
52
from .data .utils import CustomSpatialDataType
53
53
from .geometry .base import Box , Geometry , GeometryGroup
54
54
from .geometry .mesh import TriangleMesh
55
- from .geometry .utils import flatten_groups , traverse_geometries
55
+ from .geometry .utils import _shift_object , flatten_groups , traverse_geometries
56
56
from .geometry .utils_2d import get_bounds , get_thickened_geom , snap_coordinate_to_grid , subdivide
57
57
from .grid .grid import Coords , Coords1D , Grid
58
58
from .grid .grid_spec import AutoGrid , GridSpec , UniformGrid
113
113
Ax ,
114
114
Axis ,
115
115
CoordinateOptional ,
116
- Direction ,
117
116
FreqBound ,
118
117
InterpMethod ,
119
118
PermittivityComponent ,
@@ -470,8 +469,10 @@ def _shifted_internal_absorbers(self) -> list[InternalAbsorber]:
470
469
"""List of absorber shifted to their actual locations based on their grid_shift's."""
471
470
472
471
return [
473
- self . _shift_object (
472
+ _shift_object (
474
473
obj = absorber ,
474
+ grid = self .grid ,
475
+ bounds = self .bounds ,
475
476
direction = absorber .direction ,
476
477
shift = absorber .grid_shift ,
477
478
)
@@ -1876,7 +1877,7 @@ def subsection(
1876
1877
Used internally.
1877
1878
deep_copy: bool = True
1878
1879
Recursively copy all nested objects in the generated simulation object.
1879
- internal_absorbers : Tuple[SourceType , ...] = None
1880
+ internal_absorbers : Tuple[InternalAbsorber , ...] = None
1880
1881
New list of internal absorbers. If ``None``, then the absorbers intersecting the new simulation
1881
1882
domain are inherited from the original simulation.
1882
1883
**kwargs
@@ -2108,73 +2109,6 @@ def _invalidate_solver_cache(self) -> None:
2108
2109
"""Clear cached attributes that become stale when subpixel changes."""
2109
2110
self ._cached_properties .pop ("_mode_solver" , None )
2110
2111
2111
- def _shift_value_signed (
2112
- self , obj : Box , direction : Direction , shift : int , name : Optional [str ] = None
2113
- ) -> float :
2114
- """Calculate the signed distance corresponding to moving the object by ``shift`` number
2115
- of cells in the positive or negative ``direction`` along the dimension given by
2116
- ``obj._normal_axis``.
2117
- """
2118
- if name is None :
2119
- name = f"A '{ obj .type } '"
2120
-
2121
- # get the grid boundaries and sizes along obj normal from the simulation
2122
- normal_axis = obj ._normal_axis
2123
- grid_boundaries = self .grid .boundaries .to_list [normal_axis ]
2124
- grid_centers = self .grid .centers .to_list [normal_axis ]
2125
-
2126
- # get the index of the grid cell where the obj lies
2127
- obj_position = obj .center [normal_axis ]
2128
- obj_pos_gt_grid_bounds = np .argwhere (obj_position > grid_boundaries )
2129
-
2130
- # no obj index can be determined
2131
- if len (obj_pos_gt_grid_bounds ) == 0 or obj_position > grid_boundaries [- 1 ]:
2132
- raise SetupError (
2133
- f"{ name } position '{ obj_position } ' is outside of simulation bounds '({ grid_boundaries [0 ]} , { grid_boundaries [- 1 ]} )' along dimension '{ 'xyz' [normal_axis ]} '."
2134
- )
2135
- obj_index = obj_pos_gt_grid_bounds [- 1 ]
2136
-
2137
- # shift the obj to the left
2138
- signed_shift = shift if direction == "+" else - shift
2139
- if signed_shift < 0 :
2140
- shifted_index = obj_index + signed_shift
2141
- if shifted_index < 0 or grid_centers [shifted_index ] <= self .bounds [0 ][normal_axis ]:
2142
- raise SetupError (
2143
- f"{ name } normal is less than 2 cells to the boundary "
2144
- f"on -{ 'xyz' [normal_axis ]} side. "
2145
- "Please either increase the mesh resolution near the obj or "
2146
- "move the obj away from the boundary."
2147
- )
2148
-
2149
- # shift the obj to the right
2150
- else :
2151
- shifted_index = obj_index + signed_shift
2152
- if (
2153
- shifted_index >= len (grid_centers )
2154
- or grid_centers [shifted_index ] >= self .bounds [1 ][normal_axis ]
2155
- ):
2156
- raise SetupError (
2157
- f"{ name } normal is less than 2 cells to the boundary "
2158
- f"on +{ 'xyz' [normal_axis ]} side."
2159
- "Please either increase the mesh resolution near the obj or "
2160
- "move the obj away from the boundary."
2161
- )
2162
-
2163
- new_pos = grid_centers [shifted_index ]
2164
- return new_pos - obj_position
2165
-
2166
- def _shift_object (self , obj : InternalAbsorber , direction : Direction , shift : int ) -> float :
2167
- """Move a plane-like object by ``shift`` number
2168
- of cells in the positive or negative ``direction`` along the dimension given by
2169
- ``obj._normal_axis``.
2170
- """
2171
- shift = self ._shift_value_signed (obj , direction , shift )
2172
- new_center = np .array (obj .center )
2173
- new_center [obj ._normal_axis ] += shift
2174
- # note: if this needs to be generalized beyond absorber, one would probably
2175
- # slightly adjust the code below regarding grid_shift
2176
- return obj .updated_copy (center = tuple (new_center ), grid_shift = 0 )
2177
-
2178
2112
2179
2113
class Simulation (AbstractYeeGridSimulation ):
2180
2114
"""
@@ -3496,7 +3430,10 @@ def _projection_monitors_homogeneous(cls, val, values):
3496
3430
3497
3431
@classmethod
3498
3432
def _get_mediums_on_abc (
3499
- cls , boundary_spec , medium , center , size , structures
3433
+ cls ,
3434
+ boundary_spec : BoundarySpec ,
3435
+ sim_structure : Structure ,
3436
+ structures : tuple [Structure , ...],
3500
3437
) -> tuple [
3501
3438
list [MediumType3D ],
3502
3439
list [MediumType3D ],
@@ -3510,19 +3447,14 @@ def _get_mediums_on_abc(
3510
3447
"""
3511
3448
3512
3449
# list of structures including background as a Box()
3513
- structure_bg = Structure (
3514
- geometry = Box (
3515
- size = size ,
3516
- center = center ,
3517
- ),
3518
- medium = medium ,
3519
- )
3520
-
3521
- surfaces = Box .surfaces (
3522
- center = structure_bg .geometry .center , size = structure_bg .geometry .size
3450
+ surface_box = sim_structure .geometry
3451
+ # expand zero dimensions to make sure surface are extracted correctly and treatment is uniform
3452
+ surface_box = surface_box .updated_copy (
3453
+ size = [1e-6 if s == 0 else s for s in surface_box .size ]
3523
3454
)
3455
+ surfaces = Box .surfaces (center = surface_box .center , size = surface_box .size )
3524
3456
3525
- total_structures = [structure_bg , * list (structures )]
3457
+ total_structures = [sim_structure , * list (structures )]
3526
3458
3527
3459
mediums = []
3528
3460
for boundary , surface in zip (np .ravel (boundary_spec .to_list ), surfaces ):
@@ -3541,14 +3473,14 @@ def _abc_boundaries_homogeneous(cls, val, values):
3541
3473
if val is None :
3542
3474
return val
3543
3475
3544
- # expand zero dimensions to make the treatment uniform
3545
- size = [fp_eps if s == 0 else s for s in values .get ("size" )]
3476
+ sim_structure = Structure (
3477
+ geometry = Box (size = values .get ("size" ), center = values .get ("center" )),
3478
+ medium = values .get ("medium" ),
3479
+ )
3546
3480
3547
3481
mediums_all_sides = cls ._get_mediums_on_abc (
3548
3482
boundary_spec = val ,
3549
- medium = values .get ("medium" ),
3550
- size = size ,
3551
- center = values .get ("center" ),
3483
+ sim_structure = sim_structure ,
3552
3484
structures = values .get ("structures" ) or [],
3553
3485
)
3554
3486
0 commit comments