Restart: Prepare to Output Well/Group Guide Rates

This commit identifies vector items in XWEL and XGRP that hold guide
rate values at the well and group levels, and adds functionality to
output those values to the restart file.  We do not identify such
value at the FIELD level.  As with other summary-like quantities, we
expect to pick up the fully converted values from a SummaryState
object.

Calculating and storing the guide rate quantities in SummaryState is
the subject of future work.
This commit is contained in:
Bård Skaflestad 2020-05-18 21:13:43 +02:00
parent 598f0e9056
commit 317d1ba14e
7 changed files with 229 additions and 3 deletions

View File

@ -74,8 +74,12 @@ public:
"GOPT", "GWPT", "GGPT", "GVPT", "GWIT",
"GGIT", "GVIT",
"GOPTH", "GWPTH", "GGPTH",
"GWITH", "GGITH"};
"GWITH", "GGITH",
"GOPGR", "GWPGR", "GGPGR", "GVPGR",
"GOIGR", "GWIGR", "GGIGR",
};
// Note: guide rates don't exist at the FIELD level.
const std::vector<std::string> restart_field_keys = {"FOPP", "FWPP", "FOPR", "FWPR", "FGPR",
"FVPR", "FWIR", "FGIR", "FWCT", "FGOR",
"FOPT", "FWPT", "FGPT", "FVPT", "FWIT",
@ -101,6 +105,13 @@ public:
{"GVIT", 17},
{"GOPP", 22},
{"GWPP", 23},
{"GOPGR", 85},
{"GWPGR", 86},
{"GGPGR", 87},
{"GVPGR", 88},
{"GOIGR", 89},
{"GWIGR", 91},
{"GGIGR", 93},
{"GOPTH", 135},
{"GWPTH", 139},
{"GWITH", 140},
@ -121,6 +132,7 @@ public:
{inj_cmode_enum::SALE, 0},
};
// Note: guide rates don't exist at the FIELD level.
const std::map<std::string, size_t> fieldKeyToIndex = {
{"FOPR", 0},
{"FWPR", 1},

View File

@ -74,6 +74,26 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
OilPrPot = 22, // Group's oil production potential
WatPrPot = 23, // Group's water production potential
OilPrGuideRate = 85, // Group's producer guide rate for oil.
WatPrGuideRate = 86, // Group's producer guide rate for water.
GasPrGuideRate = 87, // Group's producer guide rate for gas.
VoidPrGuideRate = 88, // Group's producer guide rate for reservoir voidage volume.
OilInjGuideRate = 89, // Group's injection guide rate for oil.
WatInjGuideRate = 91, // Group's injection guide rate for water.
WatInjGuideRate_2 = 92, // Second copy of group's injection guide rate for water.
// Not fully characterised.
GasInjGuideRate = 93, // Groups injection guide rate for gas.
OilPrGuideRate_2 = 127, // Second copy of group's producer guide rate for oil.
// Not fully characterised.
WatPrGuideRate_2 = 128, // Second copy of group's producer guide rate for water.
// Not fully characterised.
GasPrGuideRate_2 = 129, // Second copy of group's producer guide rate for gas.
// Not fully characterised.
VoidPrGuideRate_2 = 130, // Second copy of group's producer guide rate for
// reservoir voidage volume. Not fully characterised.
HistOilPrTotal = 135, // Group's total cumulative oil
// production (observed/historical rates)
HistWatPrTotal = 139, // Group's total cumulative water

View File

@ -157,6 +157,12 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
BHPTarget = 41, // Well's current BHP Target/Limit
PrimGuideRate = 48, // Well's "primary" guide rate (oil for producers,
// preferred phase for injectors)
WatPrGuideRate = 49, // Well's producer guide rate for water
GasPrGuideRate = 50, // Well's producer guide rate for gas
VoidPrGuideRate = 68, // Well's producer guide rate for reservoir voidag volume
HistOilPrTotal = 75, // Well's total cumulative oil production
// (observed/historical rates)
HistWatPrTotal = 76, // Well's total cumulative water
@ -169,6 +175,15 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
HistGasInjTotal = 82, // Well's total cumulative gas injection
// (observed/historical rates)
PrimGuideRate_2 = 91, // Second copy of well's primary guide rate.
// Not fully characterised.
WatPrGuideRate_2 = 92, // Second copy of well's producer guide rate for water.
// Not fully characterised.
GasPrGuideRate_2 = 93, // Second copy of well's producer guide rate for gas
// Not fully characterised.
VoidPrGuideRate_2 = 94, // Second copy of well's producer guide rate for reservoir voidage
// Not fully characterised.
WatVoidPrRate = 122, // Well's voidage production rate
GasVoidPrRate = 123, // Well's voidage production rate
};

