46 #ifndef XPETRA_MAPEXTRACTOR_HPP_ 47 #define XPETRA_MAPEXTRACTOR_HPP_ 53 #include <Teuchos_RCP.hpp> 54 #include <Teuchos_Describable.hpp> 69 #ifndef DOXYGEN_SHOULD_SKIP_THIS 71 template<
class S,
class LO,
class GO,
class N>
class BlockedMultiVector;
74 template <
class Scalar,
78 class MapExtractor :
public Teuchos::Describable {
86 #undef XPETRA_MAPEXTRACTOR_SHORT 103 MapExtractor(
const RCP<const Map>& fullmap,
const std::vector<RCP<const Map> >& maps,
bool bThyraMode =
false) {
106 if(bThyraMode ==
false) {
111 size_t numAllElements = 0;
112 for(
size_t v = 0; v < maps.size(); ++v) {
113 numAllElements += maps[v]->getGlobalNumElements();
115 TEUCHOS_TEST_FOR_EXCEPTION(fullmap->getGlobalNumElements() != numAllElements, std::logic_error,
116 "logic error. full map and sub maps have not same number of elements. We cannot build MapExtractor with Xpetra-style numbering. Please make sure that you want Xpetra-style numbering instead of Thyra-style numbering.");
126 for(
size_t v = 0; v < maps.size(); ++v) {
127 TEUCHOS_TEST_FOR_EXCEPTION(maps[v]->getMinAllGlobalIndex() != 0, std::logic_error,
128 "logic error. When using Thyra-style numbering all sub-block maps must start with zero as GID. Map block " << v <<
" starts with GID " << maps[v]->getMinAllGlobalIndex());
135 std::vector<GlobalOrdinal> gidOffsets(maps.size(),0);
136 for(
size_t v = 1; v < maps.size(); ++v) {
137 gidOffsets[v] = maps[v-1]->getMaxAllGlobalIndex() + gidOffsets[v-1] + 1;
141 maps_.resize(maps.size());
142 std::vector<GlobalOrdinal> fullMapGids;
143 const GO INVALID = Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid();
144 for(
size_t v = 0; v < maps.size(); ++v) {
145 std::vector<GlobalOrdinal> subMapGids(maps[v]->getNodeNumElements(),0);
146 for (LocalOrdinal l = 0; l < Teuchos::as<LocalOrdinal>(maps[v]->getNodeNumElements()); ++l) {
147 GlobalOrdinal myGid = maps[v]->getGlobalElement(l);
148 subMapGids[l] = myGid + gidOffsets[v];
149 fullMapGids.push_back(myGid + gidOffsets[v]);
154 Teuchos::ArrayView<GlobalOrdinal> subMapGidsView(&subMapGids[0], subMapGids.size());
166 Teuchos::ArrayView<GlobalOrdinal> fullMapGidsView(&fullMapGids[0], fullMapGids.size());
170 size_t numAllElements = 0;
171 for(
size_t v = 0; v <
maps_.size(); ++v) {
172 numAllElements +=
maps_[v]->getGlobalNumElements();
174 TEUCHOS_TEST_FOR_EXCEPTION(
fullmap_->getGlobalNumElements() != numAllElements, std::logic_error,
175 "logic error. full map and sub maps have not same number of elements. This cannot be. Please report the bug to the Xpetra developers!");
180 for (
unsigned i = 0; i <
maps_.size(); ++i)
184 "logic error. full map and sub maps are inconsistently distributed over the processors.");
189 MapExtractor(
const std::vector<RCP<const Map> >& maps,
const std::vector<RCP<const Map> >& thyramaps) {
194 TEUCHOS_TEST_FOR_EXCEPTION(thyramaps.size() != maps.size(), std::logic_error,
"logic error. The number of submaps must be identical!");
195 for(
size_t v = 0; v < thyramaps.size(); ++v) {
196 TEUCHOS_TEST_FOR_EXCEPTION(thyramaps[v]->getMinAllGlobalIndex() != 0, std::logic_error,
197 "logic error. When using Thyra-style numbering all sub-block maps must start with zero as GID.");
198 TEUCHOS_TEST_FOR_EXCEPTION(thyramaps[v]->getNodeNumElements() != maps[v]->getNodeNumElements(), std::logic_error,
199 "logic error. The size of the submaps must be identical (same distribution, just different GIDs)");
209 size_t numAllElements = 0;
210 for(
size_t v = 0; v <
maps_.size(); ++v) {
211 numAllElements +=
maps_[v]->getGlobalNumElements();
213 TEUCHOS_TEST_FOR_EXCEPTION(
fullmap_->getGlobalNumElements() != numAllElements, std::logic_error,
214 "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 for (
unsigned i = 0; i <
maps_.size(); ++i)
222 "logic error. full map and sub maps are inconsistently distributed over the processors.");
231 maps_.resize(input.NumMaps(), Teuchos::null);
233 thyraMaps_.resize(input.NumMaps(), Teuchos::null);
234 for(
size_t i = 0; i < input.NumMaps(); ++i) {
241 size_t numAllElements = 0;
242 for(
size_t v = 0; v <
maps_.size(); ++v) {
243 numAllElements +=
maps_[v]->getGlobalNumElements();
245 TEUCHOS_TEST_FOR_EXCEPTION(
fullmap_->getGlobalNumElements() != numAllElements, std::logic_error,
246 "logic error. full map and sub maps have not same number of elements. This cannot be. Please report the bug to the Xpetra developers!");
250 for (
unsigned i = 0; i <
maps_.size(); ++i)
251 if (
maps_[i] != null)
254 "logic error. full map and sub maps are inconsistently distributed over the processors.");
260 XPETRA_TEST_FOR_EXCEPTION(block >=
maps_.size(), std::out_of_range,
"ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " <<
maps_.size() <<
" partial blocks.");
262 "ExtractVector: maps_[" << block <<
"] is null");
267 XPETRA_TEST_FOR_EXCEPTION(block >=
maps_.size(), std::out_of_range,
"ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " <<
maps_.size() <<
" partial blocks.");
269 "ExtractVector: maps_[" << block <<
"] is null");
277 RCP< Vector>
ExtractVector(RCP<const Vector>& full,
size_t block,
bool bThyraMode =
false)
const {
278 XPETRA_TEST_FOR_EXCEPTION(block >=
maps_.size(), std::out_of_range,
"ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " <<
maps_.size() <<
" partial blocks.");
280 "ExtractVector: maps_[" << block <<
"] is null");
284 if(bThyraMode ==
false)
return vv;
286 "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
288 vv->replaceMap(
getMap(block,
true));
293 Teuchos::ArrayRCP<Scalar> thyraVecData = thyraVec->getDataNonConst(0);
294 Teuchos::ArrayRCP<const Scalar> xpetraVecData = vv->getData(0);
296 for(
size_t i=0; i < vv->getLocalLength(); i++) {
297 thyraVecData[i] = xpetraVecData[i];
302 RCP< Vector>
ExtractVector(RCP< Vector>& full,
size_t block,
bool bThyraMode =
false)
const {
303 XPETRA_TEST_FOR_EXCEPTION(block >=
maps_.size(), std::out_of_range,
"ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " <<
maps_.size() <<
" partial blocks.");
305 "ExtractVector: maps_[" << block <<
"] is null");
309 if(bThyraMode ==
false)
return vv;
311 "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
313 vv->replaceMap(
getMap(block,
true));
318 Teuchos::ArrayRCP<Scalar> thyraVecData = thyraVec->getDataNonConst(0);
319 Teuchos::ArrayRCP<const Scalar> xpetraVecData = vv->getData(0);
321 for(
size_t i=0; i < vv->getLocalLength(); i++) {
322 thyraVecData[i] = xpetraVecData[i];
327 RCP<MultiVector>
ExtractVector(RCP<const MultiVector>& full,
size_t block,
bool bThyraMode =
false)
const {
328 XPETRA_TEST_FOR_EXCEPTION(block >=
maps_.size(), std::out_of_range,
"ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " <<
maps_.size() <<
" partial blocks.");
330 "ExtractVector: maps_[" << block <<
"] is null");
334 if(bThyraMode ==
false)
return vv;
336 "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
338 vv->replaceMap(
getMap(block,
true));
343 for(
size_t k=0; k < vv->getNumVectors(); k++) {
344 Teuchos::ArrayRCP<Scalar> thyraVecData = thyraVec->getDataNonConst(k);
345 Teuchos::ArrayRCP<const Scalar> xpetraVecData = vv->getData(k);
346 for(
size_t i=0; i < vv->getLocalLength(); i++) {
347 thyraVecData[i] = xpetraVecData[i];
353 RCP<MultiVector>
ExtractVector(RCP< MultiVector>& full,
size_t block,
bool bThyraMode =
false)
const {
354 XPETRA_TEST_FOR_EXCEPTION(block >=
maps_.size(), std::out_of_range,
"ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " <<
maps_.size() <<
" partial blocks.");
356 "ExtractVector: maps_[" << block <<
"] is null");
360 if(bThyraMode ==
false)
return vv;
362 "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
364 vv->replaceMap(
getMap(block,
true));
369 for(
size_t k=0; k < vv->getNumVectors(); k++) {
370 Teuchos::ArrayRCP<Scalar> thyraVecData = thyraVec->getDataNonConst(k);
371 Teuchos::ArrayRCP<const Scalar> xpetraVecData = vv->getData(k);
372 for(
size_t i=0; i < vv->getLocalLength(); i++) {
373 thyraVecData[i] = xpetraVecData[i];
380 XPETRA_TEST_FOR_EXCEPTION(block >=
maps_.size(), std::out_of_range,
"ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " <<
maps_.size() <<
" partial blocks.");
382 "ExtractVector: maps_[" << block <<
"] is null");
384 "ExtractVector: Number of blocks in map extractor is " <<
NumMaps() <<
" but should be " << full->getMapExtractor()->NumMaps() <<
" (number of blocks in BlockedMultiVector)");
385 Teuchos::RCP<MultiVector> vv = full->getMultiVector(block,bThyraMode);
389 XPETRA_TEST_FOR_EXCEPTION(block >=
maps_.size(), std::out_of_range,
"ExtractVector: Error, block = " << block <<
" is too big. The MapExtractor only contains " <<
maps_.size() <<
" partial blocks.");
391 "ExtractVector: maps_[" << block <<
"] is null");
393 "ExtractVector: Number of blocks in map extractor is " <<
NumMaps() <<
" but should be " << full->getMapExtractor()->NumMaps() <<
" (number of blocks in BlockedMultiVector)");
394 Teuchos::RCP<MultiVector> vv = full->getMultiVector(block,bThyraMode);
403 "InsertVector: maps_[" << block <<
"] is null");
405 "MapExtractor::InsertVector: InsertVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
410 RCP<const MultiVector> rcpPartial = Teuchos::rcpFromRef(partial);
411 RCP<MultiVector> rcpNonConstPartial = Teuchos::rcp_const_cast<
MultiVector>(rcpPartial);
412 RCP<const Map> oldMap = rcpNonConstPartial->
getMap();
413 rcpNonConstPartial->replaceMap(
getMap(block,
false));
415 rcpNonConstPartial->replaceMap(oldMap);
419 Teuchos::ArrayRCP<const Scalar> thyraVecData = partial.
getData(0);
420 Teuchos::ArrayRCP<Scalar> xpetraVecData = xpetraVec->getDataNonConst(0);
421 for(
size_t i=0; i < xpetraVec->getLocalLength(); i++) {
422 xpetraVecData[i] = thyraVecData[i];
433 "InsertVector: maps_[" << block <<
"] is null");
435 "MapExtractor::InsertVector: InsertVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
440 RCP<const MultiVector> rcpPartial = Teuchos::rcpFromRef(partial);
441 RCP<MultiVector> rcpNonConstPartial = Teuchos::rcp_const_cast<
MultiVector>(rcpPartial);
442 RCP<const Map> oldMap = rcpNonConstPartial->
getMap();
443 rcpNonConstPartial->replaceMap(
getMap(block,
false));
445 rcpNonConstPartial->replaceMap(oldMap);
450 Teuchos::ArrayRCP<const Scalar> thyraVecData = partial.
getData(k);
451 Teuchos::ArrayRCP<Scalar> xpetraVecData = xpetraVec->getDataNonConst(k);
452 for(
size_t i=0; i < xpetraVec->getLocalLength(); i++) {
453 xpetraVecData[i] = thyraVecData[i];
464 void InsertVector(RCP<const Vector> partial,
size_t block, RCP< Vector> full,
bool bThyraMode =
false)
const {
InsertVector(*partial, block, *full, bThyraMode); }
465 void InsertVector(RCP< Vector> partial,
size_t block, RCP< Vector> full,
bool bThyraMode =
false)
const {
InsertVector(*partial, block, *full, bThyraMode); }
466 void InsertVector(RCP<const MultiVector> partial,
size_t block, RCP<MultiVector> full,
bool bThyraMode =
false)
const {
InsertVector(*partial, block, *full, bThyraMode); }
467 void InsertVector(RCP< MultiVector> partial,
size_t block, RCP<MultiVector> full,
bool bThyraMode =
false)
const {
InsertVector(*partial, block, *full, bThyraMode); }
471 "InsertVector: maps_[" << block <<
"] is null");
474 full->setMultiVector(block, partial, bThyraMode);
478 "InsertVector: maps_[" << block <<
"] is null");
481 full->setMultiVector(block, partial, bThyraMode);
486 RCP< Vector>
getVector(
size_t i,
bool bThyraMode =
false,
bool bZero =
true)
const {
488 "MapExtractor::getVector: getVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
491 RCP<MultiVector>
getVector(
size_t i,
size_t numvec,
bool bThyraMode =
false,
bool bZero =
true)
const {
493 "MapExtractor::getVector: getVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
510 const RCP<const Map>
getMap(
size_t i,
bool bThyraMode =
false)
const {
515 "MapExtractor::getMap: cannot return sub map in Thyra-style numbering if MapExtractor object is not created using Thyra-style numbered submaps.");
524 for (
size_t i = 0; i <
NumMaps(); i++)
525 if (
getMap(i)->isNodeGlobalElement(gid) ==
true)
529 "getMapIndexForGID: GID " << gid <<
" is not contained by a map in mapextractor." );
539 for (
size_t i = 0; i <
NumMaps(); i++) {
540 const RCP<const Map> map =
getMap(i);
542 ArrayView<const GlobalOrdinal> mapGids = map->getNodeElementList();
543 for (
typename ArrayView< const GlobalOrdinal >::const_iterator it = mapGids.begin(); it != mapGids.end(); it++)
544 if (fullMap->isNodeGlobalElement(*it) ==
false)
559 #define XPETRA_MAPEXTRACTOR_SHORT
static RCP< Import< LocalOrdinal, GlobalOrdinal, Node > > Build(const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &source, const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &target)
Constructor specifying the number of non-zeros for all rows.
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, const Teuchos::RCP< Node > &node=defaultArgNode())
Map constructor with Xpetra-defined contiguous uniform distribution.
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").
Exception throws to report errors in the internal logical of the program.
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 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.
static RCP< Vector > Build(const Teuchos::RCP< const Map > &map, bool zeroOut=true)
Constructor specifying the number of non-zeros for all rows.
#define XPETRA_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
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.
virtual size_t getNumVectors() const =0
Number of columns in the multivector.
virtual Teuchos::ArrayRCP< const Scalar > getData(size_t j) const =0
Const view of the local values in a particular vector of this multivector.