Int NonLinearRichardson( VectorEpetra& sol, Fct& functional, Real abstol, Real reltol, UInt& maxit, Real eta_max, Int NonLinearLineSearch, std::ofstream& out_res, const Real& time, UInt iter = UInt(0) ) { /* */ /* max_increase_res: maximum number of successive increases in residual before failure is reported */ // const Int max_increase_res = 5; /* Parameters for the linear solver, gamma: Default value = 0.9 */ const Real gamma = 0.9; //---------------------------------------------------------------------- bool const verbose(sol.comm().MyPID() == 0); //UInt iter = 0; VectorEpetra residual ( sol.map() ); VectorEpetra step ( sol.map() ); step *= 0.; Real normResOld = 1; if (verbose) { //std::cout << "------------------------------------------------------------------" << std::endl; std::cout << std::endl; std::cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl; std::cout << " Non-Linear Richardson: starting " << std::endl; std::cout << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl; std::cout << std::endl; //std::cout << "------------------------------------------------------------------" << std::endl; } functional.evalResidual( residual, sol, iter ); Real normRes = residual.normInf(); Real stop_tol = abstol + reltol*normRes; Real linearRelTol = std::fabs(eta_max); Real eta_old; Real eta_new; Real ratio; Real slope; Real linres; Real lambda; // Real solNormInf(sol.normInf()); Real stepNormInf; if (verbose) { out_res << std::scientific; out_res << "# time = "; out_res << time << " " << "initial norm_res " << normRes << " stop tol = " << stop_tol << "initial norm_sol " << solNormInf << std::endl; out_res << "#iter disp_norm step_norm residual_norm" << std::endl; } while ( normRes > stop_tol && iter < maxit ) { if (verbose) { std::cout << std::endl; //std::cout << "------------------------------------------------------------------" << std::endl; std::cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl; std::cout << " Non-Linear Richardson: iteration = " << iter << std::endl << " residual = " << normRes << std::endl << " tolerance = " << stop_tol << std::endl; std::cout << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl; std::cout << std::endl; //std::cout << "------------------------------------------------------------------" << std::endl; //std::cout << std::endl; } iter++; ratio = normRes/normResOld; normResOld = normRes; normRes = residual.normInf(); residual *= -1; functional.solveJac(step, residual, linearRelTol); // J*step = -R solNormInf = sol.normInf(); stepNormInf = step.normInf(); if (verbose) { out_res << std::setw(5) << iter << std::setw(15) << solNormInf << std::setw(15) << stepNormInf; } linres = linearRelTol; lambda = 1.; slope = normRes * normRes * ( linres * linres - 1 ); Int status(EXIT_SUCCESS); switch ( NonLinearLineSearch ) { case 0: // no NonLinearLineSearch sol += step; functional.evalResidual( residual, sol, iter); // normRes = residual.NormInf(); break; case 1: status = NonLinearLineSearchParabolic( functional, residual, sol, step, normRes, lambda, iter, verbose ); break; case 2: // recommended status = NonLinearLineSearchCubic( functional, residual, sol, step, normRes, lambda, slope, iter, verbose ); break; default: std::cout << "Unknown NonLinearLineSearch \n"; status = EXIT_FAILURE; } if (status == EXIT_FAILURE) return status; normRes = residual.normInf(); if (verbose) out_res << std::setw(15) << normRes << std::endl; if ( eta_max > 0 ) { eta_old = linearRelTol; eta_new = gamma * ratio * ratio; if ( gamma * eta_old * eta_old > .1 ) { eta_new = std::max<Real>( eta_new, gamma * eta_old * eta_old ); } linearRelTol = std::min<Real>( eta_new, eta_max ); linearRelTol = std::min<Real>( eta_max, std::max<Real>( linearRelTol, .5 * stop_tol / normRes ) ); //if (verbose) // std::cout << " Newton: forcing term eta = " << linearRelTol << std::endl; } } if ( normRes > stop_tol ) { if (verbose) std::cout << "!!! NonLinRichardson: convergence fails" << std::endl; maxit = iter; return EXIT_FAILURE; } if (verbose) { std::cout << std::endl; //std::cout << "------------------------------------------------------------------" << std::endl; std::cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl; std::cout << " Non-Linear Richardson: convergence = " << normRes << std::endl << " iterations = " << iter << std::endl; std::cout << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl; std::cout << std::endl; //std::cout << "------------------------------------------------------------------" << std::endl; } maxit = iter; return EXIT_SUCCESS; }