Add Support Infrastructure for WELPI Feature

This commit adds logic implementing the static parts of the WELPI
keyword.  We internalize the keyword data, record appropriate events
and provide hooks for dynamically adjusting the per-connection
transmissibility factor (Connection::CF()) when those events occur.
We implement support at three levels

  - WellConnections:
    Add new public member functions prepareWellPIScaling and
    applyWellPIScaling which, respectively, creates bookkeeping
    data to track those connections which are subject to CF scaling
    and actually applies that CF scaling.

  - Well:
    Add new data member 'productivity_index' which holds the 'WELPI'
    data value from the input keyword (converted to SI) and new
    member functions updateWellProductivityIndex and
    applyWellProdIndexScaling.  The first follows the 'update*'
    protocol (return 'true' if state change) and assigns new values
    to 'productivity_index' while the second uses the stored PI
    value and a dynamically calculated effective PI value to rescale
    the pertinent connections' CF value.

  - Schedule:
    Add new member function handleWELPI which internalizes the WELPI
    keyword and its data and records WELPI events for subsequent
    playback in the simulator layer.

Also add a set of unit tests to exercise the new features at all
levels.
This commit is contained in:
Bård Skaflestad
2020-10-08 11:19:03 +02:00
parent de5e3d90cd
commit fa7d8bc28c
10 changed files with 573 additions and 14 deletions
+91
View File
@@ -58,6 +58,18 @@
using namespace Opm;
namespace {
double liquid_PI_unit()
{
return UnitSystem::newMETRIC().to_si(UnitSystem::measure::liquid_productivity_index, 1.0);
}
double cp_rm3_per_db()
{
return prefix::centi*unit::Poise * unit::cubic(unit::meter)
/ (unit::day * unit::barsa);
}
}
static Schedule make_schedule(const std::string& deck_string) {
const auto& deck = Parser{}.parseString(deck_string);
@@ -3702,3 +3714,82 @@ WLIFTOPT
BOOST_CHECK(w3.alloc_extra_gas());
}
BOOST_AUTO_TEST_CASE(WellPI) {
const auto deck = Parser{}.parseString(R"(RUNSPEC
START
7 OCT 2020 /
DIMENS
10 10 3 /
GRID
DXV
10*100.0 /
DYV
10*100.0 /
DZV
3*10.0 /
DEPTHZ
121*2000.0 /
PERMX
300*100.0 /
PERMY
300*100.0 /
PERMZ
300*10.0 /
PORO
300*0.3 /
SCHEDULE
WELSPECS
'P' 'G' 10 10 2005 'LIQ' /
/
COMPDAT
'P' 0 0 1 3 OPEN 1 100 /
/
TSTEP
10
/
WELPI
'P' 200.0 /
/
TSTEP
10
/
END
)");
const auto es = EclipseState{ deck };
const auto sched = Schedule{ deck, es };
// Apply WELPI before seeing WELPI data
{
const auto expectCF = 100.0*cp_rm3_per_db();
auto wellP = sched.getWell("P", 0);
wellP.applyWellProdIndexScaling(2.7182818);
for (const auto& conn : wellP.getConnections()) {
BOOST_CHECK_CLOSE(conn.CF(), expectCF, 1.0e-10);
}
}
// Apply WELPI after seeing WELPI data.
{
const auto expectCF = (200.0 / 100.0) * 100.0*cp_rm3_per_db();
auto wellP = sched.getWell("P", 1);
wellP.applyWellProdIndexScaling(100.0*liquid_PI_unit());
for (const auto& conn : wellP.getConnections()) {
BOOST_CHECK_CLOSE(conn.CF(), expectCF, 1.0e-10);
}
}
BOOST_CHECK_MESSAGE(sched.hasWellGroupEvent("P", ScheduleEvents::WELL_PRODUCTIVITY_INDEX, 1),
"Must have WELL_PRODUCTIVITY_INDEX event at report step 1");
}