Merge pull request #1179 from GitPaean/fixing_history_matching_well_1
Fixing history matching wells part 1
This commit is contained in:
@@ -32,13 +32,17 @@ namespace Opm {
|
||||
|
||||
class WellProductionProperties {
|
||||
public:
|
||||
// the rates serve as limits under prediction mode
|
||||
// while they are observed rates under historical mode
|
||||
double OilRate = 0.0;
|
||||
double WaterRate = 0.0;
|
||||
double GasRate = 0.0;
|
||||
double LiquidRate = 0.0;
|
||||
double ResVRate = 0.0;
|
||||
// BHP and THP limit
|
||||
double BHPLimit = 0.0;
|
||||
double THPLimit = 0.0;
|
||||
// historical BHP and THP under historical mode
|
||||
double BHPH = 0.0;
|
||||
double THPH = 0.0;
|
||||
int VFPTableNumber = 0;
|
||||
@@ -51,7 +55,7 @@ namespace Opm {
|
||||
bool operator!=(const WellProductionProperties& other) const;
|
||||
WellProductionProperties();
|
||||
|
||||
static WellProductionProperties history(double BHPLimit, const DeckRecord& record, const Phases &phases = Phases(true, true, true) );
|
||||
static WellProductionProperties history(double BHPLimit, const DeckRecord& record);
|
||||
static WellProductionProperties prediction( const DeckRecord& record, bool addGroupProductionControl );
|
||||
|
||||
bool hasProductionControl(WellProducer::ControlModeEnum controlModeArg) const {
|
||||
|
||||
@@ -455,33 +455,16 @@ namespace Opm {
|
||||
properties = WellProductionProperties::prediction( record, addGrupProductionControl );
|
||||
} else {
|
||||
const WellProductionProperties& prev_properties = well->getProductionProperties(currentStep);
|
||||
double BHPLimit = prev_properties.BHPLimit;
|
||||
properties = WellProductionProperties::history( BHPLimit , record, m_phases);
|
||||
const double BHPLimit = prev_properties.BHPLimit;
|
||||
properties = WellProductionProperties::history( BHPLimit , record);
|
||||
}
|
||||
|
||||
if (status != WellCommon::SHUT) {
|
||||
std::string cmodeString =
|
||||
record.getItem("CMODE").getTrimmedString(0);
|
||||
|
||||
WellProducer::ControlModeEnum control =
|
||||
WellProducer::ControlModeFromString(cmodeString);
|
||||
|
||||
|
||||
if ( m_controlModeWHISTCTL != WellProducer::CMODE_UNDEFINED &&
|
||||
m_controlModeWHISTCTL != WellProducer::NONE && !isPredictionMode){
|
||||
control = m_controlModeWHISTCTL; // overwrite given control
|
||||
cmodeString = WellProducer::ControlMode2String(control); // update the string
|
||||
}
|
||||
|
||||
if (properties.hasProductionControl(control)) {
|
||||
properties.controlMode = control;
|
||||
}
|
||||
else {
|
||||
std::string msg =
|
||||
"Tried to set invalid control: " +
|
||||
cmodeString + " for well: " + well->name();
|
||||
m_messages.error(keyword.getFileName(), msg, keyword.getLineNumber());
|
||||
throw std::invalid_argument(msg);
|
||||
if ( !properties.hasProductionControl(m_controlModeWHISTCTL) )
|
||||
properties.addProductionControl(m_controlModeWHISTCTL);
|
||||
properties.controlMode = m_controlModeWHISTCTL;
|
||||
}
|
||||
}
|
||||
updateWellStatus( *well , currentStep , status );
|
||||
|
||||
@@ -41,49 +41,36 @@ namespace Opm {
|
||||
{}
|
||||
|
||||
|
||||
WellProductionProperties WellProductionProperties::history(double BHPLimit, const DeckRecord& record, const Phases &phases)
|
||||
WellProductionProperties WellProductionProperties::history(const double BHPLimit, const DeckRecord& record)
|
||||
{
|
||||
// Modes supported in WCONHIST just from {O,W,G}RAT values
|
||||
//
|
||||
// Note: The default value of observed {O,W,G}RAT is zero
|
||||
// (numerically) whence the following control modes are
|
||||
// unconditionally supported.
|
||||
WellProductionProperties p(record);
|
||||
p.predictionMode = false;
|
||||
|
||||
namespace wp = WellProducer;
|
||||
if(phases.active(Phase::OIL))
|
||||
p.addProductionControl( wp::ORAT );
|
||||
|
||||
if(phases.active(Phase::WATER))
|
||||
p.addProductionControl( wp::WRAT );
|
||||
|
||||
if(phases.active(Phase::GAS))
|
||||
p.addProductionControl( wp::GRAT );
|
||||
|
||||
for( auto cmode : { wp::LRAT, wp::RESV, wp::GRUP } ) {
|
||||
p.addProductionControl( cmode );
|
||||
}
|
||||
|
||||
/*
|
||||
We do not update the BHPLIMIT based on the BHP value given
|
||||
in WCONHIST, that is purely a historical value; instead we
|
||||
copy the old value of the BHP limit from the previous
|
||||
timestep.
|
||||
|
||||
To actually set the BHPLIMIT in historical mode you must
|
||||
use the WELTARG keyword.
|
||||
*/
|
||||
p.BHPLimit = BHPLimit;
|
||||
|
||||
const auto& cmodeItem = record.getItem("CMODE");
|
||||
if (!cmodeItem.defaultApplied(0)) {
|
||||
const auto cmode = WellProducer::ControlModeFromString( cmodeItem.getTrimmedString( 0 ) );
|
||||
|
||||
if (p.hasProductionControl( 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) {
|
||||
p.addProductionControl( cmode );
|
||||
p.controlMode = cmode;
|
||||
} else {
|
||||
const std::string cmode_string = cmodeItem.getTrimmedString( 0 );
|
||||
const std::string msg = "unsupported control mode " + cmode_string + " for WCONHIST";
|
||||
throw std::invalid_argument(msg);
|
||||
}
|
||||
|
||||
// always have a BHP control/limit, while the limit value needs to be determined
|
||||
// the control mode added above can be a BHP control or a type of RATE control
|
||||
if ( !p.hasProductionControl( wp::BHP ) )
|
||||
p.addProductionControl( wp::BHP );
|
||||
|
||||
|
||||
if (cmode == wp::BHP)
|
||||
p.BHPLimit = record.getItem( "BHP" ).getSIDouble( 0 );
|
||||
else
|
||||
throw std::invalid_argument("Setting CMODE to unspecified control");
|
||||
p.BHPLimit = BHPLimit;
|
||||
}
|
||||
|
||||
if ( record.getItem( "BHP" ).hasValue(0) )
|
||||
|
||||
@@ -808,10 +808,10 @@ BOOST_AUTO_TEST_CASE(testWellNameInWellNamePattern) {
|
||||
|
||||
namespace {
|
||||
namespace WCONHIST {
|
||||
std::string all_specified_CMODE_BHP() {
|
||||
std::string all_specified_CMODE_THP() {
|
||||
const std::string input =
|
||||
"WCONHIST\n"
|
||||
"'P' 'OPEN' 'BHP' 1 2 3/\n/\n";
|
||||
"'P' 'OPEN' 'THP' 1 2 3/\n/\n";
|
||||
|
||||
return input;
|
||||
}
|
||||
@@ -903,18 +903,15 @@ BOOST_AUTO_TEST_CASE(WCH_All_Specified_BHP_Defaulted)
|
||||
const Opm::WellProductionProperties& p =
|
||||
WCONHIST::properties(WCONHIST::all_specified());
|
||||
|
||||
// WCONHIST always supports {O,W,G}RAT, LRAT, and
|
||||
// RESV--irrespective of actual specification.
|
||||
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( !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);
|
||||
|
||||
// BHP must be explicitly provided/specified
|
||||
BOOST_CHECK(! p.hasProductionControl(Opm::WellProducer::BHP));
|
||||
BOOST_CHECK(p.hasProductionControl(Opm::WellProducer::BHP));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(WCH_ORAT_Defaulted_BHP_Defaulted)
|
||||
@@ -922,17 +919,14 @@ BOOST_AUTO_TEST_CASE(WCH_ORAT_Defaulted_BHP_Defaulted)
|
||||
const Opm::WellProductionProperties& p =
|
||||
WCONHIST::properties(WCONHIST::orat_defaulted());
|
||||
|
||||
// WCONHIST always supports {O,W,G}RAT, LRAT, and
|
||||
// RESV--irrespective of actual specification.
|
||||
BOOST_CHECK(p.hasProductionControl(Opm::WellProducer::ORAT));
|
||||
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( !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::WRAT);
|
||||
|
||||
// BHP must be explicitly provided/specified
|
||||
BOOST_CHECK(! p.hasProductionControl(Opm::WellProducer::BHP));
|
||||
BOOST_CHECK(p.hasProductionControl(Opm::WellProducer::BHP));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(WCH_OWRAT_Defaulted_BHP_Defaulted)
|
||||
@@ -940,17 +934,14 @@ BOOST_AUTO_TEST_CASE(WCH_OWRAT_Defaulted_BHP_Defaulted)
|
||||
const Opm::WellProductionProperties& p =
|
||||
WCONHIST::properties(WCONHIST::owrat_defaulted());
|
||||
|
||||
// WCONHIST always supports {O,W,G}RAT, LRAT, and
|
||||
// RESV--irrespective of actual specification.
|
||||
BOOST_CHECK(p.hasProductionControl(Opm::WellProducer::ORAT));
|
||||
BOOST_CHECK(p.hasProductionControl(Opm::WellProducer::WRAT));
|
||||
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( !p.hasProductionControl(Opm::WellProducer::LRAT));
|
||||
BOOST_CHECK( !p.hasProductionControl(Opm::WellProducer::RESV));
|
||||
BOOST_CHECK_EQUAL(p.controlMode , Opm::WellProducer::GRAT);
|
||||
|
||||
// BHP must be explicitly provided/specified
|
||||
BOOST_CHECK(! p.hasProductionControl(Opm::WellProducer::BHP));
|
||||
BOOST_CHECK(p.hasProductionControl(Opm::WellProducer::BHP));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(WCH_Rates_Defaulted_BHP_Defaulted)
|
||||
@@ -958,17 +949,14 @@ BOOST_AUTO_TEST_CASE(WCH_Rates_Defaulted_BHP_Defaulted)
|
||||
const Opm::WellProductionProperties& p =
|
||||
WCONHIST::properties(WCONHIST::all_defaulted());
|
||||
|
||||
// WCONHIST always supports {O,W,G}RAT, LRAT, and
|
||||
// RESV--irrespective of actual specification.
|
||||
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::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( !p.hasProductionControl(Opm::WellProducer::RESV));
|
||||
BOOST_CHECK_EQUAL(p.controlMode , Opm::WellProducer::LRAT);
|
||||
|
||||
// BHP must be explicitly provided/specified
|
||||
BOOST_CHECK(! p.hasProductionControl(Opm::WellProducer::BHP));
|
||||
BOOST_CHECK(p.hasProductionControl(Opm::WellProducer::BHP));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(WCH_Rates_Defaulted_BHP_Specified)
|
||||
@@ -976,27 +964,21 @@ BOOST_AUTO_TEST_CASE(WCH_Rates_Defaulted_BHP_Specified)
|
||||
const Opm::WellProductionProperties& p =
|
||||
WCONHIST::properties(WCONHIST::all_defaulted_with_bhp());
|
||||
|
||||
// WCONHIST always supports {O,W,G}RAT, LRAT, and
|
||||
// RESV--irrespective of actual specification.
|
||||
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::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::RESV);
|
||||
|
||||
/*
|
||||
BHP in WCONHIST is not an available control; just information
|
||||
about the historical BHP.
|
||||
*/
|
||||
BOOST_CHECK_EQUAL(false , p.hasProductionControl(Opm::WellProducer::BHP));
|
||||
BOOST_CHECK_EQUAL(true, p.hasProductionControl(Opm::WellProducer::BHP));
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(BHP_CMODE)
|
||||
{
|
||||
BOOST_CHECK_THROW( WCONHIST::properties(WCONHIST::all_specified_CMODE_BHP()) , std::invalid_argument);
|
||||
BOOST_CHECK_THROW( WCONHIST::properties(WCONHIST::all_specified_CMODE_THP()) , std::invalid_argument);
|
||||
BOOST_CHECK_THROW( WCONPROD::properties(WCONPROD::all_specified_CMODE_BHP()) , std::invalid_argument);
|
||||
}
|
||||
|
||||
|
||||
@@ -199,8 +199,8 @@ BOOST_AUTO_TEST_CASE(WellTesting) {
|
||||
const WellProductionProperties& prop3 = well2->getProductionProperties(3);
|
||||
BOOST_CHECK_EQUAL( WellProducer::ORAT , prop3.controlMode);
|
||||
BOOST_CHECK( prop3.hasProductionControl(WellProducer::ORAT));
|
||||
BOOST_CHECK( prop3.hasProductionControl(WellProducer::GRAT));
|
||||
BOOST_CHECK( prop3.hasProductionControl(WellProducer::WRAT));
|
||||
BOOST_CHECK( !prop3.hasProductionControl(WellProducer::GRAT));
|
||||
BOOST_CHECK( !prop3.hasProductionControl(WellProducer::WRAT));
|
||||
}
|
||||
|
||||
// BOOST_CHECK( !well2->getProductionProperties(8).hasProductionControl(WellProducer::GRAT));
|
||||
|
||||
Reference in New Issue
Block a user