AdaptiveTimeStepping: move controller creation to translation unit

This commit is contained in:
Arne Morten Kvarving
2025-01-03 09:12:51 +01:00
parent c25a7480cd
commit ca9ea2ccf1
3 changed files with 105 additions and 74 deletions

View File

@@ -138,5 +138,101 @@ void registerAdaptiveParameters()
"can be reduced to based on newton iteration counts");
}
std::tuple<TimeStepControlType, std::unique_ptr<TimeStepControlInterface>, bool>
createController(const UnitSystem& unitSystem)
{
const double tol = Parameters::Get<Parameters::TimeStepControlTolerance>(); // 1e-1
using RetVal = std::tuple<TimeStepControlType, std::unique_ptr<TimeStepControlInterface>, bool>;
using Func = std::function<RetVal()>;
const auto creators = std::unordered_map<std::string, Func> {
{"pid",
[tol]() {
return RetVal{
TimeStepControlType::PID,
std::make_unique<PIDTimeStepControl>(tol),
false
};
}},
{"pid+iteration",
[tol]() {
const int iterations = Parameters::Get<Parameters::TimeStepControlTargetIterations>(); // 30
const double decayDampingFactor = Parameters::Get<Parameters::TimeStepControlDecayDampingFactor>(); // 1.0
const double growthDampingFactor = Parameters::Get<Parameters::TimeStepControlGrowthDampingFactor>(); // 3.2
return RetVal{
TimeStepControlType::PIDAndIterationCount,
std::make_unique<PIDAndIterationCountTimeStepControl>(iterations,
decayDampingFactor,
growthDampingFactor,
tol),
false
};
}},
{"pid+newtoniteration",
[tol, &unitSystem]() {
const int iterations = Parameters::Get<Parameters::TimeStepControlTargetNewtonIterations>(); // 8
const double decayDampingFactor = Parameters::Get<Parameters::TimeStepControlDecayDampingFactor>(); // 1.0
const double growthDampingFactor = Parameters::Get<Parameters::TimeStepControlGrowthDampingFactor>(); // 3.2
const double nonDimensionalMinTimeStepIterations = Parameters::Get<Parameters::MinTimeStepBasedOnNewtonIterations>(); // 0.0 by default
// the min time step can be reduced by the newton iteration numbers
double minTimeStepReducedByIterations = unitSystem.to_si(UnitSystem::measure::time,
nonDimensionalMinTimeStepIterations);
return RetVal{
TimeStepControlType::PIDAndIterationCount,
std::make_unique<PIDAndIterationCountTimeStepControl>(iterations,
decayDampingFactor,
growthDampingFactor,
tol,
minTimeStepReducedByIterations),
true
};
}},
{"iterationcount",
[]() {
const int iterations = Parameters::Get<Parameters::TimeStepControlTargetIterations>(); // 30
const double decayrate = Parameters::Get<Parameters::TimeStepControlDecayRate>(); // 0.75
const double growthrate = Parameters::Get<Parameters::TimeStepControlGrowthRate>(); // 1.25
return RetVal{
TimeStepControlType::SimpleIterationCount,
std::make_unique<SimpleIterationCountTimeStepControl>(iterations,
decayrate,
growthrate),
false
};
}},
{"newtoniterationcount",
[]() {
const int iterations = Parameters::Get<Parameters::TimeStepControlTargetNewtonIterations>(); // 8
const double decayrate = Parameters::Get<Parameters::TimeStepControlDecayRate>(); // 0.75
const double growthrate = Parameters::Get<Parameters::TimeStepControlGrowthRate>(); // 1.25
return RetVal{
TimeStepControlType::SimpleIterationCount,
std::make_unique<SimpleIterationCountTimeStepControl>(iterations,
decayrate,
growthrate),
true
};
}},
{"hardcoded",
[]() {
const std::string filename = Parameters::Get<Parameters::TimeStepControlFileName>(); // "timesteps"
return RetVal{
TimeStepControlType::HardCodedTimeStep,
std::make_unique<HardcodedTimeStepControl>(filename),
false
};
}},
};
const std::string control = Parameters::Get<Parameters::TimeStepControl>(); // "pid"
const auto it = creators.find(control);
if (it == creators.end()) {
OPM_THROW(std::runtime_error,
"Unsupported time step control selected " + control);
}
// invoke creator
return it->second();
}
} // namespace detail
} // namespace Opm

View File

