Pass VFP ALQ type to enable unit conversion for ALQ values

This commit is contained in:
Joakim Hove
2020-10-16 12:16:33 +02:00
parent 3e02a48c10
commit 134834cefa
7 changed files with 53 additions and 34 deletions
@@ -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"
+2 -2
View File
@@ -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";
-2
View File
@@ -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) );
+9 -8
View File
@@ -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