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 
57 
58 namespace Xpetra {
59 
60 
61 
62 template<class LocalOrdinal, class GlobalOrdinal, class Node>
65 {
66  bThyraMode_ = false;
67 }
68 
69 
70 template<class LocalOrdinal, class GlobalOrdinal, class Node>
72 BlockedMap(const RCP<const Map>& fullmap, const std::vector<RCP<const Map>>& maps, bool bThyraMode)
73 {
74  bThyraMode_ = bThyraMode;
75 
76  if(bThyraMode == false)
77  {
78  // use Xpetra-style numbering for sub-block maps
79  // That is, all sub-block maps have unique GIDs which may not be contiguous and start with GIDs different than zero.
80 
81  // plausibility check
82  size_t numAllElements = 0;
83  for(size_t v = 0; v < maps.size(); ++v)
84  {
85  numAllElements += maps[ v ]->getGlobalNumElements();
86  }
87  TEUCHOS_TEST_FOR_EXCEPTION(fullmap->getGlobalNumElements() != numAllElements,
88  std::logic_error,
89  "logic error. full map and sub maps have not same number of elements ("
90  << fullmap->getGlobalNumElements() << " versus " << numAllElements
91  << "). We cannot build MapExtractor with Xpetra-style numbering. Please make sure that you want "
92  "Xpetra-style numbering instead of Thyra-style numbering.");
93 
94  fullmap_ = fullmap;
95  maps_ = maps;
96  }
97  else
98  {
99  // std::cout << "Create Map Extractor in Thyra Mode!!! " << std::endl;
100  // use Thyra-style numbering for sub-block maps
101  // That is, all sub-block maps start with zero as GID and are contiguous
102 
103  // plausibility check
104  for(size_t v = 0; v < maps.size(); ++v)
105  {
106  TEUCHOS_TEST_FOR_EXCEPTION(maps[ v ]->getMinAllGlobalIndex() != 0,
107  std::logic_error,
108  "logic error. When using Thyra-style numbering all sub-block maps must start with zero as GID. Map block "
109  << v << " starts with GID " << maps[ v ]->getMinAllGlobalIndex());
110  }
111 
112  // store submaps in Thyra-style ordering
113  thyraMaps_ = maps;
114 
115  // get offsets
116  std::vector<GlobalOrdinal> gidOffsets(maps.size(), 0);
117  for(size_t v = 1; v < maps.size(); ++v)
118  {
119  gidOffsets[ v ] = maps[ v - 1 ]->getMaxAllGlobalIndex() + gidOffsets[ v - 1 ] + 1;
120  }
121 
122  // build submaps
123  maps_.resize(maps.size());
124  std::vector<GlobalOrdinal> fullMapGids;
125  const GO INVALID = Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid();
126  for(size_t v = 0; v < maps.size(); ++v)
127  {
128  size_t myNumElements = maps[ v ]->getNodeNumElements();
129  std::vector<GlobalOrdinal> subMapGids(myNumElements, 0);
130  for(LocalOrdinal l = 0; l < Teuchos::as<LocalOrdinal>(myNumElements); ++l)
131  {
132  GlobalOrdinal myGid = maps[ v ]->getGlobalElement(l);
133  subMapGids[ l ] = myGid + gidOffsets[ v ];
134  fullMapGids.push_back(myGid + gidOffsets[ v ]);
135  }
136  // std::sort(subMapGids.begin(), subMapGids.end());
137  // subMapGids.erase(std::unique(subMapGids.begin(), subMapGids.end()), subMapGids.end());
138 
139  Teuchos::ArrayView<GlobalOrdinal> subMapGidsView(&subMapGids[ 0 ], subMapGids.size());
140 
142  maps[ v ]->lib(), INVALID, subMapGidsView, maps[ v ]->getIndexBase(), maps[ v ]->getComm());
143  maps_[ v ] = mySubMap;
144  }
145 
146  // const GO INVALID = Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid();
147  // std::sort(coarseMapGids.begin(), coarseMapGids.end());
148  // coarseMapGids.erase(std::unique(coarseMapGids.begin(), coarseMapGids.end()), coarseMapGids.end());
149  // Teuchos::ArrayView<GO> coarseMapGidsView(&coarseMapGids[0], coarseMapGids.size());
150  // std::sort(fullMapGids.begin(), fullMapGids.end());
151  // fullMapGids.erase(std::unique(fullMapGids.begin(), fullMapGids.end()), fullMapGids.end());
152 
153  Teuchos::ArrayView<GlobalOrdinal> fullMapGidsView(&fullMapGids[ 0 ], fullMapGids.size());
154 
156  fullmap->lib(), INVALID, fullMapGidsView, fullmap->getIndexBase(), fullmap->getComm());
157 
158  // plausibility check
159  size_t numAllElements = 0;
160  for(size_t v = 0; v < maps_.size(); ++v)
161  {
162  numAllElements += maps_[ v ]->getGlobalNumElements();
163  }
164  TEUCHOS_TEST_FOR_EXCEPTION(
165  fullmap_->getGlobalNumElements() != numAllElements,
166  std::logic_error,
167  "logic error. full map and sub maps have not same number of elements. This cannot be. Please report the bug to the Xpetra developers!");
168  }
169 
170  // build importers for sub maps
171  importers_.resize(maps_.size());
172  for(unsigned i = 0; i < maps_.size(); ++i)
173  {
174  if(maps[ i ] != null)
175  {
176  importers_[ i ] = Xpetra::ImportFactory<LocalOrdinal, GlobalOrdinal, Node>::Build(fullmap_, maps_[ i ]);
177  }
178  }
179  TEUCHOS_TEST_FOR_EXCEPTION(
180  CheckConsistency() == false, std::logic_error, "logic error. full map and sub maps are inconsistently distributed over the processors.");
181 }
182 
183 
184 template<class LocalOrdinal, class GlobalOrdinal, class Node>
186 BlockedMap(const std::vector<RCP<const Map>>& maps, const std::vector<RCP<const Map>>& thyramaps)
187 {
188  bThyraMode_ = true;
189 
190  // plausibility check
191  TEUCHOS_TEST_FOR_EXCEPTION(thyramaps.size() != maps.size(), std::logic_error, "logic error. The number of submaps must be identical!");
192  for(size_t v = 0; v < thyramaps.size(); ++v)
193  {
194  TEUCHOS_TEST_FOR_EXCEPTION(thyramaps[ v ]->getMinAllGlobalIndex() != 0,
195  std::logic_error,
196  "logic error. When using Thyra-style numbering all sub-block maps must start with zero as GID.");
197 
198  XPETRA_TEST_FOR_EXCEPTION(thyramaps[ v ]->getNodeNumElements() != maps[ v ]->getNodeNumElements(),
199  std::logic_error,
200  "logic error. The size of the submaps must be identical (same distribution, just different GIDs)");
201  }
202 
203  // store user-provided maps and thyramaps
204  thyraMaps_ = thyramaps;
205  maps_ = maps;
206  fullmap_ = this->concatenateMaps(maps);
207 
208  // plausibility check
209  size_t numAllElements = 0;
210  for(size_t v = 0; v < maps_.size(); ++v)
211  {
212  numAllElements += maps_[ v ]->getGlobalNumElements();
213  }
214  TEUCHOS_TEST_FOR_EXCEPTION(
215  fullmap_->getGlobalNumElements() != numAllElements,
216  std::logic_error,
217  "logic error. full map and sub maps have not same number of elements. This cannot be. Please report the bug to the Xpetra developers!");
218 
219  // build importers for sub maps
220  importers_.resize(maps_.size());
221  for(unsigned i = 0; i < maps_.size(); ++i)
222  {
223  if(maps[ i ] != null)
224  {
225  importers_[ i ] = Xpetra::ImportFactory<LocalOrdinal, GlobalOrdinal, Node>::Build(fullmap_, maps_[ i ]);
226  }
227  }
228  TEUCHOS_TEST_FOR_EXCEPTION(
229  CheckConsistency() == false, std::logic_error, "logic error. full map and sub maps are inconsistently distributed over the processors.");
230 }
231 
232 
233 template<class LocalOrdinal, class GlobalOrdinal, class Node>
235 BlockedMap(const BlockedMap& input)
236 {
237  bThyraMode_ = input.getThyraMode();
238  fullmap_ = Teuchos::null;
239  maps_.resize(input.getNumMaps(), Teuchos::null);
240  thyraMaps_.resize(input.getNumMaps(), Teuchos::null);
241  this->assign(input);
242 }
243 
244 
245 template<class LocalOrdinal, class GlobalOrdinal, class Node>
248 {
249  // make sure all RCP's are freed
250  for(size_t v = 0; v < maps_.size(); ++v)
251  {
252  maps_[ v ] = Teuchos::null;
253  if(bThyraMode_ == true)
254  thyraMaps_[ v ] = Teuchos::null;
255  importers_[ v ] = Teuchos::null;
256  }
257 
258  fullmap_ = Teuchos::null;
259 }
260 
261 
262 template<class LocalOrdinal, class GlobalOrdinal, class Node>
266 {
267  return fullmap_->getGlobalNumElements();
268 }
269 
270 
271 template<class LocalOrdinal, class GlobalOrdinal, class Node>
272 size_t
274 {
275  return fullmap_->getNodeNumElements();
276 }
277 
278 
279 template<class LocalOrdinal, class GlobalOrdinal, class Node>
280 GlobalOrdinal
283 {
284  return fullmap_->getIndexBase();
285 }
286 
287 
288 template<class LocalOrdinal, class GlobalOrdinal, class Node>
289 LocalOrdinal
292 {
293  return fullmap_->getMinLocalIndex();
294 }
295 
296 
297 template<class LocalOrdinal, class GlobalOrdinal, class Node>
298 LocalOrdinal
301 {
302  return fullmap_->getMaxLocalIndex();
303 }
304 
305 
306 template<class LocalOrdinal, class GlobalOrdinal, class Node>
307 GlobalOrdinal
310 {
311  return fullmap_->getMinGlobalIndex();
312 }
313 
314 
315 template<class LocalOrdinal, class GlobalOrdinal, class Node>
316 GlobalOrdinal
319 {
320  return fullmap_->getMaxGlobalIndex();
321 }
322 
323 
324 template<class LocalOrdinal, class GlobalOrdinal, class Node>
325 GlobalOrdinal
328 {
329  return fullmap_->getMinAllGlobalIndex();
330 }
331 
332 
333 template<class LocalOrdinal, class GlobalOrdinal, class Node>
334 GlobalOrdinal
337 {
338  return fullmap_->getMaxAllGlobalIndex();
339 }
340 
341 
342 template<class LocalOrdinal, class GlobalOrdinal, class Node>
343 LocalOrdinal
345 getLocalElement(GlobalOrdinal globalIndex) const
346 {
347  return fullmap_->getLocalElement(globalIndex);
348 }
349 
350 
351 template<class LocalOrdinal, class GlobalOrdinal, class Node>
352 GlobalOrdinal
354 getGlobalElement(LocalOrdinal localIndex) const
355 {
356  return fullmap_->getGlobalElement(localIndex);
357 }
358 
359 
360 template<class LocalOrdinal, class GlobalOrdinal, class Node>
363 getRemoteIndexList(const Teuchos::ArrayView<const GlobalOrdinal>& /* GIDList */,
364  const Teuchos::ArrayView<int>& /* nodeIDList */,
365  const Teuchos::ArrayView<LocalOrdinal>& /* LIDList */) const
366 {
367  throw Xpetra::Exceptions::RuntimeError("BlockedMap::getRemoteIndexList: routine not implemented.");
368  TEUCHOS_UNREACHABLE_RETURN(IDNotPresent);
369 }
370 
371 
372 template<class LocalOrdinal, class GlobalOrdinal, class Node>
375 getRemoteIndexList(const Teuchos::ArrayView<const GlobalOrdinal>& /* GIDList */,
376  const Teuchos::ArrayView<int>& /* nodeIDList */) const
377 {
378  throw Xpetra::Exceptions::RuntimeError("BlockedMap::getRemoteIndexList: routine not implemented.");
379  TEUCHOS_UNREACHABLE_RETURN(IDNotPresent);
380 }
381 
382 
383 template<class LocalOrdinal, class GlobalOrdinal, class Node>
384 Teuchos::ArrayView<const GlobalOrdinal>
387 {
388  return fullmap_->getNodeElementList();
389 }
390 
391 
392 template<class LocalOrdinal, class GlobalOrdinal, class Node>
393 bool
395 isNodeLocalElement(LocalOrdinal localIndex) const
396 {
397  return fullmap_->isNodeLocalElement(localIndex);
398 }
399 
400 
401 template<class LocalOrdinal, class GlobalOrdinal, class Node>
402 bool
404 isNodeGlobalElement(GlobalOrdinal globalIndex) const
405 {
406  return fullmap_->isNodeGlobalElement(globalIndex);
407 }
408 
409 
410 template<class LocalOrdinal, class GlobalOrdinal, class Node>
411 bool
414 {
415  throw Xpetra::Exceptions::RuntimeError("BlockedMap::isContiguous: routine not implemented.");
416  TEUCHOS_UNREACHABLE_RETURN(false);
417 }
418 
419 
420 template<class LocalOrdinal, class GlobalOrdinal, class Node>
421 bool
424 {
425  return fullmap_->isDistributed();
426 }
427 
428 
429 template<class LocalOrdinal, class GlobalOrdinal, class Node>
430 bool
433 {
434  RCP<const Map> rcpMap = Teuchos::rcpFromRef(map);
435  RCP<const BlockedMap> rcpBMap = Teuchos::rcp_dynamic_cast<const BlockedMap>(rcpMap);
436  if(rcpBMap.is_null() == true)
437  return false;
438 
439  for(size_t v = 0; v < maps_.size(); ++v)
440  {
441  bool bSame = getMap(v, false)->isCompatible(*(rcpBMap->getMap(v, false)));
442  if(bSame == false)
443  return false;
444  if(bThyraMode_)
445  {
446  bSame = getMap(v, true)->isCompatible(*(rcpBMap->getMap(v, true)));
447  }
448  }
449  return true;
450 }
451 
452 
453 template<class LocalOrdinal, class GlobalOrdinal, class Node>
454 bool
457 {
458  RCP<const Map> rcpMap = Teuchos::rcpFromRef(map);
459  RCP<const BlockedMap> rcpBMap = Teuchos::rcp_dynamic_cast<const BlockedMap>(rcpMap);
460  if(rcpBMap.is_null() == true)
461  {
462  // If this is a blocked map with > 1 blocks but "map" is a plain map they can't be the same
463  if(this->getNumMaps() > 1)
464  {
465  return false;
466  }
467 
468  // special case: this is a single blocked map and "map" is a plain map object
469  bool bSame = getMap(0, bThyraMode_)->isSameAs(*rcpMap);
470  return bSame;
471  }
472 
473  for(size_t v = 0; v < maps_.size(); ++v)
474  {
475  bool bSame = getMap(v, false)->isSameAs(*(rcpBMap->getMap(v, false)));
476  if(bSame == false)
477  {
478  return false;
479  }
480  if(bThyraMode_)
481  {
482  bSame = getMap(v, true)->isSameAs(*(rcpBMap->getMap(v, true)));
483  if(bSame == false)
484  {
485  return false;
486  }
487  }
488  }
489  return true;
490 }
491 
492 
493 template<class LocalOrdinal, class GlobalOrdinal, class Node>
494 Teuchos::RCP<const Teuchos::Comm<int>>
496 getComm() const
497 {
498  return fullmap_->getComm();
499 }
500 
501 
502 
503 
504 template<class LocalOrdinal, class GlobalOrdinal, class Node>
508 {
509  assign(rhs); // dispatch to protected virtual method
510  return *this;
511 }
512 
513 template<class LocalOrdinal, class GlobalOrdinal, class Node>
514 bool
516 {
517  return bThyraMode_;
518 }
519 
520 
521 template<class LocalOrdinal, class GlobalOrdinal, class Node>
522 RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
525 {
526  throw Xpetra::Exceptions::RuntimeError("BlockedMap::removeEmptyProcesses: routine not implemented.");
527 }
528 
529 
530 template<class LocalOrdinal, class GlobalOrdinal, class Node>
531 RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
533 replaceCommWithSubset(const Teuchos::RCP<const Teuchos::Comm<int>>& /* newComm */) const
534 {
535  throw Xpetra::Exceptions::RuntimeError("BlockedMap::replaceCommWithSubset: routine not implemented.");
536 }
537 
538 
539 template<class LocalOrdinal, class GlobalOrdinal, class Node>
542 {
543  return fullmap_->lib();
544 }
545 
546 
547 template<class LocalOrdinal, class GlobalOrdinal, class Node>
548 RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
550 getMap() const
551 {
552  return getFullMap();
553 }
554 
555 
556 template<class LocalOrdinal, class GlobalOrdinal, class Node>
557 size_t
559 getNumMaps() const
560 {
561  return maps_.size();
562 }
563 
564 
565 template<class LocalOrdinal, class GlobalOrdinal, class Node>
566 const RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
568 getMap(size_t i,
569  bool bThyraMode) const
570 {
571  XPETRA_TEST_FOR_EXCEPTION(i >= getNumMaps(),
573  "BlockedMap::getMap: tried to access block " << i << ", but BlockedMap has only " << getNumMaps()
574  << " blocks! Block indices must be between 0 and " << getNumMaps() - 1
575  << ".");
576  if(bThyraMode_ == true && bThyraMode == true)
577  {
578  return thyraMaps_[ i ];
579  }
580 
581  XPETRA_TEST_FOR_EXCEPTION(bThyraMode_ == false && bThyraMode == true,
583  "BlockedMap::getMap: cannot return sub map in Thyra-style numbering if BlockedMap object is not created using "
584  "Thyra-style numbered submaps.");
585  return maps_[ i ];
586 }
587 
588 
589 template<class LocalOrdinal, class GlobalOrdinal, class Node>
590 const RCP<Xpetra::Import<LocalOrdinal,GlobalOrdinal,Node>>
592 getImporter(size_t i) const
593 {
594  XPETRA_TEST_FOR_EXCEPTION(i >= getNumMaps(),
596  "BlockedMap::getImporter: tried to access block " << i << ", but BlockedMap has only " << getNumMaps()
597  << " blocks! Block indices must be between 0 and " << getNumMaps() - 1
598  << ".");
599  return importers_[ i ];
600 }
601 
602 
603 template<class LocalOrdinal, class GlobalOrdinal, class Node>
604 const RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node>>
606 getFullMap() const
607 {
608  return fullmap_;
609 }
610 
611 
612 template<class LocalOrdinal, class GlobalOrdinal, class Node>
613 size_t
615 getMapIndexForGID(GlobalOrdinal gid) const
616 {
617  for(size_t i = 0; i < getNumMaps(); i++)
618  if(getMap(i)->isNodeGlobalElement(gid) == true)
619  return i;
620 
621  TEUCHOS_TEST_FOR_EXCEPTION(
622  false, Xpetra::Exceptions::RuntimeError, "getMapIndexForGID: GID " << gid << " is not contained by a map in mapextractor.");
623  return 0;
624 }
625 
626 
627 template<class LocalOrdinal, class GlobalOrdinal, class Node>
628 std::string
630 description() const
631 {
632  return std::string("BlockedMap");
633 }
634 
635 
636 template<class LocalOrdinal, class GlobalOrdinal, class Node>
637 void
639 describe(Teuchos::FancyOStream& out, const Teuchos::EVerbosityLevel verbLevel) const
640 {
641  out << "------------- Blocked Map -----------" << std::endl;
642  out << description() << std::endl;
643  out << "Thyra mode: " << getThyraMode() << std::endl;
644  out << "No of submaps: " << getNumMaps() << std::endl;
645  Teuchos::OSTab tab(out);
646  for(size_t r = 0; r < getNumMaps(); r++)
647  {
648  std::cout << "MAP " << r << "/" << getNumMaps() - 1 << std::endl;
649  getMap(r, false)->describe(out, verbLevel);
650  }
651  if(getThyraMode() == true)
652  {
653  for(size_t r = 0; r < getNumMaps(); r++)
654  {
655  std::cout << "Thyra MAP " << r << "/" << getNumMaps() - 1 << std::endl;
656  getMap(r, true)->describe(out, verbLevel);
657  }
658  }
659  out << "-------------------------------------" << std::endl;
660 }
661 
662 
663 template<class LocalOrdinal, class GlobalOrdinal, class Node>
664 void
666 assign(const BlockedMap& input)
667 {
668  // TODO check implementation, simplify copy constructor
669  bThyraMode_ = input.getThyraMode();
670 
672 
673  maps_.resize(input.getNumMaps(), Teuchos::null);
674  if(bThyraMode_ == true)
675  thyraMaps_.resize(input.getNumMaps(), Teuchos::null);
676  for(size_t i = 0; i < input.getNumMaps(); ++i)
677  {
679  if(bThyraMode_ == true)
680  thyraMaps_[ i ] = Xpetra::MapFactory<LocalOrdinal, GlobalOrdinal, Node>::Build(input.getMap(i, true), 1);
681  }
682 
683  // plausibility check
684  size_t numAllElements = 0;
685  for(size_t v = 0; v < maps_.size(); ++v)
686  {
687  numAllElements += maps_[ v ]->getGlobalNumElements();
688  }
689  TEUCHOS_TEST_FOR_EXCEPTION(
690  fullmap_->getGlobalNumElements() != numAllElements,
691  std::logic_error,
692  "logic error. full map and sub maps have not same number of elements. This cannot be. Please report the bug to the Xpetra developers!");
693 
694  // build importers for sub maps
695  importers_.resize(maps_.size());
696  for(unsigned i = 0; i < maps_.size(); ++i)
697  if(maps_[ i ] != null)
698  importers_[ i ] = Xpetra::ImportFactory<LocalOrdinal, GlobalOrdinal, Node>::Build(fullmap_, maps_[ i ]);
699  TEUCHOS_TEST_FOR_EXCEPTION(
700  CheckConsistency() == false, std::logic_error, "logic error. full map and sub maps are inconsistently distributed over the processors.");
701 }
702 
703 
704 template<class LocalOrdinal, class GlobalOrdinal, class Node>
705 Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
707 concatenateMaps(const std::vector<Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>>& subMaps)
708 {
709 
710  // merge submaps to global map
711  std::vector<GlobalOrdinal> gids;
712  for(size_t tt = 0; tt < subMaps.size(); ++tt)
713  {
714  Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> subMap = subMaps[ tt ];
715 
716 #if 1 // WCMCLEN : IS THIS NECESSARY TO HANG ONTO?
717  Teuchos::ArrayView<const GlobalOrdinal> subMapGids = subMap->getNodeElementList();
718  gids.insert(gids.end(), subMapGids.begin(), subMapGids.end());
719 #else
720  size_t myNumElements = subMap->getNodeNumElements();
721  for(LocalOrdinal l = 0; l < Teuchos::as<LocalOrdinal>(myNumElements); ++l)
722  {
723  GlobalOrdinal gid = subMap->getGlobalElement(l);
724  gids.push_back(gid);
725  }
726 #endif
727  }
728 
729  const GlobalOrdinal INVALID = Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid();
730  // std::sort(gids.begin(), gids.end());
731  // gids.erase(std::unique(gids.begin(), gids.end()), gids.end());
732  Teuchos::ArrayView<GlobalOrdinal> gidsView(&gids[ 0 ], gids.size());
733 
734  Teuchos::RCP<Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> fullMap = Xpetra::MapFactory<LocalOrdinal, GlobalOrdinal, Node>::
735  Build(subMaps[ 0 ]->lib(), INVALID, gidsView, subMaps[ 0 ]->getIndexBase(), subMaps[ 0 ]->getComm());
736 
737  return fullMap;
738 }
739 
740 
741 template<class LocalOrdinal, class GlobalOrdinal, class Node>
742 bool
745 {
746  const RCP<const Map> fullMap = getFullMap();
747 
748  for(size_t i = 0; i < getNumMaps(); i++)
749  {
750  const RCP<const Map> map = getMap(i);
751 
752  ArrayView<const GlobalOrdinal> mapGids = map->getNodeElementList();
753  for(typename ArrayView<const GlobalOrdinal>::const_iterator it = mapGids.begin(); it != mapGids.end(); it++)
754  {
755  if(fullMap->isNodeGlobalElement(*it) == false)
756  {
757  return false; // Global ID (*it) not found locally on this proc in fullMap -> error
758  }
759  }
760  }
761  return true;
762 }
763 
764 
765 
766 } // namespace Xpetra
767 #endif /* PACKAGES_XPETRA_SUP_BLOCKEDMAP_XPETRA_BLOCKEDMAP_DECL_HPP_ */
virtual GlobalOrdinal getIndexBase() const
The index base for this Map.
virtual Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const
Return a view of the global indices owned by this process.
virtual std::string description() const
A simple one-line description of this object.
GlobalOrdinal GO
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 size_t getNodeNumElements() const
The number of elements belonging to the calling process.
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 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.
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 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.