Teko  Version of the Day
 All Classes Files Functions Variables Pages
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 
10 #include "Teko_LU2x2InverseOp.hpp"
11 
12 #include "Thyra_DefaultProductVectorSpace.hpp"
13 #include "Thyra_ProductMultiVectorBase.hpp"
14 #include "Thyra_DefaultMultipliedLinearOp.hpp"
15 #include "Thyra_MultiVectorStdOps.hpp"
16 
17 using namespace Thyra;
18 using Teuchos::ArrayRCP;
19 using Teuchos::dyn_cast;
20 using Teuchos::RCP;
21 
22 namespace Teko {
23 
24 // Thyra::LinearOpBase requirements
26 LU2x2InverseOp::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 
55 LU2x2InverseOp::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 
73 void 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 
120 void 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
const LinearOp hatInvA00_
inverse of
Teuchos::RCP< const Thyra::ProductVectorSpaceBase< double > > productRange_
Range vector space.
const LinearOp A01_
operator
Teuchos::RCP< const Thyra::ProductVectorSpaceBase< double > > productDomain_
Domain vector space.
virtual VectorSpace domain() const
Domain space of this operator.
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 invS_
inverse of
virtual VectorSpace range() const
Range space of this operator.
const LinearOp A10_
operator
const LinearOp tildeInvA00_
inverse of