-// 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.
* 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;
}
_cycle_type.resize(_dimension);
for (int i=0; i<_dimension; i++)
- _cycle_type[i]=ParaMEDMEM::Block;
+ _cycle_type[i]=MEDCoupling::Block;
}
/*!
* 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;
_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;
}
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
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]);
}
_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;