Teko Version of the Day
Loading...
Searching...
No Matches
Teko_LU2x2InverseOp.cpp
1// @HEADER
2// *****************************************************************************
3// Teko: A package for block and physics based preconditioning
4//
5// Copyright 2010 NTESS and the Teko contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
11
12#include "Thyra_DefaultProductVectorSpace.hpp"
13#include "Thyra_ProductMultiVectorBase.hpp"
14#include "Thyra_DefaultMultipliedLinearOp.hpp"
15#include "Thyra_MultiVectorStdOps.hpp"
16
17using namespace Thyra;
18using Teuchos::ArrayRCP;
19using Teuchos::dyn_cast;
20using Teuchos::RCP;
21
22namespace Teko {
23
24// Thyra::LinearOpBase requirements
26LU2x2InverseOp::LU2x2InverseOp(const BlockedLinearOp& A, const LinearOp& invA00,
27 const LinearOp& invS)
28 : A_(A),
29 hatInvA00_(invA00),
30 tildeInvA00_(invA00),
31 invS_(invS),
32 A10_(A->getBlock(1, 0)),
33 A01_(A->getBlock(0, 1)) {
34 using Teuchos::tuple;
35 using Thyra::productVectorSpace;
36
37 // create and store range space
38 productRange_ = productVectorSpace<double>(tuple(hatInvA00_->range(), invS_->range())());
39
40 // create and store domain space
41 productDomain_ = productVectorSpace<double>(tuple(hatInvA00_->domain(), invS_->domain())());
42}
43
55LU2x2InverseOp::LU2x2InverseOp(const BlockedLinearOp& A, const LinearOp& hatInvA00,
56 const LinearOp& tildeInvA00, const LinearOp& invS)
57 : A_(A),
58 hatInvA00_(hatInvA00),
59 tildeInvA00_(tildeInvA00),
60 invS_(invS),
61 A10_(A->getBlock(1, 0)),
62 A01_(A->getBlock(0, 1)) {
63 using Teuchos::tuple;
64 using Thyra::productVectorSpace;
65
66 // create and store range space
67 productRange_ = productVectorSpace<double>(tuple(hatInvA00_->range(), invS_->range())());
68
69 // create and store domain space
70 productDomain_ = productVectorSpace<double>(tuple(hatInvA00_->domain(), invS_->domain()));
71}
72
73void LU2x2InverseOp::implicitApply(const BlockedMultiVector& x, BlockedMultiVector& y,
74 const double alpha, const double beta) const {
75 // get src blocks
76 MultiVector f = getBlock(0, x); // f
77 MultiVector g = getBlock(1, x); // g
78
79 // get extra storage
80 MultiVector ps = deepcopy(g); // this is need b/c of p = -inv(S)*p
81
82 // get destination blocks
83 MultiVector u = getBlock(0, y); // u (u^)
84 MultiVector p = getBlock(1, y); // p (p^)
85
86 // for efficiency make copies of u and p
87 MultiVector uc, pc; // copies of u and p
88 if (beta != 0) {
89 // perform a deep copy
90 uc = deepcopy(u);
91 pc = deepcopy(p);
92 } else {
93 // perform a shallow copy
94
95 // uc and pc point
96 // to the data of u and p
97 uc = u;
98 pc = p;
99 }
100
101 // set temporary operator for performing inv(A_00)*A_01
102 LinearOp invA00_A01 = Thyra::multiply(tildeInvA00_, A01_);
103
104 // compute actual product
105 applyOp(hatInvA00_, f, uc); // u = inv(A_00) * f
106 applyOp(A10_, uc, ps, -1.0, 1.0); // ps += -A_10*u
107 applyOp(invS_, ps, pc, -1.0); // p = -inv(S)*ps
108 applyOp(invA00_A01, pc, uc, -1.0, 1.0); // u += -inv(A_00)*A_01*p
109
110 // scale result by alpha
111 if (beta != 0) {
112 update(alpha, uc, beta, u); // u = alpha * uc + beta * u
113 update(alpha, pc, beta, p); // p = alpha * pc + beta * p
114 } else if (alpha != 1.0) {
115 scale(alpha, u); // u = alpha * u
116 scale(alpha, p); // p = alpha * p
117 }
118}
119
120void LU2x2InverseOp::describe(Teuchos::FancyOStream& out_arg,
121 const Teuchos::EVerbosityLevel verbLevel) const {
122 using Teuchos::OSTab;
123
124 RCP<Teuchos::FancyOStream> out = rcp(&out_arg, false);
125 OSTab tab(out);
126 switch (verbLevel) {
127 case Teuchos::VERB_DEFAULT:
128 case Teuchos::VERB_LOW: *out << this->description() << std::endl; break;
129 case Teuchos::VERB_MEDIUM:
130 case Teuchos::VERB_HIGH:
131 case Teuchos::VERB_EXTREME: {
132 *out << Teuchos::Describable::description() << "{"
133 << "rangeDim=" << this->range()->dim() << ",domainDim=" << this->domain()->dim()
134 << "}\n";
135 {
136 *out << "[invS]:\n";
137 *out << Teuchos::describe(*invS_, verbLevel);
138
139 *out << "[hatInvA00]:\n";
140 *out << Teuchos::describe(*hatInvA00_, verbLevel);
141
142 *out << "[tildeInvA00]:\n";
143 *out << Teuchos::describe(*tildeInvA00_, verbLevel);
144
145 *out << "[A_10]:\n";
146 *out << Teuchos::describe(*A10_, verbLevel);
147
148 *out << "[A_01]:\n";
149 *out << Teuchos::describe(*A01_, verbLevel);
150 }
151 break;
152 }
153 default: TEUCHOS_TEST_FOR_EXCEPT(true); // Should never get here!
154 }
155}
156
157} // end namespace Teko
MultiVector getBlock(int i, const BlockedMultiVector &bmv)
Get the ith block from a BlockedMultiVector object.
MultiVector deepcopy(const MultiVector &v)
Perform a deep copy of the vector.
const LinearOp hatInvA00_
inverse of
virtual void implicitApply(const BlockedMultiVector &x, BlockedMultiVector &y, const double alpha=1.0, const double beta=0.0) const
Perform a matrix vector multiply with this operator.
const LinearOp tildeInvA00_
inverse of
Teuchos::RCP< const Thyra::ProductVectorSpaceBase< double > > productDomain_
Domain vector space.
virtual VectorSpace domain() const
Domain space of this operator.
Teuchos::RCP< const Thyra::ProductVectorSpaceBase< double > > productRange_
Range vector space.
const LinearOp invS_
inverse of
virtual VectorSpace range() const
Range space of this operator.
const LinearOp A01_
operator
const LinearOp A10_
operator
LU2x2InverseOp(const BlockedLinearOp &A, const LinearOp &invA00, const LinearOp &invS)
This constructor explicitly takes the parts of required to build the inverse operator.
const BlockedLinearOp A_
operator