Teko  Version of the Day
 All Classes Files Functions Variables Pages
Teko_BlockDiagonalInverseOp.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_BlockDiagonalInverseOp.hpp"
11 
12 #include "Teuchos_Utils.hpp"
13 
14 namespace Teko {
15 
16 using Teuchos::RCP;
17 
18 BlockDiagonalInverseOp::BlockDiagonalInverseOp(BlockedLinearOp& A,
19  const std::vector<LinearOp>& invDiag)
20  : invDiag_(invDiag) {
21  // sanity check
22  int blocks = blockRowCount(A);
23  TEUCHOS_ASSERT(blocks > 0);
24  TEUCHOS_ASSERT(blocks == blockColCount(A));
25  TEUCHOS_ASSERT(blocks == (int)invDiag_.size());
26 
27  // create the range and product space
29 
30  // just flip flop them!
31  productRange_ = A->productDomain();
32  productDomain_ = A->productRange();
33 }
34 
35 void BlockDiagonalInverseOp::implicitApply(const BlockedMultiVector& src, BlockedMultiVector& dst,
36  const double alpha, const double beta) const {
37  // call the no tranpose version
38  implicitApply(Thyra::NOTRANS, src, dst, alpha, beta);
39 }
40 
41 void BlockDiagonalInverseOp::implicitApply(const Thyra::EOpTransp M_trans,
42  const BlockedMultiVector& src, BlockedMultiVector& dst,
43  const double alpha, const double beta) const {
44  int blocks = blockCount(src);
45 
46  TEUCHOS_ASSERT(blocks == (int)invDiag_.size());
47 
48  if (!allocated) {
49  srcScrap_ = deepcopy(src);
50  dstScrap_ = deepcopy(dst);
51  allocated = true;
52  }
53 
54  // build a scrap vector for storing work
55  Thyra::assign<double>(srcScrap_.ptr(), *src);
56  BlockedMultiVector dstCopy;
57  if (beta != 0.0) {
58  Thyra::assign<double>(dstScrap_.ptr(), *dst);
59  dstCopy = dstScrap_;
60  } else
61  dstCopy = dst; // shallow copy
62 
63  // extract the blocks components from
64  // the source and destination vectors
65  std::vector<MultiVector> dstVec;
66  std::vector<MultiVector> scrapVec;
67  for (int b = 0; b < blocks; b++) {
68  dstVec.push_back(getBlock(b, dstCopy));
69  scrapVec.push_back(getBlock(b, srcScrap_));
70  }
71 
72  if (M_trans == Thyra::NOTRANS) {
73  for (int b = 0; b < blocks; b++) {
74  applyOp(invDiag_[b], scrapVec[b], dstVec[b]);
75  }
76  } else if (M_trans == Thyra::TRANS || M_trans == Thyra::CONJTRANS) {
77  for (int b = 0; b < blocks; b++) {
78  applyTransposeOp(invDiag_[b], scrapVec[b], dstVec[b]);
79  }
80  } else {
81  TEUCHOS_TEST_FOR_EXCEPT(true);
82  }
83 
84  // scale result by alpha
85  if (beta != 0)
86  update(alpha, dstCopy, beta, dst); // dst = alpha * dstCopy + beta * dst
87  else if (alpha != 1.0)
88  scale(alpha, dst); // dst = alpha * dst
89 }
90 
91 void BlockDiagonalInverseOp::describe(Teuchos::FancyOStream& out_arg,
92  const Teuchos::EVerbosityLevel verbLevel) const {
93  using Teuchos::OSTab;
94 
95  RCP<Teuchos::FancyOStream> out = rcp(&out_arg, false);
96  OSTab tab(out);
97  switch (verbLevel) {
98  case Teuchos::VERB_DEFAULT:
99  case Teuchos::VERB_LOW: *out << this->description() << std::endl; break;
100  case Teuchos::VERB_MEDIUM:
101  case Teuchos::VERB_HIGH:
102  case Teuchos::VERB_EXTREME: {
103  *out << Teuchos::Describable::description() << "{"
104  << "rangeDim=" << this->range()->dim() << ",domainDim=" << this->domain()->dim()
105  << ",rows=" << invDiag_.size() << ",cols=" << invDiag_.size() << "}\n";
106  {
107  OSTab tab2(out);
108  *out << "[invDiag Operators]:\n";
109  tab.incrTab();
110  for (auto i = 0U; i < invDiag_.size(); i++) {
111  *out << "[invD(" << i << ")] = ";
112  *out << Teuchos::describe(*invDiag_[i], verbLevel);
113  }
114  }
115  break;
116  }
117  default: TEUCHOS_TEST_FOR_EXCEPT(true); // Should never get here!
118  }
119 }
120 
121 } // end namespace Teko
virtual VectorSpace domain() const
Domain space of this operator.
Teuchos::RCP< const Thyra::ProductVectorSpaceBase< double > > productRange_
Range vector space.
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.
std::vector< LinearOp > invDiag_
(Approximate) Inverses of the diagonal operators
virtual VectorSpace range() const
Range space of this operator.
Teuchos::RCP< const Thyra::ProductVectorSpaceBase< double > > productDomain_
Domain vector space.