1#ifndef NONLINEARSOLVER_DEF_hpp
2#define NONLINEARSOLVER_DEF_hpp
3#include "NonLinearSolver_decl.hpp"
16template<
class SC,
class LO,
class GO,
class NO>
17NonLinearSolver<SC,LO,GO,NO>::NonLinearSolver():
22template<
class SC,
class LO,
class GO,
class NO>
23NonLinearSolver<SC,LO,GO,NO>::NonLinearSolver(std::string type):
27template<
class SC,
class LO,
class GO,
class NO>
28NonLinearSolver<SC,LO,GO,NO>::~NonLinearSolver(){
32template<
class SC,
class LO,
class GO,
class NO>
35 if (!type_.compare(
"FixedPoint")) {
36 solveFixedPoint(problem,valuesForExport);
38 else if(!type_.compare(
"Newton")){
39 solveNewton(problem,valuesForExport);
41 else if(!type_.compare(
"NOX")){
43 solveNOX(problem,valuesForExport);
49template<
class SC,
class LO,
class GO,
class NO>
52 if (!type_.compare(
"FixedPoint")) {
53 solveFixedPoint(problem,time);
55 else if(!type_.compare(
"Newton")){
56 solveNewton(problem,time, valuesForExport);
58 else if(!type_.compare(
"NOX")){
60 solveNOX(problem, valuesForExport);
63 else if(!type_.compare(
"Extrapolation")){
64 solveExtrapolation(problem, time);
69template<
class SC,
class LO,
class GO,
class NO>
72 bool verbose = problem.getVerbose();
73 Teuchos::RCP<NonLinearProblem<SC,LO,GO,NO> > problemPtr = Teuchos::rcpFromRef(problem);
74 Teuchos::RCP<Teuchos::ParameterList> p = sublist(problemPtr->getParameterList(),
"ThyraSolver");
77 problemPtr->getLinearSolverBuilder()->setParameterList(p);
79 Teuchos::RCP<Thyra::LinearOpWithSolveFactoryBase<SC> > lowsFactory = problemPtr->getLinearSolverBuilder()->createLinearSolveStrategy(
"");
84 Teuchos::RCP<Thyra::VectorBase<SC> > initial_guess = problemPtr->getNominalValues().get_x()->clone_v();
85 Thyra::V_S(initial_guess.ptr(),Teuchos::ScalarTraits<SC>::zero());
87 Teuchos::RCP<Thyra::LinearOpBase<SC> > W_op = problemPtr->create_W_op();
88 Teuchos::RCP<Thyra::PreconditionerBase<SC> > W_prec = problemPtr->create_W_prec();
94 Teuchos::RCP<NOX::Thyra::Group> nox_group(
new NOX::Thyra::Group(initial_guess,
95 problemPtr.getConst(),
97 lowsFactory.getConst(),
103 nox_group->computeF();
108 Teuchos::RCP<NOX::StatusTest::NormUpdate> updateTol =
109 Teuchos::rcp(
new NOX::StatusTest::NormUpdate( problemPtr->getParameterList()->sublist(
"Parameter").get(
"updateTol",1.0e-6) ) );
111 Teuchos::RCP<NOX::StatusTest::RelativeNormF> relresid =
112 Teuchos::rcp(
new NOX::StatusTest::RelativeNormF( problemPtr->getParameterList()->sublist(
"Parameter").get(
"relNonLinTol",1.0e-4) ) );
114 Teuchos::RCP<NOX::StatusTest::NormWRMS> wrms =
115 Teuchos::rcp(
new NOX::StatusTest::NormWRMS(problemPtr->getParameterList()->sublist(
"Parameter").get(
"relNonLinTol",1.0e-4), problemPtr->getParameterList()->sublist(
"Parameter").get(
"absNonLinTol",1.0e-6)));
117 Teuchos::RCP<NOX::StatusTest::NormF> absRes =
118 Teuchos::rcp(
new NOX::StatusTest::NormF( problemPtr->getParameterList()->sublist(
"Parameter").get(
"absNonLinTol",1.0e-6) ) );
120 Teuchos::RCP<NOX::StatusTest::Combo> converged;
122 if ( !problemPtr->getParameterList()->sublist(
"Parameter").get(
"Combo",
"AND").compare(
"AND") )
123 converged = Teuchos::rcp(
new NOX::StatusTest::Combo(NOX::StatusTest::Combo::AND));
124 else if (!problemPtr->getParameterList()->sublist(
"Parameter").get(
"Combo",
"AND").compare(
"OR") )
125 converged = Teuchos::rcp(
new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR));
127 if ( problemPtr->getParameterList()->sublist(
"Parameter").get(
"Use rel tol",
true) )
128 converged->addStatusTest(relresid);
129 if ( problemPtr->getParameterList()->sublist(
"Parameter").get(
"Use update tol",
false) )
130 converged->addStatusTest(updateTol);
131 if (problemPtr->getParameterList()->sublist(
"Parameter").get(
"Use WRMS",
false))
132 converged->addStatusTest(wrms);
133 if (problemPtr->getParameterList()->sublist(
"Parameter").get(
"Use abs tol",
false))
134 converged->addStatusTest(absRes);
136 Teuchos::RCP<NOX::StatusTest::MaxIters> maxiters =
137 Teuchos::rcp(
new NOX::StatusTest::MaxIters(problemPtr->getParameterList()->sublist(
"Parameter").get(
"MaxNonLinIts",10)));
138 Teuchos::RCP<NOX::StatusTest::FiniteValue> fv =
139 Teuchos::rcp(
new NOX::StatusTest::FiniteValue);
140 Teuchos::RCP<NOX::StatusTest::Combo> combo =
141 Teuchos::rcp(
new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR));
142 combo->addStatusTest(fv);
143 combo->addStatusTest(converged);
144 combo->addStatusTest(maxiters);
147 Teuchos::RCP<Teuchos::ParameterList> nl_params = sublist(problemPtr->getParameterList(),
"NOXSolver");
150 Teuchos::RCP<NOX::Solver::Generic> solver = NOX::Solver::buildSolver(nox_group, combo, nl_params);
151 NOX::StatusTest::StatusType solveStatus = solver->solve();
152 double nonLinearIts = solver->getSolverStatistics()->linearSolve.allNonlinearSolves_NumLinearSolves;
153 double linearIts = solver->getSolverStatistics()->linearSolve.allNonlinearSolves_NumLinearIterations;
155 linearIts/=nonLinearIts;
157 std::cout <<
"############################################################" << std::endl;
158 std::cout <<
"### Total nonlinear iterations : " << nonLinearIts <<
" with an average of " << linearIts <<
" linear iterations ###" << std::endl;
159 std::cout <<
"############################################################" << std::endl;
162 if ( problemPtr->getParameterList()->sublist(
"Parameter").get(
"Cancel MaxNonLinIts",
false) ) {
163 TEUCHOS_TEST_FOR_EXCEPTION((
int)nonLinearIts == problemPtr->getParameterList()->sublist(
"Parameter").get(
"MaxNonLinIts",10) ,std::runtime_error,
"Maximum nonlinear Iterations reached. Problem might have converged in the last step. Still we cancel here.");
165 nonLinearIts_ = nonLinearIts;
169template<
class SC,
class LO,
class GO,
class NO>
172 bool verbose = problem.getVerbose();
173 Teuchos::RCP<TimeProblem_Type> problemPtr = Teuchos::rcpFromRef(problem);
174 Teuchos::RCP<Teuchos::ParameterList> p = sublist(problemPtr->getParameterList(),
"ThyraSolver");
176 problemPtr->getLinearSolverBuilder()->setParameterList(p);
178 Teuchos::RCP<Thyra::LinearOpWithSolveFactoryBase<SC> >
179 lowsFactory = problemPtr->getLinearSolverBuilder()->createLinearSolveStrategy(
"");
181 TEUCHOS_TEST_FOR_EXCEPTION(problemPtr->getSolution()->getNumVectors()>1, std::runtime_error,
"With the current implementation NOX can only be used with 1 MultiVector column.");
183 Teuchos::RCP<Thyra::VectorBase<SC> > initialGuess = problemPtr->getNominalValues().get_x()->clone_v();
185 Teuchos::RCP<Thyra::ProductVectorBase<SC> > initialGuessProd = Teuchos::rcp_dynamic_cast<Thyra::ProductVectorBase<SC> >(initialGuess);
186 Teuchos::RCP<Thyra::MultiVectorBase<SC> > solMV;
187 if (!initialGuessProd.is_null())
188 solMV = problemPtr->getSolution()->getProdThyraMultiVector();
190 solMV = problemPtr->getSolution()->getThyraMultiVector();
192 Thyra::assign(initialGuess.ptr(), *solMV->col(0));
194 Teuchos::RCP<Thyra::LinearOpBase<SC> > W_op = problemPtr->create_W_op();
195 Teuchos::RCP<Thyra::PreconditionerBase<SC> > W_prec = problemPtr->create_W_prec();
198 Teuchos::RCP<NOX::Thyra::Group> nox_group(
new NOX::Thyra::Group(initialGuess,
199 problemPtr.getConst(),
201 lowsFactory.getConst(),
207 nox_group->computeF();
211 Teuchos::RCP<NOX::StatusTest::NormUpdate> updateTol =
212 Teuchos::rcp(
new NOX::StatusTest::NormUpdate( problemPtr->getParameterList()->sublist(
"Parameter").get(
"updateTol",1.0e-6) ) );
214 Teuchos::RCP<NOX::StatusTest::RelativeNormF> relresid =
215 Teuchos::rcp(
new NOX::StatusTest::RelativeNormF( problemPtr->getParameterList()->sublist(
"Parameter").get(
"relNonLinTol",1.0e-4) ) );
217 Teuchos::RCP<NOX::StatusTest::NormWRMS> wrms =
218 Teuchos::rcp(
new NOX::StatusTest::NormWRMS(problemPtr->getParameterList()->sublist(
"Parameter").get(
"relNonLinTol",1.0e-4), problemPtr->getParameterList()->sublist(
"Parameter").get(
"absNonLinTol",1.0e-6)));
220 Teuchos::RCP<NOX::StatusTest::NormF> absRes =
221 Teuchos::rcp(
new NOX::StatusTest::NormF( problemPtr->getParameterList()->sublist(
"Parameter").get(
"absNonLinTol",1.0e-6) ) );
223 Teuchos::RCP<NOX::StatusTest::Combo> converged;
225 if ( !problemPtr->getParameterList()->sublist(
"Parameter").get(
"Combo",
"AND").compare(
"AND") )
226 converged = Teuchos::rcp(
new NOX::StatusTest::Combo(NOX::StatusTest::Combo::AND));
227 else if (!problemPtr->getParameterList()->sublist(
"Parameter").get(
"Combo",
"AND").compare(
"OR") )
228 converged = Teuchos::rcp(
new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR));
230 if ( problemPtr->getParameterList()->sublist(
"Parameter").get(
"Use rel tol",
true) )
231 converged->addStatusTest(relresid);
232 if ( problemPtr->getParameterList()->sublist(
"Parameter").get(
"Use update tol",
false) )
233 converged->addStatusTest(updateTol);
234 if (problemPtr->getParameterList()->sublist(
"Parameter").get(
"Use WRMS",
false))
235 converged->addStatusTest(wrms);
236 if (problemPtr->getParameterList()->sublist(
"Parameter").get(
"Use abs tol",
false))
237 converged->addStatusTest(absRes);
239 Teuchos::RCP<NOX::StatusTest::MaxIters> maxiters =
240 Teuchos::rcp(
new NOX::StatusTest::MaxIters(problemPtr->getParameterList()->sublist(
"Parameter").get(
"MaxNonLinIts",10)));
241 Teuchos::RCP<NOX::StatusTest::FiniteValue> fv =
242 Teuchos::rcp(
new NOX::StatusTest::FiniteValue);
243 Teuchos::RCP<NOX::StatusTest::Combo> combo =
244 Teuchos::rcp(
new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR));
245 combo->addStatusTest(fv);
246 combo->addStatusTest(converged);
247 combo->addStatusTest(maxiters);
250 Teuchos::RCP<Teuchos::ParameterList> nl_params = sublist(problemPtr->getParameterList(),
"NOXSolver");
253 Teuchos::RCP<NOX::Solver::Generic> solver =
254 NOX::Solver::buildSolver(nox_group, combo, nl_params);
255 NOX::StatusTest::StatusType solveStatus = solver->solve();
257 double nonLinearIts = solver->getSolverStatistics()->linearSolve.allNonlinearSolves_NumLinearSolves;
258 double linearIts = solver->getSolverStatistics()->linearSolve.allNonlinearSolves_NumLinearIterations;
260 linearIts/=nonLinearIts;
262 std::cout <<
"############################################################" << std::endl;
263 std::cout <<
"### Total nonlinear iterations : " << nonLinearIts <<
" with an average of " << linearIts <<
" linear iterations ###" << std::endl;
264 std::cout <<
"############################################################" << std::endl;
267 if ( problemPtr->getParameterList()->sublist(
"Parameter").get(
"Cancel MaxNonLinIts",
false) ) {
268 TEUCHOS_TEST_FOR_EXCEPTION((
int)nonLinearIts == problemPtr->getParameterList()->sublist(
"Parameter").get(
"MaxNonLinIts",10) ,std::runtime_error,
"Maximum nonlinear Iterations reached. Problem might have converged in the last step. Still we cancel here.");
271 if (!valuesForExport.is_null()) {
272 if (valuesForExport->size() == 2){
273 (*valuesForExport)[0] = linearIts;
274 (*valuesForExport)[1] = nonLinearIts;
280template<
class SC,
class LO,
class GO,
class NO>
281void NonLinearSolver<SC,LO,GO,NO>::solveFixedPoint(NonLinearProblem_Type &problem,vec_dbl_ptr_Type valuesForExport){
283 bool verbose = problem.getVerbose();
284 TEUCHOS_TEST_FOR_EXCEPTION(problem.getRhs()->getNumVectors()!=1,std::logic_error,
"We need to change the code for numVectors>1.");
288 double gmresIts = 0.;
289 double residual0 = 1.;
290 double residual = 1.;
292 double tol = problem.getParameterList()->sublist(
"Parameter").get(
"relNonLinTol",1.0e-6);
293 int maxNonLinIts = problem.getParameterList()->sublist(
"Parameter").get(
"MaxNonLinIts",10);
296 double criterionValue = 1.;
297 std::string criterion = problem.getParameterList()->sublist(
"Parameter").get(
"Criterion",
"Residual");
299 while ( nlIts < maxNonLinIts ) {
301 problem.calculateNonLinResidualVec(
"reverse");
303 problem.setBoundariesSystem();
305 if (criterion==
"Residual")
306 residual = problem.calculateResidualNorm();
309 residual0 = residual;
311 if (criterion==
"Residual"){
312 criterionValue = residual/residual0;
314 std::cout <<
"### Fixed Point iteration : " << nlIts <<
" relative nonlinear residual : " << criterionValue << std::endl;
315 if ( criterionValue < tol )
320 gmresIts += problem.solveAndUpdate( criterion, criterionValue );
322 if(criterion==
"Update"){
324 std::cout <<
"### Fixed Point iteration : " << nlIts <<
" residual of update : " << criterionValue << std::endl;
325 if ( criterionValue < tol )
333 std::cout <<
"### Total FPI : " << nlIts <<
" with average gmres its : " << gmresIts << std::endl;
334 if ( problem.getParameterList()->sublist(
"Parameter").get(
"Cancel MaxNonLinIts",
false) ) {
335 TEUCHOS_TEST_FOR_EXCEPTION( nlIts == maxNonLinIts ,std::runtime_error,
"Maximum nonlinear Iterations reached. Problem might have converged in the last step. Still we cancel here.");
340template<
class SC,
class LO,
class GO,
class NO>
341void NonLinearSolver<SC,LO,GO,NO>::solveNewton( NonLinearProblem_Type &problem, vec_dbl_ptr_Type valuesForExport ){
343 bool verbose = problem.getVerbose();
345 TEUCHOS_TEST_FOR_EXCEPTION(problem.getRhs()->getNumVectors()!=1,std::logic_error,
"We need to change the code for numVectors>1.")
349 double gmresIts = 0.;
350 double residual0 = 1.;
351 double residual = 1.;
352 double tol = problem.getParameterList()->sublist(
"Parameter").get(
"relNonLinTol",1.0e-6);
354 int maxNonLinIts = problem.getParameterList()->sublist(
"Parameter").get(
"MaxNonLinIts",10);
355 double criterionValue = 1.;
356 std::
string criterion = problem.getParameterList()->sublist(
"Parameter").get(
"Criterion",
"Residual");
358 while ( nlIts < maxNonLinIts ) {
361 problem.calculateNonLinResidualVec(
"reverse");
363 if (criterion==
"Residual")
364 residual = problem.calculateResidualNorm();
366 problem.assemble(
"Newton");
368 problem.setBoundariesSystem();
371 residual0 = residual;
373 if (criterion==
"Residual"){
374 criterionValue = residual/residual0;
376 std::cout <<
"### Newton iteration : " << nlIts <<
" relative nonlinear residual : " << criterionValue << std::endl;
377 if ( criterionValue < tol )
381 gmresIts += problem.solveAndUpdate( criterion, criterionValue );
383 if(criterion==
"Update"){
385 std::cout <<
"### Newton iteration : " << nlIts <<
" residual of update : " << criterionValue << std::endl;
386 if ( criterionValue < tol )
395 std::cout <<
"### Total Newton iterations : " << nlIts <<
" with average gmres its : " << gmresIts << std::endl;
396 if ( problem.getParameterList()->sublist(
"Parameter").get(
"Cancel MaxNonLinIts",
false) ) {
397 TEUCHOS_TEST_FOR_EXCEPTION(nlIts == maxNonLinIts ,std::runtime_error,
"Maximum nonlinear Iterations reached. Problem might have converged in the last step. Still we cancel here.");
400 if (!valuesForExport.is_null()) {
401 if (valuesForExport->size() == 2){
402 (*valuesForExport)[0] = gmresIts;
403 (*valuesForExport)[1] = nlIts;
408template<
class SC,
class LO,
class GO,
class NO>
409void NonLinearSolver<SC,LO,GO,NO>::solveFixedPoint(TimeProblem_Type &problem,
double time){
411 bool verbose = problem.getVerbose();
412 problem.setBoundariesRHS(time);
413 TEUCHOS_TEST_FOR_EXCEPTION(problem.getRhs()->getNumVectors()!=1,std::logic_error,
"We need to change the code for numVectors>1.")
418 double gmresIts = 0.;
419 double residual0 = 1.;
420 double residual = 1.;
421 double tol = problem.getParameterList()->sublist(
"Parameter").get(
"relNonLinTol",1.0e-6);
423 int maxNonLinIts = problem.getParameterList()->sublist(
"Parameter").get(
"MaxNonLinIts",10);
424 double criterionValue = 1.;
425 std::
string criterion = problem.getParameterList()->sublist(
"Parameter").get(
"Criterion",
"Residual");
427 while ( nlIts < maxNonLinIts ) {
429 problem.calculateNonLinResidualVec(
"reverse", time);
431 if (criterion==
"Residual")
432 residual = problem.calculateResidualNorm();
435 residual0 = residual;
439 problem.combineSystems();
441 problem.setBoundariesSystem();
443 if (criterion==
"Residual"){
444 criterionValue = residual/residual0;
446 std::cout <<
"### Fixed Point iteration : " << nlIts <<
" relative nonlinear residual : " << criterionValue << std::endl;
447 if ( criterionValue < tol )
451 gmresIts += problem.solveAndUpdate( criterion, criterionValue );
454 if(criterion==
"Update"){
456 std::cout <<
"### Fixed Point iteration : " << nlIts <<
" residual of update : " << criterionValue << std::endl;
457 if ( criterionValue < tol )
465 std::cout <<
"### Total FPI : " << nlIts <<
" with average gmres its : " << gmresIts << std::endl;
466 if ( problem.getParameterList()->sublist(
"Parameter").get(
"Cancel MaxNonLinIts",
false) ) {
467 TEUCHOS_TEST_FOR_EXCEPTION( nlIts == maxNonLinIts ,std::runtime_error,
"Maximum nonlinear Iterations reached. Problem might have converged in the last step. Still we cancel here.");
473template<
class SC,
class LO,
class GO,
class NO>
474void NonLinearSolver<SC,LO,GO,NO>::solveNewton(TimeProblem_Type &problem,
double time, vec_dbl_ptr_Type valuesForExport ){
476 bool verbose = problem.getVerbose();
477 problem.setBoundariesRHS(time);
480 TEUCHOS_TEST_FOR_EXCEPTION(problem.getRhs()->getNumVectors()!=1,std::logic_error,
"We need to change the code for numVectors>1.")
485 double gmresIts = 0.;
486 double residual0 = 1.;
487 double residual = 1.;
488 double tol = problem.getParameterList()->sublist(
"Parameter").get(
"relNonLinTol",1.0e-6);
490 int maxNonLinIts = problem.getParameterList()->sublist(
"Parameter").get(
"MaxNonLinIts",10);
491 double criterionValue = 1.;
492 std::
string criterion = problem.getParameterList()->sublist(
"Parameter").get(
"Criterion",
"Residual");
493 std::
string timestepping = problem.getParameterList()->sublist(
"Timestepping Parameter").get(
"Class",
"Singlestep");
495 while ( nlIts < maxNonLinIts ) {
496 if (timestepping ==
"External")
497 problem.calculateNonLinResidualVec(
"external", time);
499 problem.calculateNonLinResidualVec(
"reverse", time);
500 if (criterion==
"Residual")
501 residual = problem.calculateResidualNorm();
504 residual0 = residual;
506 if (criterion==
"Residual"){
507 criterionValue = residual/residual0;
510 std::cout <<
"### Newton iteration : " << nlIts <<
" relative nonlinear residual : " << criterionValue << std::endl;
511 if ( criterionValue < tol )
516 problem.assemble(
"Newton");
518 problem.setBoundariesSystem();
520 problem.getSystem()->writeMM(
"Assembled");
523 if (timestepping ==
"External"){
524 gmresIts += problem.solveAndUpdate(
"ResidualAceGen", criterionValue );
530 gmresIts += problem.solveAndUpdate( criterion, criterionValue );
535 if(criterion==
"Update"){
537 std::cout <<
"### Newton iteration : " << nlIts <<
" residual of update : " << criterionValue << std::endl;
538 if ( criterionValue < tol )
547 std::cout <<
"### Total Newton iteration : " << nlIts <<
" with average gmres its : " << gmresIts << std::endl;
548 if ( problem.getParameterList()->sublist(
"Parameter").get(
"Cancel MaxNonLinIts",
false) ) {
549 TEUCHOS_TEST_FOR_EXCEPTION(nlIts == maxNonLinIts ,std::runtime_error,
"Maximum nonlinear Iterations reached. Problem might have converged in the last step. Still we cancel here.");
551 if (!valuesForExport.is_null()) {
552 if (valuesForExport->size() == 2){
553 (*valuesForExport)[0] = gmresIts;
554 (*valuesForExport)[1] = nlIts;
563template<
class SC,
class LO,
class GO,
class NO>
564void NonLinearSolver<SC,LO,GO,NO>::solveExtrapolation(TimeProblem<SC,LO,GO,NO> &problem,
double time){
566 bool verbose = problem.getVerbose();
568 problem.assemble(
"Extrapolation");
570 problem.setBoundaries(time);
572 int gmresIts = problem.solve( );
575 std::cout <<
"### GMRES Its : " << gmresIts << std::endl;
Definition NonLinearSolver_decl.hpp:32
void solve(NonLinearProblem_Type &problem, vec_dbl_ptr_Type valuesForExport=Teuchos::null)
Call for solving a nonlinear problem, depending on linearization solveNOX/solveFixedPoint/solveNewton...
Definition NonLinearSolver_def.hpp:33
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement_decl.hpp:33