// Example of problem solving in parallel // Usage: // ff-mpirun -np 12 LaplacianParallel.edp (here 12 is the number of threads (command nproc to know that) // Need FreeFem++ with PETSc // Parallel stuff load "PETSc" macro partitioner()metis// macro dimension()2// include "./macro_ddm.idp" macro def(i)[i]// macro init(i)[i]// //macro meshN()mesh// //these macro are defined in macro_ddm.idp //macro intN()int2d// // Parameters int nn = 500; real L = 1.; real H = 1.; func f = 1.; func Pk = P1; // Mesh border b1(t=0, L){x=t; y=0; label=1;} border b2(t=0, H){x=L; y=t; label=2;} border b3(t=L, 0){x=t; y=H; label=3;} border b4(t=H, 0){x=0; y=t; label=4;} meshN Th = buildmesh(b1(1) + b2(1) + b3(1) + b4(1)); //build a really coarse mesh (just to build the fespace later) //meshN Th = square(1, 1, [L*x, H*y]); int[int] Wall = [1, 2, 3, 4]; // Fespace fespace Uh(Th, Pk); // Mesh partition int[int] ArrayIntersection; int[int][int] RestrictionIntersection(0); real[int] D; meshN ThBorder; meshN ThGlobal = buildmesh(b1(nn*L) + b2(nn*H) + b3(nn*L) + b4(nn*H)); //build the mesh to partition //meshN ThGlobal = square(nn*L, nn*H, [L*x, H*y]); int InterfaceLabel = 10; int Split = 1; int Overlap = 1; build(Th, ThBorder, ThGlobal, InterfaceLabel, Split, Overlap, D, ArrayIntersection, RestrictionIntersection, Uh, Pk, mpiCommWorld, false); //see macro_ddm.idp for detailed parameters // Macro macro grad(u) [dx(u), dy(u)] // // Problem varf vLaplacian (u, uh) //Problem in varf formulation mandatory = intN(Th)( grad(u)' * grad(uh) ) - intN(Th)( f * uh ) + on(Wall, u=0) ; matrix Laplacian = vLaplacian(Uh, Uh); //build the sequential matrix real[int] LaplacianBoundary = vLaplacian(0, Uh);// and right hand side //// In sequential, you normally do that: //// Solve //Uh def(u)=init(0); //u[] = Laplacian^-1 * LaplacianBoundary; //// Plot //plot(u); // In parallel: // Matrix construction dmatrix PLaplacian(Laplacian, ArrayIntersection, RestrictionIntersection, D, bs=1); //build the parallel matrix set(PLaplacian, sparams="-pc_type lu -pc_factor_mat_solver_package mumps"); //preconditioner LU and MUMPS solver (see PETSc doc for detailed parameters) // Solve Uh def(u)=init(0); //define the unknown (must be defined after mesh partitioning) u[] = PLaplacian^-1 * LaplacianBoundary; // Export results to vtk (there is not plot in parallel) { fespace PV(Th, P1); PV uu=u; int[int] Order = [1]; export("Result", Th, uu, Order, mpiCommWorld); }