]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Introduced domain bounding boxes for OverlapDEC, plus: abn/mpi_imp
authorabn <adrien.bruneton@cea.fr>
Fri, 11 Dec 2015 15:28:15 +0000 (16:28 +0100)
committerabn <adrien.bruneton@cea.fr>
Fri, 11 Dec 2015 15:28:15 +0000 (16:28 +0100)
  - algo 2 is now the default
  - bug fix on multi component

src/ParaMEDMEM/OverlapDEC.cxx
src/ParaMEDMEM/OverlapDEC.hxx
src/ParaMEDMEM/OverlapElementLocator.cxx
src/ParaMEDMEM/OverlapElementLocator.hxx
src/ParaMEDMEM/OverlapMapping.cxx
src/ParaMEDMEMTest/ParaMEDMEMTest.hxx
src/ParaMEDMEMTest/ParaMEDMEMTest_OverlapDEC.cxx

index af842fb9dd08f600d6886b8afa3d109c564d4660..c1505e55dff7d73770c3d7171b85084c272eeda8 100644 (file)
@@ -209,7 +209,9 @@ namespace ParaMEDMEM
     The method in charge to perform this is : ParaMEDMEM::OverlapMapping::prepare.
 */
   OverlapDEC::OverlapDEC(const std::set<int>& procIds, const MPI_Comm& world_comm):
-      _load_balancing_algo(1),
+      _load_balancing_algo(2),
+      _domain_bbox_adj(1.0e-4),
+      _domain_bbox_adj_abs(0.0),
       _own_group(true),_interpolation_matrix(0), _locator(0),
       _source_field(0),_own_source_field(false),
       _target_field(0),_own_target_field(false),
@@ -285,7 +287,7 @@ namespace ParaMEDMEM
     if (_target_field->getField()->getNumberOfComponents() != _source_field->getField()->getNumberOfComponents())
       throw INTERP_KERNEL::Exception("OverlapDEC::synchronize(): source and target field have different number of components!");
     delete _interpolation_matrix;
-    _locator = new OverlapElementLocator(_source_field,_target_field,*_group, getBoundingBoxAdjustmentAbs(), _load_balancing_algo);
+    _locator = new OverlapElementLocator(_source_field,_target_field,*_group, _domain_bbox_adj, _domain_bbox_adj_abs, _load_balancing_algo);
     _interpolation_matrix=new OverlapInterpolationMatrix(_source_field,_target_field,*_group,*this,*this, *_locator);
     _locator->copyOptions(*this);
     _locator->exchangeMeshes(*_interpolation_matrix);
index 2d63789b7da6e059f42ff458a905b02fb0abb50c..4e8d52eefec05cf17fe3ce1d09277a3199a02910 100644 (file)
@@ -51,12 +51,24 @@ namespace ParaMEDMEM
     bool isInGroup() const;
 
     void setDefaultValue(double val) {_default_field_value = val;}
-    //! 0 means initial algo from Antho, 1 or 2 means Adrien's algo (2 should be better). Make your choice :-))
+    /*! 0 means initial algo from Antho, 1 or 2 means Adrien's algo (2 should be better). Make your choice :-))
+     *  (1 is mainly kept for debug purposes as it offers a different job repartition)      */
     void setWorkSharingAlgo(int method)  { _load_balancing_algo = method; }
 
+    //! Bounding box adjustment for the domain interaction computations
+    double getDomainBoundingBoxAdjustment() const { return _domain_bbox_adj; }
+    void setDomainBoundingBoxAdjustment(double bba) { _domain_bbox_adj=bba; }
+
+    //! Bounding box adjustment for the domain interaction computations
+    double getDomainBoundingBoxAdjustmentAbs() const { return _domain_bbox_adj_abs; }
+    void setDomainBoundingBoxAdjustmentAbs(double bba) { _domain_bbox_adj_abs=bba; }
+
+
     void debugPrintWorkSharing(std::ostream & ostr) const;
   private:
     int _load_balancing_algo;
+    double _domain_bbox_adj;
+    double _domain_bbox_adj_abs;
 
     bool _own_group;
     OverlapInterpolationMatrix* _interpolation_matrix;
