Salome HOME
MED33 porting
[tools/medcoupling.git] / src / ParaMEDMEM / BlockTopology.cxx
index e769260cd4a9a1833438f608c4c1abbe23c43ba3..dbb8226a501f637b9b3501bf524f395bbfbb5ac3 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "BlockTopology.hxx"
-#include "MemArray.hxx"
-#include "MEDCouplingSMesh.hxx"
+#include "MEDCouplingMemArray.hxx"
+#include "MEDCouplingCMesh.hxx"
 #include "CommInterface.hxx"
 #include "ProcessorGroup.hxx"
 #include "MPIProcessorGroup.hxx"
 
 using namespace std;
 
-namespace ParaMEDMEM
+namespace MEDCoupling
 {
-
-  //!converts a pair <subdomainid,local> to a global number 
-  std::pair<int,int> BlockTopology::globalToLocal(const int global) const
-  {
-    int subdomain_id=0;
-    int position=global;
-    int size=_nb_elems;
-    int size_procs=_proc_group->size();
-    int increment=size;
-    vector<int>axis_position(_dimension);
-    vector<int>axis_offset(_dimension);
-    for (int idim=0; idim<_dimension; idim++)
-      {
-        int axis_size=_local_array_indices[idim].size()-1;
-        int axis_nb_elem=_local_array_indices[idim][axis_size];
-        increment=increment/axis_nb_elem;
-        int proc_increment = size_procs/(axis_size);
-        int axis_pos=position/increment;
-        position=position%increment;  
-        int iaxis=1;
-        while (_local_array_indices[idim][iaxis]<=axis_pos)
-          {
-            subdomain_id+=proc_increment;
-            iaxis++;
-          }
-        axis_position[idim]=axis_pos-_local_array_indices[idim][iaxis-1];
-        axis_offset[idim]=iaxis;
-      }
-    int local=0;
-    int local_increment=1;
-    for (int idim=_dimension-1; idim>=0; idim--)
-      {
-        local+=axis_position[idim]*local_increment;
-        local_increment*=_local_array_indices[idim][axis_offset[idim]]-_local_array_indices[idim][axis_offset[idim]-1];
-      }
-    return make_pair(subdomain_id,local);
-  }
-
-  //!converts local number to a global number
-  int BlockTopology::localToGlobal(const pair<int,int> local) const
-  {
-  
-    int subdomain_id=local.first;
-    int global=0;
-    int loc=local.second;
-    int increment=_nb_elems;
-    int proc_increment=_proc_group->size();
-    int local_increment=getNbLocalElements();
-    for (int idim=0; idim < _dimension; idim++)
-      {
-        int axis_size=_local_array_indices[idim].size()-1;
-        int axis_nb_elem=_local_array_indices[idim][axis_size];
-        increment=increment/axis_nb_elem;
-        proc_increment = proc_increment/(axis_size);
-        int proc_axis=subdomain_id/proc_increment;
-        subdomain_id=subdomain_id%proc_increment;
-        int local_axis_nb_elem=_local_array_indices[idim][proc_axis+1]-_local_array_indices[idim][proc_axis];
-        local_increment = local_increment/local_axis_nb_elem;  
-        int iaxis=loc/local_increment+_local_array_indices[idim][proc_axis];
-        global+=increment*iaxis;
-        loc = loc%local_increment;
-      }
-    return global;
-  }
-
-  //Retrieves the local number of elements 
-  int BlockTopology::getNbLocalElements()const 
-  {
-    int position=_proc_group->myRank();
-    int nb_elem = 1;
-    int increment=1;
-    for (int i=_dimension-1; i>=0; i--)
-      {  
-        increment *=_nb_procs_per_dim[i];
-        int idim=position%increment;
-        position=position/increment;
-        int imin=_local_array_indices[i][idim];
-        int imax=_local_array_indices[i][idim+1];
-        nb_elem*=(imax-imin);
-      }
-    return nb_elem;
-  }
+  /*!
+   * Default ctor.
+   */
+  BlockTopology::BlockTopology() :
+    _dimension(0), _nb_procs_per_dim(0),
+    _local_array_indices(0), _cycle_type(0),
+    _proc_group(NULL),_nb_elems(0),
+    _owns_processor_group(false)
+  {}
 
   /*!
    * Constructor of a block topology from a grid. 
@@ -123,8 +51,8 @@ namespace ParaMEDMEM
    * instead of making the best choice with respect to the 
    * values of the different axes. 
    */
-  BlockTopology::BlockTopology(const ProcessorGroup& group, MEDCouplingSMesh *grid):
-    _proc_group(&group), _dimension(grid->getSpaceDimension()), _owns_processor_group(false)
+  BlockTopology::BlockTopology(const ProcessorGroup& group, MEDCouplingCMesh *grid):
+    _dimension(grid->getSpaceDimension()), _proc_group(&group), _owns_processor_group(false)
   {
     vector <int> axis_length(_dimension);
     _nb_elems=1;
@@ -158,7 +86,7 @@ namespace ParaMEDMEM
       }
     _cycle_type.resize(_dimension);
     for (int i=0; i<_dimension; i++)
-      _cycle_type[i]=ParaMEDMEM::Block;  
+      _cycle_type[i]=MEDCoupling::Block;  
   }
 
   /*!
@@ -209,14 +137,14 @@ namespace ParaMEDMEM
    * to \a group will cause an MPI error, while calling from a subset
    * of \a group will result in a deadlock. 
    */
