All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
239  numVectors_ = vin[0]->getNumVectors();
240  map_ = map;
241  vv_.resize(vin.size());
242  for(size_t i=0; i<vv_.size(); i++)
243  vv_[i] = vin[i];
244  }
245 
248  for (size_t r = 0; r < vv_.size(); ++r)
249  vv_[r] = Teuchos::null;
250  map_ = Teuchos::null;
251  numVectors_ = 0;
252  }
253 
262  operator= (const MultiVector& rhs) {
263  assign (rhs); // dispatch to protected virtual method
264  return *this;
265  }
266 
268 
270 
272  virtual void replaceGlobalValue(GlobalOrdinal /* globalRow */, size_t /* vectorIndex */, const Scalar &/* value */) {
273  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::replaceGlobalValue: Not (yet) supported by BlockedMultiVector.");
274  }
275 
277  virtual void sumIntoGlobalValue(GlobalOrdinal /* globalRow */, size_t /* vectorIndex */, const Scalar &/* value */) {
278  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::sumIntoGlobalValue: Not (yet) supported by BlockedMultiVector.");
279  }
280 
282  virtual void replaceLocalValue(LocalOrdinal /* myRow */, size_t /* vectorIndex */, const Scalar &/* value */) {
283  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::replaceLocalValue: Not supported by BlockedMultiVector.");
284  }
285 
287  virtual void sumIntoLocalValue(LocalOrdinal /* myRow */, size_t /* vectorIndex */, const Scalar &/* value */) {
288  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::sumIntoLocalValue:Not (yet) supported by BlockedMultiVector.");
289  }
290 
292  virtual void putScalar(const Scalar &value) {
293  XPETRA_MONITOR("BlockedMultiVector::putScalar");
294  for(size_t r = 0; r < map_->getNumMaps(); r++) {
295  getMultiVector(r)->putScalar(value);
296  }
297  }
298 
300 
302 
303 
308 
309  for(size_t r=0; r<getBlockedMap()->getNumMaps(); r++) {
311  this->getMultiVector(r,this->getBlockedMap()->getThyraMode())->getVector(j);
312  ret->setMultiVector(r,subvec,this->getBlockedMap()->getThyraMode());
313  }
314  return ret;
315  }
316 
321  return ret;
322  }
323 
325  virtual Teuchos::ArrayRCP< const Scalar > getData(size_t j) const {
326  if(map_->getNumMaps() == 1) {
327  return vv_[0]->getData(j);
328  }
329  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::getData: Not (yet) supported by BlockedMultiVector.");
330  TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
331  }
332 
335  if(map_->getNumMaps() == 1) {
336  return vv_[0]->getDataNonConst(j);
337  }
338  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::getDataNonConst: Not (yet) supported by BlockedMultiVector.");
339  TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
340  }
341 
343 
345 
346 
348  virtual void dot(const MultiVector&/* A */, const Teuchos::ArrayView< Scalar > &/* dots */) const {
349  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::dot: Not (yet) supported by BlockedMultiVector.");
350  }
351 
353  virtual void abs(const MultiVector&/* A */) {
354  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::abs: Not (yet) supported by BlockedMultiVector.");
355  }
356 
358  virtual void reciprocal(const MultiVector&/* A */) {
359  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::reciprocal: Not (yet) supported by BlockedMultiVector.");
360  }
361 
363  virtual void scale(const Scalar &alpha) {
364  XPETRA_MONITOR("BlockedMultiVector::scale (Scalar)");
365  for (size_t r = 0; r < map_->getNumMaps(); ++r) {
366  if(getMultiVector(r)!=Teuchos::null) {
367  getMultiVector(r)->scale(alpha);
368  }
369  }
370  }
371 
374  XPETRA_MONITOR("BlockedMultiVector::scale (Array)");
375  for (size_t r = 0; r < map_->getNumMaps(); ++r) {
376  if(getMultiVector(r)!=Teuchos::null) {
377  getMultiVector(r)->scale(alpha);
378  }
379  }
380  }
381 
383  virtual void update(const Scalar &alpha, const MultiVector&A, const Scalar &beta) {
384  XPETRA_MONITOR("BlockedMultiVector::update");
385  Teuchos::RCP<const MultiVector> rcpA = Teuchos::rcpFromRef(A);
386  Teuchos::RCP<const BlockedMultiVector> bA = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpA);
387  TEUCHOS_TEST_FOR_EXCEPTION(numVectors_ != rcpA->getNumVectors(),Xpetra::Exceptions::RuntimeError,"BlockedMultiVector::update: update with incompatible vector (different number of vectors in multivector).");
388  if(bA != Teuchos::null) {
389  // A is a BlockedMultiVector (and compatible with this)
390  // Call update recursively on all sub vectors
391  TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() != bA->getBlockedMap()->getThyraMode(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: update with incompatible vector (different thyra mode).");
392  TEUCHOS_TEST_FOR_EXCEPTION(map_->getNumMaps() != bA->getBlockedMap()->getNumMaps(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: update with incompatible vector (different number of partial vectors).");
393  for(size_t r = 0; r < map_->getNumMaps(); r++) {
394 
395  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.");
396  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.");
397  // TAW: 12/6 We basically want to do something like:
398  // getMultiVector(r)->update(alpha, *(bA->getMultiVector(r)), beta);
399  // But if the left hand side is a standard MultiVector and bA->getMultiVector(r) is
400  // a blocked MultiVector this will not work, as the update implementation of the standard
401  // multivector cannot deal with blocked multivectors.
402  // The only use case where this could happen is, if the rhs vector is a single block multivector
404  Teuchos::RCP<MultiVector> rmv = bA->getMultiVector(r);
405 
406  // check whether lmv/rmv are blocked or not
407  Teuchos::RCP<BlockedMultiVector> blmv = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(lmv);
408  Teuchos::RCP<BlockedMultiVector> brmv = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(rmv);
409 
410  if(blmv.is_null() == true && brmv.is_null() == false) {
411  // special case: lmv is standard MultiVector but rmv is BlockedMultiVector
412  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.");
413  lmv->update(alpha, *(brmv->getMultiVector(0)), beta);
414  } else
415  lmv->update(alpha, *rmv, beta);
416  }
417  } else {
418  // A is a MultiVector
419  // If this is a BlockedMultiVector with only one sub-vector of same length we can just update
420  // Otherwise, A is not compatible with this as BlockedMultiVector and we have to extract the vector data from A
421 
422  if(getBlockedMap()->getNumMaps() == 1) {
423  // Actually call "update" on the underlying MultiVector (Epetra or Tpetra).
424  // The maps have to be compatible.
425  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).");
426  getMultiVector(0)->update(alpha,*rcpA,beta);
427  } else {
428  // general case: A has to be splitted and subparts have to be extracted and stored in this BlockedMultiVector
429  //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!");
430  for(size_t r = 0; r < map_->getNumMaps(); r++) {
431  // Call "update" on the subvector. Note, that getMultiVector(r) could return another BlockedMultiVector.
432  // That is, in Thyra mode the maps could differ (local Xpetra versus Thyra style gids)
433  Teuchos::RCP<const MultiVector> part = this->ExtractVector(rcpA, r, map_->getThyraMode());
434  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.");
435  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.");
436  getMultiVector(r)->update(alpha, *part, beta);
437  }
438  }
439  }
440  }
441 
443  virtual void update(const Scalar &alpha, const MultiVector&A, const Scalar &beta, const MultiVector&B, const Scalar &gamma) {
444  XPETRA_MONITOR("BlockedMultiVector::update2");
445  Teuchos::RCP<const MultiVector> rcpA = Teuchos::rcpFromRef(A);
446  Teuchos::RCP<const MultiVector> rcpB = Teuchos::rcpFromRef(B);
447  Teuchos::RCP<const BlockedMultiVector> bA = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpA);
448  Teuchos::RCP<const BlockedMultiVector> bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
449  if(bA != Teuchos::null && bB != Teuchos::null) {
450  TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() != bA->getBlockedMap()->getThyraMode(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: update with incompatible vector (different thyra mode in vector A).");
451  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).");
452  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).");
453  TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() != bB->getBlockedMap()->getThyraMode(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::update: update with incompatible vector (different thyra mode in vector B).");
454  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).");
455  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).");
456 
457  for(size_t r = 0; r < map_->getNumMaps(); r++) {
458  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 << ").");
459  getMultiVector(r)->update(alpha, *(bA->getMultiVector(r)), beta, *(bB->getMultiVector(r)), gamma);
460  }
461  return;
462  }
463  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::update: only supports update with other BlockedMultiVector.");
464  }
465 
467  virtual void norm1(const Teuchos::ArrayView< typename Teuchos::ScalarTraits< Scalar >::magnitudeType > &norms) const {
468  XPETRA_MONITOR("BlockedMultiVector::norm1");
469  typedef typename ScalarTraits<Scalar>::magnitudeType Magnitude;
470  Array<Magnitude> temp_norms(getNumVectors());
471  std::fill(norms.begin(),norms.end(),ScalarTraits<Magnitude>::zero());
472  std::fill(temp_norms.begin(),temp_norms.end(),ScalarTraits<Magnitude>::zero());
473  for (size_t r = 0; r < map_->getNumMaps(); ++r) {
474  if(getMultiVector(r)!=Teuchos::null) {
475  getMultiVector(r)->norm1(temp_norms);
476  for (size_t c = 0; c < getNumVectors(); ++c)
477  norms[c] += temp_norms[c];
478  }
479  }
480  }
481 
483  virtual void norm2(const Teuchos::ArrayView< typename Teuchos::ScalarTraits< Scalar >::magnitudeType > &norms) const {
484  XPETRA_MONITOR("BlockedMultiVector::norm2");
485  typedef typename ScalarTraits<Scalar>::magnitudeType Magnitude;
486  Array<Magnitude> results(getNumVectors());
487  Array<Magnitude> temp_norms(getNumVectors());
488  std::fill(norms.begin(),norms.end(),ScalarTraits<Magnitude>::zero());
489  std::fill(results.begin(),results.end(),ScalarTraits<Magnitude>::zero());
490  std::fill(temp_norms.begin(),temp_norms.end(),ScalarTraits<Magnitude>::zero());
491  for (size_t r = 0; r < map_->getNumMaps(); ++r) {
492  if(getMultiVector(r)!=Teuchos::null) {
493  getMultiVector(r)->norm2(temp_norms);
494  for (size_t c = 0; c < getNumVectors(); ++c)
495  results[c] += temp_norms[c] * temp_norms[c];
496  }
497  }
498  for (size_t c = 0; c < getNumVectors(); ++c)
499  norms[c] = Teuchos::ScalarTraits<Magnitude >::squareroot(results[c]);
500  }
501 
503  virtual void normInf(const Teuchos::ArrayView< typename Teuchos::ScalarTraits< Scalar >::magnitudeType > &norms) const {
504  XPETRA_MONITOR("BlockedMultiVector::normInf");
505  typedef typename ScalarTraits<Scalar>::magnitudeType Magnitude;
506  Array<Magnitude> temp_norms(getNumVectors());
507  std::fill(norms.begin(),norms.end(),ScalarTraits<Magnitude>::zero());
508  std::fill(temp_norms.begin(),temp_norms.end(),ScalarTraits<Magnitude>::zero());
509  for (size_t r = 0; r < map_->getNumMaps(); ++r) {
510  if(getMultiVector(r)!=Teuchos::null) {
511  getMultiVector(r)->normInf(temp_norms);
512  for (size_t c = 0; c < getNumVectors(); ++c)
513  norms[c] = std::max(norms[c],temp_norms[c]);
514  }
515  }
516  }
517 
519  virtual void meanValue(const Teuchos::ArrayView< Scalar > &/* means */) const {
520  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::meanValue: Not (yet) supported by BlockedMultiVector.");
521  }
522 
524  virtual void multiply(Teuchos::ETransp /* transA */, Teuchos::ETransp /* transB */, const Scalar &/* alpha */, const MultiVector&/* A */, const MultiVector&/* B */, const Scalar &/* beta */) {
525  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::multiply: Not (yet) supported by BlockedMultiVector.");
526  }
527 
529  virtual void elementWiseMultiply(Scalar scalarAB, const Xpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node>&A, const MultiVector&B, Scalar scalarThis) {
530  XPETRA_MONITOR("BlockedMultiVector::elementWiseMultiply");
531  XPETRA_TEST_FOR_EXCEPTION(B.getMap()->isSameAs(*(this->getMap()))==false, Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::elementWiseMultipy: B must have same blocked map than this.");
532  //XPETRA_TEST_FOR_EXCEPTION(A.getMap()->isSameAs(*(this->getMap()))==false, Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::elementWiseMultipy: A must have same blocked map than this.");
533  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() << ".");
534  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() << ".");
535 
539  Teuchos::rcp_dynamic_cast<const Xpetra::BlockedVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(rcpA);
540 
541  RCP<const MultiVector> rcpB = Teuchos::rcpFromRef(B);
542  RCP<const BlockedMultiVector> bB = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpB);
543  TEUCHOS_TEST_FOR_EXCEPTION(bB.is_null() == true, Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::elementWiseMultipy: B must be a BlockedMultiVector.");
544 
545  //RCP<Xpetra::MapExtractor<Scalar,LocalOrdinal,GlobalOrdinal,Node> > me = Teuchos::rcp(new Xpetra::MapExtractor<Scalar,LocalOrdinal,GlobalOrdinal,Node>(bmap));
546 
547  for(size_t m = 0; m < bmap->getNumMaps(); m++) {
549  bA->getMultiVector(m, bmap->getThyraMode())->getVector(0);
551  bB->getMultiVector(m, bmap->getThyraMode());
553  this->getMultiVector(m, bmap->getThyraMode());
554 
555  thisPart->elementWiseMultiply(scalarAB,*partA,*partB,scalarThis);
556  }
557  }
558 
560 
562 
563 
565  virtual size_t getNumVectors() const {
566  return numVectors_;
567  }
568 
570  virtual size_t getLocalLength() const {
571  XPETRA_MONITOR("BlockedMultiVector::getLocalLength()");
572  return map_->getFullMap()->getNodeNumElements();
573  }
574 
576  virtual global_size_t getGlobalLength() const {
577  XPETRA_MONITOR("BlockedMultiVector::getGlobalLength()");
578  return map_->getFullMap()->getGlobalNumElements();
579  }
580 
583  const BlockedMultiVector * Vb = dynamic_cast<const BlockedMultiVector *>(&vec);
584  if(!Vb) return false;
585  for (size_t r = 0; r < map_->getNumMaps(); ++r) {
588  if((a==Teuchos::null && b != Teuchos::null) ||
589  (a!=Teuchos::null && b == Teuchos::null))
590  return false;
591  if(a!=Teuchos::null && b !=Teuchos::null && !a->isSameSize(*b))
592  return false;
593  }
594  return true;
595  }
596 
598 
600 
601 
603  virtual std::string description() const {
604  return std::string("BlockedMultiVector");
605  }
606 
609  out << description() << std::endl;
610  for(size_t r = 0; r < map_->getNumMaps(); r++)
611  getMultiVector(r)->describe(out, verbLevel);
612  }
613 
614  virtual void replaceMap(const RCP<const Map>& map) {
615  XPETRA_MONITOR("BlockedMultiVector::replaceMap");
616  RCP<const BlockedMap> bmap = Teuchos::rcp_dynamic_cast<const BlockedMap>(map);
617  if (bmap.is_null() == true) {
618  // if this has more than 1 sub blocks but "map" is not a blocked map, they are very likely not compatible
619  if (this->getBlockedMap()->getNumMaps() > 1) {
620  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::replaceMap: map is not of type BlockedMap. General implementation not available, yet.");
622  }
623  // special case: this is a blocked map with only one block
624  // TODO add more debug check (especially for Thyra mode)
625  std::vector<Teuchos::RCP<const Map> > subMaps (1, map);
626  map_ = Teuchos::rcp(new BlockedMap(map, subMaps,this->getBlockedMap()->getThyraMode()));
627  this->getMultiVector(0)->replaceMap(map);
628  return;
629  }
630  RCP<const BlockedMap> mybmap = Teuchos::rcp_dynamic_cast<const BlockedMap>(map_);
631 
632  XPETRA_TEST_FOR_EXCEPTION(mybmap->getThyraMode() != bmap->getThyraMode(), Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::replaceMap: inconsistent Thyra mode");
633  map_ = bmap;
634  for(size_t r = 0; r < map_->getNumMaps(); r++)
635  getMultiVector(r)->replaceMap(bmap->getMap(r,map_->getThyraMode()));
636  }
637 
639  virtual void doImport(const DistObject<Scalar, LocalOrdinal, GlobalOrdinal, Node> &/* source */, const Import& /* importer */, CombineMode /* CM */) {
640  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::doImport: Not supported by BlockedMultiVector.");
641  }
642 
644  virtual void doExport(const DistObject<Scalar, LocalOrdinal, GlobalOrdinal, Node> &/* dest */, const Import& /* importer */, CombineMode /* CM */) {
645  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::doExport: Not supported by BlockedMultiVector.");
646  }
647 
649  virtual void doImport(const DistObject<Scalar, LocalOrdinal, GlobalOrdinal, Node> &/* source */, const Export& /* exporter */, CombineMode /* CM */) {
650  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::doImport: Not supported by BlockedMultiVector.");
651  }
652 
654  virtual void doExport(const DistObject<Scalar, LocalOrdinal, GlobalOrdinal, Node> &/* dest */, const Export& /* exporter */, CombineMode /* CM */) {
655  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::doExport: Not supported by BlockedMultiVector.");
656  }
657 
659 
661 
662 
664  virtual void setSeed(unsigned int seed) {
665  for(size_t r = 0; r < map_->getNumMaps(); ++r) {
666  getMultiVector(r)->setSeed(seed);
667  }
668  }
669 
670 
671  virtual void randomize(bool bUseXpetraImplementation = false) {
672  for(size_t r = 0; r < map_->getNumMaps(); ++r) {
673  getMultiVector(r)->randomize(bUseXpetraImplementation);
674  }
675  }
676 
678  virtual void Xpetra_randomize()
679  {
681  }
682 
683 #ifdef HAVE_XPETRA_KOKKOS_REFACTOR
684  typedef typename Kokkos::Details::ArithTraits<Scalar>::val_type impl_scalar_type;
685  typedef Kokkos::DualView<impl_scalar_type**, Kokkos::LayoutStride,
686  typename node_type::execution_space,
687  Kokkos::MemoryUnmanaged> dual_view_type;
688  typedef typename dual_view_type::host_mirror_space host_execution_space;
689  typedef typename dual_view_type::t_dev::execution_space dev_execution_space;
690 
696  template<class TargetDeviceType>
697  typename Kokkos::Impl::if_c<
698  Kokkos::Impl::is_same<
699  typename dev_execution_space::memory_space,
700  typename TargetDeviceType::memory_space>::value,
701  typename dual_view_type::t_dev_um,
702  typename dual_view_type::t_host_um>::type
703  getLocalView () const {
704  if(Kokkos::Impl::is_same<
705  typename host_execution_space::memory_space,
706  typename TargetDeviceType::memory_space
707  >::value) {
708  return getHostLocalView();
709  } else {
710  return getDeviceLocalView();
711  }
712  }
713 
714  virtual typename dual_view_type::t_host_um getHostLocalView () const {
715  typename dual_view_type::t_host_um test;
716  return test;
717  }
718  virtual typename dual_view_type::t_dev_um getDeviceLocalView() const {
719  typename dual_view_type::t_dev_um test;
720  return test;
721  }
722 
723 #endif
724 
726 
728  Teuchos::RCP< const Map> getMap() const { XPETRA_MONITOR("BlockedMultiVector::getMap"); return map_; }
729 
732 
735  XPETRA_MONITOR("BlockedMultiVector::getMultiVector(r)");
736  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.");
737  return vv_[r];
738  }
739 
741  Teuchos::RCP<MultiVector> getMultiVector(size_t r, bool bThyraMode) const {
742  XPETRA_MONITOR("BlockedMultiVector::getMultiVector(r,bThyraMode)");
743  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.");
744  XPETRA_TEST_FOR_EXCEPTION(map_->getThyraMode() != bThyraMode, Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::getMultiVector: inconsistent Thyra mode");
745  (void)bThyraMode; // avoid unused parameter warning when HAVE_XPETRA_DEBUG isn't defined
746  return vv_[r];
747  }
748 
750  void setMultiVector(size_t r, Teuchos::RCP<const MultiVector> v, bool bThyraMode) {
751  // The map of the MultiVector should be the same as the stored submap
752  // In thyra mode the vectors should live on the thyra maps
753  // in xpetra mode the should live in the xpetra maps
754  // that should be also ok in the nested case for thyra (if the vectors are distributed accordingly)
755  XPETRA_MONITOR("BlockedMultiVector::setMultiVector");
756  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.");
757  XPETRA_TEST_FOR_EXCEPTION(numVectors_ != v->getNumVectors(),Xpetra::Exceptions::RuntimeError,"The BlockedMultiVectors expects " << getNumVectors() << " vectors. The provided partial multivector has " << v->getNumVectors() << " vectors.");
758  XPETRA_TEST_FOR_EXCEPTION(map_->getThyraMode() != bThyraMode, Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::setMultiVector: inconsistent Thyra mode");
759  (void)bThyraMode; // avoid unused parameter warning when HAVE_XPETRA_DEBUG isn't defined
760  Teuchos::RCP<MultiVector> vv = Teuchos::rcp_const_cast<MultiVector>(v);
761  TEUCHOS_TEST_FOR_EXCEPTION(vv==Teuchos::null, Xpetra::Exceptions::RuntimeError, "Partial vector must not be Teuchos::null");
762  vv_[r] = vv;
763  }
764 
767  XPETRA_MONITOR("BlockedMultiVector::Merge");
768  using Teuchos::RCP;
769 
771  for(size_t r = 0; r < map_->getNumMaps(); ++r) {
773  RCP<BlockedMultiVector> bvi = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(vi);
774  if(bvi.is_null() == true) {
775  this->InsertVector(vi,r,v,map_->getThyraMode());
776  } else {
777  RCP<MultiVector> mvi = bvi->Merge();
778  this->InsertVector(mvi,r,v,map_->getThyraMode());
779  }
780  }
781 
782  // TODO plausibility checks
783 
784  return v;
785  }
786 
787 
788  protected:
795  virtual void assign (const MultiVector& rhs) {
796  Teuchos::RCP<const MultiVector> rcpRhs = Teuchos::rcpFromRef(rhs);
797  Teuchos::RCP<const BlockedMultiVector> bRhs = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(rcpRhs);
798  if(bRhs == Teuchos::null)
799  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::assign: argument is not a blocked multi vector.");
800 
801  map_ = Teuchos::rcp(new BlockedMap(*(bRhs->getBlockedMap())));
802  vv_ = std::vector<Teuchos::RCP<MultiVector> >(map_->getNumMaps());
803  for(size_t r = 0; r < map_->getNumMaps(); ++r) {
804  // extract source vector (is of type MultiVector or BlockedMultiVector)
805  RCP<MultiVector> src = bRhs->getMultiVector(r,map_->getThyraMode());
806 
807  // create new (empty) multivector (is of type MultiVector or BlockedMultiVector)
808  RCP<MultiVector> vv = Xpetra::MultiVectorFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Build(map_->getMap(r,bRhs->getBlockedMap()->getThyraMode()),rcpRhs->getNumVectors(),true);
809 
810  // check type of source and target vector
811  RCP<BlockedMultiVector> bsrc = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(src);
812  RCP<BlockedMultiVector> bvv = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(vv);
813  if(bsrc.is_null() == true && bvv.is_null() == true) {
814  *vv = *src; // deep copy
815  } else if (bsrc.is_null() == true && bvv.is_null() == false) {
816  // special case: source vector is a merged MultiVector but target vector is blocked
817  *vv = *src; // deep copy (is this a problem???)
818  } else if (bsrc.is_null() == false && bvv.is_null() == true) {
819  // special case: source vector is blocked but target vector is a merged MultiVector
820  // This is a problem and only works if bsrc has only one block
821  if(bsrc->getBlockedMap()->getNumMaps() > 1) {
822  throw Xpetra::Exceptions::RuntimeError("BlockedMultiVector::assign: source vector is of type BlockedMultiVector (with more than 1 blocks) and target is a MultiVector.");
824  }
825  RCP<MultiVector> ssrc = bsrc->getMultiVector(0,map_->getThyraMode());
826  XPETRA_TEST_FOR_EXCEPTION(ssrc.is_null() == true, Xpetra::Exceptions::RuntimeError, "BlockedMultiVector::assign: cannot extract vector");
827  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.");
828  *vv = *ssrc;
829  } else {
830  // this should work (no exception necessary, i guess)
831  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.");
832  *vv = *src; // deep copy
833  }
834  vv_[r] = vv;
835  }
836  numVectors_ = rcpRhs->getNumVectors();
837  }
838 
839  private:
840  // helper routines for interaction of MultiVector and BlockedMultiVectors
841 
842  void ExtractVector(RCP<const MultiVector>& full, size_t block, RCP<MultiVector>& partial) const { ExtractVector(*full, block, *partial); }
843  void ExtractVector(RCP< MultiVector>& full, size_t block, RCP<MultiVector>& partial) const { ExtractVector(*full, block, *partial); }
844 
845  RCP<MultiVector> ExtractVector(RCP<const MultiVector>& full, size_t block, bool bThyraMode = false) const {
846  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.");
848  "ExtractVector: map_->getmap(" << block << ",false) is null");
849  RCP<const BlockedMultiVector> bfull = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(full);
850  if(bfull.is_null() == true) {
851  // standard case: full is not of type BlockedMultiVector
852  // first extract partial vector from full vector (using xpetra style GIDs)
853  const RCP<MultiVector> vv = Xpetra::MultiVectorFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Build(map_->getMap(block,false), full->getNumVectors(), false);
854  //if(bThyraMode == false) {
855  // ExtractVector(*full, block, *vv);
856  // return vv;
857  //} else {
858  RCP<const Map> oldThyMapFull = full->getMap(); // temporarely store map of full
859  RCP<MultiVector> rcpNonConstFull = Teuchos::rcp_const_cast<MultiVector>(full);
860  rcpNonConstFull->replaceMap(map_->getImporter(block)->getSourceMap());
861  ExtractVector(*rcpNonConstFull, block, *vv);
862  TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true, Xpetra::Exceptions::RuntimeError,
863  "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
864  if(bThyraMode == true)
865  vv->replaceMap(map_->getMap(block,true)); // switch to Thyra-style map
866  rcpNonConstFull->replaceMap(oldThyMapFull);
867  return vv;
868  //}
869  } else {
870  // special case: full is of type BlockedMultiVector
871  XPETRA_TEST_FOR_EXCEPTION(map_->getNumMaps() != bfull->getBlockedMap()->getNumMaps(), Xpetra::Exceptions::RuntimeError,
872  "ExtractVector: Number of blocks in map extractor is " << map_->getNumMaps() << " but should be " << bfull->getBlockedMap()->getNumMaps() << " (number of blocks in BlockedMultiVector)");
873  return bfull->getMultiVector(block,bThyraMode);
874  }
875  }
876  RCP<MultiVector> ExtractVector(RCP< MultiVector>& full, size_t block, bool bThyraMode = false) const {
877  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.");
879  "ExtractVector: map_->getmap(" << block << ",false) is null");
880  RCP<BlockedMultiVector> bfull = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(full);
881  if(bfull.is_null() == true) {
882  // standard case: full is not of type BlockedMultiVector
883  // first extract partial vector from full vector (using xpetra style GIDs)
884  const RCP<MultiVector> vv = Xpetra::MultiVectorFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Build(map_->getMap(block,false), full->getNumVectors(), false);
885  //if(bThyraMode == false) {
886  // ExtractVector(*full, block, *vv);
887  // return vv;
888  //} else {
889  RCP<const Map> oldThyMapFull = full->getMap(); // temporarely store map of full
890  full->replaceMap(map_->getImporter(block)->getSourceMap());
891  ExtractVector(*full, block, *vv);
892  TEUCHOS_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true, Xpetra::Exceptions::RuntimeError,
893  "MapExtractor::ExtractVector: ExtractVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
894  if(bThyraMode == true)
895  vv->replaceMap(map_->getMap(block,true)); // switch to Thyra-style map
896  full->replaceMap(oldThyMapFull);
897  return vv;
898  //}
899  } else {
900  // special case: full is of type BlockedMultiVector
901  XPETRA_TEST_FOR_EXCEPTION(map_->getNumMaps() != bfull->getBlockedMap()->getNumMaps(), Xpetra::Exceptions::RuntimeError,
902  "ExtractVector: Number of blocks in map extractor is " << map_->getNumMaps() << " but should be " << bfull->getBlockedMap()->getNumMaps() << " (number of blocks in BlockedMultiVector)");
903  return bfull->getMultiVector(block,bThyraMode);
904  }
905  }
906  void ExtractVector(const MultiVector& full, size_t block, MultiVector& partial) const {
907  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.");
909  "ExtractVector: maps_[" << block << "] is null");
910  partial.doImport(full, *(map_->getImporter(block)), Xpetra::INSERT);
911  }
912 
913  void InsertVector(const MultiVector& partial, size_t block, MultiVector& full, bool bThyraMode = false) const {
914  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.");
916  "ExtractVector: map_->getmap(" << block << ",false) is null");
917  XPETRA_TEST_FOR_EXCEPTION(map_->getThyraMode() == false && bThyraMode == true, Xpetra::Exceptions::RuntimeError,
918  "MapExtractor::InsertVector: InsertVector in Thyra-style numbering only possible if MapExtractor has been created using Thyra-style numbered submaps.");
919  if(bThyraMode) {
920  // NOTE: the importer objects in the BlockedMap are always using Xpetra GIDs (or Thyra style Xpetra GIDs)
921  // The source map corresponds to the full map (in Xpetra GIDs) starting with GIDs from zero. The GIDs are consecutive in Thyra mode
922  // The target map is the partial map (in the corresponding Xpetra GIDs)
923 
924  // TODO can we skip the Export call in special cases (i.e. Src = Target map, same length, etc...)
925 
926  // store original GIDs (could be Thyra GIDs)
927  RCP<const MultiVector> rcpPartial = Teuchos::rcpFromRef(partial);
928  RCP<MultiVector> rcpNonConstPartial = Teuchos::rcp_const_cast<MultiVector>(rcpPartial);
929  RCP<const Map> oldThyMapPartial = rcpNonConstPartial->getMap(); // temporarely store map of partial
930  RCP<const Map> oldThyMapFull = full.getMap(); // temporarely store map of full
931 
932  // check whether getMap(block,false) is identical to target map of importer
933  //XPETRA_TEST_FOR_EXCEPTION(map_->getMap(block,false)->isSameAs(*(map_->getImporter(block)->getTargetMap()))==false, Xpetra::Exceptions::RuntimeError,
934  // "MapExtractor::InsertVector: InsertVector in Thyra-style mode: Xpetra GIDs of partial vector are not identical to target Map of Importer. This should not be.");
935 
936  //XPETRA_TEST_FOR_EXCEPTION(full.getMap()->isSameAs(*(map_->getImporter(block)->getSourceMap()))==false, Xpetra::Exceptions::RuntimeError,
937  // "MapExtractor::InsertVector: InsertVector in Thyra-style mode: Xpetra GIDs of full vector are not identical to source Map of Importer. This should not be.");
938 
939  rcpNonConstPartial->replaceMap(map_->getMap(block,false)); // temporarely switch to xpetra-style map
940  full.replaceMap(map_->getImporter(block)->getSourceMap()); // temporarely switch to Xpetra GIDs
941 
942  // do the Export
943  full.doExport(*rcpNonConstPartial, *(map_->getImporter(block)), Xpetra::INSERT);
944 
945  // switch back to original maps
946  full.replaceMap(oldThyMapFull); // reset original map (Thyra GIDs)
947  rcpNonConstPartial->replaceMap(oldThyMapPartial); // change map back to original map
948  } else {
949  // Xpetra style numbering
950  full.doExport(partial, *(map_->getImporter(block)), Xpetra::INSERT);
951  }
952  }
953  void InsertVector(RCP<const MultiVector> partial, size_t block, RCP<MultiVector> full, bool bThyraMode = false) const {
955  if(bfull.is_null() == true)
956  InsertVector(*partial, block, *full, bThyraMode);
957  else {
959  "InsertVector: maps_[" << block << "] is null");
960  full->setMultiVector(block, partial, bThyraMode);
961  }
962  }
963  void InsertVector(RCP< MultiVector> partial, size_t block, RCP<MultiVector> full, bool bThyraMode = false) const {
965  if(bfull.is_null() == true)
966  InsertVector(*partial, block, *full, bThyraMode);
967  else {
969  "InsertVector: maps_[" << block << "] is null");
970  bfull->setMultiVector(block, partial, bThyraMode);
971  }
972  }
973 
974  private:
976  std::vector<Teuchos::RCP<MultiVector> > vv_;
977  size_t numVectors_;
978  }; // BlockedMultiVector class
979 
980 } // Xpetra namespace
981 
982 #define XPETRA_BLOCKEDMULTIVECTOR_SHORT
983 #endif // XPETRA_BLOCKEDMULTIVECTOR_HPP
virtual void replaceGlobalValue(GlobalOrdinal, size_t, const Scalar &)
Replace value, using global (row) index.
Teuchos::RCP< MultiVector > getMultiVector(size_t r) const
return partial multivector associated with block row r
void ExtractVector(RCP< MultiVector > &full, size_t block, RCP< MultiVector > &partial) const
virtual void reciprocal(const MultiVector &)
Put element-wise reciprocal values of input Multi-vector in target, this(i,j) = 1/A(i,j).
virtual void setSeed(unsigned int seed)
Set seed for Random function.
virtual void sumIntoGlobalValue(GlobalOrdinal, size_t, const Scalar &)
Add value to existing value, using global (row) index.
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;).
virtual void replaceLocalValue(LocalOrdinal, size_t, const Scalar &)
Replace value, using local (row) index.
virtual std::string description() const
A simple one-line description of this object.
RCP< MultiVector > ExtractVector(RCP< const MultiVector > &full, size_t block, bool bThyraMode=false) const
virtual void doExport(const DistObject< Scalar, LocalOrdinal, GlobalOrdinal, Node > &, const Export &, CombineMode)
Export (using an Importer).
std::vector< Teuchos::RCP< MultiVector > > vv_
array containing RCPs of the partial vectors
virtual void multiply(Teuchos::ETransp, Teuchos::ETransp, const Scalar &, const MultiVector &, const MultiVector &, const Scalar &)
Matrix-matrix multiplication: this = beta*this + alpha*op(A)*op(B).
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
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 Xpetra_randomize()
Set multi-vector values to random numbers. XPetra implementation.
BlockedMultiVector(const Teuchos::RCP< const BlockedMap > &map, size_t NumVectors, bool zeroOut=true)
Constructor.
Teuchos::RCP< const Map > getMap() const
Access function for the underlying Map this DistObject was constructed with.
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.
void InsertVector(RCP< MultiVector > partial, size_t block, RCP< MultiVector > full, bool bThyraMode=false) const
virtual void scale(const Scalar &alpha)
Scale the current values of a multi-vector, this = alpha*this.
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 doImport(const DistObject< Scalar, LocalOrdinal, GlobalOrdinal, Node > &, const Import &, CombineMode)
Import.
virtual Teuchos::ArrayRCP< Scalar > getDataNonConst(size_t j)
View of the local values in a particular vector of this multivector.
virtual void abs(const MultiVector &)
Put element-wise absolute values of input Multi-vector in target: A = abs(this).
BlockedMultiVector(Teuchos::RCP< const Xpetra::BlockedMap< LocalOrdinal, GlobalOrdinal, Node > > bmap, Teuchos::RCP< MultiVector > v)
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;).
size_t numVectors_
number of vectors (columns in multi vector)
RCP< MultiVector > ExtractVector(RCP< MultiVector > &full, size_t block, bool bThyraMode=false) const
virtual global_size_t getGlobalLength() const
Global number of rows in the multivector.
void ExtractVector(const MultiVector &full, size_t block, MultiVector &partial) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::RCP< MultiVector > getMultiVector(size_t r, bool bThyraMode) const
return partial multivector associated with block row r
virtual bool isSameSize(const Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &vec) const
Local number of rows on the calling process.
virtual void Xpetra_randomize()
Set multi-vector values to random numbers. XPetra implementation.
BlockedMultiVector(const Teuchos::RCP< const BlockedMap > &map, std::vector< Teuchos::RCP< MultiVector > > &vin)
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 doImport(const DistObject< Scalar, LocalOrdinal, GlobalOrdinal, Node > &, const Export &, CombineMode)
Import (using an Exporter).
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 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.
virtual void assign(const MultiVector &rhs)
Implementation of the assignment operator (operator=); does a deep copy.
void setMultiVector(size_t r, Teuchos::RCP< const MultiVector > v, bool bThyraMode)
set partial multivector associated with block row r
virtual void sumIntoLocalValue(LocalOrdinal, size_t, const Scalar &)
Add value to existing value, using local (row) index.
BlockedMultiVector(Teuchos::RCP< const Xpetra::MapExtractor< Scalar, LocalOrdinal, GlobalOrdinal, Node > > mapExtractor, Teuchos::RCP< MultiVector > v)
virtual void randomize(bool bUseXpetraImplementation=false)
Set multi-vector values to random numbers.
size_t global_size_t
Global size_t object.
iterator end()
static const EVerbosityLevel verbLevel_default
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 InsertVector(const MultiVector &partial, size_t block, MultiVector &full, bool bThyraMode=false) const
Teuchos::RCP< MultiVector > Merge() const
merge BlockedMultiVector blocks to a single MultiVector
virtual void normInf(const Teuchos::ArrayView< typename Teuchos::ScalarTraits< Scalar >::magnitudeType > &norms) const
Compute Inf-norm of each vector in multi-vector.
#define TEUCHOS_UNREACHABLE_RETURN(dummyReturnVal)
#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 norm2(const Teuchos::ArrayView< typename Teuchos::ScalarTraits< Scalar >::magnitudeType > &norms) const
virtual void putScalar(const Scalar &value)
Set all values in the multivector with the given value.
virtual Teuchos::ArrayRCP< const Scalar > getData(size_t j) const
Const view of the local values in a particular vector of this multivector.
void ExtractVector(RCP< const MultiVector > &full, size_t block, RCP< MultiVector > &partial) const
virtual void meanValue(const Teuchos::ArrayView< Scalar > &) const
Compute mean (average) value of each vector in multi-vector. The outcome of this routine is undefined...
static Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Build(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &map, size_t NumVectors, bool zeroOut=true)
Constructor specifying the number of non-zeros for all rows.
virtual void norm1(const Teuchos::ArrayView< typename Teuchos::ScalarTraits< Scalar >::magnitudeType > &norms) const
Compute 1-norm of each vector in multi-vector.
virtual size_t getLocalLength() const
Local number of rows on the calling process.
CombineMode
Xpetra::Combine Mode enumerable type.
#define XPETRA_MONITOR(funcName)
void InsertVector(RCP< const MultiVector > partial, size_t block, RCP< MultiVector > full, bool bThyraMode=false) const
virtual void dot(const MultiVector &, const Teuchos::ArrayView< Scalar > &) const
Compute dot product of each corresponding pair of vectors, dots[i] = this[i].dot(A[i]).
virtual void doExport(const DistObject< Scalar, LocalOrdinal, GlobalOrdinal, Node > &, const Import &, CombineMode)
Export.
BlockedMultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > & operator=(const MultiVector &rhs)
Assignment operator: Does a deep copy.
iterator begin()
BlockedMultiVector(Teuchos::RCP< const Xpetra::MapExtractor< Scalar, LocalOrdinal, GlobalOrdinal, Node > > mapExtractor, Teuchos::RCP< const MultiVector > v)
virtual size_t getNumVectors() const
Number of columns in the multivector.
Teuchos::RCP< const Xpetra::BlockedMap< LocalOrdinal, GlobalOrdinal, Node > > getBlockedMap() const
Access function for the underlying Map this DistObject was constructed with.
virtual Teuchos::RCP< Xpetra::Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getVectorNonConst(size_t j)
Return a Vector which is a nonconst view of column j.
bool is_null() const