diff --git a/opm/core/simulator/AdaptiveTimeStepping_impl.hpp b/opm/core/simulator/AdaptiveTimeStepping_impl.hpp index 56a11dec..33d92d90 100644 --- a/opm/core/simulator/AdaptiveTimeStepping_impl.hpp +++ b/opm/core/simulator/AdaptiveTimeStepping_impl.hpp @@ -95,6 +95,10 @@ namespace Opm { const double decayrate = param.getDefault("timestep.control.decayrate", double(0.75) ); const double growthrate = param.getDefault("timestep.control.growthrate", double(1.25) ); timeStepControl_ = TimeStepControlType( new SimpleIterationCountTimeStepControl( iterations, decayrate, growthrate ) ); + } else if ( control == "hardcoded") { + const std::string filename = param.getDefault("timestep.control.filename", std::string("timesteps")); + timeStepControl_ = TimeStepControlType( new HardcodedTimeStepControl( filename ) ); + } else OPM_THROW(std::runtime_error,"Unsupported time step control selected "<< control ); @@ -202,7 +206,7 @@ namespace Opm { // compute new time step estimate double dtEstimate = - timeStepControl_->computeTimeStepSize( dt, linearIterations, relativeChange ); + timeStepControl_->computeTimeStepSize( dt, linearIterations, relativeChange, substepTimer.simulationTimeElapsed()); // limit the growth of the timestep size by the growth factor dtEstimate = std::min( dtEstimate, double(max_growth_ * dt) ); diff --git a/opm/core/simulator/TimeStepControl.cpp b/opm/core/simulator/TimeStepControl.cpp index e7d11043..a6787191 100644 --- a/opm/core/simulator/TimeStepControl.cpp +++ b/opm/core/simulator/TimeStepControl.cpp @@ -23,6 +23,9 @@ #include #include #include +#include +#include +#include #include #include @@ -55,7 +58,7 @@ namespace Opm } double SimpleIterationCountTimeStepControl:: - computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& /* relativeChange */ ) const + computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& /* relativeChange */, const double /*simulationTimeElapsed */) const { double dtEstimate = dt ; @@ -74,6 +77,37 @@ namespace Opm return dtEstimate; } + //////////////////////////////////////////////////////// + // + // HardcodedTimeStepControl Implementation + // + //////////////////////////////////////////////////////// + + HardcodedTimeStepControl:: + HardcodedTimeStepControl( const std::string& filename) + { + std::ifstream infile (filename); + if (!infile.is_open()) { + OPM_THROW(std::runtime_error,"Incorrect or no filename is provided to the hardcodedTimeStep. Use timestep.control.filename=your_file_name"); + } + std::string::size_type sz; + std::string line; + while ( std::getline(infile, line)) { + if( line[0] != '-') { // ignore lines starting with '-' + const double time = std::stod(line,&sz); // read the first number i.e. the actual substep time + subStepTime_.push_back( time * unit::day ); + } + + } + } + + double HardcodedTimeStepControl:: + computeTimeStepSize( const double /*dt */, const int /*iterations */, const RelativeChangeInterface& /* relativeChange */ , const double simulationTimeElapsed) const + { + auto nextTime = std::upper_bound(subStepTime_.begin(), subStepTime_.end(), simulationTimeElapsed); + return (*nextTime - simulationTimeElapsed); + } + //////////////////////////////////////////////////////// @@ -90,7 +124,7 @@ namespace Opm {} double PIDTimeStepControl:: - computeTimeStepSize( const double dt, const int /* iterations */, const RelativeChangeInterface& relChange ) const + computeTimeStepSize( const double dt, const int /* iterations */, const RelativeChangeInterface& relChange, const double /*simulationTimeElapsed */) const { // shift errors for( int i=0; i<2; ++i ) { @@ -141,9 +175,9 @@ namespace Opm {} double PIDAndIterationCountTimeStepControl:: - computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& relChange ) const + computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& relChange, const double simulationTimeElapsed ) const { - double dtEstimate = BaseType :: computeTimeStepSize( dt, iterations, relChange ); + double dtEstimate = BaseType :: computeTimeStepSize( dt, iterations, relChange, simulationTimeElapsed); // further reduce step size if to many iterations were used if( iterations > target_iterations_ ) diff --git a/opm/core/simulator/TimeStepControl.hpp b/opm/core/simulator/TimeStepControl.hpp index ec14ddbe..00a82d74 100644 --- a/opm/core/simulator/TimeStepControl.hpp +++ b/opm/core/simulator/TimeStepControl.hpp @@ -48,7 +48,7 @@ namespace Opm const bool verbose = false); /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize - double computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& /* relativeChange */ ) const; + double computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& /* relativeChange */, const double /*simulationTimeElapsed */ ) const; protected: const int target_iterations_; @@ -82,7 +82,7 @@ namespace Opm const bool verbose = false ); /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize - double computeTimeStepSize( const double dt, const int /* iterations */, const RelativeChangeInterface& relativeChange ) const; + double computeTimeStepSize( const double dt, const int /* iterations */, const RelativeChangeInterface& relativeChange, const double /*simulationTimeElapsed */ ) const; protected: const double tol_; @@ -111,12 +111,36 @@ namespace Opm const bool verbose = false); /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize - double computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& relativeChange ) const; + double computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& relativeChange, const double /*simulationTimeElapsed */ ) const; protected: const int target_iterations_; }; + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// + /// HardcodedTimeStepControl + /// Input generated from summary file using the ert application: + /// + /// ecl_summary DECK TIME > filename + /// + /// Assumes time is given in days + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + class HardcodedTimeStepControl : public TimeStepControlInterface + { + public: + /// \brief constructor + /// \param filename filename contaning the timesteps + explicit HardcodedTimeStepControl( const std::string& filename); + + /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize + double computeTimeStepSize( const double dt, const int /* iterations */, const RelativeChangeInterface& /*relativeChange */, const double simulationTimeElapsed) const; + + protected: + // store the time (in days) of the substeps the simulator should use + std::vector subStepTime_; + }; + } // end namespace Opm #endif diff --git a/opm/core/simulator/TimeStepControlInterface.hpp b/opm/core/simulator/TimeStepControlInterface.hpp index 2aee5aeb..bdab5e3a 100644 --- a/opm/core/simulator/TimeStepControlInterface.hpp +++ b/opm/core/simulator/TimeStepControlInterface.hpp @@ -56,7 +56,7 @@ namespace Opm /// \param timeError object to compute || u^n+1 - u^n || / || u^n+1 || /// /// \return suggested time step size for the next step - virtual double computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& relativeChange ) const = 0; + virtual double computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& relativeChange , const double simulationTimeElapsed) const = 0; /// virtual destructor (empty) virtual ~TimeStepControlInterface () {}