Skip to content

Commit a55bba3

Browse files
committed
Rewrite test to check all corner-cases.
1 parent 30750ab commit a55bba3

1 file changed

Lines changed: 123 additions & 19 deletions

File tree

tests/test_mesh.py

Lines changed: 123 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ def ref_interface(x):
296296
def test_exterior_boundary_subdomain(dtype, ghost_mode, cell_type):
297297
comm = MPI.COMM_WORLD
298298
mesh = dolfinx.mesh.create_unit_cube(
299-
comm, 10, 5, 7, cell_type=cell_type, ghost_mode=ghost_mode, dtype=dtype
299+
comm, 13, 7, 11, cell_type=cell_type, ghost_mode=ghost_mode, dtype=dtype
300300
)
301301

302302
def center(x):
@@ -305,35 +305,139 @@ def center(x):
305305
tdim = mesh.topology.dim
306306
cell_map = mesh.topology.index_map(tdim)
307307
all_cells = np.arange(cell_map.size_local + cell_map.num_ghosts, dtype=np.int32)
308-
values = np.full_like(all_cells, 1, dtype=np.int32)
309-
values[dolfinx.mesh.locate_entities(mesh, tdim, center)] = 2
308+
value_map = dolfinx.la.vector(cell_map, 1, dtype=np.int32)
309+
value_map.array[:] = 0
310+
value_map.array[dolfinx.mesh.locate_entities(mesh, tdim, center)] = 1
311+
value_map.scatter_reverse(dolfinx.la.InsertMode.add)
312+
value_map.scatter_forward()
313+
314+
values = np.ones_like(all_cells, dtype=np.int32)
315+
values[value_map.array > 0] = 2
316+
310317
cell_tags = dolfinx.mesh.meshtags(mesh, tdim, all_cells, values)
311318

312-
ext_facets_1 = scifem.compute_subdomain_exterior_facets(mesh, cell_tags, (1,))
319+
def boundary_check(mesh, facets, cell_tags, values):
320+
is_in_subdomain = np.isin(cell_tags.values, np.asarray(values))
321+
mesh.topology.create_connectivity(mesh.topology.dim - 1, mesh.topology.dim)
322+
num_facets_local = mesh.topology.index_map(mesh.topology.dim - 1).size_local
323+
f_to_c = mesh.topology.connectivity(mesh.topology.dim - 1, mesh.topology.dim)
324+
cell_map = mesh.topology.index_map(mesh.topology.dim)
325+
owned_facets_in_subdomain = []
326+
owned_facets_on_outside = []
327+
ghosted_facets_in_subdomain = []
328+
ghosted_facets_on_outside = []
329+
330+
facet_map = mesh.topology.index_map(mesh.topology.dim - 1)
331+
332+
for facet in facets:
333+
cells = f_to_c.links(facet)
334+
if len(cells) != 1:
335+
assert np.sum(is_in_subdomain[cells]) == 1
336+
elif len(cells) == 1:
337+
if facet < num_facets_local:
338+
# If connected to only one cell, we send it to the other process
339+
# that has it to verify that it is a boundary facet
340+
if is_in_subdomain[cells[0]]:
341+
owned_facets_in_subdomain.append(facet)
342+
else:
343+
owned_facets_on_outside.append(facet)
344+
else:
345+
if is_in_subdomain[cells[0]]:
346+
ghosted_facets_in_subdomain.append(facet)
347+
else:
348+
ghosted_facets_on_outside.append(facet)
349+
# Receive facets from other process that is on subdomain on that process
350+
facet_vector = dolfinx.la.vector(
351+
mesh.topology.index_map(mesh.topology.dim - 1), 1, dtype=np.int32
352+
)
353+
facet_vector.array[:] = 0
354+
facet_vector.array[ghosted_facets_in_subdomain] = 1
355+
facet_vector.scatter_reverse(dolfinx.la.InsertMode.add)
313356

314-
# Exterior facets for domain 1 are the original exterior facets + those at the interface
315-
mesh.topology.create_connectivity(mesh.topology.dim - 1, mesh.topology.dim)
316-
owned_exterior_facets = dolfinx.mesh.exterior_facet_indices(mesh.topology)
317-
exterior_facet_indices = scifem.reverse_mark_entities(
318-
mesh.topology.index_map(tdim - 1), owned_exterior_facets
319-
)
357+
exterior_facets = dolfinx.mesh.exterior_facet_indices(mesh.topology)
358+
all_local_exterior_facets = scifem.reverse_mark_entities(facet_map, exterior_facets)
320359

