Skip to content

Commit c698af0

Browse files
authored
DirichletBC.dof_indices() are wrong for blocked spaces (#3937)
* Add failing test to illustrate issue * Add fix * Revert line switch
1 parent 7032158 commit c698af0

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

cpp/dolfinx/fem/DirichletBC.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,8 @@ class DirichletBC
259259
std::size_t num_owned(const DofMap& dofmap,
260260
std::span<const std::int32_t> dofs)
261261
{
262-
int bs = dofmap.index_map_bs();
263262
std::int32_t map_size = dofmap.index_map->size_local();
264-
std::int32_t owned_size = bs * map_size;
263+
std::int32_t owned_size = map_size;
265264
auto it = std::ranges::lower_bound(dofs, owned_size);
266265
return std::distance(dofs.begin(), it);
267266
}

python/test/unit/fem/test_bcs.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (C) 2020-2021 Joseph P. Dean, Massimiliano Leoni and Jørgen S. Dokken
1+
# Copyright (C) 2020-2025 Joseph P. Dean, Massimiliano Leoni and Jørgen S. Dokken
22
#
33
# This file is part of DOLFINx (https://www.fenicsproject.org)
44
#
@@ -362,3 +362,26 @@ def test_mixed_blocked_constant():
362362
with pytest.raises(RuntimeError):
363363
dofs1 = locate_dofs_topological(W.sub(1), tdim - 1, boundary_facets)
364364
dirichletbc(c1, dofs1, W.sub(1))
365+
366+
367+
@pytest.mark.parametrize("shape", [(), (2,), (3, 2)])
368+
def test_blocked_dof_ownership(shape):
369+
mesh = create_unit_square(MPI.COMM_WORLD, 4, 4)
370+
V = functionspace(mesh, ("Lagrange", 1, shape))
371+
372+
u_bc = Function(V)
373+
mesh.topology.create_connectivity(mesh.topology.dim - 1, mesh.topology.dim)
374+
bc_facets = exterior_facet_indices(mesh.topology)
375+
# Blocked spaces are not unrolled here
376+
bc_dofs_u = locate_dofs_topological(V, mesh.topology.dim - 1, bc_facets)
377+
378+
# Num owned dofs
379+
num_owned_blocked = V.dofmap.index_map.size_local
380+
381+
input_dofs_owned = bc_dofs_u[bc_dofs_u < num_owned_blocked]
382+
383+
bc = dirichletbc(u_bc, bc_dofs_u)
384+
unrolled_bc_dofs, num_owned = bc.dof_indices()
385+
386+
assert len(input_dofs_owned) * V.dofmap.index_map_bs == num_owned
387+
assert len(unrolled_bc_dofs) == len(bc_dofs_u) * V.dofmap.index_map_bs

0 commit comments

Comments
 (0)