10 #ifndef XPETRA_MAPEXTRACTOR_DEF_HPP_
11 #define XPETRA_MAPEXTRACTOR_DEF_HPP_
13 #include <Xpetra_MultiVectorFactory.hpp>
14 #include <Xpetra_VectorFactory.hpp>
15 #include <Xpetra_BlockedMultiVector.hpp>
21 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
23 MapExtractor(
const RCP<const Map>& fullmap,
const std::vector<RCP<const Map>>& maps,
bool bThyraMode) {
24 map_ = Teuchos::rcp(
new BlockedMap(fullmap, maps, bThyraMode));
27 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
29 MapExtractor(
const std::vector<RCP<const Map>>& maps,
const std::vector<RCP<const Map>>& thyramaps) {
30 map_ = Teuchos::rcp(
new BlockedMap(maps, thyramaps));
33 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
35 MapExtractor(
const Teuchos::RCP<const BlockedMap>& blockedMap)
38 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
44 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
50 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
54 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps() <<
" partial blocks.");
56 "ExtractVector: map_->getMap(" << block <<
",false) is null");
61 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
66 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
67 <<
" partial blocks.");
74 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
76 ExtractVector(RCP<const Vector>& full,
size_t block, RCP<Vector>& partial)
const {
77 ExtractVector(*full, block, *partial);
80 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
82 ExtractVector(RCP<Vector>& full,
size_t block, RCP<Vector>& partial)
const {
83 ExtractVector(*full, block, *partial);
86 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
88 ExtractVector(RCP<const MultiVector>& full,
size_t block, RCP<MultiVector>& partial)
const {
89 ExtractVector(*full, block, *partial);
92 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
94 ExtractVector(RCP<MultiVector>& full,
size_t block, RCP<MultiVector>& partial)
const {
95 ExtractVector(*full, block, *partial);
98 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
99 RCP<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
104 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
105 <<
" partial blocks.");
110 ExtractVector(*full, block, *vv);
111 if (bThyraMode ==
false)
113 TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() ==
false && bThyraMode ==
true,
114 Xpetra::Exceptions::RuntimeError,
115 "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been "
116 "created using Thyra-style numbered submaps.");
117 vv->replaceMap(getMap(block,
true));
121 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
122 RCP<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
127 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
128 <<
" partial blocks.");
130 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"ExtractVector: map_->getmap(" << block <<
",false) is null");
134 ExtractVector(*full, block, *vv);
135 if (bThyraMode ==
false)
137 TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() ==
false && bThyraMode ==
true,
138 Xpetra::Exceptions::RuntimeError,
139 "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been "
140 "created using Thyra-style numbered submaps.");
141 vv->replaceMap(getMap(block,
true));
145 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
146 RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
151 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
152 <<
" partial blocks.");
154 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"ExtractVector: map_->getmap(" << block <<
",false) is null");
155 RCP<const BlockedMultiVector> bfull = Teuchos::rcp_dynamic_cast<
const BlockedMultiVector>(full);
156 if (bfull.is_null() ==
true) {
164 RCP<const Map> oldThyMapFull = full->getMap();
165 RCP<MultiVector> rcpNonConstFull = Teuchos::rcp_const_cast<MultiVector>(full);
166 rcpNonConstFull->replaceMap(map_->getImporter(block)->getSourceMap());
167 ExtractVector(*rcpNonConstFull, block, *vv);
168 TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() ==
false && bThyraMode ==
true,
169 Xpetra::Exceptions::RuntimeError,
170 "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been "
171 "created using Thyra-style numbered submaps.");
172 if (bThyraMode ==
true)
173 vv->replaceMap(getMap(block,
true));
174 rcpNonConstFull->replaceMap(oldThyMapFull);
180 Xpetra::Exceptions::RuntimeError,
181 "ExtractVector: Number of blocks in map extractor is " << map_->getNumMaps() <<
" but should be "
182 << bfull->getBlockedMap()->getNumMaps()
183 <<
" (number of blocks in BlockedMultiVector)");
184 return bfull->getMultiVector(block, bThyraMode);
188 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
189 RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
194 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
195 <<
" partial blocks.");
197 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"ExtractVector: map_->getmap(" << block <<
",false) is null");
198 RCP<BlockedMultiVector> bfull = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(full);
199 if (bfull.is_null() ==
true) {
207 RCP<const Map> oldThyMapFull = full->getMap();
208 full->replaceMap(map_->getImporter(block)->getSourceMap());
209 ExtractVector(*full, block, *vv);
210 TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() ==
false && bThyraMode ==
true,
211 Xpetra::Exceptions::RuntimeError,
212 "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been "
213 "created using Thyra-style numbered submaps.");
214 if (bThyraMode ==
true)
215 vv->replaceMap(getMap(block,
true));
216 full->replaceMap(oldThyMapFull);
222 Xpetra::Exceptions::RuntimeError,
223 "ExtractVector: Number of blocks in map extractor is " << map_->getNumMaps() <<
" but should be "
224 << bfull->getBlockedMap()->getNumMaps()
225 <<
" (number of blocks in BlockedMultiVector)");
226 return bfull->getMultiVector(block, bThyraMode);
230 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
231 RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
236 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
237 <<
" partial blocks.");
239 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"ExtractVector: map_->getmap(" << block <<
",false) is null");
241 Xpetra::Exceptions::RuntimeError,
242 "ExtractVector: Number of blocks in map extractor is " << map_->getNumMaps() <<
" but should be "
243 << full->getBlockedMap()->getNumMaps()
244 <<
" (number of blocks in BlockedMultiVector)");
245 Teuchos::RCP<MultiVector> vv = full->getMultiVector(block, bThyraMode);
249 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
250 RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
255 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
256 <<
" partial blocks.");
258 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"ExtractVector: map_->getmap(" << block <<
",false) is null");
260 Xpetra::Exceptions::RuntimeError,
261 "ExtractVector: Number of blocks in map extractor is " << map_->getNumMaps() <<
" but should be "
262 << full->getBlockedMap()->getNumMaps()
263 <<
" (number of blocks in BlockedMultiVector)");
264 Teuchos::RCP<MultiVector> vv = full->getMultiVector(block, bThyraMode);
268 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
273 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
274 <<
" partial blocks.");
276 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"ExtractVector: map_->getmap(" << block <<
",false) is null");
278 Xpetra::Exceptions::RuntimeError,
279 "MapExtractor::InsertVector: InsertVector in Thyra-style numbering only possible if MapExtractor has been created "
280 "using Thyra-style numbered submaps.");
289 RCP<const MultiVector> rcpPartial = Teuchos::rcpFromRef(partial);
290 RCP<MultiVector> rcpNonConstPartial = Teuchos::rcp_const_cast<
MultiVector>(rcpPartial);
291 RCP<const Map> oldThyMapPartial = rcpNonConstPartial->
getMap();
292 RCP<const Map> oldThyMapFull = full.
getMap();
296 Xpetra::Exceptions::RuntimeError,
297 "MapExtractor::InsertVector: InsertVector in Thyra-style mode: Xpetra GIDs of partial vector are not identical "
298 "to target Map of Importer. This should not be.");
305 rcpNonConstPartial->replaceMap(getMap(block,
false));
306 full.
replaceMap(map_->getImporter(block)->getSourceMap());
313 rcpNonConstPartial->replaceMap(oldThyMapPartial);
320 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
325 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
326 <<
" partial blocks.");
328 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"ExtractVector: map_->getmap(" << block <<
",false) is null");
330 Xpetra::Exceptions::RuntimeError,
331 "MapExtractor::InsertVector: InsertVector in Thyra-style numbering only possible if MapExtractor has been created "
332 "using Thyra-style numbered submaps.");
341 RCP<const MultiVector> rcpPartial = Teuchos::rcpFromRef(partial);
342 RCP<MultiVector> rcpNonConstPartial = Teuchos::rcp_const_cast<
MultiVector>(rcpPartial);
343 RCP<const Map> oldThyMapPartial = rcpNonConstPartial->
getMap();
344 RCP<const Map> oldThyMapFull = full.
getMap();
348 Xpetra::Exceptions::RuntimeError,
349 "MapExtractor::InsertVector: InsertVector in Thyra-style mode: Xpetra GIDs of partial vector are not identical "
350 "to target Map of Importer. This should not be.");
357 rcpNonConstPartial->replaceMap(getMap(block,
false));
358 full.
replaceMap(map_->getImporter(block)->getSourceMap());
365 rcpNonConstPartial->replaceMap(oldThyMapPartial);
372 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
374 InsertVector(RCP<const Vector> partial,
size_t block, RCP<Vector> full,
bool bThyraMode)
const {
375 InsertVector(*partial, block, *full, bThyraMode);
378 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
380 InsertVector(RCP<Vector> partial,
size_t block, RCP<Vector> full,
bool bThyraMode)
const {
381 InsertVector(*partial, block, *full, bThyraMode);
384 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
389 bool bThyraMode)
const {
390 RCP<BlockedMultiVector> bfull = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(full);
391 if (bfull.is_null() ==
true)
392 InsertVector(*partial, block, *full, bThyraMode);
395 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"InsertVector: map_->getmap(" << block <<
",false) is null");
400 full->setMultiVector(block, partial, bThyraMode);
402 throw std::runtime_error(
"Xpetra::MultiVector::setMultiVector() doesn't exist in " + std::string(__FILE__) +
":" + std::to_string(__LINE__));
407 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
412 bool bThyraMode)
const {
413 RCP<BlockedMultiVector> bfull = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(full);
414 if (bfull.is_null() ==
true)
415 InsertVector(*partial, block, *full, bThyraMode);
418 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"InsertVector: map_->getmap(" << block <<
",false) is null");
420 bfull->setMultiVector(block, partial, bThyraMode);
424 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
429 bool bThyraMode)
const {
431 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"InsertVector: map_->getmap(" << block <<
",false) is null");
433 full->setMultiVector(block, partial, bThyraMode);
436 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
441 bool bThyraMode)
const {
443 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"InsertVector: map_->getmap(" << block <<
",false) is null");
444 full->setMultiVector(block, partial, bThyraMode);
447 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
448 RCP<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
450 getVector(
size_t i,
bool bThyraMode,
bool bZero)
const {
452 Xpetra::Exceptions::RuntimeError,
453 "MapExtractor::getVector: getVector in Thyra-style numbering only possible if MapExtractor has been created using "
454 "Thyra-style numbered submaps.");
459 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
460 RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
462 getVector(
size_t i,
size_t numvec,
bool bThyraMode,
bool bZero)
const {
464 Xpetra::Exceptions::RuntimeError,
465 "MapExtractor::getVector: getVector in Thyra-style numbering only possible if MapExtractor has been created using "
466 "Thyra-style numbered submaps.");
472 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
475 return map_->getThyraMode();
478 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
482 return map_->getNumMaps();
485 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
486 const RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
488 getMap(
size_t i,
bool bThyraMode)
const {
489 return map_->getMap(i, bThyraMode);
492 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
493 const RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
499 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
500 const RCP<const Xpetra::BlockedMap<LocalOrdinal, GlobalOrdinal, Node>>
506 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
507 const RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
510 return map_->getFullMap();
513 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
517 return map_->getMapIndexForGID(gid);
virtual void replaceMap(const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node >> &map)=0
virtual void doExport(const DistObject< Packet, LocalOrdinal, GlobalOrdinal, Node > &source, const Export< LocalOrdinal, GlobalOrdinal, Node > &exporter, CombineMode CM)=0
Export data into this object using an Export object ("forward mode").
static Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Build(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node >> &map, size_t NumVectors, bool zeroOut=true)
Constructor specifying the number of non-zeros for all rows.
static Teuchos::RCP< Xpetra::Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Build(const Teuchos::RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node >> &map, bool zeroOut=true)
Constructor specifying the number of non-zeros for all rows.
Exception throws to report errors in the internal logical of the program.
virtual void doImport(const DistObject< Packet, LocalOrdinal, GlobalOrdinal, Node > &source, const Import< LocalOrdinal, GlobalOrdinal, Node > &importer, CombineMode CM)=0
Import data into this object using an Import object ("forward mode").
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const =0
The Map describing the parallel distribution of this object.
#define XPETRA_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)