Thyra Version of the Day
Loading...
Searching...
No Matches
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
20namespace Thyra {
21
22
23// Constructors/initializers/accessors
24
25
26template <class Scalar>
31
32
33template <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));
41 TEUCHOS_TEST_FOR_EXCEPT(is_null(multiVec));
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
58template <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));
66 TEUCHOS_TEST_FOR_EXCEPT(is_null(multiVec));
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
83template <class Scalar>
86{
87 return multiVec_.getNonconstObj();
88}
89
90
91template <class Scalar>
94{
95 return multiVec_.getConstObj();
96}
97
98
99template <class Scalar>
101{
102 numBlocks_ = 0;
103 productSpace_ = Teuchos::null;
104 multiVec_.uninitialize();
105}
106
107
108// Overridden from Teuchos::Describable
109
110
111template<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
124template<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) {
137 *out << this->description() << std::endl;
138 break;
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
160template <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
171template <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
185template <class Scalar>
188{
189 return productSpace_;
190}
191
192
193template <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
205template <class Scalar>
208{
209 return getNonconstVectorBlock(k);
210}
211
212
213template <class Scalar>
216{
217 return getVectorBlock(k);
218}
219
220
221// Overridden public functions from VectorBase
222
223
224template <class Scalar>
227{
228 return productSpace_;
229}
230
231
232// protected
233
234
235// Overridden protected functions from VectorBase
236
237
238template <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
250template <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
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
271template <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
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
292template <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
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
313template <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;
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
340template <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
354template <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
363template <class Scalar>
366 ) const
367{
368 this->getDefaultProductVector()->releaseDetachedView(sub_vec);
369}
370
371
372template <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
381template <class Scalar>
384 )
385{
386 TEUCHOS_TEST_FOR_EXCEPT("ToDo: Implement DefaultMultiVectorProductVector<Scalar>::commitNonconstDetachedVectorViewImpl(...)!");
387}
388
389
390template <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
402template <class Scalar>
404{
405 multiVec_.getNonconstObj()->assign(alpha);
406}
407
408
409template <class Scalar>
412 )
413{
414#ifdef TEUCHOS_DEBUG
415 TEUCHOS_ASSERT_EQUALITY(mv.domain()->dim(), 1);
416 TEUCHOS_ASSERT(productSpace_->isCompatible(*mv.range()));
417#endif
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
430template <class Scalar>
432{
433 multiVec_.getNonconstObj()->scale(alpha);
434}
435
436
437template <class Scalar>
439 Scalar alpha,
441 )
442{
443#ifdef TEUCHOS_DEBUG
444 TEUCHOS_ASSERT_EQUALITY(mv.domain()->dim(), 1);
445 TEUCHOS_ASSERT(productSpace_->isCompatible(*mv.range()));
446#endif
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
459template <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) {
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());
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
501template <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
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
527template <class Scalar>
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
543template <class Scalar>
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
561template <class Scalar>
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
582template <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
size_type size() const
size_type size() const
void push_back(const value_type &x)
virtual std::string description() const
Standard concrete implementation of a product vector space that creates product vectors fromed implic...
Concrete implementation of a product vector which is really composed out of the columns of a multi-ve...
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
void initialize(const RCP< const DefaultMultiVectorProductVectorSpace< Scalar > > &productSpace, const RCP< MultiVectorBase< Scalar > > &multiVec)
Initialize with a non-const multi-vector.
RCP< const ProductVectorSpaceBase< Scalar > > productSpace() const
virtual void dotsImpl(const MultiVectorBase< Scalar > &mv, const ArrayView< Scalar > &prods) const
virtual void eleWiseScaleImpl(const VectorBase< Scalar > &x)
RCP< const MultiVectorBase< Scalar > > getMultiVector() const
virtual void normsInfImpl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
void commitNonconstDetachedVectorViewImpl(RTOpPack::SubVectorView< Scalar > *sub_vec)
RCP< const VectorSpaceBase< Scalar > > space() const
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
RCP< MultiVectorBase< Scalar > > getNonconstMultiVectorBlock(const int k)
RCP< const VectorBase< Scalar > > getVectorBlock(const int k) const
virtual void reciprocalImpl(const VectorBase< Scalar > &x)
void releaseDetachedVectorViewImpl(RTOpPack::ConstSubVectorView< Scalar > *sub_vec) const
virtual void assignMultiVecImpl(const MultiVectorBase< Scalar > &mv)
virtual void updateImpl(Scalar alpha, const MultiVectorBase< Scalar > &mv)
virtual void norms1Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
void acquireDetachedVectorViewImpl(const Range1D &rng, RTOpPack::ConstSubVectorView< Scalar > *sub_vec) const
virtual void linearCombinationImpl(const ArrayView< const Scalar > &alpha, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &mv, const Scalar &beta)
void setSubVectorImpl(const RTOpPack::SparseSubVectorT< Scalar > &sub_vec)
virtual void norms2Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
RCP< const MultiVectorBase< Scalar > > getMultiVectorBlock(const int k) const
RCP< VectorBase< Scalar > > getNonconstVectorBlock(const int k)
void acquireNonconstDetachedVectorViewImpl(const Range1D &rng, RTOpPack::SubVectorView< Scalar > *sub_vec)
virtual Teuchos::ScalarTraits< Scalar >::magnitudeType norm2WeightedImpl(const VectorBase< Scalar > &x) const
virtual RCP< const VectorSpaceBase< Scalar > > range() const =0
Return a smart pointer for the range space for this operator.
virtual RCP< const VectorSpaceBase< Scalar > > domain() const =0
Return a smart pointer for the domain space for this operator.
Interface for a collection of column vectors called a multi-vector.
virtual void dotsImpl(const MultiVectorBase< Scalar > &mv, const ArrayView< Scalar > &prods) const
Default implementation of dots 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 assignMultiVecImpl(const MultiVectorBase< Scalar > &mv)
Default implementation of assign(MV) using RTOps.
virtual void updateImpl(Scalar alpha, const MultiVectorBase< Scalar > &mv)
Default implementation of update using RTOps.
Abstract interface for finite-dimensional dense vectors.
virtual RCP< const VectorSpaceBase< Scalar > > space() const =0
Return a smart pointer to the vector space that this vector belongs to.
virtual Teuchos::ScalarTraits< Scalar >::magnitudeType norm2WeightedImpl(const VectorBase< Scalar > &x) const
Default implementation of norm_2 (weighted) using RTOps.
virtual void reciprocalImpl(const VectorBase< Scalar > &x)
Default implementation of reciprocal using RTOps.
virtual void absImpl(const VectorBase< Scalar > &x)
Default implementation of abs using RTOps.
virtual void eleWiseScaleImpl(const VectorBase< Scalar > &x)
Default implementation of ele_wise_scale using RTOps.
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(index, lower_inclusive, upper_exclusive)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
#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.
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
T_To & dyn_cast(T_From &from)