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>
33void NonLinearSolver<SC,LO,GO,NO>::solve(NonLinearProblem_Type &problem){
35 if (!type_.compare(
"FixedPoint")) {
36 solveFixedPoint(problem);
38 else if(!type_.compare(
"Newton")){
41 else if(!type_.compare(
"NOX")){
49template<
class SC,
class LO,
class GO,
class NO>
50void NonLinearSolver<SC,LO,GO,NO>::solve(TimeProblem_Type &problem,
double time, vec_dbl_ptr_Type valuesForExport){
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>
70void NonLinearSolver<SC,LO,GO,NO>::solveNOX(NonLinearProblem_Type &problem){
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();
89 Teuchos::RCP<NOX::Thyra::Group> nox_group(
new NOX::Thyra::Group(initial_guess,
90 problemPtr.getConst(),
92 lowsFactory.getConst(),
98 nox_group->computeF();
103 Teuchos::RCP<NOX::StatusTest::NormUpdate> updateTol =
104 Teuchos::rcp(
new NOX::StatusTest::NormUpdate( problemPtr->getParameterList()->sublist(
"Parameter").get(
"updateTol",1.0e-6) ) );
106 Teuchos::RCP<NOX::StatusTest::RelativeNormF> relresid =
107 Teuchos::rcp(
new NOX::StatusTest::RelativeNormF( problemPtr->getParameterList()->sublist(
"Parameter").get(
"relNonLinTol",1.0e-4) ) );
109 Teuchos::RCP<NOX::StatusTest::NormWRMS> wrms =
110 Teuchos::rcp(
new NOX::StatusTest::NormWRMS(problemPtr->getParameterList()->sublist(
"Parameter").get(
"relNonLinTol",1.0e-4), problemPtr->getParameterList()->sublist(
"Parameter").get(
"absNonLinTol",1.0e-6)));
112 Teuchos::RCP<NOX::StatusTest::NormF> absRes =
113 Teuchos::rcp(
new NOX::StatusTest::NormF( problemPtr->getParameterList()->sublist(
"Parameter").get(
"absNonLinTol",1.0e-6) ) );
115 Teuchos::RCP<NOX::StatusTest::Combo> converged;
117 if ( !problemPtr->getParameterList()->sublist(
"Parameter").get(
"Combo",
"AND").compare(
"AND") )
118 converged = Teuchos::rcp(
new NOX::StatusTest::Combo(NOX::StatusTest::Combo::AND));
119 else if (!problemPtr->getParameterList()->sublist(
"Parameter").get(
"Combo",
"AND").compare(
"OR") )
120 converged = Teuchos::rcp(
new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR));
122 if ( problemPtr->getParameterList()->sublist(
"Parameter").get(
"Use rel tol",
true) )
123 converged->addStatusTest(relresid);
124 if ( problemPtr->getParameterList()->sublist(
"Parameter").get(
"Use update tol",
false) )
125 converged->addStatusTest(updateTol);
126 if (problemPtr->getParameterList()->sublist(
"Parameter").get(
"Use WRMS",
false))
127 converged->addStatusTest(wrms);
128 if (problemPtr->getParameterList()->sublist(
"Parameter").get(
"Use abs tol",
false))
129 converged->addStatusTest(absRes);
131 Teuchos::RCP<NOX::StatusTest::MaxIters> maxiters =
132 Teuchos::rcp(
new NOX::StatusTest::MaxIters(problemPtr->getParameterList()->sublist(
"Parameter").get(
"MaxNonLinIts",10)));
133 Teuchos::RCP<NOX::StatusTest::FiniteValue> fv =
134 Teuchos::rcp(
new NOX::StatusTest::FiniteValue);
135 Teuchos::RCP<NOX::StatusTest::Combo> combo =
136 Teuchos::rcp(
new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR));
137 combo->addStatusTest(fv);
138 combo->addStatusTest(converged);
139 combo->addStatusTest(maxiters);
142 Teuchos::RCP<Teuchos::ParameterList> nl_params = sublist(problemPtr->getParameterList(),
"NOXSolver");
145 Teuchos::RCP<NOX::Solver::Generic> solver = NOX::Solver::buildSolver(nox_group, combo, nl_params);
146 NOX::StatusTest::StatusType solveStatus = solver->solve();
147 double nonLinearIts = solver->getSolverStatistics()->linearSolve.allNonlinearSolves_NumLinearSolves;
148 double linearIts = solver->getSolverStatistics()->linearSolve.allNonlinearSolves_NumLinearIterations;
150 linearIts/=nonLinearIts;
152 std::cout <<
"############################################################" << std::endl;
153 std::cout <<
"### Total nonlinear iterations : " << nonLinearIts <<
" with an average of " << linearIts <<
" linear iterations ###" << std::endl;
154 std::cout <<
"############################################################" << std::endl;
157 if ( problemPtr->getParameterList()->sublist(
"Parameter").get(
"Cancel MaxNonLinIts",
false) ) {
158 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.");
160 nonLinearIts_ = nonLinearIts;
164template<
class SC,
class LO,
class GO,
class NO>
165void NonLinearSolver<SC,LO,GO,NO>::solveNOX(TimeProblem_Type &problem, vec_dbl_ptr_Type valuesForExport){
167 bool verbose = problem.getVerbose();
168 Teuchos::RCP<TimeProblem_Type> problemPtr = Teuchos::rcpFromRef(problem);
169 Teuchos::RCP<Teuchos::ParameterList> p = sublist(problemPtr->getParameterList(),
"ThyraSolver");
171 problemPtr->getLinearSolverBuilder()->setParameterList(p);
173 Teuchos::RCP<Thyra::LinearOpWithSolveFactoryBase<SC> >
174 lowsFactory = problemPtr->getLinearSolverBuilder()->createLinearSolveStrategy(
"");
176 TEUCHOS_TEST_FOR_EXCEPTION(problemPtr->getSolution()->getNumVectors()>1, std::runtime_error,
"With the current implementation NOX can only be used with 1 MultiVector column.");
178 Teuchos::RCP<Thyra::VectorBase<SC> > initialGuess = problemPtr->getNominalValues().get_x()->clone_v();
180 Teuchos::RCP<Thyra::ProductVectorBase<SC> > initialGuessProd = Teuchos::rcp_dynamic_cast<Thyra::ProductVectorBase<SC> >(initialGuess);
181 Teuchos::RCP<Thyra::MultiVectorBase<SC> > solMV;
182 if (!initialGuessProd.is_null())
183 solMV = problemPtr->getSolution()->getProdThyraMultiVector();
185 solMV = problemPtr->getSolution()->getThyraMultiVector();
187 Thyra::assign(initialGuess.ptr(), *solMV->col(0));
189 Teuchos::RCP<Thyra::LinearOpBase<SC> > W_op = problemPtr->create_W_op();
190 Teuchos::RCP<Thyra::PreconditionerBase<SC> > W_prec = problemPtr->create_W_prec();
191 Teuchos::RCP<NOX::Thyra::Group> nox_group(
new NOX::Thyra::Group(initialGuess,
192 problemPtr.getConst(),
194 lowsFactory.getConst(),
200 nox_group->computeF();
204 Teuchos::RCP<NOX::StatusTest::NormUpdate> updateTol =
205 Teuchos::rcp(
new NOX::StatusTest::NormUpdate( problemPtr->getParameterList()->sublist(
"Parameter").get(
"updateTol",1.0e-6) ) );
207 Teuchos::RCP<NOX::StatusTest::RelativeNormF> relresid =
208 Teuchos::rcp(
new NOX::StatusTest::RelativeNormF( problemPtr->getParameterList()->sublist(
"Parameter").get(
"relNonLinTol",1.0e-4) ) );
210 Teuchos::RCP<NOX::StatusTest::NormWRMS> wrms =
211 Teuchos::rcp(
new NOX::StatusTest::NormWRMS(problemPtr->getParameterList()->sublist(
"Parameter").get(
"relNonLinTol",1.0e-4), problemPtr->getParameterList()->sublist(
"Parameter").get(
"absNonLinTol",1.0e-6)));
213 Teuchos::RCP<NOX::StatusTest::NormF> absRes =
214 Teuchos::rcp(
new NOX::StatusTest::NormF( problemPtr->getParameterList()->sublist(
"Parameter").get(
"absNonLinTol",1.0e-6) ) );
216 Teuchos::RCP<NOX::StatusTest::Combo> converged;
218 if ( !problemPtr->getParameterList()->sublist(
"Parameter").get(
"Combo",
"AND").compare(
"AND") )
219 converged = Teuchos::rcp(
new NOX::StatusTest::Combo(NOX::StatusTest::Combo::AND));
220 else if (!problemPtr->getParameterList()->sublist(
"Parameter").get(
"Combo",
"AND").compare(
"OR") )
221 converged = Teuchos::rcp(
new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR));
223 if ( problemPtr->getParameterList()->sublist(
"Parameter").get(
"Use rel tol",
true) )
224 converged->addStatusTest(relresid);
225 if ( problemPtr->getParameterList()->sublist(
"Parameter").get(
"Use update tol",
false) )
226 converged->addStatusTest(updateTol);
227 if (problemPtr->getParameterList()->sublist(
"Parameter").get(
"Use WRMS",
false))
228 converged->addStatusTest(wrms);
229 if (problemPtr->getParameterList()->sublist(
"Parameter").get(
"Use abs tol",
false))
230 converged->addStatusTest(absRes);
232 Teuchos::RCP<NOX::StatusTest::MaxIters> maxiters =
233 Teuchos::rcp(
new NOX::StatusTest::MaxIters(problemPtr->getParameterList()->sublist(
"Parameter").get(
"MaxNonLinIts",10)));
234 Teuchos::RCP<NOX::StatusTest::FiniteValue> fv =
235 Teuchos::rcp(
new NOX::StatusTest::FiniteValue);
236 Teuchos::RCP<NOX::StatusTest::Combo> combo =
237 Teuchos::rcp(
new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR));
238 combo->addStatusTest(fv);
239 combo->addStatusTest(converged);
240 combo->addStatusTest(maxiters);
243 Teuchos::RCP<Teuchos::ParameterList> nl_params = sublist(problemPtr->getParameterList(),
"NOXSolver");
246 Teuchos::RCP<NOX::Solver::Generic> solver =
247 NOX::Solver::buildSolver(nox_group, combo, nl_params);
248 NOX::StatusTest::StatusType solveStatus = solver->solve();
250 double nonLinearIts = solver->getSolverStatistics()->linearSolve.allNonlinearSolves_NumLinearSolves;
251 double linearIts = solver->getSolverStatistics()->linearSolve.allNonlinearSolves_NumLinearIterations;
253 linearIts/=nonLinearIts;
255 std::cout <<
"############################################################" << std::endl;
256 std::cout <<
"### Total nonlinear iterations : " << nonLinearIts <<
" with an average of " << linearIts <<
" linear iterations ###" << std::endl;
257 std::cout <<
"############################################################" << std::endl;
260 if ( problemPtr->getParameterList()->sublist(
"Parameter").get(
"Cancel MaxNonLinIts",
false) ) {
261 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.");
264 if (!valuesForExport.is_null()) {
265 if (valuesForExport->size() == 2){
266 (*valuesForExport)[0] = linearIts;
267 (*valuesForExport)[1] = nonLinearIts;
273template<
class SC,
class LO,
class GO,
class NO>
274void NonLinearSolver<SC,LO,GO,NO>::solveFixedPoint(NonLinearProblem_Type &problem){
276 bool verbose = problem.getVerbose();
277 TEUCHOS_TEST_FOR_EXCEPTION(problem.getRhs()->getNumVectors()!=1,std::logic_error,
"We need to change the code for numVectors>1.");
281 double gmresIts = 0.;
282 double residual0 = 1.;
283 double residual = 1.;
285 double tol = problem.getParameterList()->sublist(
"Parameter").get(
"relNonLinTol",1.0e-6);
286 int maxNonLinIts = problem.getParameterList()->sublist(
"Parameter").get(
"MaxNonLinIts",10);
289 double criterionValue = 1.;
290 std::string criterion = problem.getParameterList()->sublist(
"Parameter").get(
"Criterion",
"Residual");
292 while ( nlIts < maxNonLinIts ) {
294 problem.calculateNonLinResidualVec(
"reverse");
296 problem.setBoundariesSystem();
298 if (criterion==
"Residual")
299 residual = problem.calculateResidualNorm();
302 residual0 = residual;
304 if (criterion==
"Residual"){
305 criterionValue = residual/residual0;
307 std::cout <<
"### Fixed Point iteration : " << nlIts <<
" relative nonlinear residual : " << criterionValue << std::endl;
308 if ( criterionValue < tol )
313 gmresIts += problem.solveAndUpdate( criterion, criterionValue );
315 if(criterion==
"Update"){
317 std::cout <<
"### Fixed Point iteration : " << nlIts <<
" residual of update : " << criterionValue << std::endl;
318 if ( criterionValue < tol )
326 std::cout <<
"### Total FPI : " << nlIts <<
" with average gmres its : " << gmresIts << std::endl;
327 if ( problem.getParameterList()->sublist(
"Parameter").get(
"Cancel MaxNonLinIts",
false) ) {
328 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.");
333template<
class SC,
class LO,
class GO,
class NO>
334void NonLinearSolver<SC,LO,GO,NO>::solveNewton( NonLinearProblem_Type &problem ){
336 bool verbose = problem.getVerbose();
338 TEUCHOS_TEST_FOR_EXCEPTION(problem.getRhs()->getNumVectors()!=1,std::logic_error,
"We need to change the code for numVectors>1.")
342 double gmresIts = 0.;
343 double residual0 = 1.;
344 double residual = 1.;
345 double tol = problem.getParameterList()->sublist(
"Parameter").get(
"relNonLinTol",1.0e-6);
347 int maxNonLinIts = problem.getParameterList()->sublist(
"Parameter").get(
"MaxNonLinIts",10);
348 double criterionValue = 1.;
349 std::
string criterion = problem.getParameterList()->sublist(
"Parameter").get(
"Criterion",
"Residual");
351 while ( nlIts < maxNonLinIts ) {
354 problem.calculateNonLinResidualVec(
"reverse");
356 if (criterion==
"Residual")
357 residual = problem.calculateResidualNorm();
359 problem.assemble(
"Newton");
361 problem.setBoundariesSystem();
364 residual0 = residual;
366 if (criterion==
"Residual"){
367 criterionValue = residual/residual0;
369 std::cout <<
"### Newton iteration : " << nlIts <<
" relative nonlinear residual : " << criterionValue << std::endl;
370 if ( criterionValue < tol )
374 gmresIts += problem.solveAndUpdate( criterion, criterionValue );
376 if(criterion==
"Update"){
378 std::cout <<
"### Newton iteration : " << nlIts <<
" residual of update : " << criterionValue << std::endl;
379 if ( criterionValue < tol )
388 std::cout <<
"### Total Newton iterations : " << nlIts <<
" with average gmres its : " << gmresIts << std::endl;
389 if ( problem.getParameterList()->sublist(
"Parameter").get(
"Cancel MaxNonLinIts",
false) ) {
390 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.");
394template<
class SC,
class LO,
class GO,
class NO>
395void NonLinearSolver<SC,LO,GO,NO>::solveFixedPoint(TimeProblem_Type &problem,
double time){
397 bool verbose = problem.getVerbose();
398 problem.setBoundariesRHS(time);
399 TEUCHOS_TEST_FOR_EXCEPTION(problem.getRhs()->getNumVectors()!=1,std::logic_error,
"We need to change the code for numVectors>1.")
404 double gmresIts = 0.;
405 double residual0 = 1.;
406 double residual = 1.;
407 double tol = problem.getParameterList()->sublist(
"Parameter").get(
"relNonLinTol",1.0e-6);
409 int maxNonLinIts = problem.getParameterList()->sublist(
"Parameter").get(
"MaxNonLinIts",10);
410 double criterionValue = 1.;
411 std::
string criterion = problem.getParameterList()->sublist(
"Parameter").get(
"Criterion",
"Residual");
413 while ( nlIts < maxNonLinIts ) {
415 problem.calculateNonLinResidualVec(
"reverse", time);
417 if (criterion==
"Residual")
418 residual = problem.calculateResidualNorm();
421 residual0 = residual;
425 problem.combineSystems();
427 problem.setBoundariesSystem();
429 if (criterion==
"Residual"){
430 criterionValue = residual/residual0;
432 std::cout <<
"### Fixed Point iteration : " << nlIts <<
" relative nonlinear residual : " << criterionValue << std::endl;
433 if ( criterionValue < tol )
437 gmresIts += problem.solveAndUpdate( criterion, criterionValue );
440 if(criterion==
"Update"){
442 std::cout <<
"### Fixed Point iteration : " << nlIts <<
" residual of update : " << criterionValue << std::endl;
443 if ( criterionValue < tol )
451 std::cout <<
"### Total FPI : " << nlIts <<
" with average gmres its : " << gmresIts << std::endl;
452 if ( problem.getParameterList()->sublist(
"Parameter").get(
"Cancel MaxNonLinIts",
false) ) {
453 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.");
459template<
class SC,
class LO,
class GO,
class NO>
460void NonLinearSolver<SC,LO,GO,NO>::solveNewton(TimeProblem_Type &problem,
double time, vec_dbl_ptr_Type valuesForExport ){
462 bool verbose = problem.getVerbose();
463 problem.setBoundariesRHS(time);
466 TEUCHOS_TEST_FOR_EXCEPTION(problem.getRhs()->getNumVectors()!=1,std::logic_error,
"We need to change the code for numVectors>1.")
471 double gmresIts = 0.;
472 double residual0 = 1.;
473 double residual = 1.;
474 double tol = problem.getParameterList()->sublist(
"Parameter").get(
"relNonLinTol",1.0e-6);
476 int maxNonLinIts = problem.getParameterList()->sublist(
"Parameter").get(
"MaxNonLinIts",10);
477 double criterionValue = 1.;
478 std::
string criterion = problem.getParameterList()->sublist(
"Parameter").get(
"Criterion",
"Residual");
479 std::
string timestepping = problem.getParameterList()->sublist(
"Timestepping Parameter").get(
"Class",
"Singlestep");
481 while ( nlIts < maxNonLinIts ) {
482 if (timestepping ==
"External")
483 problem.calculateNonLinResidualVec(
"external", time);
485 problem.calculateNonLinResidualVec(
"reverse", time);
486 if (criterion==
"Residual")
487 residual = problem.calculateResidualNorm();
490 residual0 = residual;
492 if (criterion==
"Residual"){
493 criterionValue = residual/residual0;
496 std::cout <<
"### Newton iteration : " << nlIts <<
" relative nonlinear residual : " << criterionValue << std::endl;
497 if ( criterionValue < tol )
502 problem.assemble(
"Newton");
504 problem.setBoundariesSystem();
506 problem.getSystem()->writeMM(
"Assembled");
509 if (timestepping ==
"External"){
510 gmresIts += problem.solveAndUpdate(
"ResidualAceGen", criterionValue );
516 gmresIts += problem.solveAndUpdate( criterion, criterionValue );
521 if(criterion==
"Update"){
523 std::cout <<
"### Newton iteration : " << nlIts <<
" residual of update : " << criterionValue << std::endl;
524 if ( criterionValue < tol )
533 std::cout <<
"### Total Newton iteration : " << nlIts <<
" with average gmres its : " << gmresIts << std::endl;
534 if ( problem.getParameterList()->sublist(
"Parameter").get(
"Cancel MaxNonLinIts",
false) ) {
535 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.");
537 if (!valuesForExport.is_null()) {
538 if (valuesForExport->size() == 2){
539 (*valuesForExport)[0] = gmresIts;
540 (*valuesForExport)[1] = nlIts;
549template<
class SC,
class LO,
class GO,
class NO>
550void NonLinearSolver<SC,LO,GO,NO>::solveExtrapolation(TimeProblem<SC,LO,GO,NO> &problem,
double time){
552 bool verbose = problem.getVerbose();
554 problem.assemble(
"Extrapolation");
556 problem.setBoundaries(time);
558 int gmresIts = problem.solve( );
561 std::cout <<
"### GMRES Its : " << gmresIts << std::endl;
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement.cpp:5