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 sub stepping will require a copy of the state variables
if (adaptiveTimeStepping_) {
const auto& events = schedule()[timer.currentStepNum()].events();
if (events.hasEvent(ScheduleEvents::TUNING_CHANGE)) {
const auto& sched_state = schedule()[timer.currentStepNum()];
const auto& max_next_tstep = sched_state.max_next_tstep(enableTUNING);
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);
}
}
auto tuningUpdater = [enableTUNING, this, reportStep = timer.currentStepNum()]()
{
auto& schedule = this->ebosSimulator_.vanguard().schedule();
auto& events = this->schedule()[reportStep].events();
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) ||
events.hasEvent(ScheduleEvents::INJECTION_TYPE_CHANGED) ||
events.hasEvent(ScheduleEvents::WELL_SWITCHED_INJECTOR_PRODUCER) ||
events.hasEvent(ScheduleEvents::PRODUCTION_UPDATE) ||
events.hasEvent(ScheduleEvents::INJECTION_UPDATE) ||
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;
//Pass simulation report to eclwriter for summary output
ebosSimulator_.problem().setSimulationReport(report_);

View File

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

View File

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

View File

@ -39,6 +39,7 @@
#include <algorithm>
#include <cassert>
#include <cmath>
#include <functional>
#include <memory>
#include <set>
#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
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>
SimulatorReport step(const SimulatorTimer& simulatorTimer,
Solver& solver,
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;
const double timestep = simulatorTimer.currentStepLength();
@ -377,8 +383,14 @@ std::set<std::string> consistentlyFailingWells(const std::vector<StepReport>& sr
// sub step time loop
while (!substepTimer.done()) {
// Maybe update tuning
// 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_) {
detail::logTimer(substepTimer);
}