~CopyMultiVectorViewBack()
   {
     RTOpPack::ConstSubMultiVectorView<Scalar> smv;
     mv_->acquireDetachedView(Range1D(),Range1D(),&smv);
     RTOpPack::assign_entries<Scalar>( Teuchos::outArg(raw_mv_), smv );
     mv_->releaseDetachedView(&smv);
   }
inline
const DMatrixSlice DMatrixSlice::operator()(size_type i1, size_type i2, size_type j1
  , size_type j2) const
{
  return DMatrixSlice( const_cast<DMatrixSlice&>(*this), Range1D(i1,i2)
    , Range1D(j1,j2) );
}
Teuchos::RCP<MultiVectorBase<Scalar> >
VectorSpaceDefaultBase<Scalar>::createMembersView(
  const RTOpPack::SubMultiVectorView<Scalar> &raw_mv ) const
{
#ifdef TEUCHOS_DEBUG
  TEST_FOR_EXCEPT( raw_mv.subDim() != this->dim() );
#endif
  // Create a multi-vector
  RCP< MultiVectorBase<Scalar> > mv = this->createMembers(raw_mv.numSubCols());
  // Copy initial values in raw_mv into multi-vector
  RTOpPack::SubMultiVectorView<Scalar> smv;
  mv->acquireDetachedView(Range1D(),Range1D(),&smv);
  RTOpPack::assign_entries<Scalar>(
    Ptr<const RTOpPack::SubMultiVectorView<Scalar> >(Teuchos::outArg(smv)),
    raw_mv
    );
  mv->commitDetachedView(&smv);
  // Setup smart pointer to multi-vector to copy view back out just before multi-vector is destroyed
  Teuchos::set_extra_data(
    Teuchos::rcp(new CopyMultiVectorViewBack<Scalar>(&*mv,raw_mv)),
    "CopyMultiVectorViewBack",
    Teuchos::outArg(mv),
    Teuchos::PRE_DESTROY
    );
  return mv;
}
 ~CopyVectorViewBack()
   {
     RTOpPack::ConstSubVectorView<Scalar> sv;
     v_->acquireDetachedView(Range1D(),&sv);
     RTOpPack::assign_entries<Scalar>( Teuchos::outArg(raw_v_), sv );
     v_->releaseDetachedView(&sv);
   }
 /** \brief Construct an explicit non-mutable (const) view of a subset of elements.
  *
  * @param v [in] The vector that a view will be taken.  This object must be
  * maintained until <tt>*this</tt> is destroyed.
  *
  * @param rng [in] the range of element indices that the explicit view will
  * be taken.
  *
  * @param forceUnitStride [in] If <tt>true</tt> then the view will have unit
  * stride.
  *
  * Preconditions:<ul>
  *
  * <li>[<tt>rng.full_range()==false</tt>] <tt>rng.ubound() <
  * v.space()->dim()</tt>
  *
  * </ul>
  *
  * Postconditions:<ul>
  *
  * <li><tt>this->sv()</tt> returns the created view
  *
  * <li><tt>this->globalOffset()==rng.lbound()</tt>
  *
  * <li><tt>this->subDim()==rng.size()</tt>
  *
  * <li><tt>this->values()</tt> returns a pointer to a <tt>Scalar</tt> array
  *
  * <li><tt>this->stride()</tt> returns the stride between the elements
  * pointed it in <tt>this->values()</tt>
  *
  * <li>[<tt>forceUnitStride==true</tt>] <tt>this->stride()==1</tt>
  *
  * </ul>
  */
 ConstDetachedVectorView(
   const Teuchos::RCP<const VectorBase<Scalar> > &v
   ,const Range1D &rng = Range1D(), const bool forceUnitStride = false
   )
   {
     this->initialize(v,rng,forceUnitStride);
   }
