Refactor iteration over Schedule section to for ACTIONX

This commit is contained in:
Joakim Hove 2018-07-11 13:54:49 +02:00
parent bbb5e27e90
commit 451d52c18a
5 changed files with 197 additions and 107 deletions

View File

@ -55,6 +55,8 @@ public:
ActionX(const std::string& name, size_t max_run, double max_wait);
explicit ActionX(const DeckKeyword& kw);
void addKeyword(const DeckKeyword& kw);
const std::string& name() const;
private:
std::string m_name;

View File

@ -189,6 +189,15 @@ namespace Opm
void handleVFPINJ(const DeckKeyword& vfpprodKeyword, const UnitSystem& unit_system, size_t currentStep);
void checkUnhandledKeywords( const SCHEDULESection& ) const;
void checkIfAllConnectionsIsShut(size_t currentStep);
void handleKeyword(size_t& currentStep,
const SCHEDULESection& section,
size_t keywordIdx,
const DeckKeyword& keyword,
const ParseContext& parseContext,
const EclipseGrid& grid,
const Eclipse3DProperties& eclipseProperties,
const UnitSystem& unit_system,
std::vector<std::pair<const DeckKeyword*, size_t > >& rftProperties);
static double convertInjectionRateToSI(double rawRate, WellInjector::TypeEnum wellType, const Opm::UnitSystem &unitSystem);
static double convertInjectionRateToSI(double rawRate, Phase wellPhase, const Opm::UnitSystem &unitSystem);

View File

@ -42,7 +42,6 @@ void ActionX::addKeyword(const DeckKeyword& kw) {
this->keywords.push_back(kw);
}
const std::string& ActionX::name() const {
return this->m_name;
}

View File

