Chapter 10
Parallel version experimental
A first attempt of parallelization of FreeFem++is made here with mpi.
We add 4 words in the language:
-
mpisize
- The total number of processes
-
mpirank
- the number of my current process in {0,...,mpisize -1}.
-
processor
- a function to set the possessor to send or receive data
-
broadcast
- a function to broadcast from a processor to all other a data
processor(10) << a ; // send to the process 10 the data
a;
processor(10) >> a ; // receive from the process 10 the data
a;
10.1 Schwarz in parallel
This example is just the rewritting of example schwarz-overlapin section 9.8.1.
[examples++-mpi] Hecht%lamboot
LAM 6.5.9/MPI 2 C++/ROMIO - Indiana University
[examples++-mpi] hecht% mpirun -np 2 FreeFem++-mpi schwarz-c.edp
// a new coding version c, methode de schwarz in parallele
// with 2 proc.
// -------------------------------
// F.Hecht december 2003
// ----------------------------------
// to test the broadcast instruction
// and array of mesh
// add add the stop test
// ---------------------------------
if ( mpisize != 2 ) {
cout << " sorry number of processeur !=2 " << endl;
exit(1);}
verbosity=3;
real pi=4⋆atan(1);
int inside = 2;
int outside = 1;
border a(t=1,2){x=t;y=0;label=outside;};
border b(t=0,1){x=2;y=t;label=outside;};
border c(t=2,0){x=t ;y=1;label=outside;};
border d(t=1,0){x = 1-t; y = t;label=inside;};
border e(t=0, pi/2){ x= cos(t); y = sin(t);label=inside;};
border e1(t=pi/2, 2⋆pi){ x= cos(t); y = sin(t);label=outside;};
int n=4;
mesh[int] Th(mpisize);
if (mpirank == 0)
Th[0] = buildmesh( a(5⋆n) + b(5⋆n) + c(10⋆n) + d(5⋆n));
else
Th[1] = buildmesh ( e(5⋆n) + e1(25⋆n) );
broadcast(processor(0),Th[0]);
broadcast(processor(1),Th[1]);
fespace Vh(Th[mpirank],P1);
fespace Vhother(Th[1-mpirank],P1);
Vh u=0,v;
Vhother U=0;
int i=0;
problem pb(u,v,init=i,solver=Cholesky) =
int2d(Th[mpirank])( dx(u)⋆dx(v)+dy(u)⋆dy(v) )
- int2d(Th[mpirank])( v)
+ on(inside,u = U) + on(outside,u= U ) ;
for ( i=0 ;i< 20; i++)
{
cout << mpirank << " looP " << i << endl;
pb;
// send u to the other proc, receive in
U
processor(1-mpirank) << u[]; processor(1-mpirank) >> U[];
real err0,err1;
err0 = int1d(Th[mpirank],inside)(square(U-u)) ;
// send err0 to the other proc, receive in
err1
processor(1-mpirank)<<err0; processor(1-mpirank)>>err1;
real err= sqrt(err0+err1);
cout <<" err = " << err << " err0 = " << err0
<< ", err1 = " << err1 << endl;
if(err<1e-3) break;
};
if (mpirank==0)
plot(u,U,ps="uU.eps");