mirror of
https://github.com/OPM/opm-simulators.git
synced 2026-07-29 18:57:56 -05:00
implemented the PID controler, seems to work fine. More testing needed.
This commit is contained in:
@@ -191,7 +191,8 @@ namespace Opm {
|
|||||||
|
|
||||||
std::vector<int> primalVariable_;
|
std::vector<int> primalVariable_;
|
||||||
|
|
||||||
IterationCountTimeStepControl timeStepControl_;
|
//IterationCountTimeStepControl timeStepControl_;
|
||||||
|
PIDTimeStepControl timeStepControl_;
|
||||||
|
|
||||||
// Private methods.
|
// Private methods.
|
||||||
SolutionState
|
SolutionState
|
||||||
|
|||||||
@@ -279,6 +279,8 @@ namespace {
|
|||||||
computeWellConnectionPressures(state, xw);
|
computeWellConnectionPressures(state, xw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initialize time step control
|
||||||
|
timeStepControl_.initialize( x );
|
||||||
|
|
||||||
std::vector<std::vector<double>> residual_history;
|
std::vector<std::vector<double>> residual_history;
|
||||||
|
|
||||||
@@ -344,7 +346,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Linear iterations: " << linearIterations << std::endl;
|
std::cout << "Linear iterations: " << linearIterations << std::endl;
|
||||||
return timeStepControl_.computeTimeStepSize( dt, linearIterations );
|
return timeStepControl_.computeTimeStepSize( dt, linearIterations, x );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -355,7 +355,6 @@ namespace Opm
|
|||||||
|
|
||||||
if( subStepping )
|
if( subStepping )
|
||||||
{
|
{
|
||||||
|
|
||||||
// create sub step simulator timer with previously used sub step size
|
// create sub step simulator timer with previously used sub step size
|
||||||
SubStepSimulatorTimer subStepper( timer, lastSubStep );
|
SubStepSimulatorTimer subStepper( timer, lastSubStep );
|
||||||
|
|
||||||
@@ -368,7 +367,10 @@ namespace Opm
|
|||||||
subStepper.report( std::cout );
|
subStepper.report( std::cout );
|
||||||
|
|
||||||
// store last small time step for next reportStep
|
// store last small time step for next reportStep
|
||||||
lastSubStep = subStepper.currentStepLength();
|
//lastSubStep = subStepper.maxStepLength();
|
||||||
|
//lastSubStep = subStepper.averageStepLength();
|
||||||
|
//lastSubStep = subStepper.suggestedMax();
|
||||||
|
lastSubStep = subStepper.suggestedAverage();
|
||||||
|
|
||||||
std::cout << "Last suggested step size = " << lastSubStep << std::endl;
|
std::cout << "Last suggested step size = " << lastSubStep << std::endl;
|
||||||
if( lastSubStep != lastSubStep )
|
if( lastSubStep != lastSubStep )
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ namespace Opm
|
|||||||
protected:
|
protected:
|
||||||
TimeStepControlInterface() {}
|
TimeStepControlInterface() {}
|
||||||
public:
|
public:
|
||||||
virtual double computeTimeStepSize( const double dt, const int iterations ) const = 0;
|
virtual void initialize( const SimulatorState& state ) {}
|
||||||
|
virtual double computeTimeStepSize( const double dt, const int iterations, const SimulatorState& ) const = 0;
|
||||||
virtual ~TimeStepControlInterface () {}
|
virtual ~TimeStepControlInterface () {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -49,7 +50,7 @@ namespace Opm
|
|||||||
upperTargetIterationCount_( 200 ), lowerTargetIterationCount_( 30 )
|
upperTargetIterationCount_( 200 ), lowerTargetIterationCount_( 30 )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
double computeTimeStepSize( const double dt, const int iterations ) const
|
double computeTimeStepSize( const double dt, const int iterations, const SimulatorState& ) const
|
||||||
{
|
{
|
||||||
// make sure dt is somewhat reliable
|
// make sure dt is somewhat reliable
|
||||||
assert( dt > 0 && dt == dt );
|
assert( dt > 0 && dt == dt );
|
||||||
@@ -98,6 +99,98 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PIDTimeStepControl : public TimeStepControlInterface
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
mutable std::vector<double> p0_;
|
||||||
|
mutable std::vector<double> sat0_;
|
||||||
|
|
||||||
|
mutable double prevDt_;
|
||||||
|
mutable int prevIterations_;
|
||||||
|
const int targetIterationCount_;
|
||||||
|
const double adjustmentFactor_;
|
||||||
|
|
||||||
|
const int upperTargetIterationCount_;
|
||||||
|
const int lowerTargetIterationCount_;
|
||||||
|
|
||||||
|
const double tol_;
|
||||||
|
|
||||||
|
mutable std::vector< double > errors_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PIDTimeStepControl( const double tol = 8e-4 )
|
||||||
|
: p0_(), sat0_(), prevDt_( 0.0 ), prevIterations_( 0 ),
|
||||||
|
targetIterationCount_( 100 ), adjustmentFactor_( 1.25 ),
|
||||||
|
upperTargetIterationCount_( 200 ), lowerTargetIterationCount_( 30 ),
|
||||||
|
tol_( tol ),
|
||||||
|
errors_( 3, tol_ )
|
||||||
|
{}
|
||||||
|
|
||||||
|
void initialize( const SimulatorState& state )
|
||||||
|
{
|
||||||
|
// store current state
|
||||||
|
p0_ = state.pressure();
|
||||||
|
sat0_ = state.saturation();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
double inner_product( Iterator it, const Iterator end ) const
|
||||||
|
{
|
||||||
|
double product = 0.0 ;
|
||||||
|
for( ; it != end; ++it )
|
||||||
|
product += ( *it * *it );
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
double computeTimeStepSize( const double dt, const int iterations, const SimulatorState& state ) const
|
||||||
|
{
|
||||||
|
const size_t size = p0_.size();
|
||||||
|
assert( state.pressure().size() == size );
|
||||||
|
// compute u^n - u^n+1
|
||||||
|
for( size_t i=0; i<size; ++i )
|
||||||
|
{
|
||||||
|
p0_[ i ] -= state.pressure()[ i ];
|
||||||
|
sat0_[ i ] -= state.saturation()[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute || u^n - u^n+1 ||
|
||||||
|
double stateN0 = inner_product( p0_.begin(), p0_.end() ) +
|
||||||
|
inner_product( sat0_.begin(), sat0_.end() );
|
||||||
|
|
||||||
|
// compute || u^n+1 ||
|
||||||
|
double stateN = inner_product( state.pressure().begin(), state.pressure().end() ) +
|
||||||
|
inner_product( state.saturation().begin(), state.saturation().end() );
|
||||||
|
|
||||||
|
|
||||||
|
for( int i=0; i<2; ++i )
|
||||||
|
errors_[ i ] = errors_[i+1];
|
||||||
|
|
||||||
|
double error = stateN0 / stateN ;
|
||||||
|
errors_[ 2 ] = error ;
|
||||||
|
|
||||||
|
prevDt_ = dt;
|
||||||
|
prevIterations_ = iterations;
|
||||||
|
|
||||||
|
if( error > tol_ )
|
||||||
|
{
|
||||||
|
// adjust dt by given tolerance
|
||||||
|
std::cout << "Computed step size (tol): " << (dt * tol_ / error ) << std::endl;
|
||||||
|
return (dt * tol_ / error );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const double kP = 0.075 ;
|
||||||
|
const double kI = 0.175 ;
|
||||||
|
const double kD = 0.01 ;
|
||||||
|
double newDt = (dt * std::pow( errors_[ 1 ] / errors_[ 2 ], kP ) *
|
||||||
|
std::pow( tol_ / errors_[ 2 ], kI ) *
|
||||||
|
std::pow( (errors_[0]*errors_[0]/errors_[ 1 ]*errors_[ 2 ]), kD ));
|
||||||
|
std::cout << "Computed step size (pow): " << newDt << std::endl;
|
||||||
|
return newDt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // end namespace OPM
|
} // end namespace OPM
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user