[Fix] Correct handling of NEXTSTEP in ACTIONX

Previously, the step size would only have used for the first time step
of the next report step (at least of --enable-tuning=true was used).
This commit is contained in:
Markus Blatt 2024-02-22 17:02:48 +01:00
parent c94da66810
commit 2cd490b601
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()]()
{
auto& schedule = this->ebosSimulator_.vanguard().schedule();
auto& events = this->schedule()[reportStep].events();
if (events.hasEvent(ScheduleEvents::TUNING_CHANGE)) { if (events.hasEvent(ScheduleEvents::TUNING_CHANGE)) {
const auto& sched_state = schedule()[timer.currentStepNum()]; // 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& max_next_tstep = sched_state.max_next_tstep(enableTUNING);
if (enableTUNING) {
const auto& tuning = sched_state.tuning(); const auto& tuning = sched_state.tuning();
if (enableTUNING) {
adaptiveTimeStepping_->updateTUNING(max_next_tstep, tuning); adaptiveTimeStepping_->updateTUNING(max_next_tstep, tuning);
// \Note: Assumes TUNING is only used with adaptive time-stepping // \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. // \Note: Need to update both solver (model) and simulator since solver is re-created each report step.
solver_->model().updateTUNING(tuning); solver_->model().updateTUNING(tuning);
this->updateTUNING(tuning); this->updateTUNING(tuning);
} else { } else {
adaptiveTimeStepping_->updateNEXTSTEP(max_next_tstep); 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

@ -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,7 +383,13 @@ 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
auto oldValue = suggestedNextTimestep_;
if (tuningUpdater()) {
substepTimer.setCurrentStepLength(suggestedNextTimestep_);
suggestedNextTimestep_ = oldValue;
}
const double dt = substepTimer.currentStepLength(); const double dt = substepTimer.currentStepLength();
if (timestepVerbose_) { if (timestepVerbose_) {
detail::logTimer(substepTimer); detail::logTimer(substepTimer);