00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef RTOPPACK_ROP_GET_SUB_VECTOR_HPP
00031 #define RTOPPACK_ROP_GET_SUB_VECTOR_HPP
00032
00033 #include "RTOpPack_RTOpTHelpers.hpp"
00034
00035 namespace RTOpPack {
00036
00038 template<class Scalar> class ReductTargetSubVectorT;
00039
00045 template<class Scalar>
00046 class ROpGetSubVector : public RTOpT<Scalar> {
00047 public:
00048
00050 typedef typename RTOpT<Scalar>::primitive_value_type primitive_value_type;
00051
00053 ROpGetSubVector( const index_type l = 0, const index_type u = 0 );
00054
00056 void set_range( const index_type l, const index_type u );
00057
00059 ReductTargetSubVectorT<Scalar>& operator()( ReductTarget& reduct_obj ) const;
00060
00062 const ReductTargetSubVectorT<Scalar>& operator()( const ReductTarget& reduct_obj ) const;
00063
00066
00068 void get_reduct_type_num_entries(
00069 int* num_values
00070 ,int* num_indexes
00071 ,int* num_chars
00072 ) const;
00074 Teuchos::RefCountPtr<ReductTarget> reduct_obj_create() const;
00076 void reduce_reduct_objs(
00077 const ReductTarget& _in_reduct_obj, ReductTarget* _inout_reduct_obj
00078 ) const;
00080 void reduct_obj_reinit( ReductTarget* reduct_obj ) const;
00082 void extract_reduct_obj_state(
00083 const ReductTarget &reduct_obj
00084 ,int num_values
00085 ,primitive_value_type value_data[]
00086 ,int num_indexes
00087 ,Teuchos_Index index_data[]
00088 ,int num_chars
00089 ,::RTOpPack::char_type char_data[]
00090 ) const;
00092 void load_reduct_obj_state(
00093 int num_values
00094 ,const primitive_value_type value_data[]
00095 ,int num_indexes
00096 ,const Teuchos_Index index_data[]
00097 ,int num_chars
00098 ,const ::RTOpPack::char_type char_data[]
00099 ,ReductTarget *reduct_obj
00100 ) const;
00102 void get_op_type_num_entries(
00103 int* num_values
00104 ,int* num_indexes
00105 ,int* num_chars
00106 ) const;
00108 void extract_op_state(
00109 int num_values
00110 ,primitive_value_type value_data[]
00111 ,int num_indexes
00112 ,Teuchos_Index index_data[]
00113 ,int num_chars
00114 ,::RTOpPack::char_type char_data[]
00115 ) const;
00117 void load_op_state(
00118 int num_values
00119 ,const primitive_value_type value_data[]
00120 ,int num_indexes
00121 ,const Teuchos_Index index_data[]
00122 ,int num_chars
00123 ,const ::RTOpPack::char_type char_data[]
00124 );
00126 bool coord_invariant() const;
00128 void apply_op(
00129 const int num_vecs, const ConstSubVectorView<Scalar> sub_vecs[]
00130 ,const int num_targ_vecs, const SubVectorView<Scalar> targ_sub_vecs[]
00131 ,ReductTarget *reduct_obj
00132 ) const;
00133
00135
00136 private:
00137
00138 index_type l_;
00139 index_type u_;
00140
00141 };
00142
00144 template<class Scalar>
00145 class ReductTargetSubVectorT : public ReductTarget {
00146 public:
00148 ReductTargetSubVectorT( const index_type l, const index_type u)
00149 {
00150 Scalar *values = NULL;
00151 try {
00152 const int subDim = u-l+1;
00153 sub_vec.initialize(
00154 l
00155 ,subDim
00156 ,new Scalar[subDim]
00157 ,1
00158 );
00159 reinit();
00160 }
00161 catch(...) {
00162 delete [] values;
00163 }
00164 }
00166 ~ReductTargetSubVectorT()
00167 {
00168 free(&sub_vec);
00169 }
00171 void reinit()
00172 {
00173 std::fill_n( const_cast<Scalar*>(sub_vec.values()), sub_vec.subDim(), Teuchos::ScalarTraits<Scalar>::zero() );
00174 }
00176 void transfer( ConstSubVectorView<Scalar> *sub_vec_out )
00177 {
00178 sub_vec_out->initialize(sub_vec.globalOffset(),sub_vec.subDim(),sub_vec.values(),sub_vec.stride());
00179 sub_vec.set_uninitialized();
00180 }
00182 static void free( ConstSubVectorView<Scalar> *sub_vec )
00183 {
00184 if(sub_vec->values())
00185 delete [] const_cast<Scalar*>(sub_vec->values());
00186 sub_vec->set_uninitialized();
00187 }
00189 ConstSubVectorView<Scalar> sub_vec;
00190 private:
00191
00192 ReductTargetSubVectorT();
00193 ReductTargetSubVectorT(const ReductTargetSubVectorT&);
00194 ReductTargetSubVectorT<Scalar>& operator=(const ReductTargetSubVectorT&);
00195 };
00196
00197
00198
00199
00200 template<class Scalar>
00201 ROpGetSubVector<Scalar>::ROpGetSubVector( const index_type l, const index_type u )
00202 :RTOpT<Scalar>("ROpGetSubVector"), l_(l), u_(u)
00203 {}
00204
00205 template<class Scalar>
00206 void ROpGetSubVector<Scalar>::set_range( const index_type l, const index_type u )
00207 {
00208 l_ = l;
00209 u_ = u;
00210 }
00211
00212 template<class Scalar>
00213 ReductTargetSubVectorT<Scalar>&
00214 ROpGetSubVector<Scalar>::operator()(ReductTarget& reduct_obj ) const
00215 {
00216 using Teuchos::dyn_cast;
00217 return dyn_cast<ReductTargetSubVectorT<Scalar> >(reduct_obj);
00218 }
00219
00220 template<class Scalar>
00221 const ReductTargetSubVectorT<Scalar>&
00222 ROpGetSubVector<Scalar>::operator()( const ReductTarget& reduct_obj ) const
00223 {
00224 using Teuchos::dyn_cast;
00225 return dyn_cast<const ReductTargetSubVectorT<Scalar> >(reduct_obj);
00226 }
00227
00228
00229
00230 template<class Scalar>
00231 void ROpGetSubVector<Scalar>::get_reduct_type_num_entries(
00232 int* num_values
00233 ,int* num_indexes
00234 ,int* num_chars
00235 ) const
00236 {
00237 const int num_prim_objs_per_scalar = Teuchos::PrimitiveTypeTraits<Scalar>::numPrimitiveObjs();
00238 *num_values = (u_-l_+1)*num_prim_objs_per_scalar;
00239 *num_indexes = 0;
00240 *num_chars = 0;
00241 }
00242
00243 template<class Scalar>
00244 Teuchos::RefCountPtr<ReductTarget>
00245 ROpGetSubVector<Scalar>::reduct_obj_create() const
00246 {
00247 return Teuchos::rcp(new ReductTargetSubVectorT<Scalar>(l_,u_));
00248 }
00249
00250 template<class Scalar>
00251 void ROpGetSubVector<Scalar>::reduce_reduct_objs(
00252 const ReductTarget& in_reduct_obj, ReductTarget* inout_reduct_obj
00253 ) const
00254 {
00255 using Teuchos::dyn_cast;
00256 const ConstSubVectorView<Scalar> &sub_vec_in = dyn_cast<const ReductTargetSubVectorT<Scalar> >(in_reduct_obj).sub_vec;
00257 ConstSubVectorView<Scalar> &sub_vec_inout = dyn_cast<ReductTargetSubVectorT<Scalar> >(*inout_reduct_obj).sub_vec;
00258 TEST_FOR_EXCEPT(
00259 sub_vec_in.subDim()!=sub_vec_inout.subDim()||sub_vec_in.globalOffset()!=sub_vec_inout.globalOffset()
00260 ||!sub_vec_in.values()||!sub_vec_inout.values()
00261 );
00262 Scalar *svio_values = const_cast<Scalar*>(sub_vec_inout.values());
00263 for( int k = 0; k < sub_vec_in.subDim(); ++k ) {
00264 svio_values[k] += sub_vec_in[k];
00265 }
00266 }
00267
00268 template<class Scalar>
00269 void ROpGetSubVector<Scalar>::reduct_obj_reinit( ReductTarget* reduct_obj ) const
00270 {
00271 using Teuchos::dyn_cast;
00272 dyn_cast<ReductTargetSubVectorT<Scalar> >(*reduct_obj).reinit();
00273 }
00274
00275 template<class Scalar>
00276 void ROpGetSubVector<Scalar>::extract_reduct_obj_state(
00277 const ReductTarget &reduct_obj
00278 ,int num_values
00279 ,primitive_value_type value_data[]
00280 ,int num_indexes
00281 ,Teuchos_Index index_data[]
00282 ,int num_chars
00283 ,::RTOpPack::char_type char_data[]
00284 ) const
00285 {
00286 using Teuchos::dyn_cast;
00287 typedef Teuchos::PrimitiveTypeTraits<Scalar> PTT;
00288 const int num_prim_objs_per_scalar = PTT::numPrimitiveObjs();
00289 const ConstSubVectorView<Scalar> &sub_vec = dyn_cast<const ReductTargetSubVectorT<Scalar> >(reduct_obj).sub_vec;
00290 int value_data_off = 0;
00291 for( int k = 0; k < sub_vec.subDim(); ++k, value_data_off += num_prim_objs_per_scalar )
00292 PTT::extractPrimitiveObjs( sub_vec[k], num_prim_objs_per_scalar, value_data+value_data_off );
00293 }
00294
00295 template<class Scalar>
00296 void ROpGetSubVector<Scalar>::load_reduct_obj_state(
00297 int num_values
00298 ,const primitive_value_type value_data[]
00299 ,int num_indexes
00300 ,const Teuchos_Index index_data[]
00301 ,int num_chars
00302 ,const ::RTOpPack::char_type char_data[]
00303 ,ReductTarget *reduct_obj
00304 ) const
00305 {
00306 using Teuchos::dyn_cast;
00307 typedef Teuchos::PrimitiveTypeTraits<Scalar> PTT;
00308 const int num_prim_objs_per_scalar = PTT::numPrimitiveObjs();
00309 ConstSubVectorView<Scalar> &sub_vec = dyn_cast<ReductTargetSubVectorT<Scalar> >(*reduct_obj).sub_vec;
00310 Scalar *sv_values = const_cast<Scalar*>(sub_vec.values());
00311 int value_data_off = 0;
00312 for( int k = 0; k < sub_vec.subDim(); ++k, value_data_off += num_prim_objs_per_scalar )
00313 PTT::loadPrimitiveObjs( num_prim_objs_per_scalar, value_data+value_data_off, &sv_values[k] );
00314 }
00315
00316 template<class Scalar>
00317 void ROpGetSubVector<Scalar>::get_op_type_num_entries(
00318 int* num_values
00319 ,int* num_indexes
00320 ,int* num_chars
00321 ) const
00322 {
00323 TEST_FOR_EXCEPT( !num_values || !num_indexes || !num_chars );
00324 *num_values = 0;
00325 *num_indexes = 2;
00326 *num_chars = 0;
00327 }
00328
00329 template<class Scalar>
00330 void ROpGetSubVector<Scalar>::extract_op_state(
00331 int num_values
00332 ,primitive_value_type value_data[]
00333 ,int num_indexes
00334 ,Teuchos_Index index_data[]
00335 ,int num_chars
00336 ,::RTOpPack::char_type char_data[]
00337 ) const
00338 {
00339 TEST_FOR_EXCEPT( num_values!=0 || num_indexes!=2 || num_chars!=0 );
00340 TEST_FOR_EXCEPT( !index_data );
00341 index_data[0] = l_;
00342 index_data[1] = u_;
00343 }
00344
00345 template<class Scalar>
00346 void ROpGetSubVector<Scalar>::load_op_state(
00347 int num_values
00348 ,const primitive_value_type value_data[]
00349 ,int num_indexes
00350 ,const Teuchos_Index index_data[]
00351 ,int num_chars
00352 ,const ::RTOpPack::char_type char_data[]
00353 )
00354 {
00355 TEST_FOR_EXCEPT( num_values!=0 || num_indexes!=2 || num_chars!=0 );
00356 TEST_FOR_EXCEPT( !index_data );
00357 l_ = index_data[0];
00358 u_ = index_data[1];
00359 }
00360
00361 template<class Scalar>
00362 bool ROpGetSubVector<Scalar>::coord_invariant() const
00363 {
00364 return false;
00365 }
00366
00367 template<class Scalar>
00368 void ROpGetSubVector<Scalar>::apply_op(
00369 const int num_vecs, const ConstSubVectorView<Scalar> sub_vecs[]
00370 ,const int num_targ_vecs, const SubVectorView<Scalar> targ_sub_vecs[]
00371 ,ReductTarget *reduct_obj
00372 ) const
00373 {
00374 using Teuchos::dyn_cast;
00375
00376 RTOP_APPLY_OP_1_0(num_vecs,sub_vecs,num_targ_vecs,targ_sub_vecs);
00377
00378 if( u_ < globalOffset || globalOffset + subDim - 1 < l_ )
00379 return;
00380
00381 index_type
00382 i_l = ( l_ <= globalOffset ? 0 : l_ - globalOffset ),
00383 i_u = ( u_ >= globalOffset+subDim-1 ? subDim-1 : u_ - globalOffset );
00384
00385 ConstSubVectorView<Scalar> &sub_vec_targ = dyn_cast<ReductTargetSubVectorT<Scalar> >(*reduct_obj).sub_vec;
00386 Scalar *svt_values = const_cast<Scalar*>(sub_vec_targ.values());
00387
00388 for( index_type i = i_l; i <= i_u; ++i )
00389 svt_values[i+(globalOffset-l_)] = v0_val[i*v0_s];
00390
00391 }
00392
00393 }
00394
00395 #endif // RTOPPACK_ROP_GET_SUB_VECTOR_HPP