47 #ifndef PACKAGES_XPETRA_SUP_BLOCKEDMAP_XPETRA_BLOCKEDMAP_DEF_HPP_
48 #define PACKAGES_XPETRA_SUP_BLOCKEDMAP_XPETRA_BLOCKEDMAP_DEF_HPP_
54 #include "Xpetra_MapFactory.hpp"
58 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
64 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
66 BlockedMap(
const RCP<const Map>& fullmap,
const std::vector<RCP<const Map>>& maps,
bool bThyraMode) {
67 bThyraMode_ = bThyraMode;
69 if (bThyraMode ==
false) {
74 size_t numAllElements = 0;
75 for (
size_t v = 0; v < maps.size(); ++v) {
76 numAllElements += maps[v]->getGlobalNumElements();
78 TEUCHOS_TEST_FOR_EXCEPTION(fullmap->getGlobalNumElements() != numAllElements,
80 "logic error. full map and sub maps have not same number of elements ("
81 << fullmap->getGlobalNumElements() <<
" versus " << numAllElements
82 <<
"). We cannot build MapExtractor with Xpetra-style numbering. Please make sure that you want "
83 "Xpetra-style numbering instead of Thyra-style numbering.");
93 for (
size_t v = 0; v < maps.size(); ++v) {
94 TEUCHOS_TEST_FOR_EXCEPTION(maps[v]->getMinAllGlobalIndex() != 0,
96 "logic error. When using Thyra-style numbering all sub-block maps must start with zero as GID. Map block "
97 << v <<
" starts with GID " << maps[v]->getMinAllGlobalIndex());
104 std::vector<GlobalOrdinal> gidOffsets(maps.size(), 0);
105 for (
size_t v = 1; v < maps.size(); ++v) {
106 gidOffsets[v] = maps[v - 1]->getMaxAllGlobalIndex() + gidOffsets[v - 1] + 1;
110 maps_.resize(maps.size());
111 std::vector<GlobalOrdinal> fullMapGids;
112 const GO INVALID = Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid();
113 for (
size_t v = 0; v < maps.size(); ++v) {
114 size_t myNumElements = maps[v]->getLocalNumElements();
115 std::vector<GlobalOrdinal> subMapGids(myNumElements, 0);
116 for (LocalOrdinal l = 0; l < Teuchos::as<LocalOrdinal>(myNumElements); ++l) {
117 GlobalOrdinal myGid = maps[v]->getGlobalElement(l);
118 subMapGids[l] = myGid + gidOffsets[v];
119 fullMapGids.push_back(myGid + gidOffsets[v]);
124 Teuchos::ArrayView<GlobalOrdinal> subMapGidsView(&subMapGids[0], subMapGids.size());
127 maps[v]->lib(), INVALID, subMapGidsView, maps[v]->getIndexBase(), maps[v]->getComm());
138 Teuchos::ArrayView<GlobalOrdinal> fullMapGidsView(&fullMapGids[0], fullMapGids.size());
141 fullmap->lib(), INVALID, fullMapGidsView, fullmap->getIndexBase(), fullmap->getComm());
144 size_t numAllElements = 0;
145 for (
size_t v = 0; v < maps_.size(); ++v) {
146 numAllElements += maps_[v]->getGlobalNumElements();
148 TEUCHOS_TEST_FOR_EXCEPTION(
149 fullmap_->getGlobalNumElements() != numAllElements,
151 "logic error. full map and sub maps have not same number of elements. This cannot be. Please report the bug to the Xpetra developers!");
155 importers_.resize(maps_.size());
156 for (
unsigned i = 0; i < maps_.size(); ++i) {
157 if (maps[i] != null) {
161 TEUCHOS_TEST_FOR_EXCEPTION(
162 CheckConsistency() ==
false, std::logic_error,
"logic error. full map and sub maps are inconsistently distributed over the processors.");
165 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
167 BlockedMap(
const std::vector<RCP<const Map>>& maps,
const std::vector<RCP<const Map>>& thyramaps) {
171 TEUCHOS_TEST_FOR_EXCEPTION(thyramaps.size() != maps.size(), std::logic_error,
"logic error. The number of submaps must be identical!");
172 for (
size_t v = 0; v < thyramaps.size(); ++v) {
173 TEUCHOS_TEST_FOR_EXCEPTION(thyramaps[v]->getMinAllGlobalIndex() != 0,
175 "logic error. When using Thyra-style numbering all sub-block maps must start with zero as GID.");
179 "logic error. The size of the submaps must be identical (same distribution, just different GIDs)");
183 thyraMaps_ = thyramaps;
185 fullmap_ = this->concatenateMaps(maps);
188 size_t numAllElements = 0;
189 for (
size_t v = 0; v < maps_.size(); ++v) {
190 numAllElements += maps_[v]->getGlobalNumElements();
192 TEUCHOS_TEST_FOR_EXCEPTION(
193 fullmap_->getGlobalNumElements() != numAllElements,
195 "logic error. full map and sub maps have not same number of elements. This cannot be. Please report the bug to the Xpetra developers!");
198 importers_.resize(maps_.size());
199 for (
unsigned i = 0; i < maps_.size(); ++i) {
200 if (maps[i] != null) {
204 TEUCHOS_TEST_FOR_EXCEPTION(
205 CheckConsistency() ==
false, std::logic_error,
"logic error. full map and sub maps are inconsistently distributed over the processors.");
208 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
212 fullmap_ = Teuchos::null;
213 maps_.resize(input.
getNumMaps(), Teuchos::null);
214 thyraMaps_.resize(input.
getNumMaps(), Teuchos::null);
218 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
222 for (
size_t v = 0; v < maps_.size(); ++v) {
223 maps_[v] = Teuchos::null;
224 if (bThyraMode_ ==
true)
225 thyraMaps_[v] = Teuchos::null;
226 importers_[v] = Teuchos::null;
229 fullmap_ = Teuchos::null;
232 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
236 return fullmap_->getGlobalNumElements();
239 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
242 return fullmap_->getLocalNumElements();
245 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
249 return fullmap_->getIndexBase();
252 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
256 return fullmap_->getMinLocalIndex();
259 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
263 return fullmap_->getMaxLocalIndex();
266 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
270 return fullmap_->getMinGlobalIndex();
273 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
277 return fullmap_->getMaxGlobalIndex();
280 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
284 return fullmap_->getMinAllGlobalIndex();
287 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
291 return fullmap_->getMaxAllGlobalIndex();
294 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
298 return fullmap_->getLocalElement(globalIndex);
301 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
305 return fullmap_->getGlobalElement(localIndex);
308 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
312 const Teuchos::ArrayView<int>& ,
313 const Teuchos::ArrayView<LocalOrdinal>& )
const {
318 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
322 const Teuchos::ArrayView<int>& )
const {
327 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
328 Teuchos::ArrayView<const GlobalOrdinal>
331 return fullmap_->getLocalElementList();
334 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
338 return fullmap_->getMyGlobalIndicesDevice();
341 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
344 return fullmap_->isNodeLocalElement(localIndex);
347 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
350 return fullmap_->isNodeGlobalElement(globalIndex);
353 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
357 TEUCHOS_UNREACHABLE_RETURN(
false);
360 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
363 return fullmap_->isDistributed();
366 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
369 RCP<const Map> rcpMap = Teuchos::rcpFromRef(map);
370 RCP<const BlockedMap> rcpBMap = Teuchos::rcp_dynamic_cast<
const BlockedMap>(rcpMap);
371 if (rcpBMap.is_null() ==
true)
374 for (
size_t v = 0; v < maps_.size(); ++v) {
375 bool bSame = getMap(v,
false)->
isCompatible(*(rcpBMap->getMap(v,
false)));
379 bSame = getMap(v,
true)->isCompatible(*(rcpBMap->getMap(v,
true)));
385 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
388 RCP<const Map> rcpMap = Teuchos::rcpFromRef(map);
389 RCP<const BlockedMap> rcpBMap = Teuchos::rcp_dynamic_cast<
const BlockedMap>(rcpMap);
390 if (rcpBMap.is_null() ==
true) {
392 if (this->getNumMaps() > 1) {
397 bool bSame = getMap(0, bThyraMode_)->
isSameAs(*rcpMap);
401 for (
size_t v = 0; v < maps_.size(); ++v) {
402 bool bSame = getMap(v,
false)->isSameAs(*(rcpBMap->getMap(v,
false)));
403 if (bSame ==
false) {
407 bSame = getMap(v,
true)->isSameAs(*(rcpBMap->getMap(v,
true)));
408 if (bSame ==
false) {
416 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
417 Teuchos::RCP<const Teuchos::Comm<int>>
420 return fullmap_->getComm();
423 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
431 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
436 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
437 RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
443 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
444 RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
450 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
453 return fullmap_->lib();
456 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
457 RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
463 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
470 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
471 const RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
474 bool bThyraMode)
const {
477 "BlockedMap::getMap: tried to access block " << i <<
", but BlockedMap has only " << getNumMaps()
478 <<
" blocks! Block indices must be between 0 and " << getNumMaps() - 1
480 if (bThyraMode_ ==
true && bThyraMode ==
true) {
481 return thyraMaps_[i];
486 "BlockedMap::getMap: cannot return sub map in Thyra-style numbering if BlockedMap object is not created using "
487 "Thyra-style numbered submaps.");
491 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
492 const RCP<Xpetra::Import<LocalOrdinal, GlobalOrdinal, Node>>
497 "BlockedMap::getImporter: tried to access block " << i <<
", but BlockedMap has only " << getNumMaps()
498 <<
" blocks! Block indices must be between 0 and " << getNumMaps() - 1
500 return importers_[i];
503 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
504 const RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
510 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
514 for (
size_t i = 0; i < getNumMaps(); i++)
515 if (getMap(i)->isNodeGlobalElement(gid) ==
true)
518 TEUCHOS_TEST_FOR_EXCEPTION(
523 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
527 return std::string(
"BlockedMap");
530 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
532 describe(Teuchos::FancyOStream& out,
const Teuchos::EVerbosityLevel verbLevel)
const {
533 out <<
"------------- Blocked Map -----------" << std::endl;
534 out << description() << std::endl;
535 out <<
"Thyra mode: " << getThyraMode() << std::endl;
536 out <<
"No of submaps: " << getNumMaps() << std::endl;
537 Teuchos::OSTab tab(out);
538 for (
size_t r = 0; r < getNumMaps(); r++) {
539 std::cout <<
"MAP " << r <<
"/" << getNumMaps() - 1 << std::endl;
540 getMap(r,
false)->describe(out, verbLevel);
542 if (getThyraMode() ==
true) {
543 for (
size_t r = 0; r < getNumMaps(); r++) {
544 std::cout <<
"Thyra MAP " << r <<
"/" << getNumMaps() - 1 << std::endl;
545 getMap(r,
true)->describe(out, verbLevel);
548 out <<
"-------------------------------------" << std::endl;
551 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
559 maps_.resize(input.
getNumMaps(), Teuchos::null);
560 if (bThyraMode_ ==
true)
561 thyraMaps_.resize(input.
getNumMaps(), Teuchos::null);
562 for (
size_t i = 0; i < input.
getNumMaps(); ++i) {
564 if (bThyraMode_ ==
true)
569 size_t numAllElements = 0;
570 for (
size_t v = 0; v < maps_.size(); ++v) {
571 numAllElements += maps_[v]->getGlobalNumElements();
573 TEUCHOS_TEST_FOR_EXCEPTION(
574 fullmap_->getGlobalNumElements() != numAllElements,
576 "logic error. full map and sub maps have not same number of elements. This cannot be. Please report the bug to the Xpetra developers!");
579 importers_.resize(maps_.size());
580 for (
unsigned i = 0; i < maps_.size(); ++i)
581 if (maps_[i] != null)
583 TEUCHOS_TEST_FOR_EXCEPTION(
584 CheckConsistency() ==
false, std::logic_error,
"logic error. full map and sub maps are inconsistently distributed over the processors.");
587 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
588 Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
592 std::vector<GlobalOrdinal> gids;
593 for (
size_t tt = 0; tt < subMaps.size(); ++tt) {
594 Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> subMap = subMaps[tt];
596 #if 1 // WCMCLEN : IS THIS NECESSARY TO HANG ONTO?
597 Teuchos::ArrayView<const GlobalOrdinal> subMapGids = subMap->getLocalElementList();
598 gids.insert(gids.end(), subMapGids.begin(), subMapGids.end());
600 size_t myNumElements = subMap->getLocalNumElements();
601 for (LocalOrdinal l = 0; l < Teuchos::as<LocalOrdinal>(myNumElements); ++l) {
602 GlobalOrdinal gid = subMap->getGlobalElement(l);
608 const GlobalOrdinal INVALID = Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid();
611 Teuchos::ArrayView<GlobalOrdinal> gidsView(&gids[0], gids.size());
614 Build(subMaps[0]->lib(), INVALID, gidsView, subMaps[0]->getIndexBase(), subMaps[0]->getComm());
619 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
622 const RCP<const Map> fullMap = getFullMap();
624 for (
size_t i = 0; i < getNumMaps(); i++) {
625 const RCP<const Map> map = getMap(i);
627 ArrayView<const GlobalOrdinal> mapGids = map->getLocalElementList();
628 for (
typename ArrayView<const GlobalOrdinal>::const_iterator it = mapGids.begin(); it != mapGids.end(); it++) {
629 if (fullMap->isNodeGlobalElement(*it) ==
false) {
virtual GlobalOrdinal getIndexBase() const
The index base for this Map.
virtual std::string description() const
A simple one-line description of this object.
bool CheckConsistency() const
virtual RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const
virtual Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Get this Map's Comm object.
virtual ~BlockedMap()
Destructor.
Exception throws to report errors in the internal logical of the program.
virtual bool isCompatible(const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &map) const
True if and only if map is compatible with this Map.
const RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getFullMap() const
the full map
virtual RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > removeEmptyProcesses() const
Return a new Map with processes with zero elements removed.
virtual global_size_t getGlobalNumElements() const
The number of elements in this Map.
virtual GlobalOrdinal getMinGlobalIndex() const
The minimum global index owned by the calling process.
virtual bool isNodeGlobalElement(GlobalOrdinal globalIndex) const
Whether the given global index is valid for this Map on this process.
const RCP< Xpetra::Import< LocalOrdinal, GlobalOrdinal, Node > > getImporter(size_t i) const
get the importer between full map and partial map
virtual RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > replaceCommWithSubset(const Teuchos::RCP< const Teuchos::Comm< int >> &) const
Replace this Map's communicator with a subset communicator.
virtual void assign(const BlockedMap &input)
Implementation of the assignment operator (operator=); does a deep copy.
static Teuchos::RCP< Map< LocalOrdinal, GlobalOrdinal, Node > > Build(UnderlyingLib lib, global_size_t numGlobalElements, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int >> &comm, LocalGlobal lg=Xpetra::GloballyDistributed)
Map constructor with Xpetra-defined contiguous uniform distribution.
virtual global_indices_array_device_type getMyGlobalIndicesDevice() const
Return a view of the global indices owned by this process.
virtual LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &, const Teuchos::ArrayView< int > &, const Teuchos::ArrayView< LocalOrdinal > &) const
Return the process ranks and corresponding local indices for the given global indices.
virtual bool isSameAs(const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &map) const
True if and only if map is identical to this Map.
virtual LocalOrdinal getMinLocalIndex() const
The minimum local index.
size_t getNumMaps() const
number of partial maps
virtual GlobalOrdinal getMinAllGlobalIndex() const
The minimum global index over all processes in the communicator.
virtual LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
virtual bool isNodeLocalElement(LocalOrdinal localIndex) const
Whether the given local index is valid for this Map on this process.
BlockedMap< LocalOrdinal, GlobalOrdinal, Node > & operator=(const BlockedMap &rhs)
Assignment operator: Does a deep copy.
size_t global_size_t
Global size_t object.
Kokkos::View< const global_ordinal_type *, typename Node::device_type > global_indices_array_device_type
static Teuchos::RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > concatenateMaps(const std::vector< Teuchos::RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node >>> &subMaps)
Helper function to concatenate several maps.
virtual UnderlyingLib lib() const
Get the library used by this object (Tpetra or Epetra?)
virtual GlobalOrdinal getMaxGlobalIndex() const
The maximum global index owned by the calling process.
virtual GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const
The global index corresponding to the given local index.
#define XPETRA_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
virtual LocalOrdinal getMaxLocalIndex() const
The maximum local index on the calling process.
virtual bool isDistributed() const
Whether this Map is globally distributed or locally replicated.
virtual bool isContiguous() const
True if this Map is distributed contiguously, else false.
virtual size_t getLocalNumElements() const
The number of elements belonging to the calling process.
virtual GlobalOrdinal getMaxAllGlobalIndex() const
The maximum global index over all processes in the communicator.
size_t getMapIndexForGID(GlobalOrdinal gid) const
returns map index in map extractor which contains GID
virtual bool getThyraMode() const
Local number of rows on the calling process.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with the given verbosity level to a FancyOStream.
static RCP< Import< LocalOrdinal, GlobalOrdinal, Node > > Build(const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &source, const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &target, const Teuchos::RCP< Teuchos::ParameterList > &plist=Teuchos::null)
Constructor specifying the number of non-zeros for all rows.
virtual Teuchos::ArrayView< const GlobalOrdinal > getLocalElementList() const
Return a view of the global indices owned by this process.