Issue with transfer between two meshes

Hello,

I am having an issue when using the transfer routine when trying to copy variables from one mesh to another. I have used the following Maxwell 3D example: https://github.com/FreeFem/FreeFem-sources/blob/develop/examples/hpddm/maxwell-mg-3d-PETSc-complex.edp
and added these lines at the end of the file:

fespace Vh2(Th[level-1],Pk);
Vh2<complex> def(u2);
transfer(Th[0],Pk,def(u),Th[level-1],Pk,def(u2));
if (mpirank==0)
savevtk(“onemesh.vtu”,Th[level-1],[real(u2), real(u2y), real(u2z)], [imag(u2), imag(u2y), imag(u2z)], order = fforder, bin = 1);

When I run the code, I get an error like this:

1424 @
1195 @ IFMACRO(privateDmeshTh[
0 in maxwell-mg-3d-PETSc-complex.edp line : 65
2 in macro: transfer in /usr/local/lib/ff++/4.7-1/idp/macro_ddm.idp line : 1407
current line = 1195 mpirank 0 / 4
Compile error : missing ‘)’ after IFMACRO(macro)
line number :1195, [
error Compile error : missing ‘)’ after IFMACRO(macro)
line number :1195, [
code = 1 mpirank: 0

Is there something missing in my code?

Thanks in advance

Dear Christophe,
Very interesting issue! The example you use, maxwell-mg-3d-PETSc-complex.edp, deals with nested meshes. Meaning that the meshes are build by uniformly refining the one from the previous level. In that case, you don’t need to transfer anything, the interpolation is purely local on each process. You can simply write

def(u2) = def(u);

If you want to transfer variables between non-nested meshes, you can for example have a look at this other post.

In fact I want to transfer the result in variable u from the local meshes to the global mesh. Even when I recreate the original coarse mesh by adding

mesh3 ThGlobal=cube(n, n, n, [x, y, z], label = LL);
fespace Vh2(ThGlobal,Pk);
Vh2<complex> def(u2);
transfer(Th[0],Pk,def(u),ThGlobal,Pk,def(u2));
if (mpirank==0)
savevtk(“onemesh.vtu”,ThGlobal,[real(u2), real(u2y), real(u2z)], [imag(u2), imag(u2y), imag(u2z)], order = fforder, bin = 1);

I get the same error. Is there a way to do this?

Why do you want to do that (going back to the global mesh)?
Anyway, this is not the proper way to do it. You can have a look at maxwell-3d-PETSc.edp that rebuilds a global solution (but you should avoid that). You’ll have to use the N2O keyword, see lines 28 and 80.

I forgot to say, but the goal of using multiple levels by doing uniform refinement is to generate extremely fine global meshes without having to store them on a single process. So trying to gather everything on a single process is kind of conter-intuitive. What is it that you want to do exactly if I may ask, please?

I would like to interpolate the result from u at specific points (x,y,z) and save those values in a unique file. I thought it might be easier if only one process was doing this operation, so that the file is not written in parallel.

So, first, you can do exactly that from inside ParaView, using a distributed output, as currently done in the initial file you mentioned. You just have to apply a filter.

If you want to do this directly in FreeFEM, I think it would be much more efficient, especially for very large mesh, to just:

  1. for each point (x, y, z), use the chi function to know if said point is in the local mesh, see https://doc.freefem.org/references/functions.html#chi
  2. if the point is local to the subdomain, get the value
  3. afterwards, do a loop, and let all processes write in sequence your unique file where you store all the values

If you want, you can even make step 3. much more efficient by simply creating an array complex[int] and doing an mpiReduce of this array on process #0, where each process fills the array for points local to its subdomain, see 2. After the reduction, only process 0 will write the result to disk.

OK, thank you, the chi function is the one I was missing!