Teko Version of the Day
Loading...
Searching...
No Matches
Teko_PCDStrategy.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_PCDStrategy.hpp"
11
12#include "Teuchos_TimeMonitor.hpp"
13#include "Teko_Utilities.hpp"
14
15namespace Teko {
16namespace NS {
17
18using Teuchos::TimeMonitor;
19
20Teuchos::RCP<Teuchos::Time> PCDStrategy::initTimer_;
21Teuchos::RCP<Teuchos::Time> PCDStrategy::invSTimer_;
22Teuchos::RCP<Teuchos::Time> PCDStrategy::invFTimer_;
23Teuchos::RCP<Teuchos::Time> PCDStrategy::opsTimer_;
24
26 if (initTimer_ == Teuchos::null)
27 initTimer_ = TimeMonitor::getNewTimer("PCDStrategy::initializePrec");
28
29 if (invSTimer_ == Teuchos::null)
30 invSTimer_ = TimeMonitor::getNewTimer("PCDStrategy::initializePrec invS");
31
32 if (invFTimer_ == Teuchos::null)
33 invFTimer_ = TimeMonitor::getNewTimer("PCDStrategy::initializePrec invF");
34
35 if (opsTimer_ == Teuchos::null)
36 opsTimer_ = TimeMonitor::getNewTimer("PCDStrategy::initializePrec buildOps");
37}
38
39PCDStrategy::PCDStrategy() : massInverseType_(Diagonal), schurCompOrdering_(false) {
40 pcdParams_ = Teuchos::rcp(new Teuchos::ParameterList);
41 lapParams_ = Teuchos::rcp(new Teuchos::ParameterList);
42
43 lapParams_->set("Name", getPressureLaplaceString());
44 pcdParams_->set("Name", getPCDString());
45
47}
48
50PCDStrategy::PCDStrategy(const Teuchos::RCP<InverseFactory>& invFA,
51 const Teuchos::RCP<InverseFactory>& invS)
52 : invFactoryF_(invFA),
53 invFactoryS_(invS),
54 massInverseType_(Diagonal),
55 schurCompOrdering_(false) {
56 pcdParams_ = Teuchos::rcp(new Teuchos::ParameterList);
57 lapParams_ = Teuchos::rcp(new Teuchos::ParameterList);
58
59 lapParams_->set("Name", getPressureLaplaceString());
60 pcdParams_->set("Name", getPCDString());
61
63}
64
66const Teko::LinearOp PCDStrategy::getHatInvA00(const Teko::BlockedLinearOp& A,
67 BlockPreconditionerState& state) const {
68 initializeState(A, state);
69
70 return state.getModifiableOp("invF");
71}
72
74const Teko::LinearOp PCDStrategy::getTildeInvA00(const Teko::BlockedLinearOp& A,
75 BlockPreconditionerState& state) const {
76 initializeState(A, state);
77
78 return state.getModifiableOp("invF");
79}
80
83const Teko::LinearOp PCDStrategy::getInvS(const Teko::BlockedLinearOp& A,
84 BlockPreconditionerState& state) const {
85 initializeState(A, state);
86
87 return state.getLinearOp("invS");
88}
89
90void PCDStrategy::initializeState(const Teko::BlockedLinearOp& A,
91 BlockPreconditionerState& state) const {
92 Teko_DEBUG_SCOPE("PCDStrategy::initializeState", 10);
93 TEUCHOS_ASSERT(getRequestHandler() != Teuchos::null);
94
95 std::string pcdStr = getPCDString();
96 std::string presLapStr = getPressureLaplaceString();
97 std::string presMassStr = getPressureMassString();
98
99 // no work to be done
100 if (state.isInitialized()) return;
101
102 Teuchos::TimeMonitor timer(*initTimer_, true);
103
104 // extract sub blocks
105 LinearOp F = Teko::getBlock(0, 0, A);
106 LinearOp Bt = Teko::getBlock(0, 1, A);
107 LinearOp B = Teko::getBlock(1, 0, A);
108 LinearOp C = Teko::getBlock(1, 1, A);
109
110 LinearOp Qp = getRequestHandler()->request<LinearOp>(presMassStr);
111 TEUCHOS_ASSERT(Qp != Teuchos::null);
112
113 // build the inverse Laplacian complement
115 LinearOp iQp;
116 if (massInverseType_ == NotDiag) {
117 ModifiableLinearOp& invMass = state.getModifiableOp("invMass");
118 Teko_DEBUG_SCOPE("Building inv(Mass)", 10);
119
120 if (invMass == Teuchos::null)
121 invMass = buildInverse(*invFactoryS_, Qp);
122 else
123 rebuildInverse(*invFactoryS_, Qp, invMass);
124
125 iQp = invMass;
126 } else {
127 Teko_DEBUG_MSG(
128 "Building inverse mass of type \"" << Teko::getDiagonalName(massInverseType_) << "\"", 10);
129 iQp = getInvDiagonalOp(Qp, massInverseType_);
130 }
131
132 // build the inverse Laplacian complement
134 ModifiableLinearOp& invLaplace = state.getModifiableOp("invLaplace");
135 {
136 Teuchos::TimeMonitor timerInvS(*invSTimer_, true);
137
138 // LinearOp laplace = getRequestHandler()->request<Teko::LinearOp>(presLapStr);
139 LinearOp laplace = getRequestHandler()->request<Teko::LinearOp>(RequestMesg(lapParams_));
140 TEUCHOS_ASSERT(laplace != Teuchos::null);
141 if (invLaplace == Teuchos::null)
142 invLaplace = buildInverse(*invFactoryS_, laplace);
143 else
144 rebuildInverse(*invFactoryS_, laplace, invLaplace);
145 }
146
147 // build the inverse Schur complement
149 {
150 Teko_DEBUG_SCOPE("Building S", 10);
151 Teuchos::TimeMonitor timerS(*opsTimer_, true);
152
153 // build Schur-complement
154 // LinearOp pcd = getRequestHandler()->request<Teko::LinearOp>(pcdStr);
155 LinearOp pcd = getRequestHandler()->request<Teko::LinearOp>(RequestMesg(pcdParams_));
156 TEUCHOS_ASSERT(pcd != Teuchos::null);
157 LinearOp invL = invLaplace;
158
159 LinearOp invS;
160 if (schurCompOrdering_ == false)
161 invS = multiply(iQp, pcd, invL);
162 else
163 invS = multiply(invL, pcd, iQp);
164
165 state.addLinearOp("invS", invS);
166 }
167
168 // build inverse F
170 {
171 Teko_DEBUG_SCOPE("Building inv(F)", 10);
172 Teuchos::TimeMonitor timerInvF(*invFTimer_, true);
173
174 ModifiableLinearOp& invF = state.getModifiableOp("invF");
175 if (invF == Teuchos::null)
176 invF = buildInverse(*invFactoryF_, F);
177 else
178 rebuildInverse(*invFactoryF_, F, invF);
179 }
180
181 // mark state as initialized
182 state.setInitialized(true);
183}
184
196void PCDStrategy::initializeFromParameterList(const Teuchos::ParameterList& pl,
197 const InverseLibrary& invLib) {
198 Teko_DEBUG_SCOPE("PCDStrategy::initializeFromParameterList", 10);
199
200 std::string invStr = "", invFStr = "", invSStr = "";
201#if defined(Teko_ENABLE_Amesos)
202 invStr = "Amesos";
203#elif defined(Teko_ENABLE_Amesos2)
204 invStr = "Amesos2";
205#endif
206
207 massInverseType_ = Diagonal;
208
209 // "parse" the parameter list
210 if (pl.isParameter("Inverse Type")) invStr = pl.get<std::string>("Inverse Type");
211 if (pl.isParameter("Inverse F Type")) invFStr = pl.get<std::string>("Inverse F Type");
212 if (pl.isParameter("Inverse Laplace Type")) invSStr = pl.get<std::string>("Inverse Laplace Type");
213 if (pl.isParameter("Inverse Mass Type")) {
214 std::string massInverseStr = pl.get<std::string>("Inverse Mass Type");
215
216 // build inverse types
217 massInverseType_ = getDiagonalType(massInverseStr);
218 }
219 if (pl.isParameter("Flip Schur Complement Ordering"))
220 schurCompOrdering_ = pl.get<bool>("Flip Schur Complement Ordering");
221
222 // set defaults as needed
223 if (invFStr == "") invFStr = invStr;
224 if (invSStr == "") invSStr = invStr;
225
226 // read pressure laplace parameters
227 if (pl.isSublist("Pressure Laplace Parameters"))
228 lapParams_ =
229 Teuchos::rcp(new Teuchos::ParameterList(pl.sublist("Pressure Laplace Parameters")));
230 else
231 lapParams_ = Teuchos::rcp(new Teuchos::ParameterList);
232
233 // read pcd operator parameters
234 if (pl.isSublist("Pressure Convection Diffusion Parameters"))
235 pcdParams_ = Teuchos::rcp(
236 new Teuchos::ParameterList(pl.sublist("Pressure Convection Diffusion Parameters")));
237 else
238 pcdParams_ = Teuchos::rcp(new Teuchos::ParameterList);
239
240 // The user should not have already added this parameters
241 TEUCHOS_TEST_FOR_EXCEPTION(
242 lapParams_->isParameter("Name"), std::logic_error,
243 "Teko: Parameter \"Name\" is not allowed in the sublist \"" + lapParams_->name() + "\"");
244 TEUCHOS_TEST_FOR_EXCEPTION(
245 lapParams_->isParameter("Tag"), std::logic_error,
246 "Teko: Parameter \"Tag\" is not allowed in the sublist \"" + lapParams_->name() + "\"");
247 TEUCHOS_TEST_FOR_EXCEPTION(
248 pcdParams_->isParameter("Name"), std::logic_error,
249 "Teko: Parameter \"Name\" is not allowed in the sublist \"" + pcdParams_->name() + "\"");
250 TEUCHOS_TEST_FOR_EXCEPTION(
251 pcdParams_->isParameter("Tag"), std::logic_error,
252 "Teko: Parameter \"Tag\" is not allowed in the sublist \"" + pcdParams_->name() + "\"");
253
254 Teko_DEBUG_MSG_BEGIN(5) DEBUG_STREAM << "PCD Strategy Parameters: " << std::endl;
255 DEBUG_STREAM << " inv type = \"" << invStr << "\"" << std::endl;
256 DEBUG_STREAM << " inv F type = \"" << invFStr << "\"" << std::endl;
257 DEBUG_STREAM << " inv Laplace type = \"" << invSStr << "\"" << std::endl;
258 DEBUG_STREAM << " inv Mass type = \"" << Teko::getDiagonalName(massInverseType_) << "\""
259 << std::endl;
260 DEBUG_STREAM << "PCD Strategy Parameter list: " << std::endl;
261 pl.print(DEBUG_STREAM);
262 Teko_DEBUG_MSG_END()
263
264 // build velocity inverse factory
265 invFactoryF_ = invLib.getInverseFactory(invFStr);
266
267 if (invFStr == invSStr)
268 invFactoryS_ = invFactoryF_;
269 else
270 invFactoryS_ = invLib.getInverseFactory(invSStr);
271
272 lapParams_->set("Name", getPressureLaplaceString());
273 pcdParams_->set("Name", getPCDString());
274
275 // setup a request for required operators
276 getRequestHandler()->preRequest<Teko::LinearOp>(getPressureMassString());
277 // getRequestHandler()->preRequest<Teko::LinearOp>(getPCDString());
278 // getRequestHandler()->preRequest<Teko::LinearOp>(getPressureLaplaceString());
279 getRequestHandler()->preRequest<Teko::LinearOp>(Teko::RequestMesg(lapParams_));
280 getRequestHandler()->preRequest<Teko::LinearOp>(Teko::RequestMesg(pcdParams_));
281}
282
284Teuchos::RCP<Teuchos::ParameterList> PCDStrategy::getRequestedParameters() const {
285 TEUCHOS_ASSERT(false);
286
287 return Teuchos::null;
288}
289
291bool PCDStrategy::updateRequestedParameters(const Teuchos::ParameterList& /* pl */) {
292 TEUCHOS_ASSERT(false);
293
294 return true;
295}
296
297} // end namespace NS
298} // end namespace Teko
@ NotDiag
For user convenience, if Teko recieves this value, exceptions will be thrown.
@ Diagonal
Specifies that just the diagonal is used.
MultiVector getBlock(int i, const BlockedMultiVector &bmv)
Get the ith block from a BlockedMultiVector object.
An implementation of a state object for block preconditioners.
Teuchos::RCP< RequestHandler > getRequestHandler() const
This method gets the request handler uses by this object.
Teuchos::RCP< Teuchos::ParameterList > lapParams_
Passed to application for construction of laplace operator.
virtual const Teko::LinearOp getTildeInvA00(const Teko::BlockedLinearOp &A, BlockPreconditionerState &state) const
virtual void initializeFromParameterList(const Teuchos::ParameterList &settings, const InverseLibrary &invLib)
This function builds the internals of the state from a parameter list.
Teuchos::RCP< Teuchos::ParameterList > pcdParams_
Passed to application for construction of PCD operator.
virtual const Teko::LinearOp getInvS(const Teko::BlockedLinearOp &A, BlockPreconditionerState &state) const
virtual const Teko::LinearOp getHatInvA00(const Teko::BlockedLinearOp &A, BlockPreconditionerState &state) const
virtual Teuchos::RCP< Teuchos::ParameterList > getRequestedParameters() const
Request the additional parameters this preconditioner factory needs.
virtual bool updateRequestedParameters(const Teuchos::ParameterList &pl)
Update this object with the fields from a parameter list.
void initializeState(const Teko::BlockedLinearOp &A, BlockPreconditionerState &state) const
PCDStrategy()
default Constructor
virtual void addLinearOp(const std::string &name, const Teko::LinearOp &lo)
Add a named operator to the state object.
virtual Teko::ModifiableLinearOp & getModifiableOp(const std::string &name)
Add a named operator to the state object.
virtual Teko::LinearOp getLinearOp(const std::string &name)
Add a named operator to the state object.
virtual void setInitialized(bool init=true)