Teko  Version of the Day
 All Classes Files Functions Variables Pages
Teko_BlockLowerTriInverseOp.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_BlockLowerTriInverseOp.hpp"
11 
12 #include "Teuchos_Utils.hpp"
13 
14 namespace Teko {
15 
16 using Teuchos::RCP;
17 
18 BlockLowerTriInverseOp::BlockLowerTriInverseOp(BlockedLinearOp& L,
19  const std::vector<LinearOp>& invDiag)
20  : L_(L) {
21  invDiag_ = invDiag;
22 
23  // sanity check
24  int blocks = blockRowCount(L_);
25  TEUCHOS_ASSERT(blocks > 0);
26  TEUCHOS_ASSERT(blocks == blockColCount(L_));
27  TEUCHOS_ASSERT(blocks == (int)invDiag_.size());
28 
29  // create the range and product space
31 
32  // just flip flop them!
33  productRange_ = L_->productDomain();
34  productDomain_ = L_->productRange();
35 }
36 
49 void BlockLowerTriInverseOp::implicitApply(const BlockedMultiVector& src, BlockedMultiVector& dst,
50  const double alpha, const double beta) const {
51  int blocks = blockCount(src);
52 
53  TEUCHOS_ASSERT(blocks == blockRowCount(L_));
54  TEUCHOS_ASSERT(blocks == blockCount(dst));
55 
56  if (!allocated) {
57  srcScrap_ = deepcopy(src);
58  dstScrap_ = deepcopy(dst);
59  allocated = true;
60  }
61 
62  // build a scrap vector for storing work
63  Thyra::assign<double>(srcScrap_.ptr(), *src);
64  BlockedMultiVector dstCopy;
65  if (beta != 0.0) {
66  Thyra::assign<double>(dstScrap_.ptr(), *dst);
67  dstCopy = dstScrap_;
68  } else
69  dstCopy = dst; // shallow copy
70 
71  // extract the blocks componets from
72  // the source and destination vectors
73  std::vector<MultiVector> dstVec;
74  std::vector<MultiVector> scrapVec;
75  for (int b = 0; b < blocks; b++) {
76  dstVec.push_back(getBlock(b, dstCopy));
77  scrapVec.push_back(getBlock(b, srcScrap_));
78  }
79 
80  // run forward-substituion: run over each column
81  // From Heath pg. 65
82  for (int b = 0; b < blocks; b++) {
83  applyOp(invDiag_[b], scrapVec[b], dstVec[b]);
84 
85  // loop over each row
86  for (int i = b + 1; i < blocks; i++) {
87  LinearOp u_ib = getBlock(i, b, L_);
88  if (u_ib != Teuchos::null) {
89  applyOp(u_ib, dstVec[b], scrapVec[i], -1.0, 1.0);
90  }
91  }
92  }
93 
94  // scale result by alpha
95  if (beta != 0)
96  update(alpha, dstCopy, beta, dst); // dst = alpha * dstCopy + beta * dst
97  else if (alpha != 1.0)
98  scale(alpha, dst); // dst = alpha * dst
99 }
100 
101 void BlockLowerTriInverseOp::describe(Teuchos::FancyOStream& out_arg,
102  const Teuchos::EVerbosityLevel verbLevel) const {
103  using Teuchos::OSTab;
104 
105  RCP<Teuchos::FancyOStream> out = rcp(&out_arg, false);
106  OSTab tab(out);
107  switch (verbLevel) {
108  case Teuchos::VERB_DEFAULT:
109  case Teuchos::VERB_LOW: *out << this->description() << std::endl; break;
110  case Teuchos::VERB_MEDIUM:
111  case Teuchos::VERB_HIGH:
112  case Teuchos::VERB_EXTREME: {
113  *out << Teuchos::Describable::description() << "{"
114  << "rangeDim=" << this->range()->dim() << ",domainDim=" << this->domain()->dim()
115  << ",rows=" << blockRowCount(L_) << ",cols=" << blockColCount(L_) << "}\n";
116  {
117  OSTab tab2(out);
118  *out << "[L Operator] = ";
119  *out << Teuchos::describe(*L_, verbLevel);
120  }
121  {
122  OSTab tab2(out);
123  *out << "[invDiag Operators]:\n";
124  tab.incrTab();
125  for (int i = 0; i < blockRowCount(L_); i++) {
126  *out << "[invD(" << i << ")] = ";
127  *out << Teuchos::describe(*invDiag_[i], verbLevel);
128  }
129  }
130  break;
131  }
132  default: TEUCHOS_TEST_FOR_EXCEPT(true); // Should never get here!
133  }
134 }
135 
136 } // end namespace Teko
virtual VectorSpace domain() const
Domain space of this operator.
const BlockedLinearOp L_
operator
Teuchos::RCP< const Thyra::ProductVectorSpaceBase< double > > productDomain_
Domain 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
Teuchos::RCP< const Thyra::ProductVectorSpaceBase< double > > productRange_
Range vector space.
virtual VectorSpace range() const
Range space of this operator.