MueLu Version of the Day
Loading...
Searching...
No Matches
Thyra_XpetraLinearOp_def.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// MueLu: A package for multigrid based preconditioning
4//
5// Copyright 2012 NTESS and the MueLu contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef THYRA_XPETRA_LINEAR_OP_HPP
11#define THYRA_XPETRA_LINEAR_OP_HPP
12
14#include "Teuchos_ScalarTraits.hpp"
15#include "Teuchos_TypeNameTraits.hpp"
16
18#include "Xpetra_MapExtractor.hpp"
19
20namespace Thyra {
21
22// Constructors/initializers
23
24template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
26
27template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
29
30template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
32 const RCP<const VectorSpaceBase<Scalar> > &rangeSpace,
33 const RCP<const VectorSpaceBase<Scalar> > &domainSpace,
34 const RCP<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> > &xpetraOperator) {
35 initializeImpl(rangeSpace, domainSpace, xpetraOperator);
36}
37
38template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
40 const RCP<const VectorSpaceBase<Scalar> > &rangeSpace,
41 const RCP<const VectorSpaceBase<Scalar> > &domainSpace,
42 const RCP<const Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> > &xpetraOperator) {
43 initializeImpl(rangeSpace, domainSpace, xpetraOperator);
44}
45
46template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
47RCP<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
49 return xpetraOperator_.getNonconstObj();
50}
51
52template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
53RCP<const Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
57
58// Public Overridden functions from LinearOpBase
59
60template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
61RCP<const Thyra::VectorSpaceBase<Scalar> >
65
66template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
67RCP<const Thyra::VectorSpaceBase<Scalar> >
71
72// Protected Overridden functions from LinearOpBase
73
74template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
76 Thyra::EOpTransp M_trans) const {
77 if (is_null(xpetraOperator_))
78 return false;
79
80 if (M_trans == NOTRANS)
81 return true;
82
83 if (M_trans == CONJ) {
84 // For non-complex scalars, CONJ is always supported since it is equivalent to NO_TRANS.
85 // For complex scalars, Xpetra does not support conjugation without transposition.
86 return !Teuchos::ScalarTraits<Scalar>::isComplex;
87 }
88
89 return xpetraOperator_->hasTransposeApply();
90}
91
92template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
94 const Thyra::EOpTransp M_trans,
95 const Thyra::MultiVectorBase<Scalar> &X_in,
96 const Teuchos::Ptr<Thyra::MultiVectorBase<Scalar> > &Y_inout,
97 const Scalar alpha,
98 const Scalar beta) const {
99 using Teuchos::rcpFromPtr;
100 using Teuchos::rcpFromRef;
101
102 TEUCHOS_TEST_FOR_EXCEPTION(getConstXpetraOperator() == Teuchos::null, MueLu::Exceptions::RuntimeError, "XpetraLinearOp::applyImpl: internal Xpetra::Operator is null.");
103 RCP<const Teuchos::Comm<int> > comm = getConstXpetraOperator()->getRangeMap()->getComm();
104
105 const RCP<const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> > tX_in =
106 Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toXpetra(rcpFromRef(X_in), comm);
107 RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> > tY_inout =
108 Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toXpetra(rcpFromPtr(Y_inout), comm);
109 Teuchos::ETransp transp;
110 switch (M_trans) {
111 case NOTRANS: transp = Teuchos::NO_TRANS; break;
112 case TRANS: transp = Teuchos::TRANS; break;
113 case CONJTRANS: transp = Teuchos::CONJ_TRANS; break;
114 default: TEUCHOS_TEST_FOR_EXCEPTION(true, MueLu::Exceptions::NotImplemented, "Thyra::XpetraLinearOp::apply. Unknown value for M_trans. Only NOTRANS, TRANS and CONJTRANS are supported.");
115 }
116
117 xpetraOperator_->apply(*tX_in, *tY_inout, transp, alpha, beta);
118
119 // check whether Y is a product vector
120 RCP<const Xpetra::MapExtractor<Scalar, LocalOrdinal, GlobalOrdinal, Node> > rgMapExtractor = Teuchos::null;
121 Teuchos::Ptr<Thyra::ProductMultiVectorBase<Scalar> > prodY_inout =
122 Teuchos::ptr_dynamic_cast<Thyra::ProductMultiVectorBase<Scalar> >(Y_inout);
123 if (prodY_inout != Teuchos::null) {
124 // If Y is a product vector we split up the data from tY and merge them
125 // into the product vector. The necessary Xpetra::MapExtractor is extracted
126 // from the fine level operator (not this!)
127
128 // get underlying fine level operator (BlockedCrsMatrix)
129 // to extract the range MapExtractor
130 RCP<MueLu::XpetraOperator<Scalar, LocalOrdinal, GlobalOrdinal, Node> > mueXop =
131 Teuchos::rcp_dynamic_cast<MueLu::XpetraOperator<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(xpetraOperator_.getNonconstObj());
132
133 RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > A =
134 mueXop->GetHierarchy()->GetLevel(0)->template Get<RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > >("A");
135 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(A));
136
137 RCP<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > bA =
138 Teuchos::rcp_dynamic_cast<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(A);
139 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(bA));
140
141 rgMapExtractor = bA->getRangeMapExtractor();
142 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(rgMapExtractor));
143 }
144}
145
146// private
147
148template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
149template <class XpetraOperator_t>
151 const RCP<const VectorSpaceBase<Scalar> > &rangeSpace,
152 const RCP<const VectorSpaceBase<Scalar> > &domainSpace,
153 const RCP<XpetraOperator_t> &xpetraOperator) {
154#ifdef THYRA_DEBUG
155 TEUCHOS_ASSERT(nonnull(rangeSpace));
156 TEUCHOS_ASSERT(nonnull(domainSpace));
157 TEUCHOS_ASSERT(nonnull(xpetraOperator));
158#endif
159 rangeSpace_ = rangeSpace;
160 domainSpace_ = domainSpace;
161 xpetraOperator_ = xpetraOperator;
162}
163
164} // namespace Thyra
165
166#endif // THYRA_XPETRA_LINEAR_OP_HPP
MueLu::DefaultScalar Scalar
Exception throws when you call an unimplemented method of MueLu.
Exception throws to report errors in the internal logical of the program.
void applyImpl(const Thyra::EOpTransp M_trans, const Thyra::MultiVectorBase< Scalar > &X_in, const Teuchos::Ptr< Thyra::MultiVectorBase< Scalar > > &Y_inout, const Scalar alpha, const Scalar beta) const
void constInitialize(const RCP< const VectorSpaceBase< Scalar > > &rangeSpace, const RCP< const VectorSpaceBase< Scalar > > &domainSpace, const RCP< const Xpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &xpetraOperator)
Initialize.
RCP< const Thyra::VectorSpaceBase< Scalar > > range() const
RCP< const Thyra::VectorSpaceBase< Scalar > > domain() const
RCP< const Xpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getConstXpetraOperator() const
Get embedded const Xpetra::Operator.
void initialize(const RCP< const VectorSpaceBase< Scalar > > &rangeSpace, const RCP< const VectorSpaceBase< Scalar > > &domainSpace, const RCP< Xpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &xpetraOperator)
Initialize.
RCP< Xpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getXpetraOperator()
Get embedded non-const Xpetra::Operator.
void initializeImpl(const RCP< const VectorSpaceBase< Scalar > > &rangeSpace, const RCP< const VectorSpaceBase< Scalar > > &domainSpace, const RCP< XpetraOperator_t > &xpetraOperator)
bool opSupportedImpl(Thyra::EOpTransp M_trans) const
XpetraLinearOp()
Construct to uninitialized.