Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Time step rejection if tolerance test fails #6009

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion opm/simulators/flow/NonlinearSolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include <opm/simulators/timestepping/SimulatorReport.hpp>
#include <opm/simulators/timestepping/SimulatorTimerInterface.hpp>
#include <opm/simulators/timestepping/TimeStepControl.hpp>

#include <memory>

Expand Down Expand Up @@ -128,7 +129,7 @@ struct NonlinearSolverParameters
}


SimulatorReportSingle step(const SimulatorTimerInterface& timer)
SimulatorReportSingle step(const SimulatorTimerInterface& timer, const TimeStepControlInterface& timeStepControl)
{
SimulatorReportSingle report;
report.global_time = timer.simulationTimeElapsed();
Expand Down Expand Up @@ -174,6 +175,13 @@ struct NonlinearSolverParameters
std::string msg = "Solver convergence failure - Failed to complete a time step within " + std::to_string(maxIter()) + " iterations.";
OPM_THROW_NOLOG(TooManyIterations, msg);
}
if (!timeStepControl.timeStepAccepted(model_->relativeChange())) {
report.converged = false;
failureReport_ = report;

std::string msg = "Time step was too large. Tolerance test failed.";
OPM_THROW_NOLOG(TimeSteppingBreakdown, msg);
}

// Do model-specific post-step actions.
report += model_->afterStep(timer);
Expand Down
2 changes: 1 addition & 1 deletion opm/simulators/flow/SimulatorFullyImplicitBlackoil.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ class SimulatorFullyImplicitBlackoil : private SerializableSim
simulator_.problem().setSimulationReport(report_);
} else {
// solve for complete report step
auto stepReport = solver_->step(timer);
auto stepReport = solver_->step(timer, adaptiveTimeStepping_->timeStepControl());
report_ += stepReport;
if (terminalOutput_) {
std::ostringstream ss;
Expand Down
7 changes: 6 additions & 1 deletion opm/simulators/timestepping/AdaptiveTimeStepping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ void registerAdaptiveParameters()
Parameters::Register<Parameters::TimeStepControlSafetyFactor>
("Value to be multiplied with the time step control tolerance to ensure that the target "
"relative change is lower than the tolerance");
Parameters::Register<Parameters::TimeStepControlRejectCompletedStep>
("(Only applicable for the general 3rd order controller.) Include rejection of completed "
"time steps if the relative change is larger than the time step control tolerance");
}

std::tuple<TimeStepControlType, std::unique_ptr<TimeStepControlInterface>, bool>
Expand Down Expand Up @@ -218,10 +221,12 @@ createController(const UnitSystem& unitSystem)
{"general3rdorder",
[tol]() {
const double safetyFactor = Parameters::Get<Parameters::TimeStepControlSafetyFactor>(); // 0.8
const bool rejectCompletedStep = Parameters::Get<Parameters::TimeStepControlRejectCompletedStep>(); // false
return RetVal{
TimeStepControlType::General3rdOrder,
std::make_unique<General3rdOrderController>(tol,
safetyFactor),
safetyFactor,
rejectCompletedStep),
false
};
}},
Expand Down
2 changes: 2 additions & 0 deletions opm/simulators/timestepping/AdaptiveTimeStepping.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ struct TimeStepControlFileName { static constexpr auto value = "timesteps"; };
struct MinTimeStepBeforeShuttingProblematicWellsInDays { static constexpr double value = 0.01; };
struct MinTimeStepBasedOnNewtonIterations { static constexpr double value = 0.0; };
struct TimeStepControlSafetyFactor { static constexpr double value = 0.8; };
struct TimeStepControlRejectCompletedStep { static constexpr bool value = false; };

} // namespace Opm::Parameters

Expand Down Expand Up @@ -212,6 +213,7 @@ class AdaptiveTimeStepping
#endif
void setSuggestedNextStep(const double x);
double suggestedNextStep() const;
const TimeStepControlInterface& timeStepControl() const;

template <class Solver>
SimulatorReport step(const SimulatorTimer& simulator_timer,
Expand Down
15 changes: 13 additions & 2 deletions opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,14 @@ suggestedNextStep() const
return this->suggested_next_timestep_;
}

template<class TypeTag>
const TimeStepControlInterface&
AdaptiveTimeStepping<TypeTag>::
timeStepControl() const
{
return *this->time_step_control_;
}


