272 template <
class Solver>
275 const Solver& solver_;
277 SolutionTimeErrorSolverWrapperEbos(
const Solver&
solver)
282 double relativeChange()
const
283 {
return solver_.model().relativeChange(); }
291 message =
"Caught Exception: ";
293 OpmLog::debug(message);
317 , minTimeStepBeforeShuttingProblematicWells_(
EWOMS_GET_PARAM(TypeTag,
double, MinTimeStepBeforeShuttingProblematicWellsInDays)*
unit::
day)
346 , minTimeStepBeforeShuttingProblematicWells_(
EWOMS_GET_PARAM(TypeTag,
double, MinTimeStepBeforeShuttingProblematicWellsInDays)*
unit::
day)
351 static void registerParameters()
355 "The factor time steps are elongated after restarts");
357 "The factor time steps are elongated after a successful substep");
359 "The maximum factor time steps are elongated after a report step");
361 "The maximum size of a time step in days");
363 "The minimum size of a time step in days for field and metric and hours for lab. If a step cannot converge without getting cut below this step size the simulator will stop");
365 "Continue instead of stop when minimum solver time step is reached");
367 "The maximum number of breakdowns before a substep is given up and the simulator is terminated");
369 "Specify the \"chattiness\" of the non-linear solver itself");
371 "Specify the \"chattiness\" during the time integration");
373 "The size of the initial time step in days");
375 "Always attempt to finish a report step using a single substep");
377 "Time step size of the first time step after an event occurs during the simulation in days");
379 "The algorithm used to determine time-step sizes. valid options are: 'pid' (default), 'pid+iteration', 'pid+newtoniteration', 'iterationcount', 'newtoniterationcount' and 'hardcoded'");
381 "The tolerance used by the time step size control algorithm");
383 "The number of linear iterations which the time step control scheme should aim for (if applicable)");
385 "The number of Newton iterations which the time step control scheme should aim for (if applicable)");
387 "The decay rate of the time step size of the number of target iterations is exceeded");
389 "The growth rate of the time step size of the number of target iterations is undercut");
391 "The decay rate of the time step decrease when the target iterations is exceeded");
393 "The growth rate of the time step increase when the target iterations is undercut");
395 "The name of the file which contains the hardcoded time steps sizes");
397 "The minimum time step size in days for which problematic wells are not shut");
399 "The minimum time step size (in days for field and metric unit and hours for lab unit) can be reduced to based on newton iteration counts");
405 template <
class Solver>
409 const std::vector<int>*
fipnum =
nullptr)
428 auto& ebosSimulator =
solver.model().ebosSimulator();
451 OpmLog::debug(
"Overall linear iterations used: " + std::to_string(
substepReport.total_linear_iterations));
456 causeOfFailure =
"Solver convergence failure - Iteration limit reached";
470 causeOfFailure =
"Solver convergence failure - Numerical problem encountered";
475 catch (
const std::runtime_error&
e) {
481 catch (
const Dune::ISTLError&
e) {
487 catch (
const Dune::MatrixBlockError&
e) {
502 const auto msg = std::string(
"Solver failed to converge but timestep ")
503 + std::to_string(
dt) +
" is smaller or equal to "
504 + std::to_string(
minTimeStep_) +
"\n which is the minimum threshold given"
505 +
"by option --solver-min-time-step= \n";
538 if (
solver.model().wellModel().hasTHPConstraints()) {
544 std::ostringstream
ss;
546 OpmLog::info(
ss.str());
562 report.success.output_write_time +=
perfTimer.secsSinceStart();
578 const auto msg = std::string(
"Solver failed to converge after cutting timestep ")
579 + std::to_string(
restarts) +
" times.";
593 const auto msg = std::string(
"Solver failed to converge after cutting timestep to ")
594 + std::to_string(
minTimeStep_) +
"\n which is the minimum threshold given"
595 +
"by option --solver-min-time-step= \n";
608 + std::to_string(unit::convert::to(
substepTimer.currentStepLength(), unit::day)) +
" days\n";
609 OpmLog::problem(
msg);
620 std::set<std::string>
failing_wells = detail::consistentlyFailingWells(
solver.model().stepReports());
641 msg =
"\nProblematic well(s) were shut: ";
646 msg +=
"(retrying timestep)\n";
647 OpmLog::problem(
msg);
659 std::ostringstream
ss;
661 ss <<
"Suggested next step size = " << unit::convert::to(
suggestedNextTimestep_, unit::day) <<
" (days)" << std::endl;
662 OpmLog::debug(
ss.str());
677 void setSuggestedNextStep(
const double x)
680 void updateTUNING(
double max_next_tstep,
const Tuning& tuning)
690 template<
class Serializer>
691 void serializeOp(Serializer& serializer)
695 case TimeStepControlType::HardCodedTimeStep:
696 allocAndSerialize<HardcodedTimeStepControl>(serializer);
698 case TimeStepControlType::PIDAndIterationCount:
699 allocAndSerialize<PIDAndIterationCountTimeStepControl>(serializer);
701 case TimeStepControlType::SimpleIterationCount:
702 allocAndSerialize<SimpleIterationCountTimeStepControl>(serializer);
704 case TimeStepControlType::PID:
705 allocAndSerialize<PIDTimeStepControl>(serializer);
721 serializer(minTimeStepBeforeShuttingProblematicWells_);
724 static AdaptiveTimeSteppingEbos<TypeTag> serializationTestObjectHardcoded()
726 return serializationTestObject_<HardcodedTimeStepControl>();
729 static AdaptiveTimeSteppingEbos<TypeTag> serializationTestObjectPID()
731 return serializationTestObject_<PIDTimeStepControl>();
734 static AdaptiveTimeSteppingEbos<TypeTag> serializationTestObjectPIDIt()
736 return serializationTestObject_<PIDAndIterationCountTimeStepControl>();
739 static AdaptiveTimeSteppingEbos<TypeTag> serializationTestObjectSimple()
741 return serializationTestObject_<SimpleIterationCountTimeStepControl>();
744 bool operator==(
const AdaptiveTimeSteppingEbos<TypeTag>& rhs)
754 case TimeStepControlType::HardCodedTimeStep:
755 result = castAndComp<HardcodedTimeStepControl>(rhs);
757 case TimeStepControlType::PIDAndIterationCount:
758 result = castAndComp<PIDAndIterationCountTimeStepControl>(rhs);
760 case TimeStepControlType::SimpleIterationCount:
761 result = castAndComp<SimpleIterationCountTimeStepControl>(rhs);
763 case TimeStepControlType::PID:
764 result = castAndComp<PIDTimeStepControl>(rhs);
780 this->minTimeStepBeforeShuttingProblematicWells_ ==
781 rhs.minTimeStepBeforeShuttingProblematicWells_;
785 template<
class Controller>
786 static AdaptiveTimeSteppingEbos<TypeTag> serializationTestObject_()
788 AdaptiveTimeSteppingEbos<TypeTag> result;
790 result.restartFactor_ = 1.0;
791 result.growthFactor_ = 2.0;
792 result.maxGrowth_ = 3.0;
793 result.maxTimeStep_ = 4.0;
794 result.minTimeStep_ = 5.0;
795 result.ignoreConvergenceFailure_ =
true;
796 result.solverRestartMax_ = 6;
797 result.solverVerbose_ =
true;
798 result.timestepVerbose_ =
true;
799 result.suggestedNextTimestep_ = 7.0;
800 result.fullTimestepInitially_ =
true;
801 result.useNewtonIteration_ =
true;
802 result.minTimeStepBeforeShuttingProblematicWells_ = 9.0;
803 result.timeStepControlType_ = Controller::Type;
804 result.timeStepControl_ = std::make_unique<Controller>(Controller::serializationTestObject());
808 template<
class T,
class Serializer>
809 void allocAndSerialize(Serializer& serializer)
811 if (!serializer.isSerializing()) {
818 bool castAndComp(
const AdaptiveTimeSteppingEbos<TypeTag>& Rhs)
const
821 const T* rhs =
static_cast<const T*
>(Rhs.timeStepControl_.get());
826 void init_(
const UnitSystem& unitSystem)
829 std::string control = EWOMS_GET_PARAM(TypeTag, std::string, TimeStepControl);
831 const double tol = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlTolerance);
832 if (control ==
"pid") {
836 else if (control ==
"pid+iteration") {
837 const int iterations = EWOMS_GET_PARAM(TypeTag,
int, TimeStepControlTargetIterations);
838 const double decayDampingFactor = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlDecayDampingFactor);
839 const double growthDampingFactor = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlGrowthDampingFactor);
840 timeStepControl_ = std::make_unique<PIDAndIterationCountTimeStepControl>(iterations, decayDampingFactor, growthDampingFactor, tol);
843 else if (control ==
"pid+newtoniteration") {
844 const int iterations = EWOMS_GET_PARAM(TypeTag,
int, TimeStepControlTargetNewtonIterations);
845 const double decayDampingFactor = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlDecayDampingFactor);
846 const double growthDampingFactor = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlGrowthDampingFactor);
847 const double nonDimensionalMinTimeStepIterations = EWOMS_GET_PARAM(TypeTag,
double, MinTimeStepBasedOnNewtonIterations);
849 double minTimeStepReducedByIterations = unitSystem.to_si(UnitSystem::measure::time, nonDimensionalMinTimeStepIterations);
850 timeStepControl_ = std::make_unique<PIDAndIterationCountTimeStepControl>(iterations, decayDampingFactor,
851 growthDampingFactor, tol, minTimeStepReducedByIterations);
855 else if (control ==
"iterationcount") {
856 const int iterations = EWOMS_GET_PARAM(TypeTag,
int, TimeStepControlTargetIterations);
857 const double decayrate = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlDecayRate);
858 const double growthrate = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlGrowthRate);
859 timeStepControl_ = std::make_unique<SimpleIterationCountTimeStepControl>(iterations, decayrate, growthrate);
862 else if (control ==
"newtoniterationcount") {
863 const int iterations = EWOMS_GET_PARAM(TypeTag,
int, TimeStepControlTargetNewtonIterations);
864 const double decayrate = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlDecayRate);
865 const double growthrate = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlGrowthRate);
866 timeStepControl_ = std::make_unique<SimpleIterationCountTimeStepControl>(iterations, decayrate, growthrate);
870 else if (control ==
"hardcoded") {
871 const std::string filename = EWOMS_GET_PARAM(TypeTag, std::string, TimeStepControlFileName);
876 OPM_THROW(std::runtime_error,
877 "Unsupported time step control selected " + control);
883 using TimeStepController = std::unique_ptr<TimeStepControlInterface>;
900 double minTimeStepBeforeShuttingProblematicWells_;