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)