Salome HOME
fix conflict
[modules/med.git] / medtool / src / ParaMEDMEMTest / ParaMEDMEMTest_OverlapDEC.cxx
index c7a6104619bb4c25f2ebe83b17102e96d56fa274..f6b14cf496b72f11bb4d509fb395a1532e9bd77a 100644 (file)
 
 #include <set>
 
-void ParaMEDMEMTest::testOverlapDEC1()
-{
-  std::string srcM("P0");
-  std::string targetM("P0");
-  int size;
-  int rank;
-  MPI_Comm_size(MPI_COMM_WORLD,&size);
-  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
+using namespace std;
 
-  if (size != 3) return ;
-   
-  int nproc = 3;
-  std::set<int> procs;
-  
-  for (int i=0; i<nproc; i++)
-    procs.insert(i);
-  
-  ParaMEDMEM::CommInterface interface;
-
-  ParaMEDMEM::OverlapDEC dec(procs);
-
-  ParaMEDMEM::MEDCouplingUMesh* meshS=0;
-  ParaMEDMEM::MEDCouplingUMesh* meshT=0;
-  ParaMEDMEM::ParaMESH* parameshS=0;
-  ParaMEDMEM::ParaMESH* parameshT=0;
-  ParaMEDMEM::ParaFIELD* parafieldS=0;
-  ParaMEDMEM::ParaFIELD* parafieldT=0;
-  
-  MPI_Barrier(MPI_COMM_WORLD);
+#include "MEDCouplingAutoRefCountObjectPtr.hxx"
+#include "MEDLoader.hxx"
+#include "MEDLoaderBase.hxx"
+#include "MEDCouplingFieldDouble.hxx"
+#include "MEDCouplingMemArray.hxx"
+#include "MEDCouplingRemapper.hxx"
+
+using namespace ParaMEDMEM;
+
+typedef  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> MUMesh;
+typedef  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> MFDouble;
+typedef  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> DADouble;
+
+//void ParaMEDMEMTest::testOverlapDEC_LMEC_seq()
+//{
+//  //  T_SC_Trio_src.med  -- "SupportOf_"
+//  //  T_SC_Trio_dst.med  -- "SupportOf_T_SC_Trio"
+//  //  h_TH_Trio_src.med  -- "SupportOf_"
+//  //  h_TH_Trio_dst.med  -- "SupportOf_h_TH_Trio"
+//  string rep("/export/home/adrien/support/antoine_LMEC/");
+//  string src_mesh_nam(rep + string("T_SC_Trio_src.med"));
+//  string tgt_mesh_nam(rep + string("T_SC_Trio_dst.med"));
+////  string src_mesh_nam(rep + string("h_TH_Trio_src.med"));
+////  string tgt_mesh_nam(rep + string("h_TH_Trio_dst.med"));
+//  MUMesh src_mesh=MEDLoader::ReadUMeshFromFile(src_mesh_nam,"SupportOf_",0);
+//  MUMesh tgt_mesh=MEDLoader::ReadUMeshFromFile(tgt_mesh_nam,"SupportOf_T_SC_Trio",0);
+////  MUMesh tgt_mesh=MEDLoader::ReadUMeshFromFile(tgt_mesh_nam,"SupportOf_h_TH_Trio",0);
+//
+//  MFDouble srcField = MEDCouplingFieldDouble::New(ON_CELLS, ONE_TIME);
+//  srcField->setMesh(src_mesh);
+//  DataArrayDouble * dad = DataArrayDouble::New(); dad->alloc(src_mesh->getNumberOfCells(),1);
+//  dad->fillWithValue(1.0);
+//  srcField->setArray(dad);
+//  srcField->setNature(ConservativeVolumic);
+//
+//  MEDCouplingRemapper remap;
+//  remap.setOrientation(2); // always consider surface intersections as absolute areas.
+//  remap.prepare(src_mesh, tgt_mesh, "P0P0");
+//  MFDouble tgtField = remap.transferField(srcField, 1.0e+300);
+//  tgtField->setName("result");
+//  string out_nam(rep + string("adrien.med"));
+//  MEDLoader::WriteField(out_nam,tgtField, true);
+//  cout << "wrote: " << out_nam << "\n";
+//  double integ1 = 0.0, integ2 = 0.0;
+//  srcField->integral(true, &integ1);
+//  tgtField->integral(true, &integ2);
+////  tgtField->reprQuickOverview(cout);
+//  CPPUNIT_ASSERT_DOUBLES_EQUAL(integ1,integ2,1e-8);
+//
+//  dad->decrRef();
+//}
+//
+//void ParaMEDMEMTest::testOverlapDEC_LMEC_para()
+//{
+//  using namespace ParaMEDMEM;
+//
+//  int size;
+//  int rank;
+//  MPI_Comm_size(MPI_COMM_WORLD,&size);
+//  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
+//
+//  if (size != 1) return ;
+//
+//  int nproc = 1;
+//  std::set<int> procs;
+//
+//  for (int i=0; i<nproc; i++)
+//    procs.insert(i);
+//
+//  CommInterface interface;
+//  OverlapDEC dec(procs);
+//
+//  ParaMESH* parameshS=0;
+//  ParaMESH* parameshT=0;
+//  ParaFIELD* parafieldS=0;
+//  ParaFIELD* parafieldT=0;
+//  MFDouble srcField;
+//
+//  // **** FILE LOADING
+//  //  T_SC_Trio_src.med  -- "SupportOf_"
+//  //  T_SC_Trio_dst.med  -- "SupportOf_T_SC_Trio"
+//  //  h_TH_Trio_src.med  -- "SupportOf_"
+//  //  h_TH_Trio_dst.med  -- "SupportOf_h_TH_Trio"
+//  string rep("/export/home/adrien/support/antoine_LMEC/");
+//  string src_mesh_nam(rep + string("T_SC_Trio_src.med"));
+//  string tgt_mesh_nam(rep + string("T_SC_Trio_dst.med"));
+//
+//
+//  MPI_Barrier(MPI_COMM_WORLD);
+//  if(rank==0)
+//    {
+//    //  string src_mesh_nam(rep + string("h_TH_Trio_src.med"));
+//    //  string tgt_mesh_nam(rep + string("h_TH_Trio_dst.med"));
+//      MUMesh src_mesh=MEDLoader::ReadUMeshFromFile(src_mesh_nam,"SupportOf_",0);
+//      MUMesh tgt_mesh=MEDLoader::ReadUMeshFromFile(tgt_mesh_nam,"SupportOf_T_SC_Trio",0);
+//    //  MUMesh tgt_mesh=MEDLoader::ReadUMeshFromFile(tgt_mesh_nam,"SupportOf_h_TH_Trio",0);
+//
+//      // **** SOURCE
+//      srcField = MEDCouplingFieldDouble::New(ON_CELLS, ONE_TIME);
+//      srcField->setMesh(src_mesh);
+//      DataArrayDouble * dad = DataArrayDouble::New(); dad->alloc(src_mesh->getNumberOfCells(),1);
+//      dad->fillWithValue(1.0);
+//      srcField->setArray(dad);
+//      srcField->setNature(ConservativeVolumic);
+//
+//      ComponentTopology comptopo;
+//      parameshS = new ParaMESH(src_mesh,*dec.getGroup(),"source mesh");
+//      parafieldS = new ParaFIELD(ON_CELLS,ONE_TIME,parameshS,comptopo);
+//      parafieldS->getField()->setNature(ConservativeVolumic);//IntegralGlobConstraint
+//      parafieldS->getField()->setArray(dad);
+//
+//      // **** TARGET
+//      parameshT=new ParaMESH(tgt_mesh,*dec.getGroup(),"target mesh");
+//      parafieldT=new ParaFIELD(ON_CELLS,ONE_TIME,parameshT,comptopo);
+//      parafieldT->getField()->setNature(ConservativeVolumic);//IntegralGlobConstraint
+//      parafieldT->getField()->getArray()->fillWithValue(1.0e300);
+////      valsT[0]=7.;
+//    }
+//  dec.setOrientation(2);
+//  dec.attachSourceLocalField(parafieldS);
+//  dec.attachTargetLocalField(parafieldT);
+//  dec.synchronize();
+//  dec.sendRecvData(true);
+//  //
+//  if(rank==0)
+//    {
+//      double integ1 = 0.0, integ2 = 0.0;
+//      MEDCouplingFieldDouble * tgtField;
+//
+//      srcField->integral(true, &integ1);
+//      tgtField = parafieldT->getField();
+////      tgtField->reprQuickOverview(cout);
+//      tgtField->integral(true, &integ2);
+//      tgtField->setName("result");
+//      string out_nam(rep + string("adrien_para.med"));
+//      MEDLoader::WriteField(out_nam,tgtField, true);
+//      cout << "wrote: " << out_nam << "\n";
+//      CPPUNIT_ASSERT_DOUBLES_EQUAL(integ1,integ2,1e-8);
+//    }
+//  delete parafieldS;
+//  delete parafieldT;
+//  delete parameshS;
+//  delete parameshT;
+//
+//  MPI_Barrier(MPI_COMM_WORLD);
+//}
+//
+void prepareData1(int rank, NatureOfField nature,
+                  MEDCouplingFieldDouble *& fieldS, MEDCouplingFieldDouble *& fieldT)
+{
   if(rank==0)
     {
       const double coordsS[10]={0.,0.,0.5,0.,1.,0.,0.,0.5,0.5,0.5};
       const double coordsT[6]={0.,0.,1.,0.,1.,1.};
-      meshS=ParaMEDMEM::MEDCouplingUMesh::New();
+      MUMesh meshS=MEDCouplingUMesh::New();
       meshS->setMeshDimension(2);
-      ParaMEDMEM::DataArrayDouble *myCoords=ParaMEDMEM::DataArrayDouble::New();
+      DataArrayDouble *myCoords=DataArrayDouble::New();
       myCoords->alloc(5,2);
       std::copy(coordsS,coordsS+10,myCoords->getPointer());
       meshS->setCoords(myCoords);
@@ -78,16 +201,16 @@ void ParaMEDMEMTest::testOverlapDEC1()
       meshS->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,connS);
       meshS->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connS+4);
       meshS->finishInsertingCells();
-      ParaMEDMEM::ComponentTopology comptopo;
-      parameshS=new ParaMEDMEM::ParaMESH(meshS,*dec.getGrp(),"source mesh");
-      parafieldS=new ParaMEDMEM::ParaFIELD(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME,parameshS,comptopo);
-      parafieldS->getField()->setNature(ParaMEDMEM::ConservativeVolumic);//IntegralGlobConstraint
-      double *valsS=parafieldS->getField()->getArray()->getPointer();
+      fieldS = MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+      DADouble arr = DataArrayDouble::New(); arr->alloc(meshS->getNumberOfCells(), 1);
+      fieldS->setMesh(meshS); fieldS->setArray(arr);
+      fieldS->setNature(nature);
+      double *valsS=fieldS->getArray()->getPointer();
       valsS[0]=7.; valsS[1]=8.;
       //
-      meshT=ParaMEDMEM::MEDCouplingUMesh::New();
+      MUMesh meshT=MEDCouplingUMesh::New();
       meshT->setMeshDimension(2);
-      myCoords=ParaMEDMEM::DataArrayDouble::New();
+      myCoords=DataArrayDouble::New();
       myCoords->alloc(3,2);
       std::copy(coordsT,coordsT+6,myCoords->getPointer());
       meshT->setCoords(myCoords);
@@ -96,10 +219,11 @@ void ParaMEDMEMTest::testOverlapDEC1()
       meshT->allocateCells(1);
       meshT->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connT);
       meshT->finishInsertingCells();
