Thyra Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
Thyra_TpetraVectorSpace_def.hpp
Go to the documentation of this file.
1// @HEADER
2// ***********************************************************************
3//
4// Thyra: Interfaces and Support for Abstract Numerical Algorithms
5// Copyright (2004) Sandia Corporation
6//
7// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8// license for use of this work by or on behalf of the U.S. Government.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// 3. Neither the name of the Corporation nor the names of the
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36//
37// Questions? Contact Roscoe A. Bartlett (bartlettra@ornl.gov)
38//
39// ***********************************************************************
40// @HEADER
41
42
43#ifndef THYRA_TPETRA_VECTOR_SPACE_HPP
44#define THYRA_TPETRA_VECTOR_SPACE_HPP
45
46
52#include "Tpetra_Details_StaticView.hpp"
53
54namespace Thyra {
55
56
57template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
60{
61 const RCP<this_t> vs(new this_t);
62 vs->weakSelfPtr_ = vs.create_weak();
63 return vs;
64}
65
66
67template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
69 const RCP<const Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > &tpetraMap
70 )
71{
72 comm_ = convertTpetraToThyraComm(tpetraMap->getComm());
73 tpetraMap_ = tpetraMap;
74 this->updateState(tpetraMap->getGlobalNumElements(),
75 !tpetraMap->isDistributed());
77}
78
79
80// Utility functions
81
82
83template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
87{
89 Tpetra::createLocalMapWithNode<LocalOrdinal,GlobalOrdinal,Node>(
90 size, tpetraMap_->getComm() ) );
91}
92
93
94// Overridden from VectorSpace
95
96
97template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
100{
102 weakSelfPtr_.create_strong().getConst(),
104 new Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node>(tpetraMap_, false)
105 )
106 );
107}
108
109
110template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
113{
115 weakSelfPtr_.create_strong().getConst(),
116 this->createLocallyReplicatedVectorSpace(numMembers),
118 new Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>(
119 tpetraMap_, numMembers, false)
120 )
121 );
122}
123
124
125template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
127public:
128 CopyTpetraMultiVectorViewBack( RCP<MultiVectorBase<Scalar> > mv, const RTOpPack::SubMultiVectorView<Scalar> &raw_mv )
129 :mv_(mv), raw_mv_(raw_mv)
130 {
131 RCP<Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > tmv = Teuchos::rcp_dynamic_cast<TpetraMultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(mv_,true)->getTpetraMultiVector();
132 bool inUse = Teuchos::get_extra_data<bool>(tmv,"inUse");
134 std::runtime_error,
135 "Cannot use the cached vector simultaneously more than once.");
136 inUse = true;
137 Teuchos::set_extra_data(inUse,"inUse",Teuchos::outArg(tmv), Teuchos::POST_DESTROY, false);
138 }
140 {
142 mv_->acquireDetachedView(Range1D(),Range1D(),&smv);
143 RTOpPack::assign_entries<Scalar>( Teuchos::outArg(raw_mv_), smv );
144 mv_->releaseDetachedView(&smv);
145 bool inUse = false;
146 RCP<Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > tmv = Teuchos::rcp_dynamic_cast<TpetraMultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(mv_,true)->getTpetraMultiVector();
147 Teuchos::set_extra_data(inUse,"inUse",Teuchos::outArg(tmv), Teuchos::POST_DESTROY, false);
148 }
149private:
152};
153
154
155template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
158 const RTOpPack::SubMultiVectorView<Scalar> &raw_mv ) const
159{
160#ifdef TEUCHOS_DEBUG
161 TEUCHOS_TEST_FOR_EXCEPT( raw_mv.subDim() != this->dim() );
162#endif
163
164 // Create a multi-vector
166 if (!tpetraMap_->isDistributed()) {
167
168 if (tpetraMV_.is_null() || (tpetraMV_->getNumVectors() != size_t (raw_mv.numSubCols()))) {
169 if (!tpetraMV_.is_null())
170 // The MV is already allocated. If we are still using it, then very bad things can happen.
171 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::get_extra_data<bool>(tpetraMV_,"inUse"),
172 std::runtime_error,
173 "Cannot use the cached vector simultaneously more than once.");
174 using IST = typename Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>::impl_scalar_type;
175 using DT = typename Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>::device_type;
176 auto dv = ::Tpetra::Details::getStatic2dDualView<IST, DT> (tpetraMap_->getGlobalNumElements(), raw_mv.numSubCols());
177 tpetraMV_ = Teuchos::rcp(new Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>(tpetraMap_, dv));
178 bool inUse = false;
179 Teuchos::set_extra_data(inUse,"inUse",Teuchos::outArg(tpetraMV_));
180 }
181
182 if (tpetraDomainSpace_.is_null() || raw_mv.numSubCols() != tpetraDomainSpace_->localSubDim())
183 tpetraDomainSpace_ = tpetraVectorSpace<Scalar>(Tpetra::createLocalMapWithNode<LocalOrdinal, GlobalOrdinal, Node>(raw_mv.numSubCols(), tpetraMap_->getComm()));
184
185 mv = tpetraMultiVector<Scalar>(weakSelfPtr_.create_strong().getConst(), tpetraDomainSpace_, tpetraMV_);
186 } else {
187 mv = this->createMembers(raw_mv.numSubCols());
188 bool inUse = false;
189 RCP<Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > tmv = Teuchos::rcp_dynamic_cast<TpetraMultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(mv,true)->getTpetraMultiVector();
190 Teuchos::set_extra_data(inUse,"inUse",Teuchos::outArg(tmv));
191 }
192 // Copy initial values in raw_mv into multi-vector
194 mv->acquireDetachedView(Range1D(),Range1D(),&smv);
196 Ptr<const RTOpPack::SubMultiVectorView<Scalar> >(Teuchos::outArg(smv)),
197 raw_mv
198 );
199 mv->commitDetachedView(&smv);
200 // Setup smart pointer to multi-vector to copy view back out just before multi-vector is destroyed
201 Teuchos::set_extra_data(
202 // We create a duplicate of the RCP, otherwise the ref count does not go to zero.
204 "CopyTpetraMultiVectorViewBack",
205 Teuchos::outArg(mv),
207 );
208 return mv;
209}
210
211
212template<class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
216{
217#ifdef TEUCHOS_DEBUG
218 TEUCHOS_TEST_FOR_EXCEPT( raw_mv.subDim() != this->dim() );
219#endif
220 // Create a multi-vector
222 if (!tpetraMap_->isDistributed()) {
223 if (tpetraMV_.is_null() || (tpetraMV_->getNumVectors() != size_t (raw_mv.numSubCols()))) {
224 if (!tpetraMV_.is_null())
225 // The MV is already allocated. If we are still using it, then very bad things can happen.
226 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::get_extra_data<bool>(tpetraMV_,"inUse"),
227 std::runtime_error,
228 "Cannot use the cached vector simultaneously more than once.");
229 using IST = typename Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>::impl_scalar_type;
230 using DT = typename Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>::device_type;
231 auto dv = ::Tpetra::Details::getStatic2dDualView<IST, DT> (tpetraMap_->getGlobalNumElements(), raw_mv.numSubCols());
232 tpetraMV_ = Teuchos::rcp(new Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>(tpetraMap_, dv));
233 bool inUse = false;
234 Teuchos::set_extra_data(inUse,"inUse",Teuchos::outArg(tpetraMV_));
235 }
236
237 if (tpetraDomainSpace_.is_null() || raw_mv.numSubCols() != tpetraDomainSpace_->localSubDim())
238 tpetraDomainSpace_ = tpetraVectorSpace<Scalar>(Tpetra::createLocalMapWithNode<LocalOrdinal, GlobalOrdinal, Node>(raw_mv.numSubCols(), tpetraMap_->getComm()));
239
240 mv = tpetraMultiVector<Scalar>(weakSelfPtr_.create_strong().getConst(), tpetraDomainSpace_, tpetraMV_);
241 } else {
242 mv = this->createMembers(raw_mv.numSubCols());
243 bool inUse = false;
244 RCP<Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > tmv = Teuchos::rcp_dynamic_cast<TpetraMultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(mv,true)->getTpetraMultiVector();
245 Teuchos::set_extra_data(inUse,"inUse",Teuchos::outArg(tmv));
246 }
247 // Copy values in raw_mv into multi-vector
249 mv->acquireDetachedView(Range1D(),Range1D(),&smv);
251 Ptr<const RTOpPack::SubMultiVectorView<Scalar> >(Teuchos::outArg(smv)),
252 raw_mv );
253 mv->commitDetachedView(&smv);
254 return mv;
255}
256
257
258template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
260 const Range1D& rng_in, const EViewType viewType, const EStrideType strideType
261 ) const
262{
263 const Range1D rng = full_range(rng_in,0,this->dim()-1);
264 const Ordinal l_localOffset = this->localOffset();
265
266 const Ordinal myLocalSubDim = tpetraMap_.is_null () ?
267 static_cast<Ordinal> (0) : tpetraMap_->getLocalNumElements ();
268
269 return ( l_localOffset<=rng.lbound() && rng.ubound()<l_localOffset+myLocalSubDim );
270}
271
272
273template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
279
280template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
286
287// Overridden from SpmdVectorSpaceDefaultBase
288
289
290template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
296
297
298template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
300{
301 return tpetraMap_.is_null () ? static_cast<Ordinal> (0) :
302 static_cast<Ordinal> (tpetraMap_->getLocalNumElements ());
303}
304
305// private
306
307
308template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
310{
311 // The base classes should automatically default initialize to a safe
312 // uninitialized state.
313}
314
315
316} // end namespace Thyra
317
318
319#endif // THYRA_TPETRA_VECTOR_SPACE_HPP
RCP< T > create_weak() const
CopyTpetraMultiVectorViewBack(RCP< MultiVectorBase< Scalar > > mv, const RTOpPack::SubMultiVectorView< Scalar > &raw_mv)
const RTOpPack::SubMultiVectorView< Scalar > raw_mv_
RCP< const TpetraEuclideanScalarProd< Scalar, LocalOrdinal, GlobalOrdinal, Node > > tpetraEuclideanScalarProd()
Nonmember constructor for TpetraEuclideanScalarProd.
RCP< TpetraMultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > tpetraMultiVector(const RCP< const TpetraVectorSpace< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &tpetraVectorSpace, const RCP< const ScalarProdVectorSpaceBase< Scalar > > &domainSpace, const RCP< Tpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &tpetraMultiVector)
Nonmember constructor for non-const TpetraMultiVector.
Concrete implementation of an SPMD vector space for Tpetra.
TpetraVectorSpace< Scalar, LocalOrdinal, GlobalOrdinal, Node > this_t
RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getTpetraMap() const
Get the embedded Tpetra::Map.
RCP< TpetraVectorSpace< Scalar, LocalOrdinal, GlobalOrdinal, Node > > tpetraVectorSpace(const RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > &tpetraMap)
Nonmember constructor that creats a serial vector space.
bool hasInCoreView(const Range1D &rng, const EViewType viewType, const EStrideType strideType) const
Returns true if all the elements in rng are in this process.
void initialize(const RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > &tpetraMap)
Initialize a serial space.
RCP< MultiVectorBase< Scalar > > createCachedMembersView(const RTOpPack::SubMultiVectorView< Scalar > &raw_mv) const
RCP< const VectorSpaceBase< Scalar > > clone() const
RCP< VectorBase< Scalar > > createMember() const
RCP< const Teuchos::Comm< Ordinal > > comm_
RCP< MultiVectorBase< Scalar > > createMembers(int numMembers) const
RCP< const Teuchos::Comm< Ordinal > > getComm() const
RCP< TpetraVectorSpace< Scalar, LocalOrdinal, GlobalOrdinal, Node > > tpetraDomainSpace_
RCP< Tpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > tpetraMV_
RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > tpetraMap_
static RCP< TpetraVectorSpace< Scalar, LocalOrdinal, GlobalOrdinal, Node > > create()
Create with weak ownership to self.
RCP< TpetraVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > tpetraVector(const RCP< const TpetraVectorSpace< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &tpetraVectorSpace, const RCP< Tpetra::Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &tpetraVector)
Nonmember constructor for TpetraVector.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void assign_entries(const Ptr< const SubVectorView< Scalar > > &msv, const ConstSubVectorView< Scalar > &sv)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
RCP< const Teuchos::Comm< Ordinal > > convertTpetraToThyraComm(const RCP< const Teuchos::Comm< int > > &tpetraComm)
Given an Tpetra Teuchos::Comm<int> object, return an equivalent Teuchos::Comm<Ordinal> object.