diff --git a/opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.hpp b/opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.hpp index ece9a7129..f901b3f15 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.hpp @@ -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 { diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp index 5b4288a33..77881c351 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp @@ -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 ); diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.cpp index 4c18d7a61..bb0ac69d6 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.cpp @@ -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) ) diff --git a/tests/parser/WellTests.cpp b/tests/parser/WellTests.cpp index a9e31bffd..4e66958ca 100644 --- a/tests/parser/WellTests.cpp +++ b/tests/parser/WellTests.cpp @@ -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); } diff --git a/tests/parser/integration/ScheduleCreateFromDeck.cpp b/tests/parser/integration/ScheduleCreateFromDeck.cpp index db5dfd8fc..8cfdbfe20 100644 --- a/tests/parser/integration/ScheduleCreateFromDeck.cpp +++ b/tests/parser/integration/ScheduleCreateFromDeck.cpp @@ -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));