Teuchos::RCP<VectorBase<Scalar> >
VectorSpaceDefaultBase<Scalar>::createMemberView(
  const RTOpPack::SubVectorView<Scalar> &raw_v ) const
{
#ifdef TEUCHOS_DEBUG
  TEST_FOR_EXCEPT( raw_v.subDim() != this->dim() );
#endif
  // Create a vector
  RCP<VectorBase<Scalar> > v = this->createMember();
  // Copy initial values in raw_v into vector
  RTOpPack::SubVectorView<Scalar> sv;
  v->acquireDetachedView(Range1D(),&sv);
  RTOpPack::assign_entries<Scalar>(
    Teuchos::ptr_implicit_cast<const RTOpPack::SubVectorView<Scalar> >(Teuchos::outArg(sv)),
    RTOpPack::ConstSubVectorView<Scalar>(raw_v) );
  v->commitDetachedView(&sv);
  // Setup smart pointer to vector to copy view back out just before vector is destroyed
  Teuchos::set_extra_data(
    Teuchos::rcp(new CopyVectorViewBack<Scalar>(&*v,raw_v)),
    "CopyVectorViewBack",
    Teuchos::outArg(v),
    Teuchos::PRE_DESTROY
    );
  return v;
}
Teuchos::RCP<const MultiVectorBase<Scalar> >
VectorSpaceDefaultBase<Scalar>::createMembersView(
  const RTOpPack::ConstSubMultiVectorView<Scalar> &raw_mv ) const
{
#ifdef TEUCHOS_DEBUG
  TEST_FOR_EXCEPT( raw_mv.subDim() != this->dim() );
#endif
  // Create a multi-vector
  RCP< MultiVectorBase<Scalar> > mv =
    this->createMembers(raw_mv.numSubCols());
  // Copy values in raw_mv into multi-vector
  RTOpPack::SubMultiVectorView<Scalar> smv;
  mv->acquireDetachedView(Range1D(),Range1D(),&smv);
  RTOpPack::assign_entries<Scalar>(
    Ptr<const RTOpPack::SubMultiVectorView<Scalar> >(Teuchos::outArg(smv)),
    raw_mv );
  mv->commitDetachedView(&smv);
  return mv;
}
VectorSpace::space_ptr_t VectorSpaceSubSpace::sub_space(const Range1D& rng_in) const
{
  namespace rcp = MemMngPack;
  if( full_space_.get() == NULL && rng_in == Range1D::Invalid )
    return Teuchos::rcp(this,false);
  validate_range(rng_in);
  const index_type dim         = this->dim();
  const Range1D    rng         = rng_in.full_range() ? Range1D(1,dim) : rng_in;
  if( rng.lbound() == 1 && rng.ubound() == dim )
    return space_ptr_t( this, false );
  const index_type this_offset = rng_.lbound() - 1;
  return Teuchos::rcp(
    new VectorSpaceSubSpace(
      full_space_
      ,Range1D( 
        this_offset  + rng.lbound()
        ,this_offset + rng.ubound() )
      ) );
}
Teuchos::RCP<const VectorBase<Scalar> >
VectorSpaceDefaultBase<Scalar>::createMemberView( const RTOpPack::ConstSubVectorView<Scalar> &raw_v ) const
{
#ifdef TEUCHOS_DEBUG
  TEST_FOR_EXCEPT( raw_v.subDim() != this->dim() );
#endif
  // Create a vector
  RCP<VectorBase<Scalar> > v = this->createMember();
  // Copy initial values in raw_v into vector
  RTOpPack::SubVectorView<Scalar> sv;
  v->acquireDetachedView(Range1D(),&sv);
  RTOpPack::assign_entries<Scalar>(
    Teuchos::ptr_implicit_cast<const RTOpPack::SubVectorView<Scalar> >(Teuchos::outArg(sv)),
    raw_v );
  v->commitDetachedView(&sv);
  return v;
}
void VectorSpaceSubSpace::initialize( const space_ptr_t& full_space, const Range1D& rng )
{
#ifdef TEUCHOS_DEBUG
  TEST_FOR_EXCEPTION(
    full_space.get() == NULL, std::invalid_argument
    ,"VectorSpaceSubSpace::initialize(...): Error!" );
#endif
  const index_type n = full_space->dim();
#ifdef TEUCHOS_DEBUG
  TEST_FOR_EXCEPTION(
    !rng.full_range() && rng.ubound() > n, std::out_of_range
    ,"VectorSpaceSubSpace::initialize(...): Error, "
    "rng = [" << rng.lbound() << "," << rng.ubound() << "] is not in the range "
    "[1,vec->dim()] = [1," << n << "]" );
#endif
  full_space_ = full_space;
  rng_ = rng.full_range() ? Range1D(1,n) : rng;
}
void SpmdMultiVectorSerializer<Scalar>::serialize(
  const MultiVectorBase<Scalar>& mv, std::ostream& out
  ) const
{
  Teuchos::RCP<const SpmdVectorSpaceBase<Scalar> >
    mpi_vec_spc
    = Teuchos::rcp_dynamic_cast<const SpmdVectorSpaceBase<Scalar> >(mv.range());
  std::ios::fmtflags fmt(out.flags());
  out.precision(std::numeric_limits<Scalar>::digits10+4);
  if( mpi_vec_spc.get() ) {
    // This is a mpi-based vector space so let's just write the local
    // multi-vector elements (row-by-row).
    const Ordinal
      localOffset = mpi_vec_spc->localOffset(),
      localSubDim = mpi_vec_spc->localSubDim();
    const Range1D localRng( localOffset, localOffset+localSubDim-1 );
    ConstDetachedMultiVectorView<Scalar> local_mv(mv,localRng,Range1D());
    out << localSubDim << " " << local_mv.numSubCols() << std::endl;
    if( binaryMode() ) {
      // Write column-wise for better cache performance
      for( Ordinal j = 0; j < local_mv.numSubCols(); ++j )
        out.write( reinterpret_cast<const char*>(&local_mv(0,j)), sizeof(Scalar)*localSubDim );
    }
    else {
      // Write row-wise for better readability
      for( Ordinal i = 0; i < localSubDim; ++i ) {
        out << " " << i;
        for( Ordinal j = 0; j < local_mv.numSubCols(); ++j ) {
          out << " " << local_mv(i,j);
        }
        out << std::endl;
      }
    }
  }
  else {
    //  This is a serial (or locally replicated) vector space so
    // just write all of the multi-vector elements here.
    TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Does not handle non-SPMD spaces yet" );
  }
  out.flags(fmt);
}
SparseVectorSlice<T_Element>
create_slice(const SparseVectorUtilityPack::SpVecIndexLookup<T_Element>& index_lookup
  , size_type size, Range1D rng)
{
  // Check preconditions
  if(rng.full_range()) {
    rng = Range1D(1,size);
  }
  else {
#ifdef TEUCHOS_DEBUG
    TEUCHOS_TEST_FOR_EXCEPT( !(  rng.ubound() <= size  ) );
#endif
  }

  // If there are no elements then any subregion will also not have any elements.
  if(!index_lookup.nz())
    return SparseVectorSlice<T_Element>(0, 0, 0, rng.ubound() - rng.lbound() + 1, true);

  // Create the slice (assumed sorted oviously).
  typedef SparseVectorUtilityPack::SpVecIndexLookup<T_Element> SpVecIndexLookup;
  index_lookup.validate_state();
  typename SpVecIndexLookup::poss_type
    lower_poss = index_lookup.find_poss(rng.lbound(), SpVecIndexLookup::LOWER_ELE),
    upper_poss = index_lookup.find_poss(rng.ubound(), SpVecIndexLookup::UPPER_ELE);
  if( lower_poss.poss == upper_poss.poss
    && (	lower_poss.rel == SpVecIndexLookup::AFTER_ELE
      ||	upper_poss.rel == SpVecIndexLookup::BEFORE_ELE )
    )
  {
    // The requested subvector does not contain any elements.
    return SparseVectorSlice<T_Element>(0, 0, 0, rng.ubound() - rng.lbound() + 1, true);
  }
  else {
    // There are nonzero elements
    return SparseVectorSlice<T_Element>(index_lookup.ele() + lower_poss.poss
      , upper_poss.poss - lower_poss.poss + 1, index_lookup.offset() - rng.lbound() + 1
      , rng.ubound() - rng.lbound() + 1, true);
  }
}
VectorMutable::vec_mut_ptr_t
VectorMutable::sub_view( const Range1D& rng_in )
{
  namespace rcp = MemMngPack;
  const index_type dim = this->dim();
  const Range1D    rng = rng_in.full_range() ? Range1D(1,dim) : rng_in;
#ifdef TEUCHOS_DEBUG
  TEST_FOR_EXCEPTION(
    rng.ubound() > dim, std::out_of_range
    ,"VectorMutable::sub_view(rng): Error, rng = ["<<rng.lbound()<<","<<rng.ubound()<<"] "
    "is not in the range [1,this->dim()] = [1,"<<dim<<"]" );
#endif	
  if( rng.lbound() == 1 && rng.ubound() == dim )
    return Teuchos::rcp( this, false );
  // We are returning a view that could change this vector so we had better
  // wipe out the cache
  //this->has_changed();  // I don't think this line is needed!
  return Teuchos::rcp(
    new VectorMutableSubView(
      Teuchos::rcp( this, false )
      ,rng ) );
}
Range1D BasisSystem::equ_decomp() const
{
  const size_type r = this->var_dep().size();
  return r ? Range1D(1,r) : Range1D::Invalid;
}
Example #15
0
Range1D RTOpT<Scalar>::range_impl() const
{
  return Range1D();
}
void SpmdMultiVectorSerializer<Scalar>::deserialize(
  std::istream& in, MultiVectorBase<Scalar>* mv
  ) const
{
  Teuchos::RCP<const SpmdVectorSpaceBase<Scalar> >
    mpi_vec_spc = Teuchos::rcp_dynamic_cast<const SpmdVectorSpaceBase<Scalar> >(mv->range());
  if( mpi_vec_spc.get() ) {
    // This is a mpi-based vector space so let's just read the local
    // multi-vector elements (row-by-row).
    const Ordinal
      localOffset = mpi_vec_spc->localOffset(),
      localSubDim = mpi_vec_spc->localSubDim();
    const Range1D localRng( localOffset, localOffset+localSubDim-1 );
    DetachedMultiVectorView<Scalar> local_mv(*mv,localRng,Range1D());
#ifdef TEUCHOS_DEBUG
    TEUCHOS_TEST_FOR_EXCEPTION(
      !in, std::logic_error
      ,"Error: The input stream given is empty before any reading has began!\n"
      "If this stream came from a file, then the file may not exist!"
      );
#endif
    Ordinal localSubDim_in;
    in >> localSubDim_in;
#ifdef TEUCHOS_DEBUG
    TEUCHOS_TEST_FOR_EXCEPTION(
      localSubDim != localSubDim_in, std::logic_error
      , "Error, localSubDim = "<<localSubDim<<" does not match the read in value of "
      "localSubDim_in = "<<localSubDim_in<<"!"
      );
#endif
    Ordinal numSubCols_in;
    in >> numSubCols_in;
#ifdef TEUCHOS_DEBUG
    TEUCHOS_TEST_FOR_EXCEPTION(
      local_mv.numSubCols() != numSubCols_in, std::logic_error
      , "Error, numSubCols = "<<local_mv.numSubCols()<<" does not match the read in value of "
      "numSubCols_in = "<<numSubCols_in<<"!"
      );
#endif
    // Get rid of extra newline after first line
    in >> std::ws;
    // Get the elements
    if( binaryMode() ) {
      // Column-wise
      for( Ordinal j = 0; j < local_mv.numSubCols(); ++j )
        in.read( reinterpret_cast<char*>(&local_mv(0,j)), sizeof(Scalar)*localSubDim );
    }
    else {
      // Row-wise
      for( Ordinal i = 0; i < localSubDim; ++i ) {
#ifdef TEUCHOS_DEBUG
        TEUCHOS_TEST_FOR_EXCEPTION( !in, std::logic_error, "Error, premature end of input!"	);
#endif
        Ordinal i_in;
        in >> i_in;
#ifdef TEUCHOS_DEBUG
        TEUCHOS_TEST_FOR_EXCEPTION(
          i != i_in, std::logic_error
          , "Error, i = "<<i<<" does not match the read in value of "
          "i_in = "<<i_in<<"!"
          );
#endif
        for( Ordinal j = 0; j < local_mv.numSubCols(); ++j ) {
#ifdef TEUCHOS_DEBUG
          TEUCHOS_TEST_FOR_EXCEPTION(
            !in, std::logic_error
            ,"Error: The input stream ran out at j="<<j<<" before"
            " reaching the promised " << local_mv.numSubCols()
            << " rows of the (multi)vector!"
            );
#endif
          in >> local_mv(i,j);
        }
      }
    }
  }
  else {
inline
DMatrixSlice DMatrixSlice::operator()(size_type i1, size_type i2, size_type j1
  , size_type j2)
{
  return DMatrixSlice(*this, Range1D(i1,i2), Range1D(j1,j2));
}
 /** \brief Construct an explicit mutable (non-const) view of a subset of elements.
  *
  * @param v [in] The vector that a view will be taken.  This object must be
  * maintained until <tt>*this</tt> is destroyed.  The elements in <tt>v</tt>
  * are not guaranteed to be updated until <tt>*this</tt> is destroyed.
  *
  * @param rng [in] the range of element indices that the explicit view will
  * be taken.
  *
  * @param forceUnitStride [in] If <tt>true</tt> then the view will have unit
  * stride.
  *
  * Preconditions:<ul>
  * <li>[<tt>rng.full_range()==false</tt>] <tt>rng.ubound() < v.space()->dim()</tt>
  * </ul>
  *
  * Postconditions:<ul>
  *
  * <li><tt>this->sv()</tt> returns the created view
  *
  * <li><tt>this->globalOffset()==rng.lbound()</tt>
  *
  * <li><tt>this->subDim()==rng.size()</tt>
  *
  * <li><tt>this->values()</tt> returns a pointer to a <tt>Scalar</tt> array
  *
  * <li><tt>this->stride()</tt> returns the stride between the elements
  * pointed it in <tt>this->values()</tt>
  *
  * <li>[<tt>forceUnitStride==true</tt>] <tt>this->stride()==1</tt>
  *
  * </ul>
  */
 DetachedVectorView( VectorBase<Scalar>& v, const Range1D &rng = Range1D(), const bool forceUnitStride = false )
   {
     this->initialize(Teuchos::rcp(&v,false),rng,forceUnitStride);
   }
 /** \brief . */
 DetachedMultiVectorView(
   MultiVectorBase<Scalar>& mv, const Range1D &rowRng = Range1D(), const Range1D &colRng = Range1D()
   )
   : mv_(mv) { mv_.acquireDetachedView(rowRng,colRng,&smv_); }