index 81cb987db440f30105e49e23626f591e18443a09..0200de9c60eca14d165f8ece5ff3413a6ee5dfd0 100644 (file)
@@ -42,14 +42,15 @@ namespace ParaMEDMEM
   const int OverlapElementLocator::START_TAG_MESH_XCH = 1140;
 
   OverlapElementLocator::OverlapElementLocator(const ParaFIELD *sourceField, const ParaFIELD *targetField,
-                                               const ProcessorGroup& group, double epsAbs, int workSharingAlgo)
+                                               const ProcessorGroup& group, double eps, double epsAbs, int workSharingAlgo)
     : _local_source_field(sourceField),
       _local_target_field(targetField),
       _local_source_mesh(0),
       _local_target_mesh(0),
       _domain_bounding_boxes(0),
       _group(group),
-      _epsAbs(epsAbs)
+      _bbox_eps(eps),
+      _bbox_eps_abs(epsAbs)
   { 
     if(_local_source_field)
       _local_source_mesh=_local_source_field->getSupport()->getCellMesh();
@@ -65,7 +66,7 @@ namespace ParaMEDMEM
       case 1:
         computeTodoList_new(false);   break;
       case 2:
-        computeTodoList_new(true);    break;
+        computeTodoList_new(true);   break;
       default:
         throw INTERP_KERNEL::Exception("OverlapElementLocator::OverlapElementLocator(): invalid algorithm selected!");
     }
@@ -122,9 +123,10 @@ namespace ParaMEDMEM
     comm_interface.allGather(minmax, bbSize, MPI_DOUBLE,
                              _domain_bounding_boxes,bbSize, MPI_DOUBLE, 
                              *comm);
-  
+    // Adjust bounding boxes with relative and absolute epsilons:
+    adjustDomainBoundingBoxes();
+
     // Computation of all pairs needing an interpolation pairs are duplicated now !
-    
     _proc_pairs.clear();//first is source second is target
     _proc_pairs.resize(_group.size());
     for(int i=0;i<_group.size();i++)
@@ -171,7 +173,7 @@ namespace ParaMEDMEM
    *    + remove this job from proc#i, and mark it as 'unremovable' from proc#j
    *  - repeat until no more duplicates are found
    */