-      parameshT=new ParaMEDMEM::ParaMESH(meshT,*dec.getGrp(),"target mesh");
-      parafieldT=new ParaMEDMEM::ParaFIELD(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME,parameshT,comptopo);
-      parafieldT->getField()->setNature(ParaMEDMEM::ConservativeVolumic);//IntegralGlobConstraint
-      double *valsT=parafieldT->getField()->getArray()->getPointer();
+      fieldT = MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+      DADouble arr2 = DataArrayDouble::New(); arr2->alloc(meshT->getNumberOfCells(), 1);
+      fieldT->setMesh(meshT);  fieldT->setArray(arr2);
+      fieldT->setNature(nature);
+      double *valsT=fieldT->getArray()->getPointer();
       valsT[0]=7.;
     }
   //
@@ -107,9 +231,9 @@ void ParaMEDMEMTest::testOverlapDEC1()
     {
       const double coordsS[10]={1.,0.,0.5,0.5,1.,0.5,0.5,1.,1.,1.};
       const double coordsT[6]={0.,0.,0.5,0.5,0.,1.};
-      meshS=ParaMEDMEM::MEDCouplingUMesh::New();
+      MUMesh meshS=MEDCouplingUMesh::New();
       meshS->setMeshDimension(2);
-      ParaMEDMEM::DataArrayDouble *myCoords=ParaMEDMEM::DataArrayDouble::New();
+      DataArrayDouble *myCoords=DataArrayDouble::New();
       myCoords->alloc(5,2);
       std::copy(coordsS,coordsS+10,myCoords->getPointer());
       meshS->setCoords(myCoords);
@@ -119,16 +243,16 @@ void ParaMEDMEMTest::testOverlapDEC1()
       meshS->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connS);
       meshS->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,connS+3);
       meshS->finishInsertingCells();
