AdaptiveSimulatorTimer: initialization of first time step size follows the same rule as

for later steps.
PIDTimeStepControl: added maxgrowth factor which indicates the maximum allow groth of
                    the time step from one to the next value.
This commit is contained in:
Robert K 2015-01-16 14:56:37 +01:00
parent f7bd6076e6
commit f38b76abe9
5 changed files with 50 additions and 52 deletions

View File

@ -36,7 +36,7 @@ namespace Opm
, total_time_( start_time_ + timer.currentStepLength() )
, report_step_( timer.reportStepNum() )
, current_time_( start_time_ )
, dt_( computeInitialTimeStep( lastStepTaken ) )
, dt_( 0.0 )
, current_step_( 0 )
, steps_()
, suggestedMax_( 0.0 )
@ -44,6 +44,9 @@ namespace Opm
{
// reserve memory for sub steps
steps_.reserve( 10 );
// set appropriate value for dt_
provideTimeStepEstimate( lastStepTaken );
}
AdaptiveSimulatorTimer& AdaptiveSimulatorTimer::operator++ ()
@ -161,16 +164,4 @@ namespace Opm
return start_date_time_;
}
double AdaptiveSimulatorTimer::
computeInitialTimeStep( const double lastDt ) const
{
const double maxTimeStep = total_time_ - start_time_;
const double fraction = (lastDt / maxTimeStep);
// when lastDt and maxTimeStep are close together, choose the max time step
if( fraction > 0.95 ) return maxTimeStep;
// otherwise choose lastDt
return std::min( lastDt, maxTimeStep );
}
} // namespace Opm

View File

@ -105,8 +105,6 @@ namespace Opm
std::vector< double > steps_;
double suggestedMax_;
double suggestedAverage_;
double computeInitialTimeStep( const double lastDt ) const;
};
} // namespace Opm

View File

