Merge pull request #4499 from akva2/adaptivetimesteppingebos_more_compile_unit

AdaptiveTimeSteppingEbos: move more code to compile unit
This commit is contained in:
Bård Skaflestad 2023-03-02 13:38:07 +01:00 committed by GitHub
commit dcf2a1304b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 88 additions and 66 deletions

View File

@ -44,6 +44,7 @@
#include <opm/simulators/flow/BlackoilModelParametersEbos.hpp>
#include <opm/simulators/linalg/ISTLSolverEbos.hpp>
#include <opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp>
#include <opm/simulators/timestepping/ConvergenceReport.hpp>
#include <opm/simulators/timestepping/SimulatorReport.hpp>
#include <opm/simulators/timestepping/SimulatorTimer.hpp>
@ -1061,13 +1062,6 @@ namespace Opm {
const SimulatorReportSingle& failureReport() const
{ return failureReport_; }
struct StepReport
{
int report_step;
int current_step;
std::vector<ConvergenceReport> report;
};
const std::vector<StepReport>& stepReports() const
{
return convergence_reports_;
@ -1155,6 +1149,7 @@ namespace Opm {
double drMaxRel() const { return param_.dr_max_rel_; }
double maxResidualAllowed() const { return param_.max_residual_allowed_; }
double linear_solve_setup_time_;
public:
std::vector<bool> wasSwitched_;
};

View File

@ -31,6 +31,7 @@
#include <opm/simulators/flow/NonlinearSolverEbos.hpp>
#include <opm/simulators/aquifers/BlackoilAquiferModel.hpp>
#include <opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp>
#include <opm/simulators/timestepping/ConvergenceReport.hpp>
#include <opm/simulators/utils/moduleVersion.hpp>
#include <opm/simulators/wells/WellState.hpp>
@ -547,7 +548,7 @@ protected:
&this->convergenceOutputObject_.value());
}
void writeConvergenceOutput(std::vector<typename Model::StepReport>&& reports)
void writeConvergenceOutput(std::vector<StepReport>&& reports)
{
if (! this->convergenceOutputThread_.has_value()) {
return;

View File

@ -2,14 +2,22 @@
*/
#include <config.h>
#include <opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp>
#include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/input/eclipse/Units/Units.hpp>
#include <opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp>
#include <opm/simulators/timestepping/ConvergenceReport.hpp>
#include <boost/date_time.hpp>
#include <set>
#include <sstream>
namespace Opm {
namespace detail {
void logTimer(const AdaptiveSimulatorTimer& substepTimer)
{
@ -24,4 +32,57 @@ void logTimer(const AdaptiveSimulatorTimer& substepTimer)
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 Opm

View File

@ -25,11 +25,11 @@
#include <opm/models/utils/parametersystem.hh>
#include <opm/models/utils/propertysystem.hh>
#include <opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp>
#include <opm/simulators/timestepping/SimulatorReport.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/TimeStepControlInterface.hpp>
#include <algorithm>
#include <cassert>
@ -253,10 +253,19 @@ struct MinTimeStepBasedOnNewtonIterations<TypeTag, TTag::FlowTimeSteppingParamet
} // namespace Opm::Properties
namespace Opm {
class StepReport;
namespace detail {
void logTimer(const AdaptiveSimulatorTimer& substepTimer);
std::set<std::string> consistentlyFailingWells(const std::vector<StepReport>& sr);
}
// AdaptiveTimeStepping
//---------------------
void logTimer(const AdaptiveSimulatorTimer& substepTimer);
template<class TypeTag>
class AdaptiveTimeSteppingEbos
{
@ -430,7 +439,7 @@ namespace Opm {
// get current delta t
const double dt = substepTimer.currentStepLength() ;
if (timestepVerbose_) {
logTimer(substepTimer);
detail::logTimer(substepTimer);
}
SimulatorReportSingle substepReport;
@ -608,7 +617,7 @@ namespace Opm {
} else {
// We are below the threshold, and will check if there are any
// 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()) {
// Found no wells to close, chop the timestep as above.
chopTimestep();
@ -871,58 +880,6 @@ namespace Opm {
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>;
TimeStepControlType timeStepControlType_; //!< type of time step control object

View File

@ -221,6 +221,14 @@ namespace Opm
bool wellGroupTargetsViolated_;
};
struct StepReport
{
int report_step;
int current_step;
std::vector<ConvergenceReport> report;
};
} // namespace Opm
#endif // OPM_CONVERGENCEREPORT_HEADER_INCLUDED