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