AdaptiveTimeSteppingEbos: put consistentlyFailingWells in detail namespace

no reason for this to be a template
This commit is contained in:
Arne Morten Kvarving 2023-03-01 13:47:00 +01:00
parent b232613623
commit c4e025190e
2 changed files with 66 additions and 56 deletions

View File

@ -5,9 +5,15 @@
#include <opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp> #include <opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp>
#include <opm/common/OpmLog/OpmLog.hpp> #include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/input/eclipse/Units/Units.hpp> #include <opm/input/eclipse/Units/Units.hpp>
#include <opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp> #include <opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp>
#include <opm/simulators/timestepping/ConvergenceReport.hpp>
#include <boost/date_time.hpp> #include <boost/date_time.hpp>
#include <set>
#include <sstream> #include <sstream>
namespace Opm { namespace Opm {
@ -26,5 +32,57 @@ void logTimer(const AdaptiveSimulatorTimer& substepTimer)
OpmLog::info(ss.str()); OpmLog::info(ss.str());
} }
std::set<std::string>
consistentlyFailingWells(const std::vector<StepReport>& 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<std::string> 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<std::string> 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 detail
} // namespace Opm } // namespace Opm

View File

@ -25,11 +25,11 @@
#include <opm/models/utils/parametersystem.hh> #include <opm/models/utils/parametersystem.hh>
#include <opm/models/utils/propertysystem.hh> #include <opm/models/utils/propertysystem.hh>
#include <opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp>
#include <opm/simulators/timestepping/SimulatorReport.hpp> #include <opm/simulators/timestepping/SimulatorReport.hpp>
#include <opm/simulators/timestepping/SimulatorTimer.hpp> #include <opm/simulators/timestepping/SimulatorTimer.hpp>
#include <opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp>
#include <opm/simulators/timestepping/TimeStepControlInterface.hpp>
#include <opm/simulators/timestepping/TimeStepControl.hpp> #include <opm/simulators/timestepping/TimeStepControl.hpp>
#include <opm/simulators/timestepping/TimeStepControlInterface.hpp>
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
@ -254,9 +254,13 @@ struct MinTimeStepBasedOnNewtonIterations<TypeTag, TTag::FlowTimeSteppingParamet
namespace Opm { namespace Opm {
class StepReport;
namespace detail { namespace detail {
void logTimer(const AdaptiveSimulatorTimer& substepTimer); void logTimer(const AdaptiveSimulatorTimer& substepTimer);
std::set<std::string> consistentlyFailingWells(const std::vector<StepReport>& sr);
} }
@ -613,7 +617,7 @@ namespace detail {
} else { } else {
// We are below the threshold, and will check if there are any // We are below the threshold, and will check if there are any
// wells we should close rather than chopping again. // wells we should close rather than chopping again.
std::set<std::string> failing_wells = consistentlyFailingWells(solver.model().stepReports()); std::set<std::string> failing_wells = detail::consistentlyFailingWells(solver.model().stepReports());
if (failing_wells.empty()) { if (failing_wells.empty()) {
// Found no wells to close, chop the timestep as above. // Found no wells to close, chop the timestep as above.
chopTimestep(); chopTimestep();
@ -876,58 +880,6 @@ namespace detail {
assert(growthFactor_ >= 1.0); assert(growthFactor_ >= 1.0);
} }
template <class ProblemType>
std::set<std::string> consistentlyFailingWells(const std::vector<ProblemType>& 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<std::string> 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<std::string> 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<TimeStepControlInterface>; using TimeStepController = std::unique_ptr<TimeStepControlInterface>;
TimeStepControlType timeStepControlType_; //!< type of time step control object TimeStepControlType timeStepControlType_; //!< type of time step control object