diff --git a/ebos/eclgenericwriter.hh b/ebos/eclgenericwriter.hh index 3288712ce..83d319781 100644 --- a/ebos/eclgenericwriter.hh +++ b/ebos/eclgenericwriter.hh @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -81,6 +82,16 @@ public: globalTrans_ = globalTrans; } + void setSubStepReport(const SimulatorReportSingle& report) + { + sub_step_report_ = report; + } + void setSimulationReport(const SimulatorReport& report) + { + simulation_report_ = report; + } + + protected: const TransmissibilityType& globalTrans() const; @@ -127,6 +138,8 @@ protected: const Dune::CartesianIndexMapper* equilCartMapper_; const EquilGrid* equilGrid_; std::vector wbp_index_list_; + SimulatorReportSingle sub_step_report_; + SimulatorReport simulation_report_; private: data::Solution computeTrans_(const std::unordered_map& cartesianToActive) const; diff --git a/ebos/eclproblem.hh b/ebos/eclproblem.hh index 9efdd017c..61c86a49b 100644 --- a/ebos/eclproblem.hh +++ b/ebos/eclproblem.hh @@ -70,6 +70,7 @@ #include #include +#include #include #include @@ -1970,6 +1971,12 @@ public: const EclipseIO& eclIO() const { return eclWriter_->eclIO(); } + void setSubStepReport(const SimulatorReportSingle& report) + { return eclWriter_->setSubStepReport(report); } + + void setSimulationReport(const SimulatorReport& report) + { return eclWriter_->setSimulationReport(report); } + bool nonTrivialBoundaryConditions() const { return nonTrivialBoundaryConditions_; } diff --git a/ebos/eclwriter.hh b/ebos/eclwriter.hh index 1cce99654..043dd58fa 100644 --- a/ebos/eclwriter.hh +++ b/ebos/eclwriter.hh @@ -39,6 +39,7 @@ #include #include +#include namespace Opm::Properties { @@ -208,6 +209,27 @@ public: if (totalCpuTime != 0.0) { miscSummaryData["TCPU"] = totalCpuTime; } + if (this->sub_step_report_.total_newton_iterations != 0) { + miscSummaryData["NEWTON"] = this->sub_step_report_.total_newton_iterations; + } + if (this->sub_step_report_.total_linear_iterations != 0) { + miscSummaryData["MLINEARS"] = this->sub_step_report_.total_linear_iterations; + } + if (this->sub_step_report_.total_newton_iterations != 0) { + miscSummaryData["NLINEARS"] = static_cast(this->sub_step_report_.total_linear_iterations) / this->sub_step_report_.total_newton_iterations; + } + if (this->sub_step_report_.min_linear_iterations != std::numeric_limits::max()) { + miscSummaryData["NLINSMIN"] = this->sub_step_report_.min_linear_iterations; + } + if (this->sub_step_report_.max_linear_iterations != 0) { + miscSummaryData["NLINSMAX"] = this->sub_step_report_.max_linear_iterations; + } + if (this->simulation_report_.success.total_newton_iterations != 0) { + miscSummaryData["MSUMLINS"] = this->simulation_report_.success.total_linear_iterations; + } + if (this->simulation_report_.success.total_newton_iterations != 0) { + miscSummaryData["MSUMNEWT"] = this->simulation_report_.success.total_newton_iterations; + } this->evalSummary(reportStepNum, curTime, this->collectToIORank_.isParallel() ? diff --git a/opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.hpp b/opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.hpp index bba49159f..cf98f2a46 100644 --- a/opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.hpp +++ b/opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.hpp @@ -259,6 +259,8 @@ public: events.hasEvent(ScheduleEvents::WELL_STATUS_CHANGE); auto stepReport = adaptiveTimeStepping_->step(timer, *solver, event, nullptr); report_ += stepReport; + //Pass simulation report to eclwriter for summary output + ebosSimulator_.problem().setSimulationReport(report_); } else { // solve for complete report step auto stepReport = solver->step(timer); diff --git a/opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp b/opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp index fa6f0421b..994bc0b5c 100644 --- a/opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp @@ -456,6 +456,9 @@ namespace Opm { // this can be thrown by ISTL's ILU0 in block mode, yet is not an ISTLError } + //Pass substep to eclwriter for summary output + ebosSimulator.problem().setSubStepReport(substepReport); + report += substepReport; bool continue_on_uncoverged_solution = ignoreConvergenceFailure_ && !substepReport.converged && dt <= minTimeStep_; diff --git a/opm/simulators/timestepping/SimulatorReport.cpp b/opm/simulators/timestepping/SimulatorReport.cpp index 267c66c5e..7aef68b8c 100644 --- a/opm/simulators/timestepping/SimulatorReport.cpp +++ b/opm/simulators/timestepping/SimulatorReport.cpp @@ -27,6 +27,7 @@ #include #include #include +#include namespace Opm { @@ -46,6 +47,8 @@ namespace Opm total_linearizations( 0 ), total_newton_iterations( 0 ), total_linear_iterations( 0 ), + min_linear_iterations ( std::numeric_limits::max() ), + max_linear_iterations ( 0 ), converged(false), exit_status(EXIT_SUCCESS), global_time(0), @@ -70,6 +73,11 @@ namespace Opm total_linearizations += sr.total_linearizations; total_newton_iterations += sr.total_newton_iterations; total_linear_iterations += sr.total_linear_iterations; + if (sr.total_linear_iterations > 0) { + min_linear_iterations = std::min(min_linear_iterations, sr.total_linear_iterations); + } + max_linear_iterations = std::max(max_linear_iterations, sr.total_linear_iterations); + // It makes no sense adding time points. Therefore, do not // overwrite the value of global_time which gets set in // NonlinearSolverEbos.hpp by the line: diff --git a/opm/simulators/timestepping/SimulatorReport.hpp b/opm/simulators/timestepping/SimulatorReport.hpp index 6eadc34b2..699dd2f0a 100644 --- a/opm/simulators/timestepping/SimulatorReport.hpp +++ b/opm/simulators/timestepping/SimulatorReport.hpp @@ -45,6 +45,9 @@ namespace Opm unsigned int total_linearizations; unsigned int total_newton_iterations; unsigned int total_linear_iterations; + unsigned int min_linear_iterations; + unsigned int max_linear_iterations; + bool converged; int exit_status; diff --git a/opm/simulators/utils/UnsupportedFlowKeywords.cpp b/opm/simulators/utils/UnsupportedFlowKeywords.cpp index 963dbc3bd..4fce2d609 100755 --- a/opm/simulators/utils/UnsupportedFlowKeywords.cpp +++ b/opm/simulators/utils/UnsupportedFlowKeywords.cpp @@ -416,7 +416,6 @@ const KeywordValidation::UnsupportedKeywords& unsupportedKeywords() {"NOCASC", {false, std::nullopt}}, {"NOGGF", {false, std::nullopt}}, {"NOINSPEC", {false, std::nullopt}}, - {"NLINEARS", {false, std::nullopt}}, {"NOMONITO", {false, std::nullopt}}, {"NONNC", {false, std::nullopt}}, {"NORSSPEC", {false, std::nullopt}},