Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NOX_Epetra_LinearSystem_MPBD.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Stokhos Package
4 //
5 // Copyright 2009 NTESS and the Stokhos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
11 
12 #include "Epetra_Map.h"
13 #include "Epetra_Vector.h"
14 #include "NOX_Epetra_Interface_Jacobian.H"
16 #include "Teuchos_TimeMonitor.hpp"
17 #include "Teuchos_Assert.hpp"
18 
19 NOX::Epetra::LinearSystemMPBD::
20 LinearSystemMPBD(
21  Teuchos::ParameterList& printingParams,
22  Teuchos::ParameterList& linearSolverParams,
23  const Teuchos::RCP<NOX::Epetra::LinearSystem>& block_solver_,
27  const Teuchos::RCP<const Epetra_Map>& base_map_,
29  block_solver(block_solver_),
30  jacInterfacePtr(iJac),
31  base_map(base_map_),
32  scaling(s),
33  utils(printingParams)
34 {
35  mp_op = Teuchos::rcp_dynamic_cast<Stokhos::BlockDiagonalOperator>(J, true);
36  block_ops = mp_op->getMPOps();
37  num_mp_blocks = block_ops->size();
38 
39  std::string prec_strategy = linearSolverParams.get("Preconditioner Strategy",
40  "Standard");
41  if (prec_strategy == "Standard")
42  precStrategy = STANDARD;
43  else if (prec_strategy == "Mean")
44  precStrategy = MEAN;
45  else if (prec_strategy == "On the fly")
46  precStrategy = ON_THE_FLY;
47  else
48  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
49  "Invalid preconditioner strategy " << prec_strategy);
50 
51  if (precStrategy == STANDARD)
52  precs.resize(num_mp_blocks);
53 }
54 
55 NOX::Epetra::LinearSystemMPBD::
56 ~LinearSystemMPBD()
57 {
58 }
59 
60 bool NOX::Epetra::LinearSystemMPBD::
61 applyJacobian(const NOX::Epetra::Vector& input,
62  NOX::Epetra::Vector& result) const
63 {
64  mp_op->SetUseTranspose(false);
65  int status = mp_op->Apply(input.getEpetraVector(), result.getEpetraVector());
66 
67  return (status == 0);
68 }
69 
70 bool NOX::Epetra::LinearSystemMPBD::
71 applyJacobianTranspose(const NOX::Epetra::Vector& input,
72  NOX::Epetra::Vector& result) const
73 {
74  mp_op->SetUseTranspose(true);
75  int status = mp_op->Apply(input.getEpetraVector(), result.getEpetraVector());
76  mp_op->SetUseTranspose(false);
77 
78  return (status == 0);
79 }
80 
81 bool NOX::Epetra::LinearSystemMPBD::
82 applyJacobianInverse(Teuchos::ParameterList &params,
83  const NOX::Epetra::Vector &input,
84  NOX::Epetra::Vector &result)
85 {
86  TEUCHOS_FUNC_TIME_MONITOR("Total deterministic solve Time");
87 
88  // Extract blocks
89  EpetraExt::BlockVector input_block(View, *base_map,
90  input.getEpetraVector());
91  EpetraExt::BlockVector result_block(View, *base_map,
92  result.getEpetraVector());
93  result_block.PutScalar(0.0);
94 
95 
96  Teuchos::ParameterList& block_solver_params =
97  params.sublist("Deterministic Solver Parameters");
98 
99  // Solve block linear systems
100  bool final_status = true;
101  bool status;
102  for (int i=0; i<num_mp_blocks; i++) {
103  NOX::Epetra::Vector nox_input(input_block.GetBlock(i),
104  NOX::Epetra::Vector::CreateView);
105  NOX::Epetra::Vector nox_result(result_block.GetBlock(i),
106  NOX::Epetra::Vector::CreateView);
107 
108  block_solver->setJacobianOperatorForSolve(block_ops->getCoeffPtr(i));
109 
110  if (precStrategy == STANDARD)
111  block_solver->setPrecOperatorForSolve(precs[i]);
112  else if (precStrategy == ON_THE_FLY) {
113  block_solver->createPreconditioner(*(prec_x->GetBlock(i)),
114  block_solver_params, false);
115  }
116 
117  status = block_solver->applyJacobianInverse(block_solver_params, nox_input,
118  nox_result);
119  final_status = final_status && status;
120  }
121 
122  return final_status;
123 }
124 
125 bool NOX::Epetra::LinearSystemMPBD::
126 applyRightPreconditioning(bool useTranspose,
127  Teuchos::ParameterList& params,
128  const NOX::Epetra::Vector& input,
129  NOX::Epetra::Vector& result) const
130 {
131  return false;
132 }
133 
134 Teuchos::RCP<NOX::Epetra::Scaling> NOX::Epetra::LinearSystemMPBD::
135 getScaling()
136 {
137  return scaling;
138 }
139 
140 void NOX::Epetra::LinearSystemMPBD::
141 resetScaling(const Teuchos::RCP<NOX::Epetra::Scaling>& s)
142 {
143  scaling = s;
144  return;
145 }
146 
147 bool NOX::Epetra::LinearSystemMPBD::
148 computeJacobian(const NOX::Epetra::Vector& x)
149 {
150  bool success = jacInterfacePtr->computeJacobian(x.getEpetraVector(),
151  *mp_op);
152  block_ops = mp_op->getMPOps();
153  //block_solver->setJacobianOperatorForSolve(block_ops->getCoeffPtr(0));
154  return success;
155 }
156 
157 bool NOX::Epetra::LinearSystemMPBD::
158 createPreconditioner(const NOX::Epetra::Vector& x,
160  bool recomputeGraph) const
161 {
162  EpetraExt::BlockVector mp_x_block(View, *base_map, x.getEpetraVector());
163  Teuchos::ParameterList& solverParams =
164  p.sublist("Deterministic Solver Parameters");
165  bool total_success = true;
166  if (precStrategy == STANDARD) {
167  for (int i=0; i<num_mp_blocks; i++) {
168  block_solver->setJacobianOperatorForSolve(block_ops->getCoeffPtr(i));
169  if (precs[i] != Teuchos::null)
170  block_solver->setPrecOperatorForSolve(precs[i]);
171  bool success =
172  block_solver->createPreconditioner(*(mp_x_block.GetBlock(i)),
173  solverParams, recomputeGraph);
174  precs[i] = block_solver->getGeneratedPrecOperator();
175  total_success = total_success && success;
176  }
177  }
178 
179  else if (precStrategy == MEAN) {
180  block_solver->setJacobianOperatorForSolve(block_ops->getCoeffPtr(0));
181  bool success =
182  block_solver->createPreconditioner(*(mp_x_block.GetBlock(0)),
183  solverParams, recomputeGraph);
184  total_success = total_success && success;
185  }
186 
187  else if (precStrategy == ON_THE_FLY) {
188  if (prec_x == Teuchos::null)
189  prec_x = Teuchos::rcp(new EpetraExt::BlockVector(mp_x_block));
190  else
191  *prec_x = mp_x_block;
192  }
193 
194  return total_success;
195 }
196 
197 bool NOX::Epetra::LinearSystemMPBD::
198 destroyPreconditioner() const
199 {
200  return block_solver->destroyPreconditioner();
201 }
202 
203 bool NOX::Epetra::LinearSystemMPBD::
204 recomputePreconditioner(const NOX::Epetra::Vector& x,
205  Teuchos::ParameterList& p) const
206 {
207  EpetraExt::BlockVector mp_x_block(View, *base_map, x.getEpetraVector());
208  Teuchos::ParameterList& solverParams =
209  p.sublist("Deterministic Solver Parameters");
210  bool total_success = true;
211 
212  if (precStrategy == STANDARD) {
213  for (int i=0; i<num_mp_blocks; i++) {
214  block_solver->setJacobianOperatorForSolve(block_ops->getCoeffPtr(i));
215  if (precs[i] != Teuchos::null)
216  block_solver->setPrecOperatorForSolve(precs[i]);
217  bool success =
218  block_solver->recomputePreconditioner(*(mp_x_block.GetBlock(i)),
219  solverParams);
220  precs[i] = block_solver->getGeneratedPrecOperator();
221  total_success = total_success && success;
222  }
223  }
224 
225  else if (precStrategy == MEAN) {
226  block_solver->setJacobianOperatorForSolve(block_ops->getCoeffPtr(0));
227  bool success =
228  block_solver->recomputePreconditioner(*(mp_x_block.GetBlock(0)),
229  solverParams);
230  total_success = total_success && success;
231  }
232 
233  else if (precStrategy == ON_THE_FLY) {
234  if (prec_x == Teuchos::null)
235  prec_x = Teuchos::rcp(new EpetraExt::BlockVector(mp_x_block));
236  else
237  *prec_x = mp_x_block;
238  }
239 
240  return total_success;
241 }
242 
243 NOX::Epetra::LinearSystem::PreconditionerReusePolicyType
244 NOX::Epetra::LinearSystemMPBD::
245 getPreconditionerPolicy(bool advanceReuseCounter)
246 {
247  return block_solver->getPreconditionerPolicy(advanceReuseCounter);
248 }
249 
250 bool NOX::Epetra::LinearSystemMPBD::
251 isPreconditionerConstructed() const
252 {
253  return block_solver->isPreconditionerConstructed();
254 }
255 
256 bool NOX::Epetra::LinearSystemMPBD::
257 hasPreconditioner() const
258 {
259  return block_solver->hasPreconditioner();
260 }
261 
262 Teuchos::RCP<const Epetra_Operator> NOX::Epetra::LinearSystemMPBD::
263 getJacobianOperator() const
264 {
265  return mp_op;
266 }
267 
268 Teuchos::RCP<Epetra_Operator> NOX::Epetra::LinearSystemMPBD::
269 getJacobianOperator()
270 {
271  return mp_op;
272 }
273 
274 Teuchos::RCP<const Epetra_Operator> NOX::Epetra::LinearSystemMPBD::
275 getGeneratedPrecOperator() const
276 {
277  if (precStrategy == MEAN)
278  return block_solver->getGeneratedPrecOperator();
279  else
281  true, std::logic_error,
282  "Cannot call getGeneratedPrecOperator() unless prec strategy is Mean");
283  return Teuchos::null;
284 }
285 
286 Teuchos::RCP<Epetra_Operator> NOX::Epetra::LinearSystemMPBD::
287 getGeneratedPrecOperator()
288 {
289  if (precStrategy == MEAN)
290  return block_solver->getGeneratedPrecOperator();
291  else
293  true, std::logic_error,
294  "Cannot call getGeneratedPrecOperator() unless prec strategy is Mean");
295  return Teuchos::null;
296 }
297 
298 void NOX::Epetra::LinearSystemMPBD::
299 setJacobianOperatorForSolve(const
301 {
303  Teuchos::rcp_dynamic_cast<const Stokhos::BlockDiagonalOperator>(solveJacOp,
304  true);
305  mp_op = Teuchos::rcp_const_cast<Stokhos::BlockDiagonalOperator>(const_mp_op);
306  block_ops = mp_op->getMPOps();
307 }
308 
309 void NOX::Epetra::LinearSystemMPBD::
310 setPrecOperatorForSolve(const Teuchos::RCP<const Epetra_Operator>& solvePrecOp)
311 {
312  if (precStrategy == MEAN)
313  block_solver->setPrecOperatorForSolve(solvePrecOp);
314  else
316  true, std::logic_error,
317  "Cannot call setPrecOperatorForSolve() unless prec strategy is Mean");
318 }
#define TEUCHOS_FUNC_TIME_MONITOR(FUNCNAME)
T & get(ParameterList &l, const std::string &name)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
RCP< ParameterList > sublist(const RCP< ParameterList > &paramList, const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
An Epetra operator representing the block stochastic Galerkin operator.
virtual Teuchos::RCP< Stokhos::ProductEpetraOperator > getMPOps()
Get multi-point ops.