-  void OverlapElementLocator::computeTodoList_new(bool revertIter)
+  void OverlapElementLocator::computeTodoList_new(bool optimized)
   {
     using namespace std;
     int infinity = std::numeric_limits<int>::max();
@@ -227,25 +229,25 @@ namespace ParaMEDMEM
         // Nothing more to do:
         if (max_sz == -1)
           break;
-        // For this proc, job with less loaded second proc:
+        // For this proc (max_id), job with less loaded second proc is to be identified (and then will be removed from max_id)
         int min_sz = infinity;
         map<ProcCouple, int> & max_map = full_set[max_id];
         ProcCouple hit_cpl = make_pair(-1,-1);
-        if(revertIter)
+        for(itMap=max_map.begin(); itMap != max_map.end(); itMap++)
           {
-          // Use a reverse iterator here increases our chances to hit a couple of the form (i, myProcId)
-          // meaning that the final matrix computed won't have to be sent: save some comm.
-          map<ProcCouple, int> ::const_reverse_iterator ritMap;
-          for(ritMap=max_map.rbegin(); ritMap != max_map.rend(); ritMap++)
-            if ((*ritMap).second < min_sz)
-              hit_cpl = (*ritMap).first;
-          }
-        else
-          {
-            for(itMap=max_map.begin(); itMap != max_map.end(); itMap++)
-              if ((*itMap).second < min_sz)
-                hit_cpl = (*itMap).first;
+            int new_size = (*itMap).second;
+            const ProcCouple & a_cpl = (*itMap).first;
+            // If there are several candidates always favor the removal of a job which will not stay local (ie (myProcId, j))
+            // For such a job the computed matrix has to be sent: so avoid some comm.
+            if (new_size < min_sz ||
+                  (optimized && new_size <= min_sz && a_cpl.second != max_id && new_size != infinity)
+                )
+              {
+                min_sz = new_size;
+                hit_cpl = a_cpl;
+              }
           }
+
         if (hit_cpl.first == -1)
           {
             // Plouf. Current proc 'max_id' can not be reduced. Invalid it:
@@ -429,6 +431,34 @@ namespace ParaMEDMEM
     return std::find(_to_do_list.begin(), _to_do_list.end(), cpl)!=_to_do_list.end();
   }
 
+  /*! Readjusts a set of bounding boxes so that they are extended
+    in all dimensions for avoiding missing interesting intersections
+
+    Taken from:
+      void PlanarIntersector<MyMeshType,MyMatrix>::adjustBoundingBoxes(...)
+  */
+  void OverlapElementLocator::adjustDomainBoundingBoxes()
+  {
+    long size = 2*_group.size();           // 2 meshes per proc: source / target
+    int bbSize = size*2*_local_space_dim;  // 2 (min/max)
+
+    for (int i=0; i<size; i++)
+      {
+        double max=- std::numeric_limits<double>::max();
+        for(int idim=0; idim<_local_space_dim; idim++)
+          {
+            // idim(max) - idim(min) = idim(extent)
+            double Dx = _domain_bounding_boxes[i*2*_local_space_dim+1+2*idim] - _domain_bounding_boxes[i*2*_local_space_dim+2*idim];
+            max=(max<Dx)?Dx:max;
+          }
+        for(int idim=0; idim<_local_space_dim; idim++)
+          {
+            _domain_bounding_boxes[i*2*_local_space_dim+2*idim  ] -= _bbox_eps*max + _bbox_eps_abs;
+            _domain_bounding_boxes[i*2*_local_space_dim+2*idim+1] += _bbox_eps*max + _bbox_eps_abs;
+          }
+      }
+  }
+
   bool OverlapElementLocator::intersectsBoundingBox(int isource, int itarget) const
   {
     const double *source_bb=_domain_bounding_boxes+isource*2*2*_local_space_dim;
@@ -436,8 +466,8 @@ namespace ParaMEDMEM
 
     for (int idim=0; idim < _local_space_dim; idim++)
       {
-        bool intersects = (target_bb[idim*2]<source_bb[idim*2+1]+_epsAbs)
-          && (source_bb[idim*2]<target_bb[idim*2+1]+_epsAbs);
+        bool intersects = (target_bb[idim*2]<source_bb[idim*2+1])
+                       && (source_bb[idim*2]<target_bb[idim*2+1]);
         if (!intersects)
           return false; 
       }
index 3ffd028dbb57ce1df667e5168151499fd17bbc08..e35f5f127d23da24ec16ead67afc5a14b5d6b7e7 100644 (file)
@@ -46,7 +46,7 @@ namespace ParaMEDMEM
   {
   public:
     OverlapElementLocator(const ParaFIELD *sourceField, const ParaFIELD *targetField, const ProcessorGroup& group,
-                          double epsAbs, int workSharingAlgo);
+                          double eps, double epsAbs, int workSharingAlgo);
     virtual ~OverlapElementLocator();
     const MPI_Comm *getCommunicator() const;
     void exchangeMeshes(OverlapInterpolationMatrix& matrix);
@@ -61,9 +61,10 @@ namespace ParaMEDMEM
     bool isInMyTodoList(int i, int j) const;
     void debugPrintWorkSharing(std::ostream & ostr) const;
   private:
+    void adjustDomainBoundingBoxes();
     void computeBoundingBoxesAndInteractionList();
     void computeTodoList_original();
-    void computeTodoList_new(bool revertIter);
+    void computeTodoList_new(bool optimized);
     void fillProcToSend();
     bool intersectsBoundingBox(int i, int j) const;
     void sendLocalMeshTo(int procId, bool sourceOrTarget, OverlapInterpolationMatrix& matrix) const;
@@ -102,8 +103,11 @@ namespace ParaMEDMEM
     //! Set of cell ID mappings for the above distant meshes (because only part of the meshes are exchanged)
     std::map< Proc_SrcOrTgt, AutoDAInt > _remote_elems;
     double* _domain_bounding_boxes;
+
+    //! bounding box relative adjustment
+    double _bbox_eps;
     //! bounding box absolute adjustment
-    double _epsAbs;
+    double _bbox_eps_abs;
 
     std::vector<int> _distant_proc_ids;
 
index f66dee02c33d6d9253849c51c90b7f8d7c87126c..a5059bb107c146dfece76d24f14029f42a7a30a5 100644 (file)
@@ -544,7 +544,7 @@ void OverlapMapping::multiply(const MEDCouplingFieldDouble *fieldInput, MEDCoupl
                   throw INTERP_KERNEL::Exception("OverlapMapping::multiply(): internal error: SEND: unexpected end iterator in _sent_src_ids!");
                 vals=fieldInput->getArray()->selectByTupleId(*(*isItem11).second);
               }
-            nbsend[procID] = vals->getNbOfElems();
+            nbsend[procID] = vals->getNbOfElems();  // account for many components
             valsToSend.insert(valsToSend.end(),vals->getConstPointer(),vals->getConstPointer()+nbsend[procID]);
           }
 
@@ -569,7 +569,7 @@ void OverlapMapping::multiply(const MEDCouplingFieldDouble *fieldInput, MEDCoupl
                 map <int,int>::const_iterator isItem11 = _nb_of_rcv_src_ids.find(procID);
                 if (isItem11 == _nb_of_rcv_src_ids.end())
                   throw INTERP_KERNEL::Exception("OverlapMapping::multiply(): internal error: RCV: unexpected end iterator in _nb_of_rcv_src_ids!");
-                nbrecv[procID] = (*isItem11).second;
+                nbrecv[procID] = (*isItem11).second*nbOfCompo;
               }
             else
               {
@@ -619,6 +619,7 @@ void OverlapMapping::multiply(const MEDCouplingFieldDouble *fieldInput, MEDCoupl
 
   // By default field value set to default value - so mark which cells are hit
   INTERP_KERNEL::AutoPtr<bool> hit_cells = new bool[fieldOutput->getNumberOfTuples()];
+  std::fill((bool*)hit_cells, hit_cells+fieldOutput->getNumberOfTuples(), false);
 
   for(vector<int>::const_iterator itProc=_the_matrix_st_source_proc_id.begin(); itProc != _the_matrix_st_source_proc_id.end();itProc++)
   // For each source processor corresponding to a locally held matrix:
index 7deb11dcad6d0312ce7b45e783ac1ee38aa93525..9160b2a2334554f276cd824c086e99a2cebcfe8d 100644 (file)
 class ParaMEDMEMTest : public CppUnit::TestFixture
 {
   CPPUNIT_TEST_SUITE( ParaMEDMEMTest );
-  CPPUNIT_TEST(testMPIProcessorGroup_constructor);  // 1 and 2 procs
-  CPPUNIT_TEST(testMPIProcessorGroup_boolean);      // 1 and 2 procs
-  CPPUNIT_TEST(testMPIProcessorGroup_rank);         // >=2 procs
-  CPPUNIT_TEST(testBlockTopology_constructor);      // >=2 procs
-  CPPUNIT_TEST(testBlockTopology_serialize);        // 1 proc
-  CPPUNIT_TEST(testInterpKernelDEC_1D);             // 5 procs
-  CPPUNIT_TEST(testInterpKernelDEC_2DCurve);        // 5 procs
-  CPPUNIT_TEST(testInterpKernelDEC_2D);             // 5 procs
-  CPPUNIT_TEST(testInterpKernelDEC2_2D);            // 5 procs
-  CPPUNIT_TEST(testInterpKernelDEC_2DP0P1);         // Not impl.
-  CPPUNIT_TEST(testInterpKernelDEC_3D);             // 3 procs
-  CPPUNIT_TEST(testInterpKernelDECNonOverlapp_2D_P0P0);     // 5 procs
-  CPPUNIT_TEST(testInterpKernelDECNonOverlapp_2D_P0P1P1P0); // 5 procs
-  CPPUNIT_TEST(testInterpKernelDEC2DM1D_P0P0);      // 3 procs
-  CPPUNIT_TEST(testInterpKernelDECPartialProcs);    // 3 procs
-  CPPUNIT_TEST(testInterpKernelDEC3DSurfEmptyBBox); // 3 procs
+//  CPPUNIT_TEST(testMPIProcessorGroup_constructor);  // 1 and 2 procs
+//  CPPUNIT_TEST(testMPIProcessorGroup_boolean);      // 1 and 2 procs
+//  CPPUNIT_TEST(testMPIProcessorGroup_rank);         // >=2 procs
+//  CPPUNIT_TEST(testBlockTopology_constructor);      // >=2 procs
+//  CPPUNIT_TEST(testBlockTopology_serialize);        // 1 proc
+//  CPPUNIT_TEST(testInterpKernelDEC_1D);             // 5 procs
+//  CPPUNIT_TEST(testInterpKernelDEC_2DCurve);        // 5 procs
+//  CPPUNIT_TEST(testInterpKernelDEC_2D);             // 5 procs
+//  CPPUNIT_TEST(testInterpKernelDEC2_2D);            // 5 procs
+//  CPPUNIT_TEST(testInterpKernelDEC_2DP0P1);         // Not impl.
+//  CPPUNIT_TEST(testInterpKernelDEC_3D);             // 3 procs
+//  CPPUNIT_TEST(testInterpKernelDECNonOverlapp_2D_P0P0);     // 5 procs
+//  CPPUNIT_TEST(testInterpKernelDECNonOverlapp_2D_P0P1P1P0); // 5 procs
+//  CPPUNIT_TEST(testInterpKernelDEC2DM1D_P0P0);      // 3 procs
+//  CPPUNIT_TEST(testInterpKernelDECPartialProcs);    // 3 procs
+//  CPPUNIT_TEST(testInterpKernelDEC3DSurfEmptyBBox); // 3 procs
+//  CPPUNIT_TEST(testOverlapDEC_LMEC_seq);
+//  CPPUNIT_TEST(testOverlapDEC_LMEC_para);
   CPPUNIT_TEST(testOverlapDEC1);                    // 3 procs
   CPPUNIT_TEST(testOverlapDEC1_bis);                // 3 procs
   CPPUNIT_TEST(testOverlapDEC1_ter);                // 3 procs
@@ -54,33 +56,37 @@ class ParaMEDMEMTest : public CppUnit::TestFixture
   CPPUNIT_TEST(testOverlapDEC2_bis);                // 3 procs
   CPPUNIT_TEST(testOverlapDEC2_ter);                // 3 procs
   CPPUNIT_TEST(testOverlapDEC3);                    // 2 procs
+  CPPUNIT_TEST(testOverlapDEC3_bis);                    // 2 procs
+  CPPUNIT_TEST(testOverlapDEC3_ter);                    // 2 procs
   CPPUNIT_TEST(testOverlapDEC4);                    // 2 procs
-
-  CPPUNIT_TEST(testSynchronousEqualInterpKernelWithoutInterpNativeDEC_2D);// 5 procs
-  CPPUNIT_TEST(testSynchronousEqualInterpKernelWithoutInterpDEC_2D);      // 5 procs
-  CPPUNIT_TEST(testSynchronousEqualInterpKernelDEC_2D);                   // 5 procs
-  CPPUNIT_TEST(testSynchronousFasterSourceInterpKernelDEC_2D);            // 5 procs
-  CPPUNIT_TEST(testSynchronousSlowerSourceInterpKernelDEC_2D);            // 5 procs
-  CPPUNIT_TEST(testSynchronousSlowSourceInterpKernelDEC_2D);              // 5 procs
-  CPPUNIT_TEST(testSynchronousFastSourceInterpKernelDEC_2D);              // 5 procs
-  CPPUNIT_TEST(testAsynchronousEqualInterpKernelDEC_2D);                  // 5 procs
-  CPPUNIT_TEST(testAsynchronousFasterSourceInterpKernelDEC_2D);           // 5 procs
-  CPPUNIT_TEST(testAsynchronousSlowerSourceInterpKernelDEC_2D);           // 5 procs
-  CPPUNIT_TEST(testAsynchronousSlowSourceInterpKernelDEC_2D);             // 5 procs
-  CPPUNIT_TEST(testAsynchronousFastSourceInterpKernelDEC_2D);             // 5 procs
-#ifdef MED_ENABLE_FVM
-  //can be added again after FVM correction for 2D
-  //  CPPUNIT_TEST(testNonCoincidentDEC_2D);
-  CPPUNIT_TEST(testNonCoincidentDEC_3D);
-#endif
-  CPPUNIT_TEST(testStructuredCoincidentDEC);     // 5 procs
-  CPPUNIT_TEST(testICoco1);           // 2 procs
-  CPPUNIT_TEST(testGauthier1);        // 4 procs
-  CPPUNIT_TEST(testGauthier2);        // >= 2 procs
-  CPPUNIT_TEST(testGauthier3);        // 4 procs
-  CPPUNIT_TEST(testGauthier4);        // 3 procs
-  CPPUNIT_TEST(testFabienAPI1);       // 3 procs
-  CPPUNIT_TEST(testFabienAPI2);       // 3 procs
+  CPPUNIT_TEST(testOverlapDEC4_bis);                    // 2 procs
+  CPPUNIT_TEST(testOverlapDEC4_ter);                    // 2 procs
+//
+//  CPPUNIT_TEST(testSynchronousEqualInterpKernelWithoutInterpNativeDEC_2D);// 5 procs
+//  CPPUNIT_TEST(testSynchronousEqualInterpKernelWithoutInterpDEC_2D);      // 5 procs
+//  CPPUNIT_TEST(testSynchronousEqualInterpKernelDEC_2D);                   // 5 procs
+//  CPPUNIT_TEST(testSynchronousFasterSourceInterpKernelDEC_2D);            // 5 procs
+//  CPPUNIT_TEST(testSynchronousSlowerSourceInterpKernelDEC_2D);            // 5 procs
+//  CPPUNIT_TEST(testSynchronousSlowSourceInterpKernelDEC_2D);              // 5 procs
+//  CPPUNIT_TEST(testSynchronousFastSourceInterpKernelDEC_2D);              // 5 procs
+//  CPPUNIT_TEST(testAsynchronousEqualInterpKernelDEC_2D);                  // 5 procs
+//  CPPUNIT_TEST(testAsynchronousFasterSourceInterpKernelDEC_2D);           // 5 procs
+//  CPPUNIT_TEST(testAsynchronousSlowerSourceInterpKernelDEC_2D);           // 5 procs
+//  CPPUNIT_TEST(testAsynchronousSlowSourceInterpKernelDEC_2D);             // 5 procs
+//  CPPUNIT_TEST(testAsynchronousFastSourceInterpKernelDEC_2D);             // 5 procs
+//#ifdef MED_ENABLE_FVM
+//  //can be added again after FVM correction for 2D
+//  //  CPPUNIT_TEST(testNonCoincidentDEC_2D);
+//  CPPUNIT_TEST(testNonCoincidentDEC_3D);
+//#endif
+//  CPPUNIT_TEST(testStructuredCoincidentDEC);     // 5 procs
+//  CPPUNIT_TEST(testICoco1);           // 2 procs
+//  CPPUNIT_TEST(testGauthier1);        // 4 procs
+//  CPPUNIT_TEST(testGauthier2);        // >= 2 procs
+//  CPPUNIT_TEST(testGauthier3);        // 4 procs
+//  CPPUNIT_TEST(testGauthier4);        // 3 procs
+//  CPPUNIT_TEST(testFabienAPI1);       // 3 procs
+//  CPPUNIT_TEST(testFabienAPI2);       // 3 procs
 
   CPPUNIT_TEST_SUITE_END();
 
@@ -106,6 +112,8 @@ public:
   void testInterpKernelDEC2DM1D_P0P0();
   void testInterpKernelDECPartialProcs();
   void testInterpKernelDEC3DSurfEmptyBBox();
+  void testOverlapDEC_LMEC_seq();
+  void testOverlapDEC_LMEC_para();
   void testOverlapDEC1();
   void testOverlapDEC1_bis();
   void testOverlapDEC1_ter();
@@ -113,8 +121,11 @@ public:
   void testOverlapDEC2_bis();
   void testOverlapDEC2_ter();
   void testOverlapDEC3();
-//  void testOverlapDEC3_bis();
+  void testOverlapDEC3_bis();
+  void testOverlapDEC3_ter();
   void testOverlapDEC4();
+  void testOverlapDEC4_bis();
+  void testOverlapDEC4_ter();
 #ifdef MED_ENABLE_FVM
   void testNonCoincidentDEC_2D();
   void testNonCoincidentDEC_3D();
index f6b14cf496b72f11bb4d509fb395a1532e9bd77a..f0c460c1f6bff6968361643e921c412d12a4dc31 100644 (file)
@@ -48,140 +48,132 @@ 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 ParaMEDMEMTest::testOverlapDEC_LMEC_seq()
+{
+  //  T_SC_Trio_src.med  -- "SupportOf_"
+  //  T_SC_Trio_dst.med  -- "SupportOf_T_SC_Trio"   // 2D
+  //  h_TH_Trio_src.med  -- "SupportOf_"
+  //  h_TH_Trio_dst.med  -- "SupportOf_h_TH_Trio"   // 3D
+  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.setBoundingBoxAdjustment(0.0);
+  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);
+  MFDouble srcField, tgtField;
+
+  // **** 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);
+
+      // **** TARGET
+      tgtField = MEDCouplingFieldDouble::New(ON_CELLS, ONE_TIME);
+      tgtField->setMesh(tgt_mesh);
+      DataArrayDouble * dad2 = DataArrayDouble::New(); dad2->alloc(tgt_mesh->getNumberOfCells(),1);
+      dad2->fillWithValue(-10.0);
+      tgtField->setArray(dad2);
+      tgtField->setNature(ConservativeVolumic);
+    }
+
+  dec.setOrientation(2);
+  dec.setBoundingBoxAdjustmentAbs(1.0e-12);
+  dec.setMaxDistance3DSurfIntersect(1e-6);
+  dec.setPrecision(1e-6);
+  dec.setWorkSharingAlgo(1);
+
+  dec.attachSourceLocalField(srcField);
+  dec.attachTargetLocalField(tgtField);
+  dec.setDefaultValue(-20.0);
+  dec.synchronize();
+  dec.sendRecvData(true);
+  //
+  if(rank==0)
+    {
+      double integ1 = 0.0, integ2 = 0.0;
+
+      srcField->integral(true, &integ1);
+      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);
+    }
+
+  MPI_Barrier(MPI_COMM_WORLD);
+}
+
 void prepareData1(int rank, NatureOfField nature,
                   MEDCouplingFieldDouble *& fieldS, MEDCouplingFieldDouble *& fieldT)
 {
@@ -380,11 +372,11 @@ void prepareData2(int rank, ProcessorGroup * grp, NatureOfField 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);
+          valsS[i] = 1. * pow(10, i);
+          valsS[fieldCompoNum+i] = 2. * pow(10, i);
           if (!stripPartOfSource)
             {
-              valsS[2*fieldCompoNum+i] = 3. * (10^i);
+              valsS[2*fieldCompoNum+i] = 3. * pow(10, i);
             }
         }
 
@@ -423,8 +415,8 @@ void prepareData2(int rank, ProcessorGroup * grp, NatureOfField 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);
+          valsS[i] = 4. * pow(10, i);
+          valsS[fieldCompoNum+i] = 5. * pow(10, i);
         }
 
       //
