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_MULTI_VECTOR_DEFAULT_BASE_HPP
00030 #define THYRA_MULTI_VECTOR_DEFAULT_BASE_HPP
00031
00032
00033 #include "Thyra_MultiVectorDefaultBaseDecl.hpp"
00034 #include "Thyra_LinearOpDefaultBase.hpp"
00035 #include "Thyra_MultiVectorBase.hpp"
00036 #include "Thyra_MultiVectorStdOps.hpp"
00037 #include "Thyra_VectorSpaceBase.hpp"
00038 #include "Thyra_VectorBase.hpp"
00039 #include "Thyra_AssertOp.hpp"
00040 #include "Thyra_DefaultColumnwiseMultiVector.hpp"
00041 #include "Teuchos_Workspace.hpp"
00042 #include "Teuchos_TestForException.hpp"
00043 #include "Teuchos_as.hpp"
00044
00045
00046 namespace Thyra {
00047
00048
00049
00050
00051
00052 template<class Scalar>
00053 RCP<MultiVectorBase<Scalar> >
00054 MultiVectorDefaultBase<Scalar>::clone_mv() const
00055 {
00056 const VectorSpaceBase<Scalar>
00057 &l_domain = *this->domain(),
00058 &l_range = *this->range();
00059 RCP<MultiVectorBase<Scalar> >
00060 copy = createMembers(l_range,l_domain.dim());
00061 assign( copy.ptr(), *this );
00062 return copy;
00063 }
00064
00065
00066
00067
00068
00069
00070
00071
00072 template<class Scalar>
00073 RCP<const MultiVectorBase<Scalar> >
00074 MultiVectorDefaultBase<Scalar>::contigSubViewImpl( const Range1D& colRng_in ) const
00075 {
00076 using Teuchos::Workspace;
00077 using Teuchos::as;
00078 Teuchos::WorkspaceStore *wss = Teuchos::get_default_workspace_store().get();
00079 const VectorSpaceBase<Scalar> &l_domain = *this->domain();
00080 const VectorSpaceBase<Scalar> &l_range = *this->range();
00081 const Index dimDomain = l_domain.dim();
00082 const Range1D colRng = Teuchos::full_range(colRng_in,0,dimDomain-1);
00083 if( colRng.lbound() == 0 && as<Index>(colRng.ubound()) == dimDomain-1 )
00084 return Teuchos::rcp(this,false);
00085 if( colRng.size() ) {
00086
00087 Workspace< RCP< VectorBase<Scalar> > > col_vecs(wss,colRng.size());
00088 for( Index j = colRng.lbound(); j <= colRng.ubound(); ++j )
00089 col_vecs[j-colRng.lbound()] = Teuchos::rcp_const_cast<VectorBase<Scalar> >(this->col(j));
00090 return Teuchos::rcp(
00091 new DefaultColumnwiseMultiVector<Scalar>(
00092 this->range(),l_range.smallVecSpcFcty()->createVecSpc(colRng.size()),col_vecs
00093 )
00094 );
00095 }
00096 return Teuchos::null;
00097 }
00098
00099
00100 template<class Scalar>
00101 RCP<MultiVectorBase<Scalar> >
00102 MultiVectorDefaultBase<Scalar>::nonconstContigSubViewImpl( const Range1D& colRng_in )
00103 {
00104 using Teuchos::Workspace;
00105 using Teuchos::as;
00106 Teuchos::WorkspaceStore *wss = Teuchos::get_default_workspace_store().get();
00107 const VectorSpaceBase<Scalar> &l_domain = *this->domain();
00108 const VectorSpaceBase<Scalar> &l_range = *this->range();
00109 const Index dimDomain = l_domain.dim();
00110 const Range1D colRng = Teuchos::full_range(colRng_in,0,dimDomain-1);
00111 if( colRng.lbound() == 0 && as<Index>(colRng.ubound()) == dimDomain-1 )
00112 return Teuchos::rcp(this,false);
00113 if( colRng.size() ) {
00114
00115 Workspace< RCP< VectorBase<Scalar> > > col_vecs(wss,colRng.size());
00116 for( Index j = colRng.lbound(); j <= colRng.ubound(); ++j )
00117 col_vecs[j-colRng.lbound()] = this->col(j);
00118 return Teuchos::rcp(
00119 new DefaultColumnwiseMultiVector<Scalar>(
00120 this->range(),l_range.smallVecSpcFcty()->createVecSpc(colRng.size()),col_vecs
00121 )
00122 );
00123 }
00124 return Teuchos::null;
00125 }
00126
00127
00128 template<class Scalar>
00129 RCP<const MultiVectorBase<Scalar> >
00130 MultiVectorDefaultBase<Scalar>::nonContigSubViewImpl(
00131 const ArrayView<const int> &cols
00132 ) const
00133 {
00134 using Teuchos::Workspace;
00135 Teuchos::WorkspaceStore *wss = Teuchos::get_default_workspace_store().get();
00136 const VectorSpaceBase<Scalar> &l_range = *this->range();
00137 const int numCols = cols.size();
00138 #ifdef TEUCHOS_DEBUG
00139 const VectorSpaceBase<Scalar> &l_domain = *this->domain();
00140 const Index dimDomain = l_domain.dim();
00141 const char msg_err[] = "MultiVectorDefaultBase<Scalar>::subView(numCols,cols[]): Error!";
00142 TEST_FOR_EXCEPTION( numCols < 1 || dimDomain < numCols, std::invalid_argument, msg_err );
00143 #endif
00144
00145 Workspace< RCP< VectorBase<Scalar> > > col_vecs(wss,numCols);
00146 for( int k = 0; k < numCols; ++k ) {
00147 const int col_k = cols[k];
00148 #ifdef TEUCHOS_DEBUG
00149 TEST_FOR_EXCEPTION(
00150 !( 0 <= col_k && col_k < dimDomain ), std::invalid_argument
00151 ,msg_err << " col["<<k<<"] = " << col_k << " is not in the range [0,"<<(dimDomain-1)<<"]!"
00152 );
00153 #endif
00154 col_vecs[k] = Teuchos::rcp_const_cast<VectorBase<Scalar> >(this->col(col_k));
00155 }
00156 return Teuchos::rcp(
00157 new DefaultColumnwiseMultiVector<Scalar>(
00158 this->range(), l_range.smallVecSpcFcty()->createVecSpc(numCols), col_vecs
00159 )
00160 );
00161 }
00162
00163
00164 template<class Scalar>
00165 RCP<MultiVectorBase<Scalar> >
00166 MultiVectorDefaultBase<Scalar>::nonconstNonContigSubViewImpl(
00167 const ArrayView<const int> &cols
00168 )
00169 {
00170 using Teuchos::Workspace;
00171 Teuchos::WorkspaceStore *wss = Teuchos::get_default_workspace_store().get();
00172 const VectorSpaceBase<Scalar> &l_range = *this->range();
00173 const int numCols = cols.size();
00174 #ifdef TEUCHOS_DEBUG
00175 const VectorSpaceBase<Scalar> &l_domain = *this->domain();
00176 const Index dimDomain = l_domain.dim();
00177 const char msg_err[] = "MultiVectorDefaultBase<Scalar>::subView(numCols,cols[]): Error!";
00178 TEST_FOR_EXCEPTION( numCols < 1 || dimDomain < numCols, std::invalid_argument, msg_err );
00179 #endif
00180
00181 Workspace< RCP< VectorBase<Scalar> > > col_vecs(wss,numCols);
00182 for( int k = 0; k < numCols; ++k ) {
00183 const int col_k = cols[k];
00184 #ifdef TEUCHOS_DEBUG
00185 TEST_FOR_EXCEPTION(
00186 !( 0 <= col_k && col_k < dimDomain ), std::invalid_argument
00187 ,msg_err << " col["<<k<<"] = " << col_k << " is not in the range [0,"<<(dimDomain-1)<<"]!"
00188 );
00189 #endif
00190 col_vecs[k] = this->col(col_k);
00191 }
00192 return Teuchos::rcp(
00193 new DefaultColumnwiseMultiVector<Scalar>(
00194 this->range(), l_range.smallVecSpcFcty()->createVecSpc(numCols), col_vecs
00195 )
00196 );
00197 }
00198
00199
00200 template<class Scalar>
00201 void MultiVectorDefaultBase<Scalar>::mvMultiReductApplyOpImpl(
00202 const RTOpPack::RTOpT<Scalar> &prim_op,
00203 const ArrayView<const Ptr<const MultiVectorBase<Scalar> > > &multi_vecs,
00204 const ArrayView<const Ptr<MultiVectorBase<Scalar> > > &targ_multi_vecs,
00205 const ArrayView<const Ptr<RTOpPack::ReductTarget> > &reduct_objs,
00206 const Index prim_first_ele_offset_in,
00207 const Index prim_sub_dim_in,
00208 const Index prim_global_offset_in,
00209 const Index sec_first_ele_offset_in,
00210 const Index sec_sub_dim_in
00211 ) const
00212 {
00213
00214 using Teuchos::Workspace;
00215 using Teuchos::as;
00216 Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
00217
00218 const int num_multi_vecs = multi_vecs.size();
00219 const int num_targ_multi_vecs = targ_multi_vecs.size();
00220
00221
00222
00223 const VectorSpaceBase<Scalar> &l_domain = *this->domain();
00224
00225
00226
00227 const Index sec_dim = l_domain.dim();
00228 const Index sec_sub_dim = ( sec_sub_dim_in >= 0 ? sec_sub_dim_in : sec_dim - sec_first_ele_offset_in );
00229 #ifdef TEUCHOS_DEBUG
00230 const VectorSpaceBase<Scalar> &l_range = *this->range();
00231 const Index prim_dim = l_range.dim();
00232 const Index prim_sub_dim = ( prim_sub_dim_in >= 0 ? prim_sub_dim_in : prim_dim - prim_first_ele_offset_in );
00233 const char err_msg[] = "MultiVectorDefaultBase<Scalar>::mvMultiReductApplyOpImpl(...): Error!";
00234 TEST_FOR_EXCEPTION( !(0 < prim_sub_dim && prim_sub_dim <= prim_dim), std::invalid_argument, err_msg );
00235 TEST_FOR_EXCEPTION( !(0 < sec_sub_dim && sec_sub_dim <= sec_dim), std::invalid_argument, err_msg );
00236 #endif
00237
00238
00239
00240
00241
00242
00243 Workspace<RCP<const VectorBase<Scalar> > > vecs_s(wss, num_multi_vecs);
00244 Workspace<Ptr<const VectorBase<Scalar> > > vecs(wss, num_multi_vecs);
00245 Workspace<RCP<VectorBase<Scalar> > > targ_vecs_s(wss, num_targ_multi_vecs);
00246 Workspace<Ptr<VectorBase<Scalar> > > targ_vecs(wss, num_targ_multi_vecs);
00247
00248 for(Index j = sec_first_ele_offset_in; j < sec_first_ele_offset_in + sec_sub_dim; ++j) {
00249
00250 {for(Index k = 0; k < as<Index>(num_multi_vecs); ++k) {
00251 vecs_s[k] = multi_vecs[k]->col(j);
00252 vecs[k] = vecs_s[k].ptr();
00253 }}
00254 {for(Index k = 0; k < as<Index>(num_targ_multi_vecs); ++k) {
00255 targ_vecs_s[k] = targ_multi_vecs[k]->col(j);
00256 targ_vecs[k] = targ_vecs_s[k].ptr();
00257 }}
00258
00259 Thyra::applyOp(
00260 prim_op,
00261 vecs().getConst(),
00262 targ_vecs().getConst(),
00263 reduct_objs.size() ? reduct_objs[j] : Ptr<RTOpPack::ReductTarget>(),
00264 prim_first_ele_offset_in, prim_sub_dim_in, prim_global_offset_in
00265 );
00266 }
00267
00268
00269
00270 }
00271
00272
00273 template<class Scalar>
00274 void MultiVectorDefaultBase<Scalar>::mvSingleReductApplyOpImpl(
00275 const RTOpPack::RTOpT<Scalar> &prim_op,
00276 const RTOpPack::RTOpT<Scalar> &sec_op,
00277 const ArrayView<const Ptr<const MultiVectorBase<Scalar> > > &multi_vecs,
00278 const ArrayView<const Ptr<MultiVectorBase<Scalar> > > &targ_multi_vecs,
00279 const Ptr<RTOpPack::ReductTarget> &reduct_obj,
00280 const Index prim_first_ele_offset_in,
00281 const Index prim_sub_dim_in,
00282 const Index prim_global_offset_in,
00283 const Index sec_first_ele_offset_in,
00284 const Index sec_sub_dim_in
00285 ) const
00286 {
00287 using Teuchos::Workspace;
00288 Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
00289
00290
00291
00292 const VectorSpaceBase<Scalar> &l_domain = *this->domain();
00293
00294
00295 const Index sec_dim = l_domain.dim();
00296 const Index sec_sub_dim = ( sec_sub_dim_in >= 0 ? sec_sub_dim_in : sec_dim - sec_first_ele_offset_in );
00297 #ifdef TEUCHOS_DEBUG
00298 const VectorSpaceBase<Scalar> &l_range = *this->range();
00299 const Index prim_dim = l_range.dim();
00300 const Index prim_sub_dim = ( prim_sub_dim_in >= 0 ? prim_sub_dim_in : prim_dim - prim_first_ele_offset_in );
00301 const char err_msg[] = "MultiVectorDefaultBase<Scalar>::mvSingleReductApplyOpImpl(...): Error!";
00302 TEST_FOR_EXCEPTION( !(0 < prim_sub_dim && prim_sub_dim <= prim_dim), std::invalid_argument, err_msg );
00303 TEST_FOR_EXCEPTION( !(0 < sec_sub_dim && sec_sub_dim <= sec_dim), std::invalid_argument, err_msg );
00304 #endif
00305
00306
00307
00308 const int reduct_objs_size = (!is_null(reduct_obj) ? sec_sub_dim : 0);
00309 Workspace<RCP<RTOpPack::ReductTarget> > rcp_reduct_objs(wss, reduct_objs_size);
00310 Workspace<Ptr<RTOpPack::ReductTarget> > reduct_objs(wss, reduct_objs_size);
00311 if (!is_null(reduct_obj)) {
00312 for(Index k = 0; k < sec_sub_dim; ++k) {
00313 rcp_reduct_objs[k] = prim_op.reduct_obj_create();
00314 reduct_objs[k] = rcp_reduct_objs[k].ptr();
00315 }
00316 }
00317
00318
00319 this->applyOp(
00320 prim_op, multi_vecs, targ_multi_vecs, reduct_objs,
00321 prim_first_ele_offset_in, prim_sub_dim_in, prim_global_offset_in,
00322 sec_first_ele_offset_in, sec_sub_dim_in
00323 );
00324
00325
00326
00327 if (!is_null(reduct_obj)) {
00328 for (Index k = 0; k < sec_sub_dim; ++k) {
00329 sec_op.reduce_reduct_objs( *reduct_objs[k], reduct_obj );
00330 }
00331 }
00332 }
00333
00334
00335 template<class Scalar>
00336 void MultiVectorDefaultBase<Scalar>::acquireDetachedMultiVectorViewImpl(
00337 const Range1D &rowRng_in,
00338 const Range1D &colRng_in,
00339 RTOpPack::ConstSubMultiVectorView<Scalar> *sub_mv
00340 ) const
00341 {
00342 const Index
00343 rangeDim = this->range()->dim(),
00344 domainDim = this->domain()->dim();
00345 const Range1D
00346 rowRng = rowRng_in.full_range() ? Range1D(0,rangeDim-1) : rowRng_in,
00347 colRng = colRng_in.full_range() ? Range1D(0,domainDim-1) : colRng_in;
00348 #ifdef TEUCHOS_DEBUG
00349 TEST_FOR_EXCEPTION(
00350 !(rowRng.ubound() < rangeDim), std::out_of_range
00351 ,"MultiVectorDefaultBase<Scalar>::acquireDetachedMultiVectorViewImpl(...): Error, rowRng = ["
00352 <<rowRng.lbound()<<","<<rowRng.ubound()<<"] is not in the range = [0,"
00353 <<(rangeDim-1)<<"]!"
00354 );
00355 TEST_FOR_EXCEPTION(
00356 !(colRng.ubound() < domainDim), std::out_of_range
00357 ,"MultiVectorDefaultBase<Scalar>::acquireDetachedMultiVectorViewImpl(...): Error, colRng = ["
00358 <<colRng.lbound()<<","<<colRng.ubound()<<"] is not in the range = [0,"
00359 <<(domainDim-1)<<"]!"
00360 );
00361 #endif
00362
00363 Scalar *values = new Scalar[ rowRng.size() * colRng.size() ];
00364
00365 RTOpPack::ConstSubVectorView<Scalar> sv;
00366 for( int k = colRng.lbound(); k <= colRng.ubound(); ++k ) {
00367 RCP<const VectorBase<Scalar> > col_k = this->col(k);
00368 col_k->acquireDetachedView( rowRng, &sv );
00369 for( int i = 0; i < rowRng.size(); ++i )
00370 values[ i + k*rowRng.size() ] = sv[i];
00371 col_k->releaseDetachedView( &sv );
00372 }
00373
00374 sub_mv->initialize(
00375 rowRng.lbound()
00376 ,rowRng.size()
00377 ,colRng.lbound()
00378 ,colRng.size()
00379 ,values
00380 ,rowRng.size()
00381 );
00382 }
00383
00384
00385 template<class Scalar>
00386 void MultiVectorDefaultBase<Scalar>::releaseDetachedMultiVectorViewImpl(
00387 RTOpPack::ConstSubMultiVectorView<Scalar>* sub_mv
00388 ) const
00389 {
00390
00391 delete [] const_cast<Scalar*>(sub_mv->values().get());
00392 sub_mv->set_uninitialized();
00393 }
00394
00395
00396 template<class Scalar>
00397 void MultiVectorDefaultBase<Scalar>::acquireNonconstDetachedMultiVectorViewImpl(
00398 const Range1D &rowRng,
00399 const Range1D &colRng,
00400 RTOpPack::SubMultiVectorView<Scalar> *sub_mv
00401 )
00402 {
00403 using Teuchos::as;
00404
00405
00406 MultiVectorDefaultBase<Scalar>::acquireDetachedMultiVectorViewImpl(
00407 rowRng, colRng,
00408 as<RTOpPack::ConstSubMultiVectorView<Scalar>*>(sub_mv)
00409
00410
00411
00412
00413 );
00414 }
00415
00416
00417 template<class Scalar>
00418 void MultiVectorDefaultBase<Scalar>::commitNonconstDetachedMultiVectorViewImpl(
00419 RTOpPack::SubMultiVectorView<Scalar>* sub_mv
00420 )
00421 {
00422 #ifdef TEUCHOS_DEBUG
00423 TEST_FOR_EXCEPTION(
00424 sub_mv==NULL, std::logic_error,
00425 "MultiVectorDefaultBase<Scalar>::commitNonconstDetachedMultiVectorViewImpl(...): Error!"
00426 );
00427 #endif
00428
00429 const Range1D rowRng(sub_mv->globalOffset(),sub_mv->globalOffset()+sub_mv->subDim()-1);
00430 RTOpPack::SubVectorView<Scalar> msv;
00431 for( int k = sub_mv->colOffset(); k < sub_mv->numSubCols(); ++k ) {
00432 RCP<VectorBase<Scalar> > col_k = this->col(k);
00433 col_k->acquireDetachedView( rowRng, &msv );
00434 for( int i = 0; i < rowRng.size(); ++i )
00435 msv[i] = sub_mv->values()[ i + k*rowRng.size() ];
00436 col_k->commitDetachedView( &msv );
00437 }
00438
00439 delete [] const_cast<Scalar*>(sub_mv->values().get());
00440
00441 sub_mv->set_uninitialized();
00442 }
00443
00444
00445 }
00446
00447
00448 #endif // THYRA_MULTI_VECTOR_DEFAULT_BASE_HPP