xWEL Restart Vectors: Switch to Using Named Indexes

While here, also update pertinent unit tests to use the same vector
identfication scheme.

Suggested by: [at]joakim-hove and [at]atgeirr.
This commit is contained in:
Bård Skaflestad
2018-07-12 10:44:27 +02:00
parent 20d0565220
commit 34b1b3a073
5 changed files with 538 additions and 276 deletions
+1
View File
@@ -493,6 +493,7 @@ if(ENABLE_ECL_OUTPUT)
opm/output/data/Solution.hpp
opm/output/data/Wells.hpp
opm/output/eclipse/VectorItems/intehead.hpp
opm/output/eclipse/VectorItems/well.hpp
opm/output/eclipse/AggregateWellData.hpp
opm/output/eclipse/CharArrayNullTerm.hpp
opm/output/eclipse/DoubHEAD.hpp
+164
View File
@@ -0,0 +1,164 @@
/*
Copyright (c) 2018 Equinor ASA
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_OUTPUT_ECLIPSE_VECTOR_WELL_HPP
#define OPM_OUTPUT_ECLIPSE_VECTOR_WELL_HPP
#include <vector>
namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems {
namespace IWell {
enum index : std::vector<int>::size_type {
IHead = 0, // I-location (one-based) of well head
JHead = 1, // J-location (one-based) of well head
FirstK = 2, // Layer ID (one-based) of top/first connection
LastK = 3, // Layer ID (one-based) of bottom/last connection
NConn = 4, // Number of active cells connected to well
Group = 5, // Index (one-based) of well's current group
WType = 6, // Well type
WCtrl = 7, // Well control
item9 = 8,
item11 = 10,
VFPTab = 11, // ID (one-based) of well's current VFP table
item18 = 17, // Unknown
item25 = 24, // Unknown
item32 = 31, // Unknown
item48 = 47, // Unknown
item50 = 49, // Unknown
MsWID = 70, // Multisegment well ID
// Value 0 for regular wells
// Value 1..#MS wells for MS wells
NWseg = 71, // Number of well segments
// Value 0 for regular wells
// Value #segments for MS wells
CompOrd = 98,
};
namespace Value {
enum WellType : int {
WTUnk = 0, // Unknown well type (OPM only)
Producer = 1, // Well is producer
OilInj = 2, // Well is oil injector
WatInj = 3, // Well is water injector
GasInj = 4, // Well is gas injector
};
enum WellCtrlMode : int {
WMCtlUnk = -10, // Unknown well control mode (OPM only)
Group = - 1, // Well under group control
Shut = 0, // Well is shut
OilRate = 1, // Well controlled by oil rate
WatRate = 2, // Well controlled by water rate
GasRate = 3, // Well controlled by gas rate
LiqRate = 4, // Well controlled by liquid rate
ResVRate = 5, // Well controlled by
// reservoir voidage rate
THP = 6, // Well controlled by
// tubing head pressure target
BHP = 7, // Well controlled by
// bottom-hole pressure target
CombRate = 9, // Well controlled by linearly
// combined rate target
};
enum CompOrder : int {
Track = 0, // Connections ordered along
// well track (increasing MD)
Depth = 1, // Connections ordered by inceasing
// true vertical depth. Not really
// supported in OPM Flow.
Input = 2, // Connections listed in order of
// appearance in simulation model's
// COMPDAT keyword.
};
} // Value
} // IWell
namespace SWell {
enum index : std::vector<float>::size_type {
OilRateTarget = 0, // Well's current oil rate production target
WatRateTarget = 1, // Well's current water rate production target
GasRateTarget = 2, // Well's current gas rate production target
LiqRateTarget = 3, // Well's current liquid rate production target
ResVRateTarget = 4, // Well's current reservoir voidate rate
// production target
THPTarget = 5, // Well's tubing head pressure target
BHPTarget = 6, // Well's bottom hole pressure target
DatumDepth = 9, // Well's reference depth for BHP
};
} // SWell
namespace XWell {
enum index : std::vector<double>::size_type {
OilPrRate = 0, // Well's oil production rate
WatPrRate = 1, // Well's water production rate
GasPrRate = 2, // Well's gas production rate
LiqPrRate = 3, // Well's liquid production rate
VoidPrRate = 4, // Well's reservoir voidage production rate
FlowBHP = 6, // Well's flowing/producing bottom hole pressure
WatCut = 7, // Well's producing water cut
GORatio = 8, // Well's producing gas/oil ratio
OilPrTotal = 18, // Well's total cumulative oil production
WatPrTotal = 19, // Well's total cumulative water production
GasPrTotal = 20, // Well's total cumulative gas production
VoidPrTotal = 21, // Well's total cumulative reservoir
// voidage production
WatInjTotal = 23, // Well's total cumulative water injection
GasInjTotal = 24, // Well's total cumulative gas injection
GasFVF = 34, // Well's producing gas formation volume factor.
item37 = 36,
item38 = 37,
BHPTarget = 41, // Well's current BHP Target/Limit
item82 = 81,
item83 = 82,
WatVoidPrRate = 122, // Well's voidage production rate
GasVoidPrRate = 123, // Well's voidage production rate
};
} // XWell
namespace ZWell {
enum index : std::vector<const char*>::size_type {
WellName = 0, // Well name
};
} // ZWell
}}}} // Opm::RestartIO::Helpers::VectorItems
#endif // OPM_OUTPUT_ECLIPSE_VECTOR_WELL_HPP
+141 -105
View File
@@ -20,6 +20,7 @@
#include <opm/output/eclipse/AggregateWellData.hpp>
#include <opm/output/eclipse/VectorItems/intehead.hpp>
#include <opm/output/eclipse/VectorItems/well.hpp>
#include <opm/output/data/Wells.hpp>
@@ -144,8 +145,11 @@ namespace {
int wellType(const Opm::Well& well,
const std::size_t sim_step)
{
using WTypeVal = ::Opm::RestartIO::Helpers::
VectorItems::IWell::Value::WellType;
if (well.isProducer(sim_step)) {
return 1; // Producer flag
return WTypeVal::Producer;
}
using IType = ::Opm::WellInjector::TypeEnum;
@@ -154,10 +158,10 @@ namespace {
.getInjectionProperties(sim_step).injectorType;
switch (itype) {
case IType::OIL: return 2; // Oil Injector
case IType::WATER: return 3; // Water Injector
case IType::GAS: return 4; // Gas Injector
default: return 0; // Undefined
case IType::OIL: return WTypeVal::OilInj;
case IType::WATER: return WTypeVal::WatInj;
case IType::GAS: return WTypeVal::GasInj;
default: return WTypeVal::WTUnk;
}
}
@@ -174,13 +178,16 @@ namespace {
int ctrlMode(const Opm::Well& well,
const std::size_t sim_step)
{
using WMCtrlVal = ::Opm::RestartIO::Helpers::
VectorItems::IWell::Value::WellCtrlMode;
{
const auto stat = well.getStatus(sim_step);
using WStat = ::Opm::WellCommon::StatusEnum;
if ((stat == WStat::SHUT) || (stat == WStat::STOP)) {
return 0;
return WMCtrlVal::Shut;
}
}
@@ -197,21 +204,21 @@ namespace {
switch (wmctl) {
case CMode::RATE: {
switch (wtype) {
case WType::OIL: return 1; // ORAT
case WType::WATER: return 2; // WRAT
case WType::GAS: return 3; // GRAT
case WType::MULTI: return 0; // MULTI (value not known)
case WType::OIL: return WMCtrlVal::OilRate;
case WType::WATER: return WMCtrlVal::WatRate;
case WType::GAS: return WMCtrlVal::GasRate;
case WType::MULTI: return WMCtrlVal::WMCtlUnk;
}
}
break;
case CMode::RESV: return 5; // RESV
case CMode::THP: return 6;
case CMode::BHP: return 7;
case CMode::GRUP: return -1;
case CMode::RESV: return WMCtrlVal::ResVRate;
case CMode::THP: return WMCtrlVal::THP;
case CMode::BHP: return WMCtrlVal::BHP;
case CMode::GRUP: return WMCtrlVal::Group;
default:
return 0;
return WMCtrlVal::WMCtlUnk;
}
}
else if (well.isProducer(sim_step)) {
@@ -221,31 +228,33 @@ namespace {
using CMode = ::Opm::WellProducer::ControlModeEnum;
switch (prop.controlMode) {
case CMode::ORAT: return 1;
case CMode::WRAT: return 2;
case CMode::GRAT: return 3;
case CMode::LRAT: return 4;
case CMode::RESV: return 5;
case CMode::THP: return 6;
case CMode::BHP: return 7;
case CMode::CRAT: return 9;
case CMode::GRUP: return -1;
case CMode::ORAT: return WMCtrlVal::OilRate;
case CMode::WRAT: return WMCtrlVal::WatRate;
case CMode::GRAT: return WMCtrlVal::GasRate;
case CMode::LRAT: return WMCtrlVal::LiqRate;
case CMode::RESV: return WMCtrlVal::ResVRate;
case CMode::THP: return WMCtrlVal::THP;
case CMode::BHP: return WMCtrlVal::BHP;
case CMode::CRAT: return WMCtrlVal::CombRate;
case CMode::GRUP: return WMCtrlVal::Group;
default: return 0;
default: return WMCtrlVal::WMCtlUnk;
}
}
return 0;
return WMCtrlVal::WMCtlUnk;
}
int compOrder(const Opm::Well& well)
{
using WCO = ::Opm::WellCompletion::CompletionOrderEnum;
using WCO = ::Opm::WellCompletion::CompletionOrderEnum;
using COVal = ::Opm::RestartIO::Helpers::
VectorItems::IWell::Value::CompOrder;
switch (well.getWellConnectionOrdering()) {
case WCO::TRACK: return 0;
case WCO::DEPTH: return 1; // Not really supported in Flow
case WCO::INPUT: return 2;
case WCO::TRACK: return COVal::Track;
case WCO::DEPTH: return COVal::Depth;
case WCO::INPUT: return COVal::Input;
}
return 0;
@@ -259,65 +268,67 @@ namespace {
const std::size_t sim_step,
IWellArray& iWell)
{
iWell[1 - 1] = well.getHeadI(sim_step) + 1;
iWell[2 - 1] = well.getHeadJ(sim_step) + 1;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::IWell::index;
iWell[Ix::IHead] = well.getHeadI(sim_step) + 1;
iWell[Ix::JHead] = well.getHeadJ(sim_step) + 1;
// Connections
{
const auto& conn = well.getConnections(sim_step);
// IWEL(5) = Number of active cells connected to well.
iWell[5 - 1] = static_cast<int>(conn.size());
// IWEL(3) = Layer ID of top connection.
iWell[3 - 1] = (iWell[5 - 1] == 0)
iWell[Ix::NConn] = static_cast<int>(conn.size());
iWell[Ix::FirstK] = (iWell[Ix::NConn] == 0)
? 0 : conn.get(0).getK() + 1;
// IWEL(4) = Layer ID of last connection.
iWell[4 - 1] = (iWell[5 - 1] == 0)
iWell[Ix::LastK] = (iWell[Ix::NConn] == 0)
? 0 : conn.get(conn.size() - 1).getK() + 1;
}
iWell[ 6 - 1] =
iWell[Ix::Group] =
groupIndex(trim(well.getGroupName(sim_step)),
groupNames, maxGroups);
iWell[ 7 - 1] = wellType (well, sim_step);
iWell[ 8 - 1] = ctrlMode (well, sim_step);
iWell[12 - 1] = wellVFPTab(well, sim_step);
iWell[Ix::WType] = wellType (well, sim_step);
iWell[Ix::WCtrl] = ctrlMode (well, sim_step);
iWell[Ix::VFPTab] = wellVFPTab(well, sim_step);
// The following items aren't fully characterised yet, but
// needed for restart of M2. Will need further refinement.
iWell[18 - 1] = -100;
iWell[25 - 1] = - 1;
iWell[32 - 1] = 7;
iWell[48 - 1] = - 1;
iWell[Ix::item18] = -100;
iWell[Ix::item25] = - 1;
iWell[Ix::item32] = 7;
iWell[Ix::item48] = - 1;
iWell[50 - 1] = iWell[8 - 1]; // Copy of ctrl mode.
iWell[Ix::item50] = iWell[Ix::WCtrl];
// Multi-segmented well information
iWell[71 - 1] = 0; // MS Well ID (0 or 1..#MS wells)
iWell[72 - 1] = 0; // Number of well segments
iWell[Ix::MsWID] = 0; // MS Well ID (0 or 1..#MS wells)
iWell[Ix::NWseg] = 0; // Number of well segments
if (well.isMultiSegment(sim_step)) {
iWell[71 - 1] = static_cast<int>(msWellID);
iWell[72 - 1] =
iWell[Ix::MsWID] = static_cast<int>(msWellID);
iWell[Ix::NWseg] =
well.getWellSegments(sim_step).size();
}
iWell[99 - 1] = compOrder(well);
iWell[Ix::CompOrd] = compOrder(well);
}
template <class IWellArray>
void dynamicContribShut(IWellArray& iWell)
{
iWell[ 9 - 1] = -1000;
iWell[11 - 1] = -1000;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::IWell::index;
iWell[Ix::item9 ] = -1000;
iWell[Ix::item11] = -1000;
}
template <class IWellArray>
void dynamicContribOpen(const Opm::data::Well& xw,
IWellArray& iWell)
{
using Ix = ::Opm::RestartIO::Helpers::VectorItems::IWell::index;
const auto any_flowing_conn =
std::any_of(std::begin(xw.connections),
std::end (xw.connections),
@@ -326,8 +337,10 @@ namespace {
return c.rates.any();
});
iWell[ 9 - 1] = any_flowing_conn ? iWell[8 - 1] : -1;
iWell[11 - 1] = 1;
iWell[Ix::item9] = any_flowing_conn
? iWell[Ix::WCtrl] : -1;
iWell[Ix::item11] = 1;
}
} // IWell
@@ -421,6 +434,7 @@ namespace {
const std::size_t sim_step,
SWellArray& sWell)
{
using Ix = ::Opm::RestartIO::Helpers::VectorItems::SWell::index;
using M = ::Opm::UnitSystem::measure;
auto swprop = [&units](const M u, const double x) -> float
@@ -436,31 +450,38 @@ namespace {
using PP = ::Opm::WellProducer::ControlModeEnum;
if (pp.hasProductionControl(PP::ORAT)) {
sWell[1 - 1] = swprop(M::liquid_surface_rate, pp.OilRate);
sWell[Ix::OilRateTarget] =
swprop(M::liquid_surface_rate, pp.OilRate);
}
if (pp.hasProductionControl(PP::WRAT)) {
sWell[2 - 1] = swprop(M::liquid_surface_rate, pp.WaterRate);
sWell[Ix::WatRateTarget] =
swprop(M::liquid_surface_rate, pp.WaterRate);
}
if (pp.hasProductionControl(PP::GRAT)) {
sWell[3 - 1] = swprop(M::gas_surface_rate, pp.GasRate);
sWell[Ix::GasRateTarget] =
swprop(M::gas_surface_rate, pp.GasRate);
}
if (pp.hasProductionControl(PP::LRAT)) {
sWell[4 - 1] = swprop(M::liquid_surface_rate, pp.LiquidRate);
sWell[Ix::LiqRateTarget] =
swprop(M::liquid_surface_rate, pp.LiquidRate);
}
if (pp.hasProductionControl(PP::RESV)) {
sWell[5 - 1] = swprop(M::rate, pp.ResVRate);
sWell[Ix::ResVRateTarget] =
swprop(M::rate, pp.ResVRate);
}
if (pp.hasProductionControl(PP::THP)) {
sWell[6 - 1] = swprop(M::pressure, pp.THPLimit);
sWell[Ix::THPTarget] =
swprop(M::pressure, pp.THPLimit);
}
if (pp.hasProductionControl(PP::BHP)) {
sWell[7 - 1] = swprop(M::pressure, pp.BHPLimit);
sWell[Ix::BHPTarget] =
swprop(M::pressure, pp.BHPLimit);
}
}
else if (well.isInjector(sim_step)) {
@@ -469,15 +490,16 @@ namespace {
using IP = ::Opm::WellInjector::ControlModeEnum;
if (ip.hasInjectionControl(IP::THP)) {
sWell[6 - 1] = swprop(M::pressure, ip.THPLimit);
sWell[Ix::THPTarget] = swprop(M::pressure, ip.THPLimit);
}
if (ip.hasInjectionControl(IP::BHP)) {
sWell[7 - 1] = swprop(M::pressure, ip.BHPLimit);
sWell[Ix::BHPTarget] = swprop(M::pressure, ip.BHPLimit);
}
}
sWell[10 - 1] = swprop(M::length, datumDepth(well, sim_step));
sWell[Ix::DatumDepth] =
swprop(M::length, datumDepth(well, sim_step));
}
} // SWell
@@ -507,15 +529,14 @@ namespace {
const std::size_t sim_step,
XWellArray& xWell)
{
using M = ::Opm::UnitSystem::measure;
using M = ::Opm::UnitSystem::measure;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
// xWell[41] = BHP target.
xWell[41] = well.isInjector(sim_step)
const auto bhpTarget = well.isInjector(sim_step)
? well.getInjectionProperties (sim_step).BHPLimit
: well.getProductionProperties(sim_step).BHPLimit;
xWell[41] = units.from_si(M::pressure, xWell[41]);
xWell[Ix::BHPTarget] = units.from_si(M::pressure, bhpTarget);
}
template <class XWellArray>
@@ -523,28 +544,34 @@ namespace {
const ::Opm::SummaryState& smry,
XWellArray& xWell)
{
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
auto get = [&smry, &well](const std::string& vector)
{
return smry.get(vector + ':' + well);
};
xWell[0] = get("WOPR");
xWell[1] = get("WWPR");
xWell[2] = get("WGPR");
xWell[3] = xWell[0] + xWell[1]; // LPR
xWell[4] = get("WVPR");
xWell[Ix::OilPrRate] = get("WOPR");
xWell[Ix::WatPrRate] = get("WWPR");
xWell[Ix::GasPrRate] = get("WGPR");
xWell[6] = get("WBHP");
xWell[7] = get("WWCT");
xWell[8] = get("WGOR");
xWell[Ix::LiqPrRate] = xWell[Ix::OilPrRate]
+ xWell[Ix::WatPrRate];
xWell[18] = get("WOPT");
xWell[19] = get("WWPT");
xWell[20] = get("WGPT");
xWell[21] = get("WVPT");
xWell[Ix::VoidPrRate] = get("WVPR");
xWell[36] = xWell[1]; // Copy of WWPR
xWell[37] = xWell[2]; // Copy of WGPR
xWell[Ix::FlowBHP] = get("WBHP");
xWell[Ix::WatCut] = get("WWCT");
xWell[Ix::GORatio] = get("WGOR");
xWell[Ix::OilPrTotal] = get("WOPT");
xWell[Ix::WatPrTotal] = get("WWPT");
xWell[Ix::GasPrTotal] = get("WGPT");
xWell[Ix::VoidPrTotal] = get("WVPT");
// Not fully characterised.
xWell[Ix::item37] = xWell[Ix::WatPrRate];
xWell[Ix::item38] = xWell[Ix::GasPrRate];
}
template <class XWellArray>
@@ -552,23 +579,26 @@ namespace {
const ::Opm::SummaryState& smry,
XWellArray& xWell)
{
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
auto get = [&smry, &well](const std::string& vector)
{
return smry.get(vector + ':' + well);
};
// Rates reported as negative, cumulative totals as positive.
xWell[1] = -get("WWIR");
xWell[3] = xWell[1]; // Copy of WWIR
// Injection rates reported as negative, cumulative
// totals as positive.
xWell[Ix::WatPrRate] = -get("WWIR");
xWell[Ix::LiqPrRate] = xWell[Ix::WatPrRate];
xWell[6] = get("WBHP");
xWell[Ix::FlowBHP] = get("WBHP");
xWell[23] = get("WWIT");
xWell[Ix::WatInjTotal] = get("WWIT");
xWell[36] = xWell[1]; // Copy of WWIR
xWell[81] = xWell[23]; // Copy of WWIT
xWell[Ix::item37] = xWell[Ix::WatPrRate];
xWell[Ix::item82] = xWell[Ix::WatInjTotal];
xWell[122] = -get("WWVIR");
xWell[Ix::WatVoidPrRate] = -get("WWVIR");
}
template <class XWellArray>
@@ -576,26 +606,30 @@ namespace {
const ::Opm::SummaryState& smry,
XWellArray& xWell)
{
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
auto get = [&smry, &well](const std::string& vector)
{
return smry.get(vector + ':' + well);
};
// Rates reported as negative, cumulative totals as positive.
xWell[2] = -get("WGIR");
xWell[4] = -get("WGVIR");
// Injection rates reported as negative production rates,
// cumulative injection totals as positive.
xWell[Ix::GasPrRate] = -get("WGIR");
xWell[Ix::VoidPrRate] = -get("WGVIR");
xWell[6] = get("WBHP");
xWell[Ix::FlowBHP] = get("WBHP");
xWell[24] = get("WGIT");
xWell[Ix::GasInjTotal] = get("WGIT");
xWell[34] = xWell[4] / xWell[2]; // Bg
xWell[Ix::GasFVF] = xWell[Ix::VoidPrRate]
/ xWell[Ix::GasPrRate];
xWell[37] = xWell[2]; // Copy of WGIR
// Not fully characterised.
xWell[Ix::item38] = xWell[Ix::GasPrRate];
xWell[Ix::item83] = xWell[Ix::GasInjTotal];
xWell[82] = xWell[24]; // Copy of WGIT
xWell[123] = xWell[4]; // Copy of WGVIR
xWell[Ix::GasVoidPrRate] = xWell[Ix::VoidPrRate];
}
template <class XWellArray>
@@ -662,7 +696,9 @@ namespace {
template <class ZWellArray>
void staticContrib(const Opm::Well& well, ZWellArray& zWell)
{
zWell[1 - 1] = well.name();
using Ix = ::Opm::RestartIO::Helpers::VectorItems::ZWell::index;
zWell[Ix::WellName] = well.name();
}
} // ZWell
} // Anonymous
+176 -122
View File
@@ -25,6 +25,9 @@
#include <opm/output/eclipse/SummaryState.hpp>
#include <opm/output/eclipse/VectorItems/intehead.hpp>
#include <opm/output/eclipse/VectorItems/well.hpp>
#include <opm/output/data/Wells.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
@@ -63,11 +66,13 @@ MockIH::MockIH(const int numWells,
const int zwelPerWell)
: value(411, 0)
{
this->nwells = this->value[17 - 1] = numWells;
this->niwelz = this->value[25 - 1] = iwelPerWell;
this->nswelz = this->value[26 - 1] = swelPerWell;
this->nxwelz = this->value[27 - 1] = xwelPerWell;
this->nzwelz = this->value[28 - 1] = zwelPerWell;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::intehead;
this->nwells = this->value[Ix::NWELLS] = numWells;
this->niwelz = this->value[Ix::NIWELZ] = iwelPerWell;
this->nswelz = this->value[Ix::NSWELZ] = swelPerWell;
this->nxwelz = this->value[Ix::NXWELZ] = xwelPerWell;
this->nzwelz = this->value[Ix::NZWELZ] = zwelPerWell;
}
namespace {
@@ -371,107 +376,123 @@ BOOST_AUTO_TEST_CASE (Declared_Well_Data)
// IWEL (OP_1)
{
using Ix = ::Opm::RestartIO::Helpers::VectorItems::IWell::index;
const auto start = 0*ih.niwelz;
const auto& iwell = awd.getIWell();
BOOST_CHECK_EQUAL(iwell[start + 0], 9); // OP_1 -> I
BOOST_CHECK_EQUAL(iwell[start + 1], 9); // OP_1 -> J
BOOST_CHECK_EQUAL(iwell[start + 2], 1); // OP_1/Head -> K
BOOST_CHECK_EQUAL(iwell[start + 4], 2); // OP_1 #Compl
BOOST_CHECK_EQUAL(iwell[start + 6], 1); // OP_1 -> Producer
BOOST_CHECK_EQUAL(iwell[start + 11], 0); // VFP defaulted -> 0
BOOST_CHECK_EQUAL(iwell[start + Ix::IHead] , 9); // OP_1 -> I
BOOST_CHECK_EQUAL(iwell[start + Ix::JHead] , 9); // OP_1 -> J
BOOST_CHECK_EQUAL(iwell[start + Ix::FirstK], 1); // OP_1/Head -> K
BOOST_CHECK_EQUAL(iwell[start + Ix::NConn] , 2); // OP_1 #Compl
BOOST_CHECK_EQUAL(iwell[start + Ix::WType] , 1); // OP_1 -> Producer
BOOST_CHECK_EQUAL(iwell[start + Ix::VFPTab], 0); // VFP defaulted -> 0
// Completion order
BOOST_CHECK_EQUAL(iwell[start + 98], 0); // Track ordering (default)
BOOST_CHECK_EQUAL(iwell[start + Ix::CompOrd], 0); // Track ordering (default)
BOOST_CHECK_EQUAL(iwell[start + 17], -100); // M2 Magic
BOOST_CHECK_EQUAL(iwell[start + 24], - 1); // M2 Magic
BOOST_CHECK_EQUAL(iwell[start + 47], - 1); // M2 Magic
BOOST_CHECK_EQUAL(iwell[start + 31], 7); // M2 Magic
BOOST_CHECK_EQUAL(iwell[start + Ix::item18], -100); // M2 Magic
BOOST_CHECK_EQUAL(iwell[start + Ix::item25], - 1); // M2 Magic
BOOST_CHECK_EQUAL(iwell[start + Ix::item48], - 1); // M2 Magic
BOOST_CHECK_EQUAL(iwell[start + Ix::item32], 7); // M2 Magic
}
// IWEL (OP_2)
{
using Ix = ::Opm::RestartIO::Helpers::VectorItems::IWell::index;
const auto start = 1*ih.niwelz;
const auto& iwell = awd.getIWell();
BOOST_CHECK_EQUAL(iwell[start + 0], 9); // OP_2 -> I
BOOST_CHECK_EQUAL(iwell[start + 1], 9); // OP_2 -> J
BOOST_CHECK_EQUAL(iwell[start + 2], 2); // OP_2/Head -> K
BOOST_CHECK_EQUAL(iwell[start + 4], 1); // OP_2 #Compl
BOOST_CHECK_EQUAL(iwell[start + 6], 4); // OP_2 -> Gas Inj.
BOOST_CHECK_EQUAL(iwell[start + 11], 0); // VFP defaulted -> 0
BOOST_CHECK_EQUAL(iwell[start + Ix::IHead] , 9); // OP_2 -> I
BOOST_CHECK_EQUAL(iwell[start + Ix::JHead] , 9); // OP_2 -> J
BOOST_CHECK_EQUAL(iwell[start + Ix::FirstK], 2); // OP_2/Head -> K
BOOST_CHECK_EQUAL(iwell[start + Ix::NConn] , 1); // OP_2 #Compl
BOOST_CHECK_EQUAL(iwell[start + Ix::WType] , 4); // OP_2 -> Gas Inj.
BOOST_CHECK_EQUAL(iwell[start + Ix::VFPTab], 0); // VFP defaulted -> 0
// Completion order
BOOST_CHECK_EQUAL(iwell[start + 98], 0); // Track ordering (default)
BOOST_CHECK_EQUAL(iwell[start + Ix::CompOrd], 0); // Track ordering (default)
BOOST_CHECK_EQUAL(iwell[start + 17], -100); // M2 Magic
BOOST_CHECK_EQUAL(iwell[start + 24], - 1); // M2 Magic
BOOST_CHECK_EQUAL(iwell[start + 47], - 1); // M2 Magic
BOOST_CHECK_EQUAL(iwell[start + 31], 7); // M2 Magic
BOOST_CHECK_EQUAL(iwell[start + Ix::item18], -100); // M2 Magic
BOOST_CHECK_EQUAL(iwell[start + Ix::item25], - 1); // M2 Magic
BOOST_CHECK_EQUAL(iwell[start + Ix::item48], - 1); // M2 Magic
BOOST_CHECK_EQUAL(iwell[start + Ix::item32], 7); // M2 Magic
}
// SWEL (OP_1)
{
const auto start = 0*ih.nswelz;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::SWell::index;
const auto i0 = 0*ih.nswelz;
const auto& swell = awd.getSWell();
BOOST_CHECK_CLOSE(swell[start + 0], 20.0e3f, 1.0e-7f); // ORAT Target
BOOST_CHECK_CLOSE(swell[start + 1], 1.0e20f, 1.0e-7f); // WRAT Limit
BOOST_CHECK_CLOSE(swell[start + 2], 1.0e20f, 1.0e-7f); // GRAT Limit
BOOST_CHECK_CLOSE(swell[start + 3], 1.0e20f, 1.0e-7f); // LRAT Limit
BOOST_CHECK_CLOSE(swell[start + 4], 1.0e20f, 1.0e-7f); // RESV Limit
BOOST_CHECK_CLOSE(swell[start + 5], 1.0e20f, 1.0e-7f); // THP Limit
BOOST_CHECK_CLOSE(swell[start + 6], 1000.0f, 1.0e-7f); // BHP Limit
BOOST_CHECK_CLOSE(swell[i0 + Ix::OilRateTarget] , 20.0e3f, 1.0e-7f);
BOOST_CHECK_CLOSE(swell[i0 + Ix::WatRateTarget] , 1.0e20f, 1.0e-7f);
BOOST_CHECK_CLOSE(swell[i0 + Ix::GasRateTarget] , 1.0e20f, 1.0e-7f);
BOOST_CHECK_CLOSE(swell[i0 + Ix::LiqRateTarget] , 1.0e20f, 1.0e-7f);
BOOST_CHECK_CLOSE(swell[i0 + Ix::ResVRateTarget], 1.0e20f, 1.0e-7f);
BOOST_CHECK_CLOSE(swell[i0 + Ix::THPTarget] , 1.0e20f, 1.0e-7f);
BOOST_CHECK_CLOSE(swell[i0 + Ix::BHPTarget] , 1000.0f, 1.0e-7f);
BOOST_CHECK_CLOSE(swell[start + 9], 0.375f, 1.0e-7f); // Datum depth
BOOST_CHECK_CLOSE(swell[i0 + Ix::DatumDepth] , 0.375f, 1.0e-7f);
}
// SWEL (OP_2)
{
const auto start = 1*ih.nswelz;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::SWell::index;
const auto i1 = 1*ih.nswelz;
const auto& swell = awd.getSWell();
BOOST_CHECK_CLOSE(swell[start + 5], 1.0e20f, 1.0e-7f); // THP Limit
BOOST_CHECK_CLOSE(swell[start + 6], 400.0f, 1.0e-7f); // BHP Limit
BOOST_CHECK_CLOSE(swell[i1 + Ix::THPTarget], 1.0e20f, 1.0e-7f);
BOOST_CHECK_CLOSE(swell[i1 + Ix::BHPTarget], 400.0f, 1.0e-7f);
BOOST_CHECK_CLOSE(swell[start + 9], 0.625f, 1.0e-7f); // Datum depth
BOOST_CHECK_CLOSE(swell[i1 + Ix::DatumDepth], 0.625f, 1.0e-7f);
}
// XWEL (OP_1)
{
const auto start = 0*ih.nxwelz;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
const auto i0 = 0*ih.nxwelz;
const auto& xwell = awd.getXWell();
BOOST_CHECK_CLOSE(xwell[start + 41], 1000.0, 1.0e-10); // BHP Limit
BOOST_CHECK_CLOSE(xwell[i0 + Ix::BHPTarget], 1000.0, 1.0e-10);
}
// XWEL (OP_2)
{
const auto start = 1*ih.nxwelz;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
const auto i1 = 1*ih.nxwelz;
const auto& xwell = awd.getXWell();
BOOST_CHECK_CLOSE(xwell[start + 41], 400.0, 1.0e-10); // BHP Limit
BOOST_CHECK_CLOSE(xwell[i1 + Ix::BHPTarget], 400.0, 1.0e-10);
}
// ZWEL (OP_1)
{
const auto start = 0*ih.nzwelz;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::ZWell::index;
const auto i0 = 0*ih.nzwelz;
const auto& zwell = awd.getZWell();
BOOST_CHECK_EQUAL(zwell[start + 0].c_str(), "OP_1 ");
BOOST_CHECK_EQUAL(zwell[i0 + Ix::WellName].c_str(), "OP_1 ");
}
// ZWEL (OP_2)
{
const auto start = 1*ih.nzwelz;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::ZWell::index;
const auto i1 = 1*ih.nzwelz;
const auto& zwell = awd.getZWell();
BOOST_CHECK_EQUAL(zwell[start + 0].c_str(), "OP_2 ");
BOOST_CHECK_EQUAL(zwell[i1 + Ix::WellName].c_str(), "OP_2 ");
}
}
@@ -496,65 +517,78 @@ BOOST_AUTO_TEST_CASE (Dynamic_Well_Data_Step1)
// IWEL (OP_1)
{
const auto start = 0*ih.niwelz;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::IWell::index;
const auto i0 = 0*ih.niwelz;
const auto& iwell = awd.getIWell();
BOOST_CHECK_EQUAL(iwell[start + 8], iwell[start + 7]); // Control mode
BOOST_CHECK_EQUAL(iwell[start + 10], 1); // Well open/shut flag
BOOST_CHECK_EQUAL(iwell[i0 + Ix::item9 ], iwell[i0 + Ix::WCtrl]);
BOOST_CHECK_EQUAL(iwell[i0 + Ix::item11], 1);
}
// IWEL (OP_2)
{
const auto start = 1*ih.niwelz;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::IWell::index;
const auto i1 = 1*ih.niwelz;
const auto& iwell = awd.getIWell();
BOOST_CHECK_EQUAL(iwell[start + 8], -1); // No flowing conns.
BOOST_CHECK_EQUAL(iwell[start + 10], 1); // Well open/shut flag
BOOST_CHECK_EQUAL(iwell[i1 + Ix::item9 ], -1); // No flowing conns.
BOOST_CHECK_EQUAL(iwell[i1 + Ix::item11], 1); // Well open/shut flag
}
// XWEL (OP_1)
{
const auto start = 0*ih.nxwelz;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
const auto i0 = 0*ih.nxwelz;
const auto& xwell = awd.getXWell();
BOOST_CHECK_CLOSE(xwell[start + 0], 1.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 1], 2.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 2], 3.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 3], 1.0 + 2.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 4], 4.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::OilPrRate], 1.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::WatPrRate], 2.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::GasPrRate], 3.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::LiqPrRate], 1.0 + 2.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::VoidPrRate], 4.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 6], 314.15, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 7], 0.625, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 8], 234.5, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::FlowBHP], 314.15, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::WatCut] , 0.625, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::GORatio], 234.5, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 18], 10.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 19], 20.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 20], 30.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 21], 40.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::OilPrTotal], 10.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::WatPrTotal], 20.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::GasPrTotal], 30.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::VoidPrTotal], 40.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 36], xwell[start + 1], 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 37], xwell[start + 2], 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::item37], xwell[i0 + Ix::WatPrRate], 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::item38], xwell[i0 + Ix::GasPrRate], 1.0e-10);
}
// XWEL (OP_2)
{
const auto start = 1*ih.nxwelz;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
const auto i1 = 1*ih.nxwelz;
const auto& xwell = awd.getXWell();
BOOST_CHECK_CLOSE(xwell[start + 2], -200.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 4], -1234.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 6], 400.6, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::GasPrRate], -200.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::VoidPrRate], -1234.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::FlowBHP], 400.6, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 24], 2000.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::GasInjTotal], 2000.0, 1.0e-10);
// Bg = VGIR / GIR = 1234.0 / 200.0
BOOST_CHECK_CLOSE(xwell[start + 34], 6.17, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::GasFVF], 6.17, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 37], xwell[start + 2], 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 82], xwell[start + 24], 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 123], xwell[start + 4], 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::item38],
xwell[i1 + Ix::GasPrRate], 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::item83],
xwell[i1 + Ix::GasInjTotal], 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::GasVoidPrRate],
xwell[i1 + Ix::VoidPrRate], 1.0e-10);
}
}
@@ -579,97 +613,117 @@ BOOST_AUTO_TEST_CASE (Dynamic_Well_Data_Step2)
// IWEL (OP_1) -- closed producer
{
const auto start = 0*ih.niwelz;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::IWell::index;
const auto i0 = 0*ih.niwelz;
const auto& iwell = awd.getIWell();
BOOST_CHECK_EQUAL(iwell[start + 8], -1000); // Control mode
BOOST_CHECK_EQUAL(iwell[start + 10], -1000); // Well open/shut flag
BOOST_CHECK_EQUAL(iwell[i0 + Ix::item9] , -1000);
BOOST_CHECK_EQUAL(iwell[i0 + Ix::item11], -1000);
}
// IWEL (OP_2) -- water injector
{
const auto start = 1*ih.niwelz;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::IWell::index;
const auto i1 = 1*ih.niwelz;
const auto& iwell = awd.getIWell();
BOOST_CHECK_EQUAL(iwell[start + 8], iwell[start + 7]); // Control mode
BOOST_CHECK_EQUAL(iwell[start + 10], 1); // Well open/shut flag
BOOST_CHECK_EQUAL(iwell[i1 + Ix::item9],
iwell[i1 + Ix::WCtrl]);
BOOST_CHECK_EQUAL(iwell[i1 + Ix::item11], 1);
}
// XWEL (OP_1) -- closed producer
{
const auto start = 0*ih.nxwelz;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
const auto i0 = 0*ih.nxwelz;
const auto& xwell = awd.getXWell();
BOOST_CHECK_CLOSE(xwell[start + 0], 1.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 1], 2.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 2], 3.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 3], 1.0 + 2.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 4], 4.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::OilPrRate], 1.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::WatPrRate], 2.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::GasPrRate], 3.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::LiqPrRate], 1.0 + 2.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::VoidPrRate], 4.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 6], 314.15, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 7], 0.625, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 8], 234.5, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::FlowBHP], 314.15, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::WatCut] , 0.625, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::GORatio], 234.5, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 18], 10.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 19], 20.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 20], 30.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 21], 40.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::OilPrTotal], 10.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::WatPrTotal], 20.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::GasPrTotal], 30.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::VoidPrTotal], 40.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 36], xwell[start + 1], 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 37], xwell[start + 2], 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::item37],
xwell[i0 + Ix::WatPrRate], 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i0 + Ix::item38],
xwell[i0 + Ix::GasPrRate], 1.0e-10);
}
// XWEL (OP_2) -- water injector
{
const auto start = 1*ih.nxwelz;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
const auto i1 = 1*ih.nxwelz;
const auto& xwell = awd.getXWell();
BOOST_CHECK_CLOSE(xwell[start + 1], -100.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::WatPrRate], -100.0, 1.0e-10);
// Copy of WWIR
BOOST_CHECK_CLOSE(xwell[start + 3], xwell[start + 1], 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::LiqPrRate],
xwell[i1 + Ix::WatPrRate], 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 6], 400.6, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::FlowBHP], 400.6, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 23], 1000.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::WatInjTotal], 1000.0, 1.0e-10);
// Copy of WWIR
BOOST_CHECK_CLOSE(xwell[start + 36], xwell[start + 1], 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::item37],
xwell[i1 + Ix::WatPrRate], 1.0e-10);
// Copy of WWIT
BOOST_CHECK_CLOSE(xwell[start + 81], xwell[start + 23], 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::item82],
xwell[i1 + Ix::WatInjTotal], 1.0e-10);
// WWVIR
BOOST_CHECK_CLOSE(xwell[start + 122], -4321.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i1 + Ix::WatVoidPrRate],
-4321.0, 1.0e-10);
}
// XWEL (OP_3) -- producer
{
const auto start = 2*ih.nxwelz;
using Ix = ::Opm::RestartIO::Helpers::VectorItems::XWell::index;
const auto i2 = 2*ih.nxwelz;
const auto& xwell = awd.getXWell();
BOOST_CHECK_CLOSE(xwell[start + 0], 11.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 1], 12.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 2], 13.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 3], 11.0 + 12.0, 1.0e-10); // LPR
BOOST_CHECK_CLOSE(xwell[start + 4], 14.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::OilPrRate], 11.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::WatPrRate], 12.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::GasPrRate], 13.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::LiqPrRate], 11.0 + 12.0, 1.0e-10); // LPR
BOOST_CHECK_CLOSE(xwell[i2 + Ix::VoidPrRate], 14.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 6], 314.15, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 7], 0.0625, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 8], 1234.5, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::FlowBHP], 314.15, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::WatCut] , 0.0625, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::GORatio], 1234.5, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 18], 110.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 19], 120.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 20], 130.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[start + 21], 140.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::OilPrTotal], 110.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::WatPrTotal], 120.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::GasPrTotal], 130.0, 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::VoidPrTotal], 140.0, 1.0e-10);
// Copy of WWPR
BOOST_CHECK_CLOSE(xwell[start + 36], xwell[start + 1], 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::item37],
xwell[i2 + Ix::WatPrRate], 1.0e-10);
// Copy of WGPR
BOOST_CHECK_CLOSE(xwell[start + 37], xwell[start + 2], 1.0e-10);
BOOST_CHECK_CLOSE(xwell[i2 + Ix::item38],
xwell[i2 + Ix::GasPrRate], 1.0e-10);
}
}
+56 -49
View File
@@ -23,6 +23,8 @@
#include <opm/output/eclipse/InteHEAD.hpp>
#include <opm/output/eclipse/VectorItems/intehead.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
@@ -36,6 +38,8 @@
#include <string>
#include <vector>
namespace VI = ::Opm::RestartIO::Helpers::VectorItems;
namespace {
std::vector<double> elapsedTime(const Opm::TimeMap& tmap)
{
@@ -79,21 +83,21 @@ BOOST_AUTO_TEST_CASE(Dimensions_Individual)
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[ 9 - 1], 100); // Nx
BOOST_CHECK_EQUAL(v[10 - 1], 60); // Ny
BOOST_CHECK_EQUAL(v[11 - 1], 15); // Nz
BOOST_CHECK_EQUAL(v[VI::intehead::NX], 100);
BOOST_CHECK_EQUAL(v[VI::intehead::NY], 60);
BOOST_CHECK_EQUAL(v[VI::intehead::NZ], 15);
}
BOOST_AUTO_TEST_CASE(Dimensions_Array)
{
const auto ih = Opm::RestartIO::InteHEAD{}
.dimensions({100, 60, 15});
.dimensions({ {100, 60, 15} });
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[ 9 - 1], 100); // Nx
BOOST_CHECK_EQUAL(v[10 - 1], 60); // Ny
BOOST_CHECK_EQUAL(v[11 - 1], 15); // Nz
BOOST_CHECK_EQUAL(v[VI::intehead::NX], 100);
BOOST_CHECK_EQUAL(v[VI::intehead::NY], 60);
BOOST_CHECK_EQUAL(v[VI::intehead::NZ], 15);
}
BOOST_AUTO_TEST_CASE(NumActive)
@@ -103,7 +107,7 @@ BOOST_AUTO_TEST_CASE(NumActive)
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[12 - 1], 72390); // NACTIVE
BOOST_CHECK_EQUAL(v[VI::intehead::NACTIV], 72390);
}
BOOST_AUTO_TEST_CASE(UnitConventions)
@@ -118,7 +122,7 @@ BOOST_AUTO_TEST_CASE(UnitConventions)
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[3 - 1], 1); // Unit
BOOST_CHECK_EQUAL(v[VI::intehead::UNIT], 1);
}
// Field
@@ -127,7 +131,7 @@ BOOST_AUTO_TEST_CASE(UnitConventions)
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[3 - 1], 2); // Unit
BOOST_CHECK_EQUAL(v[VI::intehead::UNIT], 2);
}
// Lab
@@ -136,7 +140,7 @@ BOOST_AUTO_TEST_CASE(UnitConventions)
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[3 - 1], 3); // Unit
BOOST_CHECK_EQUAL(v[VI::intehead::UNIT], 3);
}
// PVT-M
@@ -145,7 +149,7 @@ BOOST_AUTO_TEST_CASE(UnitConventions)
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[3 - 1], 4); // Unit
BOOST_CHECK_EQUAL(v[VI::intehead::UNIT], 4);
}
}
@@ -164,10 +168,10 @@ BOOST_AUTO_TEST_CASE(WellTableDimensions)
const auto& v = ih.data();
const auto nwgmax = std::max(maxWellInGroup, maxGroupInField);
BOOST_CHECK_EQUAL(v[17 - 1], numWells); // NWELLS
BOOST_CHECK_EQUAL(v[18 - 1], maxPerf); // NCWMAX
BOOST_CHECK_EQUAL(v[20 - 1], nwgmax); // NWGMAX
BOOST_CHECK_EQUAL(v[21 - 1], maxGroupInField + 1); // NGMAXZ
BOOST_CHECK_EQUAL(v[VI::intehead::NWELLS], numWells);
BOOST_CHECK_EQUAL(v[VI::intehead::NCWMAX], maxPerf);
BOOST_CHECK_EQUAL(v[VI::intehead::NWGMAX], nwgmax);
BOOST_CHECK_EQUAL(v[VI::intehead::NGMAXZ], maxGroupInField + 1);
}
BOOST_AUTO_TEST_CASE(CalendarDate)
@@ -201,7 +205,7 @@ BOOST_AUTO_TEST_CASE(ActivePhases)
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[15 - 1], 1);
BOOST_CHECK_EQUAL(v[VI::intehead::PHASE], 1);
}
// Water
@@ -210,7 +214,7 @@ BOOST_AUTO_TEST_CASE(ActivePhases)
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[15 - 1], 2);
BOOST_CHECK_EQUAL(v[VI::intehead::PHASE], 2);
}
// Gas
@@ -219,7 +223,7 @@ BOOST_AUTO_TEST_CASE(ActivePhases)
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[15 - 1], 4);
BOOST_CHECK_EQUAL(v[VI::intehead::PHASE], 4);
}
// Oil/Water
@@ -228,7 +232,7 @@ BOOST_AUTO_TEST_CASE(ActivePhases)
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[15 - 1], 3);
BOOST_CHECK_EQUAL(v[VI::intehead::PHASE], 3);
}
// Oil/Gas
@@ -237,7 +241,7 @@ BOOST_AUTO_TEST_CASE(ActivePhases)
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[15 - 1], 5);
BOOST_CHECK_EQUAL(v[VI::intehead::PHASE], 5);
}
// Water/Gas
@@ -246,7 +250,7 @@ BOOST_AUTO_TEST_CASE(ActivePhases)
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[15 - 1], 6);
BOOST_CHECK_EQUAL(v[VI::intehead::PHASE], 6);
}
// Oil/Water/Gas
@@ -255,7 +259,7 @@ BOOST_AUTO_TEST_CASE(ActivePhases)
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[15 - 1], 7);
BOOST_CHECK_EQUAL(v[VI::intehead::PHASE], 7);
}
}
@@ -266,10 +270,10 @@ BOOST_AUTO_TEST_CASE(NWell_Parameters)
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[25 - 1], 27); // NIWELZ
BOOST_CHECK_EQUAL(v[26 - 1], 18); // NSWELZ
BOOST_CHECK_EQUAL(v[27 - 1], 28); // NXWELZ
BOOST_CHECK_EQUAL(v[28 - 1], 1); // NZWELZ
BOOST_CHECK_EQUAL(v[VI::intehead::NIWELZ], 27);
BOOST_CHECK_EQUAL(v[VI::intehead::NSWELZ], 18);
BOOST_CHECK_EQUAL(v[VI::intehead::NXWELZ], 28);
BOOST_CHECK_EQUAL(v[VI::intehead::NZWELZ], 1);
}
BOOST_AUTO_TEST_CASE(NConn_Parameters)
@@ -279,22 +283,25 @@ BOOST_AUTO_TEST_CASE(NConn_Parameters)
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[33 - 1], 31); // NICONZ
BOOST_CHECK_EQUAL(v[34 - 1], 41); // NSCONZ
BOOST_CHECK_EQUAL(v[35 - 1], 59); // NXCONZ
BOOST_CHECK_EQUAL(v[VI::intehead::NICONZ], 31);
BOOST_CHECK_EQUAL(v[VI::intehead::NSCONZ], 41);
BOOST_CHECK_EQUAL(v[VI::intehead::NXCONZ], 59);
}
BOOST_AUTO_TEST_CASE(GroupSize_Parameters)
{
// https://oeis.org/A001620
const auto ih = Opm::RestartIO::InteHEAD{}
.params_GRPZ({ 577, 215, 664, 901 }); // https://oeis.org/A001620
.params_GRPZ({
{ 577, 215, 664, 901 }
});
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[37 - 1], 577); // NIGRPZ
BOOST_CHECK_EQUAL(v[38 - 1], 215); // NSGRPZ
BOOST_CHECK_EQUAL(v[39 - 1], 664); // NXGRPZ
BOOST_CHECK_EQUAL(v[40 - 1], 901); // NZGRPZ
BOOST_CHECK_EQUAL(v[VI::intehead::NIGRPZ], 577);
BOOST_CHECK_EQUAL(v[VI::intehead::NSGRPZ], 215);
BOOST_CHECK_EQUAL(v[VI::intehead::NXGRPZ], 664);
BOOST_CHECK_EQUAL(v[VI::intehead::NZGRPZ], 901);
}
BOOST_AUTO_TEST_CASE(Analytic_Aquifer_Parameters)
@@ -305,13 +312,13 @@ BOOST_AUTO_TEST_CASE(Analytic_Aquifer_Parameters)
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[42 - 1], 1); // NCAMAX
BOOST_CHECK_EQUAL(v[43 - 1], 61); // NIAAQZ
BOOST_CHECK_EQUAL(v[44 - 1], 803); // NSAAQZ
BOOST_CHECK_EQUAL(v[45 - 1], 3988); // NXAAQZ
BOOST_CHECK_EQUAL(v[46 - 1], 74989); // NICAQZ
BOOST_CHECK_EQUAL(v[47 - 1], 484820); // NSCAQZ
BOOST_CHECK_EQUAL(v[48 - 1], 4586834); // NACAQZ
BOOST_CHECK_EQUAL(v[VI::intehead::NCAMAX], 1);
BOOST_CHECK_EQUAL(v[VI::intehead::NIAAQZ], 61);
BOOST_CHECK_EQUAL(v[VI::intehead::NSAAQZ], 803);
BOOST_CHECK_EQUAL(v[VI::intehead::NXAAQZ], 3988);
BOOST_CHECK_EQUAL(v[VI::intehead::NICAQZ], 74989);
BOOST_CHECK_EQUAL(v[VI::intehead::NSCAQZ], 484820);
BOOST_CHECK_EQUAL(v[VI::intehead::NACAQZ], 4586834);
}
BOOST_AUTO_TEST_CASE(Time_and_report_step)
@@ -380,13 +387,13 @@ BOOST_AUTO_TEST_CASE(wellSegDimensions)
const auto& v = ih.data();
BOOST_CHECK_EQUAL(v[174], nsegwl);
BOOST_CHECK_EQUAL(v[175], nswlmx);
BOOST_CHECK_EQUAL(v[176], nsegmx);
BOOST_CHECK_EQUAL(v[177], nlbrmx);
BOOST_CHECK_EQUAL(v[178], nisegz);
BOOST_CHECK_EQUAL(v[179], nrsegz);
BOOST_CHECK_EQUAL(v[180], nilbrz);
BOOST_CHECK_EQUAL(v[VI::intehead::NSEGWL], nsegwl);
BOOST_CHECK_EQUAL(v[VI::intehead::NSWLMX], nswlmx);
BOOST_CHECK_EQUAL(v[VI::intehead::NSEGMX], nsegmx);
BOOST_CHECK_EQUAL(v[VI::intehead::NLBRMX], nlbrmx);
BOOST_CHECK_EQUAL(v[VI::intehead::NISEGZ], nisegz);
BOOST_CHECK_EQUAL(v[VI::intehead::NRSEGZ], nrsegz);
BOOST_CHECK_EQUAL(v[VI::intehead::NILBRZ], nilbrz);
}
BOOST_AUTO_TEST_CASE(regionDimensions)