00001
00002
00003
00004 #include <assert.h>
00005
00006 #include "AbstractLinAlgPack_apply_op_helper.hpp"
00007 #include "AbstractLinAlgPack_VectorSpace.hpp"
00008 #include "AbstractLinAlgPack_VectorMutable.hpp"
00009 #include "Teuchos_Workspace.hpp"
00010 #include "Teuchos_TestForException.hpp"
00011
00012 void AbstractLinAlgPack::apply_op_validate_input(
00013 const char func_name[]
00014 ,const RTOpPack::RTOp& op
00015 ,const size_t num_vecs, const Vector* vecs[]
00016 ,const size_t num_targ_vecs, VectorMutable* targ_vecs[]
00017 ,RTOpPack::ReductTarget *reduct_obj
00018 ,const index_type first_ele_in, const index_type sub_dim_in, const index_type global_offset_in
00019 )
00020 {
00021 const VectorSpace
00022 &space = (num_vecs ? vecs[0]->space() : targ_vecs[0]->space() );
00023 const index_type
00024 dim = space.dim();
00025 TEST_FOR_EXCEPTION(
00026 global_offset_in < 0, std::logic_error
00027 ,func_name << " : Error! global_offset_in = "
00028 <<global_offset_in<<" is not valid" );
00029 TEST_FOR_EXCEPTION(
00030 first_ele_in > dim, std::logic_error
00031 ,func_name << " : Error! first_ele_in = "
00032 <<first_ele_in<<" is not compatible with space.dim() = " << dim );
00033 TEST_FOR_EXCEPTION(
00034 sub_dim_in < 0 || (sub_dim_in > 0 && sub_dim_in > dim-(first_ele_in-1)), std::logic_error
00035 ,func_name << " : Error! first_ele_in = "
00036 <<first_ele_in<<" and sub_dim_in = "<<sub_dim_in
00037 <<" is not compatible with space.dim() = " << dim );
00038 {for(int k = 0; k < num_vecs; ++k) {
00039 const bool is_compatible = space.is_compatible(vecs[k]->space());
00040 TEST_FOR_EXCEPTION(
00041 !is_compatible, VectorSpace::IncompatibleVectorSpaces
00042 ,func_name << " : Error! vecs["<<k<<"]->space() of type \'"
00043 << typeName(vecs[k]->space()) << "\' "
00044 << " with dimension vecs["<<k<<"].dim() = " << vecs[k]->dim()
00045 << " is not compatible with space of type \'"
00046 << typeName(space) << " with dimmension space.dim() = " << dim );
00047 }}
00048 {for(int k = 0; k < num_targ_vecs; ++k) {
00049 const bool is_compatible = space.is_compatible(targ_vecs[k]->space());
00050 TEST_FOR_EXCEPTION(
00051 !is_compatible, VectorSpace::IncompatibleVectorSpaces
00052 ,func_name << " : Error! targ_vecs["<<k<<"]->space() of type \'"
00053 << typeName(targ_vecs[k]->space()) << "\' "
00054 << " with dimension targ_vecs["<<k<<"].dim() = " << targ_vecs[k]->dim()
00055 << " is not compatible with space of type \'"
00056 << typeName(space) << " with dimmension space.dim() = " << dim );
00057 }}
00058 }
00059
00060 void AbstractLinAlgPack::apply_op_serial(
00061 const RTOpPack::RTOp& op
00062 ,const size_t num_vecs, const Vector* vecs[]
00063 ,const size_t num_targ_vecs, VectorMutable* targ_vecs[]
00064 ,RTOpPack::ReductTarget *reduct_obj
00065 ,const index_type first_ele_in, const index_type sub_dim_in, const index_type global_offset_in
00066 )
00067 {
00068 using Teuchos::Workspace;
00069 Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
00070
00071
00072 const VectorSpace
00073 &space = ( num_vecs ? vecs[0]->space() : targ_vecs[0]->space() );
00074 const index_type
00075 full_dim = space.dim(),
00076 global_sub_dim = sub_dim_in ? sub_dim_in : full_dim - (first_ele_in-1);
00077 const Range1D
00078 global_sub_rng = Range1D(first_ele_in,(first_ele_in-1)+global_sub_dim);
00079
00080
00081
00082
00083
00084 Workspace<RTOpPack::ConstSubVectorView<value_type> > local_vecs(wss,num_vecs);
00085 Workspace<RTOpPack::SubVectorView<value_type> > local_targ_vecs(wss,num_targ_vecs);
00086 int k;
00087 for(k = 0; k < num_vecs; ++k) {
00088 RTOpPack::SubVector _v;
00089 vecs[k]->get_sub_vector( global_sub_rng, &_v );
00090 (local_vecs[k] = _v).setGlobalOffset( _v.globalOffset() + global_offset_in );
00091 }
00092 for(k = 0; k < num_targ_vecs; ++k) {
00093 RTOpPack::MutableSubVector _v;
00094 targ_vecs[k]->get_sub_vector( global_sub_rng, &_v );
00095 (local_targ_vecs[k] = _v).setGlobalOffset( _v.globalOffset() + global_offset_in );
00096 }
00097
00098
00099
00100
00101
00102 op.apply_op(
00103 num_vecs, num_vecs ? &local_vecs[0] : NULL
00104 ,num_targ_vecs, num_targ_vecs ? &local_targ_vecs[0] : NULL
00105 ,reduct_obj
00106 );
00107
00108
00109
00110
00111
00112
00113
00114 for(k = 0; k < num_vecs; ++k) {
00115 RTOpPack::ConstSubVectorView<value_type> &v = local_vecs[k];
00116 v.setGlobalOffset( v.globalOffset() - global_offset_in );
00117 RTOpPack::SubVector _v = v;
00118 vecs[k]->free_sub_vector(&_v);
00119 }
00120 for(k = 0; k < num_targ_vecs; ++k) {
00121 RTOpPack::SubVectorView<value_type> &v = local_targ_vecs[k];
00122 v.setGlobalOffset( v.globalOffset() - global_offset_in );
00123 RTOpPack::MutableSubVector _v = v;
00124 targ_vecs[k]->commit_sub_vector(&_v);
00125 }
00126
00127 }