diff --git a/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp b/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp index 026647ffa..3ce012f0e 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp @@ -236,6 +236,33 @@ namespace Opm { if (record->getItem("WRAT")->defaultApplied()) well->dropProductionControl( currentStep , WellProducer::WRAT ); + + if (status != WellCommon::SHUT) { + const std::string& cmodeString = record->getItem("CMODE")->getString(0); + WellProducer::ControlModeEnum control = WellProducer::ControlModeFromString( cmodeString ); + if (well->hasProductionControl( currentStep , control)) + well->setProducerControlMode( currentStep , control ); + else { + /* + This is an awkward situation. The current control mode variable + points to a control which has not been specified in the deck; i.e. a + situation like this: + + WCONHIST + 'WELL' 'OPEN' 'RESV' 0.000 0.000 0.000 5* / + / + + We have specified that the well should be controlled with 'RESV' + mode, but actual RESV value has been defaulted. ECLIPSE seems to + handle this, but the well machinery in OPM-Core keeps close track of + which controls are available, i.e. have a value set, and will be + confused by this. We therefor throw here; the fix is to modify the + deck to set an explicit value for the defaulted control, or + alternatively change control mode. + */ + throw std::invalid_argument("Tried to set invalid control: " + cmodeString + " for well: " + wellName); + } + } } } @@ -265,14 +292,12 @@ namespace Opm { double BHPLimit = record->getItem("BHP")->getSIDouble(0); double THPLimit = record->getItem("THP")->getSIDouble(0); WellCommon::StatusEnum status = WellCommon::StatusFromString( record->getItem("STATUS")->getString(0)); - WellInjector::ControlModeEnum controlMode = WellInjector::ControlModeFromString( record->getItem("CMODE")->getString(0)); well->setStatus( currentStep , status ); well->setSurfaceInjectionRate( currentStep , surfaceInjectionRate ); well->setReservoirInjectionRate( currentStep , reservoirInjectionRate ); well->setBHPLimit(currentStep, BHPLimit , false); well->setTHPLimit(currentStep, THPLimit , false); - well->setInjectorControlMode(currentStep , controlMode ); well->setInjectorType( currentStep , injectorType ); well->setInPredictionMode(currentStep, true); @@ -288,9 +313,19 @@ namespace Opm { if (record->getItem("BHP")->defaultApplied()) well->dropInjectionControl( currentStep , WellInjector::BHP ); + { + const std::string& cmodeString = record->getItem("CMODE")->getString(0); + WellInjector::ControlModeEnum controlMode = WellInjector::ControlModeFromString( cmodeString ); + if (well->hasInjectionControl( currentStep , controlMode)) + well->setInjectorControlMode( currentStep , controlMode ); + else { + throw std::invalid_argument("Tried to set invalid control: " + cmodeString + " for well: " + wellName); + } + } } } + void Schedule::handleWCONINJH(DeckConstPtr deck, DeckKeywordConstPtr keyword, size_t currentStep) { for (size_t recordNr = 0; recordNr < keyword->size(); recordNr++) { DeckRecordConstPtr record = keyword->getRecord(recordNr); diff --git a/opm/parser/eclipse/IntegrationTests/ScheduleCreateFromDeck.cpp b/opm/parser/eclipse/IntegrationTests/ScheduleCreateFromDeck.cpp index 26ce4cf2d..91415ebcc 100644 --- a/opm/parser/eclipse/IntegrationTests/ScheduleCreateFromDeck.cpp +++ b/opm/parser/eclipse/IntegrationTests/ScheduleCreateFromDeck.cpp @@ -56,7 +56,6 @@ BOOST_AUTO_TEST_CASE(CreateSchedule_Comments_After_Keywords) { TimeMapConstPtr timeMap = sched->getTimeMap(); BOOST_CHECK_EQUAL(boost::posix_time::ptime(boost::gregorian::date(2007, boost::gregorian::May, 10)), sched->getStartTime()); BOOST_CHECK_EQUAL(9U, timeMap->size()); - } @@ -69,6 +68,15 @@ BOOST_AUTO_TEST_CASE(WCONPROD_MissingCmode) { } +BOOST_AUTO_TEST_CASE(WCONPROD_Missing_DATA) { + ParserPtr parser(new Parser()); + boost::filesystem::path scheduleFile("testdata/integration_tests/SCHEDULE/SCHEDULE_CMODE_MISSING_DATA"); + DeckPtr deck = parser->parseFile(scheduleFile.string()); + + BOOST_CHECK_THROW( new Schedule(deck) , std::invalid_argument ); +} + + BOOST_AUTO_TEST_CASE(WellTesting) { ParserPtr parser(new Parser()); diff --git a/testdata/integration_tests/SCHEDULE/SCHEDULE_CMODE_MISSING_DATA b/testdata/integration_tests/SCHEDULE/SCHEDULE_CMODE_MISSING_DATA new file mode 100644 index 000000000..4f7120bff --- /dev/null +++ b/testdata/integration_tests/SCHEDULE/SCHEDULE_CMODE_MISSING_DATA @@ -0,0 +1,27 @@ +START + 10 MAI 2007 / + +SCHEDULE + +WELSPECS + 'W1' 'OP' 30 37 3.33 'OIL' 7* / + 'W2' 'OP' 30 37 3.33 'OIL' 7* / + 'W3' 'OP' 30 37 3.33 'OIL' 7* / + 'W4' 'OP' 30 37 3.33 'OIL' 7* / +/ + + +WCONPROD + 'W2' 'OPEN' 'RESV' 2079.506 0.000 230825.037 5* / +/ + + +-- The RESV control mode is currently not supported for historical mode. +WCONHIST + 'W2' 'OPEN' 'RESV' 2079.506 0.000 230825.037 5* / +/ + + +WCONINJE + 'W_1' 'WATER' 1* 'BHP' 20000.000 200000.000 * 678 4* / +/ diff --git a/testdata/integration_tests/SCHEDULE/SCHEDULE_MISSING_CMODE b/testdata/integration_tests/SCHEDULE/SCHEDULE_MISSING_CMODE index 5d627b2dd..9adc68f80 100644 --- a/testdata/integration_tests/SCHEDULE/SCHEDULE_MISSING_CMODE +++ b/testdata/integration_tests/SCHEDULE/SCHEDULE_MISSING_CMODE @@ -11,3 +11,5 @@ WELSPECS WCONPROD 'D-4H' 'SHUT' 15* / / + + diff --git a/testdata/integration_tests/SCHEDULE/SCHEDULE_WELLS2 b/testdata/integration_tests/SCHEDULE/SCHEDULE_WELLS2 index fc1c5b162..d57cd4fe2 100644 --- a/testdata/integration_tests/SCHEDULE/SCHEDULE_WELLS2 +++ b/testdata/integration_tests/SCHEDULE/SCHEDULE_WELLS2 @@ -73,8 +73,8 @@ COMPDAT WCONPROD 'W_1' 'OPEN' 'ORAT' 11000.000 44.000 188 5* / - 'W_2' 'OPEN' 'ORAT' 17998.000 2.000 1461075.000 * 777 3* / - 'W_3' 'OPEN' 'RESV' 17999.000 1.000 1471824.000 999 4* / + 'W_2' 'OPEN' 'RESV' 17998.000 2.000 1461075.000 * 777 3* / + 'W_3' 'OPEN' 'RESV' 17999.000 1.000 1471824.000 999 999 4* / / TSTEP -- 8