Skip to content

Commit 8f589e6

Browse files
committed
compute overlap
1 parent f8910e4 commit 8f589e6

File tree

3 files changed

+106
-21
lines changed

3 files changed

+106
-21
lines changed

pyphare/pyphare/pharesee/geometry.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,84 @@ def periodicity_shifts(domain_box):
190190
return shifts
191191

192192

193+
def possible_periodic_shifts(box, domain_box):
194+
from pyphare.core.box import shift
195+
196+
boxes = []
197+
dim = domain_box.ndim
198+
199+
if dim == 1:
200+
for ishift in (-1, 0, 1):
201+
ioffset = ishift * domain_box.shape[0]
202+
offset = ioffset
203+
204+
shifted = shift(box, offset)
205+
boxes += [(offset, shifted)]
206+
if dim == 2:
207+
for ishift in (-1, 0, 1):
208+
ioffset = ishift * domain_box.shape[0]
209+
for jshift in (-1, 0, 1):
210+
joffset = jshift * domain_box.shape[1]
211+
offset = [ioffset, joffset]
212+
shifted = shift(box, offset)
213+
boxes += [(offset, shifted)]
214+
if dim == 3:
215+
for ishift in (-1, 0, 1):
216+
ioffset = ishift * domain_box.shape[0]
217+
for jshift in (-1, 0, 1):
218+
joffset = jshift * domain_box.shape[1]
219+
for kshift in (-1, 0, 1):
220+
koffset = kshift * domain_box.shape[2]
221+
222+
offset = [ioffset, joffset, koffset]
223+
shifted = shift(box, offset)
224+
boxes += [(offset, shifted)]
225+
return boxes
226+
227+
193228
def compute_overlaps(patches, domain_box):
229+
overlaps = []
230+
zero_offset = [0] * domain_box.ndim if domain_box.ndim > 1 else 0
231+
232+
for ip, refPatch in enumerate(patches):
233+
for cmpPatch in patches[ip:]:
234+
235+
for ref_pdname, ref_pd in refPatch.patch_datas.items():
236+
cmp_pd = cmpPatch.patch_datas[ref_pdname]
237+
238+
gb_ref = ref_pd.ghost_box
239+
gb_cmp = cmp_pd.ghost_box
240+
241+
for offset, shifted_cmp in possible_periodic_shifts(gb_cmp, domain_box):
242+
overlap = gb_ref * shifted_cmp
243+
if overlap is not None and not np.all(
244+
overlap.shape == gb_ref.shape
245+
):
246+
if ref_pd.quantity == "field":
247+
overlap = toFieldBox(overlap, ref_pd)
248+
249+
overlaps.append(
250+
{
251+
"pdatas": (ref_pd, cmp_pd),
252+
"patches": (refPatch, cmpPatch),
253+
"box": overlap,
254+
"offset": (zero_offset, offset),
255+
}
256+
)
257+
if offset != zero_offset:
258+
overlaps.append(
259+
{
260+
"pdatas": (ref_pd, cmp_pd),
261+
"patches": (refPatch, cmpPatch),
262+
"box": overlap,
263+
"offset": (zero_offset, offset),
264+
}
265+
)
266+
267+
return overlaps
268+
269+
270+
def compute_overlaps_(patches, domain_box):
194271
"""
195272
returns a list of overlaps for all patch datas in given patches
196273
and for a domain box. An overlap is defined as an intersection of

pyphare/pyphare_tests/test_pharesee/test_geometry.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def setup_hierarchy(self, dim, interp_order, nbr_cells, refinement_boxes, **kwar
2727
domain_size=domain_size,
2828
cell_width=domain_size / nbr_cells,
2929
refinement_boxes=refinement_boxes,
30-
**kwargs
30+
**kwargs,
3131
)
3232

3333
# used for tests without ddt hierarchy overrides
@@ -78,18 +78,20 @@ def test_overlaps(self):
7878
}
7979

8080
overlaps = hierarchy_overlaps(hierarchy)
81+
tested_overlaps = {
82+
ilvl: [
83+
{"box": overlap["box"], "offset": overlap["offset"]}
84+
for overlap in overlaps[ilvl]
85+
]
86+
for ilvl in range(len(hierarchy.patch_levels))
87+
}
8188

8289
for ilvl, lvl in enumerate(hierarchy.patch_levels):
8390
self.assertEqual(len(expected[ilvl]), len(overlaps[ilvl]))
8491

85-
for exp, actual in zip(expected[ilvl], overlaps[ilvl]):
86-
act_box = actual["box"]
87-
act_offset = actual["offset"]
88-
exp_box = exp["box"]
89-
exp_offset = exp["offset"]
90-
91-
self.assertEqual(act_box, exp_box)
92-
self.assertEqual(act_offset, exp_offset)
92+
for actual in tested_overlaps[ilvl]:
93+
if actual not in expected[ilvl]:
94+
raise AssertionError(f"Unexpected overlap: {actual}")
9395

9496
def test_touch_border(self):
9597
hierarchy = self.basic_hierarchy()

pyphare/pyphare_tests/test_pharesee/test_geometry_2d.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,19 @@ def test_overlaps(self, refinement_boxes, expected):
114114
)
115115

116116
level_overlaps = hierarchy_overlaps(hierarchy)
117+
tested_overlaps = {
118+
ilvl: [
119+
{"box": overlap["box"], "offset": overlap["offset"]}
120+
for overlap in level_overlaps[ilvl]
121+
]
122+
for ilvl in expected.keys()
123+
}
117124
for ilvl, lvl in enumerate(hierarchy.levels().items()):
118125
if ilvl not in expected:
119126
continue
120127
self.assertEqual(len(expected[ilvl]), len(level_overlaps[ilvl]))
121-
for exp, actual in zip(expected[ilvl], level_overlaps[ilvl]):
122-
self.assertEqual(actual["box"], exp["box"])
123-
self.assertTrue(
124-
(np.asarray(actual["offset"]) == np.asarray(exp["offset"])).all()
125-
)
128+
for actual in tested_overlaps[ilvl]:
129+
self.assertTrue(actual in expected[ilvl])
126130

127131
if 1 in level_overlaps:
128132
fig = hierarchy.plot_2d_patches(
@@ -163,14 +167,16 @@ def test_large_patchoverlaps(self, expected):
163167
level_overlaps = hierarchy_overlaps(hierarchy)
164168
ilvl = 0
165169
overlap_boxes = []
170+
tested_overlaps = {
171+
0: [
172+
{"box": overlap["box"], "offset": overlap["offset"]}
173+
for overlap in level_overlaps[ilvl]
174+
]
175+
}
166176

167-
self.assertEqual(len(expected), len(level_overlaps[ilvl]))
168-
for exp, actual in zip(expected, level_overlaps[ilvl]):
169-
self.assertEqual(actual["box"], exp["box"])
170-
self.assertTrue(
171-
(np.asarray(actual["offset"]) == np.asarray(exp["offset"])).all()
172-
)
173-
overlap_boxes += [actual["box"]]
177+
self.assertEqual(len(expected), len(tested_overlaps[ilvl]))
178+
for actual in tested_overlaps[ilvl]:
179+
self.assertTrue(actual in expected)
174180

175181
fig = hierarchy.plot_2d_patches(
176182
ilvl,

0 commit comments

Comments
 (0)