mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
AdaptiveTimeSteppingEbos: add serialization support
This commit is contained in:
@@ -286,6 +286,8 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
AdaptiveTimeSteppingEbos() = default;
|
||||||
|
|
||||||
//! \brief contructor taking parameter object
|
//! \brief contructor taking parameter object
|
||||||
AdaptiveTimeSteppingEbos(const UnitSystem& unitSystem,
|
AdaptiveTimeSteppingEbos(const UnitSystem& unitSystem,
|
||||||
const bool terminalOutput = true)
|
const bool terminalOutput = true)
|
||||||
@@ -676,6 +678,140 @@ namespace Opm {
|
|||||||
timestepAfterEvent_ = tuning.TMAXWC;
|
timestepAfterEvent_ = tuning.TMAXWC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
result.fullTimestepInitially_ = 8.0;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void init_(const UnitSystem& unitSystem)
|
void init_(const UnitSystem& unitSystem)
|
||||||
@@ -685,13 +821,15 @@ namespace Opm {
|
|||||||
|
|
||||||
const double tol = EWOMS_GET_PARAM(TypeTag, double, TimeStepControlTolerance); // 1e-1
|
const double tol = EWOMS_GET_PARAM(TypeTag, double, TimeStepControlTolerance); // 1e-1
|
||||||
if (control == "pid") {
|
if (control == "pid") {
|
||||||
timeStepControl_ = TimeStepControlType(new PIDTimeStepControl(tol));
|
timeStepControl_ = std::make_unique<PIDTimeStepControl>(tol);
|
||||||
|
timeStepControlType_ = TimeStepControlType::PID;
|
||||||
}
|
}
|
||||||
else if (control == "pid+iteration") {
|
else if (control == "pid+iteration") {
|
||||||
const int iterations = EWOMS_GET_PARAM(TypeTag, int, TimeStepControlTargetIterations); // 30
|
const int iterations = EWOMS_GET_PARAM(TypeTag, int, TimeStepControlTargetIterations); // 30
|
||||||
const double decayDampingFactor = EWOMS_GET_PARAM(TypeTag, double, TimeStepControlDecayDampingFactor); // 1.0
|
const double decayDampingFactor = EWOMS_GET_PARAM(TypeTag, double, TimeStepControlDecayDampingFactor); // 1.0
|
||||||
const double growthDampingFactor = EWOMS_GET_PARAM(TypeTag, double, TimeStepControlGrowthDampingFactor); // 3.2
|
const double growthDampingFactor = EWOMS_GET_PARAM(TypeTag, double, TimeStepControlGrowthDampingFactor); // 3.2
|
||||||
timeStepControl_ = TimeStepControlType(new PIDAndIterationCountTimeStepControl(iterations, decayDampingFactor, growthDampingFactor, tol));
|
timeStepControl_ = std::make_unique<PIDAndIterationCountTimeStepControl>(iterations, decayDampingFactor, growthDampingFactor, tol);
|
||||||
|
timeStepControlType_ = TimeStepControlType::PIDAndIterationCount;
|
||||||
}
|
}
|
||||||
else if (control == "pid+newtoniteration") {
|
else if (control == "pid+newtoniteration") {
|
||||||
const int iterations = EWOMS_GET_PARAM(TypeTag, int, TimeStepControlTargetNewtonIterations); // 8
|
const int iterations = EWOMS_GET_PARAM(TypeTag, int, TimeStepControlTargetNewtonIterations); // 8
|
||||||
@@ -700,27 +838,30 @@ namespace Opm {
|
|||||||
const double nonDimensionalMinTimeStepIterations = EWOMS_GET_PARAM(TypeTag, double, MinTimeStepBasedOnNewtonIterations); // 0.0 by default
|
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
|
// the min time step can be reduced by the newton iteration numbers
|
||||||
double minTimeStepReducedByIterations = unitSystem.to_si(UnitSystem::measure::time, nonDimensionalMinTimeStepIterations);
|
double minTimeStepReducedByIterations = unitSystem.to_si(UnitSystem::measure::time, nonDimensionalMinTimeStepIterations);
|
||||||
timeStepControl_ = TimeStepControlType(new PIDAndIterationCountTimeStepControl(iterations, decayDampingFactor,
|
timeStepControl_ = std::make_unique<PIDAndIterationCountTimeStepControl>(iterations, decayDampingFactor,
|
||||||
growthDampingFactor, tol, minTimeStepReducedByIterations));
|
growthDampingFactor, tol, minTimeStepReducedByIterations);
|
||||||
|
timeStepControlType_ = TimeStepControlType::PIDAndIterationCount;
|
||||||
useNewtonIteration_ = true;
|
useNewtonIteration_ = true;
|
||||||
}
|
}
|
||||||
else if (control == "iterationcount") {
|
else if (control == "iterationcount") {
|
||||||
const int iterations = EWOMS_GET_PARAM(TypeTag, int, TimeStepControlTargetIterations); // 30
|
const int iterations = EWOMS_GET_PARAM(TypeTag, int, TimeStepControlTargetIterations); // 30
|
||||||
const double decayrate = EWOMS_GET_PARAM(TypeTag, double, TimeStepControlDecayRate); // 0.75
|
const double decayrate = EWOMS_GET_PARAM(TypeTag, double, TimeStepControlDecayRate); // 0.75
|
||||||
const double growthrate = EWOMS_GET_PARAM(TypeTag, double, TimeStepControlGrowthRate); // 1.25
|
const double growthrate = EWOMS_GET_PARAM(TypeTag, double, TimeStepControlGrowthRate); // 1.25
|
||||||
timeStepControl_ = TimeStepControlType(new SimpleIterationCountTimeStepControl(iterations, decayrate, growthrate));
|
timeStepControl_ = std::make_unique<SimpleIterationCountTimeStepControl>(iterations, decayrate, growthrate);
|
||||||
|
timeStepControlType_ = TimeStepControlType::SimpleIterationCount;
|
||||||
}
|
}
|
||||||
else if (control == "newtoniterationcount") {
|
else if (control == "newtoniterationcount") {
|
||||||
const int iterations = EWOMS_GET_PARAM(TypeTag, int, TimeStepControlTargetNewtonIterations); // 8
|
const int iterations = EWOMS_GET_PARAM(TypeTag, int, TimeStepControlTargetNewtonIterations); // 8
|
||||||
const double decayrate = EWOMS_GET_PARAM(TypeTag, double, TimeStepControlDecayRate); // 0.75
|
const double decayrate = EWOMS_GET_PARAM(TypeTag, double, TimeStepControlDecayRate); // 0.75
|
||||||
const double growthrate = EWOMS_GET_PARAM(TypeTag, double, TimeStepControlGrowthRate); // 1.25
|
const double growthrate = EWOMS_GET_PARAM(TypeTag, double, TimeStepControlGrowthRate); // 1.25
|
||||||
timeStepControl_ = TimeStepControlType(new SimpleIterationCountTimeStepControl(iterations, decayrate, growthrate));
|
timeStepControl_ = std::make_unique<SimpleIterationCountTimeStepControl>(iterations, decayrate, growthrate);
|
||||||
useNewtonIteration_ = true;
|
useNewtonIteration_ = true;
|
||||||
|
timeStepControlType_ = TimeStepControlType::SimpleIterationCount;
|
||||||
}
|
}
|
||||||
else if (control == "hardcoded") {
|
else if (control == "hardcoded") {
|
||||||
const std::string filename = EWOMS_GET_PARAM(TypeTag, std::string, TimeStepControlFileName); // "timesteps"
|
const std::string filename = EWOMS_GET_PARAM(TypeTag, std::string, TimeStepControlFileName); // "timesteps"
|
||||||
timeStepControl_ = TimeStepControlType(new HardcodedTimeStepControl(filename));
|
timeStepControl_ = std::make_unique<HardcodedTimeStepControl>(filename);
|
||||||
|
timeStepControlType_ = TimeStepControlType::HardCodedTimeStep;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
OPM_THROW(std::runtime_error,
|
OPM_THROW(std::runtime_error,
|
||||||
@@ -782,9 +923,10 @@ namespace Opm {
|
|||||||
return failing_wells;
|
return failing_wells;
|
||||||
}
|
}
|
||||||
|
|
||||||
using TimeStepControlType = std::unique_ptr<TimeStepControlInterface>;
|
using TimeStepController = std::unique_ptr<TimeStepControlInterface>;
|
||||||
|
|
||||||
TimeStepControlType timeStepControl_; //!< time step control object
|
TimeStepControlType timeStepControlType_; //!< 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 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 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 maxGrowth_; //!< factor that limits the maximum growth of a time step
|
||||||
|
|||||||
@@ -21,12 +21,20 @@
|
|||||||
#ifndef OPM_TIMESTEPCONTROL_HEADER_INCLUDED
|
#ifndef OPM_TIMESTEPCONTROL_HEADER_INCLUDED
|
||||||
#define OPM_TIMESTEPCONTROL_HEADER_INCLUDED
|
#define OPM_TIMESTEPCONTROL_HEADER_INCLUDED
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <opm/simulators/timestepping/TimeStepControlInterface.hpp>
|
#include <opm/simulators/timestepping/TimeStepControlInterface.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Opm
|
namespace Opm
|
||||||
{
|
{
|
||||||
|
enum class TimeStepControlType {
|
||||||
|
SimpleIterationCount,
|
||||||
|
PID,
|
||||||
|
PIDAndIterationCount,
|
||||||
|
HardCodedTimeStep
|
||||||
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
///
|
///
|
||||||
/// A simple iteration count based adaptive time step control.
|
/// A simple iteration count based adaptive time step control.
|
||||||
@@ -35,6 +43,7 @@ namespace Opm
|
|||||||
class SimpleIterationCountTimeStepControl : public TimeStepControlInterface
|
class SimpleIterationCountTimeStepControl : public TimeStepControlInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static constexpr TimeStepControlType Type = TimeStepControlType::SimpleIterationCount;
|
||||||
SimpleIterationCountTimeStepControl() = default;
|
SimpleIterationCountTimeStepControl() = default;
|
||||||
|
|
||||||
/// \brief constructor
|
/// \brief constructor
|
||||||
@@ -87,6 +96,7 @@ namespace Opm
|
|||||||
class PIDTimeStepControl : public TimeStepControlInterface
|
class PIDTimeStepControl : public TimeStepControlInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static constexpr TimeStepControlType Type = TimeStepControlType::PID;
|
||||||
/// \brief constructor
|
/// \brief constructor
|
||||||
/// \param tol tolerance for the relative changes of the numerical solution to be accepted
|
/// \param tol tolerance for the relative changes of the numerical solution to be accepted
|
||||||
/// in one time step (default is 1e-3)
|
/// in one time step (default is 1e-3)
|
||||||
@@ -126,6 +136,8 @@ namespace Opm
|
|||||||
{
|
{
|
||||||
typedef PIDTimeStepControl BaseType;
|
typedef PIDTimeStepControl BaseType;
|
||||||
public:
|
public:
|
||||||
|
static constexpr TimeStepControlType Type = TimeStepControlType::PIDAndIterationCount;
|
||||||
|
|
||||||
/// \brief constructor
|
/// \brief constructor
|
||||||
/// \param target_iterations number of desired iterations per time step
|
/// \param target_iterations number of desired iterations per time step
|
||||||
/// \param tol tolerance for the relative changes of the numerical solution to be accepted
|
/// \param tol tolerance for the relative changes of the numerical solution to be accepted
|
||||||
@@ -174,6 +186,7 @@ namespace Opm
|
|||||||
class HardcodedTimeStepControl : public TimeStepControlInterface
|
class HardcodedTimeStepControl : public TimeStepControlInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static constexpr TimeStepControlType Type = TimeStepControlType::HardCodedTimeStep;
|
||||||
HardcodedTimeStepControl() = default;
|
HardcodedTimeStepControl() = default;
|
||||||
|
|
||||||
/// \brief constructor
|
/// \brief constructor
|
||||||
|
|||||||
@@ -19,8 +19,11 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <ebos/ebos.hh>
|
||||||
|
|
||||||
#include <opm/common/utility/Serializer.hpp>
|
#include <opm/common/utility/Serializer.hpp>
|
||||||
|
|
||||||
|
#include <opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp>
|
||||||
#include <opm/simulators/timestepping/SimulatorTimer.hpp>
|
#include <opm/simulators/timestepping/SimulatorTimer.hpp>
|
||||||
#include <opm/simulators/timestepping/TimeStepControl.hpp>
|
#include <opm/simulators/timestepping/TimeStepControl.hpp>
|
||||||
#include <opm/simulators/utils/SerializationPackers.hpp>
|
#include <opm/simulators/utils/SerializationPackers.hpp>
|
||||||
@@ -42,7 +45,7 @@ std::tuple<T,int,int> PackUnpack(T& in)
|
|||||||
ser.unpack(out);
|
ser.unpack(out);
|
||||||
size_t pos2 = ser.position();
|
size_t pos2 = ser.position();
|
||||||
|
|
||||||
return std::make_tuple(out, pos1, pos2);
|
return std::make_tuple(std::move(out), pos1, pos2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TEST_FOR_TYPE_NAMED_OBJ(TYPE, NAME, OBJ) \
|
#define TEST_FOR_TYPE_NAMED_OBJ(TYPE, NAME, OBJ) \
|
||||||
@@ -66,6 +69,12 @@ TEST_FOR_TYPE(PIDTimeStepControl)
|
|||||||
TEST_FOR_TYPE(SimpleIterationCountTimeStepControl)
|
TEST_FOR_TYPE(SimpleIterationCountTimeStepControl)
|
||||||
TEST_FOR_TYPE(SimulatorTimer)
|
TEST_FOR_TYPE(SimulatorTimer)
|
||||||
|
|
||||||
|
namespace Opm { using ATE = AdaptiveTimeSteppingEbos<Opm::Properties::TTag::EbosTypeTag>; }
|
||||||
|
TEST_FOR_TYPE_NAMED_OBJ(ATE, AdaptiveTimeSteppingEbosHardcoded, serializationTestObjectHardcoded)
|
||||||
|
TEST_FOR_TYPE_NAMED_OBJ(ATE, AdaptiveTimeSteppingEbosPID, serializationTestObjectPID)
|
||||||
|
TEST_FOR_TYPE_NAMED_OBJ(ATE, AdaptiveTimeSteppingEbosPIDIt, serializationTestObjectPIDIt)
|
||||||
|
TEST_FOR_TYPE_NAMED_OBJ(ATE, AdaptiveTimeSteppingEbosSimple, serializationTestObjectSimple)
|
||||||
|
|
||||||
bool init_unit_test_func()
|
bool init_unit_test_func()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user