Merge pull request #3747 from akva2/fbhpdef
implement support for FBHPDEF
This commit is contained in:
commit
980ac2599a
@ -367,6 +367,7 @@ namespace Opm
|
||||
this->template pack_unpack<GasLiftOpt>(serializer);
|
||||
this->template pack_unpack<RFTConfig>(serializer);
|
||||
this->template pack_unpack<RSTConfig>(serializer);
|
||||
this->template pack_unpack<ScheduleState::BHPDefaults>(serializer);
|
||||
|
||||
this->template pack_unpack_map<int, VFPProdTable>(serializer);
|
||||
this->template pack_unpack_map<int, VFPInjTable>(serializer);
|
||||
@ -712,6 +713,7 @@ namespace Opm
|
||||
void handleDRVDT (HandlerContext&);
|
||||
void handleDRVDTR (HandlerContext&);
|
||||
void handleEXIT (HandlerContext&);
|
||||
void handleFBHPDEF (HandlerContext&);
|
||||
void handleGCONINJE (HandlerContext&);
|
||||
void handleGCONPROD (HandlerContext&);
|
||||
void handleGCONSALE (HandlerContext&);
|
||||
|
@ -279,7 +279,28 @@ namespace Opm {
|
||||
std::unordered_map<K, std::shared_ptr<T>> m_data;
|
||||
};
|
||||
|
||||
struct BHPDefaults {
|
||||
std::optional<double> prod_target;
|
||||
std::optional<double> inj_limit;
|
||||
|
||||
static BHPDefaults serializationTestObject()
|
||||
{
|
||||
return BHPDefaults{1.0, 2.0};
|
||||
}
|
||||
|
||||
bool operator==(const BHPDefaults& rhs) const
|
||||
{
|
||||
return this->prod_target == rhs.prod_target
|
||||
&& this->inj_limit == rhs.inj_limit;
|
||||
}
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(prod_target);
|
||||
serializer(inj_limit);
|
||||
}
|
||||
};
|
||||
|
||||
ScheduleState() = default;
|
||||
explicit ScheduleState(const time_point& start_time);
|
||||
@ -382,6 +403,8 @@ namespace Opm {
|
||||
ptr_member<RFTConfig> rft_config;
|
||||
ptr_member<RSTConfig> rst_config;
|
||||
|
||||
ptr_member<BHPDefaults> bhp_defaults;
|
||||
|
||||
template <typename T>
|
||||
ptr_member<T>& get() {
|
||||
return const_cast<ptr_member<T>&>(std::as_const(*this).template get<T>());
|
||||
@ -428,6 +451,8 @@ namespace Opm {
|
||||
return this->rft_config;
|
||||
else if constexpr ( std::is_same_v<T, RSTConfig> )
|
||||
return this->rst_config;
|
||||
else if constexpr ( std::is_same_v<T, BHPDefaults> )
|
||||
return this->bhp_defaults;
|
||||
else
|
||||
static_assert(always_false1::value, "Template type <T> not supported in get()");
|
||||
}
|
||||
|
@ -168,8 +168,29 @@ public:
|
||||
static WellInjectionProperties serializationTestObject();
|
||||
|
||||
void handleWELTARG(WELTARGCMode cmode, const UDAValue& new_arg, double SIFactorP);
|
||||
void handleWCONINJE(const DeckRecord& record, bool availableForGroupControl, const std::string& well_name);
|
||||
void handleWCONINJH(const DeckRecord& record, const bool is_producer, const std::string& well_name, const KeywordLocation& loc);
|
||||
|
||||
//! \brief Handle a WCONINJE keyword.
|
||||
//! \param record The deck record to use
|
||||
//! \param bhp_def The default BHP target in input units
|
||||
//! \param availableForGroupControl True if available for group control
|
||||
//! \param well_name Name of well
|
||||
void handleWCONINJE(const DeckRecord& record,
|
||||
const double bhp_def,
|
||||
bool availableForGroupControl,
|
||||
const std::string& well_name);
|
||||
|
||||
//! \brief Handle a WCONINJH keyword.
|
||||
//! \param record The deck record to use
|
||||
//! \param bhp_def The default BHP limit in SI units
|
||||
//! \param is_producer True if well is a producer
|
||||
//! \param well_name Name of well
|
||||
//! \param loc Location of keyword for logging purpuses
|
||||
void handleWCONINJH(const DeckRecord& record,
|
||||
const double bhp_def,
|
||||
const bool is_producer,
|
||||
const std::string& well_name,
|
||||
const KeywordLocation& loc);
|
||||
|
||||
bool hasInjectionControl(InjectorCMode controlModeArg) const {
|
||||
if (injectionControls & static_cast<int>(controlModeArg))
|
||||
return true;
|
||||
@ -240,6 +261,7 @@ public:
|
||||
// BHP and THP limit
|
||||
double bhp_hist_limit = 0.0;
|
||||
double thp_hist_limit = 0.0;
|
||||
bool bhp_hist_limit_defaulted = true; // Tracks whether value was defaulted or not
|
||||
|
||||
// historical BHP and THP under historical mode
|
||||
double BHPH = 0.0;
|
||||
@ -273,8 +295,28 @@ public:
|
||||
|
||||
// this is used to check whether the specified control mode is an effective history matching production mode
|
||||
static bool effectiveHistoryProductionControl(ProducerCMode cmode);
|
||||
void handleWCONPROD( const std::optional<VFPProdTable::ALQ_TYPE>& alq_type, const UnitSystem& unit_system, const std::string& well, const DeckRecord& record);
|
||||
void handleWCONHIST( const std::optional<VFPProdTable::ALQ_TYPE>& alq_type, const UnitSystem& unit_system, const DeckRecord& record);
|
||||
|
||||
//! \brief Handle WCONPROD keyword.
|
||||
//! \param alq_type ALQ type
|
||||
//! \param bhp_def Default BHP target in SI units
|
||||
//! \param unit_system Unit system to use
|
||||
//! \param well Well name
|
||||
//! \param record Deck record to use
|
||||
void handleWCONPROD(const std::optional<VFPProdTable::ALQ_TYPE>& alq_type,
|
||||
const double bhp_def,
|
||||
const UnitSystem& unit_system,
|
||||
const std::string& well,
|
||||
const DeckRecord& record);
|
||||
|
||||
//! \brief Handle WCONHIST keyword.
|
||||
//! \param alq_type ALQ type
|
||||
//! \param bhp_def Default BHP limit in SI units
|
||||
//! \param unit_system Unit system to use
|
||||
//! \param record Deck record to use
|
||||
void handleWCONHIST(const std::optional<VFPProdTable::ALQ_TYPE>& alq_type,
|
||||
const double bhp_def,
|
||||
const UnitSystem& unit_system,
|
||||
const DeckRecord& record);
|
||||
void handleWELTARG( WELTARGCMode cmode, const UDAValue& new_arg, double SiFactorP);
|
||||
void resetDefaultBHPLimit();
|
||||
void clearControls();
|
||||
|
@ -86,6 +86,7 @@
|
||||
#include <opm/input/eclipse/Parser/ParserKeywords/B.hpp>
|
||||
#include <opm/input/eclipse/Parser/ParserKeywords/C.hpp>
|
||||
#include <opm/input/eclipse/Parser/ParserKeywords/D.hpp>
|
||||
#include <opm/input/eclipse/Parser/ParserKeywords/F.hpp>
|
||||
#include <opm/input/eclipse/Parser/ParserKeywords/G.hpp>
|
||||
#include <opm/input/eclipse/Parser/ParserKeywords/L.hpp>
|
||||
#include <opm/input/eclipse/Parser/ParserKeywords/N.hpp>
|
||||
@ -465,6 +466,20 @@ File {} line {}.)", wname, location.keyword, location.filename, location.lineno)
|
||||
this->applyEXIT(handlerContext.keyword, handlerContext.currentStep);
|
||||
}
|
||||
|
||||
void Schedule::handleFBHPDEF(HandlerContext& handlerContext)
|
||||
{
|
||||
using FBHP = ParserKeywords::FBHPDEF;
|
||||
const auto& record = handlerContext.keyword.getRecord(0);
|
||||
ScheduleState::BHPDefaults bhp_defaults;
|
||||
const auto& prod_limit = record.getItem<FBHP::TARGET_BHP>();
|
||||
const auto& inj_limit = record.getItem<FBHP::LIMIT_BHP>();
|
||||
if (!(prod_limit.defaultApplied(0) && inj_limit.defaultApplied(0))) {
|
||||
bhp_defaults.prod_target = prod_limit.getSIDouble(0);
|
||||
bhp_defaults.inj_limit = inj_limit.getSIDouble(0);
|
||||
}
|
||||
this->snapshots.back().bhp_defaults.update(std::move(bhp_defaults));
|
||||
}
|
||||
|
||||
void Schedule::handleGCONINJE(HandlerContext& handlerContext) {
|
||||
using GI = ParserKeywords::GCONINJE;
|
||||
auto current_step = handlerContext.currentStep;
|
||||
@ -1300,10 +1315,22 @@ File {} line {}.)", wname, location.keyword, location.filename, location.lineno)
|
||||
throw OpmInputError(reason, handlerContext.keyword.location());
|
||||
}
|
||||
}
|
||||
properties->handleWCONHIST(alq_type, this->m_static.m_unit_system, record);
|
||||
double default_bhp;
|
||||
if (this->snapshots.back().bhp_defaults.get().prod_target) {
|
||||
default_bhp = *this->snapshots.back().bhp_defaults.get().prod_target;
|
||||
} else {
|
||||
default_bhp = UnitSystem::newMETRIC().to_si(UnitSystem::measure::pressure,
|
||||
ParserKeywords::FBHPDEF::TARGET_BHP::defaultValue);
|
||||
}
|
||||
|
||||
properties->handleWCONHIST(alq_type,
|
||||
default_bhp,
|
||||
this->m_static.m_unit_system, record);
|
||||
|
||||
if (switching_from_injector) {
|
||||
properties->resetDefaultBHPLimit();
|
||||
if (properties->bhp_hist_limit_defaulted) {
|
||||
properties->setBHPLimit(default_bhp);
|
||||
}
|
||||
|
||||
auto inj_props = std::make_shared<Well::WellInjectionProperties>(well2.getInjectionProperties());
|
||||
inj_props->resetBHPLimit();
|
||||
@ -1375,10 +1402,23 @@ File {} line {}.)", wname, location.keyword, location.filename, location.lineno)
|
||||
throw OpmInputError(reason, handlerContext.keyword.location());
|
||||
}
|
||||
}
|
||||
properties->handleWCONPROD(alq_type, this->m_static.m_unit_system, well_name, record);
|
||||
|
||||
double default_bhp_target;
|
||||
if (this->snapshots.back().bhp_defaults.get().prod_target) {
|
||||
default_bhp_target = *this->snapshots.back().bhp_defaults.get().prod_target;
|
||||
} else {
|
||||
default_bhp_target = UnitSystem::newMETRIC().to_si(UnitSystem::measure::pressure,
|
||||
ParserKeywords::WCONPROD::BHP::defaultValue.get<double>());
|
||||
}
|
||||
|
||||
properties->handleWCONPROD(alq_type, default_bhp_target,
|
||||
this->m_static.m_unit_system,
|
||||
well_name, record);
|
||||
|
||||
if (switching_from_injector) {
|
||||
properties->resetDefaultBHPLimit();
|
||||
if (properties->bhp_hist_limit_defaulted) {
|
||||
properties->setBHPLimit(default_bhp_target);
|
||||
}
|
||||
update_well = true;
|
||||
this->snapshots.back().wellgroup_events().addEvent( well2.name(), ScheduleEvents::WELL_SWITCHED_INJECTOR_PRODUCER);
|
||||
}
|
||||
@ -1428,7 +1468,21 @@ File {} line {}.)", wname, location.keyword, location.filename, location.lineno)
|
||||
|
||||
auto injection = std::make_shared<Well::WellInjectionProperties>(well2.getInjectionProperties());
|
||||
auto previousInjectorType = injection->injectorType;
|
||||
injection->handleWCONINJE(record, well2.isAvailableForGroupControl(), well_name);
|
||||
|
||||
double default_bhp_limit;
|
||||
if (this->snapshots.back().bhp_defaults.get().inj_limit) {
|
||||
default_bhp_limit = this->m_static.m_unit_system.from_si(UnitSystem::measure::pressure,
|
||||
*this->snapshots.back().bhp_defaults.get().inj_limit);
|
||||
} else {
|
||||
default_bhp_limit = UnitSystem::newMETRIC().to_si(UnitSystem::measure::pressure,
|
||||
ParserKeywords::WCONINJE::BHP::defaultValue.get<double>());
|
||||
default_bhp_limit = this->m_static.m_unit_system.from_si(UnitSystem::measure::pressure,
|
||||
default_bhp_limit);
|
||||
}
|
||||
|
||||
injection->handleWCONINJE(record, default_bhp_limit,
|
||||
well2.isAvailableForGroupControl(), well_name);
|
||||
|
||||
const bool switching_from_producer = well2.isProducer();
|
||||
if (well2.updateInjection(injection))
|
||||
update_well = true;
|
||||
@ -1497,9 +1551,20 @@ File {} line {}.)", wname, location.keyword, location.filename, location.lineno)
|
||||
auto well2 = this->snapshots.back().wells.get( well_name );
|
||||
auto injection = std::make_shared<Well::WellInjectionProperties>(well2.getInjectionProperties());
|
||||
auto previousInjectorType = injection->injectorType;
|
||||
injection->handleWCONINJH(record, well2.isProducer(), well_name, handlerContext.keyword.location());
|
||||
const bool switching_from_producer = well2.isProducer();
|
||||
|
||||
double default_bhp_limit;
|
||||
if (this->snapshots.back().bhp_defaults.get().inj_limit) {
|
||||
default_bhp_limit = *this->snapshots.back().bhp_defaults.get().inj_limit;
|
||||
} else {
|
||||
default_bhp_limit = UnitSystem::newMETRIC().to_si(UnitSystem::measure::pressure,
|
||||
6891.2);
|
||||
}
|
||||
|
||||
injection->handleWCONINJH(record, default_bhp_limit,
|
||||
well2.isProducer(), well_name,
|
||||
handlerContext.keyword.location());
|
||||
|
||||
const bool switching_from_producer = well2.isProducer();
|
||||
if (well2.updateInjection(injection))
|
||||
update_well = true;
|
||||
|
||||
@ -2789,6 +2854,7 @@ Well{0} entered with 'FIELD' parent group:
|
||||
{ "DRVDTR" , &Schedule::handleDRVDTR },
|
||||
{ "ENDBOX" , &Schedule::handleGEOKeyword},
|
||||
{ "EXIT", &Schedule::handleEXIT },
|
||||
{ "FBHPDEF", &Schedule::handleFBHPDEF },
|
||||
{ "GCONINJE", &Schedule::handleGCONINJE },
|
||||
{ "GCONPROD", &Schedule::handleGCONPROD },
|
||||
{ "GCONSALE", &Schedule::handleGCONSALE },
|
||||
|
@ -2427,6 +2427,7 @@ void Schedule::create_first(const time_point& start_time, const std::optional<ti
|
||||
sched_state.network_balance.update(Network::Balance{ runspec.networkDimensions().active() });
|
||||
sched_state.update_sumthin(this->m_static.sumthin);
|
||||
sched_state.rptonly(this->m_static.rptonly);
|
||||
sched_state.bhp_defaults.update( ScheduleState::BHPDefaults() );
|
||||
//sched_state.update_date( start_time );
|
||||
this->addGroup("FIELD", 0);
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include <opm/input/eclipse/Schedule/ScheduleState.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Parser/ParserKeywords/F.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Schedule/Action/Actions.hpp>
|
||||
#include <opm/input/eclipse/Schedule/GasLiftOpt.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Group/GConSale.hpp>
|
||||
@ -307,6 +309,7 @@ bool ScheduleState::operator==(const ScheduleState& other) const {
|
||||
this->guide_rate.get() == other.guide_rate.get() &&
|
||||
this->rft_config.get() == other.rft_config.get() &&
|
||||
this->udq.get() == other.udq.get() &&
|
||||
this->bhp_defaults.get() == other.bhp_defaults.get() &&
|
||||
this->wells == other.wells &&
|
||||
this->groups == other.groups &&
|
||||
this->vfpprod == other.vfpprod &&
|
||||
@ -338,6 +341,7 @@ ScheduleState ScheduleState::serializationTestObject() {
|
||||
ts.m_sumthin = 12.345;
|
||||
ts.m_rptonly = true;
|
||||
|
||||
ts.bhp_defaults.update( BHPDefaults::serializationTestObject() );
|
||||
ts.pavg.update( PAvg::serializationTestObject() );
|
||||
ts.wtest_config.update( WellTestConfig::serializationTestObject() );
|
||||
ts.gconsump.update( GConSump::serializationTestObject() );
|
||||
|
@ -427,8 +427,11 @@ Well::Well(const RestartIO::RstWell& rst_well,
|
||||
if (! i->predictionMode) {
|
||||
if (i->controlMode == Well::InjectorCMode::BHP)
|
||||
i->bhp_hist_limit = rst_well.hist_bhp_target;
|
||||
else
|
||||
else {
|
||||
// defaults (ie FBHPDEF) are not stored in the restart file.
|
||||
// we thus use an empirically obtained default value.
|
||||
i->resetDefaultHistoricalBHPLimit();
|
||||
}
|
||||
}
|
||||
else if (this->isAvailableForGroupControl())
|
||||
i->addInjectionControl(Well::InjectorCMode::GRUP);
|
||||
|
@ -85,7 +85,11 @@ namespace Opm {
|
||||
return result;
|
||||
}
|
||||
|
||||
void Well::WellInjectionProperties::handleWCONINJE(const DeckRecord& record, bool availableForGroupControl, const std::string& well_name) {
|
||||
void Well::WellInjectionProperties::handleWCONINJE(const DeckRecord& record,
|
||||
const double bhp_def,
|
||||
bool availableForGroupControl,
|
||||
const std::string& well_name)
|
||||
{
|
||||
this->injectorType = InjectorTypeFromString( record.getItem("TYPE").getTrimmedString(0) );
|
||||
this->predictionMode = true;
|
||||
|
||||
@ -118,7 +122,11 @@ namespace Opm {
|
||||
current behavoir agrees with the behavior of Eclipse when BHPLimit is not
|
||||
specified while employed during group control.
|
||||
*/
|
||||
this->BHPTarget = record.getItem("BHP").get<UDAValue>(0);
|
||||
if (record.getItem("BHP").defaultApplied(0)) {
|
||||
this->BHPTarget.update(bhp_def);
|
||||
} else {
|
||||
this->BHPTarget = record.getItem("BHP").get<UDAValue>(0);
|
||||
}
|
||||
this->addInjectionControl(InjectorCMode::BHP);
|
||||
|
||||
if (availableForGroupControl)
|
||||
@ -182,6 +190,7 @@ namespace Opm {
|
||||
|
||||
void
|
||||
Well::WellInjectionProperties::handleWCONINJH(const DeckRecord& record,
|
||||
const double bhp_def,
|
||||
const bool is_producer,
|
||||
const std::string& well_name,
|
||||
const KeywordLocation& loc)
|
||||
@ -232,7 +241,7 @@ namespace Opm {
|
||||
if (switching_from_prediction ||
|
||||
switching_from_BHP_control ||
|
||||
switching_from_producer) {
|
||||
this->resetDefaultHistoricalBHPLimit();
|
||||
this->bhp_hist_limit = bhp_def;
|
||||
}
|
||||
// otherwise, we keep its previous BHP limit
|
||||
}
|
||||
|
@ -160,13 +160,22 @@ namespace Opm {
|
||||
|
||||
|
||||
|
||||
void Well::WellProductionProperties::handleWCONPROD(const std::optional<VFPProdTable::ALQ_TYPE>& alq_type, const UnitSystem& unit_system_arg, const std::string& /* well */, const DeckRecord& record)
|
||||
void Well::WellProductionProperties::handleWCONPROD(const std::optional<VFPProdTable::ALQ_TYPE>& alq_type,
|
||||
const double bhp_def,
|
||||
const UnitSystem& unit_system_arg,
|
||||
const std::string& /* well */,
|
||||
const DeckRecord& record)
|
||||
{
|
||||
this->predictionMode = true;
|
||||
this->init_vfp(alq_type, unit_system_arg, record);
|
||||
this->init_rates(record);
|
||||
|
||||
this->BHPTarget = record.getItem("BHP").get<UDAValue>(0);
|
||||
if (record.getItem("BHP").defaultApplied(0)) {
|
||||
this->BHPTarget.update(unit_system_arg.from_si(UnitSystem::measure::pressure,
|
||||
bhp_def));
|
||||
} else {
|
||||
this->BHPTarget = record.getItem("BHP").get<UDAValue>(0);
|
||||
}
|
||||
this->THPTarget = record.getItem("THP").get<UDAValue>(0);
|
||||
this->LiquidRate = record.getItem("LRAT").get<UDAValue>(0);
|
||||
this->ResVRate = record.getItem("RESV").get<UDAValue>(0);
|
||||
@ -209,7 +218,10 @@ namespace Opm {
|
||||
originate from the WCONHIST keyword. Predictions are handled with the
|
||||
default constructor and the handleWCONPROD() method.
|
||||
*/
|
||||
void Well::WellProductionProperties::handleWCONHIST(const std::optional<VFPProdTable::ALQ_TYPE>& alq_type, const UnitSystem& unit_system_arg, const DeckRecord& record)
|
||||
void Well::WellProductionProperties::handleWCONHIST(const std::optional<VFPProdTable::ALQ_TYPE>& alq_type,
|
||||
const double bhp_def,
|
||||
const UnitSystem& unit_system_arg,
|
||||
const DeckRecord& record)
|
||||
{
|
||||
this->init_rates(record);
|
||||
this->init_vfp(alq_type, unit_system_arg, record);
|
||||
@ -220,11 +232,9 @@ void Well::WellProductionProperties::handleWCONHIST(const std::optional<VFPProdT
|
||||
// or switching from injector to producer
|
||||
// or switching from BHP control to RATE control (under history matching mode)
|
||||
// we use the defaulted BHP limit, otherwise, we use the previous BHP limit
|
||||
if (this->predictionMode)
|
||||
this->resetDefaultBHPLimit();
|
||||
|
||||
if (this->controlMode == ProducerCMode::BHP)
|
||||
this->resetDefaultBHPLimit();
|
||||
if (this->predictionMode || this->controlMode == ProducerCMode::BHP) {
|
||||
this->setBHPLimit(bhp_def);
|
||||
}
|
||||
|
||||
this->init_history(record);
|
||||
}
|
||||
@ -258,6 +268,7 @@ void Well::WellProductionProperties::handleWCONHIST(const std::optional<VFPProdT
|
||||
else
|
||||
this->bhp_hist_limit = new_arg.get<double>() * SiFactorP;
|
||||
this->addProductionControl( ProducerCMode::BHP );
|
||||
this->bhp_hist_limit_defaulted = false;
|
||||
}
|
||||
else if (cmode == WELTARGCMode::THP){
|
||||
this->THPTarget.update_value( new_arg );
|
||||
|
@ -8,12 +8,14 @@
|
||||
{
|
||||
"name": "TARGET_BHP",
|
||||
"value_type": "DOUBLE",
|
||||
"dimension": "Length"
|
||||
"dimension": "Pressure",
|
||||
"default": 1.01325
|
||||
},
|
||||
{
|
||||
"name": "LIMIT_BHP",
|
||||
"value_type": "DOUBLE",
|
||||
"dimension": "Pressure"
|
||||
"dimension": "Pressure",
|
||||
"default": 6895
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -47,6 +47,8 @@
|
||||
#include <opm/input/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/common/utility/TimeService.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Parser/ParserKeywords/F.hpp>
|
||||
|
||||
using namespace Opm;
|
||||
|
||||
namespace {
|
||||
@ -589,7 +591,9 @@ namespace {
|
||||
auto deck = parser.parseString(input);
|
||||
const auto& record = deck["WCONHIST"].back().getRecord(0);
|
||||
Opm::Well::WellProductionProperties hist(unit_system, "W");
|
||||
hist.handleWCONHIST(alq_type, unit_system, record);
|
||||
hist.handleWCONHIST(alq_type,
|
||||
Opm::ParserKeywords::FBHPDEF::TARGET_BHP::defaultValue * unit::barsa,
|
||||
unit_system, record);
|
||||
|
||||
|
||||
return hist;
|
||||
@ -642,7 +646,9 @@ namespace {
|
||||
const auto& kwd = deck["WCONPROD"].back();
|
||||
const auto& record = kwd.getRecord(0);
|
||||
Opm::Well::WellProductionProperties pred(unit_system, "W");
|
||||
pred.handleWCONPROD(alq_type, unit_system, "WELL", record);
|
||||
pred.handleWCONPROD(alq_type,
|
||||
Opm::ParserKeywords::FBHPDEF::TARGET_BHP::defaultValue * unit::barsa,
|
||||
unit_system, "WELL", record);
|
||||
|
||||
return pred;
|
||||
}
|
||||
@ -1870,3 +1876,91 @@ END
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(FBHPDEF_Basic)
|
||||
{
|
||||
const auto deck = Parser{}.parseString(R"(RUNSPEC
|
||||
DIMENS
|
||||
10 10 3 /
|
||||
GRID
|
||||
DXV
|
||||
10*100.0 /
|
||||
DYV
|
||||
10*100.0 /
|
||||
DZV
|
||||
3*5.0 /
|
||||
DEPTHZ
|
||||
121*2000 /
|
||||
PERMX
|
||||
300*100.0 /
|
||||
COPY
|
||||
PERMX PERMY /
|
||||
PERMX PERMZ /
|
||||
/
|
||||
MULTIPLY
|
||||
PERMZ 0.1 /
|
||||
/
|
||||
PORO
|
||||
300*0.3 /
|
||||
SCHEDULE
|
||||
|
||||
WELSPECS
|
||||
'P' 'G' 10 10 1* 'OIL' /
|
||||
'I' 'G' 1 1 1* 'GAS' /
|
||||
'I2' 'W' 1 1 1* 'WATER' /
|
||||
'I3' 'W' 1 1 1* 'WATER' /
|
||||
/
|
||||
COMPDAT
|
||||
'P' 10 10 1 3 'OPEN' /
|
||||
'I' 1 1 1 1 'OPEN' /
|
||||
'I2' 1 1 1 1 'OPEN' /
|
||||
'I3' 1 1 1 1 'OPEN' /
|
||||
/
|
||||
|
||||
WCONINJH
|
||||
I3 WATER OPEN 116281 1* 0 /
|
||||
/
|
||||
|
||||
FBHPDEF
|
||||
5.0 20.0 /
|
||||
|
||||
WCONPROD
|
||||
'P' 'OPEN' 'LRAT' 1* 1* 1* 1234.567 1* 1* /
|
||||
/
|
||||
|
||||
WCONINJH
|
||||
I2 WATER OPEN 116281 1* 0 /
|
||||
/
|
||||
|
||||
FBHPDEF
|
||||
2.0 30.0 /
|
||||
|
||||
WCONINJE
|
||||
'I' 'GAS' 'OPEN' 'RATE' 20.0E3 /
|
||||
/
|
||||
|
||||
TSTEP
|
||||
30.0 /
|
||||
WELSPECS
|
||||
'P' 'G1' /
|
||||
/
|
||||
TSTEP
|
||||
30.0 /
|
||||
END
|
||||
)");
|
||||
|
||||
const auto es = EclipseState { deck };
|
||||
const auto sched = Schedule { deck, es };
|
||||
|
||||
const auto& wellP = sched.getWell("P", 0);
|
||||
BOOST_CHECK_EQUAL(wellP.getProductionProperties().BHPTarget.get<double>(), 5.0);
|
||||
|
||||
const auto& wellI = sched.getWell("I", 0);
|
||||
BOOST_CHECK_CLOSE(wellI.getInjectionProperties().BHPTarget.get<double>(), 30.0, 1e-12);
|
||||
|
||||
const auto& wellI2 = sched.getWell("I2", 0);
|
||||
BOOST_CHECK_EQUAL(wellI2.getInjectionProperties().bhp_hist_limit, 20.0 * unit::barsa);
|
||||
|
||||
const auto& wellI3 = sched.getWell("I3", 0);
|
||||
BOOST_CHECK_CLOSE(wellI3.getInjectionProperties().bhp_hist_limit, 6891.2 * unit::barsa, 1e-12);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user