View File

@ -441,6 +441,8 @@ void dynamicContrib(const std::vector<std::string>& restart_group_keys,
const Opm::SummaryState& sumState,
XGrpArray& xGrp)
{
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XGroup::index;
std::string groupName = group.name();
const std::vector<std::string>& keys = (groupName == "FIELD")
? restart_field_keys : restart_group_keys;
@ -457,6 +459,13 @@ void dynamicContrib(const std::vector<std::string>& restart_group_keys,
xGrp[itr->second] = keyValue;
}
}
xGrp[Ix::OilPrGuideRate_2] = xGrp[Ix::OilPrGuideRate];
xGrp[Ix::WatPrGuideRate_2] = xGrp[Ix::WatPrGuideRate];
xGrp[Ix::GasPrGuideRate_2] = xGrp[Ix::GasPrGuideRate];
xGrp[Ix::VoidPrGuideRate_2] = xGrp[Ix::VoidPrGuideRate];
xGrp[Ix::WatInjGuideRate_2] = xGrp[Ix::WatInjGuideRate];
}
} // XGrp

View File

@ -582,6 +582,11 @@ namespace {
xWell[Ix::item37] = xWell[Ix::WatPrRate];
xWell[Ix::item38] = xWell[Ix::GasPrRate];
xWell[Ix::PrimGuideRate] = xWell[Ix::PrimGuideRate_2] = get("WOPGR");
xWell[Ix::WatPrGuideRate] = xWell[Ix::WatPrGuideRate_2] = get("WWPGR");
xWell[Ix::GasPrGuideRate] = xWell[Ix::GasPrGuideRate_2] = get("WGPGR");
xWell[Ix::VoidPrGuideRate] = xWell[Ix::VoidPrGuideRate_2] = get("WVPGR");
xWell[Ix::HistOilPrTotal] = get("WOPTH");
xWell[Ix::HistWatPrTotal] = get("WWPTH");
xWell[Ix::HistGasPrTotal] = get("WGPTH");
@ -627,6 +632,8 @@ namespace {
// Not fully characterised.
xWell[Ix::item37] = xWell[Ix::WatPrRate];
xWell[Ix::PrimGuideRate] = xWell[Ix::PrimGuideRate_2] = -get("WWIGR");
xWell[Ix::WatVoidPrRate] = -get("WWVIR");
}
@ -661,9 +668,30 @@ namespace {
// Not fully characterised.
xWell[Ix::item38] = xWell[Ix::GasPrRate];
xWell[Ix::PrimGuideRate] = xWell[Ix::PrimGuideRate_2] = -get("WGIGR");
xWell[Ix::GasVoidPrRate] = xWell[Ix::VoidPrRate];
}
template <class XWellArray>
void assignOilInjector(const std::string& well,
const ::Opm::SummaryState& smry,
XWellArray& xWell)
{
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
auto get = [&smry, &well](const std::string& vector)
{
const auto key = vector + ':' + well;
return smry.has(key) ? smry.get(key) : 0.0;
};
xWell[Ix::FlowBHP] = get("WBHP");
xWell[Ix::PrimGuideRate] = xWell[Ix::PrimGuideRate_2] = -get("WOIGR");
}
template <class XWellArray>
void dynamicContrib(const ::Opm::Well& well,
const ::Opm::SummaryState& smry,
@ -678,7 +706,7 @@ namespace {
switch (itype) {
case IType::OIL:
// Do nothing.
assignOilInjector(well.name(), smry, xWell);
break;
case IType::WATER:

View File

@ -25,6 +25,7 @@
#include <opm/output/eclipse/AggregateWellData.hpp>
#include <opm/output/eclipse/VectorItems/intehead.hpp>
#include <opm/output/eclipse/VectorItems/group.hpp>
#include <opm/output/eclipse/VectorItems/well.hpp>
#include <opm/parser/eclipse/Python/Python.hpp>
@ -436,15 +437,35 @@ END
state.update("GOPR:GRP1", 235.);
state.update("GGPR:GRP1", 100237.);
state.update("GWPR:GRP1", 239.);
state.update("GOPGR:GRP1", 345.6);
state.update("GWPGR:GRP1", 456.7);
state.update("GGPGR:GRP1", 567.8);
state.update("GVPGR:GRP1", 678.9);
state.update("GOIGR:GRP1", 0.123);
state.update("GWIGR:GRP1", 1234.5);
state.update("GGIGR:GRP1", 2345.6);
state.update("GOPR:WGRP1", 23.);
state.update("GGPR:WGRP1", 50237.);
state.update("GWPR:WGRP1", 29.);
state.update("GOPGR:WGRP1", 456.7);
state.update("GWPGR:WGRP1", 567.8);
state.update("GGPGR:WGRP1", 678.9);
state.update("GVPGR:WGRP1", 789.1);
state.update("GOIGR:WGRP1", 1.23);
state.update("GWIGR:WGRP1", 2345.6);
state.update("GGIGR:WGRP1", 3456.7);
state.update("GOPR:WGRP2", 43.);
state.update("GGPR:WGRP2", 70237.);
state.update("GWPR:WGRP2", 59.);
state.update("GOPGR:WGRP2", 56.7);
state.update("GWPGR:WGRP2", 67.8);
state.update("GGPGR:WGRP2", 78.9);
state.update("GVPGR:WGRP2", 89.1);
state.update("GOIGR:WGRP2", 12.3);
state.update("GWIGR:WGRP2", 345.6);
state.update("GGIGR:WGRP2", 456.7);
state.update("FOPR", 3456.);
state.update("FGPR", 2003456.);
@ -536,6 +557,7 @@ BOOST_AUTO_TEST_CASE (Declared_Group_Data)
// XGRP (PROD)
{
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XGroup::index;
auto start = 0*ih.nxgrpz;
const auto& xGrp = agrpd.getXGroup();
@ -543,11 +565,55 @@ BOOST_AUTO_TEST_CASE (Declared_Group_Data)
BOOST_CHECK_EQUAL(xGrp[start + 1] , 239.); // Group GRP1 - GWPR
BOOST_CHECK_EQUAL(xGrp[start + 2] , 100237.); // Group GRP1 - GGPR
BOOST_CHECK_CLOSE(xGrp[start + Ix::OilPrGuideRate], 345.6, 1.0e-10);
BOOST_CHECK_EQUAL(xGrp[start + Ix::OilPrGuideRate],
xGrp[start + Ix::OilPrGuideRate_2]);
BOOST_CHECK_CLOSE(xGrp[start + Ix::WatPrGuideRate], 456.7, 1.0e-10);
BOOST_CHECK_EQUAL(xGrp[start + Ix::WatPrGuideRate],
xGrp[start + Ix::WatPrGuideRate_2]);
BOOST_CHECK_CLOSE(xGrp[start + Ix::GasPrGuideRate], 567.8, 1.0e-10);
BOOST_CHECK_EQUAL(xGrp[start + Ix::GasPrGuideRate],
xGrp[start + Ix::GasPrGuideRate_2]);
BOOST_CHECK_CLOSE(xGrp[start + Ix::VoidPrGuideRate], 678.9, 1.0e-10);
BOOST_CHECK_EQUAL(xGrp[start + Ix::VoidPrGuideRate],
xGrp[start + Ix::VoidPrGuideRate_2]);
BOOST_CHECK_CLOSE(xGrp[start + Ix::OilInjGuideRate], 0.123, 1.0e-10);
BOOST_CHECK_CLOSE(xGrp[start + Ix::WatInjGuideRate], 1234.5, 1.0e-10);
BOOST_CHECK_EQUAL(xGrp[start + Ix::WatInjGuideRate],
xGrp[start + Ix::WatInjGuideRate_2]);
BOOST_CHECK_CLOSE(xGrp[start + Ix::GasInjGuideRate], 2345.6, 1.0e-10);
start = 1*ih.nxgrpz;
BOOST_CHECK_EQUAL(xGrp[start + 0] , 23.); // Group WGRP1 - GOPR
BOOST_CHECK_EQUAL(xGrp[start + 1] , 29.); // Group WGRP1 - GWPR
BOOST_CHECK_EQUAL(xGrp[start + 2] , 50237.); // Group WGRP1 - GGPR
BOOST_CHECK_CLOSE(xGrp[start + Ix::OilPrGuideRate], 456.7, 1.0e-10);
BOOST_CHECK_EQUAL(xGrp[start + Ix::OilPrGuideRate],
xGrp[start + Ix::OilPrGuideRate_2]);
BOOST_CHECK_CLOSE(xGrp[start + Ix::WatPrGuideRate], 567.8, 1.0e-10);
BOOST_CHECK_EQUAL(xGrp[start + Ix::WatPrGuideRate],
xGrp[start + Ix::WatPrGuideRate_2]);
BOOST_CHECK_CLOSE(xGrp[start + Ix::GasPrGuideRate], 678.9, 1.0e-10);
BOOST_CHECK_EQUAL(xGrp[start + Ix::GasPrGuideRate],
xGrp[start + Ix::GasPrGuideRate_2]);
BOOST_CHECK_CLOSE(xGrp[start + Ix::VoidPrGuideRate], 789.1, 1.0e-10);
BOOST_CHECK_EQUAL(xGrp[start + Ix::VoidPrGuideRate],
xGrp[start + Ix::VoidPrGuideRate_2]);
BOOST_CHECK_CLOSE(xGrp[start + Ix::OilInjGuideRate], 1.23, 1.0e-10);
BOOST_CHECK_CLOSE(xGrp[start + Ix::WatInjGuideRate], 2345.6, 1.0e-10);
BOOST_CHECK_EQUAL(xGrp[start + Ix::WatInjGuideRate],
xGrp[start + Ix::WatInjGuideRate_2]);
BOOST_CHECK_CLOSE(xGrp[start + Ix::GasInjGuideRate], 3456.7, 1.0e-10);
start = 2*ih.nxgrpz;
BOOST_CHECK_EQUAL(xGrp[start + 0] , 43.); // Group WGRP2 - GOPR
BOOST_CHECK_EQUAL(xGrp[start + 1] , 59.); // Group WGRP2 - GWPR

View File

@ -244,6 +244,10 @@ TSTEP -- 8
state.update("WGITH:OP_1", 0.0);
state.update("WGVIR:OP_1", 0.0);
state.update("WWVIR:OP_1", 0.0);
state.update("WOPGR:OP_1", 4.9);
state.update("WWPGR:OP_1", 3.8);
state.update("WGPGR:OP_1", 2.7);
state.update("WVPGR:OP_1", 6.1);
state.update("WOPR:OP_2" , 0.0);
state.update("WWPR:OP_2" , 0.0);
@ -268,6 +272,10 @@ TSTEP -- 8
state.update("WGITH:OP_2", 3030.0);
state.update("WGVIR:OP_2", 1234.0);
state.update("WWVIR:OP_2", 4321.0);
state.update("WOIGR:OP_2", 4.9);
state.update("WWIGR:OP_2", 3.8);
state.update("WGIGR:OP_2", 2.7);
state.update("WVIGR:OP_2", 6.1);
state.update("WOPR:OP_3" , 11.0);
state.update("WWPR:OP_3" , 12.0);
@ -292,6 +300,10 @@ TSTEP -- 8
state.update("WGITH:OP_3", 0.0);
state.update("WGVIR:OP_3", 0.0);
state.update("WWVIR:OP_3", 43.21);
state.update("WOPGR:OP_3", 49.0);
state.update("WWPGR:OP_3", 38.9);
state.update("WGPGR:OP_3", 27.8);
state.update("WVPGR:OP_3", 61.2);
return state;
}
@ -610,6 +622,18 @@ BOOST_AUTO_TEST_CASE (Dynamic_Well_Data_Step1)
BOOST_CHECK_CLOSE(xwell[i0 + Ix::HistWatInjTotal], 0.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::HistGasInjTotal], 0.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::PrimGuideRate], 4.9, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i0 + Ix::PrimGuideRate], xwell[i0 + Ix::PrimGuideRate_2]);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::WatPrGuideRate], 3.8, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i0 + Ix::WatPrGuideRate], xwell[i0 + Ix::WatPrGuideRate_2]);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::GasPrGuideRate], 2.7, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i0 + Ix::GasPrGuideRate], xwell[i0 + Ix::GasPrGuideRate_2]);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::VoidPrGuideRate], 6.1, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i0 + Ix::VoidPrGuideRate], xwell[i0 + Ix::VoidPrGuideRate_2]);
}
// XWEL (OP_2)
@ -638,6 +662,20 @@ BOOST_AUTO_TEST_CASE (Dynamic_Well_Data_Step1)
BOOST_CHECK_CLOSE(xwell[i1 + Ix::HistGasPrTotal] , 0.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::HistWatInjTotal], 1515.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::HistGasInjTotal], 3030.0, 1.0e-10);
// Gas injector => primary guide rate == gas injection guide rate (with negative sign).
BOOST_CHECK_CLOSE(xwell[i1 + Ix::PrimGuideRate], -2.7, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i1 + Ix::PrimGuideRate], xwell[i1 + Ix::PrimGuideRate_2]);
// Injector => all phase production guide rates are zero
BOOST_CHECK_CLOSE(xwell[i1 + Ix::WatPrGuideRate], 0.0, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i1 + Ix::WatPrGuideRate], xwell[i1 + Ix::WatPrGuideRate_2]);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::GasPrGuideRate], 0.0, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i1 + Ix::GasPrGuideRate], xwell[i1 + Ix::GasPrGuideRate_2]);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::VoidPrGuideRate], 0.0, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i1 + Ix::VoidPrGuideRate], xwell[i1 + Ix::VoidPrGuideRate_2]);
}
}
@ -716,6 +754,18 @@ BOOST_AUTO_TEST_CASE (Dynamic_Well_Data_Step2)
BOOST_CHECK_CLOSE(xwell[i0 + Ix::HistOilPrTotal], 345.6, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::HistWatPrTotal], 456.7, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::HistGasPrTotal], 567.8, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::PrimGuideRate], 4.9, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i0 + Ix::PrimGuideRate], xwell[i0 + Ix::PrimGuideRate_2]);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::WatPrGuideRate], 3.8, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i0 + Ix::WatPrGuideRate], xwell[i0 + Ix::WatPrGuideRate_2]);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::GasPrGuideRate], 2.7, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i0 + Ix::GasPrGuideRate], xwell[i0 + Ix::GasPrGuideRate_2]);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::VoidPrGuideRate], 6.1, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i0 + Ix::VoidPrGuideRate], xwell[i0 + Ix::VoidPrGuideRate_2]);
}
// XWEL (OP_2) -- water injector
@ -750,6 +800,20 @@ BOOST_AUTO_TEST_CASE (Dynamic_Well_Data_Step2)
// WWVIR
BOOST_CHECK_CLOSE(xwell[i1 + Ix::WatVoidPrRate],
-4321.0, 1.0e-10);
// Water injector => primary guide rate == water injection guide rate (with negative sign).
BOOST_CHECK_CLOSE(xwell[i1 + Ix::PrimGuideRate], -3.8, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i1 + Ix::PrimGuideRate], xwell[i1 + Ix::PrimGuideRate_2]);
// Injector => all phase production guide rates are zero
BOOST_CHECK_CLOSE(xwell[i1 + Ix::WatPrGuideRate], 0.0, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i1 + Ix::WatPrGuideRate], xwell[i1 + Ix::WatPrGuideRate_2]);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::GasPrGuideRate], 0.0, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i1 + Ix::GasPrGuideRate], xwell[i1 + Ix::GasPrGuideRate_2]);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::VoidPrGuideRate], 0.0, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i1 + Ix::VoidPrGuideRate], xwell[i1 + Ix::VoidPrGuideRate_2]);
}
// XWEL (OP_3) -- producer
@ -785,6 +849,18 @@ BOOST_AUTO_TEST_CASE (Dynamic_Well_Data_Step2)
BOOST_CHECK_CLOSE(xwell[i2 + Ix::HistOilPrTotal], 2345.6, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::HistWatPrTotal], 3456.7, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::HistGasPrTotal], 4567.8, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::PrimGuideRate], 49, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i2 + Ix::PrimGuideRate], xwell[i2 + Ix::PrimGuideRate_2]);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::WatPrGuideRate], 38.9, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i2 + Ix::WatPrGuideRate], xwell[i2 + Ix::WatPrGuideRate_2]);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::GasPrGuideRate], 27.8, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i2 + Ix::GasPrGuideRate], xwell[i2 + Ix::GasPrGuideRate_2]);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::VoidPrGuideRate], 61.2, 1.0e-10);
BOOST_CHECK_EQUAL(xwell[i2 + Ix::VoidPrGuideRate], xwell[i2 + Ix::VoidPrGuideRate_2]);
}
}