-      ParaMEDMEM::ComponentTopology comptopo;
-      parameshS=new ParaMEDMEM::ParaMESH(meshS,*dec.getGrp(),"source mesh");
-      parafieldS=new ParaMEDMEM::ParaFIELD(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME,parameshS,comptopo);
-      parafieldS->getField()->setNature(ParaMEDMEM::ConservativeVolumic);//IntegralGlobConstraint
-      double *valsS=parafieldS->getField()->getArray()->getPointer();
+      fieldS = MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+      DADouble arr = DataArrayDouble::New(); arr->alloc(meshS->getNumberOfCells(), 1);
+      fieldS->setMesh(meshS); fieldS->setArray(arr);
+      fieldS->setNature(nature);
+      double *valsS=fieldS->getArray()->getPointer();
       valsS[0]=9.; valsS[1]=11.;
       //
-      meshT=ParaMEDMEM::MEDCouplingUMesh::New();
+      MUMesh meshT=MEDCouplingUMesh::New();
       meshT->setMeshDimension(2);
-      myCoords=ParaMEDMEM::DataArrayDouble::New();
+      myCoords=DataArrayDouble::New();
       myCoords->alloc(3,2);
       std::copy(coordsT,coordsT+6,myCoords->getPointer());
       meshT->setCoords(myCoords);
