diff --git a/opm/simulators/timestepping/AdaptiveTimeSteppingEbos.cpp b/opm/simulators/timestepping/AdaptiveTimeSteppingEbos.cpp index 72d8ab4da..545f1051a 100644 --- a/opm/simulators/timestepping/AdaptiveTimeSteppingEbos.cpp +++ b/opm/simulators/timestepping/AdaptiveTimeSteppingEbos.cpp @@ -5,9 +5,15 @@ #include #include + #include + #include +#include + #include + +#include #include namespace Opm { @@ -26,5 +32,57 @@ void logTimer(const AdaptiveSimulatorTimer& substepTimer) OpmLog::info(ss.str()); } +std::set +consistentlyFailingWells(const std::vector& sr) +{ + // If there are wells that cause repeated failures, we + // close them, and restart the un-chopped timestep. + std::ostringstream msg; + msg << " Excessive chopping detected in report step " + << sr.back().report_step << ", substep " << sr.back().current_step << "\n"; + + std::set failing_wells; + + // return empty set if no report exists + // well failures in assembly is not yet registred + if (sr.back().report.empty()) + return failing_wells; + + const auto& wfs = sr.back().report.back().wellFailures(); + for (const auto& wf : wfs) { + msg << " Well that failed: " << wf.wellName() << "\n"; + } + msg.flush(); + OpmLog::debug(msg.str()); + + // Check the last few step reports. + const int num_steps = 3; + const int rep_step = sr.back().report_step; + const int sub_step = sr.back().current_step; + const int sr_size = sr.size(); + if (sr_size >= num_steps) { + for (const auto& wf : wfs) { + failing_wells.insert(wf.wellName()); + } + for (int s = 1; s < num_steps; ++s) { + const auto& srep = sr[sr_size - 1 - s]; + // Report must be from same report step and substep, otherwise we have + // not chopped/retried enough times on this step. + if (srep.report_step != rep_step || srep.current_step != sub_step) { + break; + } + // Get the failing wells for this step, that also failed all other steps. + std::set failing_wells_step; + for (const auto& wf : srep.report.back().wellFailures()) { + if (failing_wells.count(wf.wellName()) > 0) { + failing_wells_step.insert(wf.wellName()); + } + } + failing_wells.swap(failing_wells_step); + } + } + return failing_wells; +} + } // namespace detail } // namespace Opm diff --git a/opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp b/opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp index dd11de3db..17148f5aa 100644 --- a/opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp @@ -25,11 +25,11 @@ #include #include +#include #include #include -#include -#include #include +#include #include #include @@ -254,9 +254,13 @@ struct MinTimeStepBasedOnNewtonIterations consistentlyFailingWells(const std::vector& sr); } @@ -613,7 +617,7 @@ namespace detail { } else { // We are below the threshold, and will check if there are any // wells we should close rather than chopping again. - std::set failing_wells = consistentlyFailingWells(solver.model().stepReports()); + std::set failing_wells = detail::consistentlyFailingWells(solver.model().stepReports()); if (failing_wells.empty()) { // Found no wells to close, chop the timestep as above. chopTimestep(); @@ -876,58 +880,6 @@ namespace detail { assert(growthFactor_ >= 1.0); } - template - std::set consistentlyFailingWells(const std::vector& sr) - { - // If there are wells that cause repeated failures, we - // close them, and restart the un-chopped timestep. - std::ostringstream msg; - msg << " Excessive chopping detected in report step " - << sr.back().report_step << ", substep " << sr.back().current_step << "\n"; - - std::set failing_wells; - - // return empty set if no report exists - // well failures in assembly is not yet registred - if(sr.back().report.empty()) - return failing_wells; - - const auto& wfs = sr.back().report.back().wellFailures(); - for (const auto& wf : wfs) { - msg << " Well that failed: " << wf.wellName() << "\n"; - } - msg.flush(); - OpmLog::debug(msg.str()); - - // Check the last few step reports. - const int num_steps = 3; - const int rep_step = sr.back().report_step; - const int sub_step = sr.back().current_step; - const int sr_size = sr.size(); - if (sr_size >= num_steps) { - for (const auto& wf : wfs) { - failing_wells.insert(wf.wellName()); - } - for (int s = 1; s < num_steps; ++s) { - const auto& srep = sr[sr_size - 1 - s]; - // Report must be from same report step and substep, otherwise we have - // not chopped/retried enough times on this step. - if (srep.report_step != rep_step || srep.current_step != sub_step) { - break; - } - // Get the failing wells for this step, that also failed all other steps. - std::set failing_wells_step; - for (const auto& wf : srep.report.back().wellFailures()) { - if (failing_wells.count(wf.wellName()) > 0) { - failing_wells_step.insert(wf.wellName()); - } - } - failing_wells.swap(failing_wells_step); - } - } - return failing_wells; - } - using TimeStepController = std::unique_ptr; TimeStepControlType timeStepControlType_; //!< type of time step control object