Teko Version of the Day
Teko_ModALPreconditionerFactory.cpp
1/*
2 * Author: Zhen Wang
3 * Email: wangz@ornl.gov
4 * zhen.wang@alum.emory.edu
5 */
6
7#include "Teko_ModALPreconditionerFactory.hpp"
8
9#include "Thyra_DefaultMultipliedLinearOp.hpp"
10#include "Thyra_DefaultAddedLinearOp.hpp"
11#include "Thyra_DefaultIdentityLinearOp.hpp"
12#include "Thyra_DefaultZeroLinearOp.hpp"
13#include "Thyra_get_Epetra_Operator.hpp"
14
16#include "Teko_Utilities.hpp"
17#include "Teko_BlockLowerTriInverseOp.hpp"
18#include "Teko_BlockUpperTriInverseOp.hpp"
19#include "Teko_StaticLSCStrategy.hpp"
20#include "Teko_InvLSCStrategy.hpp"
21#include "Teko_PresLaplaceLSCStrategy.hpp"
22
23#include "EpetraExt_RowMatrixOut.h"
24
25#include "Teuchos_Time.hpp"
26
27namespace Teko
28{
29
30namespace NS
31{
32
33ModALPrecondState::ModALPrecondState():
34pressureMassMatrix_(Teuchos::null), invPressureMassMatrix_(Teuchos::null)
35{
36}
37
38ModALPreconditionerFactory::ModALPreconditionerFactory(const Teuchos::RCP<InverseFactory> & factory) :
39 invOpsStrategy_(Teuchos::rcp(new InvModALStrategy(factory))),
40 isSymmetric_(true)
41{
42}
43
44ModALPreconditionerFactory::ModALPreconditionerFactory(const Teuchos::RCP<InverseFactory> & invFactoryA,
45 const Teuchos::RCP<InverseFactory> & invFactoryS) :
46 invOpsStrategy_(Teuchos::rcp(new InvModALStrategy(invFactoryA, invFactoryS))),
47 isSymmetric_(true)
48{
49}
50
51ModALPreconditionerFactory::ModALPreconditionerFactory(const Teuchos::RCP<InverseFactory> & factory,
52 LinearOp & pressureMassMatrix) :
53 invOpsStrategy_(Teuchos::rcp(new InvModALStrategy(factory, pressureMassMatrix))), isSymmetric_(true)
54{
55}
56
57ModALPreconditionerFactory::ModALPreconditionerFactory(const Teuchos::RCP<InverseFactory> & invFactoryA,
58 const Teuchos::RCP<InverseFactory> & invFactoryS,
59 LinearOp & pressureMassMatrix) :
60 invOpsStrategy_(Teuchos::rcp(new InvModALStrategy(invFactoryA, invFactoryS, pressureMassMatrix))),
61 isSymmetric_(true)
62{
63}
64
65// Construct from a strategy.
66ModALPreconditionerFactory::ModALPreconditionerFactory(const Teuchos::RCP<InvModALStrategy> & strategy) :
67 invOpsStrategy_(strategy), isSymmetric_(true)
68{
69}
70
71LinearOp ModALPreconditionerFactory::buildPreconditionerOperator(BlockedLinearOp & alOp,
72 BlockPreconditionerState & state) const
73{
74 Teko_DEBUG_SCOPE("ModALPreconditionerFactory::buildPreconditionerOperator()", 10);
75 Teko_DEBUG_EXPR(Teuchos::Time timer(""));
76 Teko_DEBUG_EXPR(Teuchos::Time totalTimer(""));
77 Teko_DEBUG_EXPR(totalTimer.start());
78
79 // Only for 2D or 3D problems.
80 int dim = blockRowCount(alOp) - 1;
81 TEUCHOS_ASSERT(dim == 2 || dim == 3);
82
83 // Build what is necessary for the state object.
84 Teko_DEBUG_EXPR(timer.start(true));
85 invOpsStrategy_->buildState(alOp, state);
86 Teko_DEBUG_EXPR(timer.stop());
87 Teko_DEBUG_MSG("ModALPreconditionerFactory::buildPreconditionerOperator():BuildStateTime = "
88 << timer.totalElapsedTime(), 2);
89
90 // Extract inverse operators from strategy
91 Teko_DEBUG_EXPR(timer.start(true));
92 LinearOp invA11p = invOpsStrategy_->getInvA11p(state);
93 LinearOp invA22p = invOpsStrategy_->getInvA22p(state);
94 LinearOp invA33p;
95 if(dim == 3)
96 {
97 invA33p = invOpsStrategy_->getInvA33p(state);
98 }
99
100 // The inverse of S can be built from strategy,
101 // or just a diagonal matrix.
102 ModALPrecondState * modALState = dynamic_cast<ModALPrecondState*>(&state);
103 TEUCHOS_ASSERT(modALState != NULL);
104 LinearOp invS;
105 if(modALState->isStabilized_)
106 {
107 invS = invOpsStrategy_->getInvS(state);
108 }
109 else
110 {
111 invS = scale(modALState->gamma_, modALState->invPressureMassMatrix_);
112 }
113
114 Teko_DEBUG_EXPR(timer.stop());
115 Teko_DEBUG_MSG("ModALPrecFact::buildPreconditionerOperator(): GetInvTime = "
116 << timer.totalElapsedTime(), 2);
117
118 // Build diagonal operations.
119 std::vector<LinearOp> invDiag;
120 invDiag.resize(dim + 1);
121 invDiag[0] = invA11p;
122 invDiag[1] = invA22p;
123 if(dim == 2)
124 {
125 invDiag[2] = scale(-1.0, invS);
126 }
127 else if(dim == 3)
128 {
129 invDiag[2] = invA33p;
130 invDiag[3] = scale(-1.0, invS);
131 }
132
133 // Get the upper triangular matrix.
134 BlockedLinearOp U = getUpperTriBlocks(alOp);
135
136 Teko_DEBUG_EXPR(totalTimer.stop());
137 Teko_DEBUG_MSG("ModALPrecFact::buildPreconditionerOperator TotalTime = "
138 << totalTimer.totalElapsedTime(), 2);
139
140 // Create the preconditioner
141 return createBlockUpperTriInverseOp(U, invDiag, "Modified AL preconditioner-Upper");
142}
143
144} // end namespace NS
145
146} // end namespace Teko
void scale(const double alpha, MultiVector &x)
Scale a multivector by a constant.
int blockRowCount(const BlockedLinearOp &blo)
Get the row count in a block linear operator.
An implementation of a state object for block preconditioners.
Class for saving state variables for ModALPreconditionerFactory.