@@ -452,10 +444,10 @@ void prepareData2(int rank, ProcessorGroup * grp, NatureOfField nature,
 }
 
 /*! 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
+ *  WARNING: bounding boxes are 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)
+void testOverlapDEC_generic(int workSharingAlgo, double bbAdj, double bbAdjAbs)
 {
   int size, rank;
   MPI_Comm_size(MPI_COMM_WORLD,&size);
@@ -484,7 +476,8 @@ void testOverlapDEC_generic(int workSharingAlgo, double bbAdj)
   prepareData1(rank, ConservativeVolumic, mcfieldS, mcfieldT);
 
   // See comment in the caller:
-  dec.setBoundingBoxAdjustmentAbs(bbAdj);
+  dec.setDomainBoundingBoxAdjustment(bbAdj);
+  dec.setDomainBoundingBoxAdjustmentAbs(bbAdjAbs);
   dec.setWorkSharingAlgo(workSharingAlgo);  // just to ease debugging
 
   dec.attachSourceLocalField(mcfieldS);
@@ -522,46 +515,45 @@ void ParaMEDMEMTest::testOverlapDEC1()
    * Obviously this is NOT a good idea to do this in production code :-)
    * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    */
-  testOverlapDEC_generic(0,-1.0e-12);
+  testOverlapDEC_generic(0,0.0,-1.0e-12);
 }
 
 void ParaMEDMEMTest::testOverlapDEC1_bis()
 {
    // Same BB hack as above
-  testOverlapDEC_generic(1,-1.0e-12);
+  testOverlapDEC_generic(1,0.0,-1.0e-12);
 }
 
 void ParaMEDMEMTest::testOverlapDEC1_ter()
 {
    // Same BB hack as above
-  testOverlapDEC_generic(2, -1.0e-12);
+  testOverlapDEC_generic(2,0.0,-1.0e-12);
 }
 
 
 /*!
- * Same as testOverlapDEC1() but with regular bounding boxes. If you're looking for a nice debug case,
+ * Same as testOverlapDEC1() but with regular bounding boxes adj values. 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);
+  testOverlapDEC_generic(0, 1.0e-4, 0.0);
 }
 
 void ParaMEDMEMTest::testOverlapDEC2_bis()
 {
-  testOverlapDEC_generic(1,1.0e-12);
+  testOverlapDEC_generic(1, 1.0e-4, 0.0);
 }
 
 void ParaMEDMEMTest::testOverlapDEC2_ter()
 {
-  testOverlapDEC_generic(2,1.0e-12);
+  testOverlapDEC_generic(2, 1.0e-4, 0.0);
 }
 
-
 /*! Test focused on the mapping of cell IDs.
  * (i.e. when only part of the source/target mesh is transmitted)
  */
