Xpetra_MapExtractor.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_HPP_
47 #define XPETRA_MAPEXTRACTOR_HPP_
48 
49 #include <map>
50 
51 #include <iostream>
52 
53 #include <Teuchos_RCP.hpp>
54 #include <Teuchos_Describable.hpp>
55 #include <Xpetra_Import.hpp>
56 #include <Xpetra_Map.hpp>
57 
58 #include "Xpetra_Import.hpp"
59 #include "Xpetra_ImportFactory.hpp"
60 #include "Xpetra_MapFactory.hpp"
61 #include "Xpetra_MultiVector.hpp"
63 #include "Xpetra_Vector.hpp"
64 #include "Xpetra_VectorFactory.hpp"
65 
66 
67 namespace Xpetra {
68 
69  template <class Scalar /*= MultiVector<>::scalar_type*/,
70  class LocalOrdinal /*= Map<>::local_ordinal_type*/,
71  class GlobalOrdinal /*= typename Map<LocalOrdinal>::global_ordinal_type*/,
72  class Node /*= typename Map<LocalOrdinal, GlobalOrdinal>::node_type*/>
73  class MapExtractor : public Teuchos::Describable {
74  public:
75  typedef Scalar scalar_type;
76  typedef LocalOrdinal local_ordinal_type;
77  typedef GlobalOrdinal global_ordinal_type;
78  typedef Node node_type;
79 
80  private:
81 #undef XPETRA_MAPEXTRACTOR_SHORT
82 #include "Xpetra_UseShortNames.hpp"
83 
84  public:
85 
87  MapExtractor(const RCP<const Map>& fullmap, const std::vector<RCP<const Map> >& maps, bool bThyraMode = false) {
88  bThyraMode_ = bThyraMode;
89 
90  if(bThyraMode == false) {
91  // use Xpetra-style numbering for sub-block maps
92  // That is, all sub-block maps have unique GIDs which may not be contiguous and start with GIDs different than zero.
93 
94  // plausibility check
95  size_t numAllElements = 0;
96  for(size_t v = 0; v < maps.size(); ++v) {
97  numAllElements += maps[v]->getGlobalNumElements();
98  }
99  TEUCHOS_TEST_FOR_EXCEPTION(fullmap->getGlobalNumElements() != numAllElements, std::logic_error,
100  "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.");
101 
102  fullmap_ = fullmap;
103  maps_ = maps;
104  } else {
105  std::cout << "Create Map Extractor in Thyra Mode!!! " << std::endl;
106  // use Thyra-style numbering for sub-block maps
107  // That is, all sub-block maps start with zero as GID and are contiguous
108 
109  // plausibility check
110  for(size_t v = 0; v < maps.size(); ++v) {
111  TEUCHOS_TEST_FOR_EXCEPTION(maps[v]->getMinAllGlobalIndex() != 0, std::logic_error,
112  "logic error. When using Thyra-style numbering all sub-block maps must start with zero as GID.");
113  }
114 
115  // store submaps in Thyra-style ordering
116  thyraMaps_ = maps;
117 
118  // get offsets
119  std::vector<GlobalOrdinal> gidOffsets(maps.size(),0);
120  for(size_t v = 1; v < maps.size(); ++v) {
121  gidOffsets[v] = maps[v-1]->getMaxAllGlobalIndex() + gidOffsets[v-1] + 1;
122  }
123 
124  // build submaps
125  maps_.resize(maps.size());
126  std::vector<GlobalOrdinal> fullMapGids;
128  for(size_t v = 0; v < maps.size(); ++v) {
129  std::vector<GlobalOrdinal> subMapGids(maps[v]->getNodeNumElements(),0);
130  for (LocalOrdinal l = 0; l < Teuchos::as<LocalOrdinal>(maps[v]->getNodeNumElements()); ++l) {
131  GlobalOrdinal myGid = maps[v]->getGlobalElement(l);
132  subMapGids[l] = myGid + gidOffsets[v];
133  fullMapGids.push_back(myGid + gidOffsets[v]);
134  }
135  //std::sort(subMapGids.begin(), subMapGids.end());
136  //subMapGids.erase(std::unique(subMapGids.begin(), subMapGids.end()), subMapGids.end());
137 
138  Teuchos::ArrayView<GlobalOrdinal> subMapGidsView(&subMapGids[0], subMapGids.size());
139  Teuchos::RCP<Map> mySubMap = Xpetra::MapFactory<LocalOrdinal,GlobalOrdinal,Node>::Build(maps[v]->lib(), INVALID, subMapGidsView, maps[v]->getIndexBase(), maps[v]->getComm());
140  maps_[v] = mySubMap;
141  }
142 
143  //const GO INVALID = Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid();
144  //std::sort(coarseMapGids.begin(), coarseMapGids.end());
145  //coarseMapGids.erase(std::unique(coarseMapGids.begin(), coarseMapGids.end()), coarseMapGids.end());
146  //Teuchos::ArrayView<GO> coarseMapGidsView(&coarseMapGids[0], coarseMapGids.size());
147  //std::sort(fullMapGids.begin(), fullMapGids.end());
148  //fullMapGids.erase(std::unique(fullMapGids.begin(), fullMapGids.end()), fullMapGids.end());
149 
150  Teuchos::ArrayView<GlobalOrdinal> fullMapGidsView(&fullMapGids[0], fullMapGids.size());
151  fullmap_ = MapFactory::Build(fullmap->lib(), INVALID, fullMapGidsView, fullmap->getIndexBase(), fullmap->getComm());
152 
153  // plausibility check
154  size_t numAllElements = 0;
155  for(size_t v = 0; v < maps_.size(); ++v) {
156  numAllElements += maps_[v]->getGlobalNumElements();
157  }
158  TEUCHOS_TEST_FOR_EXCEPTION(fullmap_->getGlobalNumElements() != numAllElements, std::logic_error,
159  "logic error. full map and sub maps have not same number of elements. This cannot be. Please report the bug to the Xpetra developers!");
160  }
161 
162  // build importers for sub maps
163  importers_.resize(maps_.size());
164  for (unsigned i = 0; i < maps_.size(); ++i)
165  if (maps[i] != null)
167  TEUCHOS_TEST_FOR_EXCEPTION(CheckConsistency() == false, std::logic_error,
168  "logic error. full map and sub maps are inconsistently distributed over the processors.");
169 
170  }
171 
174  void ExtractVector(const Vector& full, size_t block, Vector& partial) const {
176  "ExtractVector: maps_[" << block << "] is null");
177 
178  partial.doImport(full, *importers_[block], Xpetra::INSERT);
179  }
180  void ExtractVector(const MultiVector& full, size_t block, MultiVector& partial) const {
182  "ExtractVector: maps_[" << block << "] is null");
183  partial.doImport(full, *importers_[block], Xpetra::INSERT);
184  }
185  void ExtractVector(RCP<const Vector>& full, size_t block, RCP< Vector>& partial) const { ExtractVector(*full, block, *partial); }
186  void ExtractVector(RCP< Vector>& full, size_t block, RCP< Vector>& partial) const { ExtractVector(*full, block, *partial); }
187  void ExtractVector(RCP<const MultiVector>& full, size_t block, RCP<MultiVector>& partial) const { ExtractVector(*full, block, *partial); }
188  void ExtractVector(RCP< MultiVector>& full, size_t block, RCP<MultiVector>& partial) const { ExtractVector(*full, block, *partial); }
189 
190  RCP< Vector> ExtractVector(RCP<const Vector>& full, size_t block, bool bThyraMode = false) const {
192  "ExtractVector: maps_[" << block << "] is null");
193  // extract sub vector
194  const RCP<Vector> xpetraVec = VectorFactory::Build(getMap(block,false), true);
195  ExtractVector(*full, block, *xpetraVec);
196  if(bThyraMode == false) return xpetraVec;
198  "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
199  const RCP<Vector> thyraVec = VectorFactory::Build(getMap(block,true), true);
200  // TODO introduce Kokkos version of this.
201  Teuchos::ArrayRCP<Scalar> thyraVecData = thyraVec->getDataNonConst(0);
202  Teuchos::ArrayRCP<const Scalar> xpetraVecData = xpetraVec->getData(0);
203 
204  for(size_t i=0; i < xpetraVec->getLocalLength(); i++) {
205  thyraVecData[i] = xpetraVecData[i];
206  }
207  return thyraVec;
208  }
209  RCP< Vector> ExtractVector(RCP< Vector>& full, size_t block, bool bThyraMode = false) const {
211  "ExtractVector: maps_[" << block << "] is null");
212  const RCP<Vector> xpetraVec = VectorFactory::Build(getMap(block,false), true);
213  ExtractVector(*full, block, *xpetraVec);
214  if(bThyraMode == false) return xpetraVec;
216  "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
217  const RCP<Vector> thyraVec = VectorFactory::Build(getMap(block,true), true);
218  // TODO introduce Kokkos version of this.
219  Teuchos::ArrayRCP<Scalar> thyraVecData = thyraVec->getDataNonConst(0);
220  Teuchos::ArrayRCP<const Scalar> xpetraVecData = xpetraVec->getData(0);
221 
222  for(size_t i=0; i < xpetraVec->getLocalLength(); i++) {
223  thyraVecData[i] = xpetraVecData[i];
224  }
225  return thyraVec;
226  }
227  RCP<MultiVector> ExtractVector(RCP<const MultiVector>& full, size_t block, bool bThyraMode = false) const {
229  "ExtractVector: maps_[" << block << "] is null");
230  const RCP<MultiVector> xpetraVec = MultiVectorFactory::Build(getMap(block,false), true);
231  ExtractVector(*full, block, *xpetraVec);
232  if(bThyraMode == false) return xpetraVec;
234  "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
235  const RCP<MultiVector> thyraVec = MultiVectorFactory::Build(getMap(block,true), xpetraVec->getNumVectors(), true);
236  // TODO introduce Kokkos version of this.
237  for(size_t k=0; k < xpetraVec->getNumVectors(); k++) {
238  Teuchos::ArrayRCP<Scalar> thyraVecData = thyraVec->getDataNonConst(k);
239  Teuchos::ArrayRCP<const Scalar> xpetraVecData = xpetraVec->getData(k);
240  for(size_t i=0; i < xpetraVec->getLocalLength(); i++) {
241  thyraVecData[i] = xpetraVecData[i];
242  }
243  }
244  return thyraVec;
245  }
246  RCP<MultiVector> ExtractVector(RCP< MultiVector>& full, size_t block, bool bThyraMode = false) const {
248  "ExtractVector: maps_[" << block << "] is null");
249  const RCP<MultiVector> xpetraVec = MultiVectorFactory::Build(getMap(block,false), true);
250  ExtractVector(*full, block, *xpetraVec);
251  if(bThyraMode == false) return xpetraVec;
253  "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
254  const RCP<MultiVector> thyraVec = MultiVectorFactory::Build(getMap(block,true), xpetraVec->getNumVectors(), true);
255  // TODO introduce Kokkos version of this.
256  for(size_t k=0; k < xpetraVec->getNumVectors(); k++) {
257  Teuchos::ArrayRCP<Scalar> thyraVecData = thyraVec->getDataNonConst(k);
258  Teuchos::ArrayRCP<const Scalar> xpetraVecData = xpetraVec->getData(k);
259  for(size_t i=0; i < xpetraVec->getLocalLength(); i++) {
260  thyraVecData[i] = xpetraVecData[i];
261  }
262  }
263  return thyraVec;
264  }
266 
269  void InsertVector(const Vector& partial, size_t block, Vector& full, bool bThyraMode = false) const {
271  "InsertVector: maps_[" << block << "] is null");
273  "MapExtractor::InsertVector: InsertVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
274  if(bThyraMode) {
275  const RCP<Vector> xpetraVec = VectorFactory::Build(getMap(block,false), true); // get sub vector in xpetra-style numbering
276  // TODO introduce Kokkos version of this.
277  Teuchos::ArrayRCP<const Scalar> thyraVecData = partial.getData(0);
278  Teuchos::ArrayRCP<Scalar> xpetraVecData = xpetraVec->getDataNonConst(0);
279  for(size_t i=0; i < xpetraVec->getLocalLength(); i++) {
280  xpetraVecData[i] = thyraVecData[i];
281  }
282  full.doExport(*xpetraVec, *importers_[block], Xpetra::INSERT);
283  } else {
284  // Xpetra style numbering
285  full.doExport(partial, *importers_[block], Xpetra::INSERT);
286  }
287  }
288  void InsertVector(const MultiVector& partial, size_t block, MultiVector& full, bool bThyraMode = false) const {
290  "InsertVector: maps_[" << block << "] is null");
292  "MapExtractor::InsertVector: InsertVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
293  if(bThyraMode) {
294  const RCP<MultiVector> xpetraVec = MultiVectorFactory::Build(getMap(block,false), partial.getNumVectors(), true); // get sub vector in xpetra-style numbering
295  // TODO introduce Kokkos version of this.
296  for(size_t k=0; k < partial.getNumVectors(); k++) {
297  Teuchos::ArrayRCP<const Scalar> thyraVecData = partial.getData(k);
298  Teuchos::ArrayRCP<Scalar> xpetraVecData = xpetraVec->getDataNonConst(k);
299  for(size_t i=0; i < xpetraVec->getLocalLength(); i++) {
300  xpetraVecData[i] = thyraVecData[i];
301  }
302  }
303  full.doExport(*xpetraVec, *importers_[block], Xpetra::INSERT);
304  } else {
305  // Xpetra style numbering
306  full.doExport(partial, *importers_[block], Xpetra::INSERT);
307  }
308  }
309 
310  void InsertVector(RCP<const Vector>& partial, size_t block, RCP< Vector>& full, bool bThyraMode = false) const { InsertVector(*partial, block, *full, bThyraMode); }
311  void InsertVector(RCP< Vector>& partial, size_t block, RCP< Vector>& full, bool bThyraMode = false) const { InsertVector(*partial, block, *full, bThyraMode); }
312  void InsertVector(RCP<const MultiVector>& partial, size_t block, RCP<MultiVector>& full, bool bThyraMode = false) const { InsertVector(*partial, block, *full, bThyraMode); }
313  void InsertVector(RCP< MultiVector>& partial, size_t block, RCP<MultiVector>& full, bool bThyraMode = false) const { InsertVector(*partial, block, *full, bThyraMode); }
314 
315 
317 
318  RCP< Vector> getVector(size_t i, bool bThyraMode = false) const {
320  "MapExtractor::getVector: getVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
321  return VectorFactory::Build(getMap(i, bThyraMode), true);
322  }
323  RCP<MultiVector> getVector(size_t i, size_t numvec, bool bThyraMode = false) const {
325  "MapExtractor::getVector: getVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
326  return MultiVectorFactory::Build(getMap(i, bThyraMode), numvec, true);
327  }
328 
330  bool getThyraMode() const { return bThyraMode_; }
331 
334 
336  size_t NumMaps() const { return maps_.size(); }
337 
342  const RCP<const Map> getMap(size_t i, bool bThyraMode = false) const {
343  if(bThyraMode_ == true && bThyraMode == true)
344  return thyraMaps_[i];
346  "MapExtractor::getMap: cannot return sub map in Thyra-style numbering if MapExtractor object is not created using Thyra-style numbered submaps.");
347  return maps_[i];
348  }
349 
351  const RCP<const Map> getFullMap() const { return fullmap_; }
352 
354  size_t getMapIndexForGID(GlobalOrdinal gid) const {
355  for (size_t i = 0; i < NumMaps(); i++)
356  if (getMap(i)->isNodeGlobalElement(gid) == true)
357  return i;
358 
360  "getMapIndexForGID: GID " << gid << " is not contained by a map in mapextractor." );
361  return 0;
362  }
363 
365 
366  private:
367  bool CheckConsistency() const {
368  const RCP<const Map> fullMap = getFullMap();
369 
370  for (size_t i = 0; i < NumMaps(); i++) {
371  const RCP<const Map> map = getMap(i);
372 
373  ArrayView<const GlobalOrdinal> mapGids = map->getNodeElementList();
374  for (typename ArrayView< const GlobalOrdinal >::const_iterator it = mapGids.begin(); it != mapGids.end(); it++)
375  if (fullMap->isNodeGlobalElement(*it) == false)
376  return false; // Global ID (*it) not found locally on this proc in fullMap -> error
377  }
378  return true;
379  }
380 
381  private:
383  std::vector<RCP<const Map> > maps_;
384  std::vector<RCP<Import > > importers_;
385  bool bThyraMode_; //< boolean flag: use Thyra numbering for local sub-block maps. default = false (for Xpetra mode)
386  std::vector<RCP<const Map> > thyraMaps_; //< store Thyra-style numbering maps here in Thyra mode. In Xpetra mode this vector is empty.
387  };
388 }
389 
390 #define XPETRA_MAPEXTRACTOR_SHORT
391 #endif /* XPETRA_MAPEXTRACTOR_HPP_ */
GlobalOrdinal global_ordinal_type
void ExtractVector(RCP< const Vector > &full, size_t block, RCP< Vector > &partial) const
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.
RCP< Vector > ExtractVector(RCP< const Vector > &full, size_t block, bool bThyraMode=false) const
size_t getMapIndexForGID(GlobalOrdinal gid) const
returns map index in map extractor which contains GID or -1 otherwise
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").
std::vector< RCP< const Map > > maps_
void ExtractVector(const MultiVector &full, size_t block, MultiVector &partial) const
void ExtractVector(RCP< const MultiVector > &full, size_t block, RCP< MultiVector > &partial) const
void InsertVector(const MultiVector &partial, size_t block, MultiVector &full, bool bThyraMode=false) const
iterator begin() const
GlobalOrdinal GO
void InsertVector(RCP< const MultiVector > &partial, size_t block, RCP< MultiVector > &full, bool bThyraMode=false) const
void InsertVector(RCP< Vector > &partial, size_t block, RCP< Vector > &full, bool bThyraMode=false) const
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
const_pointer const_iterator
const RCP< const Map > getFullMap() const
the full map
Xpetra namespace
Exception throws to report errors in the internal logical of the program.
void InsertVector(RCP< MultiVector > &partial, size_t block, RCP< MultiVector > &full, bool bThyraMode=false) const
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 ("forward mode").
void InsertVector(RCP< const Vector > &partial, size_t block, RCP< Vector > &full, bool bThyraMode=false) const
RCP< MultiVector > ExtractVector(RCP< MultiVector > &full, size_t block, bool bThyraMode=false) const
void InsertVector(const Vector &partial, size_t block, Vector &full, bool bThyraMode=false) const
RCP< MultiVector > getVector(size_t i, size_t numvec, bool bThyraMode=false) const
MapExtractor(const RCP< const Map > &fullmap, const std::vector< RCP< const Map > > &maps, bool bThyraMode=false)
MapExtractor basic constructor.
RCP< MultiVector > ExtractVector(RCP< const MultiVector > &full, size_t block, bool bThyraMode=false) const
std::vector< RCP< Import > > importers_
static RCP< Vector > Build(const Teuchos::RCP< const Map > &map, bool zeroOut=true)
Constructor specifying the number of non-zeros for all rows.
const RCP< const Map > getMap(size_t i, bool bThyraMode=false) const
std::vector< RCP< const Map > > thyraMaps_
void ExtractVector(const Vector &full, size_t block, Vector &partial) const
RCP< Vector > getVector(size_t i, bool bThyraMode=false) const
iterator end() const
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.
void ExtractVector(RCP< MultiVector > &full, size_t block, RCP< MultiVector > &partial) const
virtual size_t getNumVectors() const =0
Number of columns in the multivector.
RCP< Vector > ExtractVector(RCP< Vector > &full, size_t block, bool bThyraMode=false) const
size_t NumMaps() const
number of partial maps
virtual Teuchos::ArrayRCP< const Scalar > getData(size_t j) const =0
Const view of the local values in a particular vector of this multivector.
void ExtractVector(RCP< Vector > &full, size_t block, RCP< Vector > &partial) const