diff --git a/dumux/nonlinear/newtonsolver.hh b/dumux/nonlinear/newtonsolver.hh index 82f9eca3de8b4fe84564362b67d6c6630fe32759..9a101fabbdbf980566eeefcf3615327a9a1ca171 100644 --- a/dumux/nonlinear/newtonsolver.hh +++ b/dumux/nonlinear/newtonsolver.hh @@ -168,8 +168,8 @@ public: { maxSteps_ = maxSteps; } /*! - * \brief Run the newton method to solve a non-linear system. - * Does time step control when the newton fails to converge + * \brief Run the Newton method to solve a non-linear system. + * Does time step control when the Newton fails to converge */ template<class TimeLoop> void solve(SolutionVector& uCurrentIter, TimeLoop& timeLoop, @@ -214,7 +214,7 @@ public: } /*! - * \brief Run the newton method to solve a non-linear system. + * \brief Run the Newton method to solve a non-linear system. * The solver is responsible for all the strategic decisions. */ void solve(SolutionVector& uCurrentIter, const std::unique_ptr<ConvergenceWriter>& convWriter = nullptr) @@ -429,7 +429,7 @@ public: else { // If we get here, the convergence criterion does not require - // additional residual evalutions. Thus, the grid variables have + // additional residual evaluations. Thus, the grid variables have // not yet been updated to the new uCurrentIter. assembler_->updateGridVariables(uCurrentIter); } @@ -472,7 +472,7 @@ public: endIterMsgStream_.str(""); // When the Newton iterations are done: ask the model to check whether it makes sense - // TODO: how do we realize this? -> do this here in the newton solver + // TODO: how do we realize this? -> do this here in the Newton solver // model_().checkPlausibility(); } @@ -525,11 +525,37 @@ public: virtual void newtonFail(SolutionVector& u) {} /*! - * \brief Called if the Newton method ended succcessfully + * \brief Called if the Newton method ended successfully * This method is called _after_ newtonEnd() */ virtual void newtonSucceed() {} + /*! + * \brief output statistics / report + */ + void report(std::ostream& sout = std::cout) const + { + if (verbose_) + sout << '\n' + << "Newton statistics\n" + << "----------------------------------------------\n" + << "-- Total Newton iterations: " << totalWastedIter_ + totalSucceededIter_ << '\n' + << "-- Total wasted Newton iterations: " << totalWastedIter_ << '\n' + << "-- Total succeeded Newton iterations: " << totalSucceededIter_ << '\n' + << "-- Average iterations per solve: " << std::setprecision(3) << double(totalSucceededIter_) / double(numConverged_) << '\n' + << std::endl; + } + + /*! + * \brief reset the statistics + */ + void resetReport() + { + totalWastedIter_ = 0; + totalSucceededIter_ = 0; + numConverged_ = 0; + } + /*! * \brief Suggest a new time-step size based on the old time-step * size. @@ -620,7 +646,7 @@ protected: private: /*! - * \brief Run the newton method to solve a non-linear system. + * \brief Run the Newton method to solve a non-linear system. * The solver is responsible for all the strategic decisions. */ bool solve_(SolutionVector& uCurrentIter, const std::unique_ptr<ConvergenceWriter>& convWriter = nullptr) @@ -723,13 +749,17 @@ private: // tell solver we are done newtonEnd(); - // reset state if newton failed + // reset state if Newton failed if (!newtonConverged()) { + totalWastedIter_ += numSteps_; newtonFail(uCurrentIter); return false; } + totalSucceededIter_ += numSteps_; + numConverged_++; + // tell solver we converged successfully newtonSucceed(); @@ -748,6 +778,8 @@ private: { if (verbose_) std::cout << "Newton: Caught exception: \"" << e.what() << "\"\n"; + + totalWastedIter_ += numSteps_; newtonFail(uCurrentIter); return false; } @@ -1108,6 +1140,11 @@ private: Scalar reassemblyMinThreshold_; Scalar reassemblyMaxThreshold_; Scalar reassemblyShiftWeight_; + + // statistics for the optional report + std::size_t totalWastedIter_ = 0; //! Newton steps in solves that didn't converge + std::size_t totalSucceededIter_ = 0; //! Newton steps in solves that converged + std::size_t numConverged_ = 0; //! total number of converged solves }; } // end namespace Dumux diff --git a/test/porousmediumflow/2p/implicit/incompressible/test_2p_fv.cc b/test/porousmediumflow/2p/implicit/incompressible/test_2p_fv.cc index ecb43e481412eb9564ce1262c55746156f217e24..daac6cf940a40adec59f2530569db2aa503375e8 100644 --- a/test/porousmediumflow/2p/implicit/incompressible/test_2p_fv.cc +++ b/test/porousmediumflow/2p/implicit/incompressible/test_2p_fv.cc @@ -200,6 +200,9 @@ int main(int argc, char** argv) try } while (!timeLoop->finished()); + // output some Newton statistics + nonLinearSolver.report(); + timeLoop->finalize(leafGridView.comm()); ////////////////////////////////////////////////////////////