Delay UDQ Assignments Until After Summary Output

Commit 0aaa69c6e (PR #5330) was a little too eager in its effort to
handle UDQ ASSIGN operations after action processing[%].  In
particular, the assignments, which alter the internal structures of
the SummaryState and UDQState objects, would happen prior to writing
summary files.  In turn, this would make it appear as if the
assignment happened too early.  This commit defers UDQ assignments
triggered by action processing until FlowProblem<>::endEpisode() for
two reasons

  1. The problem originally addressed in 0aaa69c6e only presented
     when the assignment was triggered on the final time step of an
     episode (report step), so handling this situation here is a
     more targeted approach.

  2. Member function FlowProblem<>::endEpisode() is called after we
     write the summary file output so any alterations to the
     internal structures of the SummaryState will not be visible in
     the summary output until the next time step.  This is the
     expected behaviour.

[%] Insufficient testing by: [at]bska.
This commit is contained in:
Bård Skaflestad
2024-05-23 14:53:03 +02:00
parent 03e8c7ecdc
commit 6e8da2309b

View File

@@ -707,22 +707,9 @@ public:
return vg.gridIdxToEquilGridIdx(i);
});
});
// Rerun UDQ assignents following action processing to make sure
// that any UDQ ASSIGN operations triggered in action blocks
// take effect. This is mainly to work around a shortcoming of
// the ScheduleState copy constructor which clears pending UDQ
// assignments under the assumption that all such assignments
// have been processed. If an action block happens to trigger
// on the final time step of an episode and that action block
// runs a UDQ assignment, then that assignment would be dropped
// and the rest of the simulator will never see its effect
// without this hack.
this->actionHandler_
.evalUDQAssignments(episodeIdx, this->simulator().vanguard().udqState());
}
// deal with "clogging" for the MICP model
// Deal with "clogging" for the MICP model
if constexpr (enableMICP) {
auto& model = this->model();
const auto& residual = model.linearizer().residual();
@@ -740,21 +727,35 @@ public:
void endEpisode()
{
OPM_TIMEBLOCK(endEpisode);
auto& simulator = this->simulator();
auto& schedule = simulator.vanguard().schedule();
wellModel_.endEpisode();
aquiferModel_.endEpisode();
const int episodeIdx = this->episodeIndex();
int episodeIdx = this->episodeIndex();
// check if we're finished ...
if (episodeIdx + 1 >= static_cast<int>(schedule.size() - 1)) {
simulator.setFinished(true);
// Rerun UDQ assignents following action processing on the final
// time step of this episode to make sure that any UDQ ASSIGN
// operations triggered in action blocks take effect. This is
// mainly to work around a shortcoming of the ScheduleState copy
// constructor which clears pending UDQ assignments under the
// assumption that all such assignments have been processed. If an
// action block happens to trigger on the final time step of an
// episode and that action block runs a UDQ assignment, then that
// assignment would be dropped and the rest of the simulator will
// never see its effect without this hack.
this->actionHandler_
.evalUDQAssignments(episodeIdx, this->simulator().vanguard().udqState());
this->wellModel_.endEpisode();
this->aquiferModel_.endEpisode();
const auto& schedule = this->simulator().vanguard().schedule();
// End simulation when completed.
if (episodeIdx + 1 >= static_cast<int>(schedule.size()) - 1) {
this->simulator().setFinished(true);
return;
}
// .. if we're not yet done, start the next episode (report step)
simulator.startNextEpisode(schedule.stepLength(episodeIdx + 1));
// Otherwise, start next episode (report step).
this->simulator().startNextEpisode(schedule.stepLength(episodeIdx + 1));
}
/*!