-void ParaMEDMEMTest::testOverlapDEC3()
+void testOverlapDEC_map_generic(int workSharingAlgo)
 {
   int size, rank;
   MPI_Comm_size(MPI_COMM_WORLD,&size);
@@ -575,6 +567,7 @@ void ParaMEDMEMTest::testOverlapDEC3()
 
   CommInterface interface;
   OverlapDEC dec(procs);
+  dec.setWorkSharingAlgo(workSharingAlgo);
   ProcessorGroup * grp = dec.getGroup();
   MEDCouplingUMesh* meshS=0, *meshT=0;
   ParaMESH* parameshS=0, *parameshT=0;
@@ -616,12 +609,27 @@ void ParaMEDMEMTest::testOverlapDEC3()
   MPI_Barrier(MPI_COMM_WORLD);
 }
 
+void ParaMEDMEMTest::testOverlapDEC3()
+{
+  testOverlapDEC_map_generic(0);
+}
+
+void ParaMEDMEMTest::testOverlapDEC3_bis()
+{
+  testOverlapDEC_map_generic(1);
+}
+
+void ParaMEDMEMTest::testOverlapDEC3_ter()
+{
+  testOverlapDEC_map_generic(2);
+}
+
 /*!
  * Tests:
  *  - default value
  *  - multi-component fields
  */
