Thyra Version of the Day
Loading...
Searching...
No Matches
Thyra_DefaultProductVector_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_VECTOR_DEF_HPP
11#define THYRA_DEFAULT_PRODUCT_VECTOR_DEF_HPP
12
13
14#include "Thyra_DefaultProductVector_decl.hpp"
15#include "Thyra_DefaultProductVectorSpace.hpp"
16#include "Teuchos_Workspace.hpp"
17
18
19namespace Thyra {
20
21
22// Constructors/initializers/accessors
23
24
25template <class Scalar>
31
32
33template <class Scalar>
35 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in
36 )
37 : numBlocks_(0)
38{
39 initialize(productSpace_in);
40}
41
42
43template <class Scalar>
45 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in
46 )
47{
48 // ToDo: Validate input!
49 numBlocks_ = productSpace_in->numBlocks();
50 productSpace_ = productSpace_in;
51 vecs_.resize(numBlocks_);
52 for( int k = 0; k < numBlocks_; ++k )
53 vecs_[k].initialize(createMember(productSpace_in->getBlock(k)));
54}
55
56
57template <class Scalar>
59 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
60 const ArrayView<const RCP<VectorBase<Scalar> > > &vecs
61 )
62{
63 using Teuchos::as;
64#ifdef TEUCHOS_DEBUG
65 TEUCHOS_ASSERT_EQUALITY( as<Ordinal>(productSpace_in->numBlocks()),
66 as<Ordinal>(vecs.size()) );
67#endif
68 numBlocks_ = productSpace_in->numBlocks();
69 productSpace_ = productSpace_in;
70 vecs_.resize(numBlocks_);
71 for( int k = 0; k < numBlocks_; ++k )
72 vecs_[k].initialize(vecs[k]);
73}
74
75
76template <class Scalar>
78 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
79 const ArrayView<const RCP<const VectorBase<Scalar> > > &vecs
80 )
81{
82 using Teuchos::as;
83#ifdef TEUCHOS_DEBUG
84 TEUCHOS_ASSERT_EQUALITY( as<Ordinal>(productSpace_in->numBlocks()),
85 as<Ordinal>(vecs.size()) );
86#endif
87 numBlocks_ = productSpace_in->numBlocks();
88 productSpace_ = productSpace_in;
89 vecs_.resize(numBlocks_);
90 for( int k = 0; k < numBlocks_; ++k )
91 vecs_[k].initialize(vecs[k]);
92}
93
94
95template <class Scalar>
97{
98 productSpace_ = Teuchos::null;
99 vecs_.resize(0);
100 numBlocks_ = 0;
101}
102
103
104// Overridden from Teuchos::Describable
105
106
107template<class Scalar>
109{
110 const RCP<const VectorSpaceBase<Scalar> > vs = this->space();
111 std::ostringstream oss;
112 oss
114 << "{"
115 << "dim="<<(nonnull(vs) ? vs->dim() : 0)
116 << ", numBlocks = "<<numBlocks_
117 << "}";
118 return oss.str();
119}
120
121
122template<class Scalar>
124 Teuchos::FancyOStream &out_arg,
125 const Teuchos::EVerbosityLevel verbLevel
126 ) const
127{
129 using Teuchos::OSTab;
130 using Teuchos::describe;
131 RCP<FancyOStream> out = rcp(&out_arg,false);
132 OSTab tab(out);
133 switch(verbLevel) {
135 break;
138 *out << this->description() << std::endl;
139 break;
143 {
144 *out
146 << "dim=" << this->space()->dim()
147 << "}\n";
148 OSTab tab2(out);
149 *out
150 << "numBlocks="<< numBlocks_ << std::endl
151 << "Constituent vector objects v[0], v[1], ... v[numBlocks-1]:\n";
152 OSTab tab3(out);
153 for( int k = 0; k < numBlocks_; ++k ) {
154 *out << "v["<<k<<"] = " << describe(*vecs_[k].getConstObj(),verbLevel);
155 }
156 break;
157 }
158 default:
159 TEUCHOS_TEST_FOR_EXCEPT(true); // Should never get here!
160 }
161}
162
163
164// Extensions to ProductVectorBase suitable for physically-blocked vectors
165
166
167template <class Scalar>
169 int i, const RCP<const VectorBase<Scalar> >& b
170 )
171{
172#ifdef TEUCHOS_DEBUG
173 TEUCHOS_TEST_FOR_EXCEPT(i < 0 || i >= numBlocks_);
174 TEUCHOS_TEST_FOR_EXCEPT(!productSpace_->getBlock(i)->isCompatible(*(b->space())));
175#endif
176 vecs_[i] = b;
177}
178
179
180template <class Scalar>
182 int i, const RCP<VectorBase<Scalar> >& b
183 )
184{
185#ifdef TEUCHOS_DEBUG
186 TEUCHOS_TEST_FOR_EXCEPT(i < 0 || i >= numBlocks_);
187 TEUCHOS_TEST_FOR_EXCEPT(!productSpace_->getBlock(i)->isCompatible(*(b->space())));
188#endif
189 vecs_[i] = b;
190}
191
192
193// Overridden from ProductVectorBase
194
195
196template <class Scalar>
199{
200#ifdef TEUCHOS_DEBUG
201 TEUCHOS_TEST_FOR_EXCEPT( k < 0 || numBlocks_-1 < k);
202#endif
203 return vecs_[k].getNonconstObj();
204}
205
206
207template <class Scalar>
210{
211#ifdef TEUCHOS_DEBUG
212 TEUCHOS_TEST_FOR_EXCEPT( k < 0 || numBlocks_-1 < k);
213#endif
214 return vecs_[k].getConstObj();
215}
216
217
218// Overridden from ProductMultiVectorBase
219
220
221template <class Scalar>
224{
225 return productSpace_;
226}
227
228
229template <class Scalar>
231{
232#ifdef TEUCHOS_DEBUG
233 TEUCHOS_TEST_FOR_EXCEPT( k < 0 || numBlocks_-1 < k);
234#endif
235 return vecs_[k].isConst();
236}
237
238
239template <class Scalar>
242{
243 return getNonconstVectorBlock(k);
244}
245
246
247template <class Scalar>
250{
251 return getVectorBlock(k);
252}
253
254
255// Overridden from VectorBase
256
257
258template <class Scalar>
261{
262 return productSpace_;
263}
264
265
266/*template <class Scalar>
267void DefaultProductVector<Scalar>::randomizeImpl(
268 Scalar l,
269 Scalar u
270 )
271{
272 for(int k = 0; k < numBlocks_; ++k) {
273 vecs_[k].getNonconstObj()->randomize(l, u);
274 }
275}*/
276
277
278template <class Scalar>
280 const VectorBase<Scalar>& x
281 )
282{
283 // Apply operation block-by-block if mv is also a ProductVector
286 if (nonnull(pv)) {
287#ifdef TEUCHOS_DEBUG
288 TEUCHOS_ASSERT(productSpace_->isCompatible(*pv->productSpace()));
289#endif
290 for(int k = 0; k < numBlocks_; ++k) {
291 vecs_[k].getNonconstObj()->abs(*pv->getVectorBlock(k));
292 }
293 } else {
295 }
296}
297
298
299template <class Scalar>
301 const VectorBase<Scalar>& x
302 )
303{
304 // Apply operation block-by-block if mv is also a ProductVector
307 if (nonnull(pv)) {
308#ifdef TEUCHOS_DEBUG
309 TEUCHOS_ASSERT(productSpace_->isCompatible(*pv->productSpace()));
310#endif
311 for(int k = 0; k < numBlocks_; ++k) {
312 vecs_[k].getNonconstObj()->reciprocal(*pv->getVectorBlock(k));
313 }
314 } else {
316 }
317}
318
319
320template <class Scalar>
322 const VectorBase<Scalar>& x
323 )
324{
325 // Apply operation block-by-block if mv is also a ProductVector
328 if (nonnull(pv)) {
329#ifdef TEUCHOS_DEBUG
330 TEUCHOS_ASSERT(productSpace_->isCompatible(*pv->productSpace()));
331#endif
332 for(int k = 0; k < numBlocks_; ++k) {
333 vecs_[k].getNonconstObj()->ele_wise_scale(*pv->getVectorBlock(k));
334 }
335 } else {
337 }
338}
339
340
341template <class Scalar>
344 const VectorBase<Scalar>& x
345 ) const
346{
347 // Apply operation block-by-block if mv is also a ProductVector
348 typedef ScalarTraits<Scalar> ST;
351 if (nonnull(pv)) {
352#ifdef TEUCHOS_DEBUG
353 TEUCHOS_ASSERT(productSpace_->isCompatible(*pv->productSpace()));
354#endif
355 typename ST::magnitudeType norm = ST::magnitude(ST::zero());
356 for(int k = 0; k < numBlocks_; ++k) {
357 typename ST::magnitudeType subNorm
358 = vecs_[k].getConstObj()->norm_2(*pv->getVectorBlock(k));
359 norm += subNorm*subNorm;
360 }
361 return ST::magnitude(ST::squareroot(norm));
362 } else {
364 }
365}
366
367
368template <class Scalar>
370 const RTOpPack::RTOpT<Scalar> &op,
371 const ArrayView<const Ptr<const VectorBase<Scalar> > > &vecs,
372 const ArrayView<const Ptr<VectorBase<Scalar> > > &targ_vecs,
373 const Ptr<RTOpPack::ReductTarget> &reduct_obj,
374 const Ordinal global_offset_in
375 ) const
376{
377
378 // 2008/02/20: rabartl: ToDo: Upgrade Teuchos::Workspace<T> to implicitly
379 // convert to Teuchos::ArrayView<T>. This will allow the calls to
380 // applyOp(...) with sub_vecs and sub_targ_vecs to work without trouble!
381 // For now, I just want to get this done. It is likely that this function
382 // is going to change in major ways soon anyway!
383
384 //using Teuchos::Workspace;
385 using Teuchos::ptr_dynamic_cast;
386 using Teuchos::describe;
387 using Teuchos::null;
388
389 //Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
390
391 const Ordinal n = productSpace_->dim();
392 const int num_vecs = vecs.size();
393 const int num_targ_vecs = targ_vecs.size();
394
395 // Validate the compatibility of the vectors!
396#ifdef TEUCHOS_DEBUG
397 bool test_failed;
398 for(int k = 0; k < num_vecs; ++k) {
399 test_failed = !this->space()->isCompatible(*vecs[k]->space());
402 ,"DefaultProductVector::applyOp(...): Error vecs["<<k<<"]->space() = "
403 <<vecs[k]->space()->description()<<"\' is not compatible with this "
404 <<"vector space = "<<this->space()->description()<<"!"
405 );
406 }
407 for(int k = 0; k < num_targ_vecs; ++k) {
408 test_failed = !this->space()->isCompatible(*targ_vecs[k]->space());
411 ,"DefaultProductVector::applyOp(...): Error targ_vecs["<<k<<"]->space() = "
412 <<targ_vecs[k]->space()->description()<<"\' is not compatible with this "
413 <<"vector space = "<<this->space()->description()<<"!"
414 );
415 }
416#endif
417
418 //
419 // Dynamic cast each of the vector arguments to the ProductVectorBase interface
420 //
421 // NOTE: If the constituent vector is not a product vector, then a product
422 // vector of one component is created.
423 //
424
425 Array<RCP<const ProductVectorBase<Scalar> > > vecs_args_store(num_vecs);
426 Array<Ptr<const ProductVectorBase<Scalar> > > vecs_args(num_vecs);
427 for(int k = 0; k < num_vecs; ++k) {
428 vecs_args_store[k] =
429 castOrCreateProductVectorBase<Scalar>(rcpFromPtr(vecs[k]));
430 vecs_args[k] = vecs_args_store[k].ptr();
431 }
432
433 Array<RCP<ProductVectorBase<Scalar> > > targ_vecs_args_store(num_targ_vecs);
434 Array<Ptr<ProductVectorBase<Scalar> > > targ_vecs_args(num_targ_vecs);
435 for(int k = 0; k < num_targ_vecs; ++k) {
436 targ_vecs_args_store[k] =
437 castOrCreateNonconstProductVectorBase<Scalar>(rcpFromPtr(targ_vecs[k]));
438 targ_vecs_args[k] = targ_vecs_args_store[k].ptr();
439 }
440
441 //
442 // If we get here, then we will implement the applyOpImpl(...) one vector
443 // block at a time.
444 //
445 const Ordinal dim = n;
446 Ordinal num_elements_remaining = dim;
447 const int numBlocks = productSpace_->numBlocks();
449 sub_vecs_rcps(num_vecs);
451 sub_vecs(num_vecs);
453 sub_targ_vecs_rcps(num_targ_vecs);
455 sub_targ_vecs(num_targ_vecs);
456 Ordinal g_off = 0;
457 for(int k = 0; k < numBlocks; ++k) {
458 const Ordinal dim_k = productSpace_->getBlock(k)->dim();
459 // Fill constituent vectors for block k
460 for( int i = 0; i < num_vecs; ++i ) {
461 sub_vecs_rcps[i] = vecs_args[i]->getVectorBlock(k);
462 sub_vecs[i] = sub_vecs_rcps[i].ptr();
463 }
464 // Fill constituent target vectors for block k
465 for( int j = 0; j < num_targ_vecs; ++j ) {
466 sub_targ_vecs_rcps[j] = targ_vecs_args[j]->getNonconstVectorBlock(k);
467 sub_targ_vecs[j] = sub_targ_vecs_rcps[j].ptr();
468 }
469 Thyra::applyOp<Scalar>(
470 op, sub_vecs(), sub_targ_vecs(),
471 reduct_obj,
472 global_offset_in + g_off
473 );
474 g_off += dim_k;
475 num_elements_remaining -= dim_k;
476 }
477 TEUCHOS_TEST_FOR_EXCEPT(!(num_elements_remaining==0));
478
479}
480
481
482// protected
483
484
485// Overridden protected functions from VectorBase
486
487
488template <class Scalar>
490 const Range1D& rng_in, RTOpPack::ConstSubVectorView<Scalar>* sub_vec
491 ) const
492{
493 const Range1D
494 rng = rng_in.full_range() ? Range1D(0,productSpace_->dim()-1) : rng_in;
495 int kth_vector_space = -1;
496 Ordinal kth_global_offset = 0;
497 productSpace_->getVecSpcPoss(rng.lbound(),&kth_vector_space,&kth_global_offset);
498#ifdef TEUCHOS_DEBUG
499 TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= kth_vector_space && kth_vector_space <= numBlocks_ ) );
500#endif
501 if(
502 rng.lbound() + rng.size()
503 <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim()
504 )
505 {
506 // This involves only one sub-vector so just return it.
507 const_cast<const VectorBase<Scalar>*>(
508 &*vecs_[kth_vector_space].getConstObj()
509 )->acquireDetachedView( rng - kth_global_offset, sub_vec );
510 sub_vec->setGlobalOffset( sub_vec->globalOffset() + kth_global_offset );
511 }
512 else {
513 // Just let the default implementation handle this. ToDo: In the future
514 // we could manually construct an explicit sub-vector that spanned
515 // two or more constituent vectors but this would be a lot of work.
516 // However, this would require the use of temporary memory but
517 // so what.
519 }
520}
521
522
523template <class Scalar>
526 ) const
527{
528 if( sub_vec->values().get() == NULL ) return;
529 int kth_vector_space = -1;
530 Ordinal kth_global_offset = 0;
531 productSpace_->getVecSpcPoss(sub_vec->globalOffset(),&kth_vector_space,&kth_global_offset);
532#ifdef TEUCHOS_DEBUG
533 TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= kth_vector_space && kth_vector_space <= numBlocks_ ) );
534#endif
535 if(
536 sub_vec->globalOffset() + sub_vec->subDim()
537 <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim()
538 )
539 {
540 // This sub_vec was extracted from a single constituent vector
541 sub_vec->setGlobalOffset( sub_vec->globalOffset() - kth_global_offset );
542 vecs_[kth_vector_space].getConstObj()->releaseDetachedView(sub_vec);
543 }
544 else {
545 // This sub_vec was created by the default implementation!
547 }
548}
549
550
551template <class Scalar>
553 const Range1D& rng_in, RTOpPack::SubVectorView<Scalar>* sub_vec
554 )
555{
556 const Range1D
557 rng = rng_in.full_range() ? Range1D(0,productSpace_->dim()-1) : rng_in;
558 int kth_vector_space = -1;
559 Ordinal kth_global_offset = 0;
560 productSpace_->getVecSpcPoss(rng.lbound(),&kth_vector_space,&kth_global_offset);
561#ifdef TEUCHOS_DEBUG
562 TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= kth_vector_space && kth_vector_space <= numBlocks_ ) );
563#endif
564 if(
565 rng.lbound() + rng.size()
566 <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim()
567 )
568 {
569 // This involves only one sub-vector so just return it.
570 vecs_[kth_vector_space].getConstObj()->acquireDetachedView(
571 rng - kth_global_offset, sub_vec
572 );
573 sub_vec->setGlobalOffset( sub_vec->globalOffset() + kth_global_offset );
574 }
575 else {
576 // Just let the default implementation handle this. ToDo: In the future
577 // we could manually construct an explicit sub-vector that spanned
578 // two or more constituent vectors but this would be a lot of work.
579 // However, this would require the use of temporary memory but
580 // so what.
582 }
583}
584
585
586template <class Scalar>
589 )
590{
591 if( sub_vec->values().get() == NULL ) return;
592 int kth_vector_space = -1;
593 Ordinal kth_global_offset = 0;
594 productSpace_->getVecSpcPoss(sub_vec->globalOffset(),&kth_vector_space,&kth_global_offset);
595#ifdef TEUCHOS_DEBUG
596 TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= kth_vector_space && kth_vector_space <= numBlocks_ ) );
597#endif
598 if(
599 sub_vec->globalOffset() + sub_vec->subDim()
600 <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim()
601 )
602 {
603 // This sub_vec was extracted from a single constituent vector
604 sub_vec->setGlobalOffset( sub_vec->globalOffset() - kth_global_offset );
605 vecs_[kth_vector_space].getNonconstObj()->commitDetachedView(sub_vec);
606 }
607 else {
608 // This sub_vec was created by the default implementation!
610 }
611}
612
613
614template <class Scalar>
617 )
618{
619 int kth_vector_space = -1;
620 Ordinal kth_global_offset = 0;
621 productSpace_->getVecSpcPoss(sub_vec.globalOffset(),&kth_vector_space,&kth_global_offset);
622#ifdef TEUCHOS_DEBUG
623 TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= kth_vector_space && kth_vector_space <= numBlocks_ ) );
624#endif
625 if(
626 sub_vec.globalOffset() + sub_vec.subDim()
627 <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim()
628 )
629 {
630 // This sub-vector fits into a single constituent vector
631 RTOpPack::SparseSubVectorT<Scalar> sub_vec_g = sub_vec;
632 sub_vec_g.setGlobalOffset( sub_vec_g.globalOffset() - kth_global_offset );
633 vecs_[kth_vector_space].getNonconstObj()->setSubVector(sub_vec_g);
634 }
635 else {
636 // Let the default implementation take care of this. ToDo: In the future
637 // it would be possible to manually set the relevant constituent
638 // vectors with no temp memory allocations.
640 }
641}
642
643
644// Overridden protected functions from MultiVectorBase
645
646
647template <class Scalar>
649{
650 for(int k = 0; k < numBlocks_; ++k) {
651 vecs_[k].getNonconstObj()->assign(alpha);
652 }
653}
654
655
656template <class Scalar>
659 )
660{
661#ifdef TEUCHOS_DEBUG
662 TEUCHOS_ASSERT_EQUALITY(mv.domain()->dim(), 1);
663#endif
666 if (nonnull(pv)) {
667#ifdef TEUCHOS_DEBUG
668 TEUCHOS_ASSERT(productSpace_->isCompatible(*pv->productSpace()));
669#endif
670 for(int k = 0; k < numBlocks_; ++k) {
671 vecs_[k].getNonconstObj()->assign(*pv->getMultiVectorBlock(k));
672 }
673 } else {
675 }
676}
677
678
679template <class Scalar>
681{
682 for(int k = 0; k < numBlocks_; ++k) {
683 vecs_[k].getNonconstObj()->scale(alpha);
684 }
685}
686
687
688template <class Scalar>
690 Scalar alpha,
692 )
693{
694#ifdef TEUCHOS_DEBUG
695 TEUCHOS_ASSERT_EQUALITY(mv.domain()->dim(), 1);
696#endif
699 if (nonnull(pv)) {
700#ifdef TEUCHOS_DEBUG
701 TEUCHOS_ASSERT(productSpace_->isCompatible(*pv->productSpace()));
702#endif
703 for(int k = 0; k < numBlocks_; ++k) {
704 vecs_[k].getNonconstObj()->update(alpha, *pv->getMultiVectorBlock(k));
705 }
706 } else {
708 }
709}
710
711
712template <class Scalar>
714 const ArrayView<const Scalar>& alpha,
715 const ArrayView<const Ptr<const MultiVectorBase<Scalar> > >& mv,
716 const Scalar& beta
717 )
718{
719#ifdef TEUCHOS_DEBUG
720 TEUCHOS_ASSERT_EQUALITY(alpha.size(), mv.size());
721#endif
722
723 // Apply operation block-by-block if each element of mv is also a ProductMultiVector
724 bool allCastsSuccessful = true;
726 for (Ordinal i = 0; i < mv.size(); ++i) {
728 if (pvs[i].is_null()) {
729 allCastsSuccessful = false;
730 break;
731 }
732#ifdef TEUCHOS_DEBUG
733 TEUCHOS_ASSERT_EQUALITY(pvs[i]->domain()->dim(), 1);
734 TEUCHOS_ASSERT(productSpace_->isCompatible(*pvs[i]->productSpace()));
735#endif
736 }
737
738 if (allCastsSuccessful) {
739 Array<RCP<const MultiVectorBase<Scalar> > > blocks_rcp(pvs.size());
741 for (int k = 0; k < numBlocks_; ++k) {
742 for (Ordinal i = 0; i < pvs.size(); ++i) {
743 blocks_rcp[i] = pvs[i]->getMultiVectorBlock(k);
744 blocks[i] = blocks_rcp[i].ptr();
745 }
746 vecs_[k].getNonconstObj()->linear_combination(alpha, blocks(), beta);
747 }
748 } else {
750 }
751}
752
753
754template <class Scalar>
756 const MultiVectorBase<Scalar>& mv,
757 const ArrayView<Scalar>& prods
758 ) const
759{
760#ifdef TEUCHOS_DEBUG
761 TEUCHOS_ASSERT_EQUALITY(prods.size(), 1);
762 TEUCHOS_ASSERT_EQUALITY(mv.domain()->dim(), 1);
763#endif
766 if (nonnull(pv)) {
767#ifdef TEUCHOS_DEBUG
768 TEUCHOS_ASSERT(productSpace_->isCompatible(*pv->productSpace()));
769#endif
770 prods[0] = ScalarTraits<Scalar>::zero();
771 for(int k = 0; k < numBlocks_; ++k) {
772 Scalar prod;
773 vecs_[k].getConstObj()->dots(*pv->getMultiVectorBlock(k), Teuchos::arrayView(&prod, 1));
774 prods[0] += prod;
775 }
776 } else {
778 }
779}
780
781
782template <class Scalar>
785 ) const
786{
787#ifdef TEUCHOS_DEBUG
788 TEUCHOS_ASSERT_EQUALITY(norms.size(), 1);
789#endif
790 typedef ScalarTraits<Scalar> ST;
791 norms[0] = ST::magnitude(ST::zero());
792 for(int k = 0; k < numBlocks_; ++k) {
793 norms[0] += vecs_[k].getConstObj()->norm_1();
794 }
795}
796
797
798template <class Scalar>
801 ) const
802{
803#ifdef TEUCHOS_DEBUG
804 TEUCHOS_ASSERT_EQUALITY(norms.size(), 1);
805#endif
806 typedef ScalarTraits<Scalar> ST;
807 norms[0] = ST::magnitude(ST::zero());
808 for(int k = 0; k < numBlocks_; ++k) {
809 typename ST::magnitudeType subNorm
810 = vecs_[k].getConstObj()->norm_2();
811 norms[0] += subNorm*subNorm;
812 }
813 norms[0] = ST::magnitude(ST::squareroot(norms[0]));
814}
815
816
817template <class Scalar>
820 ) const
821{
822#ifdef TEUCHOS_DEBUG
823 TEUCHOS_ASSERT_EQUALITY(norms.size(), 1);
824#endif
825 typedef ScalarTraits<Scalar> ST;
826 norms[0] = ST::magnitude(ST::zero());
827 for(int k = 0; k < numBlocks_; ++k) {
828 typename ST::magnitudeType subNorm = vecs_[k].getConstObj()->norm_inf();
829 if (subNorm > norms[0]) {
830 norms[0] = subNorm;
831 }
832 }
833}
834
835
836} // namespace Thyra
837
838
839template<class Scalar>
841Thyra::castOrCreateNonconstProductVectorBase(const RCP<VectorBase<Scalar> > v)
842{
843 using Teuchos::rcp_dynamic_cast;
844 using Teuchos::tuple;
845 const RCP<ProductVectorBase<Scalar> > prod_v =
846 rcp_dynamic_cast<ProductVectorBase<Scalar> >(v);
847 if (nonnull(prod_v)) {
848 return prod_v;
849 }
850 return defaultProductVector<Scalar>(
851 productVectorSpace<Scalar>(tuple(v->space())()),
852 tuple(v)()
853 );
854}
855
856
857template<class Scalar>
859Thyra::castOrCreateProductVectorBase(const RCP<const VectorBase<Scalar> > v)
860{
861 using Teuchos::rcp_dynamic_cast;
862 using Teuchos::tuple;
863 const RCP<const ProductVectorBase<Scalar> > prod_v =
864 rcp_dynamic_cast<const ProductVectorBase<Scalar> >(v);
865 if (nonnull(prod_v)) {
866 return prod_v;
867 }
868 return defaultProductVector<Scalar>(
869 productVectorSpace<Scalar>(tuple(v->space())()),
870 tuple(v)()
871 );
872}
873
874
875//
876// Explicit instant macro
877//
878
879#define THYRA_DEFAULT_PRODUCT_VECTOR_INSTANT(SCALAR) \
880 \
881 template class DefaultProductVector<SCALAR >; \
882 \
883 template RCP<ProductVectorBase<SCALAR > > \
884 castOrCreateNonconstProductVectorBase(const RCP<VectorBase<SCALAR > > v); \
885 \
886 template RCP<const ProductVectorBase<SCALAR > > \
887 castOrCreateProductVectorBase(const RCP<const VectorBase<SCALAR > > v); \
888
889
890
891#endif // THYRA_DEFAULT_PRODUCT_VECTOR_DEF_HPP
Ordinal globalOffset() const
void setGlobalOffset(Ordinal globalOffset_in)
const ArrayRCP< const Scalar > values() const
Teuchos_Ordinal globalOffset() const
Teuchos_Ordinal subDim() const
void setGlobalOffset(Teuchos_Ordinal globalOffset_in)
const ArrayRCP< Scalar > values() const
T * get() const
size_type size() const
size_type size() const
virtual std::string description() const
bool full_range() const
Ordinal size() const
Ordinal lbound() const
void setSubVectorImpl(const RTOpPack::SparseSubVectorT< Scalar > &sub_vec)
void initialize(const RCP< const DefaultProductVectorSpace< Scalar > > &productSpace)
Initialize.
DefaultProductVector()
Construct to uninitialized.
void acquireNonconstDetachedVectorViewImpl(const Range1D &rng, RTOpPack::SubVectorView< Scalar > *sub_vec)
virtual void updateImpl(Scalar alpha, const MultiVectorBase< Scalar > &mv)
virtual void assignMultiVecImpl(const MultiVectorBase< Scalar > &mv)
virtual void norms2Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
virtual void normsInfImpl(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
RCP< const MultiVectorBase< Scalar > > getMultiVectorBlock(const int k) const
virtual Teuchos::ScalarTraits< Scalar >::magnitudeType norm2WeightedImpl(const VectorBase< Scalar > &x) const
virtual void norms1Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
RCP< MultiVectorBase< Scalar > > getNonconstMultiVectorBlock(const int k)
RCP< const ProductVectorSpaceBase< Scalar > > productSpace() const
void setNonconstBlock(int i, const RCP< VectorBase< Scalar > > &b)
void setBlock(int i, const RCP< const VectorBase< Scalar > > &b)
virtual void absImpl(const VectorBase< Scalar > &x)
virtual void linearCombinationImpl(const ArrayView< const Scalar > &alpha, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &mv, const Scalar &beta)
void acquireDetachedVectorViewImpl(const Range1D &rng, RTOpPack::ConstSubVectorView< Scalar > *sub_vec) const
virtual void reciprocalImpl(const VectorBase< Scalar > &x)
RCP< VectorBase< Scalar > > getNonconstVectorBlock(const int k)
RCP< const VectorSpaceBase< Scalar > > space() const
virtual void eleWiseScaleImpl(const VectorBase< Scalar > &x)
virtual void dotsImpl(const MultiVectorBase< Scalar > &mv, const ArrayView< Scalar > &prods) const
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 commitNonconstDetachedVectorViewImpl(RTOpPack::SubVectorView< Scalar > *sub_vec)
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Thrown if vector spaces are incompatible.
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.
void setSubVector(const RTOpPack::SparseSubVectorT< Scalar > &sub_vec)
Calls setSubVectorImpl().
virtual void acquireNonconstDetachedVectorViewImpl(const Range1D &rng, RTOpPack::SubVectorView< Scalar > *sub_vec)
virtual Teuchos::ScalarTraits< Scalar >::magnitudeType norm2WeightedImpl(const VectorBase< Scalar > &x) const
Default implementation of norm_2 (weighted) using RTOps.
virtual void acquireDetachedVectorViewImpl(const Range1D &rng, RTOpPack::ConstSubVectorView< Scalar > *sub_vec) const
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.
virtual void releaseDetachedVectorViewImpl(RTOpPack::ConstSubVectorView< Scalar > *sub_vec) const
virtual void commitNonconstDetachedVectorViewImpl(RTOpPack::SubVectorView< Scalar > *sub_vec)
#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 nonnull(const std::shared_ptr< T > &p)
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
Teuchos::Range1D Range1D
TypeTo as(const TypeFrom &t)
T_To & dyn_cast(T_From &from)