-  BlockTopology::BlockTopology(const ProcessorGroup& group, int nb_elem):_proc_group(&group),_dimension(1),_owns_processor_group(false)
+  BlockTopology::BlockTopology(const ProcessorGroup& group, int nb_elem):_dimension(1),_proc_group(&group),_owns_processor_group(false)
   {
     int* nbelems_per_proc = new int[group.size()];
     const MPIProcessorGroup* mpi_group=dynamic_cast<const MPIProcessorGroup*>(_proc_group);
     const MPI_Comm* comm=mpi_group->getComm();
     int nbtemp=nb_elem;
-    mpi_group->getCommInterface().allGather(&nbtemp, 1, MPI_INTEGER
-                                            nbelems_per_proc, 1, MPI_INTEGER
+    mpi_group->getCommInterface().allGather(&nbtemp, 1, MPI_INT, 
+                                            nbelems_per_proc, 1, MPI_INT, 
                                             *comm);
     _nb_elems=0;  
   
@@ -235,7 +163,7 @@ namespace ParaMEDMEM
         _nb_elems+=nbelems_per_proc[i-1];
       }
     _cycle_type.resize(1);
-    _cycle_type[0]=ParaMEDMEM::Block;
+    _cycle_type[0]=MEDCoupling::Block;
     delete[] nbelems_per_proc;
   }
 
@@ -245,6 +173,88 @@ namespace ParaMEDMEM
       delete _proc_group;
   }
 
+  //!converts a pair <subdomainid,local> to a global number
+  std::pair<int,int> BlockTopology::globalToLocal(const int global) const
+  {
+    int subdomain_id=0;
+    int position=global;
+    int size=_nb_elems;
+    int size_procs=_proc_group->size();
+    int increment=size;
+    vector<int>axis_position(_dimension);
+    vector<int>axis_offset(_dimension);
+    for (int idim=0; idim<_dimension; idim++)
+      {
+        int axis_size=_local_array_indices[idim].size()-1;
+        int axis_nb_elem=_local_array_indices[idim][axis_size];
+        increment=increment/axis_nb_elem;
+        int proc_increment = size_procs/(axis_size);
+        int axis_pos=position/increment;
+        position=position%increment;
+        int iaxis=1;
+        while (_local_array_indices[idim][iaxis]<=axis_pos)
+          {
+            subdomain_id+=proc_increment;
+            iaxis++;
+          }
+        axis_position[idim]=axis_pos-_local_array_indices[idim][iaxis-1];
+        axis_offset[idim]=iaxis;
+      }
+    int local=0;
+    int local_increment=1;
+    for (int idim=_dimension-1; idim>=0; idim--)
+      {
+        local+=axis_position[idim]*local_increment;
+        local_increment*=_local_array_indices[idim][axis_offset[idim]]-_local_array_indices[idim][axis_offset[idim]-1];
+      }
+    return make_pair(subdomain_id,local);
+  }
+
+  //!converts local number to a global number
+  int BlockTopology::localToGlobal(const pair<int,int> local) const
+  {
+
+    int subdomain_id=local.first;
+    int global=0;
+    int loc=local.second;
+    int increment=_nb_elems;
+    int proc_increment=_proc_group->size();
+    int local_increment=getNbLocalElements();
+    for (int idim=0; idim < _dimension; idim++)
+      {
+        int axis_size=_local_array_indices[idim].size()-1;
+        int axis_nb_elem=_local_array_indices[idim][axis_size];
+        increment=axis_nb_elem==0?0:increment/axis_nb_elem;
+        proc_increment = proc_increment/(axis_size);
+        int proc_axis=subdomain_id/proc_increment;
+        subdomain_id=subdomain_id%proc_increment;
+        int local_axis_nb_elem=_local_array_indices[idim][proc_axis+1]-_local_array_indices[idim][proc_axis];
+        local_increment = (local_axis_nb_elem==0)?0:(local_increment/local_axis_nb_elem);
+        int iaxis=((local_increment==0)?0:(loc/local_increment))+_local_array_indices[idim][proc_axis];
+        global+=increment*iaxis;
+        loc = (local_increment==0)?0:(loc%local_increment);
+      }
+    return global;
+  }
+
+  //Retrieves the local number of elements
+  int BlockTopology::getNbLocalElements()const
+  {
+    int position=_proc_group->myRank();
+    int nb_elem = 1;
+    int increment=1;
+    for (int i=_dimension-1; i>=0; i--)
+      {
+        increment *=_nb_procs_per_dim[i];
+        int idim=position%increment;
+        position=position/increment;
+        int imin=_local_array_indices[i][idim];
+        int imax=_local_array_indices[i][idim+1];
+        nb_elem*=(imax-imin);
+      }
+    return nb_elem;
+  }
+
   /*! Retrieves the min and max indices of the domain stored locally
    * for each dimension. The output vector has the topology dimension
    * as a size and each pair <int,int> contains min and max. Indices 
@@ -279,7 +289,7 @@ namespace ParaMEDMEM
         buffer.push_back(_nb_procs_per_dim[i]);
         buffer.push_back(_cycle_type[i]);
         buffer.push_back(_local_array_indices[i].size());
-        for (int j=0; j<_local_array_indices[i].size(); j++)
+        for (int j=0; j<(int)_local_array_indices[i].size(); j++)
           buffer.push_back(_local_array_indices[i][j]);
       }
   
@@ -320,7 +330,7 @@ namespace ParaMEDMEM
         _nb_procs_per_dim[i]=*(ptr_serializer++);
         _cycle_type[i]=(CYCLE_TYPE)*(ptr_serializer++);
         _local_array_indices[i].resize(*(ptr_serializer++));
-        for (int j=0; j<_local_array_indices[i].size(); j++)
+        for (int j=0; j<(int)_local_array_indices[i].size(); j++)
           _local_array_indices[i][j]=*(ptr_serializer++);
       }
     set<int> procs;