45 #include "AbstractLinAlgPack_VectorMutableBlocked.hpp"
46 #include "AbstractLinAlgPack_VectorMutableSubView.hpp"
47 #include "AbstractLinAlgPack_VectorSpaceBlocked.hpp"
48 #include "Teuchos_Workspace.hpp"
49 #include "Teuchos_Assert.hpp"
50 #include "Teuchos_FancyOStream.hpp"
58 T my_max(
const T& v1,
const T& v2 ) {
return v1 > v2 ? v1 : v2; }
61 T my_min(
const T& v1,
const T& v2 ) {
return v1 < v2 ? v1 : v2; }
64 namespace AbstractLinAlgPack {
66 VectorMutableBlocked::VectorMutableBlocked(
81 vec_space.
get() == NULL, std::logic_error
82 ,
"VectorMutableBlocked::initialize(...): Error, Must be constructed from "
83 "a non-null block vector space!" );
84 const int num_vec_spaces = vec_space->num_vector_spaces();
85 vecs_.resize(num_vec_spaces);
86 std::copy(vecs,vecs+num_vec_spaces,vecs_.begin());
87 vec_space_ = vec_space;
95 return vec_space_->dim();
104 const RTOpPack::RTOp& op
105 ,
const size_t num_vecs,
const Vector* vecs[]
108 ,
const index_type first_ele_in,
const index_type sub_dim_in,
const index_type global_offset_in
120 !(1 <= first_ele_in && first_ele_in <= n), std::out_of_range
121 ,
"VectorMutableBlocked::apply_op(...): Error, "
122 "first_ele_in = " << first_ele_in <<
" is not in range [1,"<<n<<
"]" );
124 sub_dim_in < 0, std::invalid_argument
125 ,
"VectorMutableBlocked::apply_op(...): Error, "
126 "sub_dim_in = " << sub_dim_in <<
" is not acceptable" );
128 global_offset_in < 0, std::invalid_argument
129 ,
"VectorMutableBlocked::apply_op(...): Error, "
130 "global_offset_in = " << global_offset_in <<
" is not acceptable" );
132 sub_dim_in > 0 && sub_dim_in - (first_ele_in - 1) > n, std::length_error
133 ,
"VectorMutableBlocked::apply_op(...): Error, "
134 "global_offset_in = " << global_offset_in <<
", sub_dim_in = " << sub_dim_in
135 <<
"first_ele_in = " << first_ele_in <<
" and n = " << n
136 <<
" are not compatible" );
138 {
for(
int k = 0; k < num_vecs; ++k) {
142 ,
"VectorMutableBlocked::apply_op(...): Error vecs["<<k<<
"]->space() "
143 <<
"of type \'"<<
typeName(vecs[k]->
space())<<
"\' is not compatible with this "
144 <<
"\'VectorSpaceBlocked\' vector space!"
147 {
for(
int k = 0; k < num_targ_vecs; ++k) {
151 ,
"VectorMutableBlocked::apply_op(...): Error targ_vecs["<<k<<
"]->space() "
152 <<
"of type \'"<<
typeName(vecs[k]->
space())<<
"\' is not compatible with this "
153 <<
"\'VectorSpaceBlocked\' vector space!"
159 Workspace<const VectorMutableBlocked*>
160 vecs_args(wss,num_vecs);
161 {
for(
int k = 0; k < num_vecs; ++k) {
166 ,
"VectorMutableBlocked::apply_op(...): Error vecs["<<k<<
"] "
167 <<
"of type \'"<<
typeName(*vecs[k])<<
"\' does not support the "
168 <<
"\'VectorMutableBlocked\' interface!"
172 Workspace<VectorMutableBlocked*>
173 targ_vecs_args(wss,num_targ_vecs);
174 {
for(
int k = 0; k < num_targ_vecs; ++k) {
179 ,
"VectorMutableBlocked::apply_op(...): Error targ_vecs["<<k<<
"] "
180 <<
"of type \'"<<
typeName(*targ_vecs[k])<<
"\' does not support the "
181 <<
"\'VectorMutableBlocked\' interface!"
188 const index_type this_dim = this->
dim();
189 const index_type sub_dim = ( sub_dim_in == 0
190 ? this_dim - (first_ele_in - 1)
192 index_type num_elements_remaining = sub_dim;
193 const int num_vec_spaces = vec_space_->num_vector_spaces();
194 Workspace<const Vector*>
195 sub_vecs(wss,num_vecs);
196 Workspace<VectorMutable*>
197 sub_targ_vecs(wss,num_targ_vecs);
198 index_type g_off = -first_ele_in + 1;
199 for(
int k = 0; k < num_vec_spaces; ++k) {
200 const index_type local_dim = vecs_[k]->dim();
201 if( g_off < 0 && -g_off > local_dim ) {
206 local_sub_dim = ( g_off >= 0
207 ? my_min( local_dim, num_elements_remaining )
208 : my_min( local_dim + g_off, num_elements_remaining ) );
209 if( local_sub_dim <= 0 )
211 for(
int i = 0; i < num_vecs; ++i )
212 sub_vecs[i] = vecs_args[i]->vecs_[k].
get();
213 for(
int j = 0; j < num_targ_vecs; ++j )
214 sub_targ_vecs[j] = targ_vecs_args[j]->vecs_[k].
get();
215 AbstractLinAlgPack::apply_op(
217 ,num_vecs,num_vecs?&sub_vecs[0]:NULL
218 ,num_targ_vecs,num_targ_vecs?&sub_targ_vecs[0]:NULL
220 ,g_off < 0 ? -g_off + 1 : 1
222 ,g_off < 0 ? global_offset_in : global_offset_in + g_off
225 num_elements_remaining -= local_sub_dim;
229 {
for(
int k = 0; k < num_targ_vecs; ++k) {
237 const int num_vec_spaces = vec_space_->num_vector_spaces();
239 for(
int k = 0; k < num_vec_spaces; ++k )
240 nz_ += vecs_[k]->
nz();
246 std::ostream& out_arg,
bool print_dim,
bool newline
247 ,index_type global_offset
253 *out << this->
dim() << std::endl;
254 size_type off = global_offset;
255 const int num_vec_spaces = vec_space_->num_vector_spaces();
256 for(
int k = 0; k < num_vec_spaces; ++k ) {
257 vecs_[k]->output(*out,
false,
false,off);
258 off += vecs_[k]->dim();
267 int kth_vector_space = -1;
268 index_type kth_global_offset = 0;
269 vec_space_->get_vector_space_position(i,&kth_vector_space,&kth_global_offset);
273 return vecs_[kth_vector_space]->get_ele( i - kth_global_offset );
278 #ifdef ALAP_VECTOR_MUTABLE_BLOCKED_IGNORE_CACHE_DATA
281 if( norm_1_ < 0.0 ) {
283 const int num_vec_spaces = vec_space_->num_vector_spaces();
285 for(
int k = 0; k < num_vec_spaces; ++k )
286 norm_1_ += vecs_[k]->
norm_1();
293 #ifdef ALAP_VECTOR_MUTABLE_BLOCKED_IGNORE_CACHE_DATA
296 if( norm_inf_ < 0.0 ) {
298 const int num_vec_spaces = vec_space_->num_vector_spaces();
300 for(
int k = 0; k < num_vec_spaces; ++k )
301 norm_inf_ = my_max( norm_inf_, vecs_[k]->
norm_inf() );
315 int kth_vector_space = -1;
316 index_type kth_global_offset = 0;
317 vec_space_->get_vector_space_position(rng.
lbound(),&kth_vector_space,&kth_global_offset);
321 if( rng.
lbound() + rng.
size() <= kth_global_offset + 1 + vecs_[kth_vector_space]->dim() ) {
324 rng - kth_global_offset, sub_vec );
325 sub_vec->setGlobalOffset( sub_vec->globalOffset() + kth_global_offset );
339 if( sub_vec->values() == NULL )
return;
340 int kth_vector_space = -1;
341 index_type kth_global_offset = 0;
342 vec_space_->get_vector_space_position(
343 sub_vec->globalOffset()+1,&kth_vector_space,&kth_global_offset);
347 if( sub_vec->globalOffset() + sub_vec->subDim() <= kth_global_offset + vecs_[kth_vector_space]->dim() ) {
349 sub_vec->setGlobalOffset( sub_vec->globalOffset() - kth_global_offset );
350 vecs_[kth_vector_space].get()->free_sub_vector(sub_vec);
361 norm_1_ = norm_inf_ = -1.0;
370 namespace rcp = MemMngPack;
371 const index_type
dim = this->
dim();
376 dim < rng.
ubound(), std::out_of_range
377 ,
"VectorMutableBlocked::sub_view(...): Error, rng = "
378 <<
"["<<rng.
lbound()<<
","<<rng.
ubound()<<
"] is not in range [1,"<<dim<<
"]" );
380 vecs_t &vecs = this->vecs_;
391 int kth_vector_space = -1;
392 index_type kth_global_offset = 0;
393 vec_space_->get_vector_space_position(rng.
lbound(),&kth_vector_space,&kth_global_offset);
395 const index_type* vec_spaces_offsets = vec_space_->vector_spaces_offsets();
399 if( rng.
lbound() == kth_global_offset + 1
400 && rng.
size() == vec_spaces_offsets[kth_vector_space+1] - vec_spaces_offsets[kth_vector_space] )
403 if( rng.
ubound() <= vec_spaces_offsets[kth_vector_space+1] )
405 return vecs[kth_vector_space]->
sub_view( rng - vec_spaces_offsets[kth_vector_space] );
408 int end_kth_vector_space = -1;
409 index_type end_kth_global_offset = 0;
410 vec_space_->get_vector_space_position(rng.
ubound(),&end_kth_vector_space,&end_kth_global_offset);
418 &vecs[kth_vector_space]
420 &vector_spaces[kth_vector_space]
421 ,end_kth_vector_space - kth_vector_space + 1 ))
423 if( rng.
lbound() == kth_global_offset + 1
424 && rng.
size() == vec_spaces_offsets[end_kth_vector_space+1] - vec_spaces_offsets[kth_vector_space] )
432 rng.
lbound()-vec_spaces_offsets[kth_vector_space]
433 ,rng.
ubound()-vec_spaces_offsets[kth_vector_space] )
445 const int num_vec_spaces = vec_space_->num_vector_spaces();
446 for(
int k = 0; k < num_vec_spaces; ++k )
461 int kth_vector_space = -1;
462 index_type kth_global_offset = 0;
463 vec_space_->get_vector_space_position(i,&kth_vector_space,&kth_global_offset);
467 vecs_[kth_vector_space]->set_ele( i - kth_global_offset, val );
473 int kth_vector_space = -1;
474 index_type kth_global_offset = 0;
475 vec_space_->get_vector_space_position(
476 sub_vec.globalOffset()+1,&kth_vector_space,&kth_global_offset);
480 if( sub_vec.globalOffset() + sub_vec.subDim() <= kth_global_offset + vecs_[kth_vector_space]->dim() ) {
482 RTOpPack::SparseSubVector sub_vec_g = sub_vec;
483 sub_vec_g.setGlobalOffset( sub_vec_g.globalOffset() - kth_global_offset );
484 vecs_[kth_vector_space]->set_sub_vector(sub_vec_g);
495 void VectorMutableBlocked::assert_in_range(
int k)
const
497 assert_initialized();
499 k >= vec_space_->num_vector_spaces(), std::logic_error
500 ,
"VectorMutableBlocked::assert_in_range(k) : Error, k = " << k <<
" is not "
501 "in range [0," << vec_space_->num_vector_spaces() <<
"]" );
504 void VectorMutableBlocked::assert_initialized()
const
void free_sub_vector(RTOpPack::SubVector *sub_vec) const
VectorMutable & operator=(value_type)
virtual void set_sub_vector(const RTOpPack::SparseSubVector &sub_vec)
Set a specific sub-vector.
virtual void get_sub_vector(const Range1D &rng, RTOpPack::SubVector *sub_vec) const
Get a non-mutable explicit view of a sub-vector.
void set_sub_vector(const RTOpPack::SparseSubVector &sub_vec)
Abstract interface for immutable, finite dimensional, coordinate vectors {abstract}.
void axpy(value_type alpha, const Vector &x)
value_type norm_1() const
value_type inner_product(const Vector &) const
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
vec_mut_ptr_t sub_view(const Range1D &rng)
Concrete subclass for a blocked vector.
value_type get_ele(index_type i) const
void apply_op(const RTOpPack::RTOp &op, const size_t num_vecs, const Vector *vecs[], const size_t num_targ_vecs, VectorMutable *targ_vecs[], RTOpPack::ReductTarget *reduct_obj, const index_type first_ele, const index_type sub_dim, const index_type global_offset) const
void get_sub_vector(const Range1D &rng, RTOpPack::SubVector *sub_vec) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual void has_changed() const
Must be called by any vector subclass that modifies this vector object!
Abstract interface for objects that represent a space for mutable coordinate vectors.
void set_ele(index_type i, value_type val)
VectorSpace subclass for the composite of one or more VectorSpace objects.
virtual void axpy(value_type alpha, const Vector &x)
Adds a linear combination of another vector to this vector object.
Concrete subclass for a sub-view of a VectorMutable object.
virtual void free_sub_vector(RTOpPack::SubVector *sub_vec) const
Free an explicit view of a sub-vector.
virtual bool is_compatible(const VectorSpace &vec_spc) const =0
Compare the compatibility of two vector spaces.
virtual VectorMutable & operator=(value_type alpha)
Assign the elements of this vector to a scalar.
std::ostream & output(std::ostream &out, bool print_dim, bool newline, index_type global_offset) const
Thrown if vector spaces are incompatible.
Abstract interface for mutable coordinate vectors {abstract}.
const VectorSpace & space() const
void initialize(VectorMutable::vec_mut_ptr_t *vecs, const vec_space_comp_ptr_t &vec_space)
Initialize given a list of constituent vectors.
virtual value_type inner_product(const Vector &v) const
Return the inner product of *this with v.
value_type norm_inf() const
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
TEUCHOSCORE_LIB_DLL_EXPORT Teuchos::RCP< WorkspaceStore > get_default_workspace_store()
std::string typeName(const T &t)