# Dirichlet Boundary Conditions on Subdomains in FEniCSx

**URL:** <https://fenicsproject.discourse.group/t/dirichlet-boundary-conditions-on-subdomains-in-fenicsx/9716>\
**Category:** variational formulation\
**Created:** [November 9, 2022, 2:26pm UTC](https://fenicsproject.discourse.group/t/dirichlet-boundary-conditions-on-subdomains-in-fenicsx/9716 "2022-11-09T14:26:09Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![tuderic](https://avatars.discourse-cdn.com/v4/letter/t/839c29/32.png) [@tuderic](https://fenicsproject.discourse.group/u/tuderic)\
**Post date:** [November 9, 2022, 2:26pm UTC](https://fenicsproject.discourse.group/t/dirichlet-boundary-conditions-on-subdomains-in-fenicsx/9716/1 "2022-11-09T14:26:09Z")

</div>

Hi everyone,

I am wondering if it is possible to define Dirichlet boundary conditions on a subdomain.

For instance, if one primary variable is not of interest in a certain subdomain, I would like to set a DBC with the value 0 in order to save computational time. In the legacy fenics, this was possible.

I appreciate any suggestions!

---

<div class="post-metadata">

**Author:** ![dokken](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/dokken/32/1560_2.png) [@dokken](https://fenicsproject.discourse.group/u/dokken)\
**Post date:** [November 9, 2022, 2:42pm UTC](https://fenicsproject.discourse.group/t/dirichlet-boundary-conditions-on-subdomains-in-fenicsx/9716/2 "2022-11-09T14:42:54Z")

</div>

I guess you are referring to `A.ident_zeros()` in legacy dolfin?  
As this simply calls petsc, you can still do this in DOLFINx, as illustrated in the following code:  
(The following code is a refined snippet of @CastriMik code at [thomas-fermi-demo/demo\_tf\_mwe.py at mpi-issue · mikics/thomas-fermi-demo · GitHub](https://github.com/mikics/thomas-fermi-demo/blob/mpi-issue/demo_tf_mwe.py#L191) which avoid global communciation)

```python
problem._A.zeroEntries()

fem.petsc.assemble_matrix(problem._A, problem._a, bcs=problem.bcs)
problem._A.assemble()

# Get diagonal of assembled A matrix
diagonal = problem._A.getDiagonal()
diagonal_values = diagonal.array

# Get zero rows of assembled A matrix.
zero_rows = problem._A.findZeroRows()
zero_rows_values_global = zero_rows.array
local_start = V.dofmap.index_map.local_range[0]*V.dofmap.index_map_bs

# Maps global numbering to local numbering
zero_rows_values_local = zero_rows_values_global - \
    local_start
diagonal.array[zero_rows_values_local] = np.ones(
    len(zero_rows_values_local), dtype=PETSc.ScalarType)
problem._A.setDiagonal(diagonal, PETSc.InsertMode.INSERT_VALUES)
problem._A.assemble()

```

---

<div class="post-metadata">

**Author:** ![dokken](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/dokken/32/1560_2.png) [@dokken](https://fenicsproject.discourse.group/u/dokken)\
**Post date:** [November 9, 2022, 2:45pm UTC](https://fenicsproject.discourse.group/t/dirichlet-boundary-conditions-on-subdomains-in-fenicsx/9716/3 "2022-11-09T14:45:28Z")

</div>

You can also set DirichletBCs on any part of a subdomain in DOLFINx, as the input to the DirichletBC is a set of degrees of freedom.  
I.e.

```python
def some_locator_function(x):
    return x[0]<0.5
deactivate_cells = dolfinx.mesh.locate_entities(mesh, mesh.topology.dim, some_locator_function)
deactivate_dofs = dolfinx.fem.locate_dofs_topological(V, mesh.topology.dim, deactivate_cells)
bc = dolfinx.fem.dirichletbc(PETSc.ScalarType(0), deactivate_dofs, V)

```

---

<div class="post-metadata">

**Author:** ![tuderic](https://avatars.discourse-cdn.com/v4/letter/t/839c29/32.png) [@tuderic](https://fenicsproject.discourse.group/u/tuderic)\
**Post date:** [November 9, 2022, 3:07pm UTC](https://fenicsproject.discourse.group/t/dirichlet-boundary-conditions-on-subdomains-in-fenicsx/9716/4 "2022-11-09T15:07:28Z")

</div>

Thank you @dokken ! Both replies are very helpful.

---

<div class="post-metadata">

**Author:** ![chenyongxin](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/chenyongxin/32/6501_2.png) [@chenyongxin](https://fenicsproject.discourse.group/u/chenyongxin)\
**Post date:** [July 9, 2025, 10:02am UTC](https://fenicsproject.discourse.group/t/dirichlet-boundary-conditions-on-subdomains-in-fenicsx/9716/5 "2025-07-09T10:02:37Z")

</div>

Given `V` as a mixed function space, how can I find the corresponding coordinates of the DOF with the all zero rows?

My attempt is attached. Any suggestions on improvement?

```auto
for i in range(V.num_sub_spaces):
    v_sub, sub_to_parent = V.sub(i).collapse()
    
    if len(zero_rows_values_local) > 0:
        coords = v_sub.tabulate_dof_coordinates()
        for dof in zero_rows_values_local:
            if dof in sub_to_parent:
                index = sub_to_parent.index(dof)
                print(f"Found coordinates: {dof = }, {coords[index] = }", flush = True)

```

---

<div class="post-metadata">

**Author:** ![dokken](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/dokken/32/1560_2.png) [@dokken](https://fenicsproject.discourse.group/u/dokken)\
**Post date:** [July 12, 2025, 1:11pm UTC](https://fenicsproject.discourse.group/t/dirichlet-boundary-conditions-on-subdomains-in-fenicsx/9716/6 "2025-07-12T13:11:04Z")

</div>

This can easily be done without a for-loop for the `dof` in `zero_rows_values_local`, if you create the inverse map `parent_to_sub` mapping from the parent space to the sub-space (where some entries will have nonsensical values, as there is nothing mapping from the parent to the sub-space).

```python
for i in range(V.num_sub_spaces):
    v_sub, sub_to_parent = V.sub(i).collapse()
    num_parent_dofs = V.dofmap.index_map.size_local * V.dofmap.index_map_bs
    parent_to_sub = np.full(num_parent_dofs, -1, dtype=np.int32)
    parent_to_sub[sub_to_parent] = np.arange(len(sub_to_parent))
    sub_indices = parent_to_sub[zero_rows_values_local]
    assert np.allclose(sub_indices >= 0, 1)
    

```
