Merge pull request #1179 from GitPaean/fixing_history_matching_well_1

Fixing history matching wells part 1
This commit is contained in:
Joakim Hove
2018-01-09 14:36:57 +01:00
committed by GitHub
5 changed files with 62 additions and 106 deletions

View File

@@ -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 {

View File

@@ -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 );

View File

@@ -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) )

View File

@@ -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);
}

View File

@@ -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));