Merge pull request #1446 from bska/currctrl-restart-support
Add Restart Infrastructure for Well's Active Control
This commit is contained in:
@@ -30,6 +30,8 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
namespace data {
|
||||
@@ -167,6 +169,31 @@ namespace Opm {
|
||||
void read(MessageBufferType& buffer);
|
||||
};
|
||||
|
||||
struct CurrentControl {
|
||||
bool isProducer{true};
|
||||
|
||||
::Opm::Well::ProducerCMode prod {
|
||||
::Opm::Well::ProducerCMode::CMODE_UNDEFINED
|
||||
};
|
||||
|
||||
::Opm::Well::InjectorCMode inj {
|
||||
::Opm::Well::InjectorCMode::CMODE_UNDEFINED
|
||||
};
|
||||
|
||||
bool operator==(const CurrentControl& rhs) const
|
||||
{
|
||||
return (this->isProducer == rhs.isProducer)
|
||||
&& ((this->isProducer && (this->prod == rhs.prod)) ||
|
||||
(!this->isProducer && (this->inj == rhs.inj)));
|
||||
}
|
||||
|
||||
template <class MessageBufferType>
|
||||
void write(MessageBufferType& buffer) const;
|
||||
|
||||
template <class MessageBufferType>
|
||||
void read(MessageBufferType& buffer);
|
||||
};
|
||||
|
||||
struct Well {
|
||||
Rates rates;
|
||||
double bhp;
|
||||
@@ -175,6 +202,8 @@ namespace Opm {
|
||||
int control;
|
||||
std::vector< Connection > connections;
|
||||
std::unordered_map<std::size_t, Segment> segments;
|
||||
CurrentControl current_control;
|
||||
|
||||
inline bool flowing() const noexcept;
|
||||
template <class MessageBufferType>
|
||||
void write(MessageBufferType& buffer) const;
|
||||
@@ -189,7 +218,8 @@ namespace Opm {
|
||||
temperature == well2.temperature &&
|
||||
control == well2.control &&
|
||||
connections == well2.connections &&
|
||||
segments == well2.segments;
|
||||
segments == well2.segments &&
|
||||
current_control == well2.current_control;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -401,6 +431,18 @@ namespace Opm {
|
||||
buffer.write(this->pressure);
|
||||
}
|
||||
|
||||
template <class MessageBufferType>
|
||||
void CurrentControl::write(MessageBufferType& buffer) const
|
||||
{
|
||||
buffer.write(this->isProducer);
|
||||
if (this->isProducer) {
|
||||
buffer.write(this->prod);
|
||||
}
|
||||
else {
|
||||
buffer.write(this->inj);
|
||||
}
|
||||
}
|
||||
|
||||
template <class MessageBufferType>
|
||||
void Well::write(MessageBufferType& buffer) const {
|
||||
this->rates.write(buffer);
|
||||
@@ -422,6 +464,8 @@ namespace Opm {
|
||||
seg.second.write(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
this->current_control.write(buffer);
|
||||
}
|
||||
|
||||
template <class MessageBufferType>
|
||||
@@ -465,6 +509,18 @@ namespace Opm {
|
||||
buffer.read(this->pressure);
|
||||
}
|
||||
|
||||
template <class MessageBufferType>
|
||||
void CurrentControl::read(MessageBufferType& buffer)
|
||||
{
|
||||
buffer.read(this->isProducer);
|
||||
if (this->isProducer) {
|
||||
buffer.read(this->prod);
|
||||
}
|
||||
else {
|
||||
buffer.read(this->inj);
|
||||
}
|
||||
}
|
||||
|
||||
template <class MessageBufferType>
|
||||
void Well::read(MessageBufferType& buffer) {
|
||||
this->rates.read(buffer);
|
||||
@@ -499,6 +555,8 @@ namespace Opm {
|
||||
const auto segNumber = seg.segNumber;
|
||||
this->segments.emplace(segNumber, std::move(seg));
|
||||
}
|
||||
|
||||
this->current_control.read(buffer);
|
||||
}
|
||||
|
||||
}} // Opm::data
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
Copyright 2019-2020 Equinor ASA
|
||||
Copyright 2018 Statoil ASA
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
@@ -77,20 +78,14 @@ namespace {
|
||||
// Remove leading/trailing blanks.
|
||||
return s.substr(b, e - b + 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename WellOp>
|
||||
void wellLoop(const std::vector<Opm::Well>& wells,
|
||||
WellOp&& wellOp)
|
||||
WellOp&& wellOp)
|
||||
{
|
||||
for (auto nWell = wells.size(), wellID = 0*nWell;
|
||||
wellID < nWell; ++wellID)
|
||||
{
|
||||
const auto& well = wells[wellID];
|
||||
|
||||
wellOp(well, wellID);
|
||||
auto wellID = 0*wells.size();
|
||||
for (const auto& well : wells) {
|
||||
wellOp(well, wellID++);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +137,7 @@ namespace {
|
||||
|
||||
int wellType(const Opm::Well& well, const Opm::SummaryState& st)
|
||||
{
|
||||
using WTypeVal = ::Opm::RestartIO::Helpers::VectorItems::IWell::Value::WellType;
|
||||
using WTypeVal = VI::IWell::Value::WellType;
|
||||
|
||||
if (well.isProducer()) {
|
||||
return WTypeVal::Producer;
|
||||
@@ -170,7 +165,7 @@ namespace {
|
||||
|
||||
int ctrlMode(const Opm::Well& well, const Opm::SummaryState& st)
|
||||
{
|
||||
using WMCtrlVal = ::Opm::RestartIO::Helpers::VectorItems::IWell::Value::WellCtrlMode;
|
||||
using WMCtrlVal = VI::IWell::Value::WellCtrlMode;
|
||||
|
||||
if (well.isInjector()) {
|
||||
const auto& controls = well.injectionControls(st);
|
||||
@@ -243,6 +238,71 @@ namespace {
|
||||
return WMCtrlVal::WMCtlUnk;
|
||||
}
|
||||
|
||||
bool wellControlDefined(const Opm::data::Well& xw)
|
||||
{
|
||||
using PMode = ::Opm::Well::ProducerCMode;
|
||||
using IMode = ::Opm::Well::InjectorCMode;
|
||||
|
||||
const auto& curr = xw.current_control;
|
||||
|
||||
return (curr.isProducer && (curr.prod != PMode::CMODE_UNDEFINED))
|
||||
|| (!curr.isProducer && (curr.inj != IMode::CMODE_UNDEFINED));
|
||||
}
|
||||
|
||||
int ctrlMode(const Opm::Well& well, const Opm::data::Well& xw)
|
||||
{
|
||||
using PMode = ::Opm::Well::ProducerCMode;
|
||||
using IMode = ::Opm::Well::InjectorCMode;
|
||||
using Val = VI::IWell::Value::WellCtrlMode;
|
||||
|
||||
const auto& curr = xw.current_control;
|
||||
|
||||
if (curr.isProducer) {
|
||||
switch (curr.prod) {
|
||||
case PMode::ORAT: return Val::OilRate;
|
||||
case PMode::WRAT: return Val::WatRate;
|
||||
case PMode::GRAT: return Val::GasRate;
|
||||
case PMode::LRAT: return Val::LiqRate;
|
||||
case PMode::RESV: return Val::ResVRate;
|
||||
case PMode::THP: return Val::THP;
|
||||
case PMode::BHP: return Val::BHP;
|
||||
case PMode::CRAT: return Val::CombRate;
|
||||
case PMode::GRUP: return Val::Group;
|
||||
|
||||
default:
|
||||
if (well.getStatus() == ::Opm::Well::Status::SHUT) {
|
||||
return Val::Shut;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // injector
|
||||
using IType = ::Opm::Well::InjectorType;
|
||||
|
||||
switch (curr.inj) {
|
||||
case IMode::RATE: {
|
||||
switch (well.injectorType()) {
|
||||
case IType::OIL: return Val::OilRate;
|
||||
case IType::WATER: return Val::WatRate;
|
||||
case IType::GAS: return Val::GasRate;
|
||||
case IType::MULTI: return Val::WMCtlUnk;
|
||||
}}
|
||||
break;
|
||||
|
||||
case IMode::RESV: return Val::ResVRate;
|
||||
case IMode::THP: return Val::THP;
|
||||
case IMode::BHP: return Val::BHP;
|
||||
case IMode::GRUP: return Val::Group;
|
||||
|
||||
default:
|
||||
if (well.getStatus() == ::Opm::Well::Status::SHUT) {
|
||||
return Val::Shut;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Val::WMCtlUnk;
|
||||
}
|
||||
|
||||
int compOrder(const Opm::Well& well)
|
||||
{
|
||||
using WCO = ::Opm::Connection::Order;
|
||||
@@ -258,14 +318,37 @@ namespace {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename IWellArray>
|
||||
void setCurrentControl(const Opm::Well& well,
|
||||
const int curr,
|
||||
IWellArray& iWell)
|
||||
{
|
||||
using Ix = VI::IWell::index;
|
||||
|
||||
iWell[Ix::ActWCtrl] = curr;
|
||||
|
||||
if (well.predictionMode()) {
|
||||
// Well in prediction mode (WCONPROD, WCONINJE). Assign
|
||||
// requested control mode for prediction.
|
||||
iWell[Ix::PredReqWCtrl] = curr;
|
||||
iWell[Ix::HistReqWCtrl] = 0;
|
||||
}
|
||||
else {
|
||||
// Well controlled by observed rates/BHP (WCONHIST,
|
||||
// WCONINJH). Assign requested control mode for history.
|
||||
iWell[Ix::PredReqWCtrl] = 0; // Possibly =1 instead.
|
||||
iWell[Ix::HistReqWCtrl] = curr;
|
||||
}
|
||||
}
|
||||
|
||||
template <class IWellArray>
|
||||
void staticContrib(const Opm::Well& well,
|
||||
void staticContrib(const Opm::Well& well,
|
||||
const Opm::SummaryState& st,
|
||||
const std::size_t msWellID,
|
||||
const std::map <const std::string, size_t>& GroupMapNameInd,
|
||||
IWellArray& iWell)
|
||||
{
|
||||
using Ix = ::Opm::RestartIO::Helpers::VectorItems::IWell::index;
|
||||
using Ix = VI::IWell::index;
|
||||
|
||||
iWell[Ix::IHead] = well.getHeadI() + 1;
|
||||
iWell[Ix::JHead] = well.getHeadJ() + 1;
|
||||
@@ -309,28 +392,14 @@ namespace {
|
||||
// the target control mode requested in the simulation deck.
|
||||
// This item is supposed to be the well's actual, active target
|
||||
// control mode in the simulator.
|
||||
iWell[Ix::ActWCtrl] = ctrlMode(well, st);
|
||||
|
||||
if (well.predictionMode()) {
|
||||
// Well in prediction mode (WCONPROD, WCONINJE). Assign
|
||||
// requested control mode for prediction.
|
||||
iWell[Ix::PredReqWCtrl] = iWell[Ix::ActWCtrl];
|
||||
iWell[Ix::HistReqWCtrl] = 0;
|
||||
}
|
||||
else {
|
||||
// Well controlled by observed rates/BHP (WCONHIST,
|
||||
// WCONINJH). Assign requested control mode for history.
|
||||
iWell[Ix::PredReqWCtrl] = 0; // Possibly =1 instead.
|
||||
iWell[Ix::HistReqWCtrl] = iWell[Ix::ActWCtrl];
|
||||
}
|
||||
setCurrentControl(well, ctrlMode(well, st), iWell);
|
||||
|
||||
// Multi-segmented well information
|
||||
iWell[Ix::MsWID] = 0; // MS Well ID (0 or 1..#MS wells)
|
||||
iWell[Ix::NWseg] = 0; // Number of well segments
|
||||
if (well.isMultiSegment()) {
|
||||
iWell[Ix::MsWID] = static_cast<int>(msWellID);
|
||||
iWell[Ix::NWseg] =
|
||||
well.getSegments().size();
|
||||
iWell[Ix::NWseg] = well.getSegments().size();
|
||||
}
|
||||
|
||||
iWell[Ix::CompOrd] = compOrder(well);
|
||||
@@ -339,17 +408,22 @@ namespace {
|
||||
template <class IWellArray>
|
||||
void dynamicContribShut(IWellArray& iWell)
|
||||
{
|
||||
using Ix = ::Opm::RestartIO::Helpers::VectorItems::IWell::index;
|
||||
using Ix = VI::IWell::index;
|
||||
|
||||
iWell[Ix::item9 ] = -1000;
|
||||
iWell[Ix::item11] = -1000;
|
||||
}
|
||||
|
||||
template <class IWellArray>
|
||||
void dynamicContribOpen(const Opm::data::Well& xw,
|
||||
void dynamicContribOpen(const Opm::Well& well,
|
||||
const Opm::data::Well& xw,
|
||||
IWellArray& iWell)
|
||||
{
|
||||
using Ix = ::Opm::RestartIO::Helpers::VectorItems::IWell::index;
|
||||
using Ix = VI::IWell::index;
|
||||
|
||||
if (wellControlDefined(xw)) {
|
||||
setCurrentControl(well, ctrlMode(well, xw), iWell);
|
||||
}
|
||||
|
||||
const auto any_flowing_conn =
|
||||
std::any_of(std::begin(xw.connections),
|
||||
@@ -415,11 +489,11 @@ namespace {
|
||||
zero , zero , infty, infty, zero , dflt , // 12.. 17 ( 2)
|
||||
infty, infty, infty, infty, infty, zero , // 18.. 23 ( 3)
|
||||
one , zero , zero , zero , zero , zero , // 24.. 29 ( 4)
|
||||
zero , one , zero , infty, zero , zero , // 30.. 35 ( 5)
|
||||
zero , one , zero , infty, zero , zero , // 30.. 35 ( 5)
|
||||
zero , zero , zero , zero , zero , zero , // 36.. 41 ( 6)
|
||||
zero , zero , zero , zero , zero , zero , // 42.. 47 ( 7)
|
||||
zero , zero , zero , zero , zero , zero , // 48.. 53 ( 8)
|
||||
infty, zero , zero , zero , zero , zero , // 54.. 59 ( 9)
|
||||
infty, zero , zero , zero , zero , zero , // 54.. 59 ( 9)
|
||||
zero , zero , zero , zero , zero , zero , // 60.. 65 (10)
|
||||
zero , zero , zero , zero , zero , zero , // 66.. 71 (11)
|
||||
zero , zero , zero , zero , zero , zero , // 72.. 77 (12)
|
||||
@@ -856,7 +930,7 @@ captureDeclaredWellData(const Schedule& sched,
|
||||
});
|
||||
|
||||
{
|
||||
const auto actResStat = ZWell::act_res_stat(sched, smry, sim_step);
|
||||
const auto actResStat = ZWell::act_res_stat(sched, smry, sim_step);
|
||||
// Static contributions to ZWEL array.
|
||||
wellLoop(wells,
|
||||
[&actResStat, this](const Well& well, const std::size_t wellID) -> void
|
||||
@@ -889,7 +963,7 @@ captureDynamicWellData(const Schedule& sched,
|
||||
IWell::dynamicContribShut(iWell);
|
||||
}
|
||||
else {
|
||||
IWell::dynamicContribOpen(i->second, iWell);
|
||||
IWell::dynamicContribOpen(well, i->second, iWell);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
namespace VI = ::Opm::RestartIO::Helpers::VectorItems;
|
||||
|
||||
namespace {
|
||||
@@ -1026,6 +1028,75 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
::Opm::Well::ProducerCMode producerControlMode(const int curr)
|
||||
{
|
||||
using PMode = ::Opm::Well::ProducerCMode;
|
||||
using Ctrl = VI::IWell::Value::WellCtrlMode;
|
||||
|
||||
switch (curr) {
|
||||
case Ctrl::OilRate: return PMode::ORAT;
|
||||
case Ctrl::WatRate: return PMode::WRAT;
|
||||
case Ctrl::GasRate: return PMode::GRAT;
|
||||
case Ctrl::LiqRate: return PMode::LRAT;
|
||||
case Ctrl::ResVRate: return PMode::RESV;
|
||||
case Ctrl::THP: return PMode::THP;
|
||||
case Ctrl::BHP: return PMode::BHP;
|
||||
case Ctrl::CombRate: return PMode::CRAT;
|
||||
case Ctrl::Group: return PMode::GRUP;
|
||||
|
||||
default:
|
||||
return PMode::CMODE_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
::Opm::Well::InjectorCMode
|
||||
injectorControlMode(const int curr, const int itype)
|
||||
{
|
||||
using IMode = ::Opm::Well::InjectorCMode;
|
||||
using WType = VI::IWell::Value::WellType;
|
||||
using Ctrl = VI::IWell::Value::WellCtrlMode;
|
||||
|
||||
switch (curr) {
|
||||
case Ctrl::OilRate:
|
||||
return (itype == WType::OilInj)
|
||||
? IMode::RATE : IMode::CMODE_UNDEFINED;
|
||||
|
||||
case Ctrl::WatRate:
|
||||
return (itype == WType::WatInj)
|
||||
? IMode::RATE : IMode::CMODE_UNDEFINED;
|
||||
|
||||
case Ctrl::GasRate:
|
||||
return (itype == WType::GasInj)
|
||||
? IMode::RATE : IMode::CMODE_UNDEFINED;
|
||||
|
||||
case Ctrl::ResVRate: return IMode::RESV;
|
||||
case Ctrl::THP: return IMode::THP;
|
||||
case Ctrl::BHP: return IMode::BHP;
|
||||
case Ctrl::Group: return IMode::GRUP;
|
||||
}
|
||||
|
||||
return IMode::CMODE_UNDEFINED;
|
||||
}
|
||||
|
||||
void restoreCurrentControl(const std::size_t wellID,
|
||||
const WellVectors& wellData,
|
||||
Opm::data::Well& xw)
|
||||
{
|
||||
const auto iwel = wellData.iwel(wellID);
|
||||
const auto act = iwel[VI::IWell::index::ActWCtrl];
|
||||
const auto wtyp = iwel[VI::IWell::index::WType];
|
||||
|
||||
auto& curr = xw.current_control;
|
||||
|
||||
curr.isProducer = wtyp == VI::IWell::Value::WellType::Producer;
|
||||
if (curr.isProducer) {
|
||||
curr.prod = producerControlMode(act);
|
||||
}
|
||||
else { // Assume injector
|
||||
curr.inj = injectorControlMode(act, wtyp);
|
||||
}
|
||||
}
|
||||
|
||||
void restoreSegmentQuantities(const std::size_t mswID,
|
||||
const Opm::WellSegments& segSet,
|
||||
const Opm::UnitSystem& usys,
|
||||
@@ -1085,7 +1156,7 @@ namespace {
|
||||
}
|
||||
|
||||
Opm::data::Well
|
||||
restore_well(const Opm::Well& well,
|
||||
restore_well(const Opm::Well& well,
|
||||
const std::size_t wellID,
|
||||
const Opm::EclipseGrid& grid,
|
||||
const Opm::UnitSystem& usys,
|
||||
@@ -1136,9 +1207,11 @@ namespace {
|
||||
// and pressure values (xw.connections[i].pressure).
|
||||
restoreConnResults(well, wellID, grid, usys, phases, wellData, xw);
|
||||
|
||||
// 4) Restore segment quantities if applicable.
|
||||
if (well.isMultiSegment() &&
|
||||
segData.hasDefinedValues())
|
||||
// 4) Restore well's active/current control
|
||||
restoreCurrentControl(wellID, wellData, xw);
|
||||
|
||||
// 5) Restore segment quantities if applicable.
|
||||
if (well.isMultiSegment() && segData.hasDefinedValues())
|
||||
{
|
||||
const auto iwel = wellData.iwel(wellID);
|
||||
const auto mswID = iwel[VI::IWell::index::MsWID]; // One-based
|
||||
|
||||
@@ -297,9 +297,10 @@ BOOST_AUTO_TEST_CASE(test_RFT)
|
||||
Opm::data::Wells wells;
|
||||
|
||||
using SegRes = decltype(wells["w"].segments);
|
||||
using Ctrl = decltype(wells["w"].current_control);
|
||||
|
||||
wells["OP_1"] = { std::move(r1), 1.0, 1.1, 3.1, 1, std::move(well1_comps), SegRes{} };
|
||||
wells["OP_2"] = { std::move(r2), 1.0, 1.1, 3.2, 1, std::move(well2_comps), SegRes{} };
|
||||
wells["OP_1"] = { std::move(r1), 1.0, 1.1, 3.1, 1, std::move(well1_comps), SegRes{}, Ctrl{} };
|
||||
wells["OP_2"] = { std::move(r2), 1.0, 1.1, 3.2, 1, std::move(well2_comps), SegRes{}, Ctrl{} };
|
||||
|
||||
RestartValue restart_value(std::move(solution), std::move(wells));
|
||||
|
||||
@@ -419,9 +420,10 @@ BOOST_AUTO_TEST_CASE(test_RFT2)
|
||||
Opm::data::Solution solution = createBlackoilState(2, numCells);
|
||||
|
||||
using SegRes = decltype(wells["w"].segments);
|
||||
using Ctrl = decltype(wells["w"].current_control);
|
||||
|
||||
wells["OP_1"] = { std::move(r1), 1.0, 1.1, 3.1, 1, std::move(well1_comps), SegRes{} };
|
||||
wells["OP_2"] = { std::move(r2), 1.0, 1.1, 3.2, 1, std::move(well2_comps), SegRes{} };
|
||||
wells["OP_1"] = { std::move(r1), 1.0, 1.1, 3.1, 1, std::move(well1_comps), SegRes{}, Ctrl{} };
|
||||
wells["OP_2"] = { std::move(r2), 1.0, 1.1, 3.2, 1, std::move(well2_comps), SegRes{}, Ctrl{} };
|
||||
|
||||
RestartValue restart_value(std::move(solution), std::move(wells));
|
||||
|
||||
|
||||
@@ -240,13 +240,23 @@ static data::Wells result_wells() {
|
||||
rates1, 0.1 * ps, 0.2 * ps, 0.3 * ps, 1,
|
||||
{ {well1_comp1} },
|
||||
{ { segment.segNumber, segment } },
|
||||
data::CurrentControl{}
|
||||
};
|
||||
well1.current_control.isProducer = false;
|
||||
well1.current_control.inj =::Opm::Well::InjectorCMode::BHP;
|
||||
|
||||
using SegRes = decltype(well1.segments);
|
||||
using Ctrl = data::CurrentControl;
|
||||
|
||||
data::Well well2 { rates2, 1.1 * ps, 1.2 * ps, 1.3 * ps, 2, { {well2_comp1 , well2_comp2} }, SegRes{} };
|
||||
data::Well well3 { rates3, 2.1 * ps, 2.2 * ps, 2.3 * ps, 3, { {well3_comp1} }, SegRes{} };
|
||||
data::Well well6 { rates6, 2.1 * ps, 2.2 * ps, 2.3 * ps, 3, { {well6_comp1} }, SegRes{} };
|
||||
data::Well well2 { rates2, 1.1 * ps, 1.2 * ps, 1.3 * ps, 2, { {well2_comp1 , well2_comp2} }, SegRes{}, Ctrl{} };
|
||||
well2.current_control.prod = ::Opm::Well::ProducerCMode::ORAT;
|
||||
|
||||
data::Well well3 { rates3, 2.1 * ps, 2.2 * ps, 2.3 * ps, 3, { {well3_comp1} }, SegRes{}, Ctrl{} };
|
||||
well2.current_control.prod = ::Opm::Well::ProducerCMode::RESV;
|
||||
|
||||
data::Well well6 { rates6, 2.1 * ps, 2.2 * ps, 2.3 * ps, 3, { {well6_comp1} }, SegRes{}, Ctrl{} };
|
||||
well6.current_control.isProducer = false;
|
||||
well6.current_control.inj = ::Opm::Well::InjectorCMode::GRUP;
|
||||
|
||||
data::Wells wellrates;
|
||||
|
||||
@@ -1490,6 +1500,12 @@ BOOST_AUTO_TEST_CASE(READ_WRITE_WELLDATA) {
|
||||
// No data for segment 10 of well W_2 (or no such segment).
|
||||
const auto& W2 = wellRatesCopy.at("W_2");
|
||||
BOOST_CHECK_THROW(W2.segments.at(10), std::out_of_range);
|
||||
|
||||
const auto& W6 = wellRatesCopy.at("W_6");
|
||||
const auto& curr = W6.current_control;
|
||||
BOOST_CHECK_MESSAGE(!curr.isProducer, "W_6 must be an injector");
|
||||
BOOST_CHECK_MESSAGE(curr.prod == ::Opm::Well::ProducerCMode::CMODE_UNDEFINED, "W_6 must have an undefined producer control");
|
||||
BOOST_CHECK_MESSAGE(curr.inj == ::Opm::Well::InjectorCMode::GRUP, "W_6 must be on GRUP control");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(efficiency_factor) {
|
||||
@@ -3123,7 +3139,6 @@ BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Reset_Cumulative_Vectors)
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SummaryState_TOTAL) {
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
st.update("FOPR", 100);
|
||||
|
||||
Reference in New Issue
Block a user