Pass VFP ALQ type to enable unit conversion for ALQ values
This commit is contained in:
@@ -44,6 +44,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellTracerProperties.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellPolymerProperties.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellEconProductionLimits.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp>
|
||||
#include <opm/parser/eclipse/Units/Units.hpp>
|
||||
|
||||
#include <opm/common/utility/ActiveGridCells.hpp>
|
||||
@@ -386,8 +387,8 @@ 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::string& well, const DeckRecord& record);
|
||||
void handleWCONHIST( const DeckRecord& record);
|
||||
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);
|
||||
void handleWELTARG( WELTARGCMode cmode, const UDAValue& new_arg, double SiFactorP);
|
||||
void resetDefaultBHPLimit();
|
||||
void clearControls();
|
||||
@@ -425,6 +426,7 @@ public:
|
||||
void init_rates( const DeckRecord& record );
|
||||
|
||||
void init_history(const DeckRecord& record);
|
||||
void init_vfp(const std::optional<VFPProdTable::ALQ_TYPE>& alq_type, const UnitSystem& unit_system, const DeckRecord& record);
|
||||
|
||||
WellProductionProperties(const DeckRecord& record);
|
||||
|
||||
|
||||
@@ -819,6 +819,7 @@ namespace {
|
||||
}
|
||||
|
||||
void Schedule::handleWCONHIST(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) {
|
||||
const auto& unit_system = handlerContext.section.unitSystem();
|
||||
for (const auto& record : handlerContext.keyword) {
|
||||
const std::string& wellNamePattern = record.getItem("WELL").getTrimmedString(0);
|
||||
const auto well_names = this->wellNames(wellNamePattern, handlerContext.currentStep);
|
||||
@@ -830,12 +831,17 @@ namespace {
|
||||
for (const auto& well_name : well_names) {
|
||||
updateWellStatus( well_name , handlerContext.currentStep , status, false );
|
||||
|
||||
const auto table_nr = record.getItem("VFP_TABLE").get< int >(0);
|
||||
std::optional<VFPProdTable::ALQ_TYPE> alq_type;
|
||||
auto& dynamic_state = this->wells_static.at(well_name);
|
||||
auto well2 = std::make_shared<Well>(*dynamic_state[handlerContext.currentStep]);
|
||||
const bool switching_from_injector = !well2->isProducer();
|
||||
auto properties = std::make_shared<Well::WellProductionProperties>(well2->getProductionProperties());
|
||||
bool update_well = false;
|
||||
properties->handleWCONHIST(record);
|
||||
|
||||
if (table_nr != 0)
|
||||
alq_type = this->getVFPProdTable(table_nr, handlerContext.currentStep).getALQType();
|
||||
properties->handleWCONHIST(alq_type, unit_system, record);
|
||||
|
||||
if (switching_from_injector) {
|
||||
properties->resetDefaultBHPLimit();
|
||||
@@ -880,6 +886,7 @@ namespace {
|
||||
}
|
||||
|
||||
void Schedule::handleWCONPROD(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) {
|
||||
const auto& unit_system = handlerContext.section.unitSystem();
|
||||
for (const auto& record : handlerContext.keyword) {
|
||||
const std::string& wellNamePattern = record.getItem("WELL").getTrimmedString(0);
|
||||
const auto well_names = this->wellNames(wellNamePattern, handlerContext.currentStep);
|
||||
@@ -890,7 +897,8 @@ namespace {
|
||||
|
||||
for (const auto& well_name : well_names) {
|
||||
updateWellStatus(well_name, handlerContext.currentStep, status, false);
|
||||
|
||||
const auto table_nr = record.getItem("VFP_TABLE").get< int >(0);
|
||||
std::optional<VFPProdTable::ALQ_TYPE> alq_type;
|
||||
auto& dynamic_state = this->wells_static.at(well_name);
|
||||
auto well2 = std::make_shared<Well>(*dynamic_state[handlerContext.currentStep]);
|
||||
const bool switching_from_injector = !well2->isProducer();
|
||||
@@ -900,7 +908,9 @@ namespace {
|
||||
if (well2->isAvailableForGroupControl())
|
||||
properties->addProductionControl(Well::ProducerCMode::GRUP);
|
||||
|
||||
properties->handleWCONPROD(well_name, record);
|
||||
if (table_nr != 0)
|
||||
alq_type = this->getVFPProdTable(table_nr, handlerContext.currentStep).getALQType();
|
||||
properties->handleWCONPROD(alq_type, unit_system, well_name, record);
|
||||
|
||||
if (switching_from_injector)
|
||||
properties->resetDefaultBHPLimit();
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp>
|
||||
|
||||
#include "../eval_uda.hpp"
|
||||
|
||||
@@ -89,6 +90,20 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
void Well::WellProductionProperties::init_vfp(const std::optional<VFPProdTable::ALQ_TYPE>& alq_type, const UnitSystem& unit_system, const DeckRecord& record) {
|
||||
if (alq_type) {
|
||||
this->VFPTableNumber = record.getItem("VFP_TABLE").get<int>(0);
|
||||
double alq_input = record.getItem("ALQ").get<double>(0);
|
||||
const auto alq_dim = VFPProdTable::ALQDimension(*alq_type, unit_system);
|
||||
this->ALQValue = alq_dim.convertRawToSi(alq_input);
|
||||
} else {
|
||||
const auto table_nr = record.getItem("VFP_TABLE").get< int >(0);
|
||||
if (table_nr != 0)
|
||||
throw std::logic_error("VFP table inconsistency - BUG");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Well::WellProductionProperties::init_history(const DeckRecord& record)
|
||||
{
|
||||
this->predictionMode = false;
|
||||
@@ -135,25 +150,18 @@ namespace Opm {
|
||||
if (cmode == ProducerCMode::BHP)
|
||||
this->setBHPLimit(this->BHPH);
|
||||
|
||||
const auto vfp_table = record.getItem("VFP_TABLE").get< int >(0);
|
||||
if (vfp_table != 0)
|
||||
this->VFPTableNumber = vfp_table;
|
||||
|
||||
auto alq_value = record.getItem("LIFT").get<double>(0); //NOTE: Unit of ALQ is never touched
|
||||
if (alq_value != 0.)
|
||||
this->ALQValue = alq_value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Well::WellProductionProperties::handleWCONPROD( const std::string& /* well */, const DeckRecord& record)
|
||||
void Well::WellProductionProperties::handleWCONPROD(const std::optional<VFPProdTable::ALQ_TYPE>& alq_type, const UnitSystem& unit_system, const std::string& /* well */, const DeckRecord& record)
|
||||
{
|
||||
this->predictionMode = true;
|
||||
this->init_vfp(alq_type, unit_system, record);
|
||||
this->init_rates(record);
|
||||
|
||||
this->BHPTarget = record.getItem("BHP").get<UDAValue>(0);
|
||||
this->THPTarget = record.getItem("THP").get<UDAValue>(0);
|
||||
this->ALQValue = record.getItem("ALQ").get< double >(0); //NOTE: Unit of ALQ is never touched
|
||||
this->VFPTableNumber = record.getItem("VFP_TABLE").get< int >(0);
|
||||
this->LiquidRate = record.getItem("LRAT").get<UDAValue>(0);
|
||||
this->ResVRate = record.getItem("RESV").get<UDAValue>(0);
|
||||
|
||||
@@ -164,8 +172,6 @@ namespace Opm {
|
||||
};
|
||||
|
||||
|
||||
this->init_rates(record);
|
||||
|
||||
for( const auto& cmode : modes ) {
|
||||
if( !record.getItem( cmode.first ).defaultApplied( 0 ) ) {
|
||||
|
||||
@@ -197,9 +203,10 @@ namespace Opm {
|
||||
originate from the WCONHIST keyword. Predictions are handled with the
|
||||
default constructor and the handleWCONPROD() method.
|
||||
*/
|
||||
void Well::WellProductionProperties::handleWCONHIST(const DeckRecord& record)
|
||||
void Well::WellProductionProperties::handleWCONHIST(const std::optional<VFPProdTable::ALQ_TYPE>& alq_type, const UnitSystem& unit_system, const DeckRecord& record)
|
||||
{
|
||||
this->init_rates(record);
|
||||
this->init_vfp(alq_type, unit_system, record);
|
||||
this->LiquidRate = 0;
|
||||
this->ResVRate = 0;
|
||||
|
||||
@@ -250,9 +257,10 @@ namespace Opm {
|
||||
this->THPTarget.update_value( new_arg );
|
||||
this->addProductionControl( ProducerCMode::THP );
|
||||
}
|
||||
else if (cmode == WELTARGCMode::VFP)
|
||||
this->VFPTableNumber = static_cast<int>(new_arg.get<double>());
|
||||
else if (cmode != WELTARGCMode::GUID)
|
||||
else if (cmode == WELTARGCMode::VFP) {
|
||||
OpmLog::warning("When using WELTARG to change VFP table it is assumed that ALQ type is the same for the new and old table");
|
||||
this->VFPTableNumber = static_cast<int>( new_arg.get<double>() );
|
||||
} else if (cmode != WELTARGCMode::GUID)
|
||||
throw std::invalid_argument("Invalid keyword (MODE) supplied");
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"comment": "The default is a state variable"
|
||||
},
|
||||
{
|
||||
"name": "LIFT",
|
||||
"name": "ALQ",
|
||||
"value_type": "DOUBLE",
|
||||
"default": 0,
|
||||
"comment": "The default is a state variable"
|
||||
|
||||
@@ -161,8 +161,8 @@ BOOST_AUTO_TEST_CASE(createDeckWithWGRUPCONandWCONPROD) {
|
||||
"/\n"
|
||||
|
||||
"WCONPROD\n"
|
||||
" 'B-37T2' 'OPEN' 'GRUP' 1000 2* 2000.000 2* 1* 10 200000.000 5* / / \n"
|
||||
" 'B-43A' 'OPEN' 'GRUP' 1200 2* 3000.000 2* 1* 11 0.000 5* / / \n"
|
||||
" 'B-37T2' 'OPEN' 'GRUP' 1000 2* 2000.000 2* 1* 0 200000.000 5* / / \n"
|
||||
" 'B-43A' 'OPEN' 'GRUP' 1200 2* 3000.000 2* 1* 0 0.000 5* / / \n"
|
||||
"/\n";
|
||||
|
||||
|
||||
|
||||
@@ -955,7 +955,6 @@ BOOST_AUTO_TEST_CASE(createDeckWithWeltArg) {
|
||||
" OP_1 RESV 1801.05 /\n"
|
||||
" OP_1 BHP 1900 /\n"
|
||||
" OP_1 THP 2000 /\n"
|
||||
" OP_1 VFP 2100.09 /\n"
|
||||
" OP_1 GUID 2300.14 /\n"
|
||||
"/\n";
|
||||
|
||||
@@ -985,7 +984,6 @@ BOOST_AUTO_TEST_CASE(createDeckWithWeltArg) {
|
||||
BOOST_CHECK_EQUAL(prod_controls.resv_rate, 1801.05 * siFactorL);
|
||||
BOOST_CHECK_EQUAL(prod_controls.bhp_limit, 1900 * siFactorP);
|
||||
BOOST_CHECK_EQUAL(prod_controls.thp_limit, 2000 * siFactorP);
|
||||
BOOST_CHECK_EQUAL(prod_controls.vfp_table_number, 2100);
|
||||
|
||||
BOOST_CHECK (wpp_2.hasProductionControl( Opm::Well::ProducerCMode::ORAT) );
|
||||
BOOST_CHECK (wpp_2.hasProductionControl( Opm::Well::ProducerCMode::RESV) );
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
|
||||
#define BOOST_TEST_MODULE WellTest
|
||||
#include <boost/test/unit_test.hpp>
|
||||
@@ -493,13 +494,13 @@ namespace {
|
||||
}
|
||||
|
||||
|
||||
Opm::Well::WellProductionProperties properties(const std::string& input) {
|
||||
Opm::Well::WellProductionProperties properties(const std::string& input, std::optional<VFPProdTable::ALQ_TYPE> alq_type = {}) {
|
||||
Opm::Parser parser;
|
||||
Opm::UnitSystem unit_system(Opm::UnitSystem::UnitType::UNIT_TYPE_METRIC);
|
||||
auto deck = parser.parseString(input);
|
||||
const auto& record = deck.getKeyword("WCONHIST").getRecord(0);
|
||||
Opm::Well::WellProductionProperties hist(unit_system, "W");
|
||||
hist.handleWCONHIST(record);
|
||||
hist.handleWCONHIST(alq_type, unit_system, record);
|
||||
|
||||
|
||||
return hist;
|
||||
@@ -545,14 +546,14 @@ namespace {
|
||||
}
|
||||
|
||||
Opm::UnitSystem unit_system(Opm::UnitSystem::UnitType::UNIT_TYPE_METRIC);
|
||||
Opm::Well::WellProductionProperties properties(const std::string& input)
|
||||
Opm::Well::WellProductionProperties properties(const std::string& input, std::optional<VFPProdTable::ALQ_TYPE> alq_type = {})
|
||||
{
|
||||
Opm::Parser parser;
|
||||
auto deck = parser.parseString(input);
|
||||
const auto& kwd = deck.getKeyword("WCONPROD");
|
||||
const auto& record = kwd.getRecord(0);
|
||||
Opm::Well::WellProductionProperties pred(unit_system, "W");
|
||||
pred.handleWCONPROD("WELL", record);
|
||||
pred.handleWCONPROD(alq_type, unit_system, "WELL", record);
|
||||
|
||||
return pred;
|
||||
}
|
||||
@@ -657,7 +658,7 @@ BOOST_AUTO_TEST_CASE(WCH_Rates_NON_Defaulted_VFP)
|
||||
{
|
||||
Opm::SummaryState st(std::chrono::system_clock::now());
|
||||
const Opm::Well::WellProductionProperties& p =
|
||||
WCONHIST::properties(WCONHIST::all_defaulted_with_bhp_vfp_table());
|
||||
WCONHIST::properties(WCONHIST::all_defaulted_with_bhp_vfp_table(), VFPProdTable::ALQ_UNDEF);
|
||||
|
||||
BOOST_CHECK( !p.hasProductionControl(Opm::Well::ProducerCMode::ORAT));
|
||||
BOOST_CHECK( !p.hasProductionControl(Opm::Well::ProducerCMode::WRAT));
|
||||
@@ -715,7 +716,7 @@ BOOST_AUTO_TEST_CASE(WCONPROD_ORAT_CMode)
|
||||
BOOST_AUTO_TEST_CASE(WCONPROD_THP_CMode)
|
||||
{
|
||||
const Opm::Well::WellProductionProperties& p =
|
||||
WCONPROD::properties(WCONPROD::thp_CMODE());
|
||||
WCONPROD::properties(WCONPROD::thp_CMODE(), VFPProdTable::ALQ_UNDEF);
|
||||
|
||||
BOOST_CHECK( p.hasProductionControl(Opm::Well::ProducerCMode::ORAT));
|
||||
BOOST_CHECK( p.hasProductionControl(Opm::Well::ProducerCMode::WRAT));
|
||||
@@ -737,7 +738,7 @@ BOOST_AUTO_TEST_CASE(WCONPROD_THP_CMode)
|
||||
BOOST_AUTO_TEST_CASE(WCONPROD_BHP_CMode)
|
||||
{
|
||||
const Opm::Well::WellProductionProperties& p =
|
||||
WCONPROD::properties(WCONPROD::bhp_CMODE());
|
||||
WCONPROD::properties(WCONPROD::bhp_CMODE(), VFPProdTable::ALQ_UNDEF);
|
||||
|
||||
BOOST_CHECK( p.hasProductionControl(Opm::Well::ProducerCMode::ORAT));
|
||||
BOOST_CHECK( p.hasProductionControl(Opm::Well::ProducerCMode::WRAT));
|
||||
@@ -1118,7 +1119,7 @@ DATES -- 2
|
||||
/
|
||||
|
||||
WCONPROD
|
||||
'P' 'OPEN' 'BHP' 1 2 3 2* 20. 10. 8 13 /
|
||||
'P' 'OPEN' 'BHP' 1 2 3 2* 20. 10. 0 13 /
|
||||
/
|
||||
|
||||
WCONINJE
|
||||
|
||||
Reference in New Issue
Block a user