Hello everyone,
I have a quick question regarding the apply method in (legacy) fenics. Consider the following: If I want to change the vector values of some function with those provided in some petsc4py.PETSc.Vec object, I can use the following code, which works nicely in serial
from fenics import *
mesh = UnitSquareMesh(8, 8)
V = FunctionSpace(mesh, "CG", 1)
u = Function(V)
x = Function(V)
x_vec = x.vector().vec() # This usually comes from somewhere else
u.vector().vec().setArray(x_vec)
Now, when I run the code in parallel, things break. This is because the petsc4py.PETSc.Vec is not assembled correctly and ghost values are not updated correctly. In order to fix it in parallel, one has to add a call to
u.vector().apply("")
after the setArray method. My question is: What does the argument of the apply method actually do? As far as I have gathered from the source code here, calling .apply("") should be similar (or even identical) to calling the petsc4py methods
u.vector().vec().assemble()
u.vector().vec().ghostUpdate()
or, more MPI friendly
u.vector().vec().assemblyBegin()
u.vector().vec().assemblyEnd()
u.vector().vec().ghostUpdateBegin()
u.vector().vec().ghostUpdateEnd()
which is explained here.
From the C++ source code, I don’t see that the string mode is even used when the apply method is called. Why is this argument even used?
And further: Can I replace all calls to apply with the petsc4py.PETSc.Vec method assemble and ghostUpdate or is there something that I am overlooking / missing?
Thanks a lot in advance and best regards,
Sebastian