]> SALOME platform Git repositories - tools/solverlab.git/blob - CoreFlows/examples/Python/MPI4PY/testTwoSimulations.py
Salome HOME
Tested use of sub communicators
[tools/solverlab.git] / CoreFlows / examples / Python / MPI4PY / testTwoSimulations.py
1 #!/usr/bin/env python3
2 # -*-coding:utf-8 -*
3
4 #===============================================================================================================================
5 # Name        : Tests of launching two independent simulations in parallel
6 # Author      : Michaël Ndjinga
7 # Copyright   : CEA Saclay 2021
8 # Description : 
9 #================================================================================================================================
10
11 from mpi4py import MPI
12 import numpy as np
13 import solverlab
14 from math import sin, pi
15
16 def StationaryDiffusionEquation_2DEF_StructuredTriangles_par(split_direction, rank):
17         # Prepare for the mesh
18         print("Processor ", rank, " : Building mesh " );
19         xinf = 0 ;
20         xsup=1.0;
21         yinf=0.0;
22         ysup=1.0;
23         nx=20;
24         ny=20; 
25         M=solverlab.Mesh(xinf,xsup,nx,yinf,ysup,ny,split_direction)#Regular triangular mesh
26         # set the limit field for each boundary
27         eps=1e-6;
28         M.setGroupAtPlan(xsup,0,eps,"Bord1")
29         M.setGroupAtPlan(xinf,0,eps,"Bord2")
30         M.setGroupAtPlan(ysup,1,eps,"Bord3")
31         M.setGroupAtPlan(yinf,1,eps,"Bord4")
32         
33         print("Processor ", rank, " : Built a regular triangular 2D mesh from a square mesh with ", nx,"x" ,ny, " cells.")
34         print("Processor ", rank, " : Each square was split in two in direction ",split_direction)
35
36         FEComputation=True
37         Lambda=1.#Thermal conductivity
38         spaceDim = 2
39
40         color = rank % 2
41         sub_comm = comm.Split(color)
42
43         myProblem = solverlab.StationaryDiffusionEquation(spaceDim,FEComputation, Lambda, sub_comm);
44         myProblem.setMesh(M);
45
46     # set the limit value for each boundary
47         T1=0;
48         T2=0;
49         T3=0;
50         T4=0;
51     
52         myProblem.setDirichletBoundaryCondition("Bord1",T1)
53         myProblem.setDirichletBoundaryCondition("Bord2",T2)
54         myProblem.setDirichletBoundaryCondition("Bord3",T3)
55         myProblem.setDirichletBoundaryCondition("Bord4",T4)
56
57         #Set the right hand side function
58         my_RHSfield = solverlab.Field("RHS_field", solverlab.NODES, M, 1)
59         for i in range(M.getNumberOfNodes()):
60                 Ni= M.getNode(i)
61                 x = Ni.x()
62                 y = Ni.y()
63
64                 my_RHSfield[i]=2*pi*pi*sin(pi*x)*sin(pi*y)#mettre la fonction definie au second membre de l'edp
65         
66         myProblem.setHeatPowerField(my_RHSfield)
67
68     # name of result file
69         fileName = "StationnaryDiffusion_2DEF_StructuredTriangles"+str(rank);
70
71     # computation parameters
72         myProblem.setFileName(fileName);
73
74     # Run the computation
75         myProblem.initialize();
76         print("Processor ", rank, " : Running python "+ fileName );
77
78         ok = myProblem.solveStationaryProblem();
79         if (not ok):
80                 print( "Python simulation of " + fileName + "  failed ! " );
81                 pass
82         else:
83                 ####################### Postprocessing #########################
84                 my_ResultField = myProblem.getOutputTemperatureField()
85                 #The following formulas use the fact that the exact solution is equal the right hand side divided by 2*pi*pi
86                 max_abs_sol_exacte=max(my_RHSfield.max(),-my_RHSfield.min())/(2*pi*pi)
87                 max_sol_num=my_ResultField.max()
88                 min_sol_num=my_ResultField.min()
89                 erreur_abs=0
90                 for i in range(M.getNumberOfNodes()) :
91                         if erreur_abs < abs(my_RHSfield[i]/(2*pi*pi) - my_ResultField[i]) :
92                                 erreur_abs = abs(my_RHSfield[i]/(2*pi*pi) - my_ResultField[i])
93                 
94                 print("Processor ", rank, " : Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
95                 print("Processor ", rank, " : Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
96                 print("Processor ", rank, " : Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
97                 
98                 assert erreur_abs/max_abs_sol_exacte <1.
99                 pass
100
101         print("Processor ", rank, " : ------------ !!! End of calculation !!! -----------" );
102
103         myProblem.terminate();
104         return erreur_abs/max_abs_sol_exacte
105
106 if __name__ == """__main__""":
107         comm = MPI.COMM_WORLD
108         size = comm.Get_size()
109         rank = comm.Get_rank()
110         
111         if(size!=2):
112                 raise ValueError("Processor ", rank, " : aborting.\n Simulation should done on two processors.\n", size, " processors given")
113                 
114         print("My rank is ", rank, " among ", size, "processors ")
115         
116         my_relative_error=StationaryDiffusionEquation_2DEF_StructuredTriangles_par(rank, rank)
117
118         if rank == 0:
119             comm.send(my_relative_error, dest=1, tag=11)
120             other_relative_error = comm.recv(source=1, tag=17)
121         elif rank == 1:
122             other_relative_error = comm.recv(source=0, tag=11)
123             comm.send(my_relative_error, dest=0, tag=17)
124         
125         print("Processor ", rank, " : Difference between the two processor relative errors is ", abs(my_relative_error-other_relative_error) )
126         #print("Processor ", rank, " : Difference between the two processors is ", (my_ResultField-other_ResultField).normMax()[0] )
127