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:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
/
|
||||
|
||||
@@ -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() );
|
||||
|
||||
Reference in New Issue
Block a user