diff --git a/opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp b/opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp index b7c558e1c..821bd49d3 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp @@ -75,6 +75,7 @@ namespace Opm { void handleWCONHIST( const DeckRecord& record); void handleWELTARG(WellTarget::ControlModeEnum cmode, double newValue, double siFactorG, double siFactorL, double siFactorP); void resetDefaultBHPLimit(); + void clearControls(); private: int m_productionControls = 0; diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp index 845901884..fd725ad12 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp @@ -757,6 +757,9 @@ namespace Opm { auto& well = this->m_wells.at(well_name); bool switching_from_injector = !well.isProducer(currentStep); WellProductionProperties properties(well.getProductionProperties(currentStep)); + + properties.clearControls(); + if (well.isAvailableForGroupControl(currentStep)) properties.addProductionControl(WellProducer::GRUP); @@ -776,6 +779,9 @@ namespace Opm { auto well2 = std::make_shared(*dynamic_state[currentStep]); bool switching_from_injector = !well2->isProducer(); auto properties = std::make_shared(well2->getProductionProperties()); + + properties->clearControls(); + if (well2->isAvailableForGroupControl()) properties->addProductionControl(WellProducer::GRUP); diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.cpp index 21e6e9cf1..d47e6dd48 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.cpp @@ -68,7 +68,8 @@ namespace Opm { cmode = wp::ControlModeFromString( cmodeItem.getTrimmedString( 0 ) ); // clearing the existing targets/limits - m_productionControls = 0; + clearControls(); + if (effectiveHistoryProductionControl(cmode)) { this->addProductionControl( cmode ); this->controlMode = cmode; @@ -117,6 +118,7 @@ namespace Opm { this->init_rates(record); + for( const auto& cmode : modes ) { if( !record.getItem( cmode.first ).defaultApplied( 0 ) ) { @@ -253,6 +255,10 @@ namespace Opm { BHPLimit = 1. * unit::atm; } + void WellProductionProperties::clearControls() { + m_productionControls = 0; + } + void WellProductionProperties::setBHPLimit(const double limit) { BHPLimit = limit; } diff --git a/tests/parser/ScheduleTests.cpp b/tests/parser/ScheduleTests.cpp index 4d7406b74..d784898e5 100644 --- a/tests/parser/ScheduleTests.cpp +++ b/tests/parser/ScheduleTests.cpp @@ -1669,6 +1669,89 @@ BOOST_AUTO_TEST_CASE(changeModeWithWHISTCTL) { BOOST_CHECK( !schedule.getWell2("P2", 5).getProductionProperties().hasProductionControl(Opm::WellProducer::LRAT) ); } +BOOST_AUTO_TEST_CASE(fromWCONHISTtoWCONPROD) { + Opm::Parser parser; + std::string input = + "START -- 0 \n" + "19 JUN 2007 / \n" + "SCHEDULE\n" + "DATES -- 1\n" + " 10 OKT 2008 / \n" + "/\n" + "WELSPECS\n" + " 'P1' 'OP' 9 9 1* 'OIL' 1* 1* 1* 1* 1* 1* 1* / \n" + " 'P2' 'OP' 5 5 1* 'OIL' 1* 1* 1* 1* 1* 1* 1* / \n" + " 'I' 'OP' 1 1 1* 'WATER' 1* 1* 1* 1* 1* 1* 1* / \n" + "/\n" + "COMPDAT\n" + " 'P1' 9 9 1 1 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n" + " 'P1' 9 9 2 2 'OPEN' 1* 46.825 0.311 4332.346 1* 1* 'X' 22.123 / \n" + " 'P2' 5 5 1 1 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n" + " 'P2' 5 5 2 2 'OPEN' 1* 46.825 0.311 4332.346 1* 1* 'X' 22.123 / \n" + " 'I' 1 1 1 1 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n" + "/\n" + "WCONHIST\n" + " 'P1' 'OPEN' 'ORAT' 5*/ \n" + " 'P2' 'OPEN' 'ORAT' 5*/ \n" + "/\n" + "DATES -- 2\n" + " 15 OKT 2008 / \n" + "/\n" + "WCONPROD\n" + " 'P1' 'OPEN' 'GRAT' 1* 200.0 300.0 / \n" + " 'P2' 'OPEN' 'WRAT' 1* 100.0 300.0 / \n" + "/\n" + "DATES -- 3\n" + " 18 OKT 2008 / \n" + "/\n" + ; + + auto deck = parser.parseString(input); + EclipseGrid grid(10,10,10); + TableManager table ( deck ); + Eclipse3DProperties eclipseProperties ( deck , table, grid); + Runspec runspec (deck); + Schedule schedule(deck, grid , eclipseProperties, runspec); + { + auto* well_p1 = schedule.getWell("P1"); + auto* well_p2 = schedule.getWell("P2"); + + //Start + BOOST_CHECK_EQUAL(well_p1->getProductionProperties(0).controlMode, Opm::WellProducer::CMODE_UNDEFINED); + BOOST_CHECK_EQUAL(well_p2->getProductionProperties(0).controlMode, Opm::WellProducer::CMODE_UNDEFINED); + + //10 OKT 2008 + BOOST_CHECK_EQUAL(well_p1->getProductionProperties(1).controlMode, Opm::WellProducer::ORAT); + BOOST_CHECK_EQUAL(well_p2->getProductionProperties(1).controlMode, Opm::WellProducer::ORAT); + + //15 OKT 2008 + BOOST_CHECK_EQUAL(well_p1->getProductionProperties(2).controlMode, Opm::WellProducer::GRAT); + BOOST_CHECK(well_p1->getProductionProperties(2).hasProductionControl(Opm::WellProducer::WRAT) ); + BOOST_CHECK_EQUAL(well_p2->getProductionProperties(2).controlMode, Opm::WellProducer::WRAT); + BOOST_CHECK(well_p2->getProductionProperties(2).hasProductionControl(Opm::WellProducer::GRAT) ); + // the previous control limits/targets should not stay + BOOST_CHECK( !well_p1->getProductionProperties(2).hasProductionControl(Opm::WellProducer::ORAT) ); + BOOST_CHECK( !well_p2->getProductionProperties(2).hasProductionControl(Opm::WellProducer::ORAT) ); + } + + //Start + BOOST_CHECK_THROW(schedule.getWell2("P1", 0), std::invalid_argument); + BOOST_CHECK_THROW(schedule.getWell2("P2", 0), std::invalid_argument); + + //10 OKT 2008 + BOOST_CHECK_EQUAL(schedule.getWell2("P1", 1).getProductionProperties().controlMode, Opm::WellProducer::ORAT); + BOOST_CHECK_EQUAL(schedule.getWell2("P2", 1).getProductionProperties().controlMode, Opm::WellProducer::ORAT); + + //15 OKT 2008 + BOOST_CHECK_EQUAL(schedule.getWell2("P1", 2).getProductionProperties().controlMode, Opm::WellProducer::GRAT); + BOOST_CHECK(schedule.getWell2("P1", 2).getProductionProperties().hasProductionControl(Opm::WellProducer::WRAT) ); + BOOST_CHECK_EQUAL(schedule.getWell2("P2", 2).getProductionProperties().controlMode, Opm::WellProducer::WRAT); + BOOST_CHECK(schedule.getWell2("P2", 2).getProductionProperties().hasProductionControl(Opm::WellProducer::GRAT) ); + // the previous control limits/targets should not stay + BOOST_CHECK( !schedule.getWell2("P1", 2).getProductionProperties().hasProductionControl(Opm::WellProducer::ORAT) ); + BOOST_CHECK( !schedule.getWell2("P2", 2).getProductionProperties().hasProductionControl(Opm::WellProducer::ORAT) ); +} + BOOST_AUTO_TEST_CASE(WHISTCTL_NEW_WELL) { Opm::Parser parser; std::string input =