+ _proc_group = nullptr;
+ }
+
+ //!converts a pair <subdomainid,local> to a global number
+ std::pair<int,mcIdType> 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;
+ vector<mcIdType>axis_position(_dimension);
+ vector<mcIdType>axis_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<int,mcIdType> 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;