Merge pull request #5222 from blattms/actionx-instant-nextstep

[Fix] Correct handling of NEXTSTEP in ACTIONX
This commit is contained in:
Markus Blatt 2024-03-05 15:00:06 +01:00 committed by GitHub
commit d061d70ba9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 51 additions and 19 deletions

View File

@ -378,29 +378,40 @@ public:
// \Note: The report steps are met in any case // \Note: The report steps are met in any case
// \Note: The sub stepping will require a copy of the state variables // \Note: The sub stepping will require a copy of the state variables
if (adaptiveTimeStepping_) { if (adaptiveTimeStepping_) {
const auto& events = schedule()[timer.currentStepNum()].events(); auto tuningUpdater = [enableTUNING, this, reportStep = timer.currentStepNum()]()
if (events.hasEvent(ScheduleEvents::TUNING_CHANGE)) { {
const auto& sched_state = schedule()[timer.currentStepNum()]; auto& schedule = this->ebosSimulator_.vanguard().schedule();
const auto& max_next_tstep = sched_state.max_next_tstep(enableTUNING); auto& events = this->schedule()[reportStep].events();
if (enableTUNING) {
const auto& tuning = sched_state.tuning();
adaptiveTimeStepping_->updateTUNING(max_next_tstep, tuning);
// \Note: Assumes TUNING is only used with adaptive time-stepping
// \Note: Need to update both solver (model) and simulator since solver is re-created each report step.
solver_->model().updateTUNING(tuning);
this->updateTUNING(tuning);
} else {
adaptiveTimeStepping_->updateNEXTSTEP(max_next_tstep);
}
}
if (events.hasEvent(ScheduleEvents::TUNING_CHANGE)) {
// Unset the event to not trigger it again on the next sub step
schedule.clear_event(ScheduleEvents::TUNING_CHANGE, reportStep);
const auto& sched_state = schedule[reportStep];
const auto& max_next_tstep = sched_state.max_next_tstep(enableTUNING);
const auto& tuning = sched_state.tuning();
if (enableTUNING) {
adaptiveTimeStepping_->updateTUNING(max_next_tstep, tuning);
// \Note: Assumes TUNING is only used with adaptive time-stepping
// \Note: Need to update both solver (model) and simulator since solver is re-created each report step.
solver_->model().updateTUNING(tuning);
this->updateTUNING(tuning);
} else {
this->adaptiveTimeStepping_->updateNEXTSTEP(max_next_tstep);
}
return max_next_tstep >0;
}
return false;
};
tuningUpdater();
const auto& events = schedule()[timer.currentStepNum()].events();
bool event = events.hasEvent(ScheduleEvents::NEW_WELL) || bool event = events.hasEvent(ScheduleEvents::NEW_WELL) ||
events.hasEvent(ScheduleEvents::INJECTION_TYPE_CHANGED) || events.hasEvent(ScheduleEvents::INJECTION_TYPE_CHANGED) ||
events.hasEvent(ScheduleEvents::WELL_SWITCHED_INJECTOR_PRODUCER) || events.hasEvent(ScheduleEvents::WELL_SWITCHED_INJECTOR_PRODUCER) ||
events.hasEvent(ScheduleEvents::PRODUCTION_UPDATE) || events.hasEvent(ScheduleEvents::PRODUCTION_UPDATE) ||
events.hasEvent(ScheduleEvents::INJECTION_UPDATE) || events.hasEvent(ScheduleEvents::INJECTION_UPDATE) ||
events.hasEvent(ScheduleEvents::WELL_STATUS_CHANGE); events.hasEvent(ScheduleEvents::WELL_STATUS_CHANGE);
auto stepReport = adaptiveTimeStepping_->step(timer, *solver_, event, nullptr); auto stepReport = adaptiveTimeStepping_->step(timer, *solver_, event, nullptr, tuningUpdater);
report_ += stepReport; report_ += stepReport;
//Pass simulation report to eclwriter for summary output //Pass simulation report to eclwriter for summary output
ebosSimulator_.problem().setSimulationReport(report_); ebosSimulator_.problem().setSimulationReport(report_);

View File

@ -62,7 +62,7 @@ namespace Opm
return ( report_step_ == 0 ) && ( current_step_ == 0 ); return ( report_step_ == 0 ) && ( current_step_ == 0 );
} }
AdaptiveSimulatorTimer& AdaptiveSimulatorTimer::operator++ () AdaptiveSimulatorTimer& AdaptiveSimulatorTimer::operator++ ()
{ {
++current_step_; ++current_step_;
current_time_ += dt_; current_time_ += dt_;
@ -115,6 +115,12 @@ AdaptiveSimulatorTimer& AdaptiveSimulatorTimer::operator++ ()
return dt_; return dt_;
} }
void AdaptiveSimulatorTimer::setCurrentStepLength(double dt)
{
assert(dt > 0);
dt_ = dt;
}
double AdaptiveSimulatorTimer::stepLengthTaken() const double AdaptiveSimulatorTimer::stepLengthTaken() const
{ {
assert( ! steps_.empty() ); assert( ! steps_.empty() );

View File

@ -69,6 +69,9 @@ namespace Opm
/// \brief \copydoc SimulationTimer::currentStepLength /// \brief \copydoc SimulationTimer::currentStepLength
double currentStepLength () const; double currentStepLength () const;
// \brief Set next step length
void setCurrentStepLength(double dt);
/// \brief \copydoc SimulationTimer::totalTime /// \brief \copydoc SimulationTimer::totalTime
double totalTime() const; double totalTime() const;

View File

@ -39,6 +39,7 @@
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
#include <cmath> #include <cmath>
#include <functional>
#include <memory> #include <memory>
#include <set> #include <set>
#include <sstream> #include <sstream>
@ -342,13 +343,18 @@ std::set<std::string> consistentlyFailingWells(const std::vector<StepReport>& sr
/** \brief step method that acts like the solver::step method /** \brief step method that acts like the solver::step method
in a sub cycle of time steps in a sub cycle of time steps
\param tuningUpdater Function used to update TUNING parameters before each
time step. ACTIONX might change tuning.
*/ */
template <class Solver> template <class Solver>
SimulatorReport step(const SimulatorTimer& simulatorTimer, SimulatorReport step(const SimulatorTimer& simulatorTimer,
Solver& solver, Solver& solver,
const bool isEvent, const bool isEvent,
const std::vector<int>* fipnum = nullptr) const std::vector<int>* fipnum = nullptr,
const std::function<bool()> tuningUpdater = [](){return false;})
{ {
// Maybe update tuning
tuningUpdater();
SimulatorReport report; SimulatorReport report;
const double timestep = simulatorTimer.currentStepLength(); const double timestep = simulatorTimer.currentStepLength();
@ -377,8 +383,14 @@ std::set<std::string> consistentlyFailingWells(const std::vector<StepReport>& sr
// sub step time loop // sub step time loop
while (!substepTimer.done()) { while (!substepTimer.done()) {
// Maybe update tuning
// get current delta t // get current delta t
const double dt = substepTimer.currentStepLength() ; auto oldValue = suggestedNextTimestep_;
if (tuningUpdater()) {
substepTimer.setCurrentStepLength(suggestedNextTimestep_);
suggestedNextTimestep_ = oldValue;
}
const double dt = substepTimer.currentStepLength();
if (timestepVerbose_) { if (timestepVerbose_) {
detail::logTimer(substepTimer); detail::logTimer(substepTimer);
} }