321-
# Compute reference exterior facets by interface computations
322-
twosided_interface = scifem.find_interface(cell_tags, (1,), (2,))
323-
interface = scifem.reverse_mark_entities(mesh.topology.index_map(tdim - 1), twosided_interface)
360+
facets_inside_subdomain = np.flatnonzero(facet_vector.array[:num_facets_local]).astype(
361+
np.int32
362+
)
363+
mesh.topology.create_connectivity(mesh.topology.dim, mesh.topology.dim - 1)
364+
for facet in facets_inside_subdomain:
365+
cells = f_to_c.links(facet)
366+
if facet in all_local_exterior_facets:
367+
assert is_in_subdomain[cells[0]]
368+
continue
369+
if len(cells) == 1:
370+
assert cells[0] < cell_map.size_local
371+
assert not is_in_subdomain[cells[0]]
372+
else:
373+
assert len(cells) == 2
374+
assert np.sum(is_in_subdomain[cells]) == 1
375+
376+
facet_vector.array[:] = 0
377+
facet_vector.array[ghosted_facets_on_outside] = 1
378+
facet_vector.scatter_reverse(dolfinx.la.InsertMode.add)
379+
facets_outside_subdomain = np.flatnonzero(facet_vector.array[:num_facets_local]).astype(
380+
np.int32
381+
)
382+
for facet in facets_outside_subdomain:
383+
cells = f_to_c.links(facet)
384+
if facet in all_local_exterior_facets:
385+
assert is_in_subdomain[cells[0]]
386+
continue
387+
if len(cells) == 1:
388+
assert cells[0] < cell_map.size_local
389+
assert is_in_subdomain[cells[0]]
390+
else:
391+
assert len(cells) == 2
392+
assert np.sum(is_in_subdomain[cells]) == 1
393+
394+
facet_vector.array[:] = 0
395+
facet_vector.array[owned_facets_in_subdomain] = 1
396+
facet_vector.scatter_forward()
397+
facets_inside_subdomain = np.flatnonzero(facet_vector.array[num_facets_local:]).astype(
398+
np.int32
399+
)
400+
for facet in facets_inside_subdomain:
401+
cells = f_to_c.links(num_facets_local + facet)
402+
if num_facets_local + facet in all_local_exterior_facets:
403+
assert is_in_subdomain[cells[0]]
404+
continue
405+
406+
if len(cells) == 1:
407+
assert cells[0] <= cell_map.size_local
408+
assert not is_in_subdomain[cells[0]]
409+
else:
410+
assert len(cells) == 2
411+
assert np.sum(is_in_subdomain[cells]) == 1
412+
413+
facet_vector.array[:] = 0
414+
facet_vector.array[owned_facets_on_outside] = 1
415+
facet_vector.scatter_forward()
416+
facets_outside_subdomain = np.flatnonzero(facet_vector.array[num_facets_local:]).astype(
417+
np.int32
418+
)
419+
for facet in facets_outside_subdomain:
420+
cells = f_to_c.links(num_facets_local + facet)
421+
if num_facets_local + facet in all_local_exterior_facets:
422+
assert is_in_subdomain[cells[0]]
423+
continue
424+
if len(cells) == 1:
425+
assert cells[0] <= cell_map.size_local
426+
assert is_in_subdomain[cells[0]]
427+
else:
428+
assert len(cells) == 2
429+
assert np.sum(is_in_subdomain[cells]) == 1
324430

325-
ref_ext_facets_1 = np.unique(np.concatenate([exterior_facet_indices, interface])).astype(
326-
np.int32
327-
)
328-
np.testing.assert_allclose(ext_facets_1, ref_ext_facets_1)
431+
ext_facets_1 = scifem.compute_subdomain_exterior_facets(mesh, cell_tags, (1,))
432+
boundary_check(mesh, ext_facets_1, cell_tags, (1,))
329433

330434
# Exterior facets are only those at the interface
331435
ext_facets_2 = scifem.compute_subdomain_exterior_facets(mesh, cell_tags, (2,))
332-
np.testing.assert_allclose(ext_facets_2, interface)
436+
boundary_check(mesh, ext_facets_2, cell_tags, (2,))
333437

334438
# Exterior facets are only exterior
335439
ext_facets = scifem.compute_subdomain_exterior_facets(mesh, cell_tags, (1, 2))
336-
np.testing.assert_allclose(ext_facets, exterior_facet_indices)
440+
boundary_check(mesh, ext_facets, cell_tags, (1, 2))
337441

338442

339443
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)