Salome HOME
Tested use of sub communicators
[tools/solverlab.git] / CoreFlows / examples / Python / MPI4PY / testSendRecvFieldSubComm.py
index ed8a3a85121d0f0fc88e3753e86e60500ec85777..79e376544b1685132bff3ac5ad0aef05a63b0d69 100644 (file)
@@ -2,7 +2,7 @@
 # -*-coding:utf-8 -*
 
 #===============================================================================================================================
-# Name        : Tests of using a subcommnicator for sending and receiving a 3D MEDCoupling field on cells (P0) lying on the same mesh between two processors
+# Name        : Tests of using a subcommnicator for sending and receiving a 3D MEDCoupling field on cells (P0) lying on the same mesh between two groups of two processors
 # Author      : MichaĆ«l Ndjinga
 # Copyright   : CEA Saclay 2021
 # Description : Use of the parallel Data Exchange Channel StructuredCoincidentDEC of MEDCoupling
 from mpi4py import MPI
 import medcoupling as mc
 
-comm = MPI.COMM_WORLD
-size = comm.Get_size()
-rank = comm.Get_rank()
 
-if(size!=3):
-       raise ValueError("Processor ", rank, " : aborting.\n Simulation should done on three processors.\n", size, " processors given")
+size = MPI.COMM_WORLD.Get_size()
+rank = MPI.COMM_WORLD.Get_rank()
+
+if(size!=4):
+       raise ValueError("Processor ", rank, " : aborting.\n Simulation should done on four processors.\n", size, " processors given")
+
+color=rank%2;
        
-print("My rank is ", rank, " among ", size, "processors")
+print("My rank is ", rank, " among ", size, "processors, my color is ", color)
+
+sub_comm = MPI.COMM_WORLD.Split(color, rank);  # two groups (0,2) and (1,3)
+sub_rank = sub_comm.Get_rank();
+sub_size = sub_comm.Get_size();
 
 procs_source = [0]
 procs_target = [1]
-procs_idle = [2]
+
+print("WORLD RANK/SIZE: ",rank,"/",size," \t subcommunicator RANK/SIZE: ",sub_rank,"/",sub_size,"\n")
 
 interface = mc.CommInterface()
-source_group = mc.MPIProcessorGroup(interface, procs_source)
-target_group = mc.MPIProcessorGroup(interface, procs_target)
+source_group = mc.MPIProcessorGroup(interface, procs_source,sub_comm)
+target_group = mc.MPIProcessorGroup(interface, procs_target,sub_comm)
 dec = mc.StructuredCoincidentDEC(source_group, target_group)
 
 # Create a MEDCouplingUMesh from a 3D cartesian mesh
@@ -41,7 +48,7 @@ mesh.setName("RegularSquare")
 if source_group.containsMyRank():
        field=mesh.fillFromAnalytic(mc.ON_CELLS,1,"(x-5.)*(x-5.)+(y-5.)*(y-5.)+(z-5.)*(z-5.)")
        field.setName("SourceField")
-       mc.WriteField("source_field.med", field, True)
+       mc.WriteField("source_field"+str(rank)+".med", field, True)
        print("Processor ", rank, " has created and saved the source field")
 else:
        field=mesh.fillFromAnalytic(mc.ON_CELLS,1,"0")
@@ -59,10 +66,12 @@ elif target_group.containsMyRank():
        print("Processor ", rank, " has received the source field on the target mesh")
        exact_field=mesh.fillFromAnalytic(mc.ON_CELLS,1,"(x-5.)*(x-5.)+(y-5.)*(y-5.)+(z-5.)*(z-5.)")
        exact_field.setName("ExactField")
-       error=(field-exact_field).normL2()[0]
-       print("Processor ", rank, " received source field differs from theoretical value by ", error, " (L2 norm on cells)" )
+       error=(field-exact_field).normMax()[0]/exact_field.normMax()[0]
+       print("Processor ", rank, " received source field that differs from theoretical value by ", error, " (maximum relative norm on cell values)" )
        assert abs(error)<1.e-6
-       mc.WriteField("target_field.med", field, True)
-       mc.WriteField("exact_field.med", exact_field, True)
+       mc.WriteField("target_field"+str(rank)+".med", field, True)
+       mc.WriteField("exact_field"+str(rank)+".med", exact_field, True)
 else:
        print("Processor ", rank, " did nothing" )
+
+sub_comm.Free()