Thyra Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
Thyra_TpetraLinearOp_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#ifndef THYRA_TPETRA_LINEAR_OP_HPP
43#define THYRA_TPETRA_LINEAR_OP_HPP
44
49
50#include "Tpetra_CrsMatrix.hpp"
51
52#ifdef HAVE_THYRA_TPETRA_EPETRA
54#endif
55
56namespace Thyra {
57
58
59#ifdef HAVE_THYRA_TPETRA_EPETRA
60
61// Utilites
62
63
65 template<class Scalar, class LocalOrdinal, class GlobalOrdinal>
66class GetTpetraEpetraRowMatrixWrapper {
67public:
68 template<class TpetraMatrixType>
69 static
72 {
73 return Teuchos::null;
74 }
75};
76
77
78// NOTE: We could support other ordinal types, but we have to
79// specialize the EpetraRowMatrix
80template<>
81class GetTpetraEpetraRowMatrixWrapper<double, int, int> {
82public:
83 template<class TpetraMatrixType>
84 static
87 {
88 return Teuchos::rcp(
89 new Tpetra::EpetraRowMatrix<TpetraMatrixType>(tpetraMatrix,
91 *convertTpetraToThyraComm(tpetraMatrix->getRowMap()->getComm())
92 )
93 )
94 );
95 }
96};
97
98
99#endif // HAVE_THYRA_TPETRA_EPETRA
100
101
102template <class Scalar>
103inline
106{
109 Exceptions::OpNotSupported,
110 "For complex scalars such as " + Teuchos::TypeNameTraits<Scalar>::name() +
111 ", Tpetra does not support conjugation without transposition."
112 );
113 return Teuchos::NO_TRANS; // For non-complex scalars, CONJ is equivalent to NOTRANS.
114}
115
116
117template <class Scalar>
118inline
121{
122 switch (transp) {
123 case NOTRANS: return Teuchos::NO_TRANS;
125 case TRANS: return Teuchos::TRANS;
126 case CONJTRANS: return Teuchos::CONJ_TRANS;
127 }
128
129 // Should not escape the switch
131}
132
133
134// Constructors/initializers
135
136
137template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
140
141
142template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
146 const RCP<Tpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node> > &tpetraOperator
147 )
148{
149 initializeImpl(rangeSpace, domainSpace, tpetraOperator);
150}
151
152
153template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
157 const RCP<const Tpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node> > &tpetraOperator
158 )
159{
160 initializeImpl(rangeSpace, domainSpace, tpetraOperator);
161}
162
163
164template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
167{
168 return tpetraOperator_.getNonconstObj();
169}
170
171
172template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
178
179
180// Public Overridden functions from LinearOpBase
181
182
183template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
189
190
191template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
194{
195 return domainSpace_;
196}
197
198
199// Overridden from EpetraLinearOpBase
200
201
202#ifdef HAVE_THYRA_TPETRA_EPETRA
203
204
205template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
207 const Ptr<RCP<Epetra_Operator> > &epetraOp,
211 )
212{
214}
215
216
217template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
218void TpetraLinearOp<Scalar,LocalOrdinal,GlobalOrdinal,Node>::getEpetraOpView(
219 const Ptr<RCP<const Epetra_Operator> > &epetraOp,
220 const Ptr<EOpTransp> &epetraOpTransp,
221 const Ptr<EApplyEpetraOpAs> &epetraOpApplyAs,
222 const Ptr<EAdjointEpetraOp> &epetraOpAdjointSupport
223 ) const
224{
225 using Teuchos::rcp_dynamic_cast;
226 typedef Tpetra::RowMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpetraRowMatrix_t;
227 if (nonnull(tpetraOperator_)) {
228 if (is_null(epetraOp_)) {
229 epetraOp_ = GetTpetraEpetraRowMatrixWrapper<Scalar,LocalOrdinal,GlobalOrdinal>::get(
230 rcp_dynamic_cast<const TpetraRowMatrix_t>(tpetraOperator_.getConstObj(), true));
231 }
235 *epetraOpAdjointSupport = ( tpetraOperator_->hasTransposeApply()
237 }
238 else {
239 *epetraOp = Teuchos::null;
240 }
241}
242
243
244#endif // HAVE_THYRA_TPETRA_EPETRA
245
246
247// Protected Overridden functions from LinearOpBase
248
249
250template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
253{
254 if (is_null(tpetraOperator_))
255 return false;
256
257 if (M_trans == NOTRANS)
258 return true;
259
260 if (M_trans == CONJ) {
261 // For non-complex scalars, CONJ is always supported since it is equivalent to NO_TRANS.
262 // For complex scalars, Tpetra does not support conjugation without transposition.
264 }
265
266 return tpetraOperator_->hasTransposeApply();
267}
268
269
270template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
275 const Scalar alpha,
276 const Scalar beta
277 ) const
278{
279 using Teuchos::rcpFromRef;
280 using Teuchos::rcpFromPtr;
283 typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>
284 TpetraMultiVector_t;
285
286 // Get Tpetra::MultiVector objects for X and Y
287
289 ConverterT::getConstTpetraMultiVector(rcpFromRef(X_in));
290
292 ConverterT::getTpetraMultiVector(rcpFromPtr(Y_inout));
293
295
296 // Apply the operator
297
298 tpetraOperator_->apply(*tX, *tY, tTransp, alpha, beta);
299 Kokkos::fence();
300}
301
302// Protected member functions overridden from ScaledLinearOpBase
303
304
305template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
310
311
312template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
317
318
319template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
320void
335
336
337template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
338void
353
354// Protected member functions overridden from RowStatLinearOpBase
355
356
357template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
360 const RowStatLinearOpBaseUtils::ERowStat rowStat) const
361{
362 if (is_null(tpetraOperator_))
363 return false;
364
365 switch (rowStat) {
366 case RowStatLinearOpBaseUtils::ROW_STAT_INV_ROW_SUM:
367 case RowStatLinearOpBaseUtils::ROW_STAT_ROW_SUM:
368 return true;
369 default:
370 return false;
371 }
372
373}
374
375
376template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
378 const RowStatLinearOpBaseUtils::ERowStat rowStat,
380 ) const
381{
382 typedef Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node>
385 typedef typename STS::magnitudeType MT;
387
388 if ( (rowStat == RowStatLinearOpBaseUtils::ROW_STAT_INV_ROW_SUM) ||
389 (rowStat == RowStatLinearOpBaseUtils::ROW_STAT_ROW_SUM) ) {
390
391 TEUCHOS_ASSERT(nonnull(tpetraOperator_));
393
394 // Currently we only support the case of row sums for a concrete
395 // Tpetra::CrsMatrix where (1) the entire row is stored on a
396 // single process and (2) that the domain map, the range map and
397 // the row map are the SAME. These checks enforce that. Later on
398 // we hope to add complete support for any mapping to the concrete
399 // tpetra matrix types.
400
403
406
407 // EGP: The following assert fails when row sum scaling is applied to blocked Tpetra operators, but without the assert, the correct row sum scaling is obtained.
408 // Furthermore, no valgrind memory errors occur in this case when the assert is removed.
409 //TEUCHOS_ASSERT(tCrsMatrix->getRowMap()->isSameAs(*tCrsMatrix->getDomainMap()));
410 TEUCHOS_ASSERT(tCrsMatrix->getRowMap()->isSameAs(*tCrsMatrix->getRangeMap()));
411 TEUCHOS_ASSERT(tCrsMatrix->getRowMap()->isSameAs(*tRowSumVec->getMap()));
412
413 size_t numMyRows = tCrsMatrix->getLocalNumRows();
414
415 using crs_t = Tpetra::CrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>;
416 typename crs_t::local_inds_host_view_type indices;
417 typename crs_t::values_host_view_type values;
418
419
420 for (size_t row=0; row < numMyRows; ++row) {
421 MT sum = STM::zero ();
422 tCrsMatrix->getLocalRowView (row, indices, values);
423
424 for (int col = 0; col < (int) values.size(); ++col) {
425 sum += STS::magnitude (values[col]);
426 }
427
428 if (rowStat == RowStatLinearOpBaseUtils::ROW_STAT_INV_ROW_SUM) {
429 if (sum < STM::sfmin ()) {
430 TEUCHOS_TEST_FOR_EXCEPTION(sum == STM::zero (), std::runtime_error,
431 "Error - Thyra::TpetraLinearOp::getRowStatImpl() - Inverse row sum "
432 << "requested for a matrix where one of the rows has a zero row sum!");
433 sum = STM::one () / STM::sfmin ();
434 }
435 else {
436 sum = STM::one () / sum;
437 }
438 }
439
440 tRowSumVec->replaceLocalValue (row, Scalar (sum));
441 }
442
443 }
444 else {
445 TEUCHOS_TEST_FOR_EXCEPTION(true,std::runtime_error,
446 "Error - Thyra::TpetraLinearOp::getRowStatImpl() - Column sum support not implemented!");
447 }
448 Kokkos::fence();
449}
450
451
452// private
453
454
455template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
456template<class TpetraOperator_t>
461 )
462{
463#ifdef THYRA_DEBUG
467 // ToDo: Assert that spaces are comparible with tpetraOperator
468#endif
469 rangeSpace_ = rangeSpace;
470 domainSpace_ = domainSpace;
471 tpetraOperator_ = tpetraOperator;
472}
473
474
475} // namespace Thyra
476
477
478#endif // THYRA_TPETRA_LINEAR_OP_HPP
RCP< T > rcpFromPtr(const Ptr< T > &ptr)
RCP< T > rcpFromRef(T &r)
bool is_null() const
RCP(T *p, const RCPNodeHandle &node)
bool nonnull(const RCP< T > &p)
T * get() const
Concrete Thyra::LinearOpBase subclass for Tpetra::Operator.
TpetraLinearOp()
Construct to uninitialized.
Traits class that enables the extraction of Tpetra operator/vector objects wrapped in Thyra operator/...
RCP< const Epetra_Comm > get_Epetra_Comm(const Teuchos::Comm< Ordinal > &comm)
Get (or create) and Epetra_Comm given a Teuchos::Comm object.
@ EPETRA_OP_APPLY_APPLY
Apply using Epetra_Operator::Apply(...)
@ EPETRA_OP_ADJOINT_UNSUPPORTED
Adjoint not supported.
@ EPETRA_OP_ADJOINT_SUPPORTED
Adjoint supported.
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::ETransp convertConjNoTransToTeuchosTransMode()
Teuchos::ETransp convertToTeuchosTransMode(const Thyra::EOpTransp transp)
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.