222 template <
class Solver>
225 const Solver& solver_;
227 SolutionTimeErrorSolverWrapperEbos(
const Solver&
solver)
232 double relativeChange()
const
233 {
return solver_.model().relativeChange(); }
241 message =
"Caught Exception: ";
243 OpmLog::debug(message);
267 , minTimeStepBeforeShuttingProblematicWells_(
EWOMS_GET_PARAM(TypeTag,
double, MinTimeStepBeforeShuttingProblematicWellsInDays)*
unit::
day)
296 , minTimeStepBeforeShuttingProblematicWells_(
EWOMS_GET_PARAM(TypeTag,
double, MinTimeStepBeforeShuttingProblematicWellsInDays)*
unit::
day)
301 static void registerParameters()
306 "Continue instead of stop when minimum solver time step is reached");
308 "The maximum number of breakdowns before a substep is given up and the simulator is terminated");
310 "Specify the \"chattiness\" of the non-linear solver itself");
312 "Specify the \"chattiness\" during the time integration");
314 "The size of the initial time step in days");
316 "Always attempt to finish a report step using a single substep");
318 "The algorithm used to determine time-step sizes. valid options are: 'pid' (default), 'pid+iteration', 'pid+newtoniteration', 'iterationcount', 'newtoniterationcount' and 'hardcoded'");
320 "The tolerance used by the time step size control algorithm");
322 "The number of linear iterations which the time step control scheme should aim for (if applicable)");
324 "The number of Newton iterations which the time step control scheme should aim for (if applicable)");
326 "The decay rate of the time step size of the number of target iterations is exceeded");
328 "The growth rate of the time step size of the number of target iterations is undercut");
330 "The decay rate of the time step decrease when the target iterations is exceeded");
332 "The growth rate of the time step increase when the target iterations is undercut");
334 "The name of the file which contains the hardcoded time steps sizes");
336 "The minimum time step size in days for which problematic wells are not shut");
338 "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");
344 template <
class Solver>
348 const std::vector<int>*
fipnum =
nullptr)
367 auto& ebosSimulator =
solver.model().ebosSimulator();
391 OpmLog::debug(
"Overall linear iterations used: " + std::to_string(
substepReport.total_linear_iterations));
396 causeOfFailure =
"Solver convergence failure - Iteration limit reached";
410 causeOfFailure =
"Solver convergence failure - Numerical problem encountered";
415 catch (
const std::runtime_error&
e) {
421 catch (
const Dune::ISTLError&
e) {
427 catch (
const Dune::MatrixBlockError&
e) {
442 const auto msg = std::string(
"Solver failed to converge but timestep ")
443 + std::to_string(
dt) +
" is smaller or equal to "
444 + std::to_string(
minTimeStep_) +
"\n which is the minimum threshold given"
445 +
"by option --solver-min-time-step= \n";
478 if (
solver.model().wellModel().hasTHPConstraints()) {
484 std::ostringstream
ss;
486 OpmLog::info(
ss.str());
502 report.success.output_write_time +=
perfTimer.secsSinceStart();
518 const auto msg = std::string(
"Solver failed to converge after cutting timestep ")
519 + std::to_string(
restarts) +
" times.";
534 const auto msg = std::string(
"Solver failed to converge after cutting timestep to ")
535 + std::to_string(
minTimeStep_) +
"\n which is the minimum threshold given"
536 +
"by option --solver-min-time-step= \n";
550 + std::to_string(unit::convert::to(
substepTimer.currentStepLength(), unit::day)) +
" days\n";
551 OpmLog::problem(
msg);
562 std::set<std::string>
failing_wells = detail::consistentlyFailingWells(
solver.model().stepReports());
583 msg =
"\nProblematic well(s) were shut: ";
588 msg +=
"(retrying timestep)\n";
589 OpmLog::problem(
msg);
601 std::ostringstream
ss;
603 ss <<
"Suggested next step size = " << unit::convert::to(
suggestedNextTimestep_, unit::day) <<
" (days)" << std::endl;
604 OpmLog::debug(
ss.str());
619 void setSuggestedNextStep(
const double x)
622 void updateTUNING(
double max_next_tstep,
const Tuning& tuning)
629 if (max_next_tstep > 0) {
635 template<
class Serializer>
636 void serializeOp(Serializer& serializer)
640 case TimeStepControlType::HardCodedTimeStep:
641 allocAndSerialize<HardcodedTimeStepControl>(serializer);
643 case TimeStepControlType::PIDAndIterationCount:
644 allocAndSerialize<PIDAndIterationCountTimeStepControl>(serializer);
646 case TimeStepControlType::SimpleIterationCount:
647 allocAndSerialize<SimpleIterationCountTimeStepControl>(serializer);
649 case TimeStepControlType::PID:
650 allocAndSerialize<PIDTimeStepControl>(serializer);
666 serializer(minTimeStepBeforeShuttingProblematicWells_);
669 static AdaptiveTimeSteppingEbos<TypeTag> serializationTestObjectHardcoded()
671 return serializationTestObject_<HardcodedTimeStepControl>();
674 static AdaptiveTimeSteppingEbos<TypeTag> serializationTestObjectPID()
676 return serializationTestObject_<PIDTimeStepControl>();
679 static AdaptiveTimeSteppingEbos<TypeTag> serializationTestObjectPIDIt()
681 return serializationTestObject_<PIDAndIterationCountTimeStepControl>();
684 static AdaptiveTimeSteppingEbos<TypeTag> serializationTestObjectSimple()
686 return serializationTestObject_<SimpleIterationCountTimeStepControl>();
689 bool operator==(
const AdaptiveTimeSteppingEbos<TypeTag>& rhs)
699 case TimeStepControlType::HardCodedTimeStep:
700 result = castAndComp<HardcodedTimeStepControl>(rhs);
702 case TimeStepControlType::PIDAndIterationCount:
703 result = castAndComp<PIDAndIterationCountTimeStepControl>(rhs);
705 case TimeStepControlType::SimpleIterationCount:
706 result = castAndComp<SimpleIterationCountTimeStepControl>(rhs);
708 case TimeStepControlType::PID:
709 result = castAndComp<PIDTimeStepControl>(rhs);
725 this->minTimeStepBeforeShuttingProblematicWells_ ==
726 rhs.minTimeStepBeforeShuttingProblematicWells_;
730 template<
class Controller>
731 static AdaptiveTimeSteppingEbos<TypeTag> serializationTestObject_()
733 AdaptiveTimeSteppingEbos<TypeTag> result;
735 result.restartFactor_ = 1.0;
736 result.growthFactor_ = 2.0;
737 result.maxGrowth_ = 3.0;
738 result.maxTimeStep_ = 4.0;
739 result.minTimeStep_ = 5.0;
740 result.ignoreConvergenceFailure_ =
true;
741 result.solverRestartMax_ = 6;
742 result.solverVerbose_ =
true;
743 result.timestepVerbose_ =
true;
744 result.suggestedNextTimestep_ = 7.0;
745 result.fullTimestepInitially_ =
true;
746 result.useNewtonIteration_ =
true;
747 result.minTimeStepBeforeShuttingProblematicWells_ = 9.0;
748 result.timeStepControlType_ = Controller::Type;
749 result.timeStepControl_ = std::make_unique<Controller>(Controller::serializationTestObject());
753 template<
class T,
class Serializer>
754 void allocAndSerialize(Serializer& serializer)
756 if (!serializer.isSerializing()) {
763 bool castAndComp(
const AdaptiveTimeSteppingEbos<TypeTag>& Rhs)
const
766 const T* rhs =
static_cast<const T*
>(Rhs.timeStepControl_.get());
771 void init_(
const UnitSystem& unitSystem)
774 std::string control = EWOMS_GET_PARAM(TypeTag, std::string, TimeStepControl);
776 const double tol = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlTolerance);
777 if (control ==
"pid") {
781 else if (control ==
"pid+iteration") {
782 const int iterations = EWOMS_GET_PARAM(TypeTag,
int, TimeStepControlTargetIterations);
783 const double decayDampingFactor = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlDecayDampingFactor);
784 const double growthDampingFactor = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlGrowthDampingFactor);
785 timeStepControl_ = std::make_unique<PIDAndIterationCountTimeStepControl>(iterations, decayDampingFactor, growthDampingFactor, tol);
788 else if (control ==
"pid+newtoniteration") {
789 const int iterations = EWOMS_GET_PARAM(TypeTag,
int, TimeStepControlTargetNewtonIterations);
790 const double decayDampingFactor = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlDecayDampingFactor);
791 const double growthDampingFactor = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlGrowthDampingFactor);
792 const double nonDimensionalMinTimeStepIterations = EWOMS_GET_PARAM(TypeTag,
double, MinTimeStepBasedOnNewtonIterations);
794 double minTimeStepReducedByIterations = unitSystem.to_si(UnitSystem::measure::time, nonDimensionalMinTimeStepIterations);
795 timeStepControl_ = std::make_unique<PIDAndIterationCountTimeStepControl>(iterations, decayDampingFactor,
796 growthDampingFactor, tol, minTimeStepReducedByIterations);
800 else if (control ==
"iterationcount") {
801 const int iterations = EWOMS_GET_PARAM(TypeTag,
int, TimeStepControlTargetIterations);
802 const double decayrate = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlDecayRate);
803 const double growthrate = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlGrowthRate);
804 timeStepControl_ = std::make_unique<SimpleIterationCountTimeStepControl>(iterations, decayrate, growthrate);
807 else if (control ==
"newtoniterationcount") {
808 const int iterations = EWOMS_GET_PARAM(TypeTag,
int, TimeStepControlTargetNewtonIterations);
809 const double decayrate = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlDecayRate);
810 const double growthrate = EWOMS_GET_PARAM(TypeTag,
double, TimeStepControlGrowthRate);
811 timeStepControl_ = std::make_unique<SimpleIterationCountTimeStepControl>(iterations, decayrate, growthrate);
815 else if (control ==
"hardcoded") {
816 const std::string filename = EWOMS_GET_PARAM(TypeTag, std::string, TimeStepControlFileName);
821 OPM_THROW(std::runtime_error,
822 "Unsupported time step control selected " + control);
828 using TimeStepController = std::unique_ptr<TimeStepControlInterface>;
845 double minTimeStepBeforeShuttingProblematicWells_;