42 #ifndef THYRA_MULTI_VECTOR_DEFAULT_BASE_DEF_HPP 43 #define THYRA_MULTI_VECTOR_DEFAULT_BASE_DEF_HPP 46 #include "Thyra_MultiVectorDefaultBase_decl.hpp" 47 #include "Thyra_LinearOpDefaultBase.hpp" 48 #include "Thyra_MultiVectorStdOps.hpp" 49 #include "Thyra_VectorSpaceFactoryBase.hpp" 50 #include "Thyra_VectorSpaceBase.hpp" 51 #include "Thyra_VectorBase.hpp" 52 #include "Thyra_AssertOp.hpp" 53 #include "Thyra_DefaultColumnwiseMultiVector.hpp" 54 #include "RTOpPack_TOpAssignScalar.hpp" 55 #include "RTOpPack_ROpDotProd.hpp" 56 #include "RTOpPack_ROpNorm1.hpp" 57 #include "RTOpPack_ROpNorm2.hpp" 58 #include "RTOpPack_ROpNormInf.hpp" 59 #include "RTOpPack_TOpAssignVectors.hpp" 60 #include "RTOpPack_TOpAXPY.hpp" 61 #include "RTOpPack_TOpLinearCombination.hpp" 62 #include "RTOpPack_TOpScaleVector.hpp" 63 #include "Teuchos_Workspace.hpp" 64 #include "Teuchos_Assert.hpp" 65 #include "Teuchos_as.hpp" 74 template<
class Scalar>
75 RCP<MultiVectorBase<Scalar> >
79 &l_domain = *this->domain(),
80 &l_range = *this->range();
81 RCP<MultiVectorBase<Scalar> >
82 copy = createMembers(l_range,l_domain.
dim());
83 ::Thyra::assign<Scalar>(copy.ptr(), *
this);
93 template<
class Scalar>
96 using Teuchos::tuple;
using Teuchos::null;
97 RTOpPack::TOpAssignScalar<Scalar> assign_scalar_op(alpha);
98 Thyra::applyOp<Scalar>(assign_scalar_op,
99 ArrayView<Ptr<const MultiVectorBase<Scalar> > >(null),
103 template<
class Scalar>
106 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
107 RTOpPack::TOpAssignVectors<Scalar> assign_vectors_op;
108 Thyra::applyOp<Scalar>(assign_vectors_op, tuple(ptrInArg(mv)),
109 tuple<Ptr<MultiVectorBase<Scalar> > >(ptr(
this)), null);
113 template<
class Scalar>
116 using Teuchos::tuple;
using Teuchos::null;
117 typedef ScalarTraits<Scalar> ST;
118 if (alpha==ST::zero()) {
119 this->assign(ST::zero());
123 if (alpha==ST::one()) {
126 RTOpPack::TOpScaleVector<Scalar> scale_vector_op(alpha);
127 Thyra::applyOp<Scalar>(scale_vector_op,
128 ArrayView<Ptr<const MultiVectorBase<Scalar> > >(null),
133 template<
class Scalar>
139 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
140 RTOpPack::TOpAXPY<Scalar> axpy_op(alpha);
141 Thyra::applyOp<Scalar>( axpy_op, tuple(ptrInArg(mv)),
142 tuple<Ptr<MultiVectorBase<Scalar> > >(ptr(
this)), null );
146 template<
class Scalar>
148 const ArrayView<const Scalar>& alpha,
153 using Teuchos::tuple;
using Teuchos::null;
155 TEUCHOS_ASSERT_EQUALITY(alpha.size(), mv.size());
157 const int m = alpha.size();
158 if ( beta == ScalarTraits<Scalar>::one() && m == 1 ) {
159 this->update(alpha[0], *mv[0]);
166 RTOpPack::TOpLinearCombination<Scalar> lin_comb_op(alpha, beta);
167 Thyra::applyOp<Scalar>(lin_comb_op, mv,
168 tuple<Ptr<MultiVectorBase<Scalar> > >(ptr(
this)), null );
172 template<
class Scalar>
174 const ArrayView<
typename ScalarTraits<Scalar>::magnitudeType>& norms
177 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
178 const int m = this->domain()->dim();
179 RTOpPack::ROpNorm1<Scalar> norm_op;
180 Array<RCP<RTOpPack::ReductTarget> > rcp_op_targs(m);
181 Array<Ptr<RTOpPack::ReductTarget> > op_targs(m);
182 for(
int kc = 0; kc < m; ++kc) {
183 rcp_op_targs[kc] = norm_op.reduct_obj_create();
184 op_targs[kc] = rcp_op_targs[kc].ptr();
186 Thyra::applyOp<Scalar>(norm_op,
187 tuple<Ptr<const MultiVectorBase<Scalar> > >(ptrInArg(*
this)),
190 for(
int kc = 0; kc < m; ++kc) {
191 norms[kc] = norm_op(*op_targs[kc]);
196 template<
class Scalar>
198 const ArrayView<
typename ScalarTraits<Scalar>::magnitudeType>& norms
201 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
202 const int m = this->domain()->dim();
203 RTOpPack::ROpNorm2<Scalar> norm_op;
204 Array<RCP<RTOpPack::ReductTarget> > rcp_op_targs(m);
205 Array<Ptr<RTOpPack::ReductTarget> > op_targs(m);
206 for(
int kc = 0; kc < m; ++kc) {
207 rcp_op_targs[kc] = norm_op.reduct_obj_create();
208 op_targs[kc] = rcp_op_targs[kc].ptr();
210 Thyra::applyOp<Scalar>(norm_op,
211 tuple<Ptr<const MultiVectorBase<Scalar> > >(ptrInArg(*
this)),
214 for(
int kc = 0; kc < m; ++kc) {
215 norms[kc] = norm_op(*op_targs[kc]);
220 template<
class Scalar>
223 const ArrayView<Scalar>& prods
226 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
227 const int m = this->domain()->dim();
228 RTOpPack::ROpDotProd<Scalar> dot_op;
229 Array<RCP<RTOpPack::ReductTarget> > rcp_dot_targs(m);
230 Array<Ptr<RTOpPack::ReductTarget> > dot_targs(m);
231 for(
int kc = 0; kc < m; ++kc ) {
232 rcp_dot_targs[kc] = dot_op.reduct_obj_create();
233 dot_targs[kc] = rcp_dot_targs[kc].ptr();
235 Thyra::applyOp<Scalar>( dot_op,
236 tuple<Ptr<const MultiVectorBase<Scalar> > >(ptrInArg(mv), ptrInArg(*
this)),
239 for(
int kc = 0; kc < m; ++kc ) {
240 prods[kc] = dot_op(*dot_targs[kc]);
245 template<
class Scalar>
247 const ArrayView<
typename ScalarTraits<Scalar>::magnitudeType>& norms
250 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::null;
251 const int m = this->domain()->dim();
252 RTOpPack::ROpNormInf<Scalar> norm_op;
253 Array<RCP<RTOpPack::ReductTarget> > rcp_op_targs(m);
254 Array<Ptr<RTOpPack::ReductTarget> > op_targs(m);
255 for(
int kc = 0; kc < m; ++kc) {
256 rcp_op_targs[kc] = norm_op.reduct_obj_create();
257 op_targs[kc] = rcp_op_targs[kc].ptr();
259 Thyra::applyOp<Scalar>(norm_op,
260 tuple<Ptr<const MultiVectorBase<Scalar> > >(ptrInArg(*
this)),
263 for(
int kc = 0; kc < m; ++kc) {
264 norms[kc] = norm_op(*op_targs[kc]);
269 template<
class Scalar>
270 RCP<const MultiVectorBase<Scalar> >
273 using Teuchos::Workspace;
275 Teuchos::WorkspaceStore *wss = Teuchos::get_default_workspace_store().get();
279 const Range1D colRng = Teuchos::full_range(colRng_in,0,dimDomain-1);
280 if( colRng.lbound() == 0 && as<Ordinal>(colRng.ubound()) == dimDomain-1 )
281 return Teuchos::rcp(
this,
false);
282 if( colRng.size() ) {
284 Workspace< RCP< VectorBase<Scalar> > > col_vecs(wss,colRng.size());
285 for(
Ordinal j = colRng.lbound(); j <= colRng.ubound(); ++j )
286 col_vecs[j-colRng.lbound()] = Teuchos::rcp_const_cast<
VectorBase<Scalar> >(this->col(j));
289 this->range(),l_range.
smallVecSpcFcty()->createVecSpc(colRng.size()),col_vecs
293 return Teuchos::null;
297 template<
class Scalar>
298 RCP<MultiVectorBase<Scalar> >
301 using Teuchos::Workspace;
303 Teuchos::WorkspaceStore *wss = Teuchos::get_default_workspace_store().get();
307 const Range1D colRng = Teuchos::full_range(colRng_in,0,dimDomain-1);
308 if( colRng.lbound() == 0 && as<Ordinal>(colRng.ubound()) == dimDomain-1 )
309 return Teuchos::rcp(
this,
false);
310 if( colRng.size() ) {
312 Workspace< RCP< VectorBase<Scalar> > > col_vecs(wss,colRng.size());
313 for(
Ordinal j = colRng.lbound(); j <= colRng.ubound(); ++j )
314 col_vecs[j-colRng.lbound()] = this->col(j);
317 this->range(),l_range.
smallVecSpcFcty()->createVecSpc(colRng.size()),col_vecs
321 return Teuchos::null;
325 template<
class Scalar>
326 RCP<const MultiVectorBase<Scalar> >
328 const ArrayView<const int> &cols
331 using Teuchos::Workspace;
332 Teuchos::WorkspaceStore *wss = Teuchos::get_default_workspace_store().get();
334 const int numCols = cols.size();
338 const char msg_err[] =
"MultiVectorDefaultBase<Scalar>::subView(numCols,cols[]): Error!";
339 TEUCHOS_TEST_FOR_EXCEPTION( numCols < 1 || dimDomain < numCols, std::invalid_argument, msg_err );
342 Workspace< RCP< VectorBase<Scalar> > > col_vecs(wss,numCols);
343 for(
int k = 0; k < numCols; ++k ) {
344 const int col_k = cols[k];
346 TEUCHOS_TEST_FOR_EXCEPTION(
347 !( 0 <= col_k && col_k < dimDomain ), std::invalid_argument
348 ,msg_err <<
" col["<<k<<
"] = " << col_k <<
" is not in the range [0,"<<(dimDomain-1)<<
"]!" 355 this->range(), l_range.
smallVecSpcFcty()->createVecSpc(numCols), col_vecs
361 template<
class Scalar>
362 RCP<MultiVectorBase<Scalar> >
364 const ArrayView<const int> &cols
367 using Teuchos::Workspace;
368 Teuchos::WorkspaceStore *wss = Teuchos::get_default_workspace_store().get();
370 const int numCols = cols.size();
374 const char msg_err[] =
"MultiVectorDefaultBase<Scalar>::subView(numCols,cols[]): Error!";
375 TEUCHOS_TEST_FOR_EXCEPTION( numCols < 1 || dimDomain < numCols, std::invalid_argument, msg_err );
378 Workspace< RCP< VectorBase<Scalar> > > col_vecs(wss,numCols);
379 for(
int k = 0; k < numCols; ++k ) {
380 const int col_k = cols[k];
382 TEUCHOS_TEST_FOR_EXCEPTION(
383 !( 0 <= col_k && col_k < dimDomain ), std::invalid_argument
384 ,msg_err <<
" col["<<k<<
"] = " << col_k <<
" is not in the range [0,"<<(dimDomain-1)<<
"]!" 387 col_vecs[k] = this->col(col_k);
391 this->range(), l_range.
smallVecSpcFcty()->createVecSpc(numCols), col_vecs
397 template<
class Scalar>
399 const RTOpPack::RTOpT<Scalar> &prim_op,
402 const ArrayView<
const Ptr<RTOpPack::ReductTarget> > &reduct_objs,
403 const Ordinal prim_global_offset_in
407 using Teuchos::Workspace;
409 Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
411 const int num_multi_vecs = multi_vecs.size();
412 const int num_targ_multi_vecs = targ_multi_vecs.size();
427 Workspace<RCP<const VectorBase<Scalar> > > vecs_s(wss, num_multi_vecs);
428 Workspace<Ptr<const VectorBase<Scalar> > > vecs(wss, num_multi_vecs);
429 Workspace<RCP<VectorBase<Scalar> > > targ_vecs_s(wss, num_targ_multi_vecs);
430 Workspace<Ptr<VectorBase<Scalar> > > targ_vecs(wss, num_targ_multi_vecs);
432 for(
Ordinal j = 0; j < sec_dim; ++j) {
434 {
for(
Ordinal k = 0; k < as<Ordinal>(num_multi_vecs); ++k) {
435 vecs_s[k] = multi_vecs[k]->col(j);
436 vecs[k] = vecs_s[k].ptr();
438 {
for(
Ordinal k = 0; k < as<Ordinal>(num_targ_multi_vecs); ++k) {
439 targ_vecs_s[k] = targ_multi_vecs[k]->col(j);
440 targ_vecs[k] = targ_vecs_s[k].ptr();
446 targ_vecs().getConst(),
447 reduct_objs.size() ? reduct_objs[j] : Ptr<RTOpPack::ReductTarget>(),
448 prim_global_offset_in);
456 template<
class Scalar>
458 const RTOpPack::RTOpT<Scalar> &prim_op,
459 const RTOpPack::RTOpT<Scalar> &sec_op,
462 const Ptr<RTOpPack::ReductTarget> &reduct_obj,
463 const Ordinal prim_global_offset_in
467 using Teuchos::Workspace;
468 Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
479 const int reduct_objs_size = (!is_null(reduct_obj) ? sec_dim : 0);
480 Workspace<RCP<RTOpPack::ReductTarget> > rcp_reduct_objs(wss, reduct_objs_size);
481 Workspace<Ptr<RTOpPack::ReductTarget> > reduct_objs(wss, reduct_objs_size);
482 if (!is_null(reduct_obj)) {
483 for(
Ordinal k = 0; k < sec_dim; ++k) {
484 rcp_reduct_objs[k] = prim_op.reduct_obj_create();
485 reduct_objs[k] = rcp_reduct_objs[k].ptr();
491 prim_op, multi_vecs, targ_multi_vecs, reduct_objs,
492 prim_global_offset_in);
496 if (!is_null(reduct_obj)) {
497 for (
Ordinal k = 0; k < sec_dim; ++k) {
498 sec_op.reduce_reduct_objs( *reduct_objs[k], reduct_obj );
504 template<
class Scalar>
508 RTOpPack::ConstSubMultiVectorView<Scalar> *sub_mv
512 rangeDim = this->range()->dim(),
513 domainDim = this->domain()->dim();
515 rowRng = rowRng_in.full_range() ?
Range1D(0,rangeDim-1) : rowRng_in,
516 colRng = colRng_in.full_range() ?
Range1D(0,domainDim-1) : colRng_in;
518 TEUCHOS_TEST_FOR_EXCEPTION(
519 !(rowRng.ubound() < rangeDim), std::out_of_range
520 ,
"MultiVectorDefaultBase<Scalar>::acquireDetachedMultiVectorViewImpl(...): Error, rowRng = [" 521 <<rowRng.lbound()<<
","<<rowRng.ubound()<<
"] is not in the range = [0," 524 TEUCHOS_TEST_FOR_EXCEPTION(
525 !(colRng.ubound() < domainDim), std::out_of_range
526 ,
"MultiVectorDefaultBase<Scalar>::acquireDetachedMultiVectorViewImpl(...): Error, colRng = [" 527 <<colRng.lbound()<<
","<<colRng.ubound()<<
"] is not in the range = [0," 528 <<(domainDim-1)<<
"]!" 532 const ArrayRCP<Scalar> values = Teuchos::arcp<Scalar>(rowRng.size() * colRng.size());
534 RTOpPack::ConstSubVectorView<Scalar> sv;
535 for(
int k = colRng.lbound(); k <= colRng.ubound(); ++k ) {
536 RCP<const VectorBase<Scalar> > col_k = this->col(k);
537 col_k->acquireDetachedView( rowRng, &sv );
538 for(
int i = 0; i < rowRng.size(); ++i )
539 values[ i + k*rowRng.size() ] = sv[i];
540 col_k->releaseDetachedView( &sv );
554 template<
class Scalar>
556 RTOpPack::ConstSubMultiVectorView<Scalar>* sub_mv
560 sub_mv->uninitialize();
564 template<
class Scalar>
568 RTOpPack::SubMultiVectorView<Scalar> *sub_mv
576 as<RTOpPack::ConstSubMultiVectorView<Scalar>*>(sub_mv)
585 template<
class Scalar>
587 RTOpPack::SubMultiVectorView<Scalar>* sub_mv
591 TEUCHOS_TEST_FOR_EXCEPTION(
592 sub_mv==NULL, std::logic_error,
593 "MultiVectorDefaultBase<Scalar>::commitNonconstDetachedMultiVectorViewImpl(...): Error!" 597 const Range1D rowRng(sub_mv->globalOffset(),sub_mv->globalOffset()+sub_mv->subDim()-1);
598 RTOpPack::SubVectorView<Scalar> msv;
599 for(
int k = sub_mv->colOffset(); k < sub_mv->numSubCols(); ++k ) {
600 RCP<VectorBase<Scalar> > col_k = this->col(k);
601 col_k->acquireDetachedView( rowRng, &msv );
602 for(
int i = 0; i < rowRng.size(); ++i )
603 msv[i] = sub_mv->values()[ i + k*rowRng.size() ];
604 col_k->commitDetachedView( &msv );
607 sub_mv->uninitialize();
614 #endif // THYRA_MULTI_VECTOR_DEFAULT_BASE_DEF_HPP RCP< MultiVectorBase< Scalar > > nonconstContigSubViewImpl(const Range1D &colRng)
virtual void mvMultiReductApplyOpImpl(const RTOpPack::RTOpT< Scalar > &primary_op, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &multi_vecs, const ArrayView< const Ptr< MultiVectorBase< Scalar > > > &targ_multi_vecs, const ArrayView< const Ptr< RTOpPack::ReductTarget > > &reduct_objs, const Ordinal primary_global_offset) const
virtual void norms1Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
Default implementation of norms_1 using RTOps.
RCP< const MultiVectorBase< Scalar > > contigSubViewImpl(const Range1D &colRng) const
virtual void acquireNonconstDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
virtual void assignMultiVecImpl(const MultiVectorBase< Scalar > &mv)
Default implementation of assign(MV) using RTOps.
virtual void mvSingleReductApplyOpImpl(const RTOpPack::RTOpT< Scalar > &primary_op, const RTOpPack::RTOpT< Scalar > &secondary_op, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &multi_vecs, const ArrayView< const Ptr< MultiVectorBase< Scalar > > > &targ_multi_vecs, const Ptr< RTOpPack::ReductTarget > &reduct_obj, const Ordinal primary_global_offset) const
virtual void linearCombinationImpl(const ArrayView< const Scalar > &alpha, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &mv, const Scalar &beta)
Default implementation of linear_combination using RTOps.
Abstract interface for objects that represent a space for vectors.
virtual void assignImpl(Scalar alpha)
Default implementation of assign(scalar) using RTOps.
virtual void normsInfImpl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
Default implementation of norms_inf using RTOps.
virtual void releaseDetachedMultiVectorViewImpl(RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
Interface for a collection of column vectors called a multi-vector.
virtual void acquireDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
virtual void dotsImpl(const MultiVectorBase< Scalar > &mv, const ArrayView< Scalar > &prods) const
Default implementation of dots using RTOps.
virtual RCP< MultiVectorBase< Scalar > > clone_mv() const
virtual RCP< const VectorSpaceFactoryBase< Scalar > > smallVecSpcFcty() const =0
Return a VectorSpaceFactoryBase object for the creation of (usually serial) vector spaces with a smal...
virtual void norms2Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
Default implementation of norms_2 using RTOps.
Abstract interface for finite-dimensional dense vectors.
Default subclass for MultiVectorBase implemented using columns of separate abstract vectors...
virtual void commitNonconstDetachedMultiVectorViewImpl(RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
RCP< MultiVectorBase< Scalar > > nonconstNonContigSubViewImpl(const ArrayView< const int > &cols)
virtual void scaleImpl(Scalar alpha)
Default implementation of scale using RTOps.
RCP< const MultiVectorBase< Scalar > > nonContigSubViewImpl(const ArrayView< const int > &cols) const
virtual Ordinal dim() const =0
Return the dimension of the vector space.
virtual void updateImpl(Scalar alpha, const MultiVectorBase< Scalar > &mv)
Default implementation of update using RTOps.