Teko  Version of the Day
 All Classes Files Functions Variables Pages
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 
15 namespace Teko {
16 namespace NS {
17 
18 using Teuchos::TimeMonitor;
19 
20 Teuchos::RCP<Teuchos::Time> PCDStrategy::initTimer_;
21 Teuchos::RCP<Teuchos::Time> PCDStrategy::invSTimer_;
22 Teuchos::RCP<Teuchos::Time> PCDStrategy::invFTimer_;
23 Teuchos::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 
39 PCDStrategy::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 
46  buildTimers();
47 }
48 
50 PCDStrategy::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 
62  buildTimers();
63 }
64 
66 const Teko::LinearOp PCDStrategy::getHatInvA00(const Teko::BlockedLinearOp& A,
67  BlockPreconditionerState& state) const {
68  initializeState(A, state);
69 
70  return state.getModifiableOp("invF");
71 }
72 
74 const Teko::LinearOp PCDStrategy::getTildeInvA00(const Teko::BlockedLinearOp& A,
75  BlockPreconditionerState& state) const {
76  initializeState(A, state);
77 
78  return state.getModifiableOp("invF");
79 }
80 
83 const Teko::LinearOp PCDStrategy::getInvS(const Teko::BlockedLinearOp& A,
84  BlockPreconditionerState& state) const {
85  initializeState(A, state);
86 
87  return state.getLinearOp("invS");
88 }
89 
90 void 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 
196 void 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 
284 Teuchos::RCP<Teuchos::ParameterList> PCDStrategy::getRequestedParameters() const {
285  TEUCHOS_ASSERT(false);
286 
287  return Teuchos::null;
288 }
289 
291 bool PCDStrategy::updateRequestedParameters(const Teuchos::ParameterList& /* pl */) {
292  TEUCHOS_ASSERT(false);
293 
294  return true;
295 }
296 
297 } // end namespace NS
298 } // end namespace Teko
void rebuildInverse(const InverseFactory &factory, const LinearOp &A, InverseLinearOp &invA)
virtual void initializeFromParameterList(const Teuchos::ParameterList &settings, const InverseLibrary &invLib)
This function builds the internals of the state from a parameter list.
virtual const Teko::LinearOp getHatInvA00(const Teko::BlockedLinearOp &A, BlockPreconditionerState &state) const
virtual const Teko::LinearOp getTildeInvA00(const Teko::BlockedLinearOp &A, BlockPreconditionerState &state) const
virtual void addLinearOp(const std::string &name, const Teko::LinearOp &lo)
Add a named operator to the state object.
void initializeState(const Teko::BlockedLinearOp &A, BlockPreconditionerState &state) const
An implementation of a state object for block preconditioners.
Teuchos::RCP< RequestHandler > getRequestHandler() const
This method gets the request handler uses by this object.
virtual Teko::LinearOp getLinearOp(const std::string &name)
Add a named operator to the state object.
PCDStrategy()
default Constructor
virtual bool updateRequestedParameters(const Teuchos::ParameterList &pl)
Update this object with the fields 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
InverseLinearOp buildInverse(const InverseFactory &factory, const LinearOp &A)
Build an inverse operator using a factory and a linear operator.
Teuchos::RCP< Teuchos::ParameterList > lapParams_
Passed to application for construction of laplace operator.
virtual void setInitialized(bool init=true)
virtual Teko::ModifiableLinearOp & getModifiableOp(const std::string &name)
Add a named operator to the state object.
virtual Teuchos::RCP< Teuchos::ParameterList > getRequestedParameters() const
Request the additional parameters this preconditioner factory needs.