@@ -137,10 +261,11 @@ void ParaMEDMEMTest::testOverlapDEC1()
       meshT->allocateCells(1);
       meshT->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connT);
       meshT->finishInsertingCells();
-      parameshT=new ParaMEDMEM::ParaMESH(meshT,*dec.getGrp(),"target mesh");
-      parafieldT=new ParaMEDMEM::ParaFIELD(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME,parameshT,comptopo);
-      parafieldT->getField()->setNature(ParaMEDMEM::ConservativeVolumic);//IntegralGlobConstraint
-      double *valsT=parafieldT->getField()->getArray()->getPointer();
+      fieldT = MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+      DADouble arr2 = DataArrayDouble::New(); arr2->alloc(meshT->getNumberOfCells(), 1);
+      fieldT->setMesh(meshT);  fieldT->setArray(arr2);
+      fieldT->setNature(nature);
+      double *valsT=fieldT->getArray()->getPointer();
       valsT[0]=8.;
     }
   //
@@ -148,9 +273,9 @@ void ParaMEDMEMTest::testOverlapDEC1()
     {
       const double coordsS[8]={0.,0.5, 0.5,0.5, 0.,1., 0.5,1.};
       const double coordsT[6]={0.5,0.5,0.,1.,1.,1.};
-      meshS=ParaMEDMEM::MEDCouplingUMesh::New();
+      MUMesh meshS=MEDCouplingUMesh::New();
       meshS->setMeshDimension(2);
-      ParaMEDMEM::DataArrayDouble *myCoords=ParaMEDMEM::DataArrayDouble::New();
+      DataArrayDouble *myCoords=DataArrayDouble::New();
       myCoords->alloc(4,2);
       std::copy(coordsS,coordsS+8,myCoords->getPointer());
       meshS->setCoords(myCoords);
@@ -159,16 +284,16 @@ void ParaMEDMEMTest::testOverlapDEC1()
       meshS->allocateCells(1);
       meshS->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,connS);
       meshS->finishInsertingCells();
-      ParaMEDMEM::ComponentTopology comptopo;
-      parameshS=new ParaMEDMEM::ParaMESH(meshS,*dec.getGrp(),"source mesh");
-      parafieldS=new ParaMEDMEM::ParaFIELD(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME,parameshS,comptopo);
-      parafieldS->getField()->setNature(ParaMEDMEM::ConservativeVolumic);//IntegralGlobConstraint
-      double *valsS=parafieldS->getField()->getArray()->getPointer();
+      fieldS = MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+      DADouble arr = DataArrayDouble::New(); arr->alloc(meshS->getNumberOfCells(), 1);
+      fieldS->setMesh(meshS); fieldS->setArray(arr);
+      fieldS->setNature(nature);
+      double *valsS=fieldS->getArray()->getPointer();
       valsS[0]=10.;
       //
-      meshT=ParaMEDMEM::MEDCouplingUMesh::New();
+      MUMesh meshT=MEDCouplingUMesh::New();
       meshT->setMeshDimension(2);
