void DefaultProductVector<Scalar>::acquireNonconstDetachedVectorViewImpl(
  const Range1D& rng_in, RTOpPack::SubVectorView<Scalar>* sub_vec
  )
{
  const Range1D
    rng = rng_in.full_range() ? Range1D(0,productSpace_->dim()-1) : rng_in;
  int    kth_vector_space  = -1;
  Ordinal  kth_global_offset = 0;
  productSpace_->getVecSpcPoss(rng.lbound(),&kth_vector_space,&kth_global_offset);
#ifdef TEUCHOS_DEBUG
  TEST_FOR_EXCEPT( !( 0 <= kth_vector_space && kth_vector_space <= numBlocks_ ) );
#endif
  if(
    rng.lbound() + rng.size()
    <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim()
    )
  {
    // This involves only one sub-vector so just return it.
    vecs_[kth_vector_space].getConstObj()->acquireDetachedView(
      rng - kth_global_offset, sub_vec
      );
    sub_vec->setGlobalOffset( sub_vec->globalOffset() + kth_global_offset );
  }
  else {
    // Just let the default implementation handle this.  ToDo: In the future
    // we could manually construct an explicit sub-vector that spanned
    // two or more constituent vectors but this would be a lot of work.
    // However, this would require the use of temporary memory but
    // so what.
    VectorDefaultBase<Scalar>::acquireNonconstDetachedVectorViewImpl(rng_in,sub_vec);
  }
}
VectorSpace::space_ptr_t
VectorSpaceBlocked::sub_space(const Range1D& rng_in) const
{
  namespace rcp = MemMngPack;
  const index_type dim = this->dim();
  const Range1D    rng = rng_in.full_range() ? Range1D(1,dim) : rng_in;
  // Validate the preconditions
#ifdef TEUCHOS_DEBUG
  TEST_FOR_EXCEPTION(
    dim < rng.ubound(), std::out_of_range
    ,"VectorSpaceBlocked::sub_space(...): Error, rng = "
    << "["<<rng.lbound()<<","<<rng.ubound()<<"] is not in range [1,"<<dim<<"]" );
#endif
  if( rng.lbound() == 1 && rng.ubound() == dim )
    return space_ptr_t( this, false ); // Client selected the whole composite vector space.
  // Get the position of the vector space object of interest
  int           kth_vector_space  = -1;
  index_type    kth_global_offset = 0;
  this->get_vector_space_position(rng.lbound(),&kth_vector_space,&kth_global_offset);
  const vector_spaces_t      &vector_spaces      = vector_spaces_;      // Need to examine in debugger!
  const vec_spaces_offsets_t &vec_spaces_offsets = vec_spaces_offsets_;
#ifdef TEUCHOS_DEBUG
  TEST_FOR_EXCEPT( !(  0 <= kth_vector_space && kth_vector_space <= vector_spaces.size()  ) );
#endif
  if( rng.lbound() == kth_global_offset + 1
    && rng.size() == vec_spaces_offsets[kth_vector_space+1] - vec_spaces_offsets[kth_vector_space] )
    // The client selected a whole single constituent vector space.
    return vector_spaces[kth_vector_space];
  if( rng.ubound() <= vec_spaces_offsets[kth_vector_space+1] )
    // The client selected a sub-space of a single consituent vector space
    return vector_spaces[kth_vector_space]->sub_space(rng-vec_spaces_offsets[kth_vector_space]);
  // The client selected a sub-space that spans two or more constituent vector spaces
  // Get the position of the vector space object with the last element of interest
  int           end_kth_vector_space  = -1;
  index_type    end_kth_global_offset = 0;
  this->get_vector_space_position(rng.ubound(),&end_kth_vector_space,&end_kth_global_offset);
#ifdef TEUCHOS_DEBUG
  TEST_FOR_EXCEPT( !(  0 <= end_kth_vector_space && end_kth_vector_space <= vector_spaces.size()  ) );
  TEST_FOR_EXCEPT( !(  end_kth_vector_space > kth_vector_space  ) );
#endif
  // Create a VectorSpaceComposite object containing the relavant constituent vector spaces
  Teuchos::RCP<VectorSpaceBlocked>
    vec_space_comp = Teuchos::rcp(
      new VectorSpaceBlocked(
        &vector_spaces[kth_vector_space]
        ,end_kth_vector_space - kth_vector_space + 1 )
      );
  if( rng.lbound() == kth_global_offset + 1
    && rng.size() == vec_spaces_offsets[end_kth_vector_space+1] - vec_spaces_offsets[kth_vector_space] )
    // The client selected exactly a contigous set of vector spaces
    return vec_space_comp;
  // The client selected some sub-set of elements in the contigous set of vector spaces
  return Teuchos::rcp(
    new VectorSpaceSubSpace(
      vec_space_comp
      ,Range1D( 
        rng.lbound()-vec_spaces_offsets[kth_vector_space]
        ,rng.ubound()-vec_spaces_offsets[kth_vector_space] )
      ) );
}
void MultiVectorDefaultBase<Scalar>::acquireDetachedMultiVectorViewImpl(
  const Range1D &rowRng_in,
  const Range1D &colRng_in,
  RTOpPack::ConstSubMultiVectorView<Scalar> *sub_mv
  ) const
{
  const Ordinal
    rangeDim = this->range()->dim(),
    domainDim = this->domain()->dim();
  const Range1D
    rowRng = rowRng_in.full_range() ? Range1D(0,rangeDim-1) : rowRng_in,
    colRng = colRng_in.full_range() ? Range1D(0,domainDim-1) : colRng_in;
#ifdef TEUCHOS_DEBUG
  TEUCHOS_TEST_FOR_EXCEPTION(
    !(rowRng.ubound() < rangeDim), std::out_of_range
    ,"MultiVectorDefaultBase<Scalar>::acquireDetachedMultiVectorViewImpl(...): Error, rowRng = ["
    <<rowRng.lbound()<<","<<rowRng.ubound()<<"] is not in the range = [0,"
    <<(rangeDim-1)<<"]!"
    );
  TEUCHOS_TEST_FOR_EXCEPTION(
    !(colRng.ubound() < domainDim), std::out_of_range
    ,"MultiVectorDefaultBase<Scalar>::acquireDetachedMultiVectorViewImpl(...): Error, colRng = ["
    <<colRng.lbound()<<","<<colRng.ubound()<<"] is not in the range = [0,"
    <<(domainDim-1)<<"]!"
    );
#endif
  // Allocate storage for the multi-vector (stored column-major)
  const ArrayRCP<Scalar> values = Teuchos::arcp<Scalar>(rowRng.size() * colRng.size());
  // Extract multi-vector values column by column
  RTOpPack::ConstSubVectorView<Scalar> sv; // uninitialized by default
  for( int k = colRng.lbound(); k <= colRng.ubound(); ++k ) {
    RCP<const VectorBase<Scalar> > col_k = this->col(k);
    col_k->acquireDetachedView( rowRng, &sv );
    for( int i = 0; i < rowRng.size(); ++i )
      values[ i + k*rowRng.size() ] = sv[i];
    col_k->releaseDetachedView( &sv );
  }
  // Initialize the multi-vector view object
  sub_mv->initialize(
    rowRng.lbound(), // globalOffset
    rowRng.size(), // subDim
    colRng.lbound(), // colOffset
    colRng.size(), // numSubCols
    values, // values
    rowRng.size() // leadingDim
    );
}
Ejemplo n.º 4
0
inline
void VectorDefaultBase<Scalar>::validateColRng( const Range1D &col_rng ) const
{
#ifdef TEUCHOS_DEBUG
  TEUCHOS_TEST_FOR_EXCEPT(
    !( col_rng.full_range() || ( col_rng.lbound() == 0 && col_rng.ubound() == 0) ) );
#endif
}
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 VectorSpaceSubSpace::validate_range(const Range1D& rng) const
{
  const index_type n = this->dim();
  TEST_FOR_EXCEPTION(
    full_space_.get() == NULL, std::logic_error
    ,"VectorSpaceSubSpace::validate_range(rng): Error, Uninitialized" );
  TEST_FOR_EXCEPTION(
    full_space_.get() && !rng.full_range() && rng.ubound() > n, std::logic_error
    ,"VectorSpaceSubSpace::validate_range(rng): Error, "
    "rng = [" << rng.lbound() << "," << rng.ubound() << "] is not in the range "
    "[1,this->dim] = [1," << n << "]" );
}
MultiVectorMutable::multi_vec_mut_ptr_t
MultiVectorMutableCols::mv_sub_view(const Range1D& row_rng, const Range1D& col_rng)
{
#ifdef TEUCHOS_DEBUG
  const size_type rows = this->rows();
  TEST_FOR_EXCEPTION(
    !( row_rng.full_range() || (row_rng.lbound() == 1 && row_rng.ubound() == rows) )
    ,std::logic_error, "Error, can't handle subrange on vectors yet!" );
#endif
  return Teuchos::rcp(
    new MultiVectorMutableCols(
      space_cols_,space_rows_->sub_space(col_rng),&col_vecs_[col_rng.lbound()-1]
      ) );
}
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() )
      ) );
}
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 ) );
}
Ejemplo n.º 11
0
void VectorDefaultBase<Scalar>::acquireDetachedVectorViewImpl(
  const Range1D& rng_in, RTOpPack::ConstSubVectorView<Scalar>* sub_vec_inout
  ) const
{
  using Teuchos::dyn_cast;
  const Range1D rng = rng_in.full_range() ? Range1D(0,this->space()->dim()-1) : rng_in;
#ifdef TEUCHOS_DEBUG
  TEUCHOS_TEST_FOR_EXCEPTION(
    !(rng.ubound() < this->space()->dim()), std::out_of_range
    ,"VectorDefaultBase<Scalar>::acquireDetachedVectorViewImpl(rng,...):"
    " Error, rng = ["<<rng.lbound()<<","<<rng.ubound()
    <<"] is not in range = [0,"<<(this->space()->dim()-1)<<"]" );
#endif
  // Initialize the operator
  RTOpPack::ROpGetSubVector<Scalar> get_sub_vector_op(rng.lbound(),rng.ubound());
  // Create the reduction object (another sub_vec)
  RCP<RTOpPack::ReductTarget>
    reduct_obj = get_sub_vector_op.reduct_obj_create(); // This is really of type RTOpPack::ConstSubVectorView<Scalar>!
  // Perform the reduction (get the sub-vector requested)
  ::Thyra::applyOp<Scalar>(get_sub_vector_op, tuple(Teuchos::ptr<const VectorBase<Scalar> >(this))(),
    Teuchos::null, reduct_obj.ptr());
  // Get the sub-vector.
  *sub_vec_inout = get_sub_vector_op(*reduct_obj);
}