Setting function values node by node in parallel - dolfinx

Dear all,

I’m transitioning my dolfin code to dolfinx and I need to set function values node by node in parallel. The strategy I used in FEniCS is exactly the one in the answer of this past question but I still haven’t figured out a way to transition to dolfinx, especially because I don’t find any function equivalent to vec.get_local(), veg.set_local() and vec.apply('insert').

The best I manage to get starting from the answer at the link above is the following code, that unfortunately only works in serial:

import dolfinx as df
from mpi4py import MPI
from petsc4py import PETSc
import ufl
import numpy as np

mesh = df.mesh.create_unit_square(MPI.COMM_WORLD, 8, 8)

V = df.fem.FunctionSpace(mesh, ('P', 1))
f = df.fem.Function(V, name='f', dtype=np.float64)

dofmap = V.dofmap
X = V.tabulate_dof_coordinates()
visited = []

Map = mesh.topology.index_map(mesh.topology.dim)
num_cells = Map.size_local + Map.num_ghosts # total number of cells

values = []

for cell_idx in range(num_cells):
    vertex_glob_idx = mesh.topology.connectivity(mesh.topology.dim,0).links(cell_idx) # np.array
    for dof in vertex_glob_idx:
        if not dof in visited:     
            visited.append(dof)
            indeces.append(dof)
            values.append(sum(X[dof]**2))

f_vec = f.vector
values = np.array(values)
ni = int(len(values))
indeces = np.array(indeces, dtype=np.int32)

f_vec.setValues(indeces, values)
f_vec.assemble()
f_vec.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD)
# f.x.array[:] = f_vec # not necessary

I installed dolfinx in a Docker container. I run the code using jupyter lab, then I visualize the function f using pyvista as explained in the available tutorials.

Any idea about how I can modify it to make it work in parallel?

Thanks in advance!

You don’t need to work with the PETSc Vec, consider just modifying the underlying data, e.g. https://github.com/FEniCS/dolfinx/blob/main/python/demo/demo_navier-stokes.py#L321-L324.

Thank you for the quick reply.

What does the following line actually do?
offset = V.dofmap.index_map.size_local * V.dofmap.index_map_bs

Computes the DoF offset for the velocity component end and pressure component start in the underlying solution vector for the Stokes velocity pressure problem.

This example was intended to be illustrative as generic python syntax and the DOLFINx interface. Consider that you probably just need to do something simple like:

f.x.array[indices] = values
f.x.scatter_forward()
1 Like

Thank for your help, Nate, with those two lines the code now works in parallel.