@@ -25,6 +25,7 @@
#include <memory>
#include <set>
#include <string>
#include <tuple>
#include <vector>
namespace Opm::Parameters {
@@ -62,6 +63,11 @@ std::set<std::string> consistentlyFailingWells(const std::vector<StepReport>& sr
void registerAdaptiveParameters();
std::tuple<TimeStepControlType,
std::unique_ptr<TimeStepControlInterface>,
bool>
createController(const UnitSystem& unitSystem);
}
// AdaptiveTimeStepping

View File

@@ -544,86 +544,15 @@ template<class TypeTag>
void AdaptiveTimeStepping<TypeTag>::
init_(const UnitSystem& unitSystem)
{
const double tol = Parameters::Get<Parameters::TimeStepControlTolerance>(); // 1e-1
using VoidFunc = std::function<void()>;
const auto creators = std::unordered_map<std::string,VoidFunc> {
{"pid",
[this, tol]() {
timeStepControl_ = std::make_unique<PIDTimeStepControl>(tol);
timeStepControlType_ = TimeStepControlType::PID;
}},
{"pid+iteration",
[this, tol]() {
const int iterations = Parameters::Get<Parameters::TimeStepControlTargetIterations>(); // 30
const double decayDampingFactor = Parameters::Get<Parameters::TimeStepControlDecayDampingFactor>(); // 1.0
const double growthDampingFactor = Parameters::Get<Parameters::TimeStepControlGrowthDampingFactor>(); // 3.2
timeStepControl_ = std::make_unique<PIDAndIterationCountTimeStepControl>(iterations,
decayDampingFactor,
growthDampingFactor,
tol);
timeStepControlType_ = TimeStepControlType::PIDAndIterationCount;
}},
{"pid+newtoniteration",
[this, tol, &unitSystem]() {
const int iterations = Parameters::Get<Parameters::TimeStepControlTargetNewtonIterations>(); // 8
const double decayDampingFactor = Parameters::Get<Parameters::TimeStepControlDecayDampingFactor>(); // 1.0
const double growthDampingFactor = Parameters::Get<Parameters::TimeStepControlGrowthDampingFactor>(); // 3.2
const double nonDimensionalMinTimeStepIterations = Parameters::Get<Parameters::MinTimeStepBasedOnNewtonIterations>(); // 0.0 by default
// the min time step can be reduced by the newton iteration numbers
double minTimeStepReducedByIterations = unitSystem.to_si(UnitSystem::measure::time,
nonDimensionalMinTimeStepIterations);
timeStepControl_ = std::make_unique<PIDAndIterationCountTimeStepControl>(iterations,
decayDampingFactor,
growthDampingFactor,
tol,
minTimeStepReducedByIterations);
timeStepControlType_ = TimeStepControlType::PIDAndIterationCount;
useNewtonIteration_ = true;
}},
{"iterationcount",
[this]() {
const int iterations = Parameters::Get<Parameters::TimeStepControlTargetIterations>(); // 30
const double decayrate = Parameters::Get<Parameters::TimeStepControlDecayRate>(); // 0.75
const double growthrate = Parameters::Get<Parameters::TimeStepControlGrowthRate>(); // 1.25
timeStepControl_ = std::make_unique<SimpleIterationCountTimeStepControl>(iterations,
decayrate,
growthrate);
timeStepControlType_ = TimeStepControlType::SimpleIterationCount;
}},
{"newtoniterationcount",
[this]() {
const int iterations = Parameters::Get<Parameters::TimeStepControlTargetNewtonIterations>(); // 8
const double decayrate = Parameters::Get<Parameters::TimeStepControlDecayRate>(); // 0.75
const double growthrate = Parameters::Get<Parameters::TimeStepControlGrowthRate>(); // 1.25
timeStepControl_ = std::make_unique<SimpleIterationCountTimeStepControl>(iterations,
decayrate,
growthrate);
useNewtonIteration_ = true;
timeStepControlType_ = TimeStepControlType::SimpleIterationCount;
}},
{"hardcoded",
[this]() {
const std::string filename = Parameters::Get<Parameters::TimeStepControlFileName>(); // "timesteps"
timeStepControl_ = std::make_unique<HardcodedTimeStepControl>(filename);
timeStepControlType_ = TimeStepControlType::HardCodedTimeStep;
}},
};
std::tie(timeStepControlType_,
timeStepControl_,
useNewtonIteration_) = detail::createController(unitSystem);
// make sure growth factor is something reasonable
if (growthFactor_ < 1.0) {
OPM_THROW(std::runtime_error,
"Growth factor cannot be less than 1.");
}
const std::string control = Parameters::Get<Parameters::TimeStepControl>(); // "pid"
const auto it = creators.find(control);
if (it == creators.end()) {
OPM_THROW(std::runtime_error,
"Unsupported time step control selected " + control);
}
// invoke creator
it->second();
}
} // namespace Opm