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_BlockedEpetraOperator.hpp"
17#include "Teko_BlockedMappingStrategy.hpp"
18#include "Teko_ReorderedMappingStrategy.hpp"
19
20#include "Teuchos_VerboseObject.hpp"
21
22#include "Thyra_LinearOpBase.hpp"
23#include "Thyra_EpetraLinearOp.hpp"
24#include "Thyra_EpetraThyraWrappers.hpp"
25#include "Thyra_DefaultProductMultiVector.hpp"
26#include "Thyra_DefaultProductVectorSpace.hpp"
27#include "Thyra_DefaultBlockedLinearOp.hpp"
28#include "Thyra_get_Epetra_Operator.hpp"
29
30#include "EpetraExt_MultiVectorOut.h"
31#include "EpetraExt_RowMatrixOut.h"
32
33#include "Teko_Utilities.hpp"
34
35#include "Teko_ALOperator.hpp"
36
37namespace Teko {
38
39namespace NS {
40
41ALOperator::ALOperator(const std::vector<std::vector<int> >& vars,
42 const Teuchos::RCP<Epetra_Operator>& content, LinearOp pressureMassMatrix,
43 double gamma, const std::string& label)
44 : Teko::Epetra::BlockedEpetraOperator(vars, content, label),
45 pressureMassMatrix_(pressureMassMatrix),
46 gamma_(gamma) {
47 checkDim(vars);
48 SetContent(vars, content);
50}
51
52ALOperator::ALOperator(const std::vector<std::vector<int> >& vars,
53 const Teuchos::RCP<Epetra_Operator>& content, double gamma,
54 const std::string& label)
55 : Teko::Epetra::BlockedEpetraOperator(vars, content, label),
56 pressureMassMatrix_(Teuchos::null),
57 gamma_(gamma) {
58 checkDim(vars);
59 SetContent(vars, content);
61}
62
63void ALOperator::setPressureMassMatrix(LinearOp pressureMassMatrix) {
64 if (pressureMassMatrix != Teuchos::null) {
65 pressureMassMatrix_ = pressureMassMatrix;
66 }
67}
68
69void ALOperator::setGamma(double gamma) {
70 TEUCHOS_ASSERT(gamma > 0.0);
71 gamma_ = gamma;
72}
73
74const Teuchos::RCP<const Epetra_Operator> ALOperator::GetBlock(int i, int j) const {
75 const Teuchos::RCP<Thyra::BlockedLinearOpBase<double> > blkOp =
76 Teuchos::rcp_dynamic_cast<Thyra::BlockedLinearOpBase<double> >(blockedOperator_, true);
77
78 return Thyra::get_Epetra_Operator(*blkOp->getBlock(i, j));
79}
80
81void ALOperator::checkDim(const std::vector<std::vector<int> >& vars) {
82 dim_ = vars.size() - 1;
83 TEUCHOS_ASSERT(dim_ == 2 || dim_ == 3);
84}
85
87 TEUCHOS_ASSERT(blockedMapping_ != Teuchos::null);
88
89 // Get an Epetra_CrsMatrix.
90 const Teuchos::RCP<const Epetra_CrsMatrix> crsContent =
91 Teuchos::rcp_dynamic_cast<const Epetra_CrsMatrix>(fullContent_);
92
93 // Ask the strategy to build the Thyra operator for you.
94 if (blockedOperator_ == Teuchos::null) {
95 blockedOperator_ = blockedMapping_->buildBlockedThyraOp(crsContent, label_);
96 } else {
97 const Teuchos::RCP<Thyra::BlockedLinearOpBase<double> > blkOp =
98 Teuchos::rcp_dynamic_cast<Thyra::BlockedLinearOpBase<double> >(blockedOperator_, true);
99 blockedMapping_->rebuildBlockedThyraOp(crsContent, blkOp);
100 }
101
102 // Extract blocks.
103 const Teuchos::RCP<Thyra::BlockedLinearOpBase<double> > blkOp =
104 Teuchos::rcp_dynamic_cast<Thyra::BlockedLinearOpBase<double> >(blockedOperator_, true);
105 numBlockRows_ = blkOp->productRange()->numBlocks();
106 Teuchos::RCP<const Thyra::LinearOpBase<double> > blockedOpBlocks[4][4];
107 for (int i = 0; i <= dim_; i++) {
108 for (int j = 0; j <= dim_; j++) {
109 blockedOpBlocks[i][j] = blkOp->getBlock(i, j);
110 }
111 }
112
113 // Pressure mass matrix.
114 if (pressureMassMatrix_ != Teuchos::null) {
116 }
117 // We need the size of the sub-block to build the identity matrix.
118 else {
119 std::cout << "Pressure mass matrix is null. Use identity." << std::endl;
120 pressureMassMatrix_ = Thyra::identity<double>(blockedOpBlocks[dim_][0]->range());
121 invPressureMassMatrix_ = Thyra::identity<double>(blockedOpBlocks[dim_][0]->range());
122 }
123
124 // Build the AL operator.
125 Teuchos::RCP<Thyra::DefaultBlockedLinearOp<double> > alOperator =
126 Thyra::defaultBlockedLinearOp<double>();
127 alOperator->beginBlockFill(dim_ + 1, dim_ + 1);
128
129 // Set blocks for the velocity parts and gradient.
130 for (int i = 0; i < dim_; i++) {
131 for (int j = 0; j < dim_; j++) {
132 // build the blocks and place it the right location
133 alOperator->setBlock(
134 i, j,
135 Thyra::add(
136 blockedOpBlocks[i][j],
137 Thyra::scale(gamma_, Thyra::multiply(blockedOpBlocks[i][dim_], invPressureMassMatrix_,
138 blockedOpBlocks[dim_][j]))));
139 } // end for j
140 } // end for i
141
142 // Last row. Divergence and (possible) stabilization matrix.
143 for (int j = 0; j <= dim_; j++) {
144 alOperator->setBlock(dim_, j, blockedOpBlocks[dim_][j]);
145 }
146
147 // Last column. Gradient.
148 for (int i = 0; i < dim_; i++) {
149 alOperator->setBlock(
150 i, dim_,
151 Thyra::add(
152 blockedOpBlocks[i][dim_],
153 Thyra::scale(gamma_, Thyra::multiply(blockedOpBlocks[i][dim_], invPressureMassMatrix_,
154 blockedOpBlocks[dim_][dim_]))));
155 }
156
157 alOperator->endBlockFill();
158
159 // Set whatever is returned.
160 SetOperator(alOperator, false);
161
162 // Set operator for augmenting the right-hand side.
163 Teuchos::RCP<Thyra::DefaultBlockedLinearOp<double> > alOpRhs_ =
164 Thyra::defaultBlockedLinearOp<double>();
165 alOpRhs_->beginBlockFill(dim_ + 1, dim_ + 1);
166
167 // Identity matrices on the main diagonal.
168 for (int i = 0; i < dim_; i++) {
169 // build the blocks and place it the right location
170 alOpRhs_->setBlock(i, i, Thyra::identity<double>(blockedOpBlocks[0][0]->range()));
171 } // end for i
172 alOpRhs_->setBlock(dim_, dim_, Thyra::identity<double>(blockedOpBlocks[dim_][dim_]->range()));
173
174 // Last column.
175 for (int i = 0; i < dim_; i++) {
176 alOpRhs_->setBlock(
177 i, dim_,
178 Thyra::scale(gamma_, Thyra::multiply(blockedOpBlocks[i][dim_], invPressureMassMatrix_)));
179 }
180
181 alOpRhs_->endBlockFill();
182
183 alOperatorRhs_ = alOpRhs_;
184
185 // reorder if necessary
186 if (reorderManager_ != Teuchos::null) Reorder(*reorderManager_);
187}
188
189void ALOperator::augmentRHS(const Epetra_MultiVector& b, Epetra_MultiVector& bAugmented) {
190 Teuchos::RCP<const Teko::Epetra::MappingStrategy> mapping = this->getMapStrategy();
191 Teuchos::RCP<Thyra::MultiVectorBase<double> > bThyra =
192 Thyra::createMembers(thyraOp_->range(), b.NumVectors());
193 Teuchos::RCP<Thyra::MultiVectorBase<double> > bThyraAugmented =
194 Thyra::createMembers(thyraOp_->range(), b.NumVectors());
195 // std::cout << Teuchos::describe(*bThyra, Teuchos::VERB_EXTREME) << std::endl;
196 // Copy Epetra vector to Thyra vector.
197 mapping->copyEpetraIntoThyra(b, bThyra.ptr());
198 // Apply operator.
199 alOperatorRhs_->apply(Thyra::NOTRANS, *bThyra, bThyraAugmented.ptr(), 1.0, 0.0);
200 // Copy Thyra vector to Epetra vector.
201 mapping->copyThyraIntoEpetra(bThyraAugmented, bAugmented);
202}
203
204} // end namespace NS
205
206} // end namespace Teko
virtual void SetContent(const std::vector< std::vector< int > > &vars, const Teuchos::RCP< const Epetra_Operator > &content)
void Reorder(const BlockReorderManager &brm)
BlockedEpetraOperator(const std::vector< std::vector< int > > &vars, const Teuchos::RCP< const Epetra_Operator > &content, const std::string &label="<ANYM>")
const RCP< const MappingStrategy > getMapStrategy() const
Get the mapping strategy for this wrapper (translate between Thyra and Epetra).
void setPressureMassMatrix(LinearOp pressureMassMatrix)
Teuchos::RCP< Thyra::LinearOpBase< double > > alOperatorRhs_
const Teuchos::RCP< const Epetra_Operator > GetBlock(int i, int j) const
void setGamma(double gamma)
void checkDim(const std::vector< std::vector< int > > &vars)
void augmentRHS(const Epetra_MultiVector &b, Epetra_MultiVector &bAugmented)
ALOperator(const std::vector< std::vector< int > > &vars, const Teuchos::RCP< Epetra_Operator > &content, LinearOp pressureMassMatrix, double gamma=0.05, const std::string &label="<ANYM>")