Add INVALID_WELL parse context

Handle invalid wellpatterns for COMPDAT.

Given a deck with:

----
WELSPECS
  'PROD' 'G1'  10 10 8400 'OIL' /
/
COMPDAT
  'SOMETHINGELSE' 10 10 3 3 'OPEN' 1* 1* 0.5 /
/
----

OPM will now by default abort and inform the user that no well match
"SOMETHINGELSE".
This commit is contained in:
Lars Petter Øren Hauge
2018-04-22 10:25:17 +02:00
parent 5dd34b1308
commit f2cb5fe9de
9 changed files with 91 additions and 10 deletions

View File

@@ -25,7 +25,7 @@
#include <memory>
#include <string>
#include <vector>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Util/Value.hpp>
@@ -37,6 +37,7 @@ namespace Opm {
class Well;
class EclipseGrid;
class Eclipse3DProperties;
class Schedule;
class Completion {
public:
@@ -81,7 +82,9 @@ namespace Opm {
fromCOMPDAT( const EclipseGrid& grid,
const Eclipse3DProperties& eclipseProperties,
const DeckKeyword& compdatKeyword,
const std::vector< const Well* >& );
const std::vector< const Well* >&,
const ParseContext&,
const Schedule&);
bool operator==( const Completion& ) const;
bool operator!=( const Completion& ) const;

View File

@@ -105,6 +105,7 @@ namespace Opm
std::vector< const Group* > getGroups() const;
const Tuning& getTuning() const;
const MessageLimits& getMessageLimits() const;
void InvalidWellPattern (const std::string& wellNamePattern, const ParseContext& parseContext, const DeckKeyword& keyword) const;
const Events& getEvents() const;
const Deck& getModifierDeck(size_t timeStep) const;
@@ -149,7 +150,7 @@ namespace Opm
void handleWCONHIST( const DeckKeyword& keyword, size_t currentStep);
void handleWCONPROD( const DeckKeyword& keyword, size_t currentStep);
void handleWGRUPCON( const DeckKeyword& keyword, size_t currentStep);
void handleCOMPDAT( const DeckKeyword& keyword, size_t currentStep, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties);
void handleCOMPDAT( const DeckKeyword& keyword, size_t currentStep, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties, const ParseContext& parseContext);
void handleCOMPLUMP( const DeckKeyword& keyword, size_t currentStep );
void handleWELSEGS( const DeckKeyword& keyword, size_t currentStep);
void handleCOMPSEGS( const DeckKeyword& keyword, size_t currentStep);

View File

@@ -243,6 +243,13 @@ namespace Opm {
const static std::string SUMMARY_UNKNOWN_WELL;
const static std::string SUMMARY_UNKNOWN_GROUP;
/*
A well must be specified (e.g. WELSPECS) and have completions
(e.g. COMPDAT) to be able to set control mode (e.g. WCONPROD).
A well missing specification and/or completion(s) will throw.
*/
const static std::string SCHEDULE_INVALID_WELL;
private:
void initDefault();
void initEnv();

View File

@@ -25,11 +25,13 @@
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Completion.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Util/Value.hpp>
namespace Opm {
@@ -195,7 +197,9 @@ namespace Opm {
Completion::fromCOMPDAT( const EclipseGrid& grid ,
const Eclipse3DProperties& eclipseProperties,
const DeckKeyword& compdatKeyword,
const std::vector< const Well* >& wells ) {
const std::vector< const Well* >& wells,
const ParseContext& parseContext,
const Schedule& schedule) {
std::map< std::string, std::vector< Completion > > res;
std::vector< int > prev_compls( wells.size(), 0 );
@@ -209,7 +213,8 @@ namespace Opm {
auto well = std::find_if( wells.begin(), wells.end(), name_eq );
if( well == wells.end() ) continue;
if( well == wells.end() )
schedule.InvalidWellPattern(wellname, parseContext, compdatKeyword);
const auto index = std::distance( wells.begin(), well );

View File

@@ -193,7 +193,7 @@ namespace Opm {
handleWGRUPCON(keyword, currentStep);
else if (keyword.name() == "COMPDAT")
handleCOMPDAT(keyword, currentStep, grid, eclipseProperties);
handleCOMPDAT(keyword, currentStep, grid, eclipseProperties, parseContext);
else if (keyword.name() == "WELSEGS")
handleWELSEGS(keyword, currentStep);
@@ -1325,9 +1325,9 @@ namespace Opm {
void Schedule::handleCOMPDAT( const DeckKeyword& keyword, size_t currentStep, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties) {
void Schedule::handleCOMPDAT( const DeckKeyword& keyword, size_t currentStep, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties, const ParseContext& parseContext) {
const auto wells = this->getWells( currentStep );
auto completions = Completion::fromCOMPDAT( grid, eclipseProperties, keyword, wells );
auto completions = Completion::fromCOMPDAT( grid, eclipseProperties, keyword, wells, parseContext, *this );
for( const auto pair : completions ) {
auto& well = this->m_wells.get( pair.first );
@@ -1449,6 +1449,12 @@ namespace Opm {
}
}
void Schedule::InvalidWellPattern( const std::string& wellNamePattern, const ParseContext& parseContext, const DeckKeyword& keyword ) const {
std::string msg = "Error when handling " + keyword.name() +". No wells match " +
wellNamePattern;
parseContext.handleError( ParseContext::SCHEDULE_INVALID_WELL, msg );
}
const TimeMap& Schedule::getTimeMap() const {
return this->m_timeMap;
}

View File

@@ -85,6 +85,7 @@ namespace Opm {
addKey(SUMMARY_UNKNOWN_WELL, InputError::THROW_EXCEPTION);
addKey(SUMMARY_UNKNOWN_GROUP, InputError::THROW_EXCEPTION);
addKey(SCHEDULE_INVALID_WELL, InputError::THROW_EXCEPTION);
}
void ParseContext::initEnv() {
@@ -257,6 +258,8 @@ namespace Opm {
const std::string ParseContext::SUMMARY_UNKNOWN_WELL = "SUMMARY_UNKNOWN_WELL";
const std::string ParseContext::SUMMARY_UNKNOWN_GROUP = "SUMMARY_UNKNOWN_GROUP";
const std::string ParseContext::SCHEDULE_INVALID_WELL = "SCHEDULE_INVALID_WELL";
}

View File

@@ -472,3 +472,60 @@ BOOST_AUTO_TEST_CASE(test_1arg_constructor) {
BOOST_CHECK_EQUAL(ctx.get(ParseContext::PARSE_RANDOM_SLASH), InputError::IGNORE);
}
}
BOOST_AUTO_TEST_CASE( test_invalid_wtemplate_config ) {
const std::string defDeckString = R"(
START -- 0
10 'JAN' 2000 /
RUNSPEC
DIMENS
10 10 10 /
GRID
DX
1000*0.25 /
DY
1000*0.25 /
DZ
1000*0.25 /
TOPS
100*0.25 /
SCHEDULE
DATES -- 1
10 OKT 2008 /
/
WELSPECS
'PROD' 'G1' 10 10 100 'OIL' /
'INJ' 'G1' 3 3 100 'WATER' /
/
)";
ParseContext parseContext;
Parser parser;
parseContext.update(ParseContext::SCHEDULE_INVALID_WELL , InputError::THROW_EXCEPTION );
std::vector < std::string > testSamples;
std::string testSample;
// Invalid well name in COMPDAT
testSample = R"(
COMPDAT
'SOMETHINGELSE' 10 10 3 3 'OPEN' 1* 1* 0.5 /
/
)";
testSamples.push_back(testSample);
std::string deckinput;
for (std::string sample : testSamples) {
deckinput = defDeckString + sample;
auto deckUnSupported = parser.parseString( deckinput , parseContext );
EclipseGrid grid( deckUnSupported );
TableManager table ( deckUnSupported );
Eclipse3DProperties eclipseProperties ( deckUnSupported , table, grid);
BOOST_CHECK_THROW( Schedule( deckUnSupported , grid , eclipseProperties, Phases(true, true, true) , parseContext), std::invalid_argument );
}
}

View File

@@ -1479,7 +1479,6 @@ BOOST_AUTO_TEST_CASE( COMPDAT_multiple_wells ) {
'W1' 0 0 1 1 'SHUT' 1* / -- regular completion (1)
'W1' 0 0 2 2 'SHUT' 1* / -- regular completion (2)
'W1' 0 0 3 4 'SHUT' 1* / -- two completions in one record (3, 4)
'W3' 0 0 1 3 'SHUT' 1* / -- doesn't exist, ignored
'W2' 0 0 3 3 'SHUT' 1* / -- regular completion (1)
'W2' 0 0 1 3 'SHUT' 1* / -- two completions (one exist already) (2, 3)
/

View File

@@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE( CreateCompletionsFromKeyword ) {
const auto& COMPDAT1 = deck.getKeyword("COMPDAT" , 1);
const auto wells = schedule.getWells( 0 );
auto completions = Completion::fromCOMPDAT( grid, eclipseProperties, COMPDAT1, wells );
auto completions = Completion::fromCOMPDAT( grid, eclipseProperties, COMPDAT1, wells, ParseContext(), schedule );
BOOST_CHECK_EQUAL( 3U , completions.size() );
BOOST_CHECK( completions.find("W_1") != completions.end() );