46 #ifndef XPETRA_MAPEXTRACTOR_DEF_HPP_
47 #define XPETRA_MAPEXTRACTOR_DEF_HPP_
49 #include <Xpetra_MultiVectorFactory.hpp>
50 #include <Xpetra_VectorFactory.hpp>
51 #include <Xpetra_BlockedMultiVector.hpp>
57 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
59 MapExtractor(
const RCP<const Map>& fullmap,
const std::vector<RCP<const Map>>& maps,
bool bThyraMode) {
60 map_ = Teuchos::rcp(
new BlockedMap(fullmap, maps, bThyraMode));
63 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
65 MapExtractor(
const std::vector<RCP<const Map>>& maps,
const std::vector<RCP<const Map>>& thyramaps) {
66 map_ = Teuchos::rcp(
new BlockedMap(maps, thyramaps));
69 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
71 MapExtractor(
const Teuchos::RCP<const BlockedMap>& blockedMap)
74 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
80 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
86 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
90 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps() <<
" partial blocks.");
92 "ExtractVector: map_->getMap(" << block <<
",false) is null");
97 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
102 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
103 <<
" partial blocks.");
110 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
112 ExtractVector(RCP<const Vector>& full,
size_t block, RCP<Vector>& partial)
const {
113 ExtractVector(*full, block, *partial);
116 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
118 ExtractVector(RCP<Vector>& full,
size_t block, RCP<Vector>& partial)
const {
119 ExtractVector(*full, block, *partial);
122 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
124 ExtractVector(RCP<const MultiVector>& full,
size_t block, RCP<MultiVector>& partial)
const {
125 ExtractVector(*full, block, *partial);
128 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
130 ExtractVector(RCP<MultiVector>& full,
size_t block, RCP<MultiVector>& partial)
const {
131 ExtractVector(*full, block, *partial);
134 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
135 RCP<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
140 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
141 <<
" partial blocks.");
146 ExtractVector(*full, block, *vv);
147 if (bThyraMode ==
false)
149 TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() ==
false && bThyraMode ==
true,
150 Xpetra::Exceptions::RuntimeError,
151 "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been "
152 "created using Thyra-style numbered submaps.");
153 vv->replaceMap(getMap(block,
true));
157 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
158 RCP<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
163 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
164 <<
" partial blocks.");
166 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"ExtractVector: map_->getmap(" << block <<
",false) is null");
170 ExtractVector(*full, block, *vv);
171 if (bThyraMode ==
false)
173 TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() ==
false && bThyraMode ==
true,
174 Xpetra::Exceptions::RuntimeError,
175 "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been "
176 "created using Thyra-style numbered submaps.");
177 vv->replaceMap(getMap(block,
true));
181 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
182 RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
187 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
188 <<
" partial blocks.");
190 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"ExtractVector: map_->getmap(" << block <<
",false) is null");
191 RCP<const BlockedMultiVector> bfull = Teuchos::rcp_dynamic_cast<
const BlockedMultiVector>(full);
192 if (bfull.is_null() ==
true) {
200 RCP<const Map> oldThyMapFull = full->getMap();
201 RCP<MultiVector> rcpNonConstFull = Teuchos::rcp_const_cast<MultiVector>(full);
202 rcpNonConstFull->replaceMap(map_->getImporter(block)->getSourceMap());
203 ExtractVector(*rcpNonConstFull, block, *vv);
204 TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() ==
false && bThyraMode ==
true,
205 Xpetra::Exceptions::RuntimeError,
206 "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been "
207 "created using Thyra-style numbered submaps.");
208 if (bThyraMode ==
true)
209 vv->replaceMap(getMap(block,
true));
210 rcpNonConstFull->replaceMap(oldThyMapFull);
216 Xpetra::Exceptions::RuntimeError,
217 "ExtractVector: Number of blocks in map extractor is " << map_->getNumMaps() <<
" but should be "
218 << bfull->getBlockedMap()->getNumMaps()
219 <<
" (number of blocks in BlockedMultiVector)");
220 return bfull->getMultiVector(block, bThyraMode);
224 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
225 RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
230 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
231 <<
" partial blocks.");
233 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"ExtractVector: map_->getmap(" << block <<
",false) is null");
234 RCP<BlockedMultiVector> bfull = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(full);
235 if (bfull.is_null() ==
true) {
243 RCP<const Map> oldThyMapFull = full->getMap();
244 full->replaceMap(map_->getImporter(block)->getSourceMap());
245 ExtractVector(*full, block, *vv);
246 TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() ==
false && bThyraMode ==
true,
247 Xpetra::Exceptions::RuntimeError,
248 "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been "
249 "created using Thyra-style numbered submaps.");
250 if (bThyraMode ==
true)
251 vv->replaceMap(getMap(block,
true));
252 full->replaceMap(oldThyMapFull);
258 Xpetra::Exceptions::RuntimeError,
259 "ExtractVector: Number of blocks in map extractor is " << map_->getNumMaps() <<
" but should be "
260 << bfull->getBlockedMap()->getNumMaps()
261 <<
" (number of blocks in BlockedMultiVector)");
262 return bfull->getMultiVector(block, bThyraMode);
266 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
267 RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
272 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
273 <<
" partial blocks.");
275 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"ExtractVector: map_->getmap(" << block <<
",false) is null");
277 Xpetra::Exceptions::RuntimeError,
278 "ExtractVector: Number of blocks in map extractor is " << map_->getNumMaps() <<
" but should be "
279 << full->getBlockedMap()->getNumMaps()
280 <<
" (number of blocks in BlockedMultiVector)");
281 Teuchos::RCP<MultiVector> vv = full->getMultiVector(block, bThyraMode);
285 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
286 RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
291 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
292 <<
" partial blocks.");
294 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"ExtractVector: map_->getmap(" << block <<
",false) is null");
296 Xpetra::Exceptions::RuntimeError,
297 "ExtractVector: Number of blocks in map extractor is " << map_->getNumMaps() <<
" but should be "
298 << full->getBlockedMap()->getNumMaps()
299 <<
" (number of blocks in BlockedMultiVector)");
300 Teuchos::RCP<MultiVector> vv = full->getMultiVector(block, bThyraMode);
304 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
309 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
310 <<
" partial blocks.");
312 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"ExtractVector: map_->getmap(" << block <<
",false) is null");
314 Xpetra::Exceptions::RuntimeError,
315 "MapExtractor::InsertVector: InsertVector in Thyra-style numbering only possible if MapExtractor has been created "
316 "using Thyra-style numbered submaps.");
325 RCP<const MultiVector> rcpPartial = Teuchos::rcpFromRef(partial);
326 RCP<MultiVector> rcpNonConstPartial = Teuchos::rcp_const_cast<
MultiVector>(rcpPartial);
327 RCP<const Map> oldThyMapPartial = rcpNonConstPartial->
getMap();
328 RCP<const Map> oldThyMapFull = full.
getMap();
332 Xpetra::Exceptions::RuntimeError,
333 "MapExtractor::InsertVector: InsertVector in Thyra-style mode: Xpetra GIDs of partial vector are not identical "
334 "to target Map of Importer. This should not be.");
341 rcpNonConstPartial->replaceMap(getMap(block,
false));
342 full.
replaceMap(map_->getImporter(block)->getSourceMap());
349 rcpNonConstPartial->replaceMap(oldThyMapPartial);
356 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
361 "ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " << map_->getNumMaps()
362 <<
" partial blocks.");
364 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"ExtractVector: map_->getmap(" << block <<
",false) is null");
366 Xpetra::Exceptions::RuntimeError,
367 "MapExtractor::InsertVector: InsertVector in Thyra-style numbering only possible if MapExtractor has been created "
368 "using Thyra-style numbered submaps.");
377 RCP<const MultiVector> rcpPartial = Teuchos::rcpFromRef(partial);
378 RCP<MultiVector> rcpNonConstPartial = Teuchos::rcp_const_cast<
MultiVector>(rcpPartial);
379 RCP<const Map> oldThyMapPartial = rcpNonConstPartial->
getMap();
380 RCP<const Map> oldThyMapFull = full.
getMap();
384 Xpetra::Exceptions::RuntimeError,
385 "MapExtractor::InsertVector: InsertVector in Thyra-style mode: Xpetra GIDs of partial vector are not identical "
386 "to target Map of Importer. This should not be.");
393 rcpNonConstPartial->replaceMap(getMap(block,
false));
394 full.
replaceMap(map_->getImporter(block)->getSourceMap());
401 rcpNonConstPartial->replaceMap(oldThyMapPartial);
408 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
410 InsertVector(RCP<const Vector> partial,
size_t block, RCP<Vector> full,
bool bThyraMode)
const {
411 InsertVector(*partial, block, *full, bThyraMode);
414 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
416 InsertVector(RCP<Vector> partial,
size_t block, RCP<Vector> full,
bool bThyraMode)
const {
417 InsertVector(*partial, block, *full, bThyraMode);
420 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
425 bool bThyraMode)
const {
426 RCP<BlockedMultiVector> bfull = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(full);
427 if (bfull.is_null() ==
true)
428 InsertVector(*partial, block, *full, bThyraMode);
431 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"InsertVector: map_->getmap(" << block <<
",false) is null");
436 full->setMultiVector(block, partial, bThyraMode);
438 throw std::runtime_error(
"Xpetra::MultiVector::setMultiVector() doesn't exist in " + std::string(__FILE__) +
":" + std::to_string(__LINE__));
443 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
448 bool bThyraMode)
const {
449 RCP<BlockedMultiVector> bfull = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(full);
450 if (bfull.is_null() ==
true)
451 InsertVector(*partial, block, *full, bThyraMode);
454 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"InsertVector: map_->getmap(" << block <<
",false) is null");
456 bfull->setMultiVector(block, partial, bThyraMode);
460 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
465 bool bThyraMode)
const {
467 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"InsertVector: map_->getmap(" << block <<
",false) is null");
469 full->setMultiVector(block, partial, bThyraMode);
472 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
477 bool bThyraMode)
const {
479 map_->getMap(block,
false) == null, Xpetra::Exceptions::RuntimeError,
"InsertVector: map_->getmap(" << block <<
",false) is null");
480 full->setMultiVector(block, partial, bThyraMode);
483 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
484 RCP<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
486 getVector(
size_t i,
bool bThyraMode,
bool bZero)
const {
488 Xpetra::Exceptions::RuntimeError,
489 "MapExtractor::getVector: getVector in Thyra-style numbering only possible if MapExtractor has been created using "
490 "Thyra-style numbered submaps.");
495 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
496 RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
498 getVector(
size_t i,
size_t numvec,
bool bThyraMode,
bool bZero)
const {
500 Xpetra::Exceptions::RuntimeError,
501 "MapExtractor::getVector: getVector in Thyra-style numbering only possible if MapExtractor has been created using "
502 "Thyra-style numbered submaps.");
508 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
511 return map_->getThyraMode();
514 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
518 return map_->getNumMaps();
521 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
522 const RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
524 getMap(
size_t i,
bool bThyraMode)
const {
525 return map_->getMap(i, bThyraMode);
528 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
529 const RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
535 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
536 const RCP<const Xpetra::BlockedMap<LocalOrdinal, GlobalOrdinal, Node>>
542 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
543 const RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
546 return map_->getFullMap();
549 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
553 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)