-      myCoords=ParaMEDMEM::DataArrayDouble::New();
+      myCoords=DataArrayDouble::New();
       myCoords->alloc(3,2);
       std::copy(coordsT,coordsT+6,myCoords->getPointer());
       meshT->setCoords(myCoords);
@@ -177,28 +302,395 @@ void ParaMEDMEMTest::testOverlapDEC1()
       meshT->allocateCells(1);
       meshT->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connT);
       meshT->finishInsertingCells();
-      parameshT=new ParaMEDMEM::ParaMESH(meshT,*dec.getGrp(),"target mesh");
-      parafieldT=new ParaMEDMEM::ParaFIELD(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME,parameshT,comptopo);
-      parafieldT->getField()->setNature(ParaMEDMEM::ConservativeVolumic);//IntegralGlobConstraint
-      double *valsT=parafieldT->getField()->getArray()->getPointer();
+      fieldT = MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+      DADouble arr2 = DataArrayDouble::New(); arr2->alloc(meshT->getNumberOfCells(), 1);
+      fieldT->setMesh(meshT); fieldT->setArray(arr2);
+      fieldT->setNature(nature);
+      double *valsT=fieldT->getArray()->getPointer();
       valsT[0]=9.;
     }
+}
+
+void prepareData2_buildOneSquare(MEDCouplingUMesh* & meshS_0, MEDCouplingUMesh* & meshT_0)
+{
+  const double coords[10] = {0.0,0.0,  0.0,1.0,  1.0,1.0,  1.0,0.0, 0.5,0.5};
+  meshS_0 = MEDCouplingUMesh::New("source", 2);
+  DataArrayDouble *myCoords=DataArrayDouble::New();
+  myCoords->alloc(5,2);
+  std::copy(coords,coords+10,myCoords->getPointer());
+  meshS_0->setCoords(myCoords);  myCoords->decrRef();
+  int connS[4]={0,1,2,3};
+  meshS_0->allocateCells(2);
+  meshS_0->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,connS);
+  //
+  meshT_0 = MEDCouplingUMesh::New("target", 2);
+  myCoords=DataArrayDouble::New();
+  myCoords->alloc(5,2);
+  std::copy(coords,coords+10,myCoords->getPointer());
+  meshT_0->setCoords(myCoords);
+  myCoords->decrRef();
+  int connT[12]={0,1,4,  1,2,4,  2,3,4,  3,0,4};
+  meshT_0->allocateCells(4);
+  meshT_0->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connT);
+  meshT_0->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connT+3);
+  meshT_0->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connT+6);
+  meshT_0->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,connT+9);
+}
+
+/**
+ * Prepare five (detached) QUAD4 disposed like this:
+ *   (0)  (1)  (2)
+ *   (3)  (4)
+ *
+ * On the target side the global mesh is identical except that each QUAD4 is split in 4 TRI3 (along the diagonals).
+ * This is a case for two procs:
+ *    - proc #0 has source squares 0,1,2 and target squares 0,3 (well, sets of TRI3s actually)
+ *    - proc #1 has source squares 3,4 and target squares 1,2,4
+ */
+void prepareData2(int rank, ProcessorGroup * grp, NatureOfField nature,
+                  MEDCouplingUMesh *& meshS, MEDCouplingUMesh *& meshT,
+                  ParaMESH*& parameshS, ParaMESH*& parameshT,
+                  ParaFIELD*& parafieldS, ParaFIELD*& parafieldT,
+                  bool stripPartOfSource=false,
+                  int fieldCompoNum=1)
+{
+  MEDCouplingUMesh *meshS_0 = 0, *meshT_0 = 0;
+  prepareData2_buildOneSquare(meshS_0, meshT_0);
+
+  if(rank==0)
+    {
+      const double tr1[] = {1.5, 0.0};
+      MEDCouplingUMesh *meshS_1 = static_cast<MEDCouplingUMesh*>(meshS_0->deepCpy());
+      meshS_1->translate(tr1);
+      const double tr2[] = {3.0, 0.0};
+      MEDCouplingUMesh *meshS_2 = static_cast<MEDCouplingUMesh*>(meshS_0->deepCpy());
+      meshS_2->translate(tr2);
+
+      std::vector<const MEDCouplingUMesh*> vec;
+      vec.push_back(meshS_0);vec.push_back(meshS_1);
+      if (!stripPartOfSource)
+        vec.push_back(meshS_2);
+      meshS = MEDCouplingUMesh::MergeUMeshes(vec);
+      meshS_1->decrRef(); meshS_2->decrRef();
+
+      ComponentTopology comptopo(fieldCompoNum);
+      parameshS=new ParaMESH(meshS, *grp,"source mesh");
+      parafieldS=new ParaFIELD(ON_CELLS,ONE_TIME,parameshS,comptopo);
+      parafieldS->getField()->setNature(nature);
+      double *valsS=parafieldS->getField()->getArray()->getPointer();
+      for(int i=0; i < fieldCompoNum; i++)
+        {
+          valsS[i] = 1. * (10^i);
+          valsS[fieldCompoNum+i] = 2. * (10^i);
+          if (!stripPartOfSource)
+            {
+              valsS[2*fieldCompoNum+i] = 3. * (10^i);
+            }
+        }
+
+      //
+      const double tr3[] = {0.0, -1.5};
+      MEDCouplingUMesh *meshT_3 = static_cast<MEDCouplingUMesh*>(meshT_0->deepCpy());
+      meshT_3->translate(tr3);
+      vec.clear();
+      vec.push_back(meshT_0);vec.push_back(meshT_3);
+      meshT = MEDCouplingUMesh::MergeUMeshes(vec);
+      meshT_3->decrRef();
+
+      parameshT=new ParaMESH(meshT,*grp,"target mesh");
+      parafieldT=new ParaFIELD(ON_CELLS,ONE_TIME,parameshT,comptopo);
+      parafieldT->getField()->setNature(nature);
+    }
+  //
+  if(rank==1)
+    {
+      const double tr3[] = {0.0, -1.5};
+      MEDCouplingUMesh *meshS_3 = static_cast<MEDCouplingUMesh*>(meshS_0->deepCpy());
+      meshS_3->translate(tr3);
+      const double tr4[] = {1.5, -1.5};
+      MEDCouplingUMesh *meshS_4 = static_cast<MEDCouplingUMesh*>(meshS_0->deepCpy());
+      meshS_4->translate(tr4);
+
+      std::vector<const MEDCouplingUMesh*> vec;
+      vec.push_back(meshS_3);vec.push_back(meshS_4);
+      meshS = MEDCouplingUMesh::MergeUMeshes(vec);
+      meshS_3->decrRef(); meshS_4->decrRef();
+
+      ComponentTopology comptopo(fieldCompoNum);
+      parameshS=new ParaMESH(meshS, *grp,"source mesh");
+      parafieldS=new ParaFIELD(ON_CELLS,ONE_TIME,parameshS,comptopo);
+      parafieldS->getField()->setNature(nature);
+      double *valsS=parafieldS->getField()->getArray()->getPointer();
+      for(int i=0; i < fieldCompoNum; i++)
+        {
+          valsS[i] = 4. * (10^i);
+          valsS[fieldCompoNum+i] = 5. * (10^i);
+        }
+
+      //
+      const double tr5[] = {1.5, 0.0};
+      MEDCouplingUMesh *meshT_1 = static_cast<MEDCouplingUMesh*>(meshT_0->deepCpy());
+      meshT_1->translate(tr5);
+      const double tr6[] = {3.0, 0.0};
+      MEDCouplingUMesh *meshT_2 = static_cast<MEDCouplingUMesh*>(meshT_0->deepCpy());
+      meshT_2->translate(tr6);
+      const double tr7[] = {1.5, -1.5};
+      MEDCouplingUMesh *meshT_4 = static_cast<MEDCouplingUMesh*>(meshT_0->deepCpy());
+      meshT_4->translate(tr7);
+
+      vec.clear();
+      vec.push_back(meshT_1);vec.push_back(meshT_2);vec.push_back(meshT_4);
+      meshT = MEDCouplingUMesh::MergeUMeshes(vec);
+      meshT_1->decrRef(); meshT_2->decrRef(); meshT_4->decrRef();
+
+      parameshT=new ParaMESH(meshT,*grp,"target mesh");
+      parafieldT=new ParaFIELD(ON_CELLS,ONE_TIME,parameshT,comptopo);
+      parafieldT->getField()->setNature(nature);
+    }
+  meshS_0->decrRef();
+  meshT_0->decrRef();
+}
+
+/*! Test case from the official doc of the OverlapDEC.
+ *  WARNING: bounding boxes might be tweaked here to make the case more interesting (i.e. to avoid an all to all exchange
+ *  between all procs).
+ */
+void testOverlapDEC_generic(int workSharingAlgo, double bbAdj)
+{
+  int size, rank;
+  MPI_Comm_size(MPI_COMM_WORLD,&size);
+  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
+  //  char hostname[256];
+  //  printf("(%d) PID %d on localhost ready for attach\n", rank, getpid());
+  //  fflush(stdout);
+
+//    if (rank == 0)
+//      {
+//        int i=1, j=0;
+//        while (i!=0)
+//          j=2;
+//      }
+
+  if (size != 3) return ;
+  int nproc = 3;
+  std::set<int> procs;
+  for (int i=0; i<nproc; i++)
+    procs.insert(i);
+
+  CommInterface interface;
+  OverlapDEC dec(procs);
+  MEDCouplingFieldDouble * mcfieldS=0, *mcfieldT=0;
+
+  prepareData1(rank, ConservativeVolumic, mcfieldS, mcfieldT);
+
+  // See comment in the caller:
+  dec.setBoundingBoxAdjustmentAbs(bbAdj);
+  dec.setWorkSharingAlgo(workSharingAlgo);  // just to ease debugging
+
+  dec.attachSourceLocalField(mcfieldS);
+  dec.attachTargetLocalField(mcfieldT);
+  dec.synchronize();
+//  dec.debugPrintWorkSharing(std::cout);
+  dec.sendRecvData(true);
+  //
+  MPI_Barrier(MPI_COMM_WORLD);
+  if(rank==0)
+    {
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(8.75,mcfieldT->getArray()->getIJ(0,0),1e-12);
+    }
+  if(rank==1)
+    {
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(8.5,mcfieldT->getArray()->getIJ(0,0),1e-12);
+    }
+  if(rank==2)
+    {
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(10.5,mcfieldT->getArray()->getIJ(0,0),1e-12);
+    }
+
+  mcfieldS->decrRef();
+  mcfieldT->decrRef();
+
+  MPI_Barrier(MPI_COMM_WORLD);
+}
+
+void ParaMEDMEMTest::testOverlapDEC1()
+{
+  /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   *  HACK ON BOUNDING BOX TO MAKE THIS CASE SIMPLE AND USABLE IN DEBUG
+   * Bounding boxes are slightly smaller than should be, thus localizing the work to be done
+   * and avoiding every proc talking to everyone else.
+   * Obviously this is NOT a good idea to do this in production code :-)
+   * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   */
+  testOverlapDEC_generic(0,-1.0e-12);
+}
+
+void ParaMEDMEMTest::testOverlapDEC1_bis()
+{
+   // Same BB hack as above
+  testOverlapDEC_generic(1,-1.0e-12);
+}
+
+void ParaMEDMEMTest::testOverlapDEC1_ter()
+{
+   // Same BB hack as above
+  testOverlapDEC_generic(2, -1.0e-12);
+}
+
+
+/*!
+ * Same as testOverlapDEC1() but with regular bounding boxes. If you're looking for a nice debug case,
+ * testOverlapDEC1() is identical in terms of geometry and field values, and more appropriate.
+ */
+void ParaMEDMEMTest::testOverlapDEC2()
+{
+  testOverlapDEC_generic(0,1.0e-12);
+}
+
+void ParaMEDMEMTest::testOverlapDEC2_bis()
+{
+  testOverlapDEC_generic(1,1.0e-12);
+}
+
+void ParaMEDMEMTest::testOverlapDEC2_ter()
+{
+  testOverlapDEC_generic(2,1.0e-12);
+}
+
+
+/*! Test focused on the mapping of cell IDs.
+ * (i.e. when only part of the source/target mesh is transmitted)
+ */
+void ParaMEDMEMTest::testOverlapDEC3()
+{
+  int size, rank;
+  MPI_Comm_size(MPI_COMM_WORLD,&size);
+  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
+
+  int nproc = 2;
+  if (size != nproc) return ;
+  std::set<int> procs;
+  for (int i=0; i<nproc; i++)
+    procs.insert(i);
+
+  CommInterface interface;
+  OverlapDEC dec(procs);
+  ProcessorGroup * grp = dec.getGroup();
+  MEDCouplingUMesh* meshS=0, *meshT=0;
+  ParaMESH* parameshS=0, *parameshT=0;
+  ParaFIELD* parafieldS=0, *parafieldT=0;
+
+  prepareData2(rank, grp, ConservativeVolumic, meshS, meshT, parameshS, parameshT, parafieldS, parafieldT);
+
   dec.attachSourceLocalField(parafieldS);
   dec.attachTargetLocalField(parafieldT);
   dec.synchronize();
   dec.sendRecvData(true);
   //
+  MEDCouplingFieldDouble * resField = parafieldT->getField();
   if(rank==0)
     {
-      CPPUNIT_ASSERT_DOUBLES_EQUAL(8.75,parafieldT->getField()->getArray()->getIJ(0,0),1e-12);
+      CPPUNIT_ASSERT_EQUAL(8, resField->getNumberOfTuples());
+      for(int i=0;i<4;i++)
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0,resField->getArray()->getIJ(i,0),1e-12);
+      for(int i=4;i<8;i++)
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0,resField->getArray()->getIJ(i,0),1e-12);
     }
   if(rank==1)
     {
-      CPPUNIT_ASSERT_DOUBLES_EQUAL(8.5,parafieldT->getField()->getArray()->getIJ(0,0),1e-12);
+      CPPUNIT_ASSERT_EQUAL(12, resField->getNumberOfTuples());
+      for(int i=0;i<4;i++)
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(2.0,resField->getArray()->getIJ(i,0),1e-12);
+      for(int i=4;i<8;i++)
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0,resField->getArray()->getIJ(i,0),1e-12);
+      for(int i=8;i<12;i++)
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(5.0,resField->getArray()->getIJ(i,0),1e-12);
     }
