RTOpPack_ROpGetSubVector.hpp

00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //      Thyra: Interfaces and Support Code for the Interoperability of Abstract Numerical Algorithms 
00005 //                 Copyright (2004) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
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 }; // class ROpGetSubVector
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                  // global_offset
00153           ,subDim              // subDim
00154           ,new Scalar[subDim]  // values
00155           ,1                   // stride
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   // Not defined and not to be called!
00190   ReductTargetSubVectorT();
00191   ReductTargetSubVectorT(const ReductTargetSubVectorT&);
00192   ReductTargetSubVectorT<Scalar>& operator=(const ReductTargetSubVectorT&);
00193 };
00194 
00195 // ////////////////////////////////
00196 // Template definitions
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 // Overridden from RTOpT
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; // l, u
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; // None of the sub-vector that we are looking for is not in this vector chunk!
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 } // namespace RTOpPack
00393 
00394 #endif // RTOPPACK_ROP_GET_SUB_VECTOR_HPP

Generated on Thu Sep 18 12:39:44 2008 for RTOp : Vector Reduction/Transformation Operators by doxygen 1.3.9.1