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 ); }
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 ) ); }
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); }