template<class TypeTag>
void
Expand Down Expand Up @@ -807,7 +815,7 @@ run()
report.success.converged = this->substep_timer_.done();
this->substep_timer_.setLastStepFailed(false);
}
else { // in case of no convergence
else { // in case of no convergence or time step tolerance test failure
this->substep_timer_.setLastStepFailed(true);
checkTimeStepMaxRestartLimit_(restarts);

Expand Down Expand Up @@ -1129,7 +1137,7 @@ runSubStep_()
};

try {
substep_report = solver_().step(this->substep_timer_);
substep_report = solver_().step(this->substep_timer_, *this->adaptive_time_stepping_.time_step_control_);
if (solverVerbose_()) {
// report number of linear iterations
OpmLog::debug("Overall linear iterations used: "
Expand All @@ -1139,6 +1147,9 @@ runSubStep_()
catch (const TooManyIterations& e) {
handleFailure("Solver convergence failure - Iteration limit reached", e);
}
catch (const TimeSteppingBreakdown& e) {
handleFailure("Time step was too large", e);
}
catch (const ConvergenceMonitorFailure& e) {
handleFailure("Convergence monitor failure", e, /*log_exception=*/false);
}
Expand Down
11 changes: 11 additions & 0 deletions opm/simulators/timestepping/TimeStepControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,11 @@ namespace Opm

General3rdOrderController::General3rdOrderController( const double tolerance,
const double safetyFactor,
const bool rejectCompletedStep,
const bool verbose)
: tolerance_( tolerance )
, safetyFactor_( safetyFactor )
, rejectCompletedStep_( rejectCompletedStep )
, errors_( 3, tolerance_ )
, timeSteps_ ( 3, 1.0 )
, verbose_( verbose )
Expand Down Expand Up @@ -361,10 +363,19 @@ namespace Opm
}
}

bool General3rdOrderController::
timeStepAccepted(const double error) const
{
if (rejectCompletedStep_ && error > tolerance_)
return false;
return true;
}

bool General3rdOrderController::operator==(const General3rdOrderController& ctrl) const
{
return this->tolerance_ == ctrl.tolerance_ &&
this->safetyFactor_ == ctrl.safetyFactor_ &&
this->rejectCompletedStep_ == ctrl.rejectCompletedStep_ &&
this->errors_ == ctrl.errors_ &&
this->timeSteps_ == ctrl.timeSteps_ &&
this->verbose_ == ctrl.verbose_;
Expand Down
13 changes: 13 additions & 0 deletions opm/simulators/timestepping/TimeStepControl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ namespace Opm
const int iterations,
const RelativeChangeInterface& /* relativeChange */,
const AdaptiveSimulatorTimer& /* substepTimer */ ) const override;

bool timeStepAccepted(const double error) const override { return true; }

template<class Serializer>
void serializeOp(Serializer& serializer)
Expand Down Expand Up @@ -117,6 +119,8 @@ namespace Opm
const RelativeChangeInterface& relativeChange,
const AdaptiveSimulatorTimer& /* substepTimer */ ) const override;

bool timeStepAccepted(const double error) const override { return true; }

template<class Serializer>
void serializeOp(Serializer& serializer)
{
Expand Down Expand Up @@ -166,6 +170,8 @@ namespace Opm
const RelativeChangeInterface& relativeChange,
const AdaptiveSimulatorTimer& /* substepTimer */ ) const override;

bool timeStepAccepted(const double error) const override { return true; }

template<class Serializer>
void serializeOp(Serializer& serializer)
{
Expand Down Expand Up @@ -197,6 +203,7 @@ namespace Opm

General3rdOrderController( const double tolerance = 1e-3,
const double safetyFactor = 0.8,
const bool rejectCompletedStep = false,
const bool verbose = false );

static General3rdOrderController serializationTestObject();
Expand All @@ -206,11 +213,14 @@ namespace Opm
const RelativeChangeInterface& relativeChange,
const AdaptiveSimulatorTimer& substepTimer) const override;

bool timeStepAccepted(const double error) const override;

template<class Serializer>
void serializeOp(Serializer& serializer)
{
serializer(tolerance_);
serializer(safetyFactor_);
serializer(rejectCompletedStep_);
serializer(errors_);
serializer(timeSteps_);
serializer(verbose_);
Expand All @@ -222,6 +232,7 @@ namespace Opm
protected:
const double tolerance_ = 1e-3;
const double safetyFactor_ = 0.8;
const bool rejectCompletedStep_ = false;
mutable std::vector<double> errors_{};
mutable std::vector<double> timeSteps_{};
mutable int counterSinceFailure_ = 0;
Expand Down Expand Up @@ -255,6 +266,8 @@ namespace Opm
const RelativeChangeInterface& /*relativeChange */,
const AdaptiveSimulatorTimer& substepTimer) const override;

bool timeStepAccepted(const double error) const override { return true; }

template<class Serializer>
void serializeOp(Serializer& serializer)
{
Expand Down
2 changes: 2 additions & 0 deletions opm/simulators/timestepping/TimeStepControlInterface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ namespace Opm
/// \return suggested time step size for the next step
virtual double computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& relativeChange , const AdaptiveSimulatorTimer& substepTimer) const = 0;

virtual bool timeStepAccepted(const double error) const = 0;

/// virtual destructor (empty)
virtual ~TimeStepControlInterface () {}
};
Expand Down