Xpetra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Xpetra_MapExtractor_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 // Ray Tuminaro (rstumin@sandia.gov)
42 //
43 // ***********************************************************************
44 //
45 // @HEADER
46 #ifndef XPETRA_MAPEXTRACTOR_DEF_HPP_
47 #define XPETRA_MAPEXTRACTOR_DEF_HPP_
48 
49 #include <Xpetra_MultiVectorFactory.hpp>
50 #include <Xpetra_VectorFactory.hpp>
51 #include <Xpetra_BlockedMultiVector.hpp>
52 
54 
55 namespace Xpetra {
56 
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));
61 }
62 
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));
67 }
68 
69 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
71  MapExtractor(const Teuchos::RCP<const BlockedMap>& blockedMap)
72  : map_(blockedMap) {}
73 
74 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
76  MapExtractor(const MapExtractor& input) {
77  map_ = Teuchos::rcp(new BlockedMap(*(input.getBlockedMap())));
78 }
79 
80 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
83  map_ = Teuchos::null;
84 }
85 
86 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
88  ExtractVector(const Vector& full, size_t block, Vector& partial) const {
89  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(), std::out_of_range,
90  "ExtractVector: Error, block = " << block << " is too big. The MapExtractor only contains " << map_->getNumMaps() << " partial blocks.");
91  XPETRA_TEST_FOR_EXCEPTION(map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError,
92  "ExtractVector: map_->getMap(" << block << ",false) is null");
93 
94  partial.doImport(full, *(map_->getImporter(block)), Xpetra::INSERT);
95 }
96 
97 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
99  ExtractVector(const MultiVector& full, size_t block, MultiVector& partial) const {
100  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
101  std::out_of_range,
102  "ExtractVector: Error, block = " << block << " is too big. The MapExtractor only contains " << map_->getNumMaps()
103  << " partial blocks.");
105  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "ExtractVector: map_->getMap(" << block << ",false) is null");
106 
107  partial.doImport(full, *(map_->getImporter(block)), Xpetra::INSERT);
108 }
109 
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);
114 }
115 
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);
120 }
121 
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);
126 }
127 
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);
132 }
133 
134 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
135 RCP<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
137  ExtractVector(RCP<const Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& full, size_t block, bool bThyraMode) const {
138  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
139  std::out_of_range,
140  "ExtractVector: Error, block = " << block << " is too big. The MapExtractor only contains " << map_->getNumMaps()
141  << " partial blocks.");
143  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "ExtractVector: map_->getMap(" << block << ",false) is null");
144  // first extract partial vector from full vector (using xpetra style GIDs)
145  const RCP<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> vv = Xpetra::VectorFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(getMap(block, false), false);
146  ExtractVector(*full, block, *vv);
147  if (bThyraMode == false)
148  return vv;
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)); // switch to Thyra-style map
154  return vv;
155 }
156 
157 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
158 RCP<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
160  ExtractVector(RCP<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& full, size_t block, bool bThyraMode) const {
161  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
162  std::out_of_range,
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");
167  // first extract partial vector from full vector (using xpetra style GIDs)
168  const RCP<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> vv = Xpetra::VectorFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(getMap(block, false), false);
169 
170  ExtractVector(*full, block, *vv);
171  if (bThyraMode == false)
172  return vv;
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)); // switch to Thyra-style map
178  return vv;
179 }
180 
181 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
182 RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
184  ExtractVector(RCP<const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& full, size_t block, bool bThyraMode) const {
185  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
186  std::out_of_range,
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) {
193  // standard case: full is not of type BlockedMultiVector
194  // first extract partial vector from full vector (using xpetra style GIDs)
195  const RCP<MultiVector> vv = MultiVectorFactory::Build(getMap(block, false), full->getNumVectors(), false);
196  // if(bThyraMode == false) {
197  // ExtractVector(*full, block, *vv);
198  // return vv;
199  //} else {
200  RCP<const Map> oldThyMapFull = full->getMap(); // temporarely store map of full
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)); // switch to Thyra-style map
210  rcpNonConstFull->replaceMap(oldThyMapFull);
211  return vv;
212  //}
213  } else {
214  // special case: full is of type BlockedMultiVector
215  XPETRA_TEST_FOR_EXCEPTION(map_->getNumMaps() != bfull->getBlockedMap()->getNumMaps(),
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);
221  }
222 }
223 
224 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
225 RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
227  ExtractVector(RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& full, size_t block, bool bThyraMode) const {
228  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
229  std::out_of_range,
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) {
236  // standard case: full is not of type BlockedMultiVector
237  // first extract partial vector from full vector (using xpetra style GIDs)
238  const RCP<MultiVector> vv = MultiVectorFactory::Build(getMap(block, false), full->getNumVectors(), false);
239  // if(bThyraMode == false) {
240  // ExtractVector(*full, block, *vv);
241  // return vv;
242  //} else {
243  RCP<const Map> oldThyMapFull = full->getMap(); // temporarely store map of full
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)); // switch to Thyra-style map
252  full->replaceMap(oldThyMapFull);
253  return vv;
254  //}
255  } else {
256  // special case: full is of type BlockedMultiVector
257  XPETRA_TEST_FOR_EXCEPTION(map_->getNumMaps() != bfull->getBlockedMap()->getNumMaps(),
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);
263  }
264 }
265 
266 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
267 RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
269  ExtractVector(RCP<const Xpetra::BlockedMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& full, size_t block, bool bThyraMode) const {
270  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
271  std::out_of_range,
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");
276  XPETRA_TEST_FOR_EXCEPTION(map_->getNumMaps() != full->getBlockedMap()->getNumMaps(),
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);
282  return vv;
283 }
284 
285 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
286 RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
289  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
290  std::out_of_range,
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");
295  XPETRA_TEST_FOR_EXCEPTION(map_->getNumMaps() != full->getBlockedMap()->getNumMaps(),
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);
301  return vv;
302 }
303 
304 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
306  InsertVector(const Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& partial, size_t block, Vector& full, bool bThyraMode) const {
307  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
308  std::out_of_range,
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");
313  XPETRA_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true,
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.");
317  if (bThyraMode) {
318  // NOTE: the importer objects in the BlockedMap are always using Xpetra GIDs (or Thyra style Xpetra GIDs)
319  // The source map corresponds to the full map (in Xpetra GIDs) starting with GIDs from zero. The GIDs are consecutive in Thyra mode
320  // The target map is the partial map (in the corresponding Xpetra GIDs)
321 
322  // TODO can we skip the Export call in special cases (i.e. Src = Target map, same length, etc...)
323 
324  // store original GIDs (could be Thyra GIDs)
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(); // temporarely store map of partial
328  RCP<const Map> oldThyMapFull = full.getMap(); // temporarely store map of full
329 
330  // check whether getMap(block,false) is identical to target map of importer
331  XPETRA_TEST_FOR_EXCEPTION(map_->getMap(block, false)->isSameAs(*(map_->getImporter(block)->getTargetMap())) == false,
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.");
335 
336  // XPETRA_TEST_FOR_EXCEPTION(full.getMap()->isSameAs(*(map_->getImporter(block)->getSourceMap()))==false,
337  // Xpetra::Exceptions::RuntimeError,
338  // "MapExtractor::InsertVector: InsertVector in Thyra-style mode: Xpetra GIDs of full vector are not identical to source Map of
339  // Importer. This should not be.");
340 
341  rcpNonConstPartial->replaceMap(getMap(block, false)); // temporarely switch to xpetra-style map
342  full.replaceMap(map_->getImporter(block)->getSourceMap()); // temporarely switch to Xpetra GIDs
343 
344  // do the Export
345  full.doExport(*rcpNonConstPartial, *(map_->getImporter(block)), Xpetra::INSERT);
346 
347  // switch back to original maps
348  full.replaceMap(oldThyMapFull); // reset original map (Thyra GIDs)
349  rcpNonConstPartial->replaceMap(oldThyMapPartial); // change map back to original map
350  } else {
351  // Xpetra style numbering
352  full.doExport(partial, *(map_->getImporter(block)), Xpetra::INSERT);
353  }
354 }
355 
356 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
358  InsertVector(const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& partial, size_t block, MultiVector& full, bool bThyraMode) const {
359  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
360  std::out_of_range,
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");
365  XPETRA_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true,
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.");
369  if (bThyraMode) {
370  // NOTE: the importer objects in the BlockedMap are always using Xpetra GIDs (or Thyra style Xpetra GIDs)
371  // The source map corresponds to the full map (in Xpetra GIDs) starting with GIDs from zero. The GIDs are consecutive in Thyra mode
372  // The target map is the partial map (in the corresponding Xpetra GIDs)
373 
374  // TODO can we skip the Export call in special cases (i.e. Src = Target map, same length, etc...)
375 
376  // store original GIDs (could be Thyra GIDs)
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(); // temporarely store map of partial
380  RCP<const Map> oldThyMapFull = full.getMap(); // temporarely store map of full
381 
382  // check whether getMap(block,false) is identical to target map of importer
383  XPETRA_TEST_FOR_EXCEPTION(map_->getMap(block, false)->isSameAs(*(map_->getImporter(block)->getTargetMap())) == false,
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.");
387 
388  // XPETRA_TEST_FOR_EXCEPTION(full.getMap()->isSameAs(*(map_->getImporter(block)->getSourceMap()))==false,
389  // Xpetra::Exceptions::RuntimeError,
390  // "MapExtractor::InsertVector: InsertVector in Thyra-style mode: Xpetra GIDs of full vector are not identical to source Map of
391  // Importer. This should not be.");
392 
393  rcpNonConstPartial->replaceMap(getMap(block, false)); // temporarely switch to xpetra-style map
394  full.replaceMap(map_->getImporter(block)->getSourceMap()); // temporarely switch to Xpetra GIDs
395 
396  // do the Export
397  full.doExport(*rcpNonConstPartial, *(map_->getImporter(block)), Xpetra::INSERT);
398 
399  // switch back to original maps
400  full.replaceMap(oldThyMapFull); // reset original map (Thyra GIDs)
401  rcpNonConstPartial->replaceMap(oldThyMapPartial); // change map back to original map
402  } else {
403  // Xpetra style numbering
404  full.doExport(partial, *(map_->getImporter(block)), Xpetra::INSERT);
405  }
406 }
407 
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);
412 }
413 
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);
418 }
419 
420 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
423  size_t block,
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);
429  else {
431  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "InsertVector: map_->getmap(" << block << ",false) is null");
432 
433 #if 0
434  // WCMCLEN - ETI: MultiVector::setMultiVector() doesn't exist.
435  // WCMCLEN - ETI: but BlockedMultiVector::setMultiVector() does... should this be using bfull.
436  full->setMultiVector(block, partial, bThyraMode);
437 #else
438  throw std::runtime_error("Xpetra::MultiVector::setMultiVector() doesn't exist in " + std::string(__FILE__) + ":" + std::to_string(__LINE__));
439 #endif
440  }
441 }
442 
443 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
446  size_t block,
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);
452  else {
454  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "InsertVector: map_->getmap(" << block << ",false) is null");
455 
456  bfull->setMultiVector(block, partial, bThyraMode);
457  }
458 }
459 
460 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
463  size_t block,
465  bool bThyraMode) const {
467  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "InsertVector: map_->getmap(" << block << ",false) is null");
468 
469  full->setMultiVector(block, partial, bThyraMode);
470 }
471 
472 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
475  size_t block,
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);
481 }
482 
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 {
487  XPETRA_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true,
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.");
491  // TODO check whether this can return a blocked multivector
493 }
494 
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 {
499  XPETRA_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true,
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.");
503  // TODO check whether this can return a blocked multivector
504  return MultiVectorFactory::Build(getMap(i, bThyraMode), numvec, bZero);
505 }
506 
508 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
510  getThyraMode() const {
511  return map_->getThyraMode();
512 }
513 
514 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
515 size_t
517  NumMaps() const {
518  return map_->getNumMaps();
519 }
520 
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);
526 }
527 
528 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
529 const RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
531  getMap() const {
532  return map_;
533 }
534 
535 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
536 const RCP<const Xpetra::BlockedMap<LocalOrdinal, GlobalOrdinal, Node>>
538  getBlockedMap() const {
539  return map_;
540 }
541 
542 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
543 const RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
545  getFullMap() const {
546  return map_->getFullMap();
547 }
548 
549 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
550 size_t
552  getMapIndexForGID(GlobalOrdinal gid) const {
553  return map_->getMapIndexForGID(gid);
554 }
555 
556 } // namespace Xpetra
557 
558 #endif /* XPETRA_MAPEXTRACTOR_DEF_HPP_ */
virtual void replaceMap(const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node >> &map)=0
size_t getMapIndexForGID(GlobalOrdinal gid) const
returns map index in map extractor which contains GID
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 (&quot;forward mode&quot;).
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.
const RCP< const Map > getFullMap() const
the full map
const RCP< const Xpetra::BlockedMap< LocalOrdinal, GlobalOrdinal, Node > > getBlockedMap() const
get the underlying BlockedMap object (as BlockedMap)
virtual ~MapExtractor()
Destructor.
MapExtractor(const RCP< const Map > &fullmap, const std::vector< RCP< const Map >> &maps, bool bThyraMode=false)
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.
bool getThyraMode() const
returns true, if sub maps are stored in Thyra-style numbering
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 (&quot;forward mode&quot;).
RCP< Vector > getVector(size_t i, bool bThyraMode=false, bool bZero=true) const
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const =0
The Map describing the parallel distribution of this object.
void InsertVector(const Vector &partial, size_t block, Vector &full, bool bThyraMode=false) const
const RCP< const Map > getMap() const
get the underlying BlockedMap object (as Map)
void ExtractVector(const Vector &full, size_t block, Vector &partial) const
#define XPETRA_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
size_t NumMaps() const
number of partial maps