MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_ProductOperator_decl.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 MUELU_PRODUCTOPERATOR_DECL_HPP
11#define MUELU_PRODUCTOPERATOR_DECL_HPP
12
13#include "Teuchos_RCP.hpp"
14#include "Xpetra_Map.hpp"
15#include "Xpetra_MultiVector.hpp"
16#include "Xpetra_MultiVectorFactory.hpp"
17#include "Xpetra_Operator.hpp"
18
19#include "Xpetra_Utils.hpp"
20
21namespace MueLu {
22
24
29template <class Scalar,
30 class LocalOrdinal,
31 class GlobalOrdinal,
32 class Node = Tpetra::KokkosClassic::DefaultNode::DefaultNodeType>
33class ProductOperator : public Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> {
34 public:
36
38 virtual const Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> getDomainMap() const {
39 return (modes_[ops_.size() - 1] == Teuchos::NO_TRANS) ? ops_[ops_.size() - 1]->getDomainMap() : ops_[ops_.size() - 1]->getRangeMap();
40 }
41
43 virtual const Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> getRangeMap() const {
44 return (modes_[0] == Teuchos::NO_TRANS) ? ops_[0]->getRangeMap() : ops_[0]->getDomainMap();
45 }
46
48
53 virtual void
54 apply(const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> &X,
55 Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> &Y,
56 Teuchos::ETransp mode = Teuchos::NO_TRANS,
57 Scalar alpha = Teuchos::ScalarTraits<Scalar>::one(),
58 Scalar beta = Teuchos::ScalarTraits<Scalar>::zero()) const;
59
61 virtual bool hasTransposeApply() const {
62 return true;
63 }
64
66
68
69
71 std::string description() const {
72 std::string descr("");
73 for (auto it = ops_.begin(); it != ops_.end(); ++it) {
74 descr += (*it)->description();
75 }
76 return descr;
77 }
78
80 void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel = Teuchos::Describable::verbLevel_default) const {
81 for (auto it = ops_.begin(); it != ops_.end(); ++it) {
82 (*it)->describe(out, verbLevel);
83 }
84 }
85
87
89
90
91 ProductOperator() = default;
92
94 ProductOperator(std::vector<Teuchos::RCP<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>> ops,
95 std::vector<Teuchos::ETransp> modes)
96 : ops_(ops)
97 , modes_(modes) {
98 TEUCHOS_ASSERT(ops_.size() >= 1);
99 TEUCHOS_ASSERT(modes_.size() == ops_.size());
100
101 CheckMaps();
102 AllocateTemporaryMultiVectors(/*NumVectors=*/1);
103 }
104
105 ProductOperator(std::vector<Teuchos::RCP<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>> ops)
106 : ops_(ops) {
107 TEUCHOS_ASSERT(ops_.size() >= 1);
108
109 for (auto it = ops_.begin(); it != ops_.end(); ++it) {
110 modes_.push_back(Teuchos::NO_TRANS);
111 }
112
113 CheckMaps();
114 AllocateTemporaryMultiVectors(/*NumVectors=*/1);
115 }
116
117 void CheckMaps() {
118 for (size_t i = 0; i < ops_.size() - 1; ++i) {
119 auto mapLeftOp = (modes_[i] == Teuchos::NO_TRANS) ? ops_[i]->getDomainMap() : ops_[i]->getRangeMap();
120 auto mapRightOp = (modes_[i + 1] == Teuchos::NO_TRANS) ? ops_[i + 1]->getRangeMap() : ops_[i + 1]->getDomainMap();
121 TEUCHOS_ASSERT(mapLeftOp->isSameAs(*mapRightOp));
122 }
123 }
124
125 void AllocateTemporaryMultiVectors(size_t NumVectors) const {
126 if ((tempVecs_.size() == 0) || (tempVecs_[0]->getNumVectors() != NumVectors)) {
127 tempVecs_.resize(0);
128 for (size_t i = 0; i < ops_.size() - 1; ++i) {
129 auto map = (modes_[i] == Teuchos::NO_TRANS) ? ops_[i]->getDomainMap() : ops_[i]->getRangeMap();
130 tempVecs_.push_back(Xpetra::MultiVectorFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(map, NumVectors));
131 }
132 }
133 }
134
136 void residual(const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> &X,
137 const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> &B,
138 Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> &R) const {
139 const auto one = Teuchos::ScalarTraits<Scalar>::one();
140 const auto zero = Teuchos::ScalarTraits<Scalar>::zero();
141
142 apply(X, R, Teuchos::NO_TRANS, one, zero);
143 R.update(one, B, -one);
144 }
145
147
148 private:
149 std::vector<Teuchos::RCP<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>> ops_;
150 std::vector<Teuchos::ETransp> modes_;
151 mutable std::vector<Teuchos::RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>> tempVecs_;
152
153}; // ProductOperator class
154
155} // namespace MueLu
156
157#define MUELU_PRODUCTOPERATOR_SHORT
158#endif
MueLu::DefaultLocalOrdinal LocalOrdinal
MueLu::DefaultScalar Scalar
MueLu::DefaultGlobalOrdinal GlobalOrdinal
MueLu::DefaultNode Node
Takes a sequence of operators and applies their product.
virtual bool hasTransposeApply() const
Whether this operator supports applying the transpose or conjugate transpose.
virtual const Teuchos::RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getDomainMap() const
The Map associated with the domain of this operator, which must be compatible with X....
void residual(const Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &X, const Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &B, Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &R) const
Compute a residual R = B - (*this) * X.
ProductOperator(std::vector< Teuchos::RCP< Xpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > > ops)
virtual void apply(const Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &X, Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, Scalar alpha=Teuchos::ScalarTraits< Scalar >::one(), Scalar beta=Teuchos::ScalarTraits< Scalar >::zero()) const
Computes the operator-multivector application.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with the given verbosity level to a FancyOStream.
std::string description() const
A simple one-line description of this object.
virtual const Teuchos::RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getRangeMap() const
The Map associated with the range of this operator, which must be compatible with Y....
std::vector< Teuchos::ETransp > modes_
std::vector< Teuchos::RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > > tempVecs_
ProductOperator(std::vector< Teuchos::RCP< Xpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > > ops, std::vector< Teuchos::ETransp > modes)
TpetraOperator constructor to wrap a Tpetra::Operator object.
void AllocateTemporaryMultiVectors(size_t NumVectors) const
std::vector< Teuchos::RCP< Xpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > > ops_
Namespace for MueLu classes and methods.