2018-06-06 03:59:41 -05:00
/*
*/
# ifndef OPM_ADAPTIVE_TIME_STEPPING_EBOS_HPP
# define OPM_ADAPTIVE_TIME_STEPPING_EBOS_HPP
2023-02-08 07:42:26 -06:00
# include <dune/common/version.hh>
# if DUNE_VERSION_NEWER(DUNE_ISTL, 2, 8)
# include <dune/istl/istlexception.hh>
# else
# include <dune/istl/ilu.hh>
# endif
2018-06-06 03:59:41 -05:00
2022-12-13 05:54:27 -06:00
# include <opm/common/Exceptions.hpp>
2018-06-06 03:59:41 -05:00
# include <opm/common/ErrorMacros.hpp>
2022-12-13 05:54:27 -06:00
# include <opm/common/OpmLog/OpmLog.hpp>
# include <opm/core/props/phaseUsageFromDeck.hpp>
# include <opm/grid/utility/StopWatch.hpp>
# include <opm/input/eclipse/Schedule/ScheduleState.hpp>
2023-01-16 05:21:29 -06:00
# include <opm/input/eclipse/Units/Units.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/parametersystem.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 <algorithm>
# include <cassert>
# include <cmath>
# include <memory>
# include <ostream>
# include <set>
# include <sstream>
# include <stdexcept>
# include <string>
# include <utility>
# include <vector>
2020-08-21 06:42:08 -05:00
namespace Opm : : Properties {
2018-06-21 05:14:17 -05:00
2020-08-27 03:30:29 -05:00
namespace TTag {
struct FlowTimeSteppingParameters { } ;
}
2018-06-21 05:14:17 -05:00
2020-08-27 04:38:38 -05:00
template < class TypeTag , class MyTypeTag >
struct SolverRestartFactor {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
struct SolverGrowthFactor {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
struct SolverMaxGrowth {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
struct SolverMaxTimeStepInDays {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
struct SolverMinTimeStep {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
2021-09-09 00:46:09 -05:00
struct SolverContinueOnConvergenceFailure {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
2020-08-27 04:38:38 -05:00
struct SolverMaxRestarts {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
struct SolverVerbosity {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
struct TimeStepVerbosity {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
struct InitialTimeStepInDays {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
struct FullTimeStepInitially {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
struct TimeStepAfterEventInDays {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
struct TimeStepControl {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
struct TimeStepControlTolerance {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
struct TimeStepControlTargetIterations {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
struct TimeStepControlTargetNewtonIterations {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
struct TimeStepControlDecayRate {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
struct TimeStepControlGrowthRate {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
2020-10-01 07:02:39 -05:00
struct TimeStepControlDecayDampingFactor {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
struct TimeStepControlGrowthDampingFactor {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
2020-08-27 04:38:38 -05:00
struct TimeStepControlFileName {
using type = UndefinedProperty ;
} ;
template < class TypeTag , class MyTypeTag >
struct MinTimeStepBeforeShuttingProblematicWellsInDays {
using type = UndefinedProperty ;
} ;
2021-02-17 04:30:57 -06:00
template < class TypeTag , class MyTypeTag >
struct MinTimeStepBasedOnNewtonIterations {
using type = UndefinedProperty ;
} ;
2018-08-06 08:59:35 -05:00
2020-08-27 04:38:38 -05:00
template < class TypeTag >
struct SolverRestartFactor < TypeTag , TTag : : FlowTimeSteppingParameters > {
using type = GetPropType < TypeTag , Scalar > ;
static constexpr type value = 0.33 ;
} ;
template < class TypeTag >
struct SolverGrowthFactor < TypeTag , TTag : : FlowTimeSteppingParameters > {
using type = GetPropType < TypeTag , Scalar > ;
static constexpr type value = 2.0 ;
} ;
template < class TypeTag >
struct SolverMaxGrowth < TypeTag , TTag : : FlowTimeSteppingParameters > {
using type = GetPropType < TypeTag , Scalar > ;
static constexpr type value = 3.0 ;
} ;
template < class TypeTag >
struct SolverMaxTimeStepInDays < TypeTag , TTag : : FlowTimeSteppingParameters > {
using type = GetPropType < TypeTag , Scalar > ;
static constexpr type value = 365.0 ;
} ;
template < class TypeTag >
struct SolverMinTimeStep < TypeTag , TTag : : FlowTimeSteppingParameters > {
using type = GetPropType < TypeTag , Scalar > ;
2021-03-18 03:23:48 -05:00
static constexpr type value = 1.0e-12 ;
2020-08-27 04:38:38 -05:00
} ;
2020-08-27 04:38:38 -05:00
template < class TypeTag >
2021-09-09 00:46:09 -05:00
struct SolverContinueOnConvergenceFailure < TypeTag , TTag : : FlowTimeSteppingParameters > {
static constexpr bool value = false ;
} ;
template < class TypeTag >
2020-08-27 04:38:38 -05:00
struct SolverMaxRestarts < TypeTag , TTag : : FlowTimeSteppingParameters > {
static constexpr int value = 10 ;
} ;
template < class TypeTag >
struct SolverVerbosity < TypeTag , TTag : : FlowTimeSteppingParameters > {
static constexpr int value = 1 ;
} ;
template < class TypeTag >
struct TimeStepVerbosity < TypeTag , TTag : : FlowTimeSteppingParameters > {
static constexpr int value = 1 ;
} ;
2020-08-27 04:38:38 -05:00
template < class TypeTag >
struct InitialTimeStepInDays < TypeTag , TTag : : FlowTimeSteppingParameters > {
using type = GetPropType < TypeTag , Scalar > ;
static constexpr type value = 1.0 ;
} ;
2020-08-27 04:38:38 -05:00
template < class TypeTag >
struct FullTimeStepInitially < TypeTag , TTag : : FlowTimeSteppingParameters > {
static constexpr bool value = false ;
} ;
2020-08-27 04:38:38 -05:00
template < class TypeTag >
struct TimeStepAfterEventInDays < TypeTag , TTag : : FlowTimeSteppingParameters > {
using type = GetPropType < TypeTag , Scalar > ;
static constexpr type value = - 1.0 ;
} ;
2020-08-27 04:38:38 -05:00
template < class TypeTag >
struct TimeStepControl < TypeTag , TTag : : FlowTimeSteppingParameters > {
2020-11-09 01:40:31 -06:00
static constexpr auto value = " pid+newtoniteration " ;
2020-08-27 04:38:38 -05:00
} ;
2020-08-27 04:38:38 -05:00
template < class TypeTag >
struct TimeStepControlTolerance < TypeTag , TTag : : FlowTimeSteppingParameters > {
using type = GetPropType < TypeTag , Scalar > ;
static constexpr type value = 1e-1 ;
} ;
2020-08-27 04:38:38 -05:00
template < class TypeTag >
struct TimeStepControlTargetIterations < TypeTag , TTag : : FlowTimeSteppingParameters > {
static constexpr int value = 30 ;
} ;
template < class TypeTag >
struct TimeStepControlTargetNewtonIterations < TypeTag , TTag : : FlowTimeSteppingParameters > {
static constexpr int value = 8 ;
} ;
2020-08-27 04:38:38 -05:00
template < class TypeTag >
struct TimeStepControlDecayRate < TypeTag , TTag : : FlowTimeSteppingParameters > {
using type = GetPropType < TypeTag , Scalar > ;
static constexpr type value = 0.75 ;
} ;
template < class TypeTag >
struct TimeStepControlGrowthRate < TypeTag , TTag : : FlowTimeSteppingParameters > {
using type = GetPropType < TypeTag , Scalar > ;
static constexpr type value = 1.25 ;
} ;
2020-08-27 04:38:38 -05:00
template < class TypeTag >
2020-10-01 07:02:39 -05:00
struct TimeStepControlDecayDampingFactor < TypeTag , TTag : : FlowTimeSteppingParameters > {
using type = GetPropType < TypeTag , Scalar > ;
static constexpr type value = 1.0 ;
} ;
template < class TypeTag >
struct TimeStepControlGrowthDampingFactor < TypeTag , TTag : : FlowTimeSteppingParameters > {
using type = GetPropType < TypeTag , Scalar > ;
2020-11-09 04:45:13 -06:00
static constexpr type value = 3.2 ;
2020-10-01 07:02:39 -05:00
} ;
template < class TypeTag >
2020-08-27 04:38:38 -05:00
struct TimeStepControlFileName < TypeTag , TTag : : FlowTimeSteppingParameters > {
static constexpr auto value = " timesteps " ;
} ;
2020-08-27 04:38:38 -05:00
template < class TypeTag >
struct MinTimeStepBeforeShuttingProblematicWellsInDays < TypeTag , TTag : : FlowTimeSteppingParameters > {
using type = GetPropType < TypeTag , Scalar > ;
2021-02-02 02:28:26 -06:00
static constexpr type value = 0.01 ;
2020-08-27 04:38:38 -05:00
} ;
2019-12-18 04:18:18 -06:00
2021-02-17 04:30:57 -06:00
template < class TypeTag >
struct MinTimeStepBasedOnNewtonIterations < TypeTag , TTag : : FlowTimeSteppingParameters > {
using type = GetPropType < TypeTag , Scalar > ;
static constexpr type value = 0.0 ;
} ;
2020-08-21 06:42:08 -05:00
} // namespace Opm::Properties
2018-06-06 03:59:41 -05:00
namespace Opm {
2023-03-01 06:47:00 -06:00
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
2023-03-01 06:47:00 -06:00
}
// AdaptiveTimeStepping
//---------------------
2018-06-21 05:14:17 -05:00
template < class TypeTag >
2018-06-06 03:59:41 -05:00
class AdaptiveTimeSteppingEbos
{
template < class Solver >
class SolutionTimeErrorSolverWrapperEbos : public RelativeChangeInterface
{
const Solver & solver_ ;
public :
SolutionTimeErrorSolverWrapperEbos ( const Solver & solver )
: 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 :
2023-01-31 05:38:54 -06:00
AdaptiveTimeSteppingEbos ( ) = default ;
2018-06-06 03:59:41 -05:00
//! \brief contructor taking parameter object
2021-02-17 04:30:57 -06:00
AdaptiveTimeSteppingEbos ( const UnitSystem & unitSystem ,
const bool terminalOutput = true )
2018-06-06 03:59:41 -05:00
: timeStepControl_ ( )
2018-08-06 08:59:35 -05:00
, restartFactor_ ( EWOMS_GET_PARAM ( TypeTag , double , SolverRestartFactor ) ) // 0.33
, growthFactor_ ( EWOMS_GET_PARAM ( TypeTag , double , SolverGrowthFactor ) ) // 2.0
, maxGrowth_ ( EWOMS_GET_PARAM ( TypeTag , double , SolverMaxGrowth ) ) // 3.0
, maxTimeStep_ ( EWOMS_GET_PARAM ( TypeTag , double , SolverMaxTimeStepInDays ) * 24 * 60 * 60 ) // 365.25
2021-03-18 03:23:48 -05:00
, minTimeStep_ ( unitSystem . to_si ( UnitSystem : : measure : : time , EWOMS_GET_PARAM ( TypeTag , double , SolverMinTimeStep ) ) ) // 1e-12;
2021-09-09 00:46:09 -05:00
, ignoreConvergenceFailure_ ( EWOMS_GET_PARAM ( TypeTag , bool , SolverContinueOnConvergenceFailure ) ) // false;
2018-08-06 08:59:35 -05:00
, solverRestartMax_ ( EWOMS_GET_PARAM ( TypeTag , int , SolverMaxRestarts ) ) // 10
, solverVerbose_ ( EWOMS_GET_PARAM ( TypeTag , int , SolverVerbosity ) > 0 & & terminalOutput ) // 2
, timestepVerbose_ ( EWOMS_GET_PARAM ( TypeTag , int , TimeStepVerbosity ) > 0 & & terminalOutput ) // 2
, suggestedNextTimestep_ ( EWOMS_GET_PARAM ( TypeTag , double , InitialTimeStepInDays ) * 24 * 60 * 60 ) // 1.0
, fullTimestepInitially_ ( EWOMS_GET_PARAM ( TypeTag , bool , FullTimeStepInitially ) ) // false
, timestepAfterEvent_ ( EWOMS_GET_PARAM ( TypeTag , double , TimeStepAfterEventInDays ) * 24 * 60 * 60 ) // 1e30
2018-06-06 03:59:41 -05:00
, useNewtonIteration_ ( false )
2019-12-18 04:18:18 -06:00
, minTimeStepBeforeShuttingProblematicWells_ ( EWOMS_GET_PARAM ( TypeTag , double , MinTimeStepBeforeShuttingProblematicWellsInDays ) * unit : : day )
2018-06-06 03:59:41 -05:00
{
2021-02-17 04:30:57 -06:00
init_ ( unitSystem ) ;
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
2021-10-18 04:52:33 -05:00
AdaptiveTimeSteppingEbos ( double max_next_tstep ,
const Tuning & tuning ,
2021-02-17 04:30:57 -06:00
const UnitSystem & unitSystem ,
2018-06-06 03:59:41 -05:00
const bool terminalOutput = true )
: timeStepControl_ ( )
2020-01-31 06:42:50 -06:00
, restartFactor_ ( tuning . TSFCNV )
, growthFactor_ ( tuning . TFDIFF )
, maxGrowth_ ( tuning . TSFMAX )
2020-05-14 14:31:18 -05:00
, maxTimeStep_ ( tuning . TSMAXZ ) // 365.25
2021-09-09 00:46:09 -05:00
, minTimeStep_ ( tuning . TSFMIN ) // 0.1;
, ignoreConvergenceFailure_ ( true )
2018-08-06 08:59:35 -05:00
, solverRestartMax_ ( EWOMS_GET_PARAM ( TypeTag , int , SolverMaxRestarts ) ) // 10
, solverVerbose_ ( EWOMS_GET_PARAM ( TypeTag , int , SolverVerbosity ) > 0 & & terminalOutput ) // 2
, timestepVerbose_ ( EWOMS_GET_PARAM ( TypeTag , int , TimeStepVerbosity ) > 0 & & terminalOutput ) // 2
2021-10-18 04:52:33 -05:00
, suggestedNextTimestep_ ( max_next_tstep ) // 1.0
2018-08-06 08:59:35 -05:00
, fullTimestepInitially_ ( EWOMS_GET_PARAM ( TypeTag , bool , FullTimeStepInitially ) ) // false
2020-05-14 14:31:18 -05:00
, timestepAfterEvent_ ( tuning . TMAXWC ) // 1e30
2018-06-06 03:59:41 -05:00
, useNewtonIteration_ ( false )
2019-12-18 04:18:18 -06:00
, minTimeStepBeforeShuttingProblematicWells_ ( EWOMS_GET_PARAM ( TypeTag , double , MinTimeStepBeforeShuttingProblematicWellsInDays ) * unit : : day )
2018-06-06 03:59:41 -05:00
{
2021-02-17 04:30:57 -06:00
init_ ( unitSystem ) ;
2018-06-21 05:14:17 -05:00
}
static void registerParameters ( )
{
// TODO: make sure the help messages are correct (and useful)
2018-08-06 08:59:35 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , double , SolverRestartFactor ,
2018-06-21 05:14:17 -05:00
" The factor time steps are elongated after restarts " ) ;
2018-08-06 08:59:35 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , double , SolverGrowthFactor ,
2018-06-21 05:14:17 -05:00
" The factor time steps are elongated after a successful substep " ) ;
2018-08-06 08:59:35 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , double , SolverMaxGrowth ,
2018-06-21 05:14:17 -05:00
" The maximum factor time steps are elongated after a report step " ) ;
2018-08-06 08:59:35 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , double , SolverMaxTimeStepInDays ,
2018-06-21 05:14:17 -05:00
" The maximum size of a time step in days " ) ;
2019-11-28 08:18:39 -06:00
EWOMS_REGISTER_PARAM ( TypeTag , double , SolverMinTimeStep ,
2021-03-18 03:23:48 -05:00
" The minimum size of a time step in days for field and metric and hours for lab. If a step cannot converge without getting cut below this step size the simulator will stop " ) ;
2021-09-09 00:46:09 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , bool , SolverContinueOnConvergenceFailure ,
" Continue instead of stop when minimum solver time step is reached " ) ;
2018-08-06 08:59:35 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , int , SolverMaxRestarts ,
2018-06-21 05:14:17 -05:00
" The maximum number of breakdowns before a substep is given up and the simulator is terminated " ) ;
2018-08-06 08:59:35 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , int , SolverVerbosity ,
2018-06-21 05:14:17 -05:00
" Specify the \" chattiness \" of the non-linear solver itself " ) ;
2018-08-06 08:59:35 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , int , TimeStepVerbosity ,
2018-06-21 05:14:17 -05:00
" Specify the \" chattiness \" during the time integration " ) ;
2018-08-06 08:59:35 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , double , InitialTimeStepInDays ,
2018-06-21 05:14:17 -05:00
" The size of the initial time step in days " ) ;
2018-08-06 08:59:35 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , bool , FullTimeStepInitially ,
2018-06-21 05:14:17 -05:00
" Always attempt to finish a report step using a single substep " ) ;
2018-08-06 08:59:35 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , double , TimeStepAfterEventInDays ,
2018-06-21 05:14:17 -05:00
" Time step size of the first time step after an event occurs during the simulation in days " ) ;
2018-08-06 08:59:35 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , std : : string , TimeStepControl ,
2020-10-01 07:02:39 -05:00
" The algorithm used to determine time-step sizes. valid options are: 'pid' (default), 'pid+iteration', 'pid+newtoniteration', 'iterationcount', 'newtoniterationcount' and 'hardcoded' " ) ;
2018-08-06 08:59:35 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , double , TimeStepControlTolerance ,
2018-06-21 05:14:17 -05:00
" The tolerance used by the time step size control algorithm " ) ;
2018-08-06 08:59:35 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , int , TimeStepControlTargetIterations ,
2018-06-21 05:14:17 -05:00
" The number of linear iterations which the time step control scheme should aim for (if applicable) " ) ;
2018-08-06 08:59:35 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , int , TimeStepControlTargetNewtonIterations ,
2018-06-21 05:14:17 -05:00
" The number of Newton iterations which the time step control scheme should aim for (if applicable) " ) ;
2018-08-06 08:59:35 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , double , TimeStepControlDecayRate ,
2018-06-21 05:14:17 -05:00
" The decay rate of the time step size of the number of target iterations is exceeded " ) ;
2018-08-06 08:59:35 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , double , TimeStepControlGrowthRate ,
2018-06-21 05:14:17 -05:00
" The growth rate of the time step size of the number of target iterations is undercut " ) ;
2020-10-01 07:02:39 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , double , TimeStepControlDecayDampingFactor ,
" The decay rate of the time step decrease when the target iterations is exceeded " ) ;
EWOMS_REGISTER_PARAM ( TypeTag , double , TimeStepControlGrowthDampingFactor ,
" The growth rate of the time step increase when the target iterations is undercut " ) ;
2018-08-06 08:59:35 -05:00
EWOMS_REGISTER_PARAM ( TypeTag , std : : string , TimeStepControlFileName ,
2018-06-21 05:14:17 -05:00
" The name of the file which contains the hardcoded time steps sizes " ) ;
2019-12-18 04:18:18 -06:00
EWOMS_REGISTER_PARAM ( TypeTag , double , MinTimeStepBeforeShuttingProblematicWellsInDays ,
" The minimum time step size in days for which problematic wells are not shut " ) ;
2021-02-17 04:30:57 -06:00
EWOMS_REGISTER_PARAM ( TypeTag , double , MinTimeStepBasedOnNewtonIterations ,
" The minimum time step size (in days for field and metric unit and hours for lab unit) can be reduced to based on newton iteration counts " ) ;
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
*/
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 ,
const std : : vector < int > * fipnum = nullptr )
2018-06-06 03:59:41 -05:00
{
SimulatorReport report ;
const double timestep = simulatorTimer . currentStepLength ( ) ;
// init last time step as a fraction of the given time step
if ( suggestedNextTimestep_ < 0 ) {
suggestedNextTimestep_ = restartFactor_ * timestep ;
}
if ( fullTimestepInitially_ ) {
suggestedNextTimestep_ = timestep ;
}
// use seperate time step after event
if ( isEvent & & timestepAfterEvent_ > 0 ) {
suggestedNextTimestep_ = timestepAfterEvent_ ;
}
2018-06-06 03:59:41 -05:00
auto & ebosSimulator = solver . model ( ) . ebosSimulator ( ) ;
auto & ebosProblem = ebosSimulator . problem ( ) ;
2018-06-06 03:59:41 -05:00
// create adaptive step timer with previously used sub step size
AdaptiveSimulatorTimer substepTimer ( simulatorTimer , suggestedNextTimestep_ , maxTimeStep_ ) ;
// counter for solver restarts
int restarts = 0 ;
// sub step time loop
while ( ! substepTimer . done ( ) ) {
// get current delta t
const double dt = substepTimer . currentStepLength ( ) ;
if ( timestepVerbose_ ) {
2023-03-01 06:47:00 -06:00
detail : : logTimer ( substepTimer ) ;
2018-06-06 03:59:41 -05:00
}
2020-05-07 09:13:39 -05:00
SimulatorReportSingle substepReport ;
2023-02-08 07:54:48 -06:00
std : : string causeOfFailure ;
2018-06-06 03:59:41 -05:00
try {
substepReport = solver . step ( substepTimer ) ;
2023-07-12 06:56:14 -05:00
2018-06-06 03:59:41 -05:00
if ( solverVerbose_ ) {
// report number of linear iterations
OpmLog : : debug ( " Overall linear iterations used: " + std : : to_string ( substepReport . total_linear_iterations ) ) ;
}
}
2021-05-05 04:22:44 -05:00
catch ( const TooManyIterations & e ) {
2020-05-07 15:09:17 -05:00
substepReport = solver . failureReport ( ) ;
2018-06-06 03:59:41 -05:00
causeOfFailure = " Solver convergence failure - Iteration limit reached " ;
logException_ ( e , solverVerbose_ ) ;
// since linearIterations is < 0 this will restart the solver
}
2021-05-05 04:22:44 -05:00
catch ( const LinearSolverProblem & e ) {
2020-05-07 15:09:17 -05:00
substepReport = solver . failureReport ( ) ;
2018-06-06 03:59:41 -05:00
causeOfFailure = " Linear solver convergence failure " ;
logException_ ( e , solverVerbose_ ) ;
// since linearIterations is < 0 this will restart the solver
}
2022-12-13 05:54:27 -06:00
catch ( const NumericalProblem & e ) {
2020-05-07 15:09:17 -05:00
substepReport = solver . failureReport ( ) ;
2018-06-06 03:59:41 -05:00
causeOfFailure = " Solver convergence failure - Numerical problem encountered " ;
logException_ ( e , solverVerbose_ ) ;
// since linearIterations is < 0 this will restart the solver
}
catch ( const std : : runtime_error & e ) {
2020-05-07 15:09:17 -05:00
substepReport = solver . failureReport ( ) ;
2018-06-06 03:59:41 -05:00
logException_ ( e , solverVerbose_ ) ;
// also catch linear solver not converged
}
catch ( const Dune : : ISTLError & e ) {
2020-05-07 15:09:17 -05:00
substepReport = solver . failureReport ( ) ;
2018-06-06 03:59:41 -05:00
logException_ ( e , solverVerbose_ ) ;
// also catch errors in ISTL AMG that occur when time step is too large
}
catch ( const Dune : : MatrixBlockError & e ) {
2020-05-07 15:09:17 -05:00
substepReport = solver . failureReport ( ) ;
2018-06-06 03:59:41 -05:00
logException_ ( e , solverVerbose_ ) ;
// this can be thrown by ISTL's ILU0 in block mode, yet is not an ISTLError
}
2022-02-03 04:58:09 -06:00
//Pass substep to eclwriter for summary output
ebosSimulator . problem ( ) . setSubStepReport ( substepReport ) ;
2020-05-07 09:13:39 -05:00
report + = substepReport ;
2021-09-09 00:46:09 -05:00
bool continue_on_uncoverged_solution = ignoreConvergenceFailure_ & & ! substepReport . converged & & dt < = minTimeStep_ ;
if ( continue_on_uncoverged_solution ) {
const auto msg = std : : string ( " Solver failed to converge but timestep " )
+ std : : to_string ( dt ) + " is smaller or equal to "
+ std : : to_string ( minTimeStep_ ) + " \n which is the minimum threshold given "
+ " by option --solver-min-time-step= \n " ;
if ( solverVerbose_ ) {
OpmLog : : error ( msg ) ;
}
}
if ( substepReport . converged | | continue_on_uncoverged_solution ) {
2018-06-06 03:59:41 -05:00
// advance by current dt
+ + substepTimer ;
// create object to compute the time error, simply forwards the call to the model
SolutionTimeErrorSolverWrapperEbos < Solver > relativeChange ( solver ) ;
// compute new time step estimate
const int iterations = useNewtonIteration_ ? substepReport . total_newton_iterations
: substepReport . total_linear_iterations ;
double dtEstimate = timeStepControl_ - > computeTimeStepSize ( dt , iterations , relativeChange ,
substepTimer . simulationTimeElapsed ( ) ) ;
2019-10-11 08:57:51 -05:00
assert ( dtEstimate > 0 ) ;
2018-06-06 03:59:41 -05:00
// limit the growth of the timestep size by the growth factor
dtEstimate = std : : min ( dtEstimate , double ( maxGrowth_ * dt ) ) ;
2019-10-11 08:57:51 -05:00
assert ( dtEstimate > 0 ) ;
2018-06-06 03:59:41 -05:00
// further restrict time step size growth after convergence problems
if ( restarts > 0 ) {
dtEstimate = std : : min ( growthFactor_ * dt , dtEstimate ) ;
// solver converged, reset restarts counter
restarts = 0 ;
}
2018-11-22 09:24:52 -06:00
// Further restrict time step size if we are in
2018-11-22 04:01:58 -06:00
// prediction mode with THP constraints.
if ( solver . model ( ) . wellModel ( ) . hasTHPConstraints ( ) ) {
const double maxPredictionTHPTimestep = 16.0 * unit : : day ;
dtEstimate = std : : min ( dtEstimate , maxPredictionTHPTimestep ) ;
}
2019-10-11 08:57:51 -05:00
assert ( dtEstimate > 0 ) ;
2018-06-06 03:59:41 -05:00
if ( timestepVerbose_ ) {
std : : ostringstream ss ;
substepReport . reportStep ( ss ) ;
OpmLog : : info ( ss . str ( ) ) ;
}
// write data if outputWriter was provided
// if the time step is done we do not need
// to write it as this will be done by the simulator
// anyway.
if ( ! substepTimer . done ( ) ) {
if ( fipnum ) {
solver . computeFluidInPlace ( * fipnum ) ;
}
2021-05-05 04:22:44 -05:00
time : : StopWatch perfTimer ;
2018-06-06 03:59:41 -05:00
perfTimer . start ( ) ;
2018-06-06 03:59:41 -05:00
2019-05-13 05:49:43 -05:00
ebosProblem . writeOutput ( ) ;
2018-06-06 03:59:41 -05:00
2020-05-07 09:13:39 -05:00
report . success . output_write_time + = perfTimer . secsSinceStart ( ) ;
2018-06-06 03:59:41 -05:00
}
// set new time step length
substepTimer . provideTimeStepEstimate ( dtEstimate ) ;
2020-05-07 09:13:39 -05:00
report . success . converged = substepTimer . done ( ) ;
2018-06-06 03:59:41 -05:00
substepTimer . setLastStepFailed ( false ) ;
}
2018-12-03 06:25:19 -06:00
else { // in case of no convergence
2018-06-06 03:59:41 -05:00
substepTimer . setLastStepFailed ( true ) ;
2018-12-03 06:25:19 -06:00
// If we have restarted (i.e. cut the timestep) too
// many times, we have failed and throw an exception.
2018-06-06 03:59:41 -05:00
if ( restarts > = solverRestartMax_ ) {
const auto msg = std : : string ( " Solver failed to converge after cutting timestep " )
+ std : : to_string ( restarts ) + " times. " ;
if ( solverVerbose_ ) {
OpmLog : : error ( msg ) ;
}
2023-07-12 06:56:14 -05:00
// Use throw directly to prevent file and line
2023-07-25 08:01:44 -05:00
throw TimeSteppingBreakdown { msg } ;
2018-06-06 03:59:41 -05:00
}
2018-12-03 06:25:19 -06:00
// The new, chopped timestep.
2018-06-06 03:59:41 -05:00
const double newTimeStep = restartFactor_ * dt ;
2018-12-03 06:25:19 -06:00
2019-11-28 08:18:39 -06:00
// If we have restarted (i.e. cut the timestep) too
// much, we have failed and throw an exception.
if ( newTimeStep < minTimeStep_ ) {
const auto msg = std : : string ( " Solver failed to converge after cutting timestep to " )
+ std : : to_string ( minTimeStep_ ) + " \n which is the minimum threshold given "
+ " by option --solver-min-time-step= \n " ;
if ( solverVerbose_ ) {
OpmLog : : error ( msg ) ;
}
2023-07-12 06:56:14 -05:00
// Use throw directly to prevent file and line
2023-07-25 08:01:44 -05:00
throw TimeSteppingBreakdown { msg } ;
2019-11-28 08:18:39 -06:00
}
2018-12-03 06:25:19 -06:00
// Define utility function for chopping timestep.
auto chopTimestep = [ & ] ( ) {
2018-11-22 09:24:52 -06:00
substepTimer . provideTimeStepEstimate ( newTimeStep ) ;
if ( solverVerbose_ ) {
std : : string msg ;
msg = causeOfFailure + " \n Timestep chopped to "
+ std : : to_string ( unit : : convert : : to ( substepTimer . currentStepLength ( ) , unit : : day ) ) + " days \n " ;
OpmLog : : problem ( msg ) ;
}
+ + restarts ;
2018-12-03 06:25:19 -06:00
} ;
2019-12-18 04:18:18 -06:00
const double minimumChoppedTimestep = minTimeStepBeforeShuttingProblematicWells_ ;
2018-12-03 06:25:19 -06:00
if ( newTimeStep > minimumChoppedTimestep ) {
chopTimestep ( ) ;
2018-11-22 09:24:52 -06:00
} else {
// We are below the threshold, and will check if there are any
// wells we should close rather than chopping again.
2023-03-01 06:47:00 -06:00
std : : set < std : : string > failing_wells = detail : : consistentlyFailingWells ( solver . model ( ) . stepReports ( ) ) ;
2018-11-22 09:24:52 -06:00
if ( failing_wells . empty ( ) ) {
// Found no wells to close, chop the timestep as above.
2018-12-03 06:25:19 -06:00
chopTimestep ( ) ;
2018-11-22 09:24:52 -06:00
} else {
// Close all consistently failing wells.
2018-12-03 06:25:19 -06:00
int num_shut_wells = 0 ;
2018-11-22 09:24:52 -06:00
for ( const auto & well : failing_wells ) {
2021-10-14 06:14:38 -05:00
bool was_shut = solver . model ( ) . wellModel ( ) . forceShutWellByName ( well , substepTimer . simulationTimeElapsed ( ) ) ;
2018-12-03 06:25:19 -06:00
if ( was_shut ) {
+ + num_shut_wells ;
}
2018-11-22 09:24:52 -06:00
}
2018-12-03 06:25:19 -06:00
if ( num_shut_wells = = 0 ) {
2021-10-14 06:14:38 -05:00
// None of the problematic wells were shut.
// We must fall back to chopping again.
2018-12-03 06:25:19 -06:00
chopTimestep ( ) ;
} else {
substepTimer . provideTimeStepEstimate ( dt ) ;
if ( solverVerbose_ ) {
std : : string msg ;
msg = " \n Problematic well(s) were shut: " ;
for ( const auto & well : failing_wells ) {
msg + = well ;
msg + = " " ;
}
msg + = " (retrying timestep) \n " ;
OpmLog : : problem ( msg ) ;
2018-11-22 09:24:52 -06:00
}
}
}
}
2018-06-06 03:59:41 -05:00
}
2018-08-16 04:51:36 -05:00
ebosProblem . setNextTimeStepSize ( substepTimer . currentStepLength ( ) ) ;
2018-06-06 03:59:41 -05:00
}
// store estimated time step for next reportStep
suggestedNextTimestep_ = substepTimer . currentStepLength ( ) ;
if ( timestepVerbose_ ) {
std : : ostringstream ss ;
substepTimer . report ( ss ) ;
ss < < " Suggested next step size = " < < unit : : convert : : to ( suggestedNextTimestep_ , unit : : day ) < < " (days) " < < std : : endl ;
OpmLog : : debug ( ss . str ( ) ) ;
}
if ( ! std : : isfinite ( suggestedNextTimestep_ ) ) { // check for NaN
suggestedNextTimestep_ = timestep ;
}
return report ;
}
/** \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 ; }
2021-10-18 04:52:33 -05:00
void updateTUNING ( double max_next_tstep , const Tuning & tuning )
2018-06-06 03:59:41 -05:00
{
2020-01-31 06:42:50 -06:00
restartFactor_ = tuning . TSFCNV ;
growthFactor_ = tuning . TFDIFF ;
maxGrowth_ = tuning . TSFMAX ;
maxTimeStep_ = tuning . TSMAXZ ;
2021-10-18 04:52:33 -05:00
suggestedNextTimestep_ = max_next_tstep ;
2020-01-31 06:42:50 -06:00
timestepAfterEvent_ = tuning . TMAXWC ;
2018-06-06 03:59:41 -05:00
}
2023-01-31 05:38:54 -06:00
template < class Serializer >
void serializeOp ( Serializer & serializer )
{
serializer ( timeStepControlType_ ) ;
switch ( timeStepControlType_ ) {
case TimeStepControlType : : HardCodedTimeStep :
allocAndSerialize < HardcodedTimeStepControl > ( serializer ) ;
break ;
case TimeStepControlType : : PIDAndIterationCount :
allocAndSerialize < PIDAndIterationCountTimeStepControl > ( serializer ) ;
break ;
case TimeStepControlType : : SimpleIterationCount :
allocAndSerialize < SimpleIterationCountTimeStepControl > ( serializer ) ;
break ;
case TimeStepControlType : : PID :
allocAndSerialize < PIDTimeStepControl > ( serializer ) ;
break ;
}
serializer ( restartFactor_ ) ;
serializer ( growthFactor_ ) ;
serializer ( maxGrowth_ ) ;
serializer ( maxTimeStep_ ) ;
serializer ( minTimeStep_ ) ;
serializer ( ignoreConvergenceFailure_ ) ;
serializer ( solverRestartMax_ ) ;
serializer ( solverVerbose_ ) ;
serializer ( timestepVerbose_ ) ;
serializer ( suggestedNextTimestep_ ) ;
serializer ( fullTimestepInitially_ ) ;
serializer ( timestepAfterEvent_ ) ;
serializer ( useNewtonIteration_ ) ;
serializer ( minTimeStepBeforeShuttingProblematicWells_ ) ;
}
static AdaptiveTimeSteppingEbos < TypeTag > serializationTestObjectHardcoded ( )
{
return serializationTestObject_ < HardcodedTimeStepControl > ( ) ;
}
static AdaptiveTimeSteppingEbos < TypeTag > serializationTestObjectPID ( )
{
return serializationTestObject_ < PIDTimeStepControl > ( ) ;
}
static AdaptiveTimeSteppingEbos < TypeTag > serializationTestObjectPIDIt ( )
{
return serializationTestObject_ < PIDAndIterationCountTimeStepControl > ( ) ;
}
static AdaptiveTimeSteppingEbos < TypeTag > serializationTestObjectSimple ( )
{
return serializationTestObject_ < SimpleIterationCountTimeStepControl > ( ) ;
}
bool operator = = ( const AdaptiveTimeSteppingEbos < TypeTag > & rhs )
{
if ( timeStepControlType_ ! = rhs . timeStepControlType_ | |
( timeStepControl_ & & ! rhs . timeStepControl_ ) | |
( ! timeStepControl_ & & rhs . timeStepControl_ ) ) {
return false ;
}
bool result = false ;
switch ( timeStepControlType_ ) {
case TimeStepControlType : : HardCodedTimeStep :
result = castAndComp < HardcodedTimeStepControl > ( rhs ) ;
break ;
case TimeStepControlType : : PIDAndIterationCount :
result = castAndComp < PIDAndIterationCountTimeStepControl > ( rhs ) ;
break ;
case TimeStepControlType : : SimpleIterationCount :
result = castAndComp < SimpleIterationCountTimeStepControl > ( rhs ) ;
break ;
case TimeStepControlType : : PID :
result = castAndComp < PIDTimeStepControl > ( rhs ) ;
break ;
}
return result & &
this - > restartFactor_ = = rhs . restartFactor_ & &
this - > growthFactor_ = = rhs . growthFactor_ & &
this - > maxGrowth_ = = rhs . maxGrowth_ & &
this - > maxTimeStep_ = = rhs . maxTimeStep_ & &
this - > minTimeStep_ = = rhs . minTimeStep_ & &
this - > ignoreConvergenceFailure_ = = rhs . ignoreConvergenceFailure_ & &
this - > solverRestartMax_ = = rhs . solverRestartMax_ & &
this - > solverVerbose_ = = rhs . solverVerbose_ & &
this - > fullTimestepInitially_ = = rhs . fullTimestepInitially_ & &
this - > timestepAfterEvent_ = = rhs . timestepAfterEvent_ & &
this - > useNewtonIteration_ = = rhs . useNewtonIteration_ & &
this - > minTimeStepBeforeShuttingProblematicWells_ = =
rhs . minTimeStepBeforeShuttingProblematicWells_ ;
}
private :
template < class Controller >
static AdaptiveTimeSteppingEbos < TypeTag > serializationTestObject_ ( )
{
AdaptiveTimeSteppingEbos < TypeTag > result ;
result . restartFactor_ = 1.0 ;
result . growthFactor_ = 2.0 ;
result . maxGrowth_ = 3.0 ;
result . maxTimeStep_ = 4.0 ;
result . minTimeStep_ = 5.0 ;
result . ignoreConvergenceFailure_ = true ;
result . solverRestartMax_ = 6 ;
result . solverVerbose_ = true ;
result . timestepVerbose_ = true ;
result . suggestedNextTimestep_ = 7.0 ;
2023-02-14 08:46:08 -06:00
result . fullTimestepInitially_ = true ;
2023-01-31 05:38:54 -06:00
result . useNewtonIteration_ = true ;
result . minTimeStepBeforeShuttingProblematicWells_ = 9.0 ;
result . timeStepControlType_ = Controller : : Type ;
result . timeStepControl_ = std : : make_unique < Controller > ( Controller : : serializationTestObject ( ) ) ;
return result ;
}
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 >
bool castAndComp ( const AdaptiveTimeSteppingEbos < TypeTag > & Rhs ) const
{
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 :
2021-02-17 04:30:57 -06:00
void init_ ( const UnitSystem & unitSystem )
2018-06-06 03:59:41 -05:00
{
// valid are "pid" and "pid+iteration"
2018-08-06 08:59:35 -05:00
std : : string control = EWOMS_GET_PARAM ( TypeTag , std : : string , TimeStepControl ) ; // "pid"
2018-06-06 03:59:41 -05:00
2018-08-06 08:59:35 -05:00
const double tol = EWOMS_GET_PARAM ( TypeTag , double , TimeStepControlTolerance ) ; // 1e-1
2018-06-06 03:59:41 -05:00
if ( control = = " pid " ) {
2023-01-31 05:38:54 -06:00
timeStepControl_ = std : : make_unique < PIDTimeStepControl > ( tol ) ;
timeStepControlType_ = TimeStepControlType : : PID ;
2018-06-06 03:59:41 -05:00
}
else if ( control = = " pid+iteration " ) {
2018-08-06 08:59:35 -05:00
const int iterations = EWOMS_GET_PARAM ( TypeTag , int , TimeStepControlTargetIterations ) ; // 30
2020-10-01 07:02:39 -05:00
const double decayDampingFactor = EWOMS_GET_PARAM ( TypeTag , double , TimeStepControlDecayDampingFactor ) ; // 1.0
2020-11-09 04:45:13 -06:00
const double growthDampingFactor = EWOMS_GET_PARAM ( TypeTag , double , TimeStepControlGrowthDampingFactor ) ; // 3.2
2023-01-31 05:38:54 -06:00
timeStepControl_ = std : : make_unique < PIDAndIterationCountTimeStepControl > ( iterations , decayDampingFactor , growthDampingFactor , tol ) ;
timeStepControlType_ = TimeStepControlType : : PIDAndIterationCount ;
2018-06-06 03:59:41 -05:00
}
else if ( control = = " pid+newtoniteration " ) {
2018-08-06 08:59:35 -05:00
const int iterations = EWOMS_GET_PARAM ( TypeTag , int , TimeStepControlTargetNewtonIterations ) ; // 8
2020-10-01 07:02:39 -05:00
const double decayDampingFactor = EWOMS_GET_PARAM ( TypeTag , double , TimeStepControlDecayDampingFactor ) ; // 1.0
2020-11-09 04:45:13 -06:00
const double growthDampingFactor = EWOMS_GET_PARAM ( TypeTag , double , TimeStepControlGrowthDampingFactor ) ; // 3.2
2021-02-17 04:30:57 -06:00
const double nonDimensionalMinTimeStepIterations = EWOMS_GET_PARAM ( TypeTag , double , MinTimeStepBasedOnNewtonIterations ) ; // 0.0 by default
// the min time step can be reduced by the newton iteration numbers
2021-03-18 03:23:48 -05:00
double minTimeStepReducedByIterations = unitSystem . to_si ( UnitSystem : : measure : : time , nonDimensionalMinTimeStepIterations ) ;
2023-01-31 05:38:54 -06:00
timeStepControl_ = std : : make_unique < PIDAndIterationCountTimeStepControl > ( iterations , decayDampingFactor ,
growthDampingFactor , tol , minTimeStepReducedByIterations ) ;
timeStepControlType_ = TimeStepControlType : : PIDAndIterationCount ;
2018-06-06 03:59:41 -05:00
useNewtonIteration_ = true ;
}
else if ( control = = " iterationcount " ) {
2018-08-06 08:59:35 -05:00
const int iterations = EWOMS_GET_PARAM ( TypeTag , int , TimeStepControlTargetIterations ) ; // 30
const double decayrate = EWOMS_GET_PARAM ( TypeTag , double , TimeStepControlDecayRate ) ; // 0.75
const double growthrate = EWOMS_GET_PARAM ( TypeTag , double , TimeStepControlGrowthRate ) ; // 1.25
2023-01-31 05:38:54 -06:00
timeStepControl_ = std : : make_unique < SimpleIterationCountTimeStepControl > ( iterations , decayrate , growthrate ) ;
timeStepControlType_ = TimeStepControlType : : SimpleIterationCount ;
2018-06-06 03:59:41 -05:00
}
2020-10-01 07:02:39 -05:00
else if ( control = = " newtoniterationcount " ) {
const int iterations = EWOMS_GET_PARAM ( TypeTag , int , TimeStepControlTargetNewtonIterations ) ; // 8
const double decayrate = EWOMS_GET_PARAM ( TypeTag , double , TimeStepControlDecayRate ) ; // 0.75
const double growthrate = EWOMS_GET_PARAM ( TypeTag , double , TimeStepControlGrowthRate ) ; // 1.25
2023-01-31 05:38:54 -06:00
timeStepControl_ = std : : make_unique < SimpleIterationCountTimeStepControl > ( iterations , decayrate , growthrate ) ;
2020-10-01 07:02:39 -05:00
useNewtonIteration_ = true ;
2023-01-31 05:38:54 -06:00
timeStepControlType_ = TimeStepControlType : : SimpleIterationCount ;
2020-10-01 07:02:39 -05:00
}
2018-06-06 03:59:41 -05:00
else if ( control = = " hardcoded " ) {
2018-08-06 08:59:35 -05:00
const std : : string filename = EWOMS_GET_PARAM ( TypeTag , std : : string , TimeStepControlFileName ) ; // "timesteps"
2023-01-31 05:38:54 -06:00
timeStepControl_ = std : : make_unique < HardcodedTimeStepControl > ( filename ) ;
timeStepControlType_ = TimeStepControlType : : HardCodedTimeStep ;
2018-06-06 03:59:41 -05:00
}
else
2023-01-02 08:21:42 -06:00
OPM_THROW ( std : : runtime_error ,
" Unsupported time step control selected " + control ) ;
2018-06-06 03:59:41 -05:00
// make sure growth factor is something reasonable
assert ( growthFactor_ > = 1.0 ) ;
}
2023-01-31 05:38:54 -06:00
using TimeStepController = std : : unique_ptr < TimeStepControlInterface > ;
2018-06-06 03:59:41 -05:00
2023-01-31 05:38:54 -06:00
TimeStepControlType timeStepControlType_ ; //!< type of time step control object
TimeStepController timeStepControl_ ; //!< time step control object
2018-06-06 03:59:41 -05:00
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
2019-11-28 08:18:39 -06:00
double maxTimeStep_ ; //!< maximal allowed time step size in days
double minTimeStep_ ; //!< minimal allowed time step size before throwing
2021-09-09 00:46:09 -05:00
bool ignoreConvergenceFailure_ ; //!< continue instead of stop when minimum time step is reached
2018-06-21 05:14:17 -05:00
int solverRestartMax_ ; //!< how many restart of solver are allowed
bool solverVerbose_ ; //!< solver verbosity
bool timestepVerbose_ ; //!< timestep verbosity
2018-06-06 03:59:41 -05:00
double suggestedNextTimestep_ ; //!< suggested size of next timestep
bool fullTimestepInitially_ ; //!< beginning with the size of the time step from data file
double timestepAfterEvent_ ; //!< suggested size of timestep after an event
bool useNewtonIteration_ ; //!< use newton iteration count for adaptive time step control
2019-12-18 04:18:18 -06:00
double minTimeStepBeforeShuttingProblematicWells_ ; //! < shut problematic wells when time step size in days are less than this
2018-06-06 03:59:41 -05:00
} ;
}
# endif // OPM_ADAPTIVE_TIME_STEPPING_EBOS_HPP