Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Thyra_DefaultMultiVectorProductVector_def.hpp
1 // @HEADER
2 // *****************************************************************************
3 // Thyra: Interfaces and Support for Abstract Numerical Algorithms
4 //
5 // Copyright 2004 NTESS and the Thyra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef THYRA_DEFAULT_MULTI_VECTOR_PRODUCT_VECTOR_HPP
11 #define THYRA_DEFAULT_MULTI_VECTOR_PRODUCT_VECTOR_HPP
12 
13 
14 #include "Thyra_DefaultMultiVectorProductVector_decl.hpp"
15 #include "Thyra_DefaultMultiVectorProductVectorSpace.hpp"
16 #include "Thyra_AssertOp.hpp"
17 #include "Teuchos_Assert.hpp"
18 
19 
20 namespace Thyra {
21 
22 
23 // Constructors/initializers/accessors
24 
25 
26 template <class Scalar>
28 {
29  uninitialize();
30 }
31 
32 
33 template <class Scalar>
35  const RCP<const DefaultMultiVectorProductVectorSpace<Scalar> > &productSpace_in,
36  const RCP<MultiVectorBase<Scalar> > &multiVec
37  )
38 {
39 #ifdef TEUCHOS_DEBUG
40  TEUCHOS_TEST_FOR_EXCEPT(is_null(productSpace_in));
43  "DefaultMultiVectorProductVector<Scalar>::initialize(productSpace,multiVec)",
44  *multiVec->range(), *productSpace_in->getBlock(0)
45  );
46  TEUCHOS_ASSERT_EQUALITY( multiVec->domain()->dim(), productSpace_in->numBlocks());
47 #endif
48 
49  numBlocks_ = productSpace_in->numBlocks();
50 
51  productSpace_ = productSpace_in;
52 
53  multiVec_ = multiVec;
54 
55 }
56 
57 
58 template <class Scalar>
60  const RCP<const DefaultMultiVectorProductVectorSpace<Scalar> > &productSpace_in,
61  const RCP<const MultiVectorBase<Scalar> > &multiVec
62  )
63 {
64 #ifdef TEUCHOS_DEBUG
65  TEUCHOS_TEST_FOR_EXCEPT(is_null(productSpace_in));
68  "DefaultMultiVectorProductVector<Scalar>::initialize(productSpace_in,multiVec)",
69  *multiVec->range(), *productSpace_in->getBlock(0)
70  );
71  TEUCHOS_ASSERT_EQUALITY( multiVec->domain()->dim(), productSpace_in->numBlocks() );
72 #endif
73 
74  numBlocks_ = productSpace_in->numBlocks();
75 
76  productSpace_ = productSpace_in;
77 
78  multiVec_ = multiVec;
79 
80 }
81 
82 
83 template <class Scalar>
86 {
87  return multiVec_.getNonconstObj();
88 }
89 
90 
91 template <class Scalar>
94 {
95  return multiVec_.getConstObj();
96 }
97 
98 
99 template <class Scalar>
101 {
102  numBlocks_ = 0;
103  productSpace_ = Teuchos::null;
104  multiVec_.uninitialize();
105 }
106 
107 
108 // Overridden from Teuchos::Describable
109 
110 
111 template<class Scalar>
113 {
114  std::ostringstream oss;
115  oss
117  << "{"
118  << "dim="<<this->space()->dim()
119  << ",numColumns = "<<numBlocks_
120  << "}";
121  return oss.str();
122 }
123 
124 template<class Scalar>
126  Teuchos::FancyOStream &out_arg,
127  const Teuchos::EVerbosityLevel verbLevel
128  ) const
129 {
130  using Teuchos::OSTab;
131  using Teuchos::describe;
132  RCP<FancyOStream> out = rcp(&out_arg,false);
133  OSTab tab(out);
134  switch(verbLevel) {
136  case Teuchos::VERB_LOW:
137  *out << this->description() << std::endl;
138  break;
140  case Teuchos::VERB_HIGH:
142  {
143  *out
145  << "dim=" << this->space()->dim()
146  << "}\n";
147  OSTab tab2(out);
148  *out << "multiVec = " << Teuchos::describe(*multiVec_.getConstObj(),verbLevel);
149  break;
150  }
151  default:
152  TEUCHOS_TEST_FOR_EXCEPT(true); // Should never get here!
153  }
154 }
155 
156 
157 // Overridden from ProductVectorBase
158 
159 
160 template <class Scalar>
163 {
164 #ifdef TEUCHOS_DEBUG
165  TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE( k, 0, numBlocks_ );
166 #endif
167  return multiVec_.getNonconstObj()->col(k);
168 }
169 
170 
171 template <class Scalar>
174 {
175 #ifdef TEUCHOS_DEBUG
176  TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE( k, 0, numBlocks_ );
177 #endif
178  return multiVec_.getConstObj()->col(k);
179 }
180 
181 
182 // Overridden from ProductMultiVectorBase
183 
184 
185 template <class Scalar>
188 {
189  return productSpace_;
190 }
191 
192 
193 template <class Scalar>
195 {
196 #ifdef TEUCHOS_DEBUG
197  TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE( k, 0, numBlocks_ );
198 #else
199  (void)k;
200 #endif
201  return multiVec_.isConst();
202 }
203 
204 
205 template <class Scalar>
208 {
209  return getNonconstVectorBlock(k);
210 }
211 
212 
213 template <class Scalar>
216 {
217  return getVectorBlock(k);
218 }
219 
220 
221 // Overridden public functions from VectorBase
222 
223 
224 template <class Scalar>
227 {
228  return productSpace_;
229 }
230 
231 
232 // protected
233 
234 
235 // Overridden protected functions from VectorBase
236 
237 
238 template <class Scalar>
240  Scalar l,
241  Scalar u
242  )
243 {
244  for(int k = 0; k < numBlocks_; ++k) {
245  multiVec_.getNonconstObj()->col(k)->randomize(l, u);
246  }
247 }
248 
249 
250 template <class Scalar>
252  const VectorBase<Scalar>& x
253  )
254 {
255 #ifdef TEUCHOS_DEBUG
256  TEUCHOS_ASSERT(productSpace_->isCompatible(*x.space()));
257 #endif
258  // Apply operation block-by-block if mv is also a ProductVector
260  = Teuchos::rcp_dynamic_cast<const ProductVectorBase<Scalar> >(Teuchos::rcpFromRef(x));
261  if (nonnull(pv)) {
262  for(int k = 0; k < numBlocks_; ++k) {
263  multiVec_.getNonconstObj()->col(k)->abs(*pv->getVectorBlock(k));
264  }
265  } else {
267  }
268 }
269 
270 
271 template <class Scalar>
273  const VectorBase<Scalar>& x
274  )
275 {
276 #ifdef TEUCHOS_DEBUG
277  TEUCHOS_ASSERT(productSpace_->isCompatible(*x.space()));
278 #endif
279  // Apply operation block-by-block if mv is also a ProductVector
281  = Teuchos::rcp_dynamic_cast<const ProductVectorBase<Scalar> >(Teuchos::rcpFromRef(x));
282  if (nonnull(pv)) {
283  for(int k = 0; k < numBlocks_; ++k) {
284  multiVec_.getNonconstObj()->col(k)->reciprocal(*pv->getVectorBlock(k));
285  }
286  } else {
288  }
289 }
290 
291 
292 template <class Scalar>
294  const VectorBase<Scalar>& x
295  )
296 {
297 #ifdef TEUCHOS_DEBUG
298  TEUCHOS_ASSERT(productSpace_->isCompatible(*x.space()));
299 #endif
300  // Apply operation block-by-block if mv is also a ProductVector
302  = Teuchos::rcp_dynamic_cast<const ProductVectorBase<Scalar> >(Teuchos::rcpFromRef(x));
303  if (nonnull(pv)) {
304  for(int k = 0; k < numBlocks_; ++k) {
305  multiVec_.getNonconstObj()->col(k)->ele_wise_scale(*pv->getVectorBlock(k));
306  }
307  } else {
309  }
310 }
311 
312 
313 template <class Scalar>
316  const VectorBase<Scalar>& x
317  ) const
318 {
319 #ifdef TEUCHOS_DEBUG
320  TEUCHOS_ASSERT(productSpace_->isCompatible(*x.space()));
321 #endif
322  // Apply operation block-by-block if mv is also a ProductVector
323  typedef ScalarTraits<Scalar> ST;
325  = Teuchos::rcp_dynamic_cast<const ProductVectorBase<Scalar> >(Teuchos::rcpFromRef(x));
326  if (nonnull(pv)) {
327  typename ST::magnitudeType norm = ST::magnitude(ST::zero());
328  for(int k = 0; k < numBlocks_; ++k) {
329  typename ST::magnitudeType subNorm
330  = multiVec_.getConstObj()->col(k)->norm_2(*pv->getVectorBlock(k));
331  norm += subNorm*subNorm;
332  }
333  return ST::magnitude(ST::squareroot(norm));
334  } else {
336  }
337 }
338 
339 
340 template <class Scalar>
342  const RTOpPack::RTOpT<Scalar> &op,
343  const ArrayView<const Ptr<const VectorBase<Scalar> > > &vecs,
344  const ArrayView<const Ptr<VectorBase<Scalar> > > &targ_vecs,
345  const Ptr<RTOpPack::ReductTarget> &reduct_obj,
346  const Ordinal global_offset
347  ) const
348 {
349  this->getDefaultProductVector()->applyOp(
350  op, vecs, targ_vecs, reduct_obj, global_offset );
351 }
352 
353 
354 template <class Scalar>
356  const Range1D& rng_in, RTOpPack::ConstSubVectorView<Scalar>* sub_vec
357  ) const
358 {
359  this->getDefaultProductVector()->acquireDetachedView(rng_in,sub_vec);
360 }
361 
362 
363 template <class Scalar>
366  ) const
367 {
368  this->getDefaultProductVector()->releaseDetachedView(sub_vec);
369 }
370 
371 
372 template <class Scalar>
374  const Range1D& /* rng_in */, RTOpPack::SubVectorView<Scalar>* /* sub_vec */
375  )
376 {
377  TEUCHOS_TEST_FOR_EXCEPT("ToDo: Implement DefaultMultiVectorProductVector<Scalar>::acquireNonconstDetachedVectorViewImpl(...)!");
378 }
379 
380 
381 template <class Scalar>
383  RTOpPack::SubVectorView<Scalar>* /* sub_vec */
384  )
385 {
386  TEUCHOS_TEST_FOR_EXCEPT("ToDo: Implement DefaultMultiVectorProductVector<Scalar>::commitNonconstDetachedVectorViewImpl(...)!");
387 }
388 
389 
390 template <class Scalar>
392  const RTOpPack::SparseSubVectorT<Scalar>& /* sub_vec */
393  )
394 {
395  TEUCHOS_TEST_FOR_EXCEPT("ToDo: Implement DefaultMultiVectorProductVector<Scalar>::setSubVector(...)!");
396 }
397 
398 
399 // Overridden protected functions from VectorBase
400 
401 
402 template <class Scalar>
404 {
405  multiVec_.getNonconstObj()->assign(alpha);
406 }
407 
408 
409 template <class Scalar>
411  const MultiVectorBase<Scalar>& mv
412  )
413 {
414 #ifdef TEUCHOS_DEBUG
415  TEUCHOS_ASSERT_EQUALITY(mv.domain()->dim(), 1);
416  TEUCHOS_ASSERT(productSpace_->isCompatible(*mv.range()));
417 #endif
419  = Teuchos::rcp_dynamic_cast<const ProductMultiVectorBase<Scalar> >(Teuchos::rcpFromRef(mv));
420  if (nonnull(pv)) {
421  for(int k = 0; k < numBlocks_; ++k) {
422  multiVec_.getNonconstObj()->col(k)->assign(*pv->getMultiVectorBlock(k));
423  }
424  } else {
426  }
427 }
428 
429 
430 template <class Scalar>
432 {
433  multiVec_.getNonconstObj()->scale(alpha);
434 }
435 
436 
437 template <class Scalar>
439  Scalar alpha,
440  const MultiVectorBase<Scalar>& mv
441  )
442 {
443 #ifdef TEUCHOS_DEBUG
444  TEUCHOS_ASSERT_EQUALITY(mv.domain()->dim(), 1);
445  TEUCHOS_ASSERT(productSpace_->isCompatible(*mv.range()));
446 #endif
448  = Teuchos::rcp_dynamic_cast<const ProductMultiVectorBase<Scalar> >(Teuchos::rcpFromRef(mv));
449  if (nonnull(pv)) {
450  for(int k = 0; k < numBlocks_; ++k) {
451  multiVec_.getNonconstObj()->col(k)->update(alpha, *pv->getMultiVectorBlock(k));
452  }
453  } else {
455  }
456 }
457 
458 
459 template <class Scalar>
461  const ArrayView<const Scalar>& alpha,
462  const ArrayView<const Ptr<const MultiVectorBase<Scalar> > >& mv,
463  const Scalar& beta
464  )
465 {
466 #ifdef TEUCHOS_DEBUG
467  TEUCHOS_ASSERT_EQUALITY(alpha.size(), mv.size());
468  for (Ordinal i = 0; i < mv.size(); ++i) {
469  TEUCHOS_ASSERT_EQUALITY(mv[i]->domain()->dim(), 1);
470  TEUCHOS_ASSERT(productSpace_->isCompatible(*mv[i]->range()));
471  }
472 #endif
473 
474  // Apply operation block-by-block if each element of mv is also a ProductMultiVector
475  bool allCastsSuccessful = true;
477  for (Ordinal i = 0; i < mv.size(); ++i) {
478  pvs[i] = Teuchos::ptr_dynamic_cast<const ProductMultiVectorBase<Scalar> >(mv[i]);
479  if (pvs[i].is_null()) {
480  allCastsSuccessful = false;
481  break;
482  }
483  }
484 
485  if (allCastsSuccessful) {
486  Array<RCP<const MultiVectorBase<Scalar> > > blocks_rcp(pvs.size());
487  Array<Ptr<const MultiVectorBase<Scalar> > > blocks(pvs.size());
488  for (int k = 0; k < numBlocks_; ++k) {
489  for (Ordinal i = 0; i < pvs.size(); ++i) {
490  blocks_rcp[i] = pvs[i]->getMultiVectorBlock(k);
491  blocks[i] = blocks_rcp[i].ptr();
492  }
493  multiVec_.getNonconstObj()->col(k)->linear_combination(alpha, blocks(), beta);
494  }
495  } else {
497  }
498 }
499 
500 
501 template <class Scalar>
503  const MultiVectorBase<Scalar>& mv,
504  const ArrayView<Scalar>& prods
505  ) const
506 {
507 #ifdef TEUCHOS_DEBUG
508  TEUCHOS_ASSERT_EQUALITY(mv.domain()->dim(), 1);
509  TEUCHOS_ASSERT_EQUALITY(prods.size(), 1);
510  TEUCHOS_ASSERT(productSpace_->isCompatible(*mv.range()));
511 #endif
513  = Teuchos::rcp_dynamic_cast<const ProductMultiVectorBase<Scalar> >(Teuchos::rcpFromRef(mv));
514  if (nonnull(pv)) {
515  prods[0] = ScalarTraits<Scalar>::zero();
516  for(int k = 0; k < numBlocks_; ++k) {
517  Scalar prod;
518  multiVec_.getConstObj()->col(k)->dots(*pv->getMultiVectorBlock(k), Teuchos::arrayView(&prod, 1));
519  prods[0] += prod;
520  }
521  } else {
523  }
524 }
525 
526 
527 template <class Scalar>
529  const ArrayView<typename ScalarTraits<Scalar>::magnitudeType>& norms
530  ) const
531 {
532 #ifdef TEUCHOS_DEBUG
533  TEUCHOS_ASSERT_EQUALITY(norms.size(), 1);
534 #endif
535  typedef ScalarTraits<Scalar> ST;
536  norms[0] = ST::magnitude(ST::zero());
537  for(int k = 0; k < numBlocks_; ++k) {
538  norms[0] += multiVec_.getConstObj()->col(k)->norm_1();
539  }
540 }
541 
542 
543 template <class Scalar>
545  const ArrayView<typename ScalarTraits<Scalar>::magnitudeType>& norms
546  ) const
547 {
548 #ifdef TEUCHOS_DEBUG
549  TEUCHOS_ASSERT_EQUALITY(norms.size(), 1);
550 #endif
551  typedef ScalarTraits<Scalar> ST;
552  norms[0] = ST::magnitude(ST::zero());
553  for(int k = 0; k < numBlocks_; ++k) {
554  typename ST::magnitudeType subNorm = multiVec_.getConstObj()->col(k)->norm_2();
555  norms[0] += subNorm*subNorm;
556  }
557  norms[0] = ST::magnitude(ST::squareroot(norms[0]));
558 }
559 
560 
561 template <class Scalar>
563  const ArrayView<typename ScalarTraits<Scalar>::magnitudeType>& norms
564  ) const
565 {
566 #ifdef TEUCHOS_DEBUG
567  TEUCHOS_ASSERT_EQUALITY(norms.size(), 1);
568 #endif
569  typedef ScalarTraits<Scalar> ST;
570  norms[0] = ST::magnitude(ST::zero());
571  for(int k = 0; k < numBlocks_; ++k) {
572  typename ST::magnitudeType subNorm = multiVec_.getConstObj()->col(k)->norm_inf();
573  if (subNorm > norms[0])
574  norms[0] = subNorm;
575  }
576 }
577 
578 
579 // private
580 
581 
582 template <class Scalar>
585 {
586 
587  // This function exists since in general we can not create views of a column
588  // vectors and expect the changes to be mirrored in the mulit-vector
589  // automatically. Later, we might be able to change this once we have a
590  // Thyra::MultiVectorBase::hasDirectColumnVectorView() function and it
591  // returns true. Until then, this is the safe way to do this ...
592 
594  for ( int k = 0; k < numBlocks_; ++k) {
595  vecArray.push_back(multiVec_.getConstObj()->col(k));
596  }
597 
598  return Thyra::defaultProductVector<Scalar>(
599  productSpace_->getDefaultProductVectorSpace(),
600  vecArray()
601  );
602 
603 }
604 
605 
606 } // namespace Thyra
607 
608 
609 #endif // THYRA_DEFAULT_MULTI_VECTOR_PRODUCT_VECTOR_HPP
virtual RCP< const VectorSpaceBase< Scalar > > space() const =0
Return a smart pointer to the vector space that this vector belongs to.
Base interface for product multi-vectors.
virtual void normsInfImpl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
#define THYRA_ASSERT_VEC_SPACES(FUNC_NAME, VS1, VS2)
This is a very useful macro that should be used to validate that two vector spaces are compatible...
bool is_null(const boost::shared_ptr< T > &p)
virtual RCP< const VectorSpaceBase< Scalar > > range() const =0
Return a smart pointer for the range space for this operator.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Base interface for product vectors.
basic_OSTab< char > OSTab
virtual void norms2Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
RCP< const VectorBase< Scalar > > getVectorBlock(const int k) const
void releaseDetachedVectorViewImpl(RTOpPack::ConstSubVectorView< Scalar > *sub_vec) const
virtual void eleWiseScaleImpl(const VectorBase< Scalar > &x)
virtual void assignMultiVecImpl(const MultiVectorBase< Scalar > &mv)
Default implementation of assign(MV) using RTOps.
size_type size() const
virtual void eleWiseScaleImpl(const VectorBase< Scalar > &x)
Default implementation of ele_wise_scale using RTOps.
virtual void reciprocalImpl(const VectorBase< Scalar > &x)
Default implementation of reciprocal using RTOps.
virtual void linearCombinationImpl(const ArrayView< const Scalar > &alpha, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &mv, const Scalar &beta)
Default implementation of linear_combination using RTOps.
virtual void absImpl(const VectorBase< Scalar > &x)
Default implementation of abs using RTOps.
Concrete implementation of a product vector which is really composed out of the columns of a multi-ve...
RCP< const MultiVectorBase< Scalar > > getMultiVectorBlock(const int k) const
void commitNonconstDetachedVectorViewImpl(RTOpPack::SubVectorView< Scalar > *sub_vec)
RCP< const ProductVectorSpaceBase< Scalar > > productSpace() const
#define TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(index, lower_inclusive, upper_exclusive)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
Interface for a collection of column vectors called a multi-vector.
RCP< const VectorBase< Scalar > > col(Ordinal j) const
Calls colImpl().
void acquireNonconstDetachedVectorViewImpl(const Range1D &rng, RTOpPack::SubVectorView< Scalar > *sub_vec)
void acquireDetachedVectorViewImpl(const Range1D &rng, RTOpPack::ConstSubVectorView< Scalar > *sub_vec) const
virtual std::string description() const
Abstract interface for finite-dimensional dense vectors.
RCP< const MultiVectorBase< Scalar > > getMultiVector() const
Standard concrete implementation of a product vector space that creates product vectors fromed implic...
virtual void norms1Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
void initialize(const RCP< const DefaultMultiVectorProductVectorSpace< Scalar > > &productSpace, const RCP< MultiVectorBase< Scalar > > &multiVec)
Initialize with a non-const multi-vector.
virtual void updateImpl(Scalar alpha, const MultiVectorBase< Scalar > &mv)
virtual Teuchos::ScalarTraits< Scalar >::magnitudeType norm2WeightedImpl(const VectorBase< Scalar > &x) const
virtual void dotsImpl(const MultiVectorBase< Scalar > &mv, const ArrayView< Scalar > &prods) const
virtual RCP< const VectorSpaceBase< Scalar > > domain() const =0
Return a smart pointer for the domain space for this operator.
bool nonnull(const boost::shared_ptr< T > &p)
void push_back(const value_type &x)
virtual void assignMultiVecImpl(const MultiVectorBase< Scalar > &mv)
virtual Teuchos::ScalarTraits< Scalar >::magnitudeType norm2WeightedImpl(const VectorBase< Scalar > &x) const
Default implementation of norm_2 (weighted) using RTOps.
void applyOpImpl(const RTOpPack::RTOpT< Scalar > &op, const ArrayView< const Ptr< const VectorBase< Scalar > > > &vecs, const ArrayView< const Ptr< VectorBase< Scalar > > > &targ_vecs, const Ptr< RTOpPack::ReductTarget > &reduct_obj, const Ordinal global_offset) const
RCP< MultiVectorBase< Scalar > > getNonconstMultiVectorBlock(const int k)
RCP< const VectorSpaceBase< Scalar > > space() const
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
RCP< VectorBase< Scalar > > getNonconstVectorBlock(const int k)
virtual void linearCombinationImpl(const ArrayView< const Scalar > &alpha, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &mv, const Scalar &beta)
virtual void dotsImpl(const MultiVectorBase< Scalar > &mv, const ArrayView< Scalar > &prods) const
Default implementation of dots using RTOps.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
virtual void updateImpl(Scalar alpha, const MultiVectorBase< Scalar > &mv)
Default implementation of update using RTOps.
virtual void reciprocalImpl(const VectorBase< Scalar > &x)
void setSubVectorImpl(const RTOpPack::SparseSubVectorT< Scalar > &sub_vec)