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 
58  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
60  MapExtractor(const RCP<const Map>& fullmap, const std::vector<RCP<const Map> >& maps, bool bThyraMode)
61  {
62  map_ = Teuchos::rcp(new BlockedMap(fullmap, maps, bThyraMode));
63  }
64 
65  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
67  MapExtractor(const std::vector<RCP<const Map> >& maps, const std::vector<RCP<const Map> >& thyramaps)
68  {
69  map_ = Teuchos::rcp(new BlockedMap(maps, thyramaps));
70  }
71 
72  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
74  MapExtractor(const Teuchos::RCP<const BlockedMap>& map)
75  : map_(map)
76  {}
77 
78 
79  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
82  {
83  map_ = Teuchos::rcp(new BlockedMap(*(input.getBlockedMap())));
84  }
85 
86 
87  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
90  {
91  map_ = Teuchos::null;
92  }
93 
94 
95  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
96  void
98  ExtractVector(const Vector& full, size_t block, Vector& partial) const
99  {
100  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(), std::out_of_range,
101  "ExtractVector: Error, block = " << block << " is too big. The MapExtractor only contains " << map_->getNumMaps() << " partial blocks.");
102  XPETRA_TEST_FOR_EXCEPTION(map_->getMap(block,false) == null, Xpetra::Exceptions::RuntimeError,
103  "ExtractVector: map_->getMap(" << block << ",false) is null");
104 
105  partial.doImport(full, *(map_->getImporter(block)), Xpetra::INSERT);
106  }
107 
108 
109  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
110  void
112  ExtractVector(const MultiVector& full, size_t block, MultiVector& partial) const
113  {
114  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
115  std::out_of_range,
116  "ExtractVector: Error, block = " << block << " is too big. The MapExtractor only contains " << map_->getNumMaps()
117  << " partial blocks.");
119  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "ExtractVector: map_->getMap(" << block << ",false) is null");
120 
121  partial.doImport(full, *(map_->getImporter(block)), Xpetra::INSERT);
122  }
123 
124 
125  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
126  void
128  ExtractVector(RCP<const Vector>& full, size_t block, RCP<Vector>& partial) const
129  {
130  ExtractVector(*full, block, *partial);
131  }
132 
133 
134  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
135  void
137  ExtractVector(RCP<Vector>& full, size_t block, RCP<Vector>& partial) const
138  {
139  ExtractVector(*full, block, *partial);
140  }
141 
142 
143  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
144  void
146  ExtractVector(RCP<const MultiVector>& full, size_t block, RCP<MultiVector>& partial) const
147  {
148  ExtractVector(*full, block, *partial);
149  }
150 
151 
152  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
153  void
155  ExtractVector(RCP<MultiVector>& full, size_t block, RCP<MultiVector>& partial) const
156  {
157  ExtractVector(*full, block, *partial);
158  }
159 
160 
161  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
162  RCP<Xpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
164  ExtractVector(RCP<const Xpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >& full, size_t block, bool bThyraMode) const
165  {
166  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
167  std::out_of_range,
168  "ExtractVector: Error, block = " << block << " is too big. The MapExtractor only contains " << map_->getNumMaps()
169  << " partial blocks.");
171  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "ExtractVector: map_->getMap(" << block << ",false) is null");
172  // first extract partial vector from full vector (using xpetra style GIDs)
173  const RCP<Xpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > vv = Xpetra::VectorFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Build(getMap(block, false), false);
174  ExtractVector(*full, block, *vv);
175  if(bThyraMode == false)
176  return vv;
177  TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true,
178  Xpetra::Exceptions::RuntimeError,
179  "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been "
180  "created using Thyra-style numbered submaps.");
181  vv->replaceMap(getMap(block, true)); // switch to Thyra-style map
182  return vv;
183  }
184 
185 
186  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
187  RCP<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
189  ExtractVector(RCP<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >& full, size_t block, bool bThyraMode) const
190  {
191  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
192  std::out_of_range,
193  "ExtractVector: Error, block = " << block << " is too big. The MapExtractor only contains " << map_->getNumMaps()
194  << " partial blocks.");
196  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "ExtractVector: map_->getmap(" << block << ",false) is null");
197  // first extract partial vector from full vector (using xpetra style GIDs)
198 const RCP<Xpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > vv = Xpetra::VectorFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Build(getMap(block, false), false);
199 
200  ExtractVector(*full, block, *vv);
201  if(bThyraMode == false)
202  return vv;
203  TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true,
204  Xpetra::Exceptions::RuntimeError,
205  "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been "
206  "created using Thyra-style numbered submaps.");
207  vv->replaceMap(getMap(block, true)); // switch to Thyra-style map
208  return vv;
209  }
210 
211 
212  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
213  RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
215  ExtractVector(RCP<const Xpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >& full, size_t block, bool bThyraMode) const
216  {
217  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
218  std::out_of_range,
219  "ExtractVector: Error, block = " << block << " is too big. The MapExtractor only contains " << map_->getNumMaps()
220  << " partial blocks.");
222  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "ExtractVector: map_->getmap(" << block << ",false) is null");
223  RCP<const BlockedMultiVector> bfull = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(full);
224  if(bfull.is_null() == true)
225  {
226  // standard case: full is not of type BlockedMultiVector
227  // first extract partial vector from full vector (using xpetra style GIDs)
228  const RCP<MultiVector> vv = MultiVectorFactory::Build(getMap(block, false), full->getNumVectors(), false);
229  // if(bThyraMode == false) {
230  // ExtractVector(*full, block, *vv);
231  // return vv;
232  //} else {
233  RCP<const Map> oldThyMapFull = full->getMap(); // temporarely store map of full
234  RCP<MultiVector> rcpNonConstFull = Teuchos::rcp_const_cast<MultiVector>(full);
235  rcpNonConstFull->replaceMap(map_->getImporter(block)->getSourceMap());
236  ExtractVector(*rcpNonConstFull, block, *vv);
237  TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true,
238  Xpetra::Exceptions::RuntimeError,
239  "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been "
240  "created using Thyra-style numbered submaps.");
241  if(bThyraMode == true)
242  vv->replaceMap(getMap(block, true)); // switch to Thyra-style map
243  rcpNonConstFull->replaceMap(oldThyMapFull);
244  return vv;
245  //}
246  }
247  else
248  {
249  // special case: full is of type BlockedMultiVector
250  XPETRA_TEST_FOR_EXCEPTION(map_->getNumMaps() != bfull->getBlockedMap()->getNumMaps(),
251  Xpetra::Exceptions::RuntimeError,
252  "ExtractVector: Number of blocks in map extractor is " << map_->getNumMaps() << " but should be "
253  << bfull->getBlockedMap()->getNumMaps()
254  << " (number of blocks in BlockedMultiVector)");
255  return bfull->getMultiVector(block, bThyraMode);
256  }
257  }
258 
259 
260  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
261  RCP<Xpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
263  ExtractVector(RCP<Xpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >& full, size_t block, bool bThyraMode) const
264  {
265  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
266  std::out_of_range,
267  "ExtractVector: Error, block = " << block << " is too big. The MapExtractor only contains " << map_->getNumMaps()
268  << " partial blocks.");
270  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "ExtractVector: map_->getmap(" << block << ",false) is null");
271  RCP<BlockedMultiVector> bfull = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(full);
272  if(bfull.is_null() == true)
273  {
274  // standard case: full is not of type BlockedMultiVector
275  // first extract partial vector from full vector (using xpetra style GIDs)
276  const RCP<MultiVector> vv = MultiVectorFactory::Build(getMap(block, false), full->getNumVectors(), false);
277  // if(bThyraMode == false) {
278  // ExtractVector(*full, block, *vv);
279  // return vv;
280  //} else {
281  RCP<const Map> oldThyMapFull = full->getMap(); // temporarely store map of full
282  full->replaceMap(map_->getImporter(block)->getSourceMap());
283  ExtractVector(*full, block, *vv);
284  TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true,
285  Xpetra::Exceptions::RuntimeError,
286  "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been "
287  "created using Thyra-style numbered submaps.");
288  if(bThyraMode == true)
289  vv->replaceMap(getMap(block, true)); // switch to Thyra-style map
290  full->replaceMap(oldThyMapFull);
291  return vv;
292  //}
293  }
294  else
295  {
296  // special case: full is of type BlockedMultiVector
297  XPETRA_TEST_FOR_EXCEPTION(map_->getNumMaps() != bfull->getBlockedMap()->getNumMaps(),
298  Xpetra::Exceptions::RuntimeError,
299  "ExtractVector: Number of blocks in map extractor is " << map_->getNumMaps() << " but should be "
300  << bfull->getBlockedMap()->getNumMaps()
301  << " (number of blocks in BlockedMultiVector)");
302  return bfull->getMultiVector(block, bThyraMode);
303  }
304  }
305 
306 
307  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
308  RCP<Xpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
310  ExtractVector(RCP<const Xpetra::BlockedMultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >& full, size_t block, bool bThyraMode) const
311  {
312  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
313  std::out_of_range,
314  "ExtractVector: Error, block = " << block << " is too big. The MapExtractor only contains " << map_->getNumMaps()
315  << " partial blocks.");
317  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "ExtractVector: map_->getmap(" << block << ",false) is null");
318  XPETRA_TEST_FOR_EXCEPTION(map_->getNumMaps() != full->getBlockedMap()->getNumMaps(),
319  Xpetra::Exceptions::RuntimeError,
320  "ExtractVector: Number of blocks in map extractor is " << map_->getNumMaps() << " but should be "
321  << full->getBlockedMap()->getNumMaps()
322  << " (number of blocks in BlockedMultiVector)");
323  Teuchos::RCP<MultiVector> vv = full->getMultiVector(block, bThyraMode);
324  return vv;
325  }
326 
327 
328  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
329  RCP<Xpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
331  ExtractVector(RCP<Xpetra::BlockedMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& full, size_t block, bool bThyraMode) const
332  {
333  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
334  std::out_of_range,
335  "ExtractVector: Error, block = " << block << " is too big. The MapExtractor only contains " << map_->getNumMaps()
336  << " partial blocks.");
338  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "ExtractVector: map_->getmap(" << block << ",false) is null");
339  XPETRA_TEST_FOR_EXCEPTION(map_->getNumMaps() != full->getBlockedMap()->getNumMaps(),
340  Xpetra::Exceptions::RuntimeError,
341  "ExtractVector: Number of blocks in map extractor is " << map_->getNumMaps() << " but should be "
342  << full->getBlockedMap()->getNumMaps()
343  << " (number of blocks in BlockedMultiVector)");
344  Teuchos::RCP<MultiVector> vv = full->getMultiVector(block, bThyraMode);
345  return vv;
346  }
347 
348 
349  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
350  void
352  InsertVector(const Xpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& partial, size_t block, Vector& full, bool bThyraMode) const
353  {
354  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
355  std::out_of_range,
356  "ExtractVector: Error, block = " << block << " is too big. The MapExtractor only contains " << map_->getNumMaps()
357  << " partial blocks.");
359  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "ExtractVector: map_->getmap(" << block << ",false) is null");
360  XPETRA_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true,
361  Xpetra::Exceptions::RuntimeError,
362  "MapExtractor::InsertVector: InsertVector in Thyra-style numbering only possible if MapExtractor has been created "
363  "using Thyra-style numbered submaps.");
364  if(bThyraMode)
365  {
366  // NOTE: the importer objects in the BlockedMap are always using Xpetra GIDs (or Thyra style Xpetra GIDs)
367  // The source map corresponds to the full map (in Xpetra GIDs) starting with GIDs from zero. The GIDs are consecutive in Thyra mode
368  // The target map is the partial map (in the corresponding Xpetra GIDs)
369 
370  // TODO can we skip the Export call in special cases (i.e. Src = Target map, same length, etc...)
371 
372  // store original GIDs (could be Thyra GIDs)
373  RCP<const MultiVector> rcpPartial = Teuchos::rcpFromRef(partial);
374  RCP<MultiVector> rcpNonConstPartial = Teuchos::rcp_const_cast<MultiVector>(rcpPartial);
375  RCP<const Map> oldThyMapPartial = rcpNonConstPartial->getMap(); // temporarely store map of partial
376  RCP<const Map> oldThyMapFull = full.getMap(); // temporarely store map of full
377 
378  // check whether getMap(block,false) is identical to target map of importer
379  XPETRA_TEST_FOR_EXCEPTION(map_->getMap(block, false)->isSameAs(*(map_->getImporter(block)->getTargetMap())) == false,
380  Xpetra::Exceptions::RuntimeError,
381  "MapExtractor::InsertVector: InsertVector in Thyra-style mode: Xpetra GIDs of partial vector are not identical "
382  "to target Map of Importer. This should not be.");
383 
384  // XPETRA_TEST_FOR_EXCEPTION(full.getMap()->isSameAs(*(map_->getImporter(block)->getSourceMap()))==false,
385  // Xpetra::Exceptions::RuntimeError,
386  // "MapExtractor::InsertVector: InsertVector in Thyra-style mode: Xpetra GIDs of full vector are not identical to source Map of
387  // Importer. This should not be.");
388 
389  rcpNonConstPartial->replaceMap(getMap(block, false)); // temporarely switch to xpetra-style map
390  full.replaceMap(map_->getImporter(block)->getSourceMap()); // temporarely switch to Xpetra GIDs
391 
392  // do the Export
393  full.doExport(*rcpNonConstPartial, *(map_->getImporter(block)), Xpetra::INSERT);
394 
395  // switch back to original maps
396  full.replaceMap(oldThyMapFull); // reset original map (Thyra GIDs)
397  rcpNonConstPartial->replaceMap(oldThyMapPartial); // change map back to original map
398  }
399  else
400  {
401  // Xpetra style numbering
402  full.doExport(partial, *(map_->getImporter(block)), Xpetra::INSERT);
403  }
404  }
405 
406 
407  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
408  void
410  InsertVector(const Xpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& partial, size_t block, MultiVector& full, bool bThyraMode) const
411  {
412  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(),
413  std::out_of_range,
414  "ExtractVector: Error, block = " << block << " is too big. The MapExtractor only contains " << map_->getNumMaps()
415  << " partial blocks.");
417  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "ExtractVector: map_->getmap(" << block << ",false) is null");
418  XPETRA_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true,
419  Xpetra::Exceptions::RuntimeError,
420  "MapExtractor::InsertVector: InsertVector in Thyra-style numbering only possible if MapExtractor has been created "
421  "using Thyra-style numbered submaps.");
422  if(bThyraMode)
423  {
424  // NOTE: the importer objects in the BlockedMap are always using Xpetra GIDs (or Thyra style Xpetra GIDs)
425  // The source map corresponds to the full map (in Xpetra GIDs) starting with GIDs from zero. The GIDs are consecutive in Thyra mode
426  // The target map is the partial map (in the corresponding Xpetra GIDs)
427 
428  // TODO can we skip the Export call in special cases (i.e. Src = Target map, same length, etc...)
429 
430  // store original GIDs (could be Thyra GIDs)
431  RCP<const MultiVector> rcpPartial = Teuchos::rcpFromRef(partial);
432  RCP<MultiVector> rcpNonConstPartial = Teuchos::rcp_const_cast<MultiVector>(rcpPartial);
433  RCP<const Map> oldThyMapPartial = rcpNonConstPartial->getMap(); // temporarely store map of partial
434  RCP<const Map> oldThyMapFull = full.getMap(); // temporarely store map of full
435 
436  // check whether getMap(block,false) is identical to target map of importer
437  XPETRA_TEST_FOR_EXCEPTION(map_->getMap(block, false)->isSameAs(*(map_->getImporter(block)->getTargetMap())) == false,
438  Xpetra::Exceptions::RuntimeError,
439  "MapExtractor::InsertVector: InsertVector in Thyra-style mode: Xpetra GIDs of partial vector are not identical "
440  "to target Map of Importer. This should not be.");
441 
442  // XPETRA_TEST_FOR_EXCEPTION(full.getMap()->isSameAs(*(map_->getImporter(block)->getSourceMap()))==false,
443  // Xpetra::Exceptions::RuntimeError,
444  // "MapExtractor::InsertVector: InsertVector in Thyra-style mode: Xpetra GIDs of full vector are not identical to source Map of
445  // Importer. This should not be.");
446 
447  rcpNonConstPartial->replaceMap(getMap(block, false)); // temporarely switch to xpetra-style map
448  full.replaceMap(map_->getImporter(block)->getSourceMap()); // temporarely switch to Xpetra GIDs
449 
450  // do the Export
451  full.doExport(*rcpNonConstPartial, *(map_->getImporter(block)), Xpetra::INSERT);
452 
453  // switch back to original maps
454  full.replaceMap(oldThyMapFull); // reset original map (Thyra GIDs)
455  rcpNonConstPartial->replaceMap(oldThyMapPartial); // change map back to original map
456  }
457  else
458  {
459  // Xpetra style numbering
460  full.doExport(partial, *(map_->getImporter(block)), Xpetra::INSERT);
461  }
462  }
463 
464 
465 
466  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
467  void
469  InsertVector(RCP<const Vector> partial, size_t block, RCP<Vector> full, bool bThyraMode) const
470  {
471  InsertVector(*partial, block, *full, bThyraMode);
472  }
473 
474 
475  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
476  void
478  InsertVector(RCP<Vector> partial, size_t block, RCP<Vector> full, bool bThyraMode) const
479  {
480  InsertVector(*partial, block, *full, bThyraMode);
481  }
482 
483 
484  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
485  void
488  size_t block,
490  bool bThyraMode) const
491  {
492  RCP<BlockedMultiVector> bfull = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(full);
493  if(bfull.is_null() == true)
494  InsertVector(*partial, block, *full, bThyraMode);
495  else
496  {
498  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "InsertVector: map_->getmap(" << block << ",false) is null");
499 
500  #if 0
501  // WCMCLEN - ETI: MultiVector::setMultiVector() doesn't exist.
502  // WCMCLEN - ETI: but BlockedMultiVector::setMultiVector() does... should this be using bfull.
503  full->setMultiVector(block, partial, bThyraMode);
504  #else
505  throw std::runtime_error("Xpetra::MultiVector::setMultiVector() doesn't exist.");
506  #endif
507  }
508  }
509 
510 
511  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
512  void
515  size_t block,
517  bool bThyraMode) const
518  {
519  RCP<BlockedMultiVector> bfull = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(full);
520  if(bfull.is_null() == true)
521  InsertVector(*partial, block, *full, bThyraMode);
522  else
523  {
525  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "InsertVector: map_->getmap(" << block << ",false) is null");
526 
527  bfull->setMultiVector(block, partial, bThyraMode);
528  }
529  }
530 
531 
532  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
533  void
536  size_t block,
538  bool bThyraMode) const
539  {
541  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "InsertVector: map_->getmap(" << block << ",false) is null");
542 
543  full->setMultiVector(block, partial, bThyraMode);
544  }
545 
546 
547  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
548  void
551  size_t block,
553  bool bThyraMode ) const
554  {
556  map_->getMap(block, false) == null, Xpetra::Exceptions::RuntimeError, "InsertVector: map_->getmap(" << block << ",false) is null");
557  full->setMultiVector(block, partial, bThyraMode);
558  }
559 
560 
561  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
562  RCP<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
564  getVector(size_t i, bool bThyraMode, bool bZero) const
565  {
566  XPETRA_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true,
567  Xpetra::Exceptions::RuntimeError,
568  "MapExtractor::getVector: getVector in Thyra-style numbering only possible if MapExtractor has been created using "
569  "Thyra-style numbered submaps.");
570  // TODO check whether this can return a blocked multivector
572  }
573 
574 
575  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
576  RCP<Xpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>>
578  getVector(size_t i, size_t numvec, bool bThyraMode, bool bZero) const
579  {
580  XPETRA_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true,
581  Xpetra::Exceptions::RuntimeError,
582  "MapExtractor::getVector: getVector in Thyra-style numbering only possible if MapExtractor has been created using "
583  "Thyra-style numbered submaps.");
584  // TODO check whether this can return a blocked multivector
585  return MultiVectorFactory::Build(getMap(i, bThyraMode), numvec, bZero);
586  }
587 
589  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
590  bool
593  {
594  return map_->getThyraMode();
595  }
596 
597 
598  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
599  size_t
601  NumMaps() const
602  {
603  return map_->getNumMaps();
604  }
605 
606 
607  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
608  const RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node>>
610  getMap(size_t i, bool bThyraMode) const
611  {
612  return map_->getMap(i, bThyraMode);
613  }
614 
615 
616  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
617  const RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node>>
619  getMap() const
620  {
621  return map_;
622  }
623 
624 
625  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
626  const RCP<const Xpetra::BlockedMap<LocalOrdinal,GlobalOrdinal,Node>>
629  {
630  return map_;
631  }
632 
633 
634  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
635  const RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node>>
637  getFullMap() const
638  {
639  return map_->getFullMap();
640  }
641 
642 
643  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
644  size_t
646  getMapIndexForGID(GlobalOrdinal gid) const
647  {
648  return map_->getMapIndexForGID(gid);
649  }
650 
651 
652 } // namespace Xpetra
653 
654 #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< 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.
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.
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)
MapExtractor(const RCP< const Map > &fullmap, const std::vector< RCP< const Map > > &maps, bool bThyraMode=false)
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
void ExtractVector(RCP< Vector > &full, size_t block, RCP< Vector > &partial) const