WELPI: Don't Inadvertently Overwrite Scaling Eligiblity

Since the Well stores a pointer to its connections, rather than the
connections themselves, we must take care not change the existing
state of the connections' WELPI eligibility flag.  Do the update
check on a copy of the connections instead of the real connections.

Pointy Hat: [at]bska
This commit is contained in:
Bård Skaflestad 2020-10-13 17:01:09 +02:00
parent f718cc1adc
commit f84858279f
4 changed files with 44 additions and 2 deletions

View File

@ -557,6 +557,8 @@ public:
bool handleCOMPLUMP(const DeckRecord& record);
bool handleWPIMULT(const DeckRecord& record);
void forceUpdateConnections(std::shared_ptr<WellConnections> connections_arg);
void filterConnections(const ActiveGridCells& grid);
ProductionControls productionControls(const SummaryState& st) const;
InjectionControls injectionControls(const SummaryState& st) const;

View File

@ -21,10 +21,12 @@
#include <fnmatch.h>
#include <functional>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include <fmt/format.h>
@ -1115,7 +1117,13 @@ namespace {
const auto& well = this->getWell(well_name, handlerContext.currentStep);
const auto unitPI = (well.getPreferredPhase() == Phase::GAS) ? gasPI : liqPI;
auto well2 = std::make_shared<Well>(well);
// Note: Need to ensure we have an independent copy of
// well's connections because
// Well::updateWellProductivityIndex() implicitly mutates
// internal state in the WellConnections class.
auto well2 = std::make_shared<Well>(well);
auto connections = std::make_shared<WellConnections>(well2->getConnections());
well2->forceUpdateConnections(std::move(connections));
if (well2->updateWellProductivityIndex(usys.to_si(unitPI, rawProdIndex)))
this->updateWell(std::move(well2), handlerContext.currentStep);

View File

@ -35,6 +35,7 @@
#include <fnmatch.h>
#include <cmath>
#include <ostream>
#include <utility>
namespace Opm {
@ -1056,6 +1057,11 @@ bool Well::updateWSEGVALV(const std::vector<std::pair<int, Valve> >& valve_pairs
return false;
}
void Well::forceUpdateConnections(std::shared_ptr<WellConnections> connections_arg) {
connections_arg->order();
this->connections = std::move(connections_arg);
}
void Well::filterConnections(const ActiveGridCells& grid) {
this->connections->filter(grid);
}

View File

@ -3760,6 +3760,14 @@ TSTEP
10
/
COMPDAT
'P' 0 0 2 2 OPEN 1 50 /
/
TSTEP
10
/
END
)");
@ -3788,11 +3796,29 @@ END
}
}
// Apply WELPI after new COMPDAT.
{
const auto expectCF = (200.0 / 100.0) * 100.0*cp_rm3_per_db();
auto wellP = sched.getWell("P", 2);
wellP.applyWellProdIndexScaling(100.0*liquid_PI_unit());
const auto& connP = wellP.getConnections();
BOOST_CHECK_CLOSE(connP[0].CF(), expectCF , 1.0e-10);
BOOST_CHECK_CLOSE(connP[1].CF(), 50*cp_rm3_per_db(), 1.0e-10);
BOOST_CHECK_CLOSE(connP[2].CF(), expectCF , 1.0e-10);
}
BOOST_CHECK_MESSAGE(sched.hasWellGroupEvent("P", ScheduleEvents::WELL_CONNECTIONS_UPDATED, 0),
"Well P must have WELL_CONNECTIONS_UPDATED event at report step 0");
BOOST_CHECK_MESSAGE(!sched.hasWellGroupEvent("P", ScheduleEvents::WELL_CONNECTIONS_UPDATED, 1),
"Well P must NOT have WELL_CONNECTIONS_UPDATED event at report step 0");
"Well P must NOT have WELL_CONNECTIONS_UPDATED event at report step 1");
BOOST_CHECK_MESSAGE(sched.hasWellGroupEvent("P", ScheduleEvents::WELL_CONNECTIONS_UPDATED, 2),
"Well P must have WELL_CONNECTIONS_UPDATED event at report step 2");
BOOST_CHECK_MESSAGE(!sched.hasWellGroupEvent("P", ScheduleEvents::WELL_CONNECTIONS_UPDATED, 3),
"Well P must NOT have WELL_CONNECTIONS_UPDATED event at report step 3");
BOOST_CHECK_MESSAGE(sched.hasWellGroupEvent("P", ScheduleEvents::WELL_PRODUCTIVITY_INDEX, 1),
"Must have WELL_PRODUCTIVITY_INDEX event at report step 1");