X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FParaMEDMEM%2FBlockTopology.cxx;h=4527fb1c70ae9f7ea39fdd447331d4a5d7f9a343;hb=1b5fb5650409b0ad3a61da3215496f2adf2dae02;hp=887d373190be3561359518cb54db79fa623eeb86;hpb=8763c12d01e33d6845dd53be65b001514d00bd42;p=tools%2Fmedcoupling.git diff --git a/src/ParaMEDMEM/BlockTopology.cxx b/src/ParaMEDMEM/BlockTopology.cxx index 887d37319..4527fb1c7 100644 --- a/src/ParaMEDMEM/BlockTopology.cxx +++ b/src/ParaMEDMEM/BlockTopology.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 CEA/DEN, EDF R&D +// Copyright (C) 2007-2023 CEA, EDF // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -33,90 +33,17 @@ using namespace std; -namespace ParaMEDMEM +namespace MEDCoupling { - - //!converts a pair to a global number - std::pair 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; - vectoraxis_position(_dimension); - vectoraxis_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 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; - } + /*! + * Default ctor. + */ + BlockTopology::BlockTopology() : + _dimension(0), _nb_procs_per_dim(0), + _local_array_indices(0), _cycle_type(0), + _proc_group(nullptr),_nb_elems(0), + _owns_processor_group(false) + {} /*! * Constructor of a block topology from a grid. @@ -127,7 +54,7 @@ namespace ParaMEDMEM BlockTopology::BlockTopology(const ProcessorGroup& group, MEDCouplingCMesh *grid): _dimension(grid->getSpaceDimension()), _proc_group(&group), _owns_processor_group(false) { - vector axis_length(_dimension); + vector axis_length(_dimension); _nb_elems=1; for (int idim=0; idim <_dimension; idim++) { @@ -159,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; } /*! @@ -192,7 +119,7 @@ namespace ParaMEDMEM _proc_group=geom_topo.getProcGroup(); _local_array_indices=geom_topo._local_array_indices; vector comp_indices = *(comp_topo.getBlockIndices()); - _local_array_indices.push_back(comp_indices); + _local_array_indices.emplace_back( comp_indices.begin(), comp_indices.end() ); _nb_procs_per_dim=geom_topo._nb_procs_per_dim; _nb_procs_per_dim.push_back(comp_topo.nbBlocks()); _cycle_type=geom_topo._cycle_type; @@ -210,16 +137,16 @@ 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):_dimension(1),_proc_group(&group),_owns_processor_group(false) + BlockTopology::BlockTopology(const ProcessorGroup& group, mcIdType nb_elem):_dimension(1),_proc_group(&group),_owns_processor_group(false) { - int* nbelems_per_proc = new int[group.size()]; + mcIdType* nbelems_per_proc = new mcIdType[group.size()]; const MPIProcessorGroup* mpi_group=dynamic_cast(_proc_group); const MPI_Comm* comm=mpi_group->getComm(); - int nbtemp=nb_elem; - mpi_group->getCommInterface().allGather(&nbtemp, 1, MPI_INT, - nbelems_per_proc, 1, MPI_INT, + mcIdType nbtemp=nb_elem; + mpi_group->getCommInterface().allGather(&nbtemp, 1, MPI_ID_TYPE, + nbelems_per_proc, 1, MPI_ID_TYPE, *comm); - _nb_elems=0; + _nb_elems=0; //splitting along only dimension _local_array_indices.resize(1); @@ -236,14 +163,105 @@ 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; } BlockTopology::~BlockTopology() + { + release(); + } + + /** Destructor involves MPI operations: make sure this is accessible from a proper + * method for Python wrapping. + */ + void BlockTopology::release() { if (_owns_processor_group) delete _proc_group; + _proc_group = nullptr; + } + + //!converts a pair to a global number + std::pair BlockTopology::globalToLocal(const mcIdType global) const + { + int subdomain_id=0; + mcIdType position=global; + mcIdType size=_nb_elems; + std::size_t size_procs=_proc_group->size(); + mcIdType increment=size; + vectoraxis_position(_dimension); + vectoraxis_offset(_dimension); + for (int idim=0; idim<_dimension; idim++) + { + std::size_t axis_size=_local_array_indices[idim].size()-1; + mcIdType axis_nb_elem=_local_array_indices[idim][axis_size]; + increment=increment/axis_nb_elem; + int proc_increment = (int)(size_procs/axis_size); + mcIdType 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; + } + mcIdType local=0; + mcIdType 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 + mcIdType BlockTopology::localToGlobal(const pair local) const + { + + std::size_t subdomain_id=local.first; + mcIdType global=0; + mcIdType loc=local.second; + mcIdType increment=_nb_elems; + std::size_t proc_increment=_proc_group->size(); + mcIdType local_increment=getNbLocalElements(); + for (int idim=0; idim < _dimension; idim++) + { + std::size_t axis_size=_local_array_indices[idim].size()-1; + mcIdType 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; + std::size_t proc_axis=subdomain_id/proc_increment; + subdomain_id=subdomain_id%proc_increment; + mcIdType 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); + mcIdType 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 + mcIdType BlockTopology::getNbLocalElements()const + { + int position=_proc_group->myRank(); + mcIdType 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; + mcIdType imin=_local_array_indices[i][idim]; + mcIdType 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 @@ -251,16 +269,16 @@ namespace ParaMEDMEM * as a size and each pair contains min and max. Indices * range from min to max-1. */ - std::vector > BlockTopology::getLocalArrayMinMax() const + std::vector > BlockTopology::getLocalArrayMinMax() const { - vector > local_indices (_dimension); + vector > local_indices (_dimension); int myrank=_proc_group->myRank(); int increment=1; for (int i=_dimension-1; i>=0; i--) { increment *=_nb_procs_per_dim[i]; int idim=myrank%increment; - local_indices[i].first=_local_array_indices[i][idim]; + local_indices[i].first=(int)_local_array_indices[i][idim]; local_indices[i].second=_local_array_indices[i][idim+1]; cout << local_indices[i].first << " "<< local_indices[i].second< buffer; + vector buffer; buffer.push_back(_dimension); buffer.push_back(_nb_elems); @@ -279,13 +297,13 @@ 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<(int)_local_array_indices[i].size(); j++) + buffer.push_back(ToIdType(_local_array_indices[i].size())); + for (std::size_t j=0; j<_local_array_indices[i].size(); j++) buffer.push_back(_local_array_indices[i][j]); } //serializing the comm group - int size_comm=_proc_group->size(); + mcIdType size_comm=_proc_group->size(); buffer.push_back(size_comm); MPIProcessorGroup world_group(_proc_group->getCommInterface()); for (int i=0; i procs; - int size_comm=*(ptr_serializer++); + mcIdType size_comm=*(ptr_serializer++); for (int i=0; i