Teko Version of the Day
Loading...
Searching...
No Matches
Teko_ALOperator.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/*
11 * Author: Zhen Wang
12 * Email: wangz@ornl.gov
13 * zhen.wang@alum.emory.edu
14 */
15
16#include "Teko_ALOperator.hpp"
17
18#include "Teko_BlockedTpetraOperator.hpp"
19#include "Teko_TpetraBlockedMappingStrategy.hpp"
20#include "Teko_TpetraReorderedMappingStrategy.hpp"
21
22#include "Teuchos_VerboseObject.hpp"
23
24#include "Thyra_LinearOpBase.hpp"
25#include "Thyra_TpetraLinearOp.hpp"
26#include "Thyra_TpetraThyraWrappers.hpp"
27#include "Thyra_DefaultProductMultiVector.hpp"
28#include "Thyra_DefaultProductVectorSpace.hpp"
29#include "Thyra_DefaultBlockedLinearOp.hpp"
30
31#include "Teko_Utilities.hpp"
32#include "Teko_ConfigDefs.hpp"
33
34namespace Teko::NS {
35
36using Teuchos::RCP;
37using Teuchos::rcp;
38using Teuchos::rcp_dynamic_cast;
39
40ALOperator::ALOperator(const std::vector<std::vector<GO> >& vars,
41 const Teuchos::RCP<Tpetra::Operator<ST, LO, GO, NT> >& content,
42 LinearOp pressureMassMatrix, double gamma, const std::string& label)
43 : Teko::TpetraHelpers::BlockedTpetraOperator(vars, content, label),
44 pressureMassMatrix_(pressureMassMatrix),
45 gamma_(gamma) {
46 checkDim(vars);
48}
49
50ALOperator::ALOperator(const std::vector<std::vector<GO> >& vars,
51 const Teuchos::RCP<Tpetra::Operator<ST, LO, GO, NT> >& content, double gamma,
52 const std::string& label)
53 : Teko::TpetraHelpers::BlockedTpetraOperator(vars, content, label),
54 pressureMassMatrix_(Teuchos::null),
55 gamma_(gamma) {
56 checkDim(vars);
58}
59
60void ALOperator::setPressureMassMatrix(LinearOp pressureMassMatrix) {
61 if (pressureMassMatrix != Teuchos::null) pressureMassMatrix_ = pressureMassMatrix;
62}
63
64void ALOperator::setGamma(double gamma) {
65 TEUCHOS_ASSERT(gamma > 0.0);
66 gamma_ = gamma;
67}
68
69const Teuchos::RCP<const Tpetra::Operator<ST, LO, GO, NT> > ALOperator::GetBlock(int i,
70 int j) const {
71 const Teuchos::RCP<Thyra::BlockedLinearOpBase<ST> > blkOp =
72 Teuchos::rcp_dynamic_cast<Thyra::BlockedLinearOpBase<ST> >(blockedOperator_, true);
73 RCP<const Thyra::TpetraLinearOp<ST, LO, GO, NT> > tOp =
74 rcp_dynamic_cast<const Thyra::TpetraLinearOp<ST, LO, GO, NT> >(blkOp->getBlock(i, j), true);
75 return tOp != Teuchos::null ? tOp->getConstTpetraOperator() : Teuchos::null;
76}
77
78void ALOperator::checkDim(const std::vector<std::vector<GO> >& vars) {
79 dim_ = static_cast<int>(vars.size()) - 1;
80 TEUCHOS_ASSERT(dim_ == 2 || dim_ == 3);
81}
82
84 TEUCHOS_ASSERT(blockedMapping_ != Teuchos::null);
85
86 // Rebuild the original blocked operator from the stored full matrix
87 const Teuchos::RCP<const Tpetra::CrsMatrix<ST, LO, GO, NT> > crsContent =
88 Teuchos::rcp_dynamic_cast<const Tpetra::CrsMatrix<ST, LO, GO, NT> >(fullContent_, true);
89
90 if (blockedOperator_ == Teuchos::null) {
91 blockedOperator_ = blockedMapping_->buildBlockedThyraOp(crsContent, label_);
92 } else {
93 const Teuchos::RCP<Thyra::BlockedLinearOpBase<ST> > blkOp0 =
94 Teuchos::rcp_dynamic_cast<Thyra::BlockedLinearOpBase<ST> >(blockedOperator_, true);
95 blockedMapping_->rebuildBlockedThyraOp(crsContent, blkOp0);
96 }
97
98 // Extract original blocks
99 const Teuchos::RCP<Thyra::BlockedLinearOpBase<ST> > blkOp =
100 Teuchos::rcp_dynamic_cast<Thyra::BlockedLinearOpBase<ST> >(blockedOperator_, true);
101
102 numBlockRows_ = blkOp->productRange()->numBlocks();
103
104 Teuchos::RCP<const Thyra::LinearOpBase<ST> > blockedOpBlocks[4][4];
105 for (int i = 0; i <= dim_; i++) {
106 for (int j = 0; j <= dim_; j++) {
107 blockedOpBlocks[i][j] = blkOp->getBlock(i, j);
108 }
109 }
110
111 if (pressureMassMatrix_ != Teuchos::null) {
112 invPressureMassMatrix_ = getInvDiagonalOp(pressureMassMatrix_);
113 } else {
114 std::cout << "Pressure mass matrix is null. Use identity." << std::endl;
115 pressureMassMatrix_ = Thyra::identity<ST>(blockedOpBlocks[dim_][0]->range());
116 invPressureMassMatrix_ = Thyra::identity<ST>(blockedOpBlocks[dim_][0]->range());
117 }
118
119 Teuchos::RCP<Thyra::DefaultBlockedLinearOp<ST> > alOperator = Thyra::defaultBlockedLinearOp<ST>();
120 alOperator->beginBlockFill(dim_ + 1, dim_ + 1);
121
122 // Velocity-velocity blocks: A_ij + gamma * B_i^T * W^{-1} * B_j
123 for (int i = 0; i < dim_; i++) {
124 for (int j = 0; j < dim_; j++) {
125 alOperator->setBlock(
126 i, j,
127 Thyra::add(
128 blockedOpBlocks[i][j],
129 Thyra::scale(gamma_, Thyra::multiply(blockedOpBlocks[i][dim_], invPressureMassMatrix_,
130 blockedOpBlocks[dim_][j]))));
131 }
132 }
133
134 // Last row: [ B -C ]
135 for (int j = 0; j <= dim_; j++) {
136 alOperator->setBlock(dim_, j, blockedOpBlocks[dim_][j]);
137 }
138
139 // Last column: B_i^T - gamma * B_i^T * W^{-1} * C
140 for (int i = 0; i < dim_; i++) {
141 alOperator->setBlock(
142 i, dim_,
143 Thyra::add(
144 blockedOpBlocks[i][dim_],
145 Thyra::scale(-gamma_, Thyra::multiply(blockedOpBlocks[i][dim_], invPressureMassMatrix_,
146 blockedOpBlocks[dim_][dim_]))));
147 }
148
149 alOperator->endBlockFill();
150 alOperator_ = alOperator;
151
152 // This is the operator used by apply()
153 SetOperator(alOperator_, false);
154
155 // Build operator for augmenting RHS:
156 // [ I 0 gamma * B^T * W^{-1} ]
157 // [ 0 I gamma * B^T * W^{-1} ]
158 // [ 0 0 I ]
159 Teuchos::RCP<Thyra::DefaultBlockedLinearOp<ST> > alOpRhs = Thyra::defaultBlockedLinearOp<ST>();
160 alOpRhs->beginBlockFill(dim_ + 1, dim_ + 1);
161
162 for (int i = 0; i < dim_; i++) {
163 alOpRhs->setBlock(i, i, Thyra::identity<ST>(blockedOpBlocks[i][i]->range()));
164 }
165 alOpRhs->setBlock(dim_, dim_, Thyra::identity<ST>(blockedOpBlocks[dim_][dim_]->range()));
166
167 for (int i = 0; i < dim_; i++) {
168 alOpRhs->setBlock(
169 i, dim_,
170 Thyra::scale(gamma_, Thyra::multiply(blockedOpBlocks[i][dim_], invPressureMassMatrix_)));
171 }
172
173 alOpRhs->endBlockFill();
174 alOperatorRhs_ = alOpRhs;
175
176 if (reorderManager_ != Teuchos::null) Reorder(*reorderManager_);
177}
178
179void ALOperator::augmentRHS(const Tpetra::MultiVector<ST, LO, GO, NT>& b,
180 Tpetra::MultiVector<ST, LO, GO, NT>& bAugmented) {
181 Teuchos::RCP<const Teko::TpetraHelpers::MappingStrategy> mapping = this->getMapStrategy();
182
183 Teuchos::RCP<Thyra::MultiVectorBase<ST> > bThyra =
184 Thyra::createMembers(thyraOp_->range(), b.getNumVectors());
185
186 Teuchos::RCP<Thyra::MultiVectorBase<ST> > bThyraAugmented =
187 Thyra::createMembers(thyraOp_->range(), b.getNumVectors());
188
189 mapping->copyTpetraIntoThyra(b, bThyra.ptr());
190 alOperatorRhs_->apply(Thyra::NOTRANS, *bThyra, bThyraAugmented.ptr(), 1.0, 0.0);
191 mapping->copyThyraIntoTpetra(bThyraAugmented, bAugmented);
192}
193
194} // end namespace Teko::NS
void augmentRHS(const Tpetra::MultiVector< ST, LO, GO, NT > &b, Tpetra::MultiVector< ST, LO, GO, NT > &bAugmented)
void setPressureMassMatrix(LinearOp pressureMassMatrix)
Teuchos::RCP< Thyra::LinearOpBase< ST > > alOperatorRhs_
void checkDim(const std::vector< std::vector< GO > > &vars)
Teuchos::RCP< Thyra::LinearOpBase< ST > > alOperator_
const Teuchos::RCP< const Tpetra::Operator< ST, LO, GO, NT > > GetBlock(int i, int j) const
void setGamma(double gamma)
ALOperator(const std::vector< std::vector< GO > > &vars, const Teuchos::RCP< Tpetra::Operator< ST, LO, GO, NT > > &content, LinearOp pressureMassMatrix, double gamma=0.05, const std::string &label="<ANYM>")
const RCP< const MappingStrategy > getMapStrategy() const
Get the mapping strategy for this wrapper (translate between Thyra and Tpetra)