-  if(rank==2)
+  delete parafieldS;
+  delete parafieldT;
+  delete parameshS;
+  delete parameshT;
+  meshS->decrRef();
+  meshT->decrRef();
+
+  MPI_Barrier(MPI_COMM_WORLD);
+}
+
+/*!
+ * Tests:
+ *  - default value
+ *  - multi-component fields
+ */
+void ParaMEDMEMTest::testOverlapDEC4()
+{
+  int size, rank;
+  MPI_Comm_size(MPI_COMM_WORLD,&size);
+  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
+
+  int nproc = 2;
+  if (size != nproc) return ;
+  std::set<int> procs;
+  for (int i=0; i<nproc; i++)
+    procs.insert(i);
+
+  CommInterface interface;
+  OverlapDEC dec(procs);
+  ProcessorGroup * grp = dec.getGroup();
+  MEDCouplingUMesh* meshS=0, *meshT=0;
+  ParaMESH* parameshS=0, *parameshT=0;
+  ParaFIELD* parafieldS=0, *parafieldT=0;
+
+  // As before, except than one of the source cell is removed, and that the field now has 2 components
+  prepareData2(rank, grp, ConservativeVolumic, meshS, meshT, parameshS, parameshT, parafieldS, parafieldT,
+               true, 2);
+//  if (rank == 1)
+//    {
+//      int i=1, j=0;
+//      while (i!=0)
+//        j=2;
+//    }
+
+  dec.attachSourceLocalField(parafieldS);
+  dec.attachTargetLocalField(parafieldT);
+  double defVal = -300.0;
+  dec.setDefaultValue(defVal);
+  dec.synchronize();
+  dec.sendRecvData(true);
+  //
+  MEDCouplingFieldDouble * resField = parafieldT->getField();
+  if(rank==0)
+    {
+      CPPUNIT_ASSERT_EQUAL(8, resField->getNumberOfTuples());
+      for(int i=0;i<4;i++)
+        {
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0,resField->getArray()->getIJ(i*2,0),1e-12);
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(10.0,resField->getArray()->getIJ(i*2+1,0),1e-12);
+        }
+      for(int i=4;i<8;i++)
+        {
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0,resField->getArray()->getIJ(i*2,0),1e-12);
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(40.0,resField->getArray()->getIJ(i*2+1,0),1e-12);
+        }
+    }
+  if(rank==1)
     {
-      CPPUNIT_ASSERT_DOUBLES_EQUAL(10.5,parafieldT->getField()->getArray()->getIJ(0,0),1e-12);
+      CPPUNIT_ASSERT_EQUAL(12, resField->getNumberOfTuples());
+      for(int i=0;i<4;i++)
+        {
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(2.0,resField->getArray()->getIJ(i*2,0),1e-12);
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(20.0,resField->getArray()->getIJ(i*2+1,0),1e-12);
+        }
+      // Default value should be here:
+      for(int i=4;i<8;i++)
+        {
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(defVal,resField->getArray()->getIJ(i*2,0),1e-12);
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(defVal,resField->getArray()->getIJ(i*2+1,0),1e-12);
+        }
+      for(int i=8;i<12;i++)
+        {
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(5.0,resField->getArray()->getIJ(i*2,0),1e-12);
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(50.0,resField->getArray()->getIJ(i*2+1,0),1e-12);
+        }
     }
   delete parafieldS;
   delete parafieldT;