@ -36,6 +36,7 @@
#include <opm/parser/eclipse/Parser/ParserKeywords/W.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ActionX.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/WellConnections.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicVector.hpp>
@ -117,15 +118,23 @@ namespace Opm {
return this->m_timeMap.getEndTime();
}
void Schedule::iterateScheduleSection(const ParseContext& parseContext , const SCHEDULESection& section , const EclipseGrid& grid,
const Eclipse3DProperties& eclipseProperties) {
/*
geoModifiers is a list of geo modifiers which can be found in the schedule
section. This is only partly supported, support is indicated by the bool
value. The keywords which are supported will be assembled in a per-timestep
'minideck', whereas ParseContext::UNSUPPORTED_SCHEDULE_GEO_MODIFIER will be
consulted for the others.
*/
void Schedule::handleKeyword(size_t& currentStep,
const SCHEDULESection& section,
size_t keywordIdx,
const DeckKeyword& keyword,
const ParseContext& parseContext,
const EclipseGrid& grid,
const Eclipse3DProperties& eclipseProperties,
const UnitSystem& unit_system,
std::vector<std::pair<const DeckKeyword*, size_t > >& rftProperties) {
/*
geoModifiers is a list of geo modifiers which can be found in the schedule
section. This is only partly supported, support is indicated by the bool
value. The keywords which are supported will be assembled in a per-timestep
'minideck', whereas ParseContext::UNSUPPORTED_SCHEDULE_GEO_MODIFIER will be
consulted for the others.
*/
const std::map<std::string,bool> geoModifiers = {{"MULTFLT" , true},
{"MULTPV" , false},
@ -143,145 +152,169 @@ namespace Opm {
{"MULTTHT" , false},
{"MULTTHT-" , false}};
size_t currentStep = 0;
std::vector<std::pair< const DeckKeyword* , size_t> > rftProperties;
const auto& unit_system = section.unitSystem();
if (keyword.name() == "DATES") {
checkIfAllConnectionsIsShut(currentStep);
currentStep += keyword.size();
}
for (size_t keywordIdx = 0; keywordIdx < section.size(); ++keywordIdx) {
const auto& keyword = section.getKeyword(keywordIdx);
else if (keyword.name() == "TSTEP") {
checkIfAllConnectionsIsShut(currentStep);
currentStep += keyword.getRecord(0).getItem(0).size(); // This is a bit weird API.
}
if (keyword.name() == "DATES") {
checkIfAllConnectionsIsShut(currentStep);
currentStep += keyword.size();
}
else if (keyword.name() == "WELSPECS")
handleWELSPECS( section, keywordIdx, currentStep );
else if (keyword.name() == "TSTEP") {
checkIfAllConnectionsIsShut(currentStep);
currentStep += keyword.getRecord(0).getItem(0).size(); // This is a bit weird API.
}
else if (keyword.name() == "WHISTCTL")
handleWHISTCTL(parseContext, keyword);
else if (keyword.name() == "WELSPECS")
handleWELSPECS( section, keywordIdx, currentStep );
else if (keyword.name() == "WCONHIST")
handleWCONHIST(keyword, currentStep, parseContext);
else if (keyword.name() == "WHISTCTL")
handleWHISTCTL(parseContext, keyword);
else if (keyword.name() == "WCONPROD")
handleWCONPROD(keyword, currentStep, parseContext);
else if (keyword.name() == "WCONHIST")
handleWCONHIST(keyword, currentStep, parseContext);
else if (keyword.name() == "WCONINJE")
handleWCONINJE(section, keyword, currentStep, parseContext);
else if (keyword.name() == "WCONPROD")
handleWCONPROD(keyword, currentStep, parseContext);
else if (keyword.name() == "WPOLYMER")
handleWPOLYMER(keyword, currentStep, parseContext);
else if (keyword.name() == "WCONINJE")
handleWCONINJE(section, keyword, currentStep, parseContext);
else if (keyword.name() == "WSOLVENT")
handleWSOLVENT(keyword, currentStep, parseContext);
else if (keyword.name() == "WPOLYMER")
handleWPOLYMER(keyword, currentStep, parseContext);
else if (keyword.name() == "WTEST")
handleWTEST(keyword, currentStep, parseContext);
else if (keyword.name() == "WSOLVENT")
handleWSOLVENT(keyword, currentStep, parseContext);
else if (keyword.name() == "WTEMP")
handleWTEMP(keyword, currentStep, parseContext);
else if (keyword.name() == "WTEST")
handleWTEST(keyword, currentStep, parseContext);
else if (keyword.name() == "WINJTEMP")
handleWINJTEMP(keyword, currentStep, parseContext);
else if (keyword.name() == "WTEMP")
handleWTEMP(keyword, currentStep, parseContext);
else if (keyword.name() == "WCONINJH")
handleWCONINJH(section, keyword, currentStep, parseContext);
else if (keyword.name() == "WINJTEMP")
handleWINJTEMP(keyword, currentStep, parseContext);
else if (keyword.name() == "WGRUPCON")
handleWGRUPCON(keyword, currentStep);
else if (keyword.name() == "WCONINJH")
handleWCONINJH(section, keyword, currentStep, parseContext);
else if (keyword.name() == "COMPDAT")
handleCOMPDAT(keyword, currentStep, grid, eclipseProperties, parseContext);
else if (keyword.name() == "WGRUPCON")
handleWGRUPCON(keyword, currentStep);
else if (keyword.name() == "WELSEGS")
handleWELSEGS(keyword, currentStep);
else if (keyword.name() == "COMPDAT")
handleCOMPDAT(keyword, currentStep, grid, eclipseProperties, parseContext);
else if (keyword.name() == "COMPSEGS")
handleCOMPSEGS(keyword, currentStep);
else if (keyword.name() == "WELSEGS")
handleWELSEGS(keyword, currentStep);
else if (keyword.name() == "WELOPEN")
handleWELOPEN(keyword, currentStep, parseContext);
else if (keyword.name() == "COMPSEGS")
handleCOMPSEGS(keyword, currentStep);
else if (keyword.name() == "WELTARG")
handleWELTARG(section, keyword, currentStep, parseContext);
else if (keyword.name() == "WELOPEN")
handleWELOPEN(keyword, currentStep, parseContext);
else if (keyword.name() == "GRUPTREE")
handleGRUPTREE(keyword, currentStep);
else if (keyword.name() == "WELTARG")
handleWELTARG(section, keyword, currentStep, parseContext);
else if (keyword.name() == "GRUPNET")
handleGRUPNET(keyword, currentStep);
else if (keyword.name() == "GRUPTREE")
handleGRUPTREE(keyword, currentStep);
else if (keyword.name() == "GCONINJE")
handleGCONINJE(section, keyword, currentStep, parseContext);
else if (keyword.name() == "GRUPNET")
handleGRUPNET(keyword, currentStep);
else if (keyword.name() == "GCONPROD")
handleGCONPROD(keyword, currentStep, parseContext);
else if (keyword.name() == "GCONINJE")
handleGCONINJE(section, keyword, currentStep, parseContext);
else if (keyword.name() == "GEFAC")
handleGEFAC(keyword, currentStep, parseContext);
else if (keyword.name() == "GCONPROD")
handleGCONPROD(keyword, currentStep, parseContext);
else if (keyword.name() == "TUNING")
handleTUNING(keyword, currentStep);
else if (keyword.name() == "GEFAC")
handleGEFAC(keyword, currentStep, parseContext);
else if (keyword.name() == "WRFT")
rftProperties.push_back( std::make_pair( &keyword , currentStep ));
else if (keyword.name() == "TUNING")
handleTUNING(keyword, currentStep);
else if (keyword.name() == "WRFTPLT")
rftProperties.push_back( std::make_pair( &keyword , currentStep ));
else if (keyword.name() == "WRFT")
rftProperties.push_back( std::make_pair( &keyword , currentStep ));
else if (keyword.name() == "WPIMULT")
handleWPIMULT(keyword, currentStep);
else if (keyword.name() == "WRFTPLT")
rftProperties.push_back( std::make_pair( &keyword , currentStep ));
else if (keyword.name() == "COMPORD")
handleCOMPORD(parseContext , keyword, currentStep);
else if (keyword.name() == "WPIMULT")
handleWPIMULT(keyword, currentStep);
else if (keyword.name() == "COMPLUMP")
handleCOMPLUMP(keyword, currentStep);
else if (keyword.name() == "COMPORD")
handleCOMPORD(parseContext , keyword, currentStep);
else if (keyword.name() == "DRSDT")
handleDRSDT(keyword, currentStep);
else if (keyword.name() == "COMPLUMP")
handleCOMPLUMP(keyword, currentStep);
else if (keyword.name() == "DRVDT")
handleDRVDT(keyword, currentStep);
else if (keyword.name() == "DRSDT")
handleDRSDT(keyword, currentStep);
else if (keyword.name() == "VAPPARS")
handleVAPPARS(keyword, currentStep);
else if (keyword.name() == "DRVDT")
handleDRVDT(keyword, currentStep);
else if (keyword.name() == "WECON")
handleWECON(keyword, currentStep, parseContext);
else if (keyword.name() == "VAPPARS")
handleVAPPARS(keyword, currentStep);
else if (keyword.name() == "MESSAGES")
handleMESSAGES(keyword, currentStep);
else if (keyword.name() == "WECON")
handleWECON(keyword, currentStep, parseContext);
else if (keyword.name() == "WEFAC")
handleWEFAC(keyword, currentStep, parseContext);
else if (keyword.name() == "MESSAGES")
handleMESSAGES(keyword, currentStep);
else if (keyword.name() == "VFPINJ")
handleVFPINJ(keyword, unit_system, currentStep);
else if (keyword.name() == "WEFAC")
handleWEFAC(keyword, currentStep, parseContext);
else if (keyword.name() == "VFPPROD")
handleVFPPROD(keyword, unit_system, currentStep);
else if (keyword.name() == "VFPINJ")
handleVFPINJ(keyword, unit_system, currentStep);
else if (keyword.name() == "VFPPROD")
handleVFPPROD(keyword, unit_system, currentStep);
else if (geoModifiers.find( keyword.name() ) != geoModifiers.end()) {
bool supported = geoModifiers.at( keyword.name() );
if (supported) {
this->m_modifierDeck[ currentStep ].addKeyword( keyword );
m_events.addEvent( ScheduleEvents::GEO_MODIFIER , currentStep);
} else {
std::string msg = "OPM does not support grid property modifier " + keyword.name() + " in the Schedule section. Error at report: " + std::to_string( currentStep );
parseContext.handleError( ParseContext::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , msg );
}
else if (geoModifiers.find( keyword.name() ) != geoModifiers.end()) {
bool supported = geoModifiers.at( keyword.name() );
if (supported) {
this->m_modifierDeck[ currentStep ].addKeyword( keyword );
m_events.addEvent( ScheduleEvents::GEO_MODIFIER , currentStep);
} else {
std::string msg = "OPM does not support grid property modifier " + keyword.name() + " in the Schedule section. Error at report: " + std::to_string( currentStep );
parseContext.handleError( ParseContext::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , msg );
}
}
checkIfAllConnectionsIsShut(currentStep);
}
void Schedule::iterateScheduleSection(const ParseContext& parseContext , const SCHEDULESection& section , const EclipseGrid& grid,
const Eclipse3DProperties& eclipseProperties) {
size_t currentStep = 0;
const auto& unit_system = section.unitSystem();
std::vector<std::pair< const DeckKeyword* , size_t> > rftProperties;
size_t keywordIdx = 0;
while (true) {
const auto& keyword = section.getKeyword(keywordIdx);
if (keyword.name() == "ACTIONX") {
ActionX action(keyword);
while (true) {
keywordIdx++;
if (keywordIdx == section.size())
throw std::invalid_argument("Invalid ACTIONX section - missing ENDACTIO");
const auto& action_keyword = section.getKeyword(keywordIdx);
if (action_keyword.name() == "ENDACTIO")
break;
action.addKeyword(action_keyword);
}
} else
this->handleKeyword(currentStep, section, keywordIdx, keyword, parseContext, grid, eclipseProperties, unit_system, rftProperties);
keywordIdx++;
if (keywordIdx == section.size())
break;
}
checkIfAllConnectionsIsShut(currentStep);
for (auto rftPair = rftProperties.begin(); rftPair != rftProperties.end(); ++rftPair) {
const DeckKeyword& keyword = *rftPair->first;
size_t timeStep = rftPair->second;
@ -297,6 +330,7 @@ namespace Opm {
checkUnhandledKeywords(section);
}
void Schedule::checkUnhandledKeywords(const SCHEDULESection& /*section*/) const
{
}

View File

@ -26,6 +26,8 @@
#include <boost/test/unit_test.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ActionX.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
@ -52,3 +54,47 @@ ACTIONX
ActionX action2(kw);
BOOST_CHECK_EQUAL(action2.name(), "ACTION");
}
BOOST_AUTO_TEST_CASE(SCAN) {
const auto MISSING_END= std::string{ R"(
SCHEDULE
ACTIONX
'ACTION' /
WWCT OPX > 0.75 /
/
)"};
const auto WITH_WELSPECS = std::string{ R"(
SCHEDULE
WELSPECS
'W2' 'OP' 1 1 3.33 'OIL' 7*/
/
ACTIONX
'ACTION' /
WWCT OPX > 0.75 /
/
WELSPECS
'W1' 'OP' 1 1 3.33 'OIL' 7*/
/
ENDACTIO
)"};
Opm::Parser parser;
auto deck1 = parser.parseString(MISSING_END, Opm::ParseContext());
auto deck2 = parser.parseString(WITH_WELSPECS, Opm::ParseContext());
EclipseGrid grid1(10,10,10);
TableManager table ( deck1 );
Eclipse3DProperties eclipseProperties ( deck1 , table, grid1);
// The ACTIONX keyword has no matching 'ENDACTIO' -> exception
BOOST_CHECK_THROW(Schedule(deck1, grid1, eclipseProperties, Phases(true,true,true), ParseContext()), std::invalid_argument);
Schedule sched(deck2, grid1, eclipseProperties, Phases(true,true,true), ParseContext());
BOOST_CHECK( !sched.hasWell("W1") );
BOOST_CHECK( sched.hasWell("W2"));
}