49 #include <Xyce_config.h>
54 #include "NOX_Abstract_Vector.H"
55 #include "NOX_Abstract_Group.H"
56 #include "NOX_Common.H"
57 #include "NOX_GlobalData.H"
58 #include "Teuchos_ParameterList.hpp"
59 #include "NOX_Utils.H"
60 #include "NOX_StatusTest_FiniteValue.H"
62 #include "N_ERH_ErrorMgr.h"
64 #include "NOX_Direction_Factory.H"
65 #include "NOX_LineSearch_Factory.H"
66 #include "NOX_Solver_SolverUtils.H"
70 const Teuchos::RefCountPtr<NOX::Abstract::Group>& xGrp,
71 const Teuchos::RefCountPtr<NOX::StatusTest::Generic>& t,
72 const Teuchos::RefCountPtr<Teuchos::ParameterList>& p,
73 double initialStepSize,
76 globalData(Teuchos::rcp(new NOX::GlobalData(p))),
77 augmentLSStrategy(als),
79 oldSolnPtr(xGrp->clone(NOX::DeepCopy)),
81 dirPtr(xGrp->getX().clone(NOX::ShapeCopy)),
85 utils(*(globalData->getUtils())),
86 lineSearch(NOX::LineSearch::buildLineSearch(globalData, paramsPtr->sublist(
"Line Search"))),
87 direction(NOX::
Direction::buildDirection(globalData, paramsPtr->sublist(
"Direction"))),
88 prePostOperator(globalData->getUtils(), paramsPtr->sublist(
"Solver Options")),
89 initialStepSize_(initialStepSize),
90 minStepSize_(minStepSize),
91 maxStepSize_(maxStepSize),
92 stepSize_(initialStepSize),
93 previousStepSize_(0.0),
107 status = NOX::StatusTest::Unconverged;
110 if (utils.isPrintType(NOX::Utils::Parameters))
112 utils.out() <<
"\n" << NOX::Utils::fill(72) <<
"\n";
113 utils.out() <<
"\n-- Parameters Passed to Nonlinear Solver --\n\n";
114 paramsPtr->print(utils.out(),5);
117 checkType = NOX::Solver::parseStatusTestCheckType(paramsPtr->sublist(
"Solver Options"));
121 reset(
const NOX::Abstract::Vector& initial_guess)
123 solnPtr->setX(initial_guess);
128 reset(
const NOX::Abstract::Vector& initial_guess,
129 const Teuchos::RCP<NOX::StatusTest::Generic>& t)
131 solnPtr->setX(initial_guess);
148 prePostOperator.runPreIterate(*
this);
151 if (this->getNumIterations() == 0) {
154 NOX::Abstract::Group::ReturnType rtype = solnPtr->computeF();
155 if (rtype != NOX::Abstract::Group::Ok) {
156 Xyce::dout() <<
"NOX::Solver::PseudoTransientBased::step - Unable to compute F" << std::endl;
161 status = testPtr->checkStatus(*
this, checkType);
162 if ((status == NOX::StatusTest::Converged) &&
163 (utils.isPrintType(NOX::Utils::Warning))) {
164 utils.out() <<
"Warning: NOX::Solver::PseudoTransientBased::step() - The solution passed "
165 <<
"into the solver (either through constructor or reset method) "
166 <<
"is already converged! The solver will not "
167 <<
"attempt to solve this system since status is flagged as "
168 <<
"converged." << std::endl;
172 if (utils.isPrintType(NOX::Utils::Parameters)) {
173 utils.out() <<
"\n-- Status Tests Passed to Nonlinear Solver --\n\n";
174 testPtr->print(utils.out(), 5);
175 utils.out() <<
"\n" << NOX::Utils::fill(72) <<
"\n";
178 if (status != NOX::StatusTest::Unconverged) {
179 prePostOperator.runPostIterate(*
this);
185 if (this->getNumIterations() == 0) {
186 stepSize_ = initialStepSize_;
189 previousStepSize_ = stepSize_;
190 double f_n = this->getSolutionGroup().getNormF();
191 double f_nm1 = this->getPreviousSolutionGroup().getNormF();
193 stepSize_ = scaleFactor_ * previousStepSize_ * f_nm1 / f_n;
207 if (stepSize_ < minStepSize_)
208 stepSize_ = minStepSize_;
210 if (stepSize_ > maxStepSize_)
211 stepSize_ = maxStepSize_;
218 augmentLSStrategy->setProgressVariable(stepSize_);
221 if (status != NOX::StatusTest::Unconverged) {
222 prePostOperator.runPostIterate(*
this);
227 NOX::Abstract::Group& soln = *solnPtr;
228 NOX::StatusTest::Generic& test = *testPtr;
232 ok = direction->compute(dir, soln, *
this);
235 Xyce::dout() <<
"N_NLS_NOX::PseudoTransientBased::iterate - unable to calculate direction" << std::endl;
236 status = NOX::StatusTest::Failed;
237 prePostOperator.runPostIterate(*
this);
248 ok = lineSearch->compute(soln, step_, dir, *
this);
253 Xyce::dout() <<
"N_NLS_NOX::PseudoTransientBased::iterate - line search failed" << std::endl;
254 status = NOX::StatusTest::Failed;
255 prePostOperator.runPostIterate(*
this);
258 else if (utils.isPrintType(NOX::Utils::Warning))
259 utils.out() <<
"N_NLS_NOX::PseudoTransientBased::iterate - using recovery step for line search" << std::endl;
263 NOX::Abstract::Group::ReturnType rtype = soln.computeF();
264 if (rtype != NOX::Abstract::Group::Ok)
266 utils.out() <<
"N_NLS_NOX::PseudoTransientBased::iterate - unable to compute F" << std::endl;
267 status = NOX::StatusTest::Failed;
268 prePostOperator.runPostIterate(*
this);
272 NOX::StatusTest::FiniteValue fv;
273 NOX::StatusTest::StatusType fvStatus = fv.checkStatus(*
this, checkType);
274 if (fvStatus == NOX::StatusTest::Failed) {
276 *group_ = *previousGroup_;
277 prePostOperator.runPostIterate(*
this);
278 group_->setX(group_->getX());
279 if (stepSize_ > minStepSize_)
280 return (NOX::StatusTest::Unconverged);
282 return (NOX::StatusTest::Failed);
288 status = test.checkStatus(*
this, checkType);
290 prePostOperator.runPostIterate(*
this);
298 prePostOperator.runPreSolve(*
this);
302 NOX::Abstract::Group* tmpGroup =
303 const_cast<NOX::Abstract::Group*
>(&(this->getSolutionGroup()));
308 NOX::Abstract::Group* tmpPreviousGroup =
309 const_cast<NOX::Abstract::Group*
>(&(this->getPreviousSolutionGroup()));
312 if ((group_ == 0) || (previousGroup_ == 0)) {
313 std::string message =
"N_NLS_NOX::PrePostOperator\n Failed to dynamic_cast the old and new groups to N_NLS_LOCA::Groups! ";
314 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, message);
318 group_->setAugmentLinearSystem(
true, augmentLSStrategy);
319 previousGroup_->setAugmentLinearSystem(
true, augmentLSStrategy);
324 while (status == NOX::StatusTest::Unconverged)
330 group_->setAugmentLinearSystem(
false, augmentLSStrategy);
331 previousGroup_->setAugmentLinearSystem(
false, augmentLSStrategy);
333 Teuchos::ParameterList& outputParams = paramsPtr->sublist(
"Output");
334 outputParams.set(
"Nonlinear Iterations", nIter);
335 outputParams.set(
"2-Norm of Residual", solnPtr->getNormF());
337 prePostOperator.runPostSolve(*
this);
342 const NOX::Abstract::Group&
348 const NOX::Abstract::Group&
359 const Teuchos::ParameterList&
372 if ((status == NOX::StatusTest::Unconverged) &&
373 (utils.isPrintType(NOX::Utils::OuterIterationStatusTest)))
375 utils.out() << NOX::Utils::fill(72) <<
"\n";
376 utils.out() <<
"-- Status Test Results --\n";
377 testPtr->print(utils.out());
378 utils.out() << NOX::Utils::fill(72) <<
"\n";
382 if (utils.isPrintType(NOX::Utils::OuterIteration))
384 normSoln = solnPtr->getNormF();
385 normStep = (nIter > 0) ? dir.norm() : 0;
389 if (utils.isPrintType(NOX::Utils::OuterIteration))
391 utils.out() <<
"\n" << NOX::Utils::fill(72) <<
"\n";
392 utils.out() <<
"-- Nonlinear Solver Step " << nIter <<
" -- \n";
393 utils.out() <<
"f = " << utils.sciformat(normSoln);
394 utils.out() <<
" step = " << utils.sciformat(step_);
395 utils.out() <<
" dx = " << utils.sciformat(normStep);
396 if (status == NOX::StatusTest::Converged)
397 utils.out() <<
" (Converged!)";
398 if (status == NOX::StatusTest::Failed)
399 utils.out() <<
" (Failed!)";
400 utils.out() <<
"\n" << NOX::Utils::fill(72) <<
"\n" << std::endl;
404 if ((status != NOX::StatusTest::Unconverged) &&
405 (utils.isPrintType(NOX::Utils::OuterIteration)))
407 utils.out() << NOX::Utils::fill(72) <<
"\n";
408 utils.out() <<
"-- Final Status Test Results --\n";
409 testPtr->print(utils.out());
410 utils.out() << NOX::Utils::fill(72) <<
"\n";