Merge pull request #453 from GitPaean/support_whistctl
handling the over-writing control part of WHISTCTL
This commit is contained in:
@@ -55,7 +55,10 @@ namespace Opm {
|
||||
bool operator!=(const WellProductionProperties& other) const;
|
||||
WellProductionProperties();
|
||||
|
||||
static WellProductionProperties history(const WellProductionProperties& prev_properties, const DeckRecord& record);
|
||||
static WellProductionProperties history(const WellProductionProperties& prevProperties,
|
||||
const DeckRecord& record,
|
||||
const WellProducer::ControlModeEnum controlModeWHISTCL);
|
||||
|
||||
static WellProductionProperties prediction( const DeckRecord& record, bool addGroupProductionControl );
|
||||
|
||||
bool hasProductionControl(WellProducer::ControlModeEnum controlModeArg) const {
|
||||
@@ -72,6 +75,9 @@ namespace Opm {
|
||||
m_productionControls += controlModeArg;
|
||||
}
|
||||
|
||||
// this is used to check whether the specified control mode is an effective history matching production mode
|
||||
static bool effectiveHistoryProductionControl(const WellProducer::ControlModeEnum cmode);
|
||||
|
||||
private:
|
||||
int m_productionControls = 0;
|
||||
|
||||
|
||||
@@ -312,7 +312,16 @@ namespace Opm {
|
||||
void Schedule::handleWHISTCTL(const ParseContext& parseContext, const DeckKeyword& keyword) {
|
||||
for( const auto& record : keyword ) {
|
||||
const std::string& cmodeString = record.getItem("CMODE").getTrimmedString(0);
|
||||
WellProducer::ControlModeEnum controlMode = WellProducer::ControlModeFromString( cmodeString );
|
||||
const WellProducer::ControlModeEnum controlMode = WellProducer::ControlModeFromString( cmodeString );
|
||||
|
||||
if (controlMode != WellProducer::NONE) {
|
||||
if (!WellProductionProperties::effectiveHistoryProductionControl(controlMode) ) {
|
||||
std::string msg = "The WHISTCTL keyword specifies an un-supported control mode " + cmodeString
|
||||
+ ", which makes WHISTCTL keyword not affect the simulation at all";
|
||||
OpmLog::warning(msg);
|
||||
}
|
||||
}
|
||||
|
||||
m_controlModeWHISTCTL = controlMode;
|
||||
const std::string bhp_terminate = record.getItem("BPH_TERMINATE").getTrimmedString(0);
|
||||
if (bhp_terminate == "YES") {
|
||||
@@ -500,17 +509,9 @@ namespace Opm {
|
||||
properties = WellProductionProperties::prediction( record, addGrupProductionControl );
|
||||
} else {
|
||||
const WellProductionProperties& prev_properties = well->getProductionProperties(currentStep);
|
||||
properties = WellProductionProperties::history(prev_properties, record);
|
||||
properties = WellProductionProperties::history(prev_properties, record, m_controlModeWHISTCTL);
|
||||
}
|
||||
|
||||
if (status != WellCommon::SHUT) {
|
||||
if ( m_controlModeWHISTCTL != WellProducer::CMODE_UNDEFINED &&
|
||||
m_controlModeWHISTCTL != WellProducer::NONE && !isPredictionMode){
|
||||
if ( !properties.hasProductionControl(m_controlModeWHISTCTL) )
|
||||
properties.addProductionControl(m_controlModeWHISTCTL);
|
||||
properties.controlMode = m_controlModeWHISTCTL;
|
||||
}
|
||||
}
|
||||
updateWellStatus( *well , currentStep , status );
|
||||
if (well->setProductionProperties(currentStep, properties))
|
||||
m_events.addEvent( ScheduleEvents::PRODUCTION_UPDATE , currentStep);
|
||||
|
||||
@@ -41,7 +41,9 @@ namespace Opm {
|
||||
{}
|
||||
|
||||
|
||||
WellProductionProperties WellProductionProperties::history(const WellProductionProperties& prev_properties, const DeckRecord& record)
|
||||
WellProductionProperties WellProductionProperties::history(const WellProductionProperties& prev_properties,
|
||||
const DeckRecord& record,
|
||||
const WellProducer::ControlModeEnum controlModeWHISTCL)
|
||||
{
|
||||
WellProductionProperties p(record);
|
||||
p.predictionMode = false;
|
||||
@@ -50,9 +52,14 @@ namespace Opm {
|
||||
const auto& cmodeItem = record.getItem("CMODE");
|
||||
if ( !cmodeItem.defaultApplied(0) ) {
|
||||
namespace wp = WellProducer;
|
||||
const auto cmode = wp::ControlModeFromString( cmodeItem.getTrimmedString( 0 ) );
|
||||
if (cmode == wp::LRAT || cmode == wp::RESV || cmode == wp::ORAT ||
|
||||
cmode == wp::WRAT || cmode == wp::GRAT || cmode == wp::BHP) {
|
||||
auto cmode = wp::ControlModeFromString( cmodeItem.getTrimmedString( 0 ) );
|
||||
|
||||
// when there is an effective control mode specified by WHISTCL, we always use this control mode
|
||||
if (effectiveHistoryProductionControl(controlModeWHISTCL) ) {
|
||||
cmode = controlModeWHISTCL;
|
||||
}
|
||||
|
||||
if (effectiveHistoryProductionControl(cmode) ) {
|
||||
p.addProductionControl( cmode );
|
||||
p.controlMode = cmode;
|
||||
} else {
|
||||
@@ -185,4 +192,11 @@ namespace Opm {
|
||||
<< "prediction: " << wp.predictionMode << " }";
|
||||
}
|
||||
|
||||
bool WellProductionProperties::effectiveHistoryProductionControl(const WellProducer::ControlModeEnum cmode) {
|
||||
// Note, not handling CRAT for now
|
||||
namespace wp = WellProducer;
|
||||
return ( (cmode == wp::LRAT || cmode == wp::RESV || cmode == wp::ORAT ||
|
||||
cmode == wp::WRAT || cmode == wp::GRAT || cmode == wp::BHP) );
|
||||
}
|
||||
|
||||
} // namespace Opm
|
||||
|
||||
@@ -761,6 +761,17 @@ namespace {
|
||||
return input;
|
||||
}
|
||||
|
||||
std::string whistctl() {
|
||||
const std::string input =
|
||||
"WHISTCTL\n"
|
||||
"ORAT /\n"
|
||||
"WCONHIST\n"
|
||||
"-- 1 2 3 4-6 7 8 9 10\n"
|
||||
" 'P' 'OPEN' 'RESV' 3* 3 10. 1* 500/\n/\n";
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
Opm::WellProductionProperties properties(const std::string& input) {
|
||||
Opm::Parser parser;
|
||||
|
||||
@@ -770,7 +781,13 @@ namespace {
|
||||
prev_p.BHPLimit = 100.;
|
||||
prev_p.VFPTableNumber = 12;
|
||||
prev_p.ALQValue = 18.;
|
||||
Opm::WellProductionProperties hist = Opm::WellProductionProperties::history(prev_p, record);;
|
||||
Opm::WellProducer::ControlModeEnum whistctl_cmode = Opm::WellProducer::NONE;
|
||||
if (deck.hasKeyword("WHISTCTL") ) {
|
||||
const auto& whistctl_record = deck.getKeyword("WHISTCTL").getRecord(0);
|
||||
const std::string& cmode_string = whistctl_record.getItem("CMODE").getTrimmedString(0);
|
||||
whistctl_cmode = Opm::WellProducer::ControlModeFromString(cmode_string);
|
||||
}
|
||||
Opm::WellProductionProperties hist = Opm::WellProductionProperties::history(prev_p, record, whistctl_cmode);;
|
||||
|
||||
return hist;
|
||||
}
|
||||
@@ -942,6 +959,27 @@ BOOST_AUTO_TEST_CASE(WCH_Rates_NON_Defaulted_VFP)
|
||||
BOOST_CHECK_EQUAL(p.BHPLimit, 100.);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(WCH_Whistctl)
|
||||
{
|
||||
const Opm::WellProductionProperties& p =
|
||||
WCONHIST::properties(WCONHIST::whistctl());
|
||||
|
||||
// the original RESV contorl in WCONHIST should be overwritten by
|
||||
// ORAT specified with WHISCTL now.
|
||||
BOOST_CHECK( p.hasProductionControl(Opm::WellProducer::ORAT));
|
||||
BOOST_CHECK( !p.hasProductionControl(Opm::WellProducer::WRAT));
|
||||
BOOST_CHECK( !p.hasProductionControl(Opm::WellProducer::GRAT));
|
||||
BOOST_CHECK( !p.hasProductionControl(Opm::WellProducer::LRAT));
|
||||
BOOST_CHECK( !p.hasProductionControl(Opm::WellProducer::RESV));
|
||||
|
||||
BOOST_CHECK_EQUAL(p.controlMode , Opm::WellProducer::ORAT);
|
||||
|
||||
BOOST_CHECK_EQUAL(true, p.hasProductionControl(Opm::WellProducer::BHP));
|
||||
BOOST_CHECK_EQUAL(p.VFPTableNumber, 3);
|
||||
BOOST_CHECK_EQUAL(p.ALQValue, 10.);
|
||||
BOOST_CHECK_EQUAL(p.BHPLimit, 100.);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(WCH_BHP_Specified)
|
||||
{
|
||||
const Opm::WellProductionProperties& p =
|
||||
|
||||
Reference in New Issue
Block a user