10 #ifndef THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_DEF_HPP
11 #define THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_DEF_HPP
13 #include "Thyra_DefaultProductMultiVector_decl.hpp"
14 #include "Thyra_DefaultProductVectorSpace.hpp"
15 #include "Thyra_DefaultProductVector.hpp"
16 #include "Thyra_AssertOp.hpp"
25 template<
class Scalar>
31 template<
class Scalar>
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));
49 template<
class Scalar>
55 initializeImpl(productSpace_in,multiVecs);
59 template<
class Scalar>
65 initializeImpl(productSpace_in,multiVecs);
69 template<
class Scalar>
72 productSpace_ = Teuchos::null;
81 template<
class Scalar>
84 std::ostringstream oss;
88 <<
"rangeDim="<<this->range()->dim()
89 <<
",domainDim="<<this->domain()->dim()
90 <<
",numBlocks = "<<numBlocks_
96 template<
class Scalar>
103 using Teuchos::describe;
113 *out << this->description() << std::endl;
121 <<
"rangeDim="<<this->range()->dim()
122 <<
",domainDim="<<this->domain()->dim()
126 <<
"numBlocks="<< numBlocks_ << std::endl
127 <<
"Constituent multi-vector objects V[0], V[1], ... V[numBlocks-1]:\n";
129 for(
int k = 0; k < numBlocks_; ++k ) {
130 *out <<
"V["<<k<<
"] = "
131 << Teuchos::describe(*multiVecs_[k].getConstObj(),verbLevel);
144 template<
class Scalar>
148 return productSpace_;
152 template<
class Scalar>
155 return multiVecs_[k].isConst();
159 template<
class Scalar>
163 return multiVecs_[k].getNonconstObj();
167 template<
class Scalar>
171 return multiVecs_[k].getConstObj();
178 template<
class Scalar>
184 for (
int k = 0; k < numBlocks_; ++k )
185 blocks.
push_back(multiVecs_[k].getConstObj()->clone_mv());
186 return defaultProductMultiVector<Scalar>(productSpace_, blocks());
193 template<
class Scalar>
197 return productSpace_;
201 template<
class Scalar>
206 return Teuchos::null;
207 return multiVecs_[0].getConstObj()->domain();
217 template<
class Scalar>
220 for (
int k = 0; k < numBlocks_; ++k ) {
221 multiVecs_[k].getNonconstObj()->assign(alpha);
226 template<
class Scalar>
240 for (
int k = 0; k < numBlocks_; ++k) {
241 multiVecs_[k].getNonconstObj()->
assign(*pv->getMultiVectorBlock(k));
249 template<
class Scalar>
252 for (
int k = 0; k < numBlocks_; ++k) {
253 multiVecs_[k].getNonconstObj()->scale(alpha);
258 template<
class Scalar>
273 for (
int k = 0; k < numBlocks_; ++k) {
274 multiVecs_[k].getNonconstObj()->
update(alpha, *pv->getMultiVectorBlock(k));
282 template<
class Scalar>
291 for (
Ordinal i = 0; i < mv.size(); ++i) {
298 bool allCastsSuccessful =
true;
300 for (
Ordinal i = 0; i < mv.size(); ++i) {
303 allCastsSuccessful =
false;
308 if (allCastsSuccessful) {
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();
316 multiVecs_[k].getNonconstObj()->linear_combination(alpha, blocks(), beta);
324 template<
class Scalar>
343 for (
int k = 0; k < numBlocks_; ++k) {
344 multiVecs_[k].getConstObj()->dots(*pv->getMultiVectorBlock(k), subProds());
346 prods[i] += subProds[i];
355 template<
class Scalar>
364 for (
Ordinal i = 0; i < norms.size(); ++i)
365 norms[i] = ST::magnitude(ST::zero());
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];
377 template<
class Scalar>
386 for (
Ordinal i = 0; i < norms.size(); ++i)
387 norms[i] = ST::magnitude(ST::zero());
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];
397 for (
Ordinal i = 0; i < norms.size(); ++i) {
398 norms[i] = ST::magnitude(ST::squareroot(norms[i]));
403 template<
class Scalar>
412 for (
Ordinal i = 0; i < norms.size(); ++i)
413 norms[i] = ST::magnitude(ST::zero());
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];
426 template<
class Scalar>
432 for (
int k = 0; k < numBlocks_; ++k )
433 cols_.
push_back(multiVecs_[k].getConstObj()->col(j));
434 return defaultProductVector<Scalar>(productSpace_, cols_());
438 template<
class Scalar>
444 for (
int k = 0; k < numBlocks_; ++k )
445 cols_.
push_back(multiVecs_[k].getNonconstObj()->col(j));
446 return defaultProductVector<Scalar>(productSpace_, cols_());
450 template<
class Scalar>
456 for (
int k = 0; k < numBlocks_; ++k )
457 blocks.
push_back(multiVecs_[k].getConstObj()->subView(colRng));
458 return defaultProductMultiVector<Scalar>(productSpace_, blocks());
462 template<
class Scalar>
468 for (
int k = 0; k < numBlocks_; ++k )
469 blocks.
push_back(multiVecs_[k].getNonconstObj()->subView(colRng));
470 return defaultProductMultiVector<Scalar>(productSpace_, blocks());
474 template<
class Scalar>
482 for (
int k = 0; k < numBlocks_; ++k )
483 blocks.
push_back(multiVecs_[k].getConstObj()->subView(cols));
484 return defaultProductMultiVector<Scalar>(productSpace_, blocks());
488 template<
class Scalar>
496 for (
int k = 0; k < numBlocks_; ++k )
497 blocks.
push_back(multiVecs_[k].getNonconstObj()->subView(cols));
498 return defaultProductMultiVector<Scalar>(productSpace_, blocks());
502 template<
class Scalar>
508 const Ordinal primary_global_offset_in
512 using Teuchos::ptr_dynamic_cast;
513 using Thyra::applyOp;
518 for (
int j = 0; j < multi_vecs_in.size(); ++j ) {
520 "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
521 *this->range(), *multi_vecs_in[j]->range()
524 "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
525 *this->domain(), *multi_vecs_in[j]->domain()
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()
534 "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
535 *this->domain(), *targ_multi_vecs_inout[j]->domain()
538 #endif // TEUCHOS_DEBUG
545 bool allProductMultiVectors =
true;
548 for (
int j = 0; j < multi_vecs_in.size() && allProductMultiVectors; ++j ) {
556 if ( !
is_null(multi_vecs_j) ) {
560 allProductMultiVectors =
false;
565 for (
int j = 0; j < targ_multi_vecs_inout.size() && allProductMultiVectors; ++j )
572 targ_multi_vecs_inout[j]
574 if (!
is_null(targ_multi_vecs_j)) {
575 targ_multi_vecs.
push_back(targ_multi_vecs_j);
578 allProductMultiVectors =
false;
586 if ( allProductMultiVectors ) {
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());
604 Ordinal g_off = primary_global_offset_in;
606 for (
int k = 0; k < numBlocks_; ++k ) {
608 const Ordinal dim_k = productSpace_->getBlock(k)->dim();
612 for (
int j = 0; j < multi_vecs_in.size(); ++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();
619 for (
int j = 0; j < targ_multi_vecs_inout.size(); ++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();
628 Thyra::applyOp<Scalar>(
629 primary_op, multi_vecs_block_k(), targ_multi_vecs_block_k(),
646 primary_op, multi_vecs_in(), targ_multi_vecs_inout(),
647 reduct_objs, primary_global_offset_in);
654 template<
class Scalar>
662 rowRng, colRng, sub_mv );
667 template<
class Scalar>
678 template<
class Scalar>
686 rowRng,colRng,sub_mv );
691 template<
class Scalar>
704 template<
class Scalar>
711 template<
class Scalar>
727 "DefaultProductMultiVector<Scalar>::apply(...)",
728 *
this, M_trans, X_in, &*Y_inout );
741 for (
int k = 0; k < numBlocks_; ++k ) {
743 *multiVecs_[k].getConstObj(), M_trans,
758 for (
int k = 0; k < numBlocks_; ++k ) {
760 M_k = multiVecs_[k].getConstObj(),
763 Thyra::apply( *M_k, M_trans, *X_k, Y_inout.
ptr(), alpha, beta );
766 Thyra::apply( *M_k, M_trans, *X_k, Y_inout.
ptr(), alpha, ST::one() );
776 template<
class Scalar>
777 template<
class MultiVectorType>
789 #endif // TEUCHOS_DEBUG
791 theDomain = multiVecs[0]->domain();
792 const int numBlocks = productSpace_in->numBlocks();
794 for (
int k = 0; k < numBlocks; ++k ) {
797 *theDomain, *multiVecs[k]->domain()
801 productSpace_ = productSpace_in;
802 numBlocks_ = numBlocks;
803 multiVecs_.assign(multiVecs.begin(),multiVecs.end());
810 template<
class Scalar>
811 void DefaultProductMultiVector<Scalar>::assertInitialized()
const
814 is_null(productSpace_), std::logic_error,
815 "Error, this DefaultProductMultiVector object is not intialized!"
820 template<
class Scalar>
821 void DefaultProductMultiVector<Scalar>::validateColIndex(
const int j)
const
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<<
"]!"
832 #endif // TEUCHOS_DEBUG
838 template<
class Scalar>
840 Thyra::defaultProductMultiVector()
842 return Teuchos::rcp(
new DefaultProductMultiVector<Scalar>);
846 template<
class Scalar>
848 Thyra::defaultProductMultiVector(
849 const RCP<
const DefaultProductVectorSpace<Scalar> > &productSpace,
853 RCP<DefaultProductMultiVector<Scalar> > pmv = defaultProductMultiVector<Scalar>();
854 pmv->initialize(productSpace, numMembers);
859 template<
class Scalar>
861 Thyra::defaultProductMultiVector(
862 const RCP<
const DefaultProductVectorSpace<Scalar> > &productSpace,
863 const ArrayView<
const RCP<MultiVectorBase<Scalar> > > &multiVecs
866 const RCP<DefaultProductMultiVector<Scalar> > pmv =
867 defaultProductMultiVector<Scalar>();
868 pmv->initialize(productSpace, multiVecs);
873 template<
class Scalar>
875 Thyra::defaultProductMultiVector(
876 const RCP<
const DefaultProductVectorSpace<Scalar> > &productSpace,
877 const ArrayView<
const RCP<
const MultiVectorBase<Scalar> > > &multiVecs
880 const RCP<DefaultProductMultiVector<Scalar> > pmv =
881 defaultProductMultiVector<Scalar>();
882 pmv->initialize(productSpace, multiVecs);
887 template<
class Scalar>
889 Thyra::castOrCreateSingleBlockProductMultiVector(
890 const RCP<
const DefaultProductVectorSpace<Scalar> > &productSpace,
891 const RCP<
const MultiVectorBase<Scalar> > &mv
894 const RCP<const ProductMultiVectorBase<Scalar> > pmv =
895 Teuchos::rcp_dynamic_cast<
const ProductMultiVectorBase<Scalar> >(mv);
898 return defaultProductMultiVector<Scalar>(productSpace, Teuchos::tuple(mv)());
902 template<
class Scalar>
904 Thyra::nonconstCastOrCreateSingleBlockProductMultiVector(
905 const RCP<
const DefaultProductVectorSpace<Scalar> > &productSpace,
906 const RCP<MultiVectorBase<Scalar> > &mv
909 const RCP<ProductMultiVectorBase<Scalar> > pmv =
910 Teuchos::rcp_dynamic_cast<ProductMultiVectorBase<Scalar> >(mv);
913 return defaultProductMultiVector<Scalar>(productSpace, Teuchos::tuple(mv)());
924 #define THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_INSTANT(SCALAR) \
926 template class DefaultProductMultiVector<SCALAR >; \
928 template RCP<DefaultProductMultiVector<SCALAR > > \
929 defaultProductMultiVector<SCALAR >(); \
932 template RCP<DefaultProductMultiVector<SCALAR > > \
933 defaultProductMultiVector( \
934 const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
935 const int numMembers \
939 template RCP<DefaultProductMultiVector<SCALAR > > \
940 defaultProductMultiVector( \
941 const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
942 const ArrayView<const RCP<MultiVectorBase<SCALAR > > > &multiVecs \
946 template RCP<DefaultProductMultiVector<SCALAR > > \
947 defaultProductMultiVector( \
948 const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
949 const ArrayView<const RCP<const MultiVectorBase<SCALAR > > > &multiVecs \
953 template RCP<const ProductMultiVectorBase<SCALAR > > \
954 castOrCreateSingleBlockProductMultiVector( \
955 const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
956 const RCP<const MultiVectorBase<SCALAR > > &mv \
960 template RCP<ProductMultiVectorBase<SCALAR > > \
961 nonconstCastOrCreateSingleBlockProductMultiVector( \
962 const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
963 const RCP<MultiVectorBase<SCALAR > > &mv \
967 #endif // THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_DEF_HPP
void initialize(int *argc, char ***argv)
Base interface for product multi-vectors.
#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...
virtual void updateImpl(Scalar alpha, const MultiVectorBase< Scalar > &mv)
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.
EOpTransp
Enumeration for determining how a linear operator is applied. `*.
bool opSupportedImpl(EOpTransp M_trans) const
virtual void releaseDetachedMultiVectorViewImpl(RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
basic_OSTab< char > OSTab
#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...
void acquireDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, 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.
basic_FancyOStream< char > FancyOStream
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Use the non-transposed operator.
RCP< VectorBase< Scalar > > nonconstColImpl(Ordinal j)
T_To & dyn_cast(T_From &from)
virtual void norms1Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
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 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 Teuchos::RCP< MultiVectorBase< Scalar > > getNonconstMultiVectorBlock(const int k)=0
Returns a non-persisting non-const view of the zero-based kth block multi-vector. ...
EOpTransp real_trans(EOpTransp transp)
Return NOTRANS or TRANS for real scalar valued operators and this also is used for determining struct...
virtual void dotsImpl(const MultiVectorBase< Scalar > &mv, const ArrayView< Scalar > &prods) const
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.
RCP< const VectorSpaceBase< Scalar > > range() const
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual void norms2Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
RCP< const MultiVectorBase< Scalar > > nonContigSubViewImpl(const ArrayView< const int > &cols) const
void releaseDetachedMultiVectorViewImpl(RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
RCP< MultiVectorBase< Scalar > > getNonconstMultiVectorBlock(const int k)
bool blockIsConst(const int k) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
void acquireNonconstDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
Interface for a collection of column vectors called a multi-vector.
RCP< MultiVectorBase< Scalar > > nonconstContigSubViewImpl(const Range1D &colRng)
Concrete implementation of a product multi-vector.
virtual void linearCombinationImpl(const ArrayView< const Scalar > &alpha, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &mv, const Scalar &beta)
virtual void assignMultiVecImpl(const MultiVectorBase< Scalar > &mv)
void update(Scalar alpha, const MultiVectorBase< Scalar > &mv)
virtual std::string description() const
RCP< MultiVectorBase< Scalar > > clone_mv() const
virtual void commitNonconstDetachedMultiVectorViewImpl(RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
virtual void normsInfImpl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
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
std::string description() const
void assign(Scalar alpha)
V = alpha.
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)
RCP< const VectorSpaceBase< Scalar > > domain() const
void commitNonconstDetachedMultiVectorViewImpl(RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
void initialize(const RCP< const DefaultProductVectorSpace< Scalar > > &productSpace, const int numMembers)
void uninitialize()
Uninitialize.
RCP< const MultiVectorBase< Scalar > > getMultiVectorBlock(const int k) const
void applyImpl(const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha, const Scalar beta) const
RCP< const ProductVectorSpaceBase< Scalar > > productSpace() const
virtual void assignImpl(Scalar alpha)
RCP< MultiVectorBase< Scalar > > nonconstNonContigSubViewImpl(const ArrayView< const int > &cols)
DefaultProductMultiVector()
Construct to uninitialized.
#define TEUCHOS_ASSERT(assertion_test)
virtual void acquireDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
RCP< const MultiVectorBase< Scalar > > contigSubViewImpl(const Range1D &colRng) const
virtual void scaleImpl(Scalar alpha)
RCP< const VectorBase< Scalar > > colImpl(Ordinal j) const
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.