diff --git a/opm/simulators/flow/ActionHandler.cpp b/opm/simulators/flow/ActionHandler.cpp index eba239b00..8f6e9f32e 100644 --- a/opm/simulators/flow/ActionHandler.cpp +++ b/opm/simulators/flow/ActionHandler.cpp @@ -137,18 +137,12 @@ namespace { template std::unordered_map - fetchWellPI(const int reportStep, - const Opm::Schedule& schedule, - const WellModel& wellModel, - const Opm::Action::ActionX& action, - const Opm::Action::Result::MatchingEntities& matches, + fetchWellPI(const WellModel& wellModel, + const std::vector& wellpi_wells, const Opm::Parallel::Communication comm) { auto wellpi = std::unordered_map {}; - const auto wellpi_wells = action.wellpi_wells - (schedule.wellMatcher(reportStep), matches); - if (wellpi_wells.empty()) { return wellpi; } @@ -207,8 +201,13 @@ applyActions(const int reportStep, bool commit_wellstate = false; for (const auto& pyaction : actions.pending_python(actionState_)) { + // The std::unordered_map wellpi contains the well production indices from the last + // timestep. This map is needed for the keyword WELPI. For a PyAction, we do not know which wells are + // affected by the PyAction, thus we get the production indices for all wells. + const std::vector wellpi_wells = schedule_[reportStep].well_order().names(); + const auto wellpi = fetchWellPI(this->wellModel_, wellpi_wells, this->comm_); auto sim_update = schedule_.runPyAction(reportStep, *pyaction, actionState_, - ecl_state_, summaryState_); + ecl_state_, summaryState_, wellpi); if (const auto pyRes = this->actionState_.python_result(pyaction->name()); !pyRes.has_value() || !*pyRes) @@ -237,9 +236,11 @@ applyActions(const int reportStep, logActiveAction(action->name(), matches.wells(), ts); - const auto wellpi = fetchWellPI - (reportStep, this->schedule_, this->wellModel_, - *action, matches, this->comm_); + // The std::unordered_map wellpi contains the well production indices from the last + // timestep. This map is needed for the keyword WELPI. For an ActionX, we know which wells are affected by + // the ActionX, thus fetch the well production indices only for the affected wells. + const std::vector wellpi_wells = action->wellpi_wells(schedule_.wellMatcher(reportStep), matches); + const auto wellpi = fetchWellPI(this->wellModel_, wellpi_wells, this->comm_); const auto sim_update = this->schedule_ .applyAction(reportStep, *action, matches, wellpi); diff --git a/pyactionActionXComparisons.cmake b/pyactionActionXComparisons.cmake index 32987d2ce..d6a9833ab 100644 --- a/pyactionActionXComparisons.cmake +++ b/pyactionActionXComparisons.cmake @@ -125,6 +125,26 @@ add_test_compareSeparateECLFiles(CASENAME pyaction_wefac_insert_kw REL_TOL ${rel_tol} IGNORE_EXTRA_KW BOTH) +add_test_compareSeparateECLFiles(CASENAME pyaction_welpi_insert_kw + DIR1 pyaction + FILENAME1 PYACTION_WELPI_INSERT_KW + DIR2 actionx + FILENAME2 ACTIONX_WELPI + SIMULATOR flow + ABS_TOL ${abs_tol} + REL_TOL ${rel_tol} + IGNORE_EXTRA_KW BOTH) + +add_test_compareSeparateECLFiles(CASENAME pyaction_wpimult_insert_kw + DIR1 pyaction + FILENAME1 PYACTION_WPIMULT_INSERT_KW + DIR2 actionx + FILENAME2 ACTIONX_WPIMULT + SIMULATOR flow + ABS_TOL ${abs_tol} + REL_TOL ${rel_tol} + IGNORE_EXTRA_KW BOTH) + add_test_compareSeparateECLFiles(CASENAME pyaction_wsegvalv_insert_kw DIR1 pyaction FILENAME1 PYACTION_WSEGVALV_INSERT_KW @@ -253,6 +273,28 @@ if(MPI_FOUND) IGNORE_EXTRA_KW BOTH MPI_PROCS 4) + add_test_compareSeparateECLFiles(CASENAME pyaction_welpi_insert_kw_4_procs + DIR1 pyaction + FILENAME1 PYACTION_WELPI_INSERT_KW + DIR2 actionx + FILENAME2 ACTIONX_WELPI + SIMULATOR flow + ABS_TOL ${abs_tol} + REL_TOL ${rel_tol} + IGNORE_EXTRA_KW BOTH, + MPI_PROCS 4) + + add_test_compareSeparateECLFiles(CASENAME pyaction_wpimult_insert_kw_4_procs + DIR1 pyaction + FILENAME1 PYACTION_WPIMULT_INSERT_KW + DIR2 actionx + FILENAME2 ACTIONX_WPIMULT + SIMULATOR flow + ABS_TOL ${abs_tol} + REL_TOL ${rel_tol} + IGNORE_EXTRA_KW BOTH + MPI_PROCS 4) + add_test_compareSeparateECLFiles(CASENAME pyaction_wsegvalv_insert_kw_4_procs DIR1 pyaction FILENAME1 PYACTION_WSEGVALV_INSERT_KW