Skip to content

Commit a038e48

Browse files
authored
Fix exterior facet integrals from meshtags (#4041)
* Add test that fails on main branch * Add fix
1 parent f25deee commit a038e48

2 files changed

Lines changed: 29 additions & 1 deletion

File tree

python/dolfinx/fem/forms.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,14 +176,24 @@ def get_integration_domains(
176176
subdomain._cpp_object.topology.create_connectivity(tdim - 2, tdim)
177177
subdomain._cpp_object.topology.create_connectivity(tdim, tdim - 2)
178178

179+
# Special handling for exterior facets, compared to other
180+
# one-sided entity integrals
181+
if integral_type is IntegralType.exterior_facet:
182+
exterior_facets = _cpp.mesh.exterior_facet_indices(subdomain.topology)
183+
179184
# Compute integration domains only for each subdomain id in
180185
# the integrals. If a process has no integral entities,
181186
# insert an empty array.
182187
for id in subdomain_ids:
188+
entities = subdomain.find(id)
189+
if integral_type is IntegralType.exterior_facet:
190+
# Compute intersection of tag an exterior facets
191+
entities = np.intersect1d(entities, exterior_facets)
192+
183193
integration_entities = _cpp.fem.compute_integration_domains(
184194
integral_type,
185195
subdomain._cpp_object.topology,
186-
subdomain.find(id),
196+
entities,
187197
)
188198
domains.append((id, integration_entities))
189199
return [(s[0], np.array(s[1])) for s in domains]

python/test/unit/fem/test_assemble_domains.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,3 +349,21 @@ def create_forms(dx, ds, dS):
349349

350350
assert np.allclose(A.data, A_mt.data)
351351
assert np.allclose(b.array, b_mt.array)
352+
353+
354+
def test_assemble_exterior_facet():
355+
"""Check special handling of packing of integration entities for exterior facets,
356+
which for any other co-dimensional entity is just a one-sided integral.
357+
"""
358+
domain = create_unit_square(MPI.COMM_WORLD, 2, 2)
359+
fdim = domain.topology.dim - 1
360+
tag = 1
361+
362+
# Only tag interior facets
363+
facets = locate_entities(domain, fdim, lambda x: np.isclose(x[0], 0.5))
364+
ft = meshtags(domain, fdim, facets, np.full_like(facets, tag))
365+
ds = ufl.Measure("ds", domain=domain, subdomain_data=ft)
366+
367+
# Check that integral is 0
368+
value = domain.comm.allreduce(assemble_scalar(form(1.0 * ds(tag))), op=MPI.SUM)
369+
assert np.isclose(value, 0.0)

0 commit comments

Comments
 (0)