Xpetra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Xpetra_BlockedMap_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Xpetra: A linear algebra interface package
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact
39 // Jonathan Hu (jhu@sandia.gov)
40 // Andrey Prokopenko (aprokop@sandia.gov)
41 // Tobias Wiesner (tawiesn@sandia.gov)
42 // Ray Tuminaro (rstumin@sandia.gov)
43 //
44 // ***********************************************************************
45 //
46 // @HEADER
47 #ifndef PACKAGES_XPETRA_SUP_BLOCKEDMAP_XPETRA_BLOCKEDMAP_DEF_HPP_
48 #define PACKAGES_XPETRA_SUP_BLOCKEDMAP_XPETRA_BLOCKEDMAP_DEF_HPP_
49 
51 
52 #include "Xpetra_Exceptions.hpp"
53 #include "Xpetra_ImportFactory.hpp"
54 #include "Xpetra_MapFactory.hpp"
55 
56 namespace Xpetra {
57 
58 template <class LocalOrdinal, class GlobalOrdinal, class Node>
61  bThyraMode_ = false;
62 }
63 
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;
68 
69  if (bThyraMode == false) {
70  // use Xpetra-style numbering for sub-block maps
71  // That is, all sub-block maps have unique GIDs which may not be contiguous and start with GIDs different than zero.
72 
73  // plausibility check
74  size_t numAllElements = 0;
75  for (size_t v = 0; v < maps.size(); ++v) {
76  numAllElements += maps[v]->getGlobalNumElements();
77  }
78  TEUCHOS_TEST_FOR_EXCEPTION(fullmap->getGlobalNumElements() != numAllElements,
79  std::logic_error,
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.");
84 
85  fullmap_ = fullmap;
86  maps_ = maps;
87  } else {
88  // std::cout << "Create Map Extractor in Thyra Mode!!! " << std::endl;
89  // use Thyra-style numbering for sub-block maps
90  // That is, all sub-block maps start with zero as GID and are contiguous
91 
92  // plausibility check
93  for (size_t v = 0; v < maps.size(); ++v) {
94  TEUCHOS_TEST_FOR_EXCEPTION(maps[v]->getMinAllGlobalIndex() != 0,
95  std::logic_error,
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());
98  }
99 
100  // store submaps in Thyra-style ordering
101  thyraMaps_ = maps;
102 
103  // get offsets
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;
107  }
108 
109  // build submaps
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]);
120  }
121  // std::sort(subMapGids.begin(), subMapGids.end());
122  // subMapGids.erase(std::unique(subMapGids.begin(), subMapGids.end()), subMapGids.end());
123 
124  Teuchos::ArrayView<GlobalOrdinal> subMapGidsView(&subMapGids[0], subMapGids.size());
125 
127  maps[v]->lib(), INVALID, subMapGidsView, maps[v]->getIndexBase(), maps[v]->getComm());
128  maps_[v] = mySubMap;
129  }
130 
131  // const GO INVALID = Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid();
132  // std::sort(coarseMapGids.begin(), coarseMapGids.end());
133  // coarseMapGids.erase(std::unique(coarseMapGids.begin(), coarseMapGids.end()), coarseMapGids.end());
134  // Teuchos::ArrayView<GO> coarseMapGidsView(&coarseMapGids[0], coarseMapGids.size());
135  // std::sort(fullMapGids.begin(), fullMapGids.end());
136  // fullMapGids.erase(std::unique(fullMapGids.begin(), fullMapGids.end()), fullMapGids.end());
137 
138  Teuchos::ArrayView<GlobalOrdinal> fullMapGidsView(&fullMapGids[0], fullMapGids.size());
139 
141  fullmap->lib(), INVALID, fullMapGidsView, fullmap->getIndexBase(), fullmap->getComm());
142 
143  // plausibility check
144  size_t numAllElements = 0;
145  for (size_t v = 0; v < maps_.size(); ++v) {
146  numAllElements += maps_[v]->getGlobalNumElements();
147  }
148  TEUCHOS_TEST_FOR_EXCEPTION(
149  fullmap_->getGlobalNumElements() != numAllElements,
150  std::logic_error,
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!");
152  }
153 
154  // build importers for sub maps
155  importers_.resize(maps_.size());
156  for (unsigned i = 0; i < maps_.size(); ++i) {
157  if (maps[i] != null) {
158  importers_[i] = Xpetra::ImportFactory<LocalOrdinal, GlobalOrdinal, Node>::Build(fullmap_, maps_[i]);
159  }
160  }
161  TEUCHOS_TEST_FOR_EXCEPTION(
162  CheckConsistency() == false, std::logic_error, "logic error. full map and sub maps are inconsistently distributed over the processors.");
163 }
164 
165 template <class LocalOrdinal, class GlobalOrdinal, class Node>
167  BlockedMap(const std::vector<RCP<const Map>>& maps, const std::vector<RCP<const Map>>& thyramaps) {
168  bThyraMode_ = true;
169 
170  // plausibility check
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,
174  std::logic_error,
175  "logic error. When using Thyra-style numbering all sub-block maps must start with zero as GID.");
176 
177  XPETRA_TEST_FOR_EXCEPTION(thyramaps[v]->getLocalNumElements() != maps[v]->getLocalNumElements(),
178  std::logic_error,
179  "logic error. The size of the submaps must be identical (same distribution, just different GIDs)");
180  }
181 
182  // store user-provided maps and thyramaps
183  thyraMaps_ = thyramaps;
184  maps_ = maps;
185  fullmap_ = this->concatenateMaps(maps);
186 
187  // plausibility check
188  size_t numAllElements = 0;
189  for (size_t v = 0; v < maps_.size(); ++v) {
190  numAllElements += maps_[v]->getGlobalNumElements();
191  }
192  TEUCHOS_TEST_FOR_EXCEPTION(
193  fullmap_->getGlobalNumElements() != numAllElements,
194  std::logic_error,
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!");
196 
197  // build importers for sub maps
198  importers_.resize(maps_.size());
199  for (unsigned i = 0; i < maps_.size(); ++i) {
200  if (maps[i] != null) {
201  importers_[i] = Xpetra::ImportFactory<LocalOrdinal, GlobalOrdinal, Node>::Build(fullmap_, maps_[i]);
202  }
203  }
204  TEUCHOS_TEST_FOR_EXCEPTION(
205  CheckConsistency() == false, std::logic_error, "logic error. full map and sub maps are inconsistently distributed over the processors.");
206 }
207 
208 template <class LocalOrdinal, class GlobalOrdinal, class Node>
210  BlockedMap(const BlockedMap& input) {
211  bThyraMode_ = input.getThyraMode();
212  fullmap_ = Teuchos::null;
213  maps_.resize(input.getNumMaps(), Teuchos::null);
214  thyraMaps_.resize(input.getNumMaps(), Teuchos::null);
215  this->assign(input);
216 }
217 
218 template <class LocalOrdinal, class GlobalOrdinal, class Node>
221  // make sure all RCP's are freed
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;
227  }
228 
229  fullmap_ = Teuchos::null;
230 }
231 
232 template <class LocalOrdinal, class GlobalOrdinal, class Node>
236  return fullmap_->getGlobalNumElements();
237 }
238 
239 template <class LocalOrdinal, class GlobalOrdinal, class Node>
240 size_t
242  return fullmap_->getLocalNumElements();
243 }
244 
245 template <class LocalOrdinal, class GlobalOrdinal, class Node>
246 GlobalOrdinal
248  getIndexBase() const {
249  return fullmap_->getIndexBase();
250 }
251 
252 template <class LocalOrdinal, class GlobalOrdinal, class Node>
253 LocalOrdinal
256  return fullmap_->getMinLocalIndex();
257 }
258 
259 template <class LocalOrdinal, class GlobalOrdinal, class Node>
260 LocalOrdinal
263  return fullmap_->getMaxLocalIndex();
264 }
265 
266 template <class LocalOrdinal, class GlobalOrdinal, class Node>
267 GlobalOrdinal
270  return fullmap_->getMinGlobalIndex();
271 }
272 
273 template <class LocalOrdinal, class GlobalOrdinal, class Node>
274 GlobalOrdinal
277  return fullmap_->getMaxGlobalIndex();
278 }
279 
280 template <class LocalOrdinal, class GlobalOrdinal, class Node>
281 GlobalOrdinal
284  return fullmap_->getMinAllGlobalIndex();
285 }
286 
287 template <class LocalOrdinal, class GlobalOrdinal, class Node>
288 GlobalOrdinal
291  return fullmap_->getMaxAllGlobalIndex();
292 }
293 
294 template <class LocalOrdinal, class GlobalOrdinal, class Node>
295 LocalOrdinal
297  getLocalElement(GlobalOrdinal globalIndex) const {
298  return fullmap_->getLocalElement(globalIndex);
299 }
300 
301 template <class LocalOrdinal, class GlobalOrdinal, class Node>
302 GlobalOrdinal
304  getGlobalElement(LocalOrdinal localIndex) const {
305  return fullmap_->getGlobalElement(localIndex);
306 }
307 
308 template <class LocalOrdinal, class GlobalOrdinal, class Node>
311  getRemoteIndexList(const Teuchos::ArrayView<const GlobalOrdinal>& /* GIDList */,
312  const Teuchos::ArrayView<int>& /* nodeIDList */,
313  const Teuchos::ArrayView<LocalOrdinal>& /* LIDList */) const {
314  throw Xpetra::Exceptions::RuntimeError("BlockedMap::getRemoteIndexList: routine not implemented.");
315  TEUCHOS_UNREACHABLE_RETURN(IDNotPresent);
316 }
317 
318 template <class LocalOrdinal, class GlobalOrdinal, class Node>
321  getRemoteIndexList(const Teuchos::ArrayView<const GlobalOrdinal>& /* GIDList */,
322  const Teuchos::ArrayView<int>& /* nodeIDList */) const {
323  throw Xpetra::Exceptions::RuntimeError("BlockedMap::getRemoteIndexList: routine not implemented.");
324  TEUCHOS_UNREACHABLE_RETURN(IDNotPresent);
325 }
326 
327 template <class LocalOrdinal, class GlobalOrdinal, class Node>
328 Teuchos::ArrayView<const GlobalOrdinal>
331  return fullmap_->getLocalElementList();
332 }
333 
334 template <class LocalOrdinal, class GlobalOrdinal, class Node>
338  return fullmap_->getMyGlobalIndicesDevice();
339 }
340 
341 template <class LocalOrdinal, class GlobalOrdinal, class Node>
343  isNodeLocalElement(LocalOrdinal localIndex) const {
344  return fullmap_->isNodeLocalElement(localIndex);
345 }
346 
347 template <class LocalOrdinal, class GlobalOrdinal, class Node>
349  isNodeGlobalElement(GlobalOrdinal globalIndex) const {
350  return fullmap_->isNodeGlobalElement(globalIndex);
351 }
352 
353 template <class LocalOrdinal, class GlobalOrdinal, class Node>
355  isContiguous() const {
356  throw Xpetra::Exceptions::RuntimeError("BlockedMap::isContiguous: routine not implemented.");
357  TEUCHOS_UNREACHABLE_RETURN(false);
358 }
359 
360 template <class LocalOrdinal, class GlobalOrdinal, class Node>
362  isDistributed() const {
363  return fullmap_->isDistributed();
364 }
365 
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)
372  return false;
373 
374  for (size_t v = 0; v < maps_.size(); ++v) {
375  bool bSame = getMap(v, false)->isCompatible(*(rcpBMap->getMap(v, false)));
376  if (bSame == false)
377  return false;
378  if (bThyraMode_) {
379  bSame = getMap(v, true)->isCompatible(*(rcpBMap->getMap(v, true)));
380  }
381  }
382  return true;
383 }
384 
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) {
391  // If this is a blocked map with > 1 blocks but "map" is a plain map they can't be the same
392  if (this->getNumMaps() > 1) {
393  return false;
394  }
395 
396  // special case: this is a single blocked map and "map" is a plain map object
397  bool bSame = getMap(0, bThyraMode_)->isSameAs(*rcpMap);
398  return bSame;
399  }
400 
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) {
404  return false;
405  }
406  if (bThyraMode_) {
407  bSame = getMap(v, true)->isSameAs(*(rcpBMap->getMap(v, true)));
408  if (bSame == false) {
409  return false;
410  }
411  }
412  }
413  return true;
414 }
415 
416 template <class LocalOrdinal, class GlobalOrdinal, class Node>
417 Teuchos::RCP<const Teuchos::Comm<int>>
419  getComm() const {
420  return fullmap_->getComm();
421 }
422 
423 template <class LocalOrdinal, class GlobalOrdinal, class Node>
426 operator=(const BlockedMap& rhs) {
427  assign(rhs); // dispatch to protected virtual method
428  return *this;
429 }
430 
431 template <class LocalOrdinal, class GlobalOrdinal, class Node>
433  return bThyraMode_;
434 }
435 
436 template <class LocalOrdinal, class GlobalOrdinal, class Node>
437 RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
440  throw Xpetra::Exceptions::RuntimeError("BlockedMap::removeEmptyProcesses: routine not implemented.");
441 }
442 
443 template <class LocalOrdinal, class GlobalOrdinal, class Node>
444 RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
446  replaceCommWithSubset(const Teuchos::RCP<const Teuchos::Comm<int>>& /* newComm */) const {
447  throw Xpetra::Exceptions::RuntimeError("BlockedMap::replaceCommWithSubset: routine not implemented.");
448 }
449 
450 template <class LocalOrdinal, class GlobalOrdinal, class Node>
453  return fullmap_->lib();
454 }
455 
456 template <class LocalOrdinal, class GlobalOrdinal, class Node>
457 RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
459  getMap() const {
460  return getFullMap();
461 }
462 
463 template <class LocalOrdinal, class GlobalOrdinal, class Node>
464 size_t
466  getNumMaps() const {
467  return maps_.size();
468 }
469 
470 template <class LocalOrdinal, class GlobalOrdinal, class Node>
471 const RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
473  getMap(size_t i,
474  bool bThyraMode) const {
475  XPETRA_TEST_FOR_EXCEPTION(i >= getNumMaps(),
477  "BlockedMap::getMap: tried to access block " << i << ", but BlockedMap has only " << getNumMaps()
478  << " blocks! Block indices must be between 0 and " << getNumMaps() - 1
479  << ".");
480  if (bThyraMode_ == true && bThyraMode == true) {
481  return thyraMaps_[i];
482  }
483 
484  XPETRA_TEST_FOR_EXCEPTION(bThyraMode_ == false && bThyraMode == true,
486  "BlockedMap::getMap: cannot return sub map in Thyra-style numbering if BlockedMap object is not created using "
487  "Thyra-style numbered submaps.");
488  return maps_[i];
489 }
490 
491 template <class LocalOrdinal, class GlobalOrdinal, class Node>
492 const RCP<Xpetra::Import<LocalOrdinal, GlobalOrdinal, Node>>
494  getImporter(size_t i) const {
495  XPETRA_TEST_FOR_EXCEPTION(i >= getNumMaps(),
497  "BlockedMap::getImporter: tried to access block " << i << ", but BlockedMap has only " << getNumMaps()
498  << " blocks! Block indices must be between 0 and " << getNumMaps() - 1
499  << ".");
500  return importers_[i];
501 }
502 
503 template <class LocalOrdinal, class GlobalOrdinal, class Node>
504 const RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
506  getFullMap() const {
507  return fullmap_;
508 }
509 
510 template <class LocalOrdinal, class GlobalOrdinal, class Node>
511 size_t
513  getMapIndexForGID(GlobalOrdinal gid) const {
514  for (size_t i = 0; i < getNumMaps(); i++)
515  if (getMap(i)->isNodeGlobalElement(gid) == true)
516  return i;
517 
518  TEUCHOS_TEST_FOR_EXCEPTION(
519  false, Xpetra::Exceptions::RuntimeError, "getMapIndexForGID: GID " << gid << " is not contained by a map in mapextractor.");
520  return 0;
521 }
522 
523 template <class LocalOrdinal, class GlobalOrdinal, class Node>
524 std::string
526  description() const {
527  return std::string("BlockedMap");
528 }
529 
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);
541  }
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);
546  }
547  }
548  out << "-------------------------------------" << std::endl;
549 }
550 
551 template <class LocalOrdinal, class GlobalOrdinal, class Node>
553  assign(const BlockedMap& input) {
554  // TODO check implementation, simplify copy constructor
555  bThyraMode_ = input.getThyraMode();
556 
558 
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)
565  thyraMaps_[i] = Xpetra::MapFactory<LocalOrdinal, GlobalOrdinal, Node>::Build(input.getMap(i, true), 1);
566  }
567 
568  // plausibility check
569  size_t numAllElements = 0;
570  for (size_t v = 0; v < maps_.size(); ++v) {
571  numAllElements += maps_[v]->getGlobalNumElements();
572  }
573  TEUCHOS_TEST_FOR_EXCEPTION(
574  fullmap_->getGlobalNumElements() != numAllElements,
575  std::logic_error,
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!");
577 
578  // build importers for sub maps
579  importers_.resize(maps_.size());
580  for (unsigned i = 0; i < maps_.size(); ++i)
581  if (maps_[i] != null)
582  importers_[i] = Xpetra::ImportFactory<LocalOrdinal, GlobalOrdinal, Node>::Build(fullmap_, maps_[i]);
583  TEUCHOS_TEST_FOR_EXCEPTION(
584  CheckConsistency() == false, std::logic_error, "logic error. full map and sub maps are inconsistently distributed over the processors.");
585 }
586 
587 template <class LocalOrdinal, class GlobalOrdinal, class Node>
588 Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
590  concatenateMaps(const std::vector<Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>>& subMaps) {
591  // merge submaps to global map
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];
595 
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());
599 #else
600  size_t myNumElements = subMap->getLocalNumElements();
601  for (LocalOrdinal l = 0; l < Teuchos::as<LocalOrdinal>(myNumElements); ++l) {
602  GlobalOrdinal gid = subMap->getGlobalElement(l);
603  gids.push_back(gid);
604  }
605 #endif
606  }
607 
608  const GlobalOrdinal INVALID = Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid();
609  // std::sort(gids.begin(), gids.end());
610  // gids.erase(std::unique(gids.begin(), gids.end()), gids.end());
611  Teuchos::ArrayView<GlobalOrdinal> gidsView(&gids[0], gids.size());
612 
613  Teuchos::RCP<Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> fullMap = Xpetra::MapFactory<LocalOrdinal, GlobalOrdinal, Node>::
614  Build(subMaps[0]->lib(), INVALID, gidsView, subMaps[0]->getIndexBase(), subMaps[0]->getComm());
615 
616  return fullMap;
617 }
618 
619 template <class LocalOrdinal, class GlobalOrdinal, class Node>
622  const RCP<const Map> fullMap = getFullMap();
623 
624  for (size_t i = 0; i < getNumMaps(); i++) {
625  const RCP<const Map> map = getMap(i);
626 
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) {
630  return false; // Global ID (*it) not found locally on this proc in fullMap -> error
631  }
632  }
633  }
634  return true;
635 }
636 
637 } // namespace Xpetra
638 #endif /* PACKAGES_XPETRA_SUP_BLOCKEDMAP_XPETRA_BLOCKEDMAP_DECL_HPP_ */
virtual GlobalOrdinal getIndexBase() const
The index base for this Map.
virtual std::string description() const
A simple one-line description of this object.
virtual RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const
virtual Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Get this Map&#39;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&#39;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.