43 #ifndef THYRA_TPETRA_VECTOR_SPACE_HPP
44 #define THYRA_TPETRA_VECTOR_SPACE_HPP
47 #include "Thyra_TpetraVectorSpace_decl.hpp"
48 #include "Thyra_TpetraThyraWrappers.hpp"
49 #include "Thyra_TpetraVector.hpp"
50 #include "Thyra_TpetraMultiVector.hpp"
51 #include "Thyra_TpetraEuclideanScalarProd.hpp"
52 #include "Tpetra_Details_StaticView.hpp"
57 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
58 RCP<TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
67 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
69 const RCP<
const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > &tpetraMap
73 tpetraMap_ = tpetraMap;
74 this->updateState(tpetraMap->getGlobalNumElements(),
75 !tpetraMap->isDistributed());
76 this->setScalarProd(tpetraEuclideanScalarProd<Scalar,LocalOrdinal,GlobalOrdinal,Node>());
83 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
87 return tpetraVector<Scalar>(
88 weakSelfPtr_.create_strong().getConst(),
90 new Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node>(tpetraMap_,
false)
96 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
100 return tpetraMultiVector<Scalar>(
101 weakSelfPtr_.create_strong().getConst(),
102 tpetraVectorSpace<Scalar>(
103 Tpetra::createLocalMapWithNode<LocalOrdinal, GlobalOrdinal, Node>(
104 numMembers, tpetraMap_->getComm()
108 new Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>(
109 tpetraMap_, numMembers,
false)
117 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
118 class CopyTpetraMultiVectorViewBack {
121 :mv_(mv), raw_mv_(raw_mv)
124 bool inUse = Teuchos::get_extra_data<bool>(tmv,
"inUse");
127 "Cannot use the cached vector simultaneously more than once.");
129 Teuchos::set_extra_data(inUse,
"inUse",Teuchos::outArg(tmv), Teuchos::POST_DESTROY,
false);
131 ~CopyTpetraMultiVectorViewBack()
135 RTOpPack::assign_entries<Scalar>( Teuchos::outArg(raw_mv_), smv );
136 mv_->releaseDetachedView(&smv);
138 RCP<Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > tmv = Teuchos::rcp_dynamic_cast<TpetraMultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(mv_,
true)->getTpetraMultiVector();
139 Teuchos::set_extra_data(inUse,
"inUse",Teuchos::outArg(tmv), Teuchos::POST_DESTROY,
false);
142 RCP<MultiVectorBase<Scalar> > mv_;
147 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
148 RCP< MultiVectorBase<Scalar> >
149 TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node>::createCachedMembersView(
157 RCP< MultiVectorBase<Scalar> > mv;
158 if (!tpetraMap_->isDistributed()) {
160 if (tpetraMV_.is_null() || (tpetraMV_->getNumVectors() != size_t (raw_mv.
numSubCols()))) {
161 if (!tpetraMV_.is_null())
165 "Cannot use the cached vector simultaneously more than once.");
166 using IST =
typename Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>::impl_scalar_type;
167 using DT =
typename Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>::device_type;
168 auto dv = ::Tpetra::Details::getStatic2dDualView<IST, DT> (tpetraMap_->getGlobalNumElements(), raw_mv.
numSubCols());
169 tpetraMV_ =
Teuchos::rcp(
new Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>(tpetraMap_, dv));
171 Teuchos::set_extra_data(inUse,
"inUse",Teuchos::outArg(tpetraMV_));
174 if (tpetraDomainSpace_.is_null() || raw_mv.
numSubCols() != tpetraDomainSpace_->localSubDim())
175 tpetraDomainSpace_ = tpetraVectorSpace<Scalar>(Tpetra::createLocalMapWithNode<LocalOrdinal, GlobalOrdinal, Node>(raw_mv.
numSubCols(), tpetraMap_->getComm()));
177 mv = tpetraMultiVector<Scalar>(weakSelfPtr_.create_strong().getConst(), tpetraDomainSpace_, tpetraMV_);
179 mv = this->createMembers(raw_mv.
numSubCols());
181 RCP<Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > tmv = Teuchos::rcp_dynamic_cast<TpetraMultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(mv,
true)->getTpetraMultiVector();
182 Teuchos::set_extra_data(inUse,
"inUse",Teuchos::outArg(tmv));
187 RTOpPack::assign_entries<Scalar>(
191 mv->commitDetachedView(&smv);
193 Teuchos::set_extra_data(
195 Teuchos::rcp(
new CopyTpetraMultiVectorViewBack<Scalar,LocalOrdinal,GlobalOrdinal,Node>(Teuchos::rcpFromRef(*mv),raw_mv)),
196 "CopyTpetraMultiVectorViewBack",
204 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
205 RCP<const MultiVectorBase<Scalar> >
206 TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node>::createCachedMembersView(
213 RCP< MultiVectorBase<Scalar> > mv;
214 if (!tpetraMap_->isDistributed()) {
215 if (tpetraMV_.is_null() || (tpetraMV_->getNumVectors() != size_t (raw_mv.
numSubCols()))) {
216 if (!tpetraMV_.is_null())
220 "Cannot use the cached vector simultaneously more than once.");
221 using IST =
typename Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>::impl_scalar_type;
222 using DT =
typename Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>::device_type;
223 auto dv = ::Tpetra::Details::getStatic2dDualView<IST, DT> (tpetraMap_->getGlobalNumElements(), raw_mv.
numSubCols());
224 tpetraMV_ =
Teuchos::rcp(
new Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>(tpetraMap_, dv));
226 Teuchos::set_extra_data(inUse,
"inUse",Teuchos::outArg(tpetraMV_));
229 if (tpetraDomainSpace_.is_null() || raw_mv.
numSubCols() != tpetraDomainSpace_->localSubDim())
230 tpetraDomainSpace_ = tpetraVectorSpace<Scalar>(Tpetra::createLocalMapWithNode<LocalOrdinal, GlobalOrdinal, Node>(raw_mv.
numSubCols(), tpetraMap_->getComm()));
232 mv = tpetraMultiVector<Scalar>(weakSelfPtr_.create_strong().getConst(), tpetraDomainSpace_, tpetraMV_);
234 mv = this->createMembers(raw_mv.
numSubCols());
236 RCP<Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > tmv = Teuchos::rcp_dynamic_cast<TpetraMultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(mv,
true)->getTpetraMultiVector();
237 Teuchos::set_extra_data(inUse,
"inUse",Teuchos::outArg(tmv));
242 RTOpPack::assign_entries<Scalar>(
245 mv->commitDetachedView(&smv);
250 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
255 const Range1D rng = full_range(rng_in,0,this->dim()-1);
256 const Ordinal l_localOffset = this->localOffset();
258 const Ordinal myLocalSubDim = tpetraMap_.is_null () ?
259 static_cast<Ordinal> (0) : tpetraMap_->getNodeNumElements ();
261 return ( l_localOffset<=rng.
lbound() && rng.
ubound()<l_localOffset+myLocalSubDim );
265 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
269 return tpetraVectorSpace<Scalar>(tpetraMap_);
272 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
282 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
290 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
293 return tpetraMap_.is_null () ?
static_cast<Ordinal> (0) :
294 static_cast<Ordinal> (tpetraMap_->getNodeNumElements ());
300 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
311 #endif // THYRA_TPETRA_VECTOR_SPACE_HPP