Thyra Version of the Day
Loading...
Searching...
No Matches
Thyra_DefaultProductMultiVector_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_PRODUCT_MULTI_VECTOR_DEF_HPP
11#define THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_DEF_HPP
12
13#include "Thyra_DefaultProductMultiVector_decl.hpp"
14#include "Thyra_DefaultProductVectorSpace.hpp"
15#include "Thyra_DefaultProductVector.hpp"
16#include "Thyra_AssertOp.hpp"
17
18
19namespace Thyra {
20
21
22// Constructors/initializers/accessors
23
24
25template<class Scalar>
29
30
31template<class Scalar>
33 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
34 const int numMembers
35 )
36{
37#ifdef TEUCHOS_DEBUG
38 TEUCHOS_TEST_FOR_EXCEPT( is_null(productSpace_in) );
39 TEUCHOS_TEST_FOR_EXCEPT( numMembers <= 0 );
40#endif
42 const int numBlocks = productSpace_in->numBlocks();
43 for ( int k = 0; k < numBlocks; ++k )
44 multiVecs.push_back(createMembers(productSpace_in->getBlock(k),numMembers));
45 initialize(productSpace_in,multiVecs);
46}
47
48
49template<class Scalar>
51 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
52 const ArrayView<const RCP<MultiVectorBase<Scalar> > > &multiVecs
53 )
54{
55 initializeImpl(productSpace_in,multiVecs);
56}
57
58
59template<class Scalar>
61 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
62 const ArrayView<const RCP<const MultiVectorBase<Scalar> > > &multiVecs
63 )
64{
65 initializeImpl(productSpace_in,multiVecs);
66}
67
68
69template<class Scalar>
71{
72 productSpace_ = Teuchos::null;
73 multiVecs_.resize(0);
74 numBlocks_ = 0;
75}
76
77
78// Overridden public functions from Teuchos::Describable
79
80
81template<class Scalar>
83{
84 std::ostringstream oss;
85 oss
87 << "{"
88 << "rangeDim="<<this->range()->dim()
89 << ",domainDim="<<this->domain()->dim()
90 << ",numBlocks = "<<numBlocks_
91 << "}";
92 return oss.str();
93}
94
95
96template<class Scalar>
98 FancyOStream &out_arg,
99 const Teuchos::EVerbosityLevel verbLevel
100 ) const
101{
102 using Teuchos::OSTab;
103 using Teuchos::describe;
104 if (verbLevel == Teuchos::VERB_NONE)
105 return;
106 RCP<FancyOStream> out = rcp(&out_arg,false);
107 OSTab tab(out);
108 switch(verbLevel) {
110 break;
111 case Teuchos::VERB_DEFAULT: // fall through
112 case Teuchos::VERB_LOW: // fall through
113 *out << this->description() << std::endl;
114 break;
115 case Teuchos::VERB_MEDIUM: // fall through
116 case Teuchos::VERB_HIGH: // fall through
118 {
119 *out
121 << "rangeDim="<<this->range()->dim()
122 << ",domainDim="<<this->domain()->dim()
123 << "}\n";
124 OSTab tab2(out);
125 *out
126 << "numBlocks="<< numBlocks_ << std::endl
127 << "Constituent multi-vector objects V[0], V[1], ... V[numBlocks-1]:\n";
128 OSTab tab3(out);
129 for( int k = 0; k < numBlocks_; ++k ) {
130 *out << "V["<<k<<"] = "
131 << Teuchos::describe(*multiVecs_[k].getConstObj(),verbLevel);
132 }
133 break;
134 }
135 default:
136 TEUCHOS_TEST_FOR_EXCEPT(true); // Should never get here!
137 }
138}
139
140
141// Overridden public functions from ProductMultiVectorBase
142
143
144template<class Scalar>
147{
148 return productSpace_;
149}
150
151
152template<class Scalar>
154{
155 return multiVecs_[k].isConst();
156}
157
158
159template<class Scalar>
162{
163 return multiVecs_[k].getNonconstObj();
164}
165
166
167template<class Scalar>
170{
171 return multiVecs_[k].getConstObj();
172}
173
174
175// Overridden public functions from MultiVectorBase
176
177
178template<class Scalar>
181{
182 assertInitialized();
184 for ( int k = 0; k < numBlocks_; ++k )
185 blocks.push_back(multiVecs_[k].getConstObj()->clone_mv());
186 return defaultProductMultiVector<Scalar>(productSpace_, blocks());
187}
188
189
190// Overriden public functions from LinearOpBase
191
192
193template<class Scalar>
196{
197 return productSpace_;
198}
199
200
201template<class Scalar>
204{
205 if (is_null(productSpace_))
206 return Teuchos::null;
207 return multiVecs_[0].getConstObj()->domain();
208}
209
210
211// protected
212
213
214// Overriden protected functions from MultiVectorBase
215
216
217template<class Scalar>
219{
220 for ( int k = 0; k < numBlocks_; ++k ) {
221 multiVecs_[k].getNonconstObj()->assign(alpha);
222 }
223}
224
225
226template<class Scalar>
229 )
230{
231#ifdef TEUCHOS_DEBUG
232 TEUCHOS_ASSERT_EQUALITY(this->domain()->dim(), mv.domain()->dim());
233 TEUCHOS_ASSERT(productSpace_->isCompatible(*mv.range()));
234#endif
235
236 // Apply operation block-by-block if mv is also a ProductMultiVector
239 if (nonnull(pv)) {
240 for (int k = 0; k < numBlocks_; ++k) {
241 multiVecs_[k].getNonconstObj()->assign(*pv->getMultiVectorBlock(k));
242 }
243 } else {
245 }
246}
247
248
249template<class Scalar>
251{
252 for (int k = 0; k < numBlocks_; ++k) {
253 multiVecs_[k].getNonconstObj()->scale(alpha);
254 }
255}
256
257
258template<class Scalar>
260 Scalar alpha,
262 )
263{
264#ifdef TEUCHOS_DEBUG
265 TEUCHOS_ASSERT_EQUALITY(this->domain()->dim(), mv.domain()->dim());
266 TEUCHOS_ASSERT(productSpace_->isCompatible(*mv.range()));
267#endif
268
269 // Apply operation block-by-block if mv is also a ProductMultiVector
272 if (nonnull(pv)) {
273 for (int k = 0; k < numBlocks_; ++k) {
274 multiVecs_[k].getNonconstObj()->update(alpha, *pv->getMultiVectorBlock(k));
275 }
276 } else {
278 }
279}
280
281
282template<class Scalar>
284 const ArrayView<const Scalar>& alpha,
285 const ArrayView<const Ptr<const MultiVectorBase<Scalar> > >& mv,
286 const Scalar& beta
287 )
288{
289#ifdef TEUCHOS_DEBUG
290 TEUCHOS_ASSERT_EQUALITY(alpha.size(), mv.size());
291 for (Ordinal i = 0; i < mv.size(); ++i) {
292 TEUCHOS_ASSERT_EQUALITY(this->domain()->dim(), mv[i]->domain()->dim());
293 TEUCHOS_ASSERT(productSpace_->isCompatible(*mv[i]->range()));
294 }
295#endif
296
297 // Apply operation block-by-block if each element of mv is also a ProductMultiVector
298 bool allCastsSuccessful = true;
300 for (Ordinal i = 0; i < mv.size(); ++i) {
302 if (pvs[i].is_null()) {
303 allCastsSuccessful = false;
304 break;
305 }
306 }
307
308 if (allCastsSuccessful) {
309 Array<RCP<const MultiVectorBase<Scalar> > > blocks_rcp(pvs.size());
311 for (int k = 0; k < numBlocks_; ++k) {
312 for (Ordinal i = 0; i < pvs.size(); ++i) {
313 blocks_rcp[i] = pvs[i]->getMultiVectorBlock(k);
314 blocks[i] = blocks_rcp[i].ptr();
315 }
316 multiVecs_[k].getNonconstObj()->linear_combination(alpha, blocks(), beta);
317 }
318 } else {
320 }
321}
322
323
324template<class Scalar>
326 const MultiVectorBase<Scalar>& mv,
327 const ArrayView<Scalar>& prods
328 ) const
329{
330#ifdef TEUCHOS_DEBUG
331 TEUCHOS_ASSERT_EQUALITY(this->domain()->dim(), mv.domain()->dim());
332 TEUCHOS_ASSERT_EQUALITY(this->domain()->dim(), prods.size());
333 TEUCHOS_ASSERT(productSpace_->isCompatible(*mv.range()));
334#endif
335 // Apply operation block-by-block if mv is also a ProductMultiVector
338 if (nonnull(pv)) {
339 for (Ordinal i = 0; i < prods.size(); ++i)
340 prods[i] = ScalarTraits<Scalar>::zero();
341
342 Array<Scalar> subProds(prods.size());
343 for (int k = 0; k < numBlocks_; ++k) {
344 multiVecs_[k].getConstObj()->dots(*pv->getMultiVectorBlock(k), subProds());
345 for (Ordinal i = 0; i < prods.size(); ++i) {
346 prods[i] += subProds[i];
347 }
348 }
349 } else {
351 }
352}
353
354
355template<class Scalar>
358 ) const
359{
360#ifdef TEUCHOS_DEBUG
361 TEUCHOS_ASSERT_EQUALITY(this->domain()->dim(), norms.size());
362#endif
363 typedef ScalarTraits<Scalar> ST;
364 for (Ordinal i = 0; i < norms.size(); ++i)
365 norms[i] = ST::magnitude(ST::zero());
366
367 Array<typename ST::magnitudeType> subNorms(norms.size());
368 for (int k = 0; k < numBlocks_; ++k) {
369 multiVecs_[k].getConstObj()->norms_1(subNorms());
370 for (Ordinal i = 0; i < norms.size(); ++i) {
371 norms[i] += subNorms[i];
372 }
373 }
374}
375
376
377template<class Scalar>
380 ) const
381{
382#ifdef TEUCHOS_DEBUG
383 TEUCHOS_ASSERT_EQUALITY(this->domain()->dim(), norms.size());
384#endif
385 typedef ScalarTraits<Scalar> ST;
386 for (Ordinal i = 0; i < norms.size(); ++i)
387 norms[i] = ST::magnitude(ST::zero());
388
389 Array<typename ST::magnitudeType> subNorms(norms.size());
390 for (int k = 0; k < numBlocks_; ++k) {
391 multiVecs_[k].getConstObj()->norms_2(subNorms());
392 for (Ordinal i = 0; i < norms.size(); ++i) {
393 norms[i] += subNorms[i]*subNorms[i];
394 }
395 }
396
397 for (Ordinal i = 0; i < norms.size(); ++i) {
398 norms[i] = ST::magnitude(ST::squareroot(norms[i]));
399 }
400}
401
402
403template<class Scalar>
406 ) const
407{
408#ifdef TEUCHOS_DEBUG
409 TEUCHOS_ASSERT_EQUALITY(this->domain()->dim(), norms.size());
410#endif
411 typedef ScalarTraits<Scalar> ST;
412 for (Ordinal i = 0; i < norms.size(); ++i)
413 norms[i] = ST::magnitude(ST::zero());
414
415 Array<typename ST::magnitudeType> subNorms(norms.size());
416 for (int k = 0; k < numBlocks_; ++k) {
417 multiVecs_[k].getConstObj()->norms_inf(subNorms());
418 for (Ordinal i = 0; i < norms.size(); ++i) {
419 if (subNorms[i] > norms[i])
420 norms[i] = subNorms[i];
421 }
422 }
423}
424
425
426template<class Scalar>
429{
430 validateColIndex(j);
432 for ( int k = 0; k < numBlocks_; ++k )
433 cols_.push_back(multiVecs_[k].getConstObj()->col(j));
434 return defaultProductVector<Scalar>(productSpace_, cols_());
435}
436
437
438template<class Scalar>
441{
442 validateColIndex(j);
444 for ( int k = 0; k < numBlocks_; ++k )
445 cols_.push_back(multiVecs_[k].getNonconstObj()->col(j));
446 return defaultProductVector<Scalar>(productSpace_, cols_());
447}
448
449
450template<class Scalar>
453{
454 assertInitialized();
456 for ( int k = 0; k < numBlocks_; ++k )
457 blocks.push_back(multiVecs_[k].getConstObj()->subView(colRng));
458 return defaultProductMultiVector<Scalar>(productSpace_, blocks());
459}
460
461
462template<class Scalar>
465{
466 assertInitialized();
468 for ( int k = 0; k < numBlocks_; ++k )
469 blocks.push_back(multiVecs_[k].getNonconstObj()->subView(colRng));
470 return defaultProductMultiVector<Scalar>(productSpace_, blocks());
471}
472
473
474template<class Scalar>
477 const ArrayView<const int> &cols
478 ) const
479{
480 assertInitialized();
482 for ( int k = 0; k < numBlocks_; ++k )
483 blocks.push_back(multiVecs_[k].getConstObj()->subView(cols));
484 return defaultProductMultiVector<Scalar>(productSpace_, blocks());
485}
486
487
488template<class Scalar>
491 const ArrayView<const int> &cols
492 )
493{
494 assertInitialized();
496 for ( int k = 0; k < numBlocks_; ++k )
497 blocks.push_back(multiVecs_[k].getNonconstObj()->subView(cols));
498 return defaultProductMultiVector<Scalar>(productSpace_, blocks());
499}
500
501
502template<class Scalar>
504 const RTOpPack::RTOpT<Scalar> &primary_op,
505 const ArrayView<const Ptr<const MultiVectorBase<Scalar> > > &multi_vecs_in,
506 const ArrayView<const Ptr<MultiVectorBase<Scalar> > > &targ_multi_vecs_inout,
507 const ArrayView<const Ptr<RTOpPack::ReductTarget> > &reduct_objs,
508 const Ordinal primary_global_offset_in
509 ) const
510{
511
512 using Teuchos::ptr_dynamic_cast;
513 using Thyra::applyOp;
514
515 assertInitialized();
516
517#ifdef TEUCHOS_DEBUG
518 for ( int j = 0; j < multi_vecs_in.size(); ++j ) {
520 "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
521 *this->range(), *multi_vecs_in[j]->range()
522 );
524 "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
525 *this->domain(), *multi_vecs_in[j]->domain()
526 );
527 }
528 for ( int j = 0; j < targ_multi_vecs_inout.size(); ++j ) {
530 "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
531 *this->range(), *targ_multi_vecs_inout[j]->range()
532 );
534 "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
535 *this->domain(), *targ_multi_vecs_inout[j]->domain()
536 );
537 }
538#endif // TEUCHOS_DEBUG
539
540 //
541 // Try to dynamic cast all of the multi-vector objects to the
542 // ProductMultiVectoBase interface.
543 //
544
545 bool allProductMultiVectors = true;
546
548 for ( int j = 0; j < multi_vecs_in.size() && allProductMultiVectors; ++j ) {
549#ifdef TEUCHOS_DEBUG
550 TEUCHOS_TEST_FOR_EXCEPT( is_null(multi_vecs_in[j]) );
551#endif
553 multi_vecs_j = ptr_dynamic_cast<const ProductMultiVectorBase<Scalar> >(
554 multi_vecs_in[j]
555 );
556 if ( !is_null(multi_vecs_j) ) {
557 multi_vecs.push_back(multi_vecs_j);
558 }
559 else {
560 allProductMultiVectors = false;
561 }
562 }
563
565 for ( int j = 0; j < targ_multi_vecs_inout.size() && allProductMultiVectors; ++j )
566 {
567#ifdef TEUCHOS_DEBUG
568 TEUCHOS_TEST_FOR_EXCEPT( is_null(targ_multi_vecs_inout[j]) );
569#endif
571 targ_multi_vecs_j = ptr_dynamic_cast<ProductMultiVectorBase<Scalar> >(
572 targ_multi_vecs_inout[j]
573 );
574 if (!is_null(targ_multi_vecs_j)) {
575 targ_multi_vecs.push_back(targ_multi_vecs_j);
576 }
577 else {
578 allProductMultiVectors = false;
579 }
580 }
581
582 //
583 // Do the reduction operations
584 //
585
586 if ( allProductMultiVectors ) {
587
588 // All of the multi-vector objects support the ProductMultiVectorBase
589 // interface so we can do the reductions block by block. Note, this is
590 // not the most efficient implementation in an SPMD program but this is
591 // easy to code up and use!
592
593 // We must set up temporary arrays for the pointers to the MultiVectorBase
594 // blocks for each block of objects! What a mess!
596 multi_vecs_rcp_block_k(multi_vecs_in.size());
598 multi_vecs_block_k(multi_vecs_in.size());
600 targ_multi_vecs_rcp_block_k(targ_multi_vecs_inout.size());
602 targ_multi_vecs_block_k(targ_multi_vecs_inout.size());
603
604 Ordinal g_off = primary_global_offset_in;
605
606 for ( int k = 0; k < numBlocks_; ++k ) {
607
608 const Ordinal dim_k = productSpace_->getBlock(k)->dim();
609
610 // Fill the MultiVector array objects for this block
611
612 for ( int j = 0; j < multi_vecs_in.size(); ++j ) {
613 RCP<const MultiVectorBase<Scalar> > multi_vecs_rcp_block_k_j =
614 multi_vecs[j]->getMultiVectorBlock(k);
615 multi_vecs_rcp_block_k[j] = multi_vecs_rcp_block_k_j;
616 multi_vecs_block_k[j] = multi_vecs_rcp_block_k_j.ptr();
617 }
618
619 for ( int j = 0; j < targ_multi_vecs_inout.size(); ++j ) {
620 RCP<MultiVectorBase<Scalar> > targ_multi_vecs_rcp_block_k_j =
621 targ_multi_vecs[j]->getNonconstMultiVectorBlock(k);
622 targ_multi_vecs_rcp_block_k[j] = targ_multi_vecs_rcp_block_k_j;
623 targ_multi_vecs_block_k[j] = targ_multi_vecs_rcp_block_k_j.ptr();
624 }
625
626 // Apply the RTOp object to the MultiVectors for this block
627
628 Thyra::applyOp<Scalar>(
629 primary_op, multi_vecs_block_k(), targ_multi_vecs_block_k(),
630 reduct_objs,
631 g_off
632 );
633
634 g_off += dim_k;
635 }
636
637 }
638 else {
639
640 // All of the multi-vector objects do not support the
641 // ProductMultiVectorBase interface but if we got here (in debug mode)
642 // then the spaces said that they are compatible so fall back on the
643 // column-by-column implementation that will work correctly in serial.
644
646 primary_op, multi_vecs_in(), targ_multi_vecs_inout(),
647 reduct_objs, primary_global_offset_in);
648
649 }
650
651}
652
653
654template<class Scalar>
656 const Range1D &rowRng,
657 const Range1D &colRng,
659 ) const
660{
662 rowRng, colRng, sub_mv );
663 // ToDo: Override this implementation if needed!
664}
665
666
667template<class Scalar>
670 ) const
671{
673 sub_mv );
674 // ToDo: Override this implementation if needed!
675}
676
677
678template<class Scalar>
680 const Range1D &rowRng,
681 const Range1D &colRng,
683 )
684{
686 rowRng,colRng,sub_mv );
687 // ToDo: Override this implementation if needed!
688}
689
690
691template<class Scalar>
699
700
701// Overridden protected functions from LinearOpBase
702
703
704template<class Scalar>
706{
707 return true; // We can do it all!
708}
709
710
711template<class Scalar>
713 const EOpTransp M_trans,
714 const MultiVectorBase<Scalar> &X_in,
715 const Ptr<MultiVectorBase<Scalar> > &Y_inout,
716 const Scalar alpha,
717 const Scalar beta
718 ) const
719{
720
722 using Teuchos::dyn_cast;
723 using Thyra::apply;
724
725#ifdef TEUCHOS_DEBUG
727 "DefaultProductMultiVector<Scalar>::apply(...)",
728 *this, M_trans, X_in, &*Y_inout );
729#endif
730
731 if ( real_trans(M_trans) == NOTRANS ) {
732 //
733 // Y = b*Y + a*M*X
734 //
735 // =>
736 //
737 // Y[k] = b*Y[k] + a*M[k]*X, k = 0...numBlocks-1
738 //
740 &Y = dyn_cast<ProductMultiVectorBase<Scalar> >(*Y_inout);
741 for ( int k = 0; k < numBlocks_; ++k ) {
742 Thyra::apply(
743 *multiVecs_[k].getConstObj(), M_trans,
744 X_in, Y.getNonconstMultiVectorBlock(k).ptr(),
745 alpha, beta );
746 }
747 }
748 else {
749 //
750 // Y = b*Y + a*trans(M)*X
751 //
752 // =>
753 //
754 // Y = b*Y + sum( a * trans(M[k]) * X[k], k=0...numBlocks-1 )
755 //
757 &X = dyn_cast<const ProductMultiVectorBase<Scalar> >(X_in);
758 for ( int k = 0; k < numBlocks_; ++k ) {
760 M_k = multiVecs_[k].getConstObj(),
761 X_k = X.getMultiVectorBlock(k);
762 if ( 0 == k ) {
763 Thyra::apply( *M_k, M_trans, *X_k, Y_inout.ptr(), alpha, beta );
764 }
765 else {
766 Thyra::apply( *M_k, M_trans, *X_k, Y_inout.ptr(), alpha, ST::one() );
767 }
768 }
769 }
770}
771
772
773// private
774
775
776template<class Scalar>
777template<class MultiVectorType>
779 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
780 const ArrayView<const RCP<MultiVectorType> > &multiVecs
781 )
782{
783 // This function provides the "strong" guarantee (i.e. if an exception is
784 // thrown, then *this will be left in the original state as before the
785 // function was called)!
786#ifdef TEUCHOS_DEBUG
787 TEUCHOS_ASSERT(nonnull(productSpace_in));
788 TEUCHOS_ASSERT_EQUALITY(multiVecs.size(), productSpace_in->numBlocks());
789#endif // TEUCHOS_DEBUG
791 theDomain = multiVecs[0]->domain();
792 const int numBlocks = productSpace_in->numBlocks();
793#ifdef TEUCHOS_DEBUG
794 for ( int k = 0; k < numBlocks; ++k ) {
797 *theDomain, *multiVecs[k]->domain()
798 );
799 }
800#endif
801 productSpace_ = productSpace_in;
802 numBlocks_ = numBlocks;
803 multiVecs_.assign(multiVecs.begin(),multiVecs.end());
804}
805
806
807#ifdef TEUCHOS_DEBUG
808
809
810template<class Scalar>
811void DefaultProductMultiVector<Scalar>::assertInitialized() const
812{
814 is_null(productSpace_), std::logic_error,
815 "Error, this DefaultProductMultiVector object is not intialized!"
816 );
817}
818
819
820template<class Scalar>
821void DefaultProductMultiVector<Scalar>::validateColIndex(const int j) const
822{
823 assertInitialized();
824 const int domainDim = multiVecs_[0].getConstObj()->domain()->dim();
826 ! ( 0 <= j && j < domainDim ), std::logic_error,
827 "Error, the column index j = " << j << " does not fall in the range [0,"<<domainDim<<"]!"
828 );
829}
830
831
832#endif // TEUCHOS_DEBUG
833
834
835} // namespace Thyra
836
837
838template<class Scalar>
840Thyra::defaultProductMultiVector()
841{
842 return Teuchos::rcp(new DefaultProductMultiVector<Scalar>);
843}
844
845
846template<class Scalar>
848Thyra::defaultProductMultiVector(
849 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
850 const int numMembers
851 )
852{
853 RCP<DefaultProductMultiVector<Scalar> > pmv = defaultProductMultiVector<Scalar>();
854 pmv->initialize(productSpace, numMembers);
855 return pmv;
856}
857
858
859template<class Scalar>
861Thyra::defaultProductMultiVector(
862 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
863 const ArrayView<const RCP<MultiVectorBase<Scalar> > > &multiVecs
864 )
865{
866 const RCP<DefaultProductMultiVector<Scalar> > pmv =
867 defaultProductMultiVector<Scalar>();
868 pmv->initialize(productSpace, multiVecs);
869 return pmv;
870}
871
872
873template<class Scalar>
875Thyra::defaultProductMultiVector(
876 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
877 const ArrayView<const RCP<const MultiVectorBase<Scalar> > > &multiVecs
878 )
879{
880 const RCP<DefaultProductMultiVector<Scalar> > pmv =
881 defaultProductMultiVector<Scalar>();
882 pmv->initialize(productSpace, multiVecs);
883 return pmv;
884}
885
886
887template<class Scalar>
889Thyra::castOrCreateSingleBlockProductMultiVector(
890 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
891 const RCP<const MultiVectorBase<Scalar> > &mv
892 )
893{
894 const RCP<const ProductMultiVectorBase<Scalar> > pmv =
896 if (nonnull(pmv))
897 return pmv;
898 return defaultProductMultiVector<Scalar>(productSpace, Teuchos::tuple(mv)());
899}
900
901
902template<class Scalar>
904Thyra::nonconstCastOrCreateSingleBlockProductMultiVector(
905 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
906 const RCP<MultiVectorBase<Scalar> > &mv
907 )
908{
909 const RCP<ProductMultiVectorBase<Scalar> > pmv =
911 if (nonnull(pmv))
912 return pmv;
913 return defaultProductMultiVector<Scalar>(productSpace, Teuchos::tuple(mv)());
914}
915
916
917//
918// Explicit instantiation macro
919//
920// Must be expanded from within the Thyra namespace!
921//
922
923
924#define THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_INSTANT(SCALAR) \
925 \
926 template class DefaultProductMultiVector<SCALAR >; \
927 \
928 template RCP<DefaultProductMultiVector<SCALAR > > \
929 defaultProductMultiVector<SCALAR >(); \
930 \
931 \
932 template RCP<DefaultProductMultiVector<SCALAR > > \
933 defaultProductMultiVector( \
934 const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
935 const int numMembers \
936 ); \
937 \
938 \
939 template RCP<DefaultProductMultiVector<SCALAR > > \
940 defaultProductMultiVector( \
941 const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
942 const ArrayView<const RCP<MultiVectorBase<SCALAR > > > &multiVecs \
943 ); \
944 \
945 \
946 template RCP<DefaultProductMultiVector<SCALAR > > \
947 defaultProductMultiVector( \
948 const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
949 const ArrayView<const RCP<const MultiVectorBase<SCALAR > > > &multiVecs \
950 ); \
951 \
952 \
953 template RCP<const ProductMultiVectorBase<SCALAR > > \
954 castOrCreateSingleBlockProductMultiVector( \
955 const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
956 const RCP<const MultiVectorBase<SCALAR > > &mv \
957 ); \
958 \
959 \
960 template RCP<ProductMultiVectorBase<SCALAR > > \
961 nonconstCastOrCreateSingleBlockProductMultiVector( \
962 const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
963 const RCP<MultiVectorBase<SCALAR > > &mv \
964 );
965
966
967#endif // THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_DEF_HPP
size_type size() const
size_type size() const
void push_back(const value_type &x)
virtual std::string description() const
Ptr< T > ptr() const
Concrete implementation of a product multi-vector.
void initialize(const RCP< const DefaultProductVectorSpace< Scalar > > &productSpace, const int numMembers)
RCP< MultiVectorBase< Scalar > > nonconstNonContigSubViewImpl(const ArrayView< const int > &cols)
RCP< MultiVectorBase< Scalar > > nonconstContigSubViewImpl(const Range1D &colRng)
RCP< const MultiVectorBase< Scalar > > nonContigSubViewImpl(const ArrayView< const int > &cols) const
void applyImpl(const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha, const Scalar beta) const
void releaseDetachedMultiVectorViewImpl(RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
RCP< const MultiVectorBase< Scalar > > contigSubViewImpl(const Range1D &colRng) const
virtual void norms1Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
virtual void dotsImpl(const MultiVectorBase< Scalar > &mv, const ArrayView< Scalar > &prods) const
void commitNonconstDetachedMultiVectorViewImpl(RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
RCP< const MultiVectorBase< Scalar > > getMultiVectorBlock(const int k) const
void acquireDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
RCP< const ProductVectorSpaceBase< Scalar > > productSpace() const
virtual void assignMultiVecImpl(const MultiVectorBase< Scalar > &mv)
RCP< const VectorSpaceBase< Scalar > > range() const
RCP< MultiVectorBase< Scalar > > getNonconstMultiVectorBlock(const int k)
void mvMultiReductApplyOpImpl(const RTOpPack::RTOpT< Scalar > &primary_op, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &multi_vecs, const ArrayView< const Ptr< MultiVectorBase< Scalar > > > &targ_multi_vecs, const ArrayView< const Ptr< RTOpPack::ReductTarget > > &reduct_objs, const Ordinal primary_global_offset) const
virtual void linearCombinationImpl(const ArrayView< const Scalar > &alpha, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &mv, const Scalar &beta)
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual void updateImpl(Scalar alpha, const MultiVectorBase< Scalar > &mv)
virtual void norms2Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
RCP< MultiVectorBase< Scalar > > clone_mv() const
void acquireNonconstDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
RCP< const VectorSpaceBase< Scalar > > domain() const
RCP< const VectorBase< Scalar > > colImpl(Ordinal j) const
RCP< VectorBase< Scalar > > nonconstColImpl(Ordinal j)
virtual void normsInfImpl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) 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 releaseDetachedMultiVectorViewImpl(RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
virtual void acquireNonconstDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
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.
virtual void mvMultiReductApplyOpImpl(const RTOpPack::RTOpT< Scalar > &primary_op, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &multi_vecs, const ArrayView< const Ptr< MultiVectorBase< Scalar > > > &targ_multi_vecs, const ArrayView< const Ptr< RTOpPack::ReductTarget > > &reduct_objs, const Ordinal primary_global_offset) const
virtual void commitNonconstDetachedMultiVectorViewImpl(RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
virtual void acquireDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
Base interface for product multi-vectors.
virtual Teuchos::RCP< MultiVectorBase< Scalar > > getNonconstMultiVectorBlock(const int k)=0
Returns a non-persisting non-const view of the zero-based kth block multi-vector.
virtual Teuchos::RCP< const MultiVectorBase< Scalar > > getMultiVectorBlock(const int k) const =0
Returns a non-persisting const view of the (zero-based) kth block multi-vector.
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
bool is_null(const std::shared_ptr< T > &p)
bool nonnull(const std::shared_ptr< T > &p)
#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.
#define THYRA_ASSERT_LINEAR_OP_MULTIVEC_APPLY_SPACES(FUNC_NAME, M, M_T, X, Y)
This is a very useful macro that should be used to validate that the spaces for the multi-vector vers...
EOpTransp
Enumeration for determining how a linear operator is applied. `*.
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
EOpTransp real_trans(EOpTransp transp)
Return NOTRANS or TRANS for real scalar valued operators and this also is used for determining struct...
@ NOTRANS
Use the non-transposed operator.
T_To & dyn_cast(T_From &from)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)