ParseContext treatment of unknown wells/groups.
This commit is contained in:
parent
433b8ce73e
commit
d3f415c5aa
@ -20,6 +20,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Section.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseConfig.hpp>
|
||||
@ -35,11 +36,12 @@ namespace Opm {
|
||||
EclipseConfig::EclipseConfig(const Deck& deck,
|
||||
const Eclipse3DProperties& eclipse3DProperties,
|
||||
const GridDims& inputGrid,
|
||||
const Schedule& schedule) :
|
||||
const Schedule& schedule,
|
||||
const ParseContext& parseContext) :
|
||||
m_ioConfig( std::make_shared<IOConfig>(deck)),
|
||||
m_initConfig( std::make_shared<const InitConfig>(deck)),
|
||||
m_simulationConfig(std::make_shared<const SimulationConfig>(deck, eclipse3DProperties)),
|
||||
m_summaryConfig( deck, schedule, eclipse3DProperties, inputGrid.getNXYZ())
|
||||
m_summaryConfig( deck, schedule, eclipse3DProperties, parseContext , inputGrid.getNXYZ())
|
||||
{
|
||||
// Hmmm - would have thought this should iterate through the SCHEDULE section as well?
|
||||
if (Section::hasSOLUTION(deck)) {
|
||||
|
@ -32,7 +32,7 @@ namespace Opm {
|
||||
class IOConfig;
|
||||
class InitConfig;
|
||||
class SimulationConfig;
|
||||
|
||||
class ParseContext;
|
||||
|
||||
class EclipseConfig
|
||||
{
|
||||
@ -40,7 +40,8 @@ namespace Opm {
|
||||
EclipseConfig(const Deck& deck,
|
||||
const Eclipse3DProperties& eclipse3DProperties,
|
||||
const GridDims& gridDims,
|
||||
const Schedule& schedule);
|
||||
const Schedule& schedule,
|
||||
const ParseContext& parseContext);
|
||||
|
||||
std::shared_ptr< const IOConfig > getIOConfigConst() const;
|
||||
std::shared_ptr< IOConfig > getIOConfig() const;
|
||||
|
@ -61,7 +61,7 @@ namespace Opm {
|
||||
m_inputGrid( std::make_shared<EclipseGrid>(deck, nullptr) ),
|
||||
m_schedule( std::make_shared<Schedule>( m_parseContext, m_inputGrid, deck ) ),
|
||||
m_eclipseProperties( deck, m_tables, *m_inputGrid ),
|
||||
m_eclipseConfig( deck, m_eclipseProperties, m_gridDims, *m_schedule),
|
||||
m_eclipseConfig( deck, m_eclipseProperties, m_gridDims, *m_schedule , parseContext),
|
||||
m_inputNnc( deck, m_gridDims ),
|
||||
m_deckUnitSystem( deck.getActiveUnitSystem() )
|
||||
|
||||
@ -148,6 +148,10 @@ namespace Opm {
|
||||
return m_eclipseConfig.getInitConfig();
|
||||
}
|
||||
|
||||
const EclipseConfig& EclipseState::getEclipseConfig() const {
|
||||
return m_eclipseConfig;
|
||||
}
|
||||
|
||||
SimulationConfigConstPtr EclipseState::getSimulationConfig() const {
|
||||
return m_eclipseConfig.getSimulationConfig();
|
||||
}
|
||||
|
@ -90,6 +90,7 @@ namespace Opm {
|
||||
const Eclipse3DProperties& get3DProperties() const;
|
||||
|
||||
const TableManager& getTableManager() const;
|
||||
const EclipseConfig& getEclipseConfig() const;
|
||||
|
||||
// the unit system used by the deck. note that it is rarely needed to convert
|
||||
// units because internally to opm-parser everything is represented by SI
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/Parser/MessageContainer.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||
@ -37,6 +39,7 @@
|
||||
|
||||
#include <ert/ecl/ecl_smspec.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <functional>
|
||||
@ -64,37 +67,52 @@ namespace Opm {
|
||||
return __ALL_expands_keywords;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
When the error handling config says that the error should be
|
||||
logged, the handleMissingWell and handleMissingGroup routines
|
||||
cheat. Ideally we should have a MessageContainer instance around
|
||||
and pass that to the parseContext::handlError() routine. Instead
|
||||
we:
|
||||
|
||||
1. We instantiate new MessageContainer() which is just
|
||||
immediately dropped to floor, leaving the messages behind.
|
||||
|
||||
2. Print a message on stderr.
|
||||
|
||||
The case of incorrectly/missing well/group names in the SUMMARY
|
||||
section did just not seem important enough to warrant the
|
||||
refactoring required to pass a mutable proper MessageContainer
|
||||
all the way down here.
|
||||
*/
|
||||
|
||||
static void handleMissingWell( const ParseContext& parseContext , const std::string& keyword, const std::string& well) {
|
||||
std::string msg = std::string("Error in keyword:") + keyword + std::string(" No such well: ") + well;
|
||||
MessageContainer msgContainer;
|
||||
if (parseContext.get( ParseContext::SUMMARY_UNKNOWN_WELL) == InputError::WARN)
|
||||
std::cerr << "ERROR: " << msg << std::endl;
|
||||
|
||||
parseContext.handleError( ParseContext::SUMMARY_UNKNOWN_WELL , msgContainer , msg );
|
||||
}
|
||||
|
||||
|
||||
static void handleMissingGroup( const ParseContext& parseContext , const std::string& keyword, const std::string& group) {
|
||||
std::string msg = std::string("Error in keyword:") + keyword + std::string(" No such group: ") + group;
|
||||
MessageContainer msgContainer;
|
||||
if (parseContext.get( ParseContext::SUMMARY_UNKNOWN_GROUP) == InputError::WARN)
|
||||
std::cerr << "ERROR: " << msg << std::endl;
|
||||
|
||||
parseContext.handleError( ParseContext::SUMMARY_UNKNOWN_GROUP , msgContainer , msg );
|
||||
}
|
||||
|
||||
|
||||
|
||||
template< typename T >
|
||||
static std::string name( const T* x ) {
|
||||
return x->name();
|
||||
}
|
||||
|
||||
static inline std::vector< ERT::smspec_node > keywordW(
|
||||
const DeckKeyword& keyword,
|
||||
const Schedule& schedule ) {
|
||||
|
||||
const auto mknode = [&keyword]( const std::string& name ) {
|
||||
return ERT::smspec_node( ECL_SMSPEC_WELL_VAR, name, keyword.name() );
|
||||
};
|
||||
|
||||
const auto missing = [&schedule]( const std::string& name ) {
|
||||
return !schedule.hasWell( name );
|
||||
};
|
||||
|
||||
const auto& item = keyword.getDataRecord().getDataItem();
|
||||
auto wnames = item.hasValue( 0 )
|
||||
? item.getData< std::string >()
|
||||
: fun::map( name< Well >, schedule.getWells() );
|
||||
|
||||
/* filter all requested names that were not in the Deck */
|
||||
wnames.erase(
|
||||
std::remove_if( wnames.begin(), wnames.end(), missing ),
|
||||
wnames.end() );
|
||||
|
||||
return fun::map( mknode, wnames );
|
||||
}
|
||||
|
||||
static inline std::vector< ERT::smspec_node > keywordW(
|
||||
static inline std::vector< ERT::smspec_node > defaultW(
|
||||
const std::string& keyword,
|
||||
const Schedule& schedule ) {
|
||||
|
||||
@ -102,47 +120,60 @@ namespace Opm {
|
||||
return ERT::smspec_node( ECL_SMSPEC_WELL_VAR, wname, keyword );
|
||||
};
|
||||
|
||||
auto wnames = fun::map( name< Well >, schedule.getWells() );
|
||||
return fun::map( mknode, wnames );
|
||||
return fun::map( mknode, fun::map( name< Well >, schedule.getWells() ) );
|
||||
}
|
||||
|
||||
static inline std::vector< ERT::smspec_node > keywordG(
|
||||
const DeckKeyword& keyword,
|
||||
const Schedule& schedule ) {
|
||||
|
||||
const auto mknode = [&keyword]( const std::string& name ) {
|
||||
return ERT::smspec_node( ECL_SMSPEC_GROUP_VAR, name, keyword.name() );
|
||||
};
|
||||
|
||||
const auto missing = [&schedule]( const std::string& name ) {
|
||||
return !schedule.hasGroup( name );
|
||||
};
|
||||
|
||||
static inline std::vector< ERT::smspec_node > keywordW(const ParseContext& parseContext,
|
||||
const DeckKeyword& keyword,
|
||||
const Schedule& schedule ) {
|
||||
|
||||
const auto& item = keyword.getDataRecord().getDataItem();
|
||||
auto gnames = item.hasValue( 0 )
|
||||
? item.getData< std::string >()
|
||||
: fun::map( name< Group >, schedule.getGroups() );
|
||||
|
||||
gnames.erase(
|
||||
std::remove_if( gnames.begin(), gnames.end(), missing ),
|
||||
gnames.end() );
|
||||
|
||||
return fun::map( mknode, gnames );
|
||||
if (item.hasValue( 0 )) {
|
||||
std::vector<ERT::smspec_node> nodes;
|
||||
for (const std::string& well : item.getData< std::string >()) {
|
||||
if (schedule.hasWell( well ))
|
||||
nodes.emplace_back( ECL_SMSPEC_WELL_VAR , well , keyword.name());
|
||||
else
|
||||
handleMissingWell( parseContext , keyword.name() , well );
|
||||
}
|
||||
return nodes;
|
||||
} else
|
||||
return defaultW( keyword.name() , schedule );
|
||||
}
|
||||
|
||||
static inline std::vector< ERT::smspec_node > keywordG(
|
||||
const std::string& keyword,
|
||||
const Schedule& schedule ) {
|
||||
|
||||
const auto mknode = [&keyword]( const std::string& name ) {
|
||||
return ERT::smspec_node( ECL_SMSPEC_GROUP_VAR, name, keyword );
|
||||
|
||||
static inline std::vector< ERT::smspec_node > defaultG(const std::string& keyword,
|
||||
const Schedule& schedule ) {
|
||||
|
||||
const auto mknode = [&keyword]( const std::string& gname ) {
|
||||
return ERT::smspec_node( ECL_SMSPEC_GROUP_VAR, gname, keyword );
|
||||
};
|
||||
|
||||
auto gnames = fun::map( name< Group >, schedule.getGroups() );
|
||||
return fun::map( mknode, gnames );
|
||||
return fun::map( mknode, fun::map( name< Group >, schedule.getGroups() ) );
|
||||
}
|
||||
|
||||
static inline std::vector< ERT::smspec_node > keywordG(const ParseContext& parseContext,
|
||||
const DeckKeyword& keyword,
|
||||
const Schedule& schedule ) {
|
||||
|
||||
const auto& item = keyword.getDataRecord().getDataItem();
|
||||
if (item.hasValue( 0 )) {
|
||||
std::vector<ERT::smspec_node> nodes;
|
||||
for (const std::string& group : item.getData< std::string >()) {
|
||||
if (schedule.hasGroup( group ))
|
||||
nodes.emplace_back( ECL_SMSPEC_GROUP_VAR , group , keyword.name());
|
||||
else
|
||||
handleMissingGroup( parseContext , keyword.name() , group );
|
||||
}
|
||||
return nodes;
|
||||
} else
|
||||
return defaultG( keyword.name() , schedule );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline std::vector< ERT::smspec_node > keywordF(
|
||||
const DeckKeyword& keyword ) {
|
||||
|
||||
@ -217,10 +248,10 @@ namespace Opm {
|
||||
return fun::map( mknode, regions );
|
||||
}
|
||||
|
||||
static inline std::vector< ERT::smspec_node > keywordC(
|
||||
const DeckKeyword& keyword,
|
||||
const Schedule& schedule,
|
||||
std::array< int, 3 > dims ) {
|
||||
static inline std::vector< ERT::smspec_node > keywordC(const ParseContext& parseContext,
|
||||
const DeckKeyword& keyword,
|
||||
const Schedule& schedule,
|
||||
std::array< int, 3 > dims ) {
|
||||
|
||||
std::vector< ERT::smspec_node > nodes;
|
||||
const auto& keywordstring = keyword.name();
|
||||
@ -251,18 +282,22 @@ namespace Opm {
|
||||
|
||||
} else {
|
||||
const auto& name = record.getItem( 0 ).get< std::string >( 0 );
|
||||
/* all specified */
|
||||
if( !record.getItem( 1 ).defaultApplied( 0 ) ) {
|
||||
auto ijk = getijk( record, 1 );
|
||||
nodes.emplace_back( keywordstring, name, dims.data(), ijk.data() );
|
||||
}
|
||||
else {
|
||||
/* well specified, block coordinates defaulted */
|
||||
for( const auto& completion : *schedule.getWell( name )->getCompletions( last_timestep ) ) {
|
||||
auto ijk = getijk( *completion );
|
||||
nodes.emplace_back( keywordstring, name, dims.data(), ijk.data() );
|
||||
}
|
||||
}
|
||||
if (!schedule.hasWell( name ))
|
||||
handleMissingWell( parseContext , keyword.name() , name );
|
||||
else {
|
||||
/* all specified */
|
||||
if( !record.getItem( 1 ).defaultApplied( 0 ) ) {
|
||||
auto ijk = getijk( record, 1 );
|
||||
nodes.emplace_back( keywordstring, name, dims.data(), ijk.data() );
|
||||
}
|
||||
else {
|
||||
/* well specified, block coordinates defaulted */
|
||||
for( const auto& completion : *schedule.getWell( name )->getCompletions( last_timestep ) ) {
|
||||
auto ijk = getijk( *completion );
|
||||
nodes.emplace_back( keywordstring, name, dims.data(), ijk.data() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,16 +307,17 @@ namespace Opm {
|
||||
std::vector< ERT::smspec_node > handleKW( const DeckKeyword& keyword,
|
||||
const Schedule& schedule,
|
||||
const Eclipse3DProperties& props,
|
||||
const ParseContext& parseContext,
|
||||
std::array< int, 3 > n_xyz ) {
|
||||
const auto var_type = ecl_smspec_identify_var_type( keyword.name().c_str() );
|
||||
|
||||
switch( var_type ) {
|
||||
case ECL_SMSPEC_WELL_VAR: return keywordW( keyword, schedule );
|
||||
case ECL_SMSPEC_GROUP_VAR: return keywordG( keyword, schedule );
|
||||
case ECL_SMSPEC_WELL_VAR: return keywordW( parseContext , keyword, schedule );
|
||||
case ECL_SMSPEC_GROUP_VAR: return keywordG( parseContext , keyword, schedule );
|
||||
case ECL_SMSPEC_FIELD_VAR: return keywordF( keyword );
|
||||
case ECL_SMSPEC_BLOCK_VAR: return keywordB( keyword, n_xyz );
|
||||
case ECL_SMSPEC_REGION_VAR: return keywordR( keyword, props, n_xyz );
|
||||
case ECL_SMSPEC_COMPLETION_VAR: return keywordC( keyword, schedule, n_xyz );
|
||||
case ECL_SMSPEC_COMPLETION_VAR: return keywordC( parseContext , keyword, schedule, n_xyz );
|
||||
|
||||
default: return {};
|
||||
}
|
||||
@ -296,10 +332,10 @@ namespace Opm {
|
||||
const auto var_type = ecl_smspec_identify_var_type(keyword.c_str());
|
||||
switch (var_type) {
|
||||
case ECL_SMSPEC_WELL_VAR:
|
||||
for(auto&k :keywordW(keyword, schedule)) all.push_back(k);
|
||||
for(auto&k :defaultW(keyword, schedule)) all.push_back(k);
|
||||
break;
|
||||
case ECL_SMSPEC_GROUP_VAR:
|
||||
for(auto& k:keywordG(keyword, schedule)) all.push_back(k);
|
||||
for(auto& k:defaultG(keyword, schedule)) all.push_back(k);
|
||||
break;
|
||||
case ECL_SMSPEC_FIELD_VAR:
|
||||
for(auto& k:keywordF(keyword)) all.push_back(k);
|
||||
@ -315,22 +351,24 @@ namespace Opm {
|
||||
return all;
|
||||
}
|
||||
|
||||
SummaryConfig::SummaryConfig( const Deck& deck, const EclipseState& es )
|
||||
SummaryConfig::SummaryConfig( const Deck& deck, const EclipseState& es , const ParseContext& parseContext)
|
||||
: SummaryConfig( deck,
|
||||
*es.getSchedule(),
|
||||
es.get3DProperties(),
|
||||
parseContext,
|
||||
dimensions( *es.getInputGrid() ) )
|
||||
{}
|
||||
|
||||
SummaryConfig::SummaryConfig( const Deck& deck,
|
||||
const Schedule& schedule,
|
||||
const Eclipse3DProperties& props,
|
||||
const ParseContext& parseContext,
|
||||
std::array< int, 3 > n_xyz ) {
|
||||
|
||||
SUMMARYSection section( deck );
|
||||
|
||||
using namespace std::placeholders;
|
||||
const auto handler = std::bind( handleKW, _1, schedule, props, n_xyz );
|
||||
const auto handler = std::bind( handleKW, _1, schedule, props, parseContext , n_xyz );
|
||||
|
||||
/* This line of code does not compile on VS2015
|
||||
* this->keywords = fun::concat( fun::map( handler, section ) );
|
||||
|
@ -32,16 +32,17 @@ namespace Opm {
|
||||
class EclipseState;
|
||||
class ParserKeyword;
|
||||
class Schedule;
|
||||
class ParseContext;
|
||||
|
||||
class SummaryConfig {
|
||||
public:
|
||||
typedef std::vector< ERT::smspec_node >::const_iterator const_iterator;
|
||||
|
||||
SummaryConfig( const Deck&, const EclipseState& );
|
||||
SummaryConfig( const Deck&, const EclipseState& , const ParseContext& );
|
||||
SummaryConfig( const Deck&, const Schedule&,
|
||||
const Eclipse3DProperties&, std::array< int, 3 > );
|
||||
const Eclipse3DProperties&, const ParseContext&, std::array< int, 3 > );
|
||||
SummaryConfig( const Deck&, const Schedule&,
|
||||
const Eclipse3DProperties&, int, int, int );
|
||||
const Eclipse3DProperties&, const ParseContext&, int, int, int );
|
||||
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
@ -95,10 +95,10 @@ static std::vector< std::string > sorted_key_names( const SummaryConfig& summary
|
||||
return ret;
|
||||
}
|
||||
|
||||
static SummaryConfig createSummary( std::string input ) {
|
||||
static SummaryConfig createSummary( std::string input , const ParseContext& parseContext = ParseContext()) {
|
||||
auto deck = createDeck( input );
|
||||
EclipseState state( deck, ParseContext() );
|
||||
return SummaryConfig( *deck, state );
|
||||
EclipseState state( deck, parseContext );
|
||||
return state.getEclipseConfig().getSummaryConfig();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(wells_all) {
|
||||
@ -124,16 +124,6 @@ BOOST_AUTO_TEST_CASE(wells_select) {
|
||||
names.begin(), names.end() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(wells_select_unknown_well) {
|
||||
const auto input = "WWCT\n'W_1' 'WX2' 'unknown'/\n";
|
||||
const auto summary = createSummary( input );
|
||||
const auto wells = { "WX2", "W_1" };
|
||||
const auto names = sorted_names( summary );
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(
|
||||
wells.begin(), wells.end(),
|
||||
names.begin(), names.end() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(fields) {
|
||||
const auto input = "FOPT\n";
|
||||
@ -234,3 +224,41 @@ BOOST_AUTO_TEST_CASE(summary_ALL) {
|
||||
key_names.begin(), key_names.end());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(INVALID_WELL1) {
|
||||
ParseContext parseContext;
|
||||
const auto input = "CWIR\n"
|
||||
"NEW-WELL /\n"
|
||||
"/\n";
|
||||
parseContext.updateKey( ParseContext::SUMMARY_UNKNOWN_WELL , InputError::THROW_EXCEPTION );
|
||||
BOOST_CHECK_THROW( createSummary( input , parseContext ) , std::invalid_argument);
|
||||
|
||||
parseContext.updateKey( ParseContext::SUMMARY_UNKNOWN_WELL , InputError::IGNORE );
|
||||
BOOST_CHECK_NO_THROW( createSummary( input , parseContext ))
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(INVALID_WELL2) {
|
||||
ParseContext parseContext;
|
||||
const auto input = "WWCT\n"
|
||||
" NEW-WELL /\n";
|
||||
parseContext.updateKey( ParseContext::SUMMARY_UNKNOWN_WELL , InputError::THROW_EXCEPTION );
|
||||
BOOST_CHECK_THROW( createSummary( input , parseContext ) , std::invalid_argument);
|
||||
|
||||
parseContext.updateKey( ParseContext::SUMMARY_UNKNOWN_WELL , InputError::IGNORE );
|
||||
BOOST_CHECK_NO_THROW( createSummary( input , parseContext ))
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(INVALID_GROUP) {
|
||||
ParseContext parseContext;
|
||||
const auto input = "GWCT\n"
|
||||
" NEW-GR /\n";
|
||||
parseContext.updateKey( ParseContext::SUMMARY_UNKNOWN_GROUP , InputError::THROW_EXCEPTION );
|
||||
BOOST_CHECK_THROW( createSummary( input , parseContext ) , std::invalid_argument);
|
||||
|
||||
parseContext.updateKey( ParseContext::SUMMARY_UNKNOWN_GROUP , InputError::IGNORE );
|
||||
BOOST_CHECK_NO_THROW( createSummary( input , parseContext ))
|
||||
}
|
||||
|
@ -69,6 +69,9 @@ namespace Opm {
|
||||
addKey(UNSUPPORTED_INITIAL_THPRES);
|
||||
|
||||
addKey(INTERNAL_ERROR_UNINITIALIZED_THPRES);
|
||||
|
||||
addKey(SUMMARY_UNKNOWN_WELL);
|
||||
addKey(SUMMARY_UNKNOWN_GROUP);
|
||||
}
|
||||
|
||||
void ParseContext::initEnv() {
|
||||
@ -242,6 +245,9 @@ namespace Opm {
|
||||
const std::string ParseContext::INTERNAL_ERROR_UNINITIALIZED_THPRES = "INTERNAL_ERROR_UNINITIALIZED_THPRES";
|
||||
|
||||
const std::string ParseContext::PARSE_MISSING_SECTIONS = "PARSE_MISSING_SECTIONS";
|
||||
|
||||
const std::string ParseContext::SUMMARY_UNKNOWN_WELL = "SUMMARY_UNKNOWN_WELL";
|
||||
const std::string ParseContext::SUMMARY_UNKNOWN_GROUP = "SUMMARY_UNKNOWN_GROUP";
|
||||
}
|
||||
|
||||
|
||||
|
@ -207,6 +207,14 @@ namespace Opm {
|
||||
*/
|
||||
const static std::string PARSE_MISSING_SECTIONS;
|
||||
|
||||
|
||||
/*
|
||||
If you have configured a specific well in the summary section,
|
||||
which is not recognized - how to handle.
|
||||
*/
|
||||
const static std::string SUMMARY_UNKNOWN_WELL;
|
||||
const static std::string SUMMARY_UNKNOWN_GROUP;
|
||||
|
||||
private:
|
||||
void initDefault();
|
||||
void initEnv();
|
||||
|
Loading…
Reference in New Issue
Block a user