Xpetra_BlockedMultiVector.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 // Tobias Wiesner (tawiesn@sandia.gov)
42 // Ray Tuminaro (rstumin@sandia.gov)
43 //
44 // ***********************************************************************
45 //
46 // @HEADER
47 #ifndef XPETRA_BLOCKEDMULTIVECTOR_HPP
48 #define XPETRA_BLOCKEDMULTIVECTOR_HPP
49 
50 /* this file is automatically generated - do not edit (see script/interfaces.py) */
51 
52 #include "Xpetra_ConfigDefs.hpp"
53 #include "Xpetra_Map.hpp"
54 #include "Xpetra_MultiVector.hpp"
55 
56 #include "Xpetra_BlockedMap.hpp"
57 
58 namespace Xpetra {
59 
60 #ifndef DOXYGEN_SHOULD_SKIP_THIS
61  // forward declaration of Vector, needed to prevent circular inclusions
62  template<class S, class LO, class GO, class N> class Vector;
63  template<class S, class LO, class GO, class N> class BlockedVector;
64  template<class S, class LO, class GO, class N> class MapExtractor;
65  template<class S, class LO, class GO, class N> class MultiVectorFactory;
66 #endif
67 
68  template <class Scalar = double,
69  class LocalOrdinal = Map<>::local_ordinal_type,
70  class GlobalOrdinal = typename Map<LocalOrdinal>::global_ordinal_type,
71  class Node = typename Map<LocalOrdinal, GlobalOrdinal>::node_type>
73  : public MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node >
74  {
75  public:
76  typedef Scalar scalar_type;
77  typedef LocalOrdinal local_ordinal_type;
78  typedef GlobalOrdinal global_ordinal_type;
79  typedef Node node_type;
80 
81  private:
82 #undef XPETRA_BLOCKEDMULTIVECTOR_SHORT
83 #include "Xpetra_UseShortNames.hpp"
84 
85  public:
87 
88 
90 
100  size_t NumVectors,
101  bool zeroOut=true) :
102  map_(map) {
103 
104  numVectors_ = NumVectors;
105 
106  vv_.reserve(map->getNumMaps());
107 
108  // add CrsMatrix objects in row,column order
109  for (size_t r = 0; r < map->getNumMaps(); ++r)
110  vv_.push_back(Xpetra::MultiVectorFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Build(map->getMap(r, map_->getThyraMode()), NumVectors, zeroOut));
111  };
112 
126  XPETRA_TEST_FOR_EXCEPTION(bmap->getMap()->getNodeNumElements() != v->getMap()->getNodeNumElements(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector: inconsistent number of local elements of MultiVector and BlockedMap. The BlockedMap has " << bmap->getMap()->getNodeNumElements() << " local elements. The vector has " << v->getMap()->getNodeNumElements() << ".");
127  XPETRA_TEST_FOR_EXCEPTION(bmap->getMap()->getGlobalNumElements() != v->getMap()->getGlobalNumElements(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector: inconsistent number of global elements of MultiVector and BlockedMap. The BlockedMap has " << bmap->getMap()->getGlobalNumElements() << " local elements. The vector has " << v->getMap()->getGlobalNumElements() << ".");
128  //TEUCHOS_TEST_FOR_EXCEPTION(bmap->getFullMap()->getNodeNumElements() != v->getMap()->getNodeNumElements(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector: inconsistent number of local elements of MultiVector and BlockedMap. The BlockedMap has " << bmap->getFullMap()->getNodeNumElements() << " local elements. The vector has " << v->getMap()->getNodeNumElements() << ".");
129  //TEUCHOS_TEST_FOR_EXCEPTION(bmap->getFullMap()->getGlobalNumElements() != v->getMap()->getGlobalNumElements(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector: inconsistent number of global elements of MultiVector and BlockedMap. The BlockedMap has " << bmap->getFullMap()->getGlobalNumElements() << " local elements. The vector has " << v->getMap()->getGlobalNumElements() << ".");
130 
131  numVectors_ = v->getNumVectors();
132 
133  map_ = bmap;
134 
135  // Extract vector
136  vv_.reserve(bmap->getNumMaps());
137 
138  // add CrsMatrix objects in row,column order
139  for (size_t r = 0; r < bmap->getNumMaps(); ++r)
140  vv_.push_back(this->ExtractVector(v, r, bmap->getThyraMode()));
141  }
142 
156  TEUCHOS_TEST_FOR_EXCEPTION(bmap->getFullMap()->getNodeNumElements() != v->getMap()->getNodeNumElements(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector: inconsistent number of local elements of MultiVector and BlockedMap");
157  TEUCHOS_TEST_FOR_EXCEPTION(bmap->getFullMap()->getGlobalNumElements() != v->getMap()->getGlobalNumElements(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector: inconsistent number of global elements of MultiVector and BlockedMap");
158 
159  numVectors_ = v->getNumVectors();
160 
161  map_ = bmap;
162 
163  // Extract vector
164  vv_.reserve(bmap->getNumMaps());
165 
166  // add CrsMatrix objects in row,column order
167  for (size_t r = 0; r < bmap->getNumMaps(); ++r)
168  vv_.push_back(this->ExtractVector(v, r, bmap->getThyraMode()));
169  }
170 
184  numVectors_ = v->getNumVectors();
185 
186  // create blocked map out of MapExtractor
187  std::vector<RCP<const Map> > maps;
188  maps.reserve(mapExtractor->NumMaps());
189  for (size_t r = 0; r < mapExtractor->NumMaps(); ++r)
190  maps.push_back(mapExtractor->getMap(r,mapExtractor->getThyraMode()));
191  map_ = Teuchos::rcp(new Xpetra::BlockedMap<LocalOrdinal,GlobalOrdinal,Node>(mapExtractor->getFullMap(),maps,mapExtractor->getThyraMode()));
192 
193  // Extract vector
194  vv_.reserve(mapExtractor->NumMaps());
195 
196  // add CrsMatrix objects in row,column order
197  for (size_t r = 0; r < mapExtractor->NumMaps(); ++r)
198  vv_.push_back(this->ExtractVector(v, r, mapExtractor->getThyraMode()));
199  }
200 
214  numVectors_ = v->getNumVectors();
215 
216  // create blocked map out of MapExtractor
217  std::vector<RCP<const Map> > maps;
218  maps.reserve(mapExtractor->NumMaps());
219  for (size_t r = 0; r < mapExtractor->NumMaps(); ++r)
220  maps.push_back(mapExtractor->getMap(r,mapExtractor->getThyraMode()));
221  map_ = Teuchos::rcp(new Xpetra::BlockedMap<LocalOrdinal,GlobalOrdinal,Node>(mapExtractor->getFullMap(),maps,mapExtractor->getThyraMode()));
222 
223  vv_.reserve(mapExtractor->NumMaps());
224 
225  // add CrsMatrix objects in row,column order
226  for (size_t r = 0; r < mapExtractor->NumMaps(); ++r)
227  vv_.push_back(this->ExtractVector(v, r, mapExtractor->getThyraMode()));
228  }
229 
232  for (size_t r = 0; r < vv_.size(); ++r)
233  vv_[r] = Teuchos::null;
234  map_ = Teuchos::null;
235  numVectors_ = 0;
236  }
237 
246  operator= (const MultiVector& rhs) {
247  assign (rhs); // dispatch to protected virtual method
248  return *this;
249  }
250 
252 
254 
256  virtual void replaceGlobalValue(GlobalOrdinal globalRow, size_t vectorIndex, const Scalar &value) {
257  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::replaceGlobalValue: Not (yet) supported by BlockedMultiVector.");
258  }
259 
261  virtual void sumIntoGlobalValue(GlobalOrdinal globalRow, size_t vectorIndex, const Scalar &value) {
262  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::sumIntoGlobalValue: Not (yet) supported by BlockedMultiVector.");
263  }
264 
266  virtual void replaceLocalValue(LocalOrdinal myRow, size_t vectorIndex, const Scalar &value) {
267  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::replaceLocalValue: Not supported by BlockedMultiVector.");
268  }
269 
271  virtual void sumIntoLocalValue(LocalOrdinal myRow, size_t vectorIndex, const Scalar &value) {
272  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::sumIntoLocalValue:Not (yet) supported by BlockedMultiVector.");
273  }
274 
276  virtual void putScalar(const Scalar &value) {
277  XPETRA_MONITOR("BlockedMultiVector::putScalar");
278  for(size_t r = 0; r < map_->getNumMaps(); r++) {
279  getMultiVector(r)->putScalar(value);
280  }
281  }
282 
284 
286 
287 
292 
293  for(size_t r=0; r<getBlockedMap()->getNumMaps(); r++) {
295  this->getMultiVector(r,this->getBlockedMap()->getThyraMode())->getVector(j);
296  ret->setMultiVector(r,subvec,this->getBlockedMap()->getThyraMode());
297  }
298  return ret;
299  }
300 
305  return ret;
306  }
307 
309  virtual Teuchos::ArrayRCP< const Scalar > getData(size_t j) const {
310  if(map_->getNumMaps() == 1) {
311  return vv_[0]->getData(j);
312  }
313  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::getData: Not (yet) supported by BlockedMultiVector.");
314  return Teuchos::null;
315  }
316 
319  if(map_->getNumMaps() == 1) {
320  return vv_[0]->getDataNonConst(j);
321  }
322  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::getDataNonConst: Not (yet) supported by BlockedMultiVector.");
323  return Teuchos::null;
324  }
325 
327 
329 
330 
332  virtual void dot(const MultiVector&A, const Teuchos::ArrayView< Scalar > &dots) const {
333  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::dot: Not (yet) supported by BlockedMultiVector.");
334  }
335 
337  virtual void abs(const MultiVector&A) {
338  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::abs: Not (yet) supported by BlockedMultiVector.");
339  }
340 
342  virtual void reciprocal(const MultiVector&A) {
343  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::reciprocal: Not (yet) supported by BlockedMultiVector.");
344  }
345 
347  virtual void scale(const Scalar &alpha) {
348  XPETRA_MONITOR("BlockedMultiVector::scale (Scalar)");
349  for (size_t r = 0; r < map_->getNumMaps(); ++r) {
350  if(getMultiVector(r)!=Teuchos::null) {
351  getMultiVector(r)->scale(alpha);
352  }
353  }
354  }
355 
358  XPETRA_MONITOR("BlockedMultiVector::scale (Array)");
359  for (size_t r = 0; r < map_->getNumMaps(); ++r) {
360  if(getMultiVector(r)!=Teuchos::null) {
361  getMultiVector(r)->scale(alpha);
362  }
363  }
364  }
365 
367  virtual void update(const Scalar &alpha, const MultiVector&A, const Scalar &beta) {
368  XPETRA_MONITOR("BlockedMultiVector::update");
369  Teuchos::RCP<const MultiVector> rcpA = Teuchos::rcpFromRef(A);
370  Teuchos::RCP<const BlockedMultiVector> bA = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpA);
371  TEUCHOS_TEST_FOR_EXCEPTION(numVectors_ != rcpA->getNumVectors(),Xpetra::Exceptions::RuntimeError,"BlockedMultiVector::update: update with incompatible vector (different number of vectors in multivector).");
372  if(bA != Teuchos::null) {
373  // A is a BlockedMultiVector (and compatible with this)
374  // Call update recursively on all sub vectors
375  TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() != bA->getBlockedMap()->getThyraMode(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: update with incompatible vector (different thyra mode).");
376  TEUCHOS_TEST_FOR_EXCEPTION(map_->getNumMaps() != bA->getBlockedMap()->getNumMaps(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: update with incompatible vector (different number of partial vectors).");
377  for(size_t r = 0; r < map_->getNumMaps(); r++) {
378 
379  XPETRA_TEST_FOR_EXCEPTION(getMultiVector(r)->getMap()->getNodeNumElements() != bA->getMultiVector(r)->getMap()->getNodeNumElements(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: in subvector " << r << ": Cannot add a vector of (local) length " << bA->getMultiVector(r)->getMap()->getNodeNumElements() << " to the existing vector with " << getMultiVector(r)->getMap()->getNodeNumElements() << " entries.");
380  XPETRA_TEST_FOR_EXCEPTION(getMultiVector(r)->getMap()->getGlobalNumElements() != bA->getMultiVector(r)->getMap()->getGlobalNumElements(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: in subvector " << r << ": Cannot add a vector of length " << bA->getMultiVector(r)->getMap()->getGlobalNumElements() << " to the existing vector with " << getMultiVector(r)->getMap()->getGlobalNumElements() << " entries.");
381  // TAW: 12/6 We basically want to do something like:
382  // getMultiVector(r)->update(alpha, *(bA->getMultiVector(r)), beta);
383  // But if the left hand side is a standard MultiVector and bA->getMultiVector(r) is
384  // a blocked MultiVector this will not work, as the update implementation of the standard
385  // multivector cannot deal with blocked multivectors.
386  // The only use case where this could happen is, if the rhs vector is a single block multivector
388  Teuchos::RCP<MultiVector> rmv = bA->getMultiVector(r);
389 
390  // check whether lmv/rmv are blocked or not
391  Teuchos::RCP<BlockedMultiVector> blmv = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(lmv);
392  Teuchos::RCP<BlockedMultiVector> brmv = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rmv);
393 
394  if(blmv.is_null() == true && brmv.is_null() == false) {
395  // special case: lmv is standard MultiVector but rmv is BlockedMultiVector
396  TEUCHOS_TEST_FOR_EXCEPTION(brmv->getBlockedMap()->getNumMaps() > 1, Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: Standard MultiVector object does not accept BlockedMultVector object as parameter in update call.");
397  lmv->update(alpha, *(brmv->getMultiVector(0)), beta);
398  } else
399  lmv->update(alpha, *rmv, beta);
400  }
401  } else {
402  // A is a MultiVector
403  // If this is a BlockedMultiVector with only one sub-vector of same length we can just update
404  // Otherwise, A is not compatible with this as BlockedMultiVector and we have to extract the vector data from A
405 
406  if(getBlockedMap()->getNumMaps() == 1) {
407  // Actually call "update" on the underlying MultiVector (Epetra or Tpetra).
408  // The maps have to be compatible.
409  XPETRA_TEST_FOR_EXCEPTION(getMultiVector(0)->getMap()->isSameAs(*(rcpA->getMap()))==false, Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: update with incompatible vector (maps of full vector do not match with map in MapExtractor).");
410  getMultiVector(0)->update(alpha,*rcpA,beta);
411  } else {
412  // general case: A has to be splitted and subparts have to be extracted and stored in this BlockedMultiVector
413  //XPETRA_TEST_FOR_EXCEPTION(map_->getFullMap()->isSameAs(*(rcpA->getMap()))==false, Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: update with incompatible vector (maps of full vector do not match with map in MapExtractor). - Note: This test might be too strict and can probably be relaxed!");
414  for(size_t r = 0; r < map_->getNumMaps(); r++) {
415  // Call "update" on the subvector. Note, that getMultiVector(r) could return another BlockedMultiVector.
416  // That is, in Thyra mode the maps could differ (local Xpetra versus Thyra style gids)
417  Teuchos::RCP<const MultiVector> part = this->ExtractVector(rcpA, r, map_->getThyraMode());
418  XPETRA_TEST_FOR_EXCEPTION(getMultiVector(r)->getMap()->getNodeNumElements() != part->getMap()->getNodeNumElements(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: in subvector " << r << ": Cannot add a vector of (local) length " << part->getMap()->getNodeNumElements() << " to the existing vector with " << getMultiVector(r)->getMap()->getNodeNumElements() << " entries.");
419  XPETRA_TEST_FOR_EXCEPTION(getMultiVector(r)->getMap()->getGlobalNumElements() !=part->getMap()->getGlobalNumElements(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: in subvector " << r << ": Cannot add a vector of length " << part->getMap()->getGlobalNumElements() << " to the existing vector with " << getMultiVector(r)->getMap()->getGlobalNumElements() << " entries.");
420  getMultiVector(r)->update(alpha, *part, beta);
421  }
422  }
423  }
424  }
425 
427  virtual void update(const Scalar &alpha, const MultiVector&A, const Scalar &beta, const MultiVector&B, const Scalar &gamma) {
428  XPETRA_MONITOR("BlockedMultiVector::update2");
429  Teuchos::RCP<const MultiVector> rcpA = Teuchos::rcpFromRef(A);
430  Teuchos::RCP<const MultiVector> rcpB = Teuchos::rcpFromRef(B);
431  Teuchos::RCP<const BlockedMultiVector> bA = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpA);
432  Teuchos::RCP<const BlockedMultiVector> bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
433  if(bA != Teuchos::null && bB != Teuchos::null) {
434  TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() != bA->getBlockedMap()->getThyraMode(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: update with incompatible vector (different thyra mode in vector A).");
435  TEUCHOS_TEST_FOR_EXCEPTION(map_->getNumMaps() != bA->getBlockedMap()->getNumMaps(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: update with incompatible vector (different number of partial vectors in vector A).");
436  TEUCHOS_TEST_FOR_EXCEPTION(numVectors_ != bA->getNumVectors(),Xpetra::Exceptions::RuntimeError,"BlockedMultiVector::update: update with incompatible vector (different number of vectors in multivector in vector A).");
437  TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() != bB->getBlockedMap()->getThyraMode(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: update with incompatible vector (different thyra mode in vector B).");
438  TEUCHOS_TEST_FOR_EXCEPTION(map_->getNumMaps() != bB->getBlockedMap()->getNumMaps(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: update with incompatible vector (different number of partial vectors in vector B).");
439  TEUCHOS_TEST_FOR_EXCEPTION(numVectors_ != bB->getNumVectors(),Xpetra::Exceptions::RuntimeError,"BlockedMultiVector::update: update with incompatible vector (different number of vectors in multivector in vector B).");
440 
441  for(size_t r = 0; r < map_->getNumMaps(); r++) {
442  XPETRA_TEST_FOR_EXCEPTION(getMultiVector(r)->getMap()->isSameAs(*(bA->getMultiVector(r)->getMap()))==false, Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: update with incompatible vector (different maps in partial vector " << r << ").");
443  getMultiVector(r)->update(alpha, *(bA->getMultiVector(r)), beta, *(bB->getMultiVector(r)), gamma);
444  }
445  return;
446  }
447  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::update: only supports update with other BlockedMultiVector.");
448  }
449 
451  virtual void norm1(const Teuchos::ArrayView< typename Teuchos::ScalarTraits< Scalar >::magnitudeType > &norms) const {
452  XPETRA_MONITOR("BlockedMultiVector::norm1");
453  typedef typename ScalarTraits<Scalar>::magnitudeType Magnitude;
454  Array<Magnitude> temp_norms(getNumVectors());
455  std::fill(norms.begin(),norms.end(),ScalarTraits<Magnitude>::zero());
456  std::fill(temp_norms.begin(),temp_norms.end(),ScalarTraits<Magnitude>::zero());
457  for (size_t r = 0; r < map_->getNumMaps(); ++r) {
458  if(getMultiVector(r)!=Teuchos::null) {
459  getMultiVector(r)->norm1(temp_norms);
460  for (size_t c = 0; c < getNumVectors(); ++c)
461  norms[c] += temp_norms[c];
462  }
463  }
464  }
465 
467  virtual void norm2(const Teuchos::ArrayView< typename Teuchos::ScalarTraits< Scalar >::magnitudeType > &norms) const {
468  XPETRA_MONITOR("BlockedMultiVector::norm2");
469  typedef typename ScalarTraits<Scalar>::magnitudeType Magnitude;
470  Array<Magnitude> results(getNumVectors());
471  Array<Magnitude> temp_norms(getNumVectors());
472  std::fill(norms.begin(),norms.end(),ScalarTraits<Magnitude>::zero());
473  std::fill(results.begin(),results.end(),ScalarTraits<Magnitude>::zero());
474  std::fill(temp_norms.begin(),temp_norms.end(),ScalarTraits<Magnitude>::zero());
475  for (size_t r = 0; r < map_->getNumMaps(); ++r) {
476  if(getMultiVector(r)!=Teuchos::null) {
477  getMultiVector(r)->norm2(temp_norms);
478  for (size_t c = 0; c < getNumVectors(); ++c)
479  results[c] += temp_norms[c] * temp_norms[c];
480  }
481  }
482  for (size_t c = 0; c < getNumVectors(); ++c)
483  norms[c] = Teuchos::ScalarTraits<Magnitude >::squareroot(results[c]);
484  }
485 
487  virtual void normInf(const Teuchos::ArrayView< typename Teuchos::ScalarTraits< Scalar >::magnitudeType > &norms) const {
488  XPETRA_MONITOR("BlockedMultiVector::normInf");
489  typedef typename ScalarTraits<Scalar>::magnitudeType Magnitude;
490  Array<Magnitude> temp_norms(getNumVectors());
491  std::fill(norms.begin(),norms.end(),ScalarTraits<Magnitude>::zero());
492  std::fill(temp_norms.begin(),temp_norms.end(),ScalarTraits<Magnitude>::zero());
493  for (size_t r = 0; r < map_->getNumMaps(); ++r) {
494  if(getMultiVector(r)!=Teuchos::null) {
495  getMultiVector(r)->normInf(temp_norms);
496  for (size_t c = 0; c < getNumVectors(); ++c)
497  norms[c] = std::max(norms[c],temp_norms[c]);
498  }
499  }
500  }
501 
503  virtual void meanValue(const Teuchos::ArrayView< Scalar > &means) const {
504  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::meanValue: Not (yet) supported by BlockedMultiVector.");
505  }
506 
508  virtual void multiply(Teuchos::ETransp transA, Teuchos::ETransp transB, const Scalar &alpha, const MultiVector&A, const MultiVector&B, const Scalar &beta) {
509  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::multiply: Not (yet) supported by BlockedMultiVector.");
510  }
511 
513  virtual void elementWiseMultiply(Scalar scalarAB, const Xpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node>&A, const MultiVector&B, Scalar scalarThis) {
514  XPETRA_MONITOR("BlockedMultiVector::elementWiseMultiply");
515  XPETRA_TEST_FOR_EXCEPTION(B.getMap()->isSameAs(*(this->getMap()))==false, Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::elementWiseMultipy: B must have same blocked map than this.");
516  //XPETRA_TEST_FOR_EXCEPTION(A.getMap()->isSameAs(*(this->getMap()))==false, Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::elementWiseMultipy: A must have same blocked map than this.");
517  TEUCHOS_TEST_FOR_EXCEPTION(A.getMap()->getNodeNumElements() != B.getMap()->getNodeNumElements(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::elementWiseMultipy: A has " << A.getMap()->getNodeNumElements() << " elements, B has " << B.getMap()->getNodeNumElements() << ".");
518  TEUCHOS_TEST_FOR_EXCEPTION(A.getMap()->getGlobalNumElements() != B.getMap()->getGlobalNumElements(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::elementWiseMultipy: A has " << A.getMap()->getGlobalNumElements() << " elements, B has " << B.getMap()->getGlobalNumElements() << ".");
519 
523  Teuchos::rcp_dynamic_cast<const Xpetra::BlockedVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(rcpA);
524 
525  RCP<const MultiVector> rcpB = Teuchos::rcpFromRef(B);
526  RCP<const BlockedMultiVector> bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
527  TEUCHOS_TEST_FOR_EXCEPTION(bB.is_null() == true, Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::elementWiseMultipy: B must be a BlockedMultiVector.");
528 
529  //RCP<Xpetra::MapExtractor<Scalar,LocalOrdinal,GlobalOrdinal,Node> > me = Teuchos::rcp(new Xpetra::MapExtractor<Scalar,LocalOrdinal,GlobalOrdinal,Node>(bmap));
530 
531  for(size_t m = 0; m < bmap->getNumMaps(); m++) {
533  bA->getMultiVector(m, bmap->getThyraMode())->getVector(0);
535  bB->getMultiVector(m, bmap->getThyraMode());
537  this->getMultiVector(m, bmap->getThyraMode());
538 
539  thisPart->elementWiseMultiply(scalarAB,*partA,*partB,scalarThis);
540  }
541  }
542 
544 
546 
547 
549  virtual size_t getNumVectors() const {
550  return numVectors_;
551  }
552 
554  virtual size_t getLocalLength() const {
555  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::getLocalLength: routine not implemented. It has no value as one must iterate on the partial vectors.");
556  return 0;
557  }
558 
560  virtual global_size_t getGlobalLength() const {
561  XPETRA_MONITOR("BlockedMultiVector::getGlobalLength()");
562  return map_->getFullMap()->getGlobalNumElements();
563  }
564 
566 
568 
569 
571  virtual std::string description() const {
572  return std::string("BlockedMultiVector");
573  }
574 
577  out << description() << std::endl;
578  for(size_t r = 0; r < map_->getNumMaps(); r++)
579  getMultiVector(r)->describe(out, verbLevel);
580  }
581 
582  virtual void replaceMap(const RCP<const Map>& map) {
583  XPETRA_MONITOR("BlockedMultiVector::replaceMap");
584  RCP<const BlockedMap> bmap = Teuchos::rcp_dynamic_cast<const BlockedMap>(map);
585  if (bmap.is_null() == true) {
586  // if this has more than 1 sub blocks but "map" is not a blocked map, they are very likely not compatible
587  if (this->getBlockedMap()->getNumMaps() > 1) {
588  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::replaceMap: map is not of type BlockedMap. General implementation not available, yet.");
589  return;
590  }
591  // special case: this is a blocked map with only one block
592  // TODO add more debug check (especially for Thyra mode)
593  std::vector<Teuchos::RCP<const Map> > subMaps (1, map);
594  map_ = Teuchos::rcp(new BlockedMap(map, subMaps,this->getBlockedMap()->getThyraMode()));
595  this->getMultiVector(0)->replaceMap(map);
596  return;
597  }
598  RCP<const BlockedMap> mybmap = Teuchos::rcp_dynamic_cast<const BlockedMap>(map_);
599 
600  XPETRA_TEST_FOR_EXCEPTION(mybmap->getThyraMode() != bmap->getThyraMode(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::replaceMap: inconsistent Thyra mode");
601  map_ = bmap;
602  for(size_t r = 0; r < map_->getNumMaps(); r++)
603  getMultiVector(r)->replaceMap(bmap->getMap(r,map_->getThyraMode()));
604  }
605 
607  virtual void doImport(const DistObject<Scalar, LocalOrdinal, GlobalOrdinal, Node> &source, const Import& importer, CombineMode CM) {
608  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::doImport: Not supported by BlockedMultiVector.");
609  }
610 
612  virtual void doExport(const DistObject<Scalar, LocalOrdinal, GlobalOrdinal, Node> &dest, const Import& importer, CombineMode CM) {
613  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::doExport: Not supported by BlockedMultiVector.");
614  }
615 
617  virtual void doImport(const DistObject<Scalar, LocalOrdinal, GlobalOrdinal, Node> &source, const Export& exporter, CombineMode CM) {
618  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::doImport: Not supported by BlockedMultiVector.");
619  }
620 
622  virtual void doExport(const DistObject<Scalar, LocalOrdinal, GlobalOrdinal, Node> &dest, const Export& exporter, CombineMode CM) {
623  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::doExport: Not supported by BlockedMultiVector.");
624  }
625 
627 
629 
630 
632  virtual void setSeed(unsigned int seed) {
633  for(size_t r = 0; r < map_->getNumMaps(); ++r) {
634  getMultiVector(r)->setSeed(seed);
635  }
636  }
637 
638 
639  virtual void randomize(bool bUseXpetraImplementation = false) {
640  for(size_t r = 0; r < map_->getNumMaps(); ++r) {
641  getMultiVector(r)->randomize(bUseXpetraImplementation);
642  }
643  }
644 
646  virtual void Xpetra_randomize()
647  {
649  }
650 
651 #ifdef HAVE_XPETRA_KOKKOS_REFACTOR
652  typedef typename Kokkos::Details::ArithTraits<Scalar>::val_type impl_scalar_type;
653  typedef Kokkos::DualView<impl_scalar_type**, Kokkos::LayoutStride,
654  typename node_type::execution_space,
655  Kokkos::MemoryUnmanaged> dual_view_type;
656  typedef typename dual_view_type::host_mirror_space host_execution_space;
657  typedef typename dual_view_type::t_dev::execution_space dev_execution_space;
658 
664  template<class TargetDeviceType>
665  typename Kokkos::Impl::if_c<
666  Kokkos::Impl::is_same<
667  typename dev_execution_space::memory_space,
668  typename TargetDeviceType::memory_space>::value,
669  typename dual_view_type::t_dev_um,
670  typename dual_view_type::t_host_um>::type
671  getLocalView () const {
672  if(Kokkos::Impl::is_same<
673  typename host_execution_space::memory_space,
674  typename TargetDeviceType::memory_space
675  >::value) {
676  return getHostLocalView();
677  } else {
678  return getDeviceLocalView();
679  }
680  }
681 
682  virtual typename dual_view_type::t_host_um getHostLocalView () const {
683  typename dual_view_type::t_host_um test;
684  return test;
685  }
686  virtual typename dual_view_type::t_dev_um getDeviceLocalView() const {
687  typename dual_view_type::t_dev_um test;
688  return test;
689  }
690 
691 #endif
692 
694 
696  Teuchos::RCP< const Map> getMap() const { XPETRA_MONITOR("BlockedMultiVector::getMap"); return map_; }
697 
700 
703  XPETRA_MONITOR("BlockedMultiVector::getMultiVector(r)");
704  TEUCHOS_TEST_FOR_EXCEPTION(r > map_->getNumMaps(), std::out_of_range, "Error, r = " << r << " is too big. The BlockedMultiVector only contains " << map_->getNumMaps() << " partial blocks.");
705  return vv_[r];
706  }
707 
709  Teuchos::RCP<MultiVector> getMultiVector(size_t r, bool bThyraMode) const {
710  XPETRA_MONITOR("BlockedMultiVector::getMultiVector(r,bThyraMode)");
711  TEUCHOS_TEST_FOR_EXCEPTION(r > map_->getNumMaps(), std::out_of_range, "Error, r = " << r << " is too big. The BlockedMultiVector only contains " << map_->getNumMaps() << " partial blocks.");
712  XPETRA_TEST_FOR_EXCEPTION(map_->getThyraMode() != bThyraMode, Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::getMultiVector: inconsistent Thyra mode");
713  return vv_[r];
714  }
715 
717  void setMultiVector(size_t r, Teuchos::RCP<const MultiVector> v, bool bThyraMode) {
718  // The map of the MultiVector should be the same as the stored submap
719  // In thyra mode the vectors should live on the thyra maps
720  // in xpetra mode the should live in the xpetra maps
721  // that should be also ok in the nested case for thyra (if the vectors are distributed accordingly)
722  XPETRA_MONITOR("BlockedMultiVector::setMultiVector");
723  XPETRA_TEST_FOR_EXCEPTION(r >= map_->getNumMaps(), std::out_of_range, "Error, r = " << r << " is too big. The BlockedMultiVector only contains " << map_->getNumMaps() << " partial blocks.");
724  XPETRA_TEST_FOR_EXCEPTION(numVectors_ != v->getNumVectors(),Xpetra::Exceptions::RuntimeError,"The BlockedMultiVectors expects " << getNumVectors() << " vectors. The provided partial multivector has " << v->getNumVectors() << " vectors.");
725  XPETRA_TEST_FOR_EXCEPTION(map_->getThyraMode() != bThyraMode, Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::setMultiVector: inconsistent Thyra mode");
726  Teuchos::RCP<MultiVector> vv = Teuchos::rcp_const_cast<MultiVector>(v);
727  TEUCHOS_TEST_FOR_EXCEPTION(vv==Teuchos::null, Xpetra::Exceptions::RuntimeError, "Partial vector must not be Teuchos::null");
728  vv_[r] = vv;
729  }
730 
733  XPETRA_MONITOR("BlockedMultiVector::Merge");
734  using Teuchos::RCP;
735 
737  for(size_t r = 0; r < map_->getNumMaps(); ++r) {
739  RCP<BlockedMultiVector> bvi = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(vi);
740  if(bvi.is_null() == true) {
741  this->InsertVector(vi,r,v,map_->getThyraMode());
742  } else {
743  RCP<MultiVector> mvi = bvi->Merge();
744  this->InsertVector(mvi,r,v,map_->getThyraMode());
745  }
746  }
747 
748  // TODO plausibility checks
749 
750  return v;
751  }
752 
753 
754  protected:
761  virtual void assign (const MultiVector& rhs) {
762  Teuchos::RCP<const MultiVector> rcpRhs = Teuchos::rcpFromRef(rhs);
763  Teuchos::RCP<const BlockedMultiVector> bRhs = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpRhs);
764  if(bRhs == Teuchos::null)
765  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::assign: argument is not a blocked multi vector.");
766 
767  map_ = Teuchos::rcp(new BlockedMap(*(bRhs->getBlockedMap())));
768  vv_ = std::vector<Teuchos::RCP<MultiVector> >(map_->getNumMaps());
769  for(size_t r = 0; r < map_->getNumMaps(); ++r) {
770  // extract source vector (is of type MultiVector or BlockedMultiVector)
771  RCP<MultiVector> src = bRhs->getMultiVector(r,map_->getThyraMode());
772 
773  // create new (empty) multivector (is of type MultiVector or BlockedMultiVector)
774  RCP<MultiVector> vv = Xpetra::MultiVectorFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Build(map_->getMap(r,bRhs->getBlockedMap()->getThyraMode()),rcpRhs->getNumVectors(),true);
775 
776  // check type of source and target vector
777  RCP<BlockedMultiVector> bsrc = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(src);
778  RCP<BlockedMultiVector> bvv = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(vv);
779  if(bsrc.is_null() == true && bvv.is_null() == true) {
780  *vv = *src; // deep copy
781  } else if (bsrc.is_null() == true && bvv.is_null() == false) {
782  // special case: source vector is a merged MultiVector but target vector is blocked
783  *vv = *src; // deep copy (is this a problem???)
784  } else if (bsrc.is_null() == false && bvv.is_null() == true) {
785  // special case: source vector is blocked but target vector is a merged MultiVector
786  // This is a problem and only works if bsrc has only one block
787  if(bsrc->getBlockedMap()->getNumMaps() > 1) {
788  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::assign: source vector is of type BlockedMultiVector (with more than 1 blocks) and target is a MultiVector.");
789  return;
790  }
791  RCP<MultiVector> ssrc = bsrc->getMultiVector(0,map_->getThyraMode());
792  XPETRA_TEST_FOR_EXCEPTION(ssrc.is_null() == true, Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::assign: cannot extract vector");
793  XPETRA_TEST_FOR_EXCEPTION(Teuchos::rcp_dynamic_cast<BlockedMultiVector>(ssrc) != Teuchos::null, Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::assign: sub block must not be of type BlockedMultiVector.");
794  *vv = *ssrc;
795  } else {
796  // this should work (no exception necessary, i guess)
797  XPETRA_TEST_FOR_EXCEPTION(bsrc->getBlockedMap()->getNumMaps() != bvv->getBlockedMap()->getNumMaps(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::assign: source and target are BlockedMultiVectors with a different number of submaps.");
798  *vv = *src; // deep copy
799  }
800  vv_[r] = vv;
801  }
802  numVectors_ = rcpRhs->getNumVectors();
803  }
804 
805  private:
806  // helper routines for interaction of MultiVector and BlockedMultiVectors
807 
808  void ExtractVector(RCP<const MultiVector>& full, size_t block, RCP<MultiVector>& partial) const { ExtractVector(*full, block, *partial); }
809  void ExtractVector(RCP< MultiVector>& full, size_t block, RCP<MultiVector>& partial) const { ExtractVector(*full, block, *partial); }
810 
811  RCP<MultiVector> ExtractVector(RCP<const MultiVector>& full, size_t block, bool bThyraMode = false) const {
812  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(), std::out_of_range, "ExtractVector: Error, block = " << block << " is too big. The MapExtractor only contains " << map_->getNumMaps() << " partial blocks.");
814  "ExtractVector: map_->getmap(" << block << ",false) is null");
815  RCP<const BlockedMultiVector> bfull = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(full);
816  if(bfull.is_null() == true) {
817  // standard case: full is not of type BlockedMultiVector
818  // first extract partial vector from full vector (using xpetra style GIDs)
819  const RCP<MultiVector> vv = Xpetra::MultiVectorFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Build(map_->getMap(block,false), full->getNumVectors(), false);
820  //if(bThyraMode == false) {
821  // ExtractVector(*full, block, *vv);
822  // return vv;
823  //} else {
824  RCP<const Map> oldThyMapFull = full->getMap(); // temporarely store map of full
825  RCP<MultiVector> rcpNonConstFull = Teuchos::rcp_const_cast<MultiVector>(full);
826  rcpNonConstFull->replaceMap(map_->getImporter(block)->getSourceMap());
827  ExtractVector(*rcpNonConstFull, block, *vv);
828  TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true, Xpetra::Exceptions::RuntimeError,
829  "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
830  if(bThyraMode == true)
831  vv->replaceMap(map_->getMap(block,true)); // switch to Thyra-style map
832  rcpNonConstFull->replaceMap(oldThyMapFull);
833  return vv;
834  //}
835  } else {
836  // special case: full is of type BlockedMultiVector
837  XPETRA_TEST_FOR_EXCEPTION(map_->getNumMaps() != bfull->getBlockedMap()->getNumMaps(), Xpetra::Exceptions::RuntimeError,
838  "ExtractVector: Number of blocks in map extractor is " << map_->getNumMaps() << " but should be " << bfull->getBlockedMap()->getNumMaps() << " (number of blocks in BlockedMultiVector)");
839  return bfull->getMultiVector(block,bThyraMode);
840  }
841  }
842  RCP<MultiVector> ExtractVector(RCP< MultiVector>& full, size_t block, bool bThyraMode = false) const {
843  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(), std::out_of_range, "ExtractVector: Error, block = " << block << " is too big. The MapExtractor only contains " << map_->getNumMaps() << " partial blocks.");
845  "ExtractVector: map_->getmap(" << block << ",false) is null");
846  RCP<BlockedMultiVector> bfull = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(full);
847  if(bfull.is_null() == true) {
848  // standard case: full is not of type BlockedMultiVector
849  // first extract partial vector from full vector (using xpetra style GIDs)
850  const RCP<MultiVector> vv = Xpetra::MultiVectorFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Build(map_->getMap(block,false), full->getNumVectors(), false);
851  //if(bThyraMode == false) {
852  // ExtractVector(*full, block, *vv);
853  // return vv;
854  //} else {
855  RCP<const Map> oldThyMapFull = full->getMap(); // temporarely store map of full
856  full->replaceMap(map_->getImporter(block)->getSourceMap());
857  ExtractVector(*full, block, *vv);
858  TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true, Xpetra::Exceptions::RuntimeError,
859  "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
860  if(bThyraMode == true)
861  vv->replaceMap(map_->getMap(block,true)); // switch to Thyra-style map
862  full->replaceMap(oldThyMapFull);
863  return vv;
864  //}
865  } else {
866  // special case: full is of type BlockedMultiVector
867  XPETRA_TEST_FOR_EXCEPTION(map_->getNumMaps() != bfull->getBlockedMap()->getNumMaps(), Xpetra::Exceptions::RuntimeError,
868  "ExtractVector: Number of blocks in map extractor is " << map_->getNumMaps() << " but should be " << bfull->getBlockedMap()->getNumMaps() << " (number of blocks in BlockedMultiVector)");
869  return bfull->getMultiVector(block,bThyraMode);
870  }
871  }
872  void ExtractVector(const MultiVector& full, size_t block, MultiVector& partial) const {
873  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(), std::out_of_range, "ExtractVector: Error, block = " << block << " is too big. The BlockedMultiVector only contains " << map_->getNumMaps() << " partial blocks.");
875  "ExtractVector: maps_[" << block << "] is null");
876  partial.doImport(full, *(map_->getImporter(block)), Xpetra::INSERT);
877  }
878 
879  void InsertVector(const MultiVector& partial, size_t block, MultiVector& full, bool bThyraMode = false) const {
880  XPETRA_TEST_FOR_EXCEPTION(block >= map_->getNumMaps(), std::out_of_range, "ExtractVector: Error, block = " << block << " is too big. The MapExtractor only contains " << map_->getNumMaps() << " partial blocks.");
882  "ExtractVector: map_->getmap(" << block << ",false) is null");
883  XPETRA_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true, Xpetra::Exceptions::RuntimeError,
884  "MapExtractor::InsertVector: InsertVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
885  if(bThyraMode) {
886  // NOTE: the importer objects in the BlockedMap are always using Xpetra GIDs (or Thyra style Xpetra GIDs)
887  // The source map corresponds to the full map (in Xpetra GIDs) starting with GIDs from zero. The GIDs are consecutive in Thyra mode
888  // The target map is the partial map (in the corresponding Xpetra GIDs)
889 
890  // TODO can we skip the Export call in special cases (i.e. Src = Target map, same length, etc...)
891 
892  // store original GIDs (could be Thyra GIDs)
893  RCP<const MultiVector> rcpPartial = Teuchos::rcpFromRef(partial);
894  RCP<MultiVector> rcpNonConstPartial = Teuchos::rcp_const_cast<MultiVector>(rcpPartial);
895  RCP<const Map> oldThyMapPartial = rcpNonConstPartial->getMap(); // temporarely store map of partial
896  RCP<const Map> oldThyMapFull = full.getMap(); // temporarely store map of full
897 
898  // check whether getMap(block,false) is identical to target map of importer
899  //XPETRA_TEST_FOR_EXCEPTION(map_->getMap(block,false)->isSameAs(*(map_->getImporter(block)->getTargetMap()))==false, Xpetra::Exceptions::RuntimeError,
900  // "MapExtractor::InsertVector: InsertVector in Thyra-style mode: Xpetra GIDs of partial vector are not identical to target Map of Importer. This should not be.");
901 
902  //XPETRA_TEST_FOR_EXCEPTION(full.getMap()->isSameAs(*(map_->getImporter(block)->getSourceMap()))==false, Xpetra::Exceptions::RuntimeError,
903  // "MapExtractor::InsertVector: InsertVector in Thyra-style mode: Xpetra GIDs of full vector are not identical to source Map of Importer. This should not be.");
904 
905  rcpNonConstPartial->replaceMap(map_->getMap(block,false)); // temporarely switch to xpetra-style map
906  full.replaceMap(map_->getImporter(block)->getSourceMap()); // temporarely switch to Xpetra GIDs
907 
908  // do the Export
909  full.doExport(*rcpNonConstPartial, *(map_->getImporter(block)), Xpetra::INSERT);
910 
911  // switch back to original maps
912  full.replaceMap(oldThyMapFull); // reset original map (Thyra GIDs)
913  rcpNonConstPartial->replaceMap(oldThyMapPartial); // change map back to original map
914  } else {
915  // Xpetra style numbering
916  full.doExport(partial, *(map_->getImporter(block)), Xpetra::INSERT);
917  }
918  }
919  void InsertVector(RCP<const MultiVector> partial, size_t block, RCP<MultiVector> full, bool bThyraMode = false) const {
921  if(bfull.is_null() == true)
922  InsertVector(*partial, block, *full, bThyraMode);
923  else {
925  "InsertVector: maps_[" << block << "] is null");
926  full->setMultiVector(block, partial, bThyraMode);
927  }
928  }
929  void InsertVector(RCP< MultiVector> partial, size_t block, RCP<MultiVector> full, bool bThyraMode = false) const {
931  if(bfull.is_null() == true)
932  InsertVector(*partial, block, *full, bThyraMode);
933  else {
935  "InsertVector: maps_[" << block << "] is null");
936  bfull->setMultiVector(block, partial, bThyraMode);
937  }
938  }
939 
940  private:
942  std::vector<Teuchos::RCP<MultiVector> > vv_;
943  size_t numVectors_;
944  }; // BlockedMultiVector class
945 
946 } // Xpetra namespace
947 
948 #define XPETRA_BLOCKEDMULTIVECTOR_SHORT
949 #endif // XPETRA_BLOCKEDMULTIVECTOR_HPP
virtual void doImport(const DistObject< Scalar, LocalOrdinal, GlobalOrdinal, Node > &source, const Export &exporter, CombineMode CM)
Import (using an Exporter).
void ExtractVector(RCP< const MultiVector > &full, size_t block, RCP< MultiVector > &partial) const
virtual void setSeed(unsigned int seed)
Set seed for Random function.
virtual std::string description() const
A simple one-line description of this object.
LocalOrdinal local_ordinal_type
Definition: Xpetra_Map.hpp:85
Teuchos::RCP< MultiVector > getMultiVector(size_t r, bool bThyraMode) const
return partial multivector associated with block row r
virtual void norm2(const Teuchos::ArrayView< typename Teuchos::ScalarTraits< Scalar >::magnitudeType > &norms) const
Teuchos::RCP< const Xpetra::BlockedMap< LocalOrdinal, GlobalOrdinal, Node > > getBlockedMap() const
Access function for the underlying Map this DistObject was constructed with.
virtual void norm1(const Teuchos::ArrayView< typename Teuchos::ScalarTraits< Scalar >::magnitudeType > &norms) const
Compute 1-norm of each vector in multi-vector.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with the given verbosity level to a FancyOStream.
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").
virtual void dot(const MultiVector &A, const Teuchos::ArrayView< Scalar > &dots) const
Compute dot product of each corresponding pair of vectors, dots[i] = this[i].dot(A[i]).
GlobalOrdinal global_ordinal_type
Definition: Xpetra_Map.hpp:86
std::vector< Teuchos::RCP< MultiVector > > vv_
array containing RCPs of the partial vectors
virtual void multiply(Teuchos::ETransp transA, Teuchos::ETransp transB, const Scalar &alpha, const MultiVector &A, const MultiVector &B, const Scalar &beta)
Matrix-matrix multiplication: this = beta*this + alpha*op(A)*op(B).
Node node_type
Definition: Xpetra_Map.hpp:87
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
virtual void Xpetra_randomize()
Set multi-vector values to random numbers. XPetra implementation.
Xpetra namespace
BlockedMultiVector(const Teuchos::RCP< const BlockedMap > &map, size_t NumVectors, bool zeroOut=true)
Constructor.
virtual void doExport(const DistObject< Scalar, LocalOrdinal, GlobalOrdinal, Node > &dest, const Import &importer, CombineMode CM)
Export.
virtual global_size_t getGlobalLength() const
Global number of rows in the multivector.
virtual void doImport(const DistObject< Scalar, LocalOrdinal, GlobalOrdinal, Node > &source, const Import &importer, CombineMode CM)
Import.
virtual void update(const Scalar &alpha, const MultiVector &A, const Scalar &beta, const MultiVector &B, const Scalar &gamma)
Update multi-vector with scaled values of A and B, this = gamma*this + alpha*A + beta*B.
Exception throws to report errors in the internal logical of the program.
virtual void reciprocal(const MultiVector &A)
Put element-wise reciprocal values of input Multi-vector in target, this(i,j) = 1/A(i,j).
virtual void scale(const Scalar &alpha)
Scale the current values of a multi-vector, this = alpha*this.
void InsertVector(RCP< MultiVector > partial, size_t block, RCP< MultiVector > full, bool bThyraMode=false) const
void InsertVector(const MultiVector &partial, size_t block, MultiVector &full, bool bThyraMode=false) const
Teuchos::RCP< MultiVector > getMultiVector(size_t r) const
return partial multivector associated with block row r
virtual void replaceMap(const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &map)=0
virtual void update(const Scalar &alpha, const MultiVector &A, const Scalar &beta)
Update multi-vector values with scaled values of A, this = beta*this + alpha*A.
virtual void sumIntoLocalValue(LocalOrdinal myRow, size_t vectorIndex, const Scalar &value)
Add value to existing value, using local (row) index.
virtual Teuchos::ArrayRCP< Scalar > getDataNonConst(size_t j)
View of the local values in a particular vector of this multivector.
Teuchos::RCP< const Map > getMap() const
Access function for the underlying Map this DistObject was constructed with.
BlockedMultiVector(Teuchos::RCP< const Xpetra::BlockedMap< LocalOrdinal, GlobalOrdinal, Node > > bmap, Teuchos::RCP< MultiVector > v)
RCP< MultiVector > ExtractVector(RCP< const MultiVector > &full, size_t block, bool bThyraMode=false) const
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").
bool is_null() const
size_t numVectors_
number of vectors (columns in multi vector)
void ExtractVector(RCP< MultiVector > &full, size_t block, RCP< MultiVector > &partial) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual void abs(const MultiVector &A)
Put element-wise absolute values of input Multi-vector in target: A = abs(this).
virtual void Xpetra_randomize()
Set multi-vector values to random numbers. XPetra implementation.
RCP< MultiVector > ExtractVector(RCP< MultiVector > &full, size_t block, bool bThyraMode=false) const
virtual void elementWiseMultiply(Scalar scalarAB, const Xpetra::Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const MultiVector &B, Scalar scalarThis)
Element-wise multiply of a Vector A with a MultiVector B.
virtual void replaceMap(const RCP< const Map > &map)
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const =0
The Map describing the parallel distribution of this object.
virtual size_t getLocalLength() const
Local number of rows on the calling process.
virtual void assign(const MultiVector &rhs)
Implementation of the assignment operator (operator=); does a deep copy.
virtual void normInf(const Teuchos::ArrayView< typename Teuchos::ScalarTraits< Scalar >::magnitudeType > &norms) const
Compute Inf-norm of each vector in multi-vector.
virtual Teuchos::RCP< const Xpetra::Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getVector(size_t j) const
Return a Vector which is a const view of column j.
void setMultiVector(size_t r, Teuchos::RCP< const MultiVector > v, bool bThyraMode)
set partial multivector associated with block row r
void InsertVector(RCP< const MultiVector > partial, size_t block, RCP< MultiVector > full, bool bThyraMode=false) const
BlockedMultiVector(Teuchos::RCP< const Xpetra::MapExtractor< Scalar, LocalOrdinal, GlobalOrdinal, Node > > mapExtractor, Teuchos::RCP< MultiVector > v)
virtual void randomize(bool bUseXpetraImplementation=false)
size_t global_size_t
Global size_t object.
Teuchos::RCP< MultiVector > Merge() const
merge BlockedMultiVector blocks to a single MultiVector
iterator end()
static const EVerbosityLevel verbLevel_default
virtual size_t getNumVectors() const
Number of columns in the multivector.
BlockedMultiVector(Teuchos::RCP< const Xpetra::BlockedMap< LocalOrdinal, GlobalOrdinal, Node > > bmap, Teuchos::RCP< const MultiVector > v)
virtual void scale(Teuchos::ArrayView< const Scalar > alpha)
Scale the current values of a multi-vector, this[j] = alpha[j]*this[j].
void ExtractVector(const MultiVector &full, size_t block, MultiVector &partial) const
#define XPETRA_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Teuchos::RCP< const BlockedMap > map_
blocked map containing the sub block maps (either thyra or xpetra mode)
virtual void replaceLocalValue(LocalOrdinal myRow, size_t vectorIndex, const Scalar &value)
Replace value, using local (row) index.
virtual void putScalar(const Scalar &value)
Set all values in the multivector with the given value.
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.
CombineMode
Xpetra::Combine Mode enumerable type.
virtual void doExport(const DistObject< Scalar, LocalOrdinal, GlobalOrdinal, Node > &dest, const Export &exporter, CombineMode CM)
Export (using an Importer).
#define XPETRA_MONITOR(funcName)
virtual void meanValue(const Teuchos::ArrayView< Scalar > &means) const
Compute mean (average) value of each vector in multi-vector. The outcome of this routine is undefined...
BlockedMultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > & operator=(const MultiVector &rhs)
Assignment operator: Does a deep copy.
virtual Teuchos::ArrayRCP< const Scalar > getData(size_t j) const
Const view of the local values in a particular vector of this multivector.
virtual void replaceGlobalValue(GlobalOrdinal globalRow, size_t vectorIndex, const Scalar &value)
Replace value, using global (row) index.
iterator begin()
BlockedMultiVector(Teuchos::RCP< const Xpetra::MapExtractor< Scalar, LocalOrdinal, GlobalOrdinal, Node > > mapExtractor, Teuchos::RCP< const MultiVector > v)
virtual void sumIntoGlobalValue(GlobalOrdinal globalRow, size_t vectorIndex, const Scalar &value)
Add value to existing value, using global (row) index.
virtual Teuchos::RCP< Xpetra::Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getVectorNonConst(size_t j)
Return a Vector which is a nonconst view of column j.