Hello, I am new to parallel implementation with FreeFem++, so I started by implementing a Poisson problem using domain decomposition, based on some examples I found online. I first implemented this code in a serial format. In this case I obtain error in the L2 norm or order 10^-14. When I implement the same code in parallel, the error in the L2 norm is of order 10^-6, using either 1 or 4 processors. I do not understand where this huge difference come from. Any help/suggestion would be greatly appreciated. Here is a minimal code of the parallel implementation:
load "PETSc"
macro dimension()2// EOM
include "macro_ddm.idp"
/* ----- Declare/Define user variables ----- */
int nx=50; //degree of freedom in x direction
int ny=25; //degree of freedom in y direction
real a1=0;
real b1=20;
real c1=0;
real d1=10;
/* ----- END Declare/Define user variables ----- */
/* ----- Mesh Generation ----- */
// Borders
real L=b1-a1;
real H=d1-c1;
border rect1(t=0,1){x=a1+L*t;y=c1;label=1;};
border rect2(t=0,1){x=b1;y=c1+H*t;label=2;};
border rect3(t=0,1){x=a1+L*(1-t);y=d1;label=3;};
border rect4(t=0,1){x=a1;y=c1+H*(1-t);label=4;};
mesh Th = buildmesh(rect1(nx)+rect2(ny)+rect3(nx)+rect4(ny));
plot(Th, wait=true, ps="poisson_2d_mesh.ps"); //Display and save mesh
/* ----- END Mesh Generation ----- */
fespace Vh (Th, P2);
// Declare/Define source term
Vh fh1, fh2;
fh1=0;
varf a(u, v)
= int2d(Th)(dx(u)*dx(v) + dy(u)*dy(v))
+ int2d(Th)(-fh1*v)
+on(4,u=0.0)
+on(2,u=1.0);
;
Mat A;
createMat(Th, A, P2);
set(A, sparams="-pc_type hypre");
real[int] b(Vh.ndof);
A = a(Vh, Vh);
b = a(0, Vh);
Vh uh;
uh[] = A^-1 * b;
/* ----- Compute L2 error ----- */
real errorL2, normL2;
real errorH1, normH1;
func u1 = (x-a1)/(b1-a1);
Vh u = u1;
// Compute L2 relative error
normL2 = sqrt(int2d(Th)(u^2));
errorL2 = sqrt(int2d(Th)((u-uh)^2)) / normL2;
//cout << "L2-error relative is " << errorL2 << endl;
// Compute H1 relative error
normH1 = sqrt(normL2^2 + int2d(Th)(dx(u)^2 + dy(u)^2));
errorH1 = sqrt( sqrt(int2d(Th)((u-uh)^2)) + int2d(Th)((dx(u)-dx(uh))^2 + (dy(u)-dy(uh))^2)) / normH1;
//cout << "H1-error relative is " << errorH1 << endl;
/* ----- End Compute L2 error ----- */
real globalL2error;
real globalH1error;
mpiAllReduce(errorL2, globalL2error, mpiCommWorld, mpiSUM);
mpiAllReduce(errorH1, globalH1error, mpiCommWorld, mpiSUM);
if (mpirank == 0){
cout << "The errorL2 is " << globalL2error << endl;
cout << "The errorH1 is " << globalH1error << endl;
}