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 THYRA_VECTOR_DEFAULT_BASE_HPP
00030 #define THYRA_VECTOR_DEFAULT_BASE_HPP
00031
00032
00033
00034
00035
00036
00037 #include "Thyra_VectorDefaultBaseDecl.hpp"
00038 #include "Thyra_VectorBase.hpp"
00039 #include "Thyra_MultiVectorDefaultBase.hpp"
00040 #include "Thyra_SingleRhsLinearOpBase.hpp"
00041 #include "Thyra_VectorStdOps.hpp"
00042 #include "Thyra_AssertOp.hpp"
00043 #include "Thyra_DefaultSpmdVectorSpace.hpp"
00044 #include "Thyra_MultiVectorBase.hpp"
00045 #include "RTOpPack_ROpGetSubVector.hpp"
00046 #include "RTOpPack_TOpSetSubVector.hpp"
00047 #include "Teuchos_TestForException.hpp"
00048
00049
00050 #ifdef THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00051 # include "Teuchos_VerboseObject.hpp"
00052 # define THYRA_VECTOR_VERBOSE_OUT_STATEMENT \
00053 Teuchos::RCP<Teuchos::FancyOStream> dbgout = Teuchos::VerboseObjectBase::getDefaultOStream()
00054 #endif // THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00055
00056
00057
00058 namespace Thyra {
00059
00060
00061
00062
00063
00064 template<class Scalar>
00065 std::string VectorDefaultBase<Scalar>::description() const
00066 {
00067 std::ostringstream oss;
00068 const Teuchos::RCP<const VectorSpaceBase<Scalar> >
00069 space = this->space();
00070 oss << Teuchos::Describable::description();
00071 if(is_null(space)) {
00072 oss << "{space=NULL}";
00073 }
00074 else {
00075 const Index dim = space->dim();
00076 oss << "{dim=" << dim << "}";
00077 }
00078 return oss.str();
00079 }
00080
00081
00082 template<class Scalar>
00083 void VectorDefaultBase<Scalar>::describe(
00084 Teuchos::FancyOStream &out_arg
00085 ,const Teuchos::EVerbosityLevel verbLevel
00086 ) const
00087 {
00088 using Teuchos::RCP;
00089 using Teuchos::FancyOStream;
00090 using Teuchos::OSTab;
00091 RCP<FancyOStream> out = rcp(&out_arg,false);
00092 OSTab tab(out);
00093 *out << this->description() << "\n";
00094 tab.incrTab();
00095 if (verbLevel >= Teuchos::VERB_HIGH) {
00096 RTOpPack::ConstSubVectorView<Scalar> sv;
00097 this->acquireDetachedView(Range1D(),&sv);
00098 for( Index i = 0; i < sv.subDim(); ++i )
00099 *out << i << ":" << sv(i) << std::endl;
00100 this->releaseDetachedView(&sv);
00101 }
00102 }
00103
00104
00105
00106
00107
00108 template<class Scalar>
00109 Teuchos::RCP< const VectorSpaceBase<Scalar> >
00110 VectorDefaultBase<Scalar>::range() const
00111 {
00112 #ifdef THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00113 THYRA_VECTOR_VERBOSE_OUT_STATEMENT;
00114 *dbgout << "\nThyra::VectorDefaultBase<"<<Teuchos::ScalarTraits<Scalar>::name()<<">::range() called!\n";
00115 #endif
00116 return this->space();
00117 }
00118
00119
00120 template<class Scalar>
00121 Teuchos::RCP< const VectorSpaceBase<Scalar> >
00122 VectorDefaultBase<Scalar>::domain() const
00123 {
00124 #ifdef THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00125 THYRA_VECTOR_VERBOSE_OUT_STATEMENT;
00126 *dbgout << "\nThyra::VectorDefaultBase<"<<Teuchos::ScalarTraits<Scalar>::name()<<">::domain() called!\n";
00127 #endif
00128 if(!domain_.get())
00129 const_cast<VectorDefaultBase<Scalar>*>(this)->domain_
00130 = Teuchos::rcp(new DefaultSpmdVectorSpace<Scalar>(1));
00131 return domain_;
00132 }
00133
00134
00135
00136
00137
00138 template<class Scalar>
00139 bool VectorDefaultBase<Scalar>::opSupported(ETransp M_trans) const
00140 {
00141 typedef Teuchos::ScalarTraits<Scalar> ST;
00142 return ( ST::isComplex ? ( M_trans==NOTRANS || M_trans==CONJTRANS ) : true );
00143 }
00144
00145
00146 template<class Scalar>
00147 void VectorDefaultBase<Scalar>::apply(
00148 const ETransp M_trans
00149 ,const VectorBase<Scalar> &x
00150 ,VectorBase<Scalar> *y
00151 ,const Scalar alpha
00152 ,const Scalar beta
00153 ) const
00154 {
00155 typedef Teuchos::ScalarTraits<Scalar> ST;
00156
00157 #ifdef TEUCHOS_DEBUG
00158 THYRA_ASSERT_LINEAR_OP_VEC_APPLY_SPACES("VectorDefaultBase<Scalar>::apply()",*this,M_trans,x,y);
00159 #endif
00160
00161 if( M_trans == NOTRANS || (M_trans == CONJ && !ST::isComplex) ) {
00162
00163 #ifdef THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00164 THYRA_VECTOR_VERBOSE_OUT_STATEMENT;
00165 *dbgout << "\nThyra::VectorDefaultBase<"<<Teuchos::ScalarTraits<Scalar>::name()<<">::apply(...) : y = beta*y + alpha*m*x (x is a scalar!)\n";
00166 #endif
00167 Vt_S( y, beta );
00168 Vp_StV( y, Scalar(alpha*get_ele(x,0)), *this );
00169 }
00170 else if( M_trans == CONJTRANS || (M_trans == TRANS && !ST::isComplex) ) {
00171
00172 #ifdef THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00173 THYRA_VECTOR_VERBOSE_OUT_STATEMENT;
00174 *dbgout << "\nThyra::VectorDefaultBase<"<<Teuchos::ScalarTraits<Scalar>::name()<<">::apply(...) : y = beta*y + alpha*m'*x (y is a scalar!)\n";
00175 #endif
00176 Scalar y_inout;
00177 if( beta == ST::zero() ) {
00178 y_inout = ST::zero();
00179 }
00180 else {
00181 y_inout = beta*get_ele(*y,0);
00182 }
00183 #if defined(THYRA_VECTOR_VERBOSE_TO_ERROR_OUT) && defined(RTOPPACK_SPMD_APPLY_OP_DUMP)
00184 RTOpPack::show_spmd_apply_op_dump = true;
00185 #endif
00186 #if defined(THYRA_VECTOR_VERBOSE_TO_ERROR_OUT) && defined(RTOPPACK_RTOPT_HELPER_DUMP_OUTPUT)
00187 RTOpPack::rtop_helpers_dump_all = true;
00188 #endif
00189 y_inout += alpha*this->space()->scalarProd(*this,x);
00190 #if defined(THYRA_VECTOR_VERBOSE_TO_ERROR_OUT) && defined(RTOPPACK_SPMD_APPLY_OP_DUMP)
00191 RTOpPack::show_spmd_apply_op_dump = false;
00192 #endif
00193 #if defined(THYRA_VECTOR_VERBOSE_TO_ERROR_OUT) && defined(RTOPPACK_RTOPT_HELPER_DUMP_OUTPUT)
00194 RTOpPack::rtop_helpers_dump_all = false;
00195 #endif
00196 set_ele(0,y_inout,y);
00197 #ifdef THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00198 *dbgout
00199 << "\nThyra::VectorDefaultBase<"<<ST::name()<<">::apply(...) : y_inout = "
00200 << y_inout << "\n";
00201 #endif
00202 }
00203 else {
00204 TEST_FOR_EXCEPTION(
00205 true,std::logic_error
00206 ,"VectorBase<"<<ST::name()<<">::apply(M_trans,...): Error, M_trans="<<toString(M_trans)<<" not supported!"
00207 );
00208 }
00209 }
00210
00211
00212
00213
00214
00215 template<class Scalar>
00216 inline
00217 void VectorDefaultBase<Scalar>::validateColRng( const Range1D &col_rng ) const
00218 {
00219 #ifdef TEUCHOS_DEBUG
00220 TEST_FOR_EXCEPT( !( col_rng.full_range() || ( col_rng.lbound() == 0 && col_rng.ubound() == 0) ) );
00221 #endif
00222 }
00223
00224
00225 template<class Scalar>
00226 inline
00227 void VectorDefaultBase<Scalar>::validateColIndexes( const int numCols, const int cols[] ) const
00228 {
00229 #ifdef TEUCHOS_DEBUG
00230 TEST_FOR_EXCEPT( numCols != 1 || cols == NULL || cols[0] != 0 );
00231 #endif
00232 }
00233
00234
00235 template<class Scalar>
00236 Teuchos::RCP<VectorBase<Scalar> >
00237 VectorDefaultBase<Scalar>::col(Index j)
00238 {
00239 #ifdef THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00240 THYRA_VECTOR_VERBOSE_OUT_STATEMENT;
00241 *dbgout << "\nThyra::VectorDefaultBase<"<<Teuchos::ScalarTraits<Scalar>::name()<<">::col(j) called!\n";
00242 #endif
00243 #ifdef TEUCHOS_DEBUG
00244 TEST_FOR_EXCEPT( j != 0 );
00245 #endif
00246 return Teuchos::rcp(this,false);
00247 }
00248
00249
00250 template<class Scalar>
00251 Teuchos::RCP<MultiVectorBase<Scalar> >
00252 VectorDefaultBase<Scalar>::clone_mv() const
00253 {
00254 #ifdef THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00255 THYRA_VECTOR_VERBOSE_OUT_STATEMENT;
00256 *dbgout << "\nThyra::VectorDefaultBase<"<<Teuchos::ScalarTraits<Scalar>::name()<<">::clone_mv() called!\n";
00257 #endif
00258 return this->clone_v();
00259 }
00260
00261
00262 template<class Scalar>
00263 Teuchos::RCP<const MultiVectorBase<Scalar> >
00264 VectorDefaultBase<Scalar>::subView( const Range1D& col_rng ) const
00265 {
00266 #ifdef THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00267 THYRA_VECTOR_VERBOSE_OUT_STATEMENT;
00268 *dbgout << "\nThyra::VectorDefaultBase<"<<Teuchos::ScalarTraits<Scalar>::name()<<">::subView(col_rng) const called!\n";
00269 #endif
00270 validateColRng(col_rng);
00271 return Teuchos::rcp(this,false);
00272 }
00273
00274
00275 template<class Scalar>
00276 Teuchos::RCP<MultiVectorBase<Scalar> >
00277 VectorDefaultBase<Scalar>::subView( const Range1D& col_rng )
00278 {
00279 #ifdef THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00280 THYRA_VECTOR_VERBOSE_OUT_STATEMENT;
00281 *dbgout << "\nThyra::VectorDefaultBase<"<<Teuchos::ScalarTraits<Scalar>::name()<<">::subView(col_rng) called!\n";
00282 #endif
00283 validateColRng(col_rng);
00284 return Teuchos::rcp(this,false);
00285 }
00286
00287
00288 template<class Scalar>
00289 Teuchos::RCP<const MultiVectorBase<Scalar> >
00290 VectorDefaultBase<Scalar>::subView( const int numCols, const int cols[] ) const
00291 {
00292 #ifdef THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00293 THYRA_VECTOR_VERBOSE_OUT_STATEMENT;
00294 *dbgout << "\nThyra::VectorDefaultBase<"<<Teuchos::ScalarTraits<Scalar>::name()<<">::subView(numCols,cols) const called!\n";
00295 #endif
00296 validateColIndexes(numCols,cols);
00297 return Teuchos::rcp(this,false);
00298 }
00299
00300
00301 template<class Scalar>
00302 Teuchos::RCP<MultiVectorBase<Scalar> >
00303 VectorDefaultBase<Scalar>::subView( const int numCols, const int cols[] )
00304 {
00305 #ifdef THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00306 THYRA_VECTOR_VERBOSE_OUT_STATEMENT;
00307 *dbgout << "\nThyra::VectorDefaultBase<"<<Teuchos::ScalarTraits<Scalar>::name()<<">::subView(numCols,cols) called!\n";
00308 #endif
00309 validateColIndexes(numCols,cols);
00310 return Teuchos::rcp(this,false);
00311 }
00312
00313
00314 template<class Scalar>
00315 void VectorDefaultBase<Scalar>::acquireDetachedMultiVectorViewImpl(
00316 const Range1D &rowRng,
00317 const Range1D &colRng,
00318 RTOpPack::ConstSubMultiVectorView<Scalar> *sub_mv
00319 ) const
00320 {
00321 #ifdef THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00322 THYRA_VECTOR_VERBOSE_OUT_STATEMENT;
00323 *dbgout << "\nThyra::VectorDefaultBase<"<<Teuchos::ScalarTraits<Scalar>::name()<<">::acquireDetachedMultiVectorViewImpl() const called!\n";
00324 #endif
00325 #ifdef TEUCHOS_DEBUG
00326 TEST_FOR_EXCEPT(sub_mv==NULL);
00327 #endif
00328 validateColRng(colRng);
00329 RTOpPack::ConstSubVectorView<Scalar> sv;
00330 acquireDetachedView(rowRng,&sv);
00331 #ifdef TEUCHOS_DEBUG
00332 TEST_FOR_EXCEPT( sv.stride() != 1 );
00333 #endif
00334 sub_mv->initialize( sv.globalOffset(), sv.subDim(), 0, 1, sv.values(), sv.subDim() );
00335 }
00336
00337
00338 template<class Scalar>
00339 void VectorDefaultBase<Scalar>::releaseDetachedMultiVectorViewImpl(
00340 RTOpPack::ConstSubMultiVectorView<Scalar>* sub_mv
00341 ) const
00342 {
00343 #ifdef THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00344 THYRA_VECTOR_VERBOSE_OUT_STATEMENT;
00345 *dbgout << "\nThyra::VectorDefaultBase<"<<Teuchos::ScalarTraits<Scalar>::name()<<">::releaseDetachedMultiVectorViewImpl() const called!\n";
00346 #endif
00347 #ifdef TEUCHOS_DEBUG
00348 TEST_FOR_EXCEPT(sub_mv==NULL);
00349 #endif
00350 RTOpPack::ConstSubVectorView<Scalar> sv(sub_mv->globalOffset(),sub_mv->subDim(),sub_mv->values(),1);
00351 releaseDetachedView(&sv);
00352 sub_mv->set_uninitialized();
00353 }
00354
00355
00356 template<class Scalar>
00357 void VectorDefaultBase<Scalar>::acquireNonconstDetachedMultiVectorViewImpl(
00358 const Range1D &rowRng,
00359 const Range1D &colRng,
00360 RTOpPack::SubMultiVectorView<Scalar> *sub_mv
00361 )
00362 {
00363 #ifdef THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00364 THYRA_VECTOR_VERBOSE_OUT_STATEMENT;
00365 *dbgout << "\nThyra::VectorDefaultBase<"<<Teuchos::ScalarTraits<Scalar>::name()<<">::acquireNonconstDetachedMultiVectorViewImpl() called!\n";
00366 #endif
00367 #ifdef TEUCHOS_DEBUG
00368 TEST_FOR_EXCEPT(sub_mv==NULL);
00369 #endif
00370 validateColRng(colRng);
00371 RTOpPack::SubVectorView<Scalar> sv;
00372 acquireDetachedView(rowRng,&sv);
00373 #ifdef TEUCHOS_DEBUG
00374 TEST_FOR_EXCEPT( sv.stride() != 1 );
00375 #endif
00376 sub_mv->initialize( sv.globalOffset(), sv.subDim(), 0, 1, sv.values(), sv.subDim() );
00377 }
00378
00379
00380 template<class Scalar>
00381 void VectorDefaultBase<Scalar>::commitNonconstDetachedMultiVectorViewImpl(
00382 RTOpPack::SubMultiVectorView<Scalar>* sub_mv
00383 )
00384 {
00385 #ifdef THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00386 THYRA_VECTOR_VERBOSE_OUT_STATEMENT;
00387 *dbgout << "\nThyra::VectorDefaultBase<"<<Teuchos::ScalarTraits<Scalar>::name()<<">::commitNonconstDetachedMultiVectorViewImpl() called!\n";
00388 #endif
00389 #ifdef TEUCHOS_DEBUG
00390 TEST_FOR_EXCEPT(sub_mv==NULL);
00391 #endif
00392 RTOpPack::SubVectorView<Scalar> sv(sub_mv->globalOffset(),sub_mv->subDim(),sub_mv->values(),1);
00393 commitDetachedView(&sv);
00394 sub_mv->set_uninitialized();
00395 }
00396
00397
00398
00399
00400
00401 template<class Scalar>
00402 Teuchos::RCP<VectorBase<Scalar> >
00403 VectorDefaultBase<Scalar>::clone_v() const
00404 {
00405 #ifdef THYRA_VECTOR_VERBOSE_TO_ERROR_OUT
00406 THYRA_VECTOR_VERBOSE_OUT_STATEMENT;
00407 *dbgout << "\nThyra::VectorDefaultBase<"<<Teuchos::ScalarTraits<Scalar>::name()<<">::clone_v() called!\n";
00408 #endif
00409 Teuchos::RCP<VectorBase<Scalar> > copy = createMember(this->space());
00410 assign( &*copy, *this );
00411 return copy;
00412 }
00413
00414
00415 template<class Scalar>
00416 void VectorDefaultBase<Scalar>::acquireDetachedVectorViewImpl(
00417 const Range1D& rng_in, RTOpPack::ConstSubVectorView<Scalar>* sub_vec_inout
00418 ) const
00419 {
00420 using Teuchos::dyn_cast;
00421 const Range1D rng = rng_in.full_range() ? Range1D(0,this->space()->dim()-1) : rng_in;
00422 #ifdef TEUCHOS_DEBUG
00423 TEST_FOR_EXCEPTION(
00424 !(rng.ubound() < this->space()->dim()), std::out_of_range
00425 ,"VectorDefaultBase<Scalar>::acquireDetachedVectorViewImpl(rng,...): Error, rng = ["<<rng.lbound()<<","<<rng.ubound()
00426 <<"] is not in range = [0,"<<(this->space()->dim()-1)<<"]" );
00427 #endif
00428
00429 if( sub_vec_inout->values() ) {
00430 delete [] sub_vec_inout->values();
00431 }
00432
00433 RTOpPack::ROpGetSubVector<Scalar> get_sub_vector_op(rng.lbound(),rng.ubound());
00434
00435 Teuchos::RCP<RTOpPack::ReductTarget>
00436 reduct_obj = get_sub_vector_op.reduct_obj_create();
00437
00438 const VectorBase<Scalar>* sub_vecs[] = { this };
00439 ::Thyra::applyOp<Scalar>(
00440 get_sub_vector_op,1,sub_vecs,0,NULL,&*reduct_obj
00441 ,rng.lbound(),rng.size(),rng.lbound()
00442 );
00443
00444
00445
00446 RTOpPack::ReductTargetSubVectorT<Scalar> &sub_vec_ro = get_sub_vector_op(*reduct_obj);
00447 sub_vec_ro.transfer(sub_vec_inout);
00448 }
00449
00450
00451 template<class Scalar>
00452 void VectorDefaultBase<Scalar>::releaseDetachedVectorViewImpl(
00453 RTOpPack::ConstSubVectorView<Scalar>* sub_vec
00454 ) const
00455 {
00456
00457 RTOpPack::ReductTargetSubVectorT<Scalar>::free(sub_vec);
00458 }
00459
00460
00461 template<class Scalar>
00462 void VectorDefaultBase<Scalar>::acquireNonconstDetachedVectorViewImpl(
00463 const Range1D& rng, RTOpPack::SubVectorView<Scalar>* sub_vec_inout
00464 )
00465 {
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 RTOpPack::ConstSubVectorView<Scalar> sub_vec;
00476 VectorDefaultBase<Scalar>::acquireDetachedVectorViewImpl( rng, &sub_vec );
00477 sub_vec_inout->initialize(
00478 sub_vec.globalOffset(), sub_vec.subDim(),
00479 const_cast<Scalar*>(sub_vec.values()),sub_vec.stride()
00480 );
00481 }
00482
00483
00484 template<class Scalar>
00485 void VectorDefaultBase<Scalar>::commitNonconstDetachedVectorViewImpl(
00486 RTOpPack::SubVectorView<Scalar>* sub_vec_inout
00487 )
00488 {
00489 RTOpPack::SparseSubVectorT<Scalar> spc_sub_vec(
00490 sub_vec_inout->globalOffset(), sub_vec_inout->subDim()
00491 ,sub_vec_inout->values(), sub_vec_inout->stride()
00492 );
00493 VectorDefaultBase<Scalar>::setSubVector( spc_sub_vec );
00494 RTOpPack::ConstSubVectorView<Scalar> sub_vec(*sub_vec_inout);
00495 VectorDefaultBase<Scalar>::releaseDetachedVectorViewImpl( &sub_vec );
00496 sub_vec_inout->set_uninitialized();
00497 }
00498
00499
00500 template<class Scalar>
00501 void VectorDefaultBase<Scalar>::setSubVector( const RTOpPack::SparseSubVectorT<Scalar>& sub_vec )
00502 {
00503 RTOpPack::TOpSetSubVector<Scalar> set_sub_vector_op(sub_vec);
00504 VectorBase<Scalar>* targ_vecs[1] = { this };
00505 ::Thyra::applyOp<Scalar>(
00506 set_sub_vector_op,0,NULL,1,targ_vecs,NULL
00507 ,sub_vec.globalOffset(),sub_vec.subDim(),sub_vec.globalOffset()
00508 );
00509 }
00510
00511
00512 }
00513
00514
00515 #endif // THYRA_VECTOR_DEFAULT_BASE_HPP