I would like to modify the values of a Function (calculated by the NonlinearVariationalSolver) and then create a new Function from it (and use it as a new initial value).
My problem is that I cannot create the new Function from a PETScVector in parallel properly.
In the following code I simply try to copy the elements of Function v to a PETSc type vector T and then create a new Function from it. When I print out the elements of T, I get no uninitialized elements, however when I print out the Function there are many of them.
I have no such problem in serial.
Function* v(V);
// ... nonlinear solver changing v
Vector vvec(*v->vector());
// Get range and size
std::pair<std::size_t, std::size_t> range = vvec.local_range();
std::size_t N = vvec.size();
// Create a new PETSc vector
Vec T;
VecCreate(PETSC_COMM_WORLD, &T);
VecSetSizes(T, PETSC_DECIDE, N);
VecSetFromOptions(T);
// Get the elements of vvec and write them into T
double u;
for (int i=range.first; i<range.second; i++) {
vvec.get(&u, 1, &i);
VecSetValues(T,1,&i, &u, ADD_VALUES);
}
VecAssemblyBegin(T);
VecAssemblyEnd(T);
// Create a new function from T and inspect the elements
PETScVector t(T);
std::vector<double> xt;
t.gather_on_zero(xt);
for (int i=0; i<xt.size();i++){
std::cout << "xt[" << i << "]" << xt[i] << std::endl;
}
Up to here everything seems to be fine, there are no unitialized elements. However if I use t to create a new Function, it contains uninitialized elements.
// Create new Function and inspect the values
Function vnew(V, t.copy());
std::vector<double> x;
vnew.compute_vertex_values(x,*mesh);
for (int i=0; i<x.size();i++){
std::cout << "x[" << i << "]" << x[i] << std::endl;
}
What is the correct way to create a new function from a PETScVector in parallel?