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