Good day everyone!
I am trying to understand the assembly process used in the real function space example. For example, in the following code:
bcs = []
main_assembly = False
try:
b = dolfinx.fem.petsc.assemble_vector_block(L_compiled, a_compiled, bcs=bcs)
except AttributeError:
main_assembly = True
b = dolfinx.fem.petsc.assemble_vector(L_compiled, kind="mpi")
apply_lifting_and_set_bc(b, a_compiled, bcs=bcs)
uh = dolfinx.fem.Function(V, name="u")
if main_assembly:
# We start by inserting the value in the real space
rh = dolfinx.fem.Function(R)
rh.x.array[0] = h
# Next we need to add this value to the existing right hand side vector.
# Therefore we create assign 0s to the primal space
b_real_space = b.duplicate()
uh.x.array[:] = 0
# Transfer the data to `b_real_space`
dolfinx.fem.petsc.assign([uh, rh], b_real_space)
# And accumulate the values in the right hand side vector
b.axpy(1, b_real_space)
# We destroy the temporary work vector after usage
b_real_space.destroy()
else:
from dolfinx.cpp.la.petsc import scatter_local_vectors, get_local_vectors
if Version(dolfinx.__version__) < Version("0.9.0"):
maps = [(V.dofmap.index_map, V.dofmap.index_map_bs), (R.dofmap.index_map, R.dofmap.index_map_bs)]
else:
maps = [(Wi.dofmap.index_map, Wi.dofmap.index_map_bs) for Wi in W.ufl_sub_spaces()]
b_local = get_local_vectors(b, maps)
b_local[1][:] = h
scatter_local_vectors(
b,
b_local,
maps,
)
b.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD)
My question is, what are the try/except blocks doing? I am at a loss trying to understand the purpose of these tests or how they work. Is it because the matrix/vector assembly needs to be different depending on where the extra DoFs resulting from the real space get allocated in the MPI environment?
I would be grateful for a brief explanation or a reference. Cheers!