10#ifndef THYRA_DEFAULT_PRODUCT_VECTOR_DEF_HPP
11#define THYRA_DEFAULT_PRODUCT_VECTOR_DEF_HPP
14#include "Thyra_DefaultProductVector_decl.hpp"
15#include "Thyra_DefaultProductVectorSpace.hpp"
16#include "Teuchos_Workspace.hpp"
25template <
class Scalar>
33template <
class Scalar>
43template <
class Scalar>
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)));
57template <
class Scalar>
66 as<Ordinal>(vecs.size()) );
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]);
76template <
class Scalar>
85 as<Ordinal>(vecs.size()) );
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]);
95template <
class Scalar>
107template<
class Scalar>
111 std::ostringstream oss;
115 <<
"dim="<<(nonnull(vs) ? vs->dim() : 0)
116 <<
", numBlocks = "<<numBlocks_
122template<
class Scalar>
130 using Teuchos::describe;
138 *out << this->description() << std::endl;
146 <<
"dim=" << this->space()->dim()
150 <<
"numBlocks="<< numBlocks_ << std::endl
151 <<
"Constituent vector objects v[0], v[1], ... v[numBlocks-1]:\n";
153 for(
int k = 0; k < numBlocks_; ++k ) {
154 *out <<
"v["<<k<<
"] = " << describe(*vecs_[k].getConstObj(),verbLevel);
167template <
class Scalar>
180template <
class Scalar>
196template <
class Scalar>
203 return vecs_[k].getNonconstObj();
207template <
class Scalar>
214 return vecs_[k].getConstObj();
221template <
class Scalar>
225 return productSpace_;
229template <
class Scalar>
235 return vecs_[k].isConst();
239template <
class Scalar>
243 return getNonconstVectorBlock(k);
247template <
class Scalar>
251 return getVectorBlock(k);
258template <
class Scalar>
262 return productSpace_;
278template <
class Scalar>
290 for(
int k = 0; k < numBlocks_; ++k) {
291 vecs_[k].getNonconstObj()->abs(*pv->getVectorBlock(k));
299template <
class Scalar>
311 for(
int k = 0; k < numBlocks_; ++k) {
312 vecs_[k].getNonconstObj()->reciprocal(*pv->getVectorBlock(k));
320template <
class Scalar>
332 for(
int k = 0; k < numBlocks_; ++k) {
333 vecs_[k].getNonconstObj()->ele_wise_scale(*pv->getVectorBlock(k));
341template <
class Scalar>
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;
361 return ST::magnitude(ST::squareroot(norm));
368template <
class Scalar>
385 using Teuchos::ptr_dynamic_cast;
386 using Teuchos::describe;
391 const Ordinal n = productSpace_->dim();
392 const int num_vecs = vecs.size();
393 const int num_targ_vecs = targ_vecs.size();
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()<<
"!"
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()<<
"!"
427 for(
int k = 0; k < num_vecs; ++k) {
429 castOrCreateProductVectorBase<Scalar>(rcpFromPtr(vecs[k]));
430 vecs_args[k] = vecs_args_store[k].ptr();
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();
446 Ordinal num_elements_remaining = dim;
447 const int numBlocks = productSpace_->numBlocks();
449 sub_vecs_rcps(num_vecs);
453 sub_targ_vecs_rcps(num_targ_vecs);
455 sub_targ_vecs(num_targ_vecs);
457 for(
int k = 0; k < numBlocks; ++k) {
458 const Ordinal dim_k = productSpace_->getBlock(k)->dim();
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();
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();
469 Thyra::applyOp<Scalar>(
470 op, sub_vecs(), sub_targ_vecs(),
472 global_offset_in + g_off
475 num_elements_remaining -= dim_k;
488template <
class Scalar>
495 int kth_vector_space = -1;
497 productSpace_->getVecSpcPoss(rng.
lbound(),&kth_vector_space,&kth_global_offset);
503 <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim()
508 &*vecs_[kth_vector_space].getConstObj()
509 )->acquireDetachedView( rng - kth_global_offset, sub_vec );
523template <
class Scalar>
528 if( sub_vec->
values().
get() == NULL )
return;
529 int kth_vector_space = -1;
531 productSpace_->getVecSpcPoss(sub_vec->
globalOffset(),&kth_vector_space,&kth_global_offset);
537 <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim()
542 vecs_[kth_vector_space].getConstObj()->releaseDetachedView(sub_vec);
551template <
class Scalar>
558 int kth_vector_space = -1;
560 productSpace_->getVecSpcPoss(rng.
lbound(),&kth_vector_space,&kth_global_offset);
566 <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim()
570 vecs_[kth_vector_space].getConstObj()->acquireDetachedView(
571 rng - kth_global_offset, sub_vec
586template <
class Scalar>
591 if( sub_vec->
values().
get() == NULL )
return;
592 int kth_vector_space = -1;
594 productSpace_->getVecSpcPoss(sub_vec->
globalOffset(),&kth_vector_space,&kth_global_offset);
600 <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim()
605 vecs_[kth_vector_space].getNonconstObj()->commitDetachedView(sub_vec);
614template <
class Scalar>
619 int kth_vector_space = -1;
621 productSpace_->getVecSpcPoss(sub_vec.
globalOffset(),&kth_vector_space,&kth_global_offset);
627 <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim()
633 vecs_[kth_vector_space].getNonconstObj()->setSubVector(sub_vec_g);
647template <
class Scalar>
650 for(
int k = 0; k < numBlocks_; ++k) {
651 vecs_[k].getNonconstObj()->assign(alpha);
656template <
class Scalar>
670 for(
int k = 0; k < numBlocks_; ++k) {
671 vecs_[k].getNonconstObj()->assign(*pv->getMultiVectorBlock(k));
679template <
class Scalar>
682 for(
int k = 0; k < numBlocks_; ++k) {
683 vecs_[k].getNonconstObj()->scale(alpha);
688template <
class Scalar>
703 for(
int k = 0; k < numBlocks_; ++k) {
704 vecs_[k].getNonconstObj()->update(alpha, *pv->getMultiVectorBlock(k));
712template <
class Scalar>
724 bool allCastsSuccessful =
true;
726 for (
Ordinal i = 0; i < mv.size(); ++i) {
728 if (pvs[i].is_null()) {
729 allCastsSuccessful =
false;
734 TEUCHOS_ASSERT(productSpace_->isCompatible(*pvs[i]->productSpace()));
738 if (allCastsSuccessful) {
741 for (
int k = 0; k < numBlocks_; ++k) {
743 blocks_rcp[i] = pvs[i]->getMultiVectorBlock(k);
744 blocks[i] = blocks_rcp[i].ptr();
746 vecs_[k].getNonconstObj()->linear_combination(alpha, blocks(), beta);
754template <
class Scalar>
771 for(
int k = 0; k < numBlocks_; ++k) {
773 vecs_[k].getConstObj()->dots(*pv->getMultiVectorBlock(k), Teuchos::arrayView(&prod, 1));
782template <
class Scalar>
791 norms[0] = ST::magnitude(ST::zero());
792 for(
int k = 0; k < numBlocks_; ++k) {
793 norms[0] += vecs_[k].getConstObj()->norm_1();
798template <
class Scalar>
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;
813 norms[0] = ST::magnitude(ST::squareroot(norms[0]));
817template <
class Scalar>
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]) {
839template<
class Scalar>
841Thyra::castOrCreateNonconstProductVectorBase(
const RCP<VectorBase<Scalar> > v)
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)) {
850 return defaultProductVector<Scalar>(
851 productVectorSpace<Scalar>(tuple(v->space())()),
857template<
class Scalar>
859Thyra::castOrCreateProductVectorBase(
const RCP<
const VectorBase<Scalar> > v)
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);
868 return defaultProductVector<Scalar>(
869 productVectorSpace<Scalar>(tuple(v->space())()),
879#define THYRA_DEFAULT_PRODUCT_VECTOR_INSTANT(SCALAR) \
881 template class DefaultProductVector<SCALAR >; \
883 template RCP<ProductVectorBase<SCALAR > > \
884 castOrCreateNonconstProductVectorBase(const RCP<VectorBase<SCALAR > > v); \
886 template RCP<const ProductVectorBase<SCALAR > > \
887 castOrCreateProductVectorBase(const RCP<const VectorBase<SCALAR > > v); \
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
virtual std::string description() 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 assignImpl(Scalar alpha)
virtual void assignMultiVecImpl(const MultiVectorBase< Scalar > &mv)
void uninitialize()
Uninitialize.
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
bool blockIsConst(const int k) 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
virtual void scaleImpl(Scalar alpha)
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
std::string description() 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. `*.
TypeTo as(const TypeFrom &t)
T_To & dyn_cast(T_From &from)