2018-06-06 03:59:41 -05:00
|
|
|
/*
|
|
|
|
*/
|
2024-01-31 07:14:50 -06:00
|
|
|
#ifndef OPM_ADAPTIVE_TIME_STEPPING_HPP
|
|
|
|
#define OPM_ADAPTIVE_TIME_STEPPING_HPP
|
2018-06-06 03:59:41 -05:00
|
|
|
|
2023-02-08 07:42:26 -06:00
|
|
|
#include <dune/common/version.hh>
|
|
|
|
#include <dune/istl/istlexception.hh>
|
2018-06-06 03:59:41 -05:00
|
|
|
|
2022-12-13 05:54:27 -06:00
|
|
|
#include <opm/common/OpmLog/OpmLog.hpp>
|
|
|
|
|
2023-01-11 08:56:47 -06:00
|
|
|
#include <opm/input/eclipse/Schedule/Tuning.hpp>
|
2022-12-13 05:54:27 -06:00
|
|
|
|
2023-02-08 07:42:26 -06:00
|
|
|
#include <opm/models/utils/basicproperties.hh>
|
|
|
|
#include <opm/models/utils/propertysystem.hh>
|
|
|
|
|
2023-03-01 06:47:00 -06:00
|
|
|
#include <opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp>
|
2022-12-13 05:54:27 -06:00
|
|
|
#include <opm/simulators/timestepping/SimulatorReport.hpp>
|
2018-06-06 03:59:41 -05:00
|
|
|
#include <opm/simulators/timestepping/SimulatorTimer.hpp>
|
|
|
|
#include <opm/simulators/timestepping/TimeStepControl.hpp>
|
2023-03-01 06:47:00 -06:00
|
|
|
#include <opm/simulators/timestepping/TimeStepControlInterface.hpp>
|
2018-06-21 05:14:17 -05:00
|
|
|
|
2023-02-08 07:42:26 -06:00
|
|
|
#include <cmath>
|
2024-02-22 10:02:48 -06:00
|
|
|
#include <functional>
|
2023-02-08 07:42:26 -06:00
|
|
|
#include <memory>
|
|
|
|
#include <set>
|
|
|
|
#include <string>
|
2025-01-03 02:12:51 -06:00
|
|
|
#include <tuple>
|
2023-02-08 07:42:26 -06:00
|
|
|
#include <vector>
|
|
|
|
|
2024-06-28 05:17:13 -05:00
|
|
|
namespace Opm::Parameters {
|
|
|
|
|
2024-07-06 03:22:47 -05:00
|
|
|
struct SolverContinueOnConvergenceFailure { static constexpr bool value = false; };
|
|
|
|
struct SolverMaxRestarts { static constexpr int value = 10; };
|
|
|
|
struct SolverVerbosity { static constexpr int value = 1; };
|
|
|
|
struct TimeStepVerbosity { static constexpr int value = 1; };
|
|
|
|
struct InitialTimeStepInDays { static constexpr double value = 1.0; };
|
|
|
|
struct FullTimeStepInitially { static constexpr bool value = false; };
|
|
|
|
struct TimeStepControl { static constexpr auto value = "pid+newtoniteration"; };
|
|
|
|
struct TimeStepControlTolerance { static constexpr double value = 1e-1; };
|
|
|
|
struct TimeStepControlTargetIterations { static constexpr int value = 30; };
|
|
|
|
struct TimeStepControlTargetNewtonIterations { static constexpr int value = 8; };
|
|
|
|
struct TimeStepControlDecayRate { static constexpr double value = 0.75; };
|
|
|
|
struct TimeStepControlGrowthRate { static constexpr double value = 1.25; };
|
|
|
|
struct TimeStepControlDecayDampingFactor { static constexpr double value = 1.0; };
|
|
|
|
struct TimeStepControlGrowthDampingFactor { static constexpr double value = 3.2; };
|
|
|
|
struct TimeStepControlFileName { static constexpr auto value = "timesteps"; };
|
|
|
|
struct MinTimeStepBeforeShuttingProblematicWellsInDays { static constexpr double value = 0.01; };
|
|
|
|
struct MinTimeStepBasedOnNewtonIterations { static constexpr double value = 0.0; };
|
2021-02-17 04:30:57 -06:00
|
|
|
|
2024-06-28 05:17:13 -05:00
|
|
|
} // namespace Opm::Parameters
|
2018-06-06 03:59:41 -05:00
|
|
|
|
|
|
|
namespace Opm {
|
2023-03-01 06:47:00 -06:00
|
|
|
|
2025-01-02 07:18:56 -06:00
|
|
|
class UnitSystem;
|
2023-03-03 03:12:46 -06:00
|
|
|
struct StepReport;
|
2023-03-01 06:47:00 -06:00
|
|
|
|
2023-03-01 06:47:00 -06:00
|
|
|
namespace detail {
|
|
|
|
|
2023-03-01 06:47:00 -06:00
|
|
|
void logTimer(const AdaptiveSimulatorTimer& substepTimer);
|
|
|
|
|
|
|
|
std::set<std::string> consistentlyFailingWells(const std::vector<StepReport>& sr);
|
2018-06-06 03:59:41 -05:00
|
|
|
|
2024-08-15 02:26:02 -05:00
|
|
|
void registerAdaptiveParameters();
|
|
|
|
|
2025-01-03 02:12:51 -06:00
|
|
|
std::tuple<TimeStepControlType,
|
|
|
|
std::unique_ptr<TimeStepControlInterface>,
|
|
|
|
bool>
|
|
|
|
createController(const UnitSystem& unitSystem);
|
|
|
|
|
2023-03-01 06:47:00 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// AdaptiveTimeStepping
|
|
|
|
//---------------------
|
2018-06-21 05:14:17 -05:00
|
|
|
template<class TypeTag>
|
2024-01-31 07:14:50 -06:00
|
|
|
class AdaptiveTimeStepping
|
2018-06-06 03:59:41 -05:00
|
|
|
{
|
2024-07-06 03:22:47 -05:00
|
|
|
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
|
2018-06-06 03:59:41 -05:00
|
|
|
template <class Solver>
|
2024-01-31 07:14:50 -06:00
|
|
|
class SolutionTimeErrorSolverWrapper : public RelativeChangeInterface
|
2018-06-06 03:59:41 -05:00
|
|
|
{
|
|
|
|
const Solver& solver_;
|
|
|
|
public:
|
2024-01-31 07:14:50 -06:00
|
|
|
SolutionTimeErrorSolverWrapper(const Solver& solver)
|
2018-06-06 03:59:41 -05:00
|
|
|
: solver_(solver)
|
|
|
|
{}
|
|
|
|
|
|
|
|
/// return || u^n+1 - u^n || / || u^n+1 ||
|
|
|
|
double relativeChange() const
|
|
|
|
{ return solver_.model().relativeChange(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
template<class E>
|
|
|
|
void logException_(const E& exception, bool verbose)
|
|
|
|
{
|
|
|
|
if (verbose) {
|
|
|
|
std::string message;
|
|
|
|
message = "Caught Exception: ";
|
|
|
|
message += exception.what();
|
|
|
|
OpmLog::debug(message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2024-01-31 07:14:50 -06:00
|
|
|
AdaptiveTimeStepping() = default;
|
2023-01-31 05:38:54 -06:00
|
|
|
|
2018-06-06 03:59:41 -05:00
|
|
|
//! \brief contructor taking parameter object
|
2025-01-02 07:18:56 -06:00
|
|
|
explicit AdaptiveTimeStepping(const UnitSystem& unitSystem,
|
|
|
|
const double max_next_tstep = -1.0,
|
|
|
|
const bool terminalOutput = true);
|
2018-06-06 03:59:41 -05:00
|
|
|
|
|
|
|
//! \brief contructor taking parameter object
|
|
|
|
//! \param tuning Pointer to ecl TUNING keyword
|
|
|
|
//! \param timeStep current report step
|
2024-01-31 07:14:50 -06:00
|
|
|
AdaptiveTimeStepping(double max_next_tstep,
|
|
|
|
const Tuning& tuning,
|
|
|
|
const UnitSystem& unitSystem,
|
2025-01-02 07:18:56 -06:00
|
|
|
const bool terminalOutput = true);
|
2018-06-21 05:14:17 -05:00
|
|
|
|
2025-01-02 07:18:56 -06:00
|
|
|
static void registerParameters();
|
2018-06-06 03:59:41 -05:00
|
|
|
|
|
|
|
/** \brief step method that acts like the solver::step method
|
|
|
|
in a sub cycle of time steps
|
2024-02-22 10:02:48 -06:00
|
|
|
\param tuningUpdater Function used to update TUNING parameters before each
|
|
|
|
time step. ACTIONX might change tuning.
|
2018-06-06 03:59:41 -05:00
|
|
|
*/
|
2018-06-06 03:59:41 -05:00
|
|
|
template <class Solver>
|
2018-06-06 03:59:41 -05:00
|
|
|
SimulatorReport step(const SimulatorTimer& simulatorTimer,
|
2020-05-08 02:21:25 -05:00
|
|
|
Solver& solver,
|
|
|
|
const bool isEvent,
|
2025-01-02 07:18:56 -06:00
|
|
|
const std::function<bool(const double, const double, const int)> tuningUpdater);
|
2018-06-06 03:59:41 -05:00
|
|
|
|
|
|
|
/** \brief Returns the simulator report for the failed substeps of the last
|
|
|
|
* report step.
|
|
|
|
*/
|
|
|
|
double suggestedNextStep() const
|
|
|
|
{ return suggestedNextTimestep_; }
|
|
|
|
|
|
|
|
void setSuggestedNextStep(const double x)
|
|
|
|
{ suggestedNextTimestep_ = x; }
|
|
|
|
|
2025-01-02 07:18:56 -06:00
|
|
|
void updateTUNING(double max_next_tstep, const Tuning& tuning);
|
2024-02-19 12:14:13 -06:00
|
|
|
|
2025-01-02 07:18:56 -06:00
|
|
|
void updateNEXTSTEP(double max_next_tstep);
|
2018-06-06 03:59:41 -05:00
|
|
|
|
2023-01-31 05:38:54 -06:00
|
|
|
template<class Serializer>
|
2025-01-02 07:18:56 -06:00
|
|
|
void serializeOp(Serializer& serializer);
|
2023-01-31 05:38:54 -06:00
|
|
|
|
2025-01-02 07:18:56 -06:00
|
|
|
static AdaptiveTimeStepping<TypeTag> serializationTestObjectHardcoded();
|
|
|
|
static AdaptiveTimeStepping<TypeTag> serializationTestObjectPID();
|
|
|
|
static AdaptiveTimeStepping<TypeTag> serializationTestObjectPIDIt();
|
|
|
|
static AdaptiveTimeStepping<TypeTag> serializationTestObjectSimple();
|
2023-01-31 05:38:54 -06:00
|
|
|
|
2025-01-02 07:18:56 -06:00
|
|
|
bool operator==(const AdaptiveTimeStepping<TypeTag>& rhs) const;
|
2023-01-31 05:38:54 -06:00
|
|
|
|
|
|
|
private:
|
|
|
|
template<class Controller>
|
2025-01-02 07:18:56 -06:00
|
|
|
static AdaptiveTimeStepping<TypeTag> serializationTestObject_();
|
|
|
|
|
2023-01-31 05:38:54 -06:00
|
|
|
template<class T, class Serializer>
|
|
|
|
void allocAndSerialize(Serializer& serializer)
|
|
|
|
{
|
|
|
|
if (!serializer.isSerializing()) {
|
|
|
|
timeStepControl_ = std::make_unique<T>();
|
|
|
|
}
|
|
|
|
serializer(*static_cast<T*>(timeStepControl_.get()));
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class T>
|
2024-01-31 07:14:50 -06:00
|
|
|
bool castAndComp(const AdaptiveTimeStepping<TypeTag>& Rhs) const
|
2023-01-31 05:38:54 -06:00
|
|
|
{
|
|
|
|
const T* lhs = static_cast<const T*>(timeStepControl_.get());
|
|
|
|
const T* rhs = static_cast<const T*>(Rhs.timeStepControl_.get());
|
|
|
|
return *lhs == *rhs;
|
|
|
|
}
|
2018-06-06 03:59:41 -05:00
|
|
|
|
|
|
|
protected:
|
2025-01-02 07:18:56 -06:00
|
|
|
void init_(const UnitSystem& unitSystem);
|
2018-06-06 03:59:41 -05:00
|
|
|
|
2023-01-31 05:38:54 -06:00
|
|
|
using TimeStepController = std::unique_ptr<TimeStepControlInterface>;
|
2018-06-06 03:59:41 -05:00
|
|
|
|
2025-01-02 07:18:56 -06:00
|
|
|
TimeStepControlType timeStepControlType_{TimeStepControlType::PIDAndIterationCount}; //!< type of time step control object
|
|
|
|
TimeStepController timeStepControl_{}; //!< time step control object
|
|
|
|
double restartFactor_{}; //!< factor to multiply time step with when solver fails to converge
|
|
|
|
double growthFactor_{}; //!< factor to multiply time step when solver recovered from failed convergence
|
|
|
|
double maxGrowth_{}; //!< factor that limits the maximum growth of a time step
|
|
|
|
double maxTimeStep_{}; //!< maximal allowed time step size in days
|
|
|
|
double minTimeStep_{}; //!< minimal allowed time step size before throwing
|
|
|
|
bool ignoreConvergenceFailure_{false}; //!< continue instead of stop when minimum time step is reached
|
|
|
|
int solverRestartMax_{}; //!< how many restart of solver are allowed
|
|
|
|
bool solverVerbose_{false}; //!< solver verbosity
|
|
|
|
bool timestepVerbose_{false}; //!< timestep verbosity
|
|
|
|
double suggestedNextTimestep_{}; //!< suggested size of next timestep
|
|
|
|
bool fullTimestepInitially_{false}; //!< beginning with the size of the time step from data file
|
|
|
|
double timestepAfterEvent_{}; //!< suggested size of timestep after an event
|
|
|
|
bool useNewtonIteration_{false}; //!< use newton iteration count for adaptive time step control
|
|
|
|
double minTimeStepBeforeShuttingProblematicWells_{}; //! < shut problematic wells when time step size in days are less than this
|
2018-06-06 03:59:41 -05:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2025-01-02 07:18:56 -06:00
|
|
|
#include <opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp>
|
|
|
|
|
2024-01-31 07:14:50 -06:00
|
|
|
#endif // OPM_ADAPTIVE_TIME_STEPPING_HPP
|