@ -51,8 +51,9 @@ namespace Opm {
}
else if ( control == "pid+iteration" )
{
const int iterations = param.getDefault("timestep.control.targetiteration", int(25) );
timeStepControl_ = TimeStepControlType( new PIDAndIterationCountTimeStepControl( iterations, tol ) );
const int iterations = param.getDefault("timestep.control.targetiteration", int(25) );
const double maxgrowth = param.getDefault("timestep.control.maxgrowth", double(3.0) );
timeStepControl_ = TimeStepControlType( new PIDAndIterationCountTimeStepControl( iterations, tol, maxgrowth ) );
}
else
OPM_THROW(std::runtime_error,"Unsupported time step control selected "<< control );
@ -150,7 +151,7 @@ namespace Opm {
{
std::cout << std::endl
<<"Substep( " << substepTimer.currentStepNum()
<< " ): Current time (days) " << unit::convert::to(substepTimer.simulationTimeElapsed(),unit::day) << std::endl
<< " ): Current time (days) " << unit::convert::to(substepTimer.simulationTimeElapsed(),unit::day) << std::endl
<< " Current stepsize est (days) " << unit::convert::to(dtEstimate, unit::day) << std::endl;
}

View File

@ -1,5 +1,5 @@
/*
Copyright 2014 IRIS AS
Copyright 2014 IRIS AS
This file is part of the Open Porous Media project (OPM).
@ -24,17 +24,17 @@
#include <opm/core/utility/Units.hpp>
#include <opm/core/simulator/PIDTimeStepControl.hpp>
namespace Opm
namespace Opm
{
PIDTimeStepControl::PIDTimeStepControl( const double tol, const bool verbose )
PIDTimeStepControl::PIDTimeStepControl( const double tol, const bool verbose )
: p0_()
, sat0_()
, sat0_()
, tol_( tol )
, errors_( 3, tol_ )
, verbose_( verbose )
{}
void PIDTimeStepControl::initialize( const SimulatorState& state )
void PIDTimeStepControl::initialize( const SimulatorState& state )
{
// store current state for later time step computation
p0_ = state.pressure();
@ -49,7 +49,7 @@ namespace Opm
const std::size_t satSize = sat0_.size();
assert( state.saturation().size() == satSize );
// compute u^n - u^n+1
// compute u^n - u^n+1
for( std::size_t i=0; i<pSize; ++i ) {
p0_[ i ] -= state.pressure()[ i ];
}
@ -58,11 +58,11 @@ namespace Opm
sat0_[ i ] -= state.saturation()[ i ];
}
// compute || u^n - u^n+1 ||
// compute || u^n - u^n+1 ||
const double stateOld = euclidianNormSquared( p0_.begin(), p0_.end() ) +
euclidianNormSquared( sat0_.begin(), sat0_.end() );
// compute || u^n+1 ||
// compute || u^n+1 ||
const double stateNew = euclidianNormSquared( state.pressure().begin(), state.pressure().end() ) +
euclidianNormSquared( state.saturation().begin(), state.saturation().end() );
@ -77,7 +77,7 @@ namespace Opm
if( error > tol_ )
{
// adjust dt by given tolerance
// adjust dt by given tolerance
const double newDt = dt * tol_ / error;
if( verbose_ )
std::cout << "Computed step size (tol): " << unit::convert::to( newDt, unit::day ) << " (days)" << std::endl;
@ -101,10 +101,12 @@ namespace Opm
PIDAndIterationCountTimeStepControl::
PIDAndIterationCountTimeStepControl( const int target_iterations,
const double tol,
const bool verbose)
const double tol,
const double maxgrowth,
const bool verbose)
: BaseType( tol, verbose )
, target_iterations_( target_iterations )
, maxgrowth_( maxgrowth )
{}
double PIDAndIterationCountTimeStepControl::
@ -113,12 +115,15 @@ namespace Opm
double dtEstimate = BaseType :: computeTimeStepSize( dt, iterations, state );
// further reduce step size if to many iterations were used
if( iterations > target_iterations_ )
if( iterations > target_iterations_ )
{
// if iterations was the same or dts were the same, do some magic
dtEstimate *= double( target_iterations_ ) / double(iterations);
}
// limit the growth of the timestep size by the growth factor
dtEstimate = std::max( dtEstimate, double(maxgrowth_ * dt) );
return dtEstimate;
}

View File

@ -1,5 +1,5 @@
/*
Copyright 2014 IRIS AS
Copyright 2014 IRIS AS
This file is part of the Open Porous Media project (OPM).
@ -23,27 +23,27 @@
#include <opm/core/simulator/TimeStepControlInterface.hpp>
namespace Opm
namespace Opm
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// PID controller based adaptive time step control as suggested in:
/// Turek and Kuzmin. Algebraic Flux Correction III. Incompressible Flow Problems. Uni Dortmund.
///
/// See also:
/// PID controller based adaptive time step control as suggested in:
/// Turek and Kuzmin. Algebraic Flux Correction III. Incompressible Flow Problems. Uni Dortmund.
///
/// See also:
/// D. Kuzmin and S.Turek. Numerical simulation of turbulent bubbly flows. Techreport Uni Dortmund. 2004
///
/// and the original article:
///
/// and the original article:
/// Valli, Coutinho, and Carey. Adaptive Control for Time Step Selection in Finite Element
/// Simulation of Coupled Viscous Flow and Heat Transfer. Proc of the 10th
/// Simulation of Coupled Viscous Flow and Heat Transfer. Proc of the 10th
/// International Conference on Numerical Methods in Fluids. 1998.
///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
class PIDTimeStepControl : public TimeStepControlInterface
{
public:
/// \brief constructor
/// \param tol tolerance for the relative changes of the numerical solution to be accepted
/// \brief constructor
/// \param tol tolerance for the relative changes of the numerical solution to be accepted
/// in one time step (default is 1e-3)
/// \param verbose if true get some output (default = false)
PIDTimeStepControl( const double tol = 1e-3, const bool verbose = false );
@ -54,10 +54,10 @@ namespace Opm
/// \brief \copydoc TimeStepControlInterface::computeTimeStepSize
double computeTimeStepSize( const double dt, const int /* iterations */, const SimulatorState& state ) const;
protected:
protected:
// return inner product for given container, here std::vector
template <class Iterator>
double euclidianNormSquared( Iterator it, const Iterator end ) const
double euclidianNormSquared( Iterator it, const Iterator end ) const
{
double product = 0.0 ;
for( ; it != end; ++it ) {
@ -66,7 +66,7 @@ namespace Opm
return product;
}
protected:
protected:
mutable std::vector<double> p0_;
mutable std::vector<double> sat0_;
@ -78,7 +78,7 @@ namespace Opm
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// PID controller based adaptive time step control as above that also takes
/// PID controller based adaptive time step control as above that also takes
/// an target iteration into account.
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -86,20 +86,23 @@ namespace Opm
{
typedef PIDTimeStepControl BaseType;
public:
/// \brief constructor
/// \brief constructor
/// \param target_iterations number of desired iterations per time step
/// \param tol tolerance for the relative changes of the numerical solution to be accepted
/// in one time step (default is 1e-3)
/// \param verbose if true get some output (default = false)
/// \param tol tolerance for the relative changes of the numerical solution to be accepted
/// in one time step (default is 1e-3)
// \param maxgrodth max growth factor for new time step in relation of old time step (default = 3.0)
/// \param verbose if true get some output (default = false)
PIDAndIterationCountTimeStepControl( const int target_iterations = 20,
const double tol = 1e-3,
const double tol = 1e-3,
const double maxgrowth = 3.0,
const bool verbose = false);
/// \brief \copydoc TimeStepControlInterface::computeTimeStepSize
double computeTimeStepSize( const double dt, const int iterations, const SimulatorState& state ) const;
protected:
const int target_iterations_;
protected:
const int target_iterations_;
const double maxgrowth_;
};