-void ParaMEDMEMTest::testOverlapDEC4()
+void testOverlapDEC_default_multi(int workSharingAlgo)
 {
   int size, rank;
   MPI_Comm_size(MPI_COMM_WORLD,&size);
@@ -635,6 +643,7 @@ void ParaMEDMEMTest::testOverlapDEC4()
 
   CommInterface interface;
   OverlapDEC dec(procs);
+  dec.setWorkSharingAlgo(workSharingAlgo);
   ProcessorGroup * grp = dec.getGroup();
   MEDCouplingUMesh* meshS=0, *meshT=0;
   ParaMESH* parameshS=0, *parameshT=0;
@@ -643,7 +652,7 @@ void ParaMEDMEMTest::testOverlapDEC4()
   // 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)
+//  if (rank == 0)
 //    {
 //      int i=1, j=0;
 //      while (i!=0)
@@ -663,13 +672,13 @@ void ParaMEDMEMTest::testOverlapDEC4()
       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);
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0,resField->getArray()->getIJ(i,0),1e-12);
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(10.0,resField->getArray()->getIJ(i,1),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);
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0,resField->getArray()->getIJ(i,0),1e-12);
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(40.0,resField->getArray()->getIJ(i,1),1e-12);
         }
     }
   if(rank==1)
@@ -677,19 +686,19 @@ void ParaMEDMEMTest::testOverlapDEC4()
       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);
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(2.0,resField->getArray()->getIJ(i,0),1e-12);
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(20.0,resField->getArray()->getIJ(i,1),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);
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(defVal,resField->getArray()->getIJ(i,0),1e-12);
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(defVal,resField->getArray()->getIJ(i,1),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);
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(5.0,resField->getArray()->getIJ(i,0),1e-12);
+          CPPUNIT_ASSERT_DOUBLES_EQUAL(50.0,resField->getArray()->getIJ(i,1),1e-12);
         }
     }
   delete parafieldS;
@@ -702,3 +711,19 @@ void ParaMEDMEMTest::testOverlapDEC4()
   MPI_Barrier(MPI_COMM_WORLD);
 }
 
+void ParaMEDMEMTest::testOverlapDEC4()
+{
+  testOverlapDEC_default_multi(0);
+}
+
+void ParaMEDMEMTest::testOverlapDEC4_bis()
+{
+  testOverlapDEC_default_multi(1);
+}
+
+void ParaMEDMEMTest::testOverlapDEC4_ter()
+{
+  testOverlapDEC_default_multi(2);
+}
+
+