Merge pull request #2059 from joakim-hove/summary-completion
Summary completion
This commit is contained in:
commit
bb905eb545
@ -526,6 +526,71 @@ inline quantity rate( const fn_args& args ) {
|
||||
return { sum, rate_unit< phase >() };
|
||||
}
|
||||
|
||||
template< rt phase, bool injection = true >
|
||||
inline quantity ratel( const fn_args& args ) {
|
||||
const quantity zero = { 0, rate_unit< phase >() };
|
||||
|
||||
const auto& well = args.schedule_wells.front();
|
||||
const auto& name = well.name();
|
||||
if( args.wells.count( name ) == 0 ) return zero;
|
||||
const auto& well_data = args.wells.at( name );
|
||||
if (well_data.current_control.isProducer == injection) return zero;
|
||||
|
||||
double sum = 0;
|
||||
const auto& connections = well.getConnections( args.num );
|
||||
for (const auto& conn_ptr : connections) {
|
||||
const size_t global_index = conn_ptr->global_index();
|
||||
const auto& conn_data = std::find_if(well_data.connections.begin(),
|
||||
well_data.connections.end(),
|
||||
[global_index] (const Opm::data::Connection cdata)
|
||||
{
|
||||
return cdata.index == global_index;
|
||||
});
|
||||
|
||||
if (conn_data != well_data.connections.end()) {
|
||||
double eff_fac = efac( args.eff_factors, name );
|
||||
sum += conn_data->rates.get( phase, 0.0 ) * eff_fac;
|
||||
}
|
||||
}
|
||||
if( !injection ) sum *= -1;
|
||||
|
||||
if (phase == rt::polymer || phase == rt::brine) return { sum, measure::mass_rate };
|
||||
return { sum, rate_unit< phase >() };
|
||||
}
|
||||
|
||||
template< rt phase, bool injection = true >
|
||||
inline quantity cratel( const fn_args& args ) {
|
||||
const quantity zero = { 0, rate_unit< phase >() };
|
||||
|
||||
const auto& well = args.schedule_wells.front();
|
||||
const auto& name = well.name();
|
||||
if( args.wells.count( name ) == 0 ) return zero;
|
||||
const auto& well_data = args.wells.at( name );
|
||||
if (well_data.current_control.isProducer == injection) return zero;
|
||||
|
||||
double sum = 0;
|
||||
const auto& conn0 = well.getConnections().getFromGlobalIndex( args.num - 1);
|
||||
const auto& connections = well.getConnections(conn0.complnum()) ;
|
||||
for (const auto& conn_ptr : connections) {
|
||||
const size_t global_index = conn_ptr->global_index();
|
||||
const auto& conn_data = std::find_if(well_data.connections.begin(),
|
||||
well_data.connections.end(),
|
||||
[global_index] (const Opm::data::Connection cdata)
|
||||
{
|
||||
return cdata.index == global_index;
|
||||
});
|
||||
if (conn_data != well_data.connections.end()) {
|
||||
double eff_fac = efac( args.eff_factors, name );
|
||||
sum += conn_data->rates.get( phase, 0.0 ) * eff_fac;
|
||||
}
|
||||
}
|
||||
if( !injection ) sum *= -1;
|
||||
|
||||
if (phase == rt::polymer || phase == rt::brine) return { sum, measure::mass_rate };
|
||||
return { sum, rate_unit< phase >() };
|
||||
}
|
||||
|
||||
|
||||
template< bool injection >
|
||||
inline quantity flowing( const fn_args& args ) {
|
||||
const auto& wells = args.wells;
|
||||
@ -1056,6 +1121,21 @@ static const std::unordered_map< std::string, ofun > funs = {
|
||||
|
||||
{ "WWPR", rate< rt::wat, producer > },
|
||||
{ "WOPR", rate< rt::oil, producer > },
|
||||
{ "WWPTL",mul(ratel< rt::wat, producer >, duration) },
|
||||
{ "WGPTL",mul(ratel< rt::gas, producer >, duration) },
|
||||
{ "WOPTL",mul(ratel< rt::oil, producer >, duration) },
|
||||
{ "WWPRL",ratel< rt::wat, producer > },
|
||||
{ "WGPRL",ratel< rt::gas, producer > },
|
||||
{ "WOPRL",ratel< rt::oil, producer > },
|
||||
{ "WOFRL",ratel< rt::oil, producer > },
|
||||
{ "WWIRL",ratel< rt::wat, injector> },
|
||||
{ "WWITL",mul(ratel< rt::wat, injector>, duration) },
|
||||
{ "WGIRL",ratel< rt::gas, injector> },
|
||||
{ "WGITL",mul(ratel< rt::gas, injector>, duration) },
|
||||
{ "WLPTL",mul( sum(ratel<rt::wat, producer>, ratel<rt::oil, producer>), duration)},
|
||||
{ "WWCTL", div( ratel< rt::wat, producer >,
|
||||
sum( ratel< rt::wat, producer >, ratel< rt::oil, producer > ) ) },
|
||||
{ "WGORL", div( ratel< rt::gas, producer >, ratel< rt::oil, producer > ) },
|
||||
{ "WGPR", rate< rt::gas, producer > },
|
||||
{ "WEPR", rate< rt::energy, producer > },
|
||||
{ "WTPRHEA", rate< rt::energy, producer > },
|
||||
@ -1270,6 +1350,20 @@ static const std::unordered_map< std::string, ofun > funs = {
|
||||
|
||||
{ "GVPRT", res_vol_production_target },
|
||||
|
||||
{ "CGIRL", cratel< rt::gas, injector> },
|
||||
{ "CGITL", mul( cratel< rt::gas, injector>, duration) },
|
||||
{ "CWIRL", cratel< rt::wat, injector> },
|
||||
{ "CWITL", mul( cratel< rt::wat, injector>, duration) },
|
||||
{ "CWPRL", cratel< rt::wat, producer > },
|
||||
{ "CWPTL", mul( cratel< rt::wat, producer >, duration) },
|
||||
{ "COPRL", cratel< rt::oil, producer > },
|
||||
{ "COPTL", mul( cratel< rt::oil, producer >, duration) },
|
||||
{ "CGPRL", cratel< rt::gas, producer > },
|
||||
{ "CGPTL", mul( cratel< rt::gas, producer >, duration) },
|
||||
{ "COFRL", cratel< rt::oil, producer > },
|
||||
{ "CGORL", div( cratel< rt::gas, producer >, cratel< rt::oil, producer > ) },
|
||||
{ "CWCTL", div( cratel< rt::wat, producer >,
|
||||
sum( cratel< rt::wat, producer >, cratel< rt::oil, producer > ) ) },
|
||||
{ "CWIR", crate< rt::wat, injector > },
|
||||
{ "CGIR", crate< rt::gas, injector > },
|
||||
{ "CCIR", crate< rt::polymer, injector > },
|
||||
@ -2276,13 +2370,27 @@ namespace Evaluator {
|
||||
bool Factory::isFunctionRelation()
|
||||
{
|
||||
auto pos = funs.find(this->node_->keyword);
|
||||
if (pos == funs.end())
|
||||
return false;
|
||||
if (pos != funs.end()) {
|
||||
// 'node_' represents a functional relation.
|
||||
// Capture evaluation function and return true.
|
||||
this->paramFunction_ = pos->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 'node_' represents a functional relation.
|
||||
// Capture evaluation function and return true.
|
||||
this->paramFunction_ = pos->second;
|
||||
return true;
|
||||
auto keyword = this->node_->keyword;
|
||||
auto dash_pos = keyword.find("_");
|
||||
if (dash_pos != std::string::npos)
|
||||
keyword = keyword.substr(0, dash_pos);
|
||||
|
||||
pos = funs.find(keyword);
|
||||
if (pos != funs.end()) {
|
||||
// 'node_' represents a functional relation.
|
||||
// Capture evaluation function and return true.
|
||||
this->paramFunction_ = pos->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Factory::isUserDefined()
|
||||
@ -2344,7 +2452,7 @@ void reportUnsupportedKeywords(std::vector<Opm::SummaryConfigNode> keywords)
|
||||
for (auto node = keywords.begin(); node != uend; ++node) {
|
||||
const auto& location = node->location();
|
||||
Opm::OpmLog::warning(Opm::OpmInputError::format("Unhandled summary keyword {keyword}\n"
|
||||
"In {file} line {line}", location));
|
||||
"In {file} line {line}", location));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,6 +274,43 @@ namespace {
|
||||
return (keyword[0] == 'A') && (keyword != "ALL");
|
||||
}
|
||||
|
||||
bool is_connection_completion(const std::string& keyword)
|
||||
{
|
||||
if (keyword[0] != 'C')
|
||||
return false;
|
||||
|
||||
if (keyword.back() != 'L')
|
||||
return false;
|
||||
|
||||
if (is_udq(keyword))
|
||||
return false;
|
||||
|
||||
if (keyword.size() != 5)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_well_completion(const std::string& keyword)
|
||||
{
|
||||
if (keyword[0] != 'W')
|
||||
return false;
|
||||
|
||||
if (keyword.back() != 'L')
|
||||
return false;
|
||||
|
||||
if (is_liquid_phase(keyword))
|
||||
return false;
|
||||
|
||||
if (is_udq(keyword))
|
||||
return false;
|
||||
|
||||
if (keyword == "WMCTL")
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_node_keyword(const std::string& keyword)
|
||||
{
|
||||
static const auto nodekw = keyword_set {
|
||||
@ -395,6 +432,7 @@ inline void keywordAquifer( SummaryConfig::keyword_list& list,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline std::array< int, 3 > getijk( const DeckRecord& record ) {
|
||||
return {{
|
||||
record.getItem( "I" ).get< int >( 0 ) - 1,
|
||||
@ -403,6 +441,90 @@ inline std::array< int, 3 > getijk( const DeckRecord& record ) {
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
inline void keywordCL( SummaryConfig::keyword_list& list,
|
||||
const ParseContext& parseContext,
|
||||
ErrorGuard& errors,
|
||||
const DeckKeyword& keyword,
|
||||
const Schedule& schedule ,
|
||||
const GridDims& dims)
|
||||
{
|
||||
auto node = SummaryConfigNode{keyword.name(), SummaryConfigNode::Category::Connection, keyword.location()};
|
||||
node.parameterType( parseKeywordType(keyword.name()) );
|
||||
node.isUserDefined( is_udq(keyword.name()) );
|
||||
|
||||
for (const auto& record : keyword) {
|
||||
const auto& pattern = record.getItem(0).get<std::string>(0);
|
||||
auto well_names = schedule.wellNames( pattern, schedule.size() - 1 );
|
||||
|
||||
|
||||
if( well_names.empty() )
|
||||
handleMissingWell( parseContext, errors, keyword.location(), pattern );
|
||||
|
||||
const auto ijk_defaulted = record.getItem( 1 ).defaultApplied( 0 );
|
||||
for (const auto& wname : well_names) {
|
||||
const auto& well = schedule.getWellatEnd(wname);
|
||||
const auto& all_connections = well.getConnections();
|
||||
|
||||
node.namedEntity( wname );
|
||||
if (ijk_defaulted) {
|
||||
for (const auto& conn : all_connections)
|
||||
list.push_back( node.number( 1 + conn.global_index()));
|
||||
} else {
|
||||
const auto& ijk = getijk(record);
|
||||
auto global_index = dims.getGlobalIndex(ijk[0], ijk[1], ijk[2]);
|
||||
|
||||
if (all_connections.hasGlobalIndex(global_index)) {
|
||||
const auto& conn = all_connections.getFromGlobalIndex(global_index);
|
||||
list.push_back( node.number( 1 + conn.global_index()));
|
||||
} else {
|
||||
const auto& ijk = getijk(record);
|
||||
std::string msg = fmt::format("Problem with keyword {{keyword}}\n"
|
||||
"In {{file}} line {{line}}\n"
|
||||
"Connnection ({},{},{}) not defined for well {} ", ijk[0], ijk[1], ijk[2], wname);
|
||||
parseContext.handleError( ParseContext::SUMMARY_UNHANDLED_KEYWORD, msg, keyword.location(), errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void keywordWL( SummaryConfig::keyword_list& list,
|
||||
const ParseContext& parseContext,
|
||||
ErrorGuard& errors,
|
||||
const DeckKeyword& keyword,
|
||||
const Schedule& schedule )
|
||||
{
|
||||
for (const auto& record : keyword) {
|
||||
const auto& pattern = record.getItem(0).get<std::string>(0);
|
||||
const int completion = record.getItem(1).get<int>(0);
|
||||
auto well_names = schedule.wellNames( pattern, schedule.size() - 1 );
|
||||
|
||||
// We add the completion number both the extra field which contains
|
||||
// parsed data from the keywordname - i.e. WOPRL__8 and also to the
|
||||
// numeric member which will be written to the NUMS field.
|
||||
auto node = SummaryConfigNode{ fmt::format("{}{:_>3}", keyword.name(), completion), SummaryConfigNode::Category::Well, keyword.location()};
|
||||
node.parameterType( parseKeywordType(keyword.name()) );
|
||||
node.isUserDefined( is_udq(keyword.name()) );
|
||||
node.number(completion);
|
||||
|
||||
if( well_names.empty() )
|
||||
handleMissingWell( parseContext, errors, keyword.location(), pattern );
|
||||
|
||||
for (const auto& wname : well_names) {
|
||||
const auto& well = schedule.getWellatEnd(wname);
|
||||
if (well.hasCompletion(completion))
|
||||
list.push_back( node.namedEntity( wname ) );
|
||||
else {
|
||||
std::string msg = fmt::format("Problem with keyword {{keyword}}\n"
|
||||
"In {{file}} line {{line}}\n"
|
||||
"Completion number {} not defined for well {} ", completion, wname);
|
||||
parseContext.handleError( ParseContext::SUMMARY_UNHANDLED_KEYWORD, msg, keyword.location(), errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void keywordW( SummaryConfig::keyword_list& list,
|
||||
const std::string& keyword,
|
||||
KeywordLocation loc,
|
||||
@ -422,25 +544,8 @@ inline void keywordW( SummaryConfig::keyword_list& list,
|
||||
ErrorGuard& errors,
|
||||
const DeckKeyword& keyword,
|
||||
const Schedule& schedule ) {
|
||||
/*
|
||||
Two step check for whether to discard this keyword as unsupported:
|
||||
|
||||
1. Completion quantity keywords are currently not supported. These are
|
||||
well summary keywords, apart from "WMCTL" and "WPIL", that end in 'L'.
|
||||
|
||||
2. If the keyword is a UDQ keyword there is no convention enforced to
|
||||
the last character, and in that case it is treated as a normal well
|
||||
keyword anyways.
|
||||
*/
|
||||
if (keyword.name().back() == 'L') {
|
||||
if (! (is_control_mode(keyword.name()) || is_liquid_phase(keyword.name()) || is_udq(keyword.name()))) {
|
||||
const auto& location = keyword.location();
|
||||
std::string msg = "Unsupported summary output keyword {}\n"
|
||||
"In {file} line {line}";
|
||||
parseContext.handleError( ParseContext::SUMMARY_UNHANDLED_KEYWORD, msg, location, errors);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (is_well_completion(keyword.name()))
|
||||
return keywordWL(list, parseContext, errors, keyword, schedule);
|
||||
|
||||
auto param = SummaryConfigNode {
|
||||
keyword.name(), SummaryConfigNode::Category::Well, keyword.location()
|
||||
@ -681,6 +786,9 @@ inline void keywordMISC( SummaryConfig::keyword_list& list,
|
||||
const Schedule& schedule,
|
||||
const GridDims& dims) {
|
||||
|
||||
if (is_connection_completion(keyword.name()))
|
||||
return keywordCL(list, parseContext, errors, keyword, schedule, dims);
|
||||
|
||||
auto param = SummaryConfigNode {
|
||||
keyword.name(), SummaryConfigNode::Category::Connection, keyword.location()
|
||||
}
|
||||
@ -703,8 +811,8 @@ inline void keywordMISC( SummaryConfig::keyword_list& list,
|
||||
param.namedEntity(name);
|
||||
const auto& well = schedule.getWellatEnd(name);
|
||||
/*
|
||||
* we don't want to add completions that don't exist, so we iterate
|
||||
* over a well's completions regardless of the desired block is
|
||||
* we don't want to add connections that don't exist, so we iterate
|
||||
* over a well's connections regardless of the desired block is
|
||||
* defaulted or not
|
||||
*/
|
||||
for( const auto& connection : well.getConnections() ) {
|
||||
@ -1000,6 +1108,12 @@ inline void handleKW( SummaryConfig::keyword_list& list,
|
||||
// =====================================================================
|
||||
|
||||
SummaryConfigNode::Type parseKeywordType(std::string keyword) {
|
||||
if (is_well_completion(keyword))
|
||||
keyword.pop_back();
|
||||
|
||||
if (is_connection_completion(keyword))
|
||||
keyword.pop_back();
|
||||
|
||||
if (is_rate(keyword)) return SummaryConfigNode::Type::Rate;
|
||||
if (is_total(keyword)) return SummaryConfigNode::Type::Total;
|
||||
if (is_ratio(keyword)) return SummaryConfigNode::Type::Ratio;
|
||||
|
@ -92,7 +92,6 @@
|
||||
"WWCT",
|
||||
"WWCTH",
|
||||
"WGOR",
|
||||
"WGORL",
|
||||
"WGORH",
|
||||
"WOGR",
|
||||
"WOGRH",
|
||||
|
@ -666,21 +666,6 @@ BOOST_AUTO_TEST_CASE(FMWPA) {
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( WOPRL ) {
|
||||
const std::string input = R"(
|
||||
WOPRL
|
||||
'W_1' 1 /
|
||||
'WX2' 2 /
|
||||
'W_3' 3 /
|
||||
/
|
||||
)";
|
||||
|
||||
ParseContext parseContext;
|
||||
parseContext.update(ParseContext::SUMMARY_UNHANDLED_KEYWORD, InputError::THROW_EXCEPTION);
|
||||
BOOST_CHECK_THROW(createSummary( input, parseContext ), OpmInputError);
|
||||
parseContext.update(ParseContext::SUMMARY_UNHANDLED_KEYWORD, InputError::IGNORE);
|
||||
BOOST_CHECK_NO_THROW( createSummary(input, parseContext ));
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( summary_require3DField ) {
|
||||
@ -1219,3 +1204,118 @@ ROPT_REG
|
||||
auto rpr = summary_config.keywords("RP*");
|
||||
BOOST_CHECK_EQUAL(rpr.size(), 3U);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( WOPRL ) {
|
||||
const std::string input1 = R"(
|
||||
WOPRL
|
||||
'W_1' 2 /
|
||||
'xxx' 2 /
|
||||
/
|
||||
)";
|
||||
|
||||
|
||||
const std::string input2 = R"(
|
||||
WOPRL
|
||||
'W_1' 2 /
|
||||
'W_1' 999 /
|
||||
/
|
||||
)";
|
||||
|
||||
ParseContext parseContext;
|
||||
// Invalid well
|
||||
parseContext.update(ParseContext::SUMMARY_UNKNOWN_WELL, InputError::THROW_EXCEPTION);
|
||||
BOOST_CHECK_THROW(createSummary( input1, parseContext ), OpmInputError);
|
||||
|
||||
// Invalid completion
|
||||
parseContext.update(ParseContext::SUMMARY_UNHANDLED_KEYWORD, InputError::THROW_EXCEPTION);
|
||||
BOOST_CHECK_THROW(createSummary( input2, parseContext ), OpmInputError);
|
||||
|
||||
|
||||
parseContext.update(ParseContext::SUMMARY_UNHANDLED_KEYWORD, InputError::IGNORE);
|
||||
parseContext.update(ParseContext::SUMMARY_UNKNOWN_WELL, InputError::IGNORE);
|
||||
const auto& summary_config1 = createSummary(input1, parseContext);
|
||||
BOOST_CHECK(summary_config1.hasKeyword("WOPRL__2"));
|
||||
BOOST_CHECK_EQUAL(summary_config1.size(), 1);
|
||||
|
||||
const auto& summary_config2 = createSummary(input2, parseContext );
|
||||
BOOST_CHECK(summary_config2.hasKeyword("WOPRL__2"));
|
||||
BOOST_CHECK(!summary_config2.hasKeyword("WOPRL999"));
|
||||
const auto& node = summary_config2[0];
|
||||
BOOST_CHECK_EQUAL( node.number(), 2 );
|
||||
BOOST_CHECK(node.type() == EclIO::SummaryNode::Type::Rate);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( COPRL ) {
|
||||
const std::string input1 = R"(
|
||||
COPRL
|
||||
'W_1' 3 7 2 /
|
||||
'xxx' 3 7 2 /
|
||||
/
|
||||
)";
|
||||
|
||||
|
||||
const std::string input2 = R"(
|
||||
COPRL
|
||||
'W_1' 3 7 2 /
|
||||
'W_1' 2 6 1 /
|
||||
/
|
||||
)";
|
||||
|
||||
const std::string input3 = R"(
|
||||
COPRL
|
||||
'W_1' /
|
||||
/
|
||||
)";
|
||||
|
||||
ParseContext parseContext;
|
||||
// Invalid well
|
||||
parseContext.update(ParseContext::SUMMARY_UNKNOWN_WELL, InputError::THROW_EXCEPTION);
|
||||
BOOST_CHECK_THROW(createSummary( input1, parseContext ), OpmInputError);
|
||||
|
||||
// Invalid connection
|
||||
parseContext.update(ParseContext::SUMMARY_UNHANDLED_KEYWORD, InputError::THROW_EXCEPTION);
|
||||
BOOST_CHECK_THROW(createSummary( input2, parseContext ), OpmInputError);
|
||||
|
||||
|
||||
parseContext.update(ParseContext::SUMMARY_UNHANDLED_KEYWORD, InputError::IGNORE);
|
||||
parseContext.update(ParseContext::SUMMARY_UNKNOWN_WELL, InputError::IGNORE);
|
||||
const auto& summary_config1 = createSummary(input1, parseContext);
|
||||
BOOST_CHECK(summary_config1.hasKeyword("COPRL"));
|
||||
BOOST_CHECK_EQUAL(summary_config1.size(), 1);
|
||||
|
||||
|
||||
EclipseGrid grid(10,10,10);
|
||||
const auto g1 = grid.getGlobalIndex(1,1,0) + 1;
|
||||
const auto g2 = grid.getGlobalIndex(1,1,1) + 1;
|
||||
const auto g3 = grid.getGlobalIndex(2,6,1) + 1;
|
||||
|
||||
const auto& summary_config2 = createSummary(input2, parseContext );
|
||||
BOOST_CHECK(summary_config2.hasKeyword("COPRL"));
|
||||
BOOST_CHECK_EQUAL( summary_config2.size(), 1);
|
||||
{
|
||||
const auto& node = summary_config2[0];
|
||||
BOOST_CHECK_EQUAL( node.number(), g3);
|
||||
BOOST_CHECK(node.type() == EclIO::SummaryNode::Type::Rate);
|
||||
}
|
||||
|
||||
|
||||
const auto& summary_config3 = createSummary(input3, parseContext );
|
||||
BOOST_CHECK(summary_config3.hasKeyword("COPRL"));
|
||||
BOOST_CHECK_EQUAL( summary_config3.size(), 3);
|
||||
{
|
||||
const auto& node = summary_config3[0];
|
||||
BOOST_CHECK_EQUAL( node.number(), g1);
|
||||
}
|
||||
{
|
||||
const auto& node = summary_config3[1];
|
||||
BOOST_CHECK_EQUAL( node.number(), g2);
|
||||
}
|
||||
{
|
||||
const auto& node = summary_config3[2];
|
||||
BOOST_CHECK_EQUAL( node.number(), g3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -701,6 +701,24 @@ WGIGR
|
||||
WWIGR
|
||||
/
|
||||
|
||||
WOPRL
|
||||
W_1 1 /
|
||||
W_2 2 /
|
||||
W_3 3 /
|
||||
/
|
||||
|
||||
WOFRL
|
||||
W_1 1 /
|
||||
W_2 2 /
|
||||
W_3 3 /
|
||||
/
|
||||
|
||||
COPRL
|
||||
W_1 1 1 1 /
|
||||
W_2 /
|
||||
/
|
||||
|
||||
|
||||
-- Water injection per connection
|
||||
CWIR
|
||||
* /
|
||||
@ -835,6 +853,12 @@ COMPDAT
|
||||
W_6 0 0 2 2 2* 1* 2* 0.7 / -- Active index: 2
|
||||
/
|
||||
|
||||
COMPLUMP
|
||||
'W_1' * * * * 1 /
|
||||
'W_2' * * * * 2 /
|
||||
'W_3' * * * * 3 /
|
||||
/
|
||||
|
||||
WCONHIST
|
||||
-- history rates are set so that W_1 produces 1, W_2 produces 2 etc.
|
||||
-- index.offset.
|
||||
|
@ -410,7 +410,7 @@ double ecl_sum_get_group_var( const EclIO::ESmry* smry,
|
||||
return smry->get(variable + ':' + groupname)[timeIdx];
|
||||
}
|
||||
|
||||
double ecl_sum_get_well_completion_var( const EclIO::ESmry* smry,
|
||||
double ecl_sum_get_well_connection_var( const EclIO::ESmry* smry,
|
||||
const int timeIdx,
|
||||
const std::string& wellname,
|
||||
const std::string& variable,
|
||||
@ -925,8 +925,8 @@ BOOST_AUTO_TEST_CASE(group_group) {
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(completion_kewords) {
|
||||
setup cfg( "test_summary_completion" );
|
||||
BOOST_AUTO_TEST_CASE(connection_kewords) {
|
||||
setup cfg( "test_summary_connection" );
|
||||
|
||||
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule, cfg.name );
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
@ -942,48 +942,61 @@ BOOST_AUTO_TEST_CASE(completion_kewords) {
|
||||
const auto* resp = res.get();
|
||||
|
||||
/* Production rates */
|
||||
BOOST_CHECK_CLOSE( 100.0, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CWPR", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 100.1, ecl_sum_get_well_completion_var( resp, 1, "W_1", "COPR", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 100.2, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CGPR", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 100.0, ecl_sum_get_well_connection_var( resp, 1, "W_1", "CWPR", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 100.1, ecl_sum_get_well_connection_var( resp, 1, "W_1", "COPR", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 100.2, ecl_sum_get_well_connection_var( resp, 1, "W_1", "CGPR", 1, 1, 1 ), 1e-5 );
|
||||
|
||||
BOOST_CHECK_CLOSE(ecl_sum_get_well_var(resp, 1, "W_1", "WOPRL__1"), ecl_sum_get_well_connection_var(resp, 1, "W_1", "COPR", 1,1,1), 1e-5);
|
||||
BOOST_CHECK_CLOSE(ecl_sum_get_well_var(resp, 1, "W_2", "WOPRL__2"), ecl_sum_get_well_connection_var(resp, 1, "W_2", "COPR", 2,1,1) +
|
||||
ecl_sum_get_well_connection_var(resp, 1, "W_2", "COPR", 2,1,2), 1e-5);
|
||||
BOOST_CHECK_CLOSE(ecl_sum_get_well_var(resp, 1, "W_3", "WOPRL__3"), ecl_sum_get_well_connection_var(resp, 1, "W_3", "COPR", 3,1,1), 1e-5);
|
||||
BOOST_CHECK_EQUAL(ecl_sum_get_well_var(resp, 1, "W_2", "WOPRL__2"), ecl_sum_get_well_var(resp, 1, "W_2", "WOFRL__2"));
|
||||
|
||||
BOOST_CHECK_CLOSE(ecl_sum_get_well_var(resp, 1, "W_1", "WOPRL__1"), ecl_sum_get_well_connection_var(resp, 1, "W_1", "COPRL", 1,1,1), 1e-5);
|
||||
BOOST_CHECK_CLOSE(ecl_sum_get_well_connection_var(resp, 1, "W_2", "COPRL", 2, 1, 1), ecl_sum_get_well_connection_var(resp, 1, "W_2", "COPR", 2,1,1) +
|
||||
ecl_sum_get_well_connection_var(resp, 1, "W_2", "COPR", 2,1,2), 1e-5);
|
||||
BOOST_CHECK_CLOSE(ecl_sum_get_well_connection_var(resp, 1, "W_2", "COPRL", 2, 1, 2), ecl_sum_get_well_connection_var(resp, 1, "W_2", "COPR", 2,1,1) +
|
||||
ecl_sum_get_well_connection_var(resp, 1, "W_2", "COPR", 2,1,2), 1e-5);
|
||||
|
||||
|
||||
/* Production totals */
|
||||
BOOST_CHECK_CLOSE( 100.0, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CWPT", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 100.1, ecl_sum_get_well_completion_var( resp, 1, "W_1", "COPT", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 100.2, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CGPT", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 100.3, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CNPT", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 2 * 100.0, ecl_sum_get_well_completion_var( resp, 2, "W_1", "CWPT", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 2 * 100.1, ecl_sum_get_well_completion_var( resp, 2, "W_1", "COPT", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 100.0, ecl_sum_get_well_connection_var( resp, 1, "W_1", "CWPT", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 100.1, ecl_sum_get_well_connection_var( resp, 1, "W_1", "COPT", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 100.2, ecl_sum_get_well_connection_var( resp, 1, "W_1", "CGPT", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 100.3, ecl_sum_get_well_connection_var( resp, 1, "W_1", "CNPT", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 2 * 100.0, ecl_sum_get_well_connection_var( resp, 2, "W_1", "CWPT", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 2 * 100.1, ecl_sum_get_well_connection_var( resp, 2, "W_1", "COPT", 1, 1, 1 ), 1e-5 );
|
||||
|
||||
BOOST_CHECK_CLOSE( 2 * 100.2, ecl_sum_get_well_completion_var( resp, 2, "W_1", "CGPT", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 2 * 200.2, ecl_sum_get_well_completion_var( resp, 2, "W_2", "CGPT", 2, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 0 , ecl_sum_get_well_completion_var( resp, 2, "W_3", "CGPT", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 2 * 100.2, ecl_sum_get_well_connection_var( resp, 2, "W_1", "CGPT", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 2 * 200.2, ecl_sum_get_well_connection_var( resp, 2, "W_2", "CGPT", 2, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 0 , ecl_sum_get_well_connection_var( resp, 2, "W_3", "CGPT", 3, 1, 1 ), 1e-5 );
|
||||
|
||||
BOOST_CHECK_CLOSE( 1 * 100.2, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CGPT", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 1 * 200.2, ecl_sum_get_well_completion_var( resp, 1, "W_2", "CGPT", 2, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 0 , ecl_sum_get_well_completion_var( resp, 1, "W_3", "CGPT", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 1 * 100.2, ecl_sum_get_well_connection_var( resp, 1, "W_1", "CGPT", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 1 * 200.2, ecl_sum_get_well_connection_var( resp, 1, "W_2", "CGPT", 2, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 0 , ecl_sum_get_well_connection_var( resp, 1, "W_3", "CGPT", 3, 1, 1 ), 1e-5 );
|
||||
|
||||
BOOST_CHECK_CLOSE( 2 * 100.3, ecl_sum_get_well_completion_var( resp, 2, "W_1", "CNPT", 1, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 2 * 100.3, ecl_sum_get_well_connection_var( resp, 2, "W_1", "CNPT", 1, 1, 1 ), 1e-5 );
|
||||
|
||||
/* Injection rates */
|
||||
BOOST_CHECK_CLOSE( 300.0, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CWIR", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 300.2, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CGIR", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 300.16, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CCIR", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 300.0, ecl_sum_get_well_connection_var( resp, 1, "W_3", "CWIR", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 300.2, ecl_sum_get_well_connection_var( resp, 1, "W_3", "CGIR", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 300.16, ecl_sum_get_well_connection_var( resp, 1, "W_3", "CCIR", 3, 1, 1 ), 1e-5 );
|
||||
|
||||
/* Injection totals */
|
||||
BOOST_CHECK_CLOSE( 300.0, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CWIT", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 300.2, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CGIT", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 300.3, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CNIT", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 300.16, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CCIT", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 2 * 300.0, ecl_sum_get_well_completion_var( resp, 2, "W_3", "CWIT", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 2 * 300.2, ecl_sum_get_well_completion_var( resp, 2, "W_3", "CGIT", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 2 * 300.3, ecl_sum_get_well_completion_var( resp, 2, "W_3", "CNIT", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 300.0, ecl_sum_get_well_connection_var( resp, 1, "W_3", "CWIT", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 300.2, ecl_sum_get_well_connection_var( resp, 1, "W_3", "CGIT", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 300.3, ecl_sum_get_well_connection_var( resp, 1, "W_3", "CNIT", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 300.16, ecl_sum_get_well_connection_var( resp, 1, "W_3", "CCIT", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 2 * 300.0, ecl_sum_get_well_connection_var( resp, 2, "W_3", "CWIT", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 2 * 300.2, ecl_sum_get_well_connection_var( resp, 2, "W_3", "CGIT", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 2 * 300.3, ecl_sum_get_well_connection_var( resp, 2, "W_3", "CNIT", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 2 * 300.16,
|
||||
ecl_sum_get_well_completion_var( resp, 2, "W_3", "CCIT", 3, 1, 1 ), 1e-5 );
|
||||
ecl_sum_get_well_connection_var( resp, 2, "W_3", "CCIT", 3, 1, 1 ), 1e-5 );
|
||||
|
||||
/* Solvent flow rate + or - Note OPM uses negative values for producers, while CNFR outputs positive
|
||||
values for producers*/
|
||||
BOOST_CHECK_CLOSE( -300.3, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CNFR", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 200.3, ecl_sum_get_well_completion_var( resp, 1, "W_2", "CNFR", 2, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( -300.3, ecl_sum_get_well_connection_var( resp, 1, "W_3", "CNFR", 3, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 200.3, ecl_sum_get_well_connection_var( resp, 1, "W_2", "CNFR", 2, 1, 1 ), 1e-5 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(DATE) {
|
||||
@ -1488,13 +1501,13 @@ BOOST_AUTO_TEST_CASE(BLOCK_VARIABLES) {
|
||||
BOOST_CHECK_CLOSE( 31.0 , units.to_si( UnitSystem::measure::viscosity , ecl_sum_get_general_var( resp, 1, "BVOIL:1,1,1")) , 1e-5);
|
||||
BOOST_CHECK_CLOSE( 33.0 , units.to_si( UnitSystem::measure::viscosity , ecl_sum_get_general_var( resp, 1, "BOVIS:1,1,1")) , 1e-5);
|
||||
|
||||
BOOST_CHECK_CLOSE( 111.222 , ecl_sum_get_well_completion_var( resp, 1, "W_1", "CTFAC", 1, 1, 1), 1e-5);
|
||||
BOOST_CHECK_CLOSE( 222.333 , ecl_sum_get_well_completion_var( resp, 1, "W_2", "CTFAC", 2, 1, 1), 1e-5);
|
||||
BOOST_CHECK_CLOSE( 333.444 , ecl_sum_get_well_completion_var( resp, 1, "W_2", "CTFAC", 2, 1, 2), 1e-5);
|
||||
BOOST_CHECK_CLOSE( 444.555 , ecl_sum_get_well_completion_var( resp, 1, "W_3", "CTFAC", 3, 1, 1), 1e-5);
|
||||
BOOST_CHECK_CLOSE( 111.222 , ecl_sum_get_well_connection_var( resp, 1, "W_1", "CTFAC", 1, 1, 1), 1e-5);
|
||||
BOOST_CHECK_CLOSE( 222.333 , ecl_sum_get_well_connection_var( resp, 1, "W_2", "CTFAC", 2, 1, 1), 1e-5);
|
||||
BOOST_CHECK_CLOSE( 333.444 , ecl_sum_get_well_connection_var( resp, 1, "W_2", "CTFAC", 2, 1, 2), 1e-5);
|
||||
BOOST_CHECK_CLOSE( 444.555 , ecl_sum_get_well_connection_var( resp, 1, "W_3", "CTFAC", 3, 1, 1), 1e-5);
|
||||
|
||||
BOOST_CHECK_CLOSE( 111.222 , ecl_sum_get_well_completion_var( resp, 3, "W_1", "CTFAC", 1, 1, 1), 1e-5);
|
||||
BOOST_CHECK_CLOSE( 111.222 , ecl_sum_get_well_completion_var( resp, 4, "W_1", "CTFAC", 1, 1, 1), 1e-5);
|
||||
BOOST_CHECK_CLOSE( 111.222 , ecl_sum_get_well_connection_var( resp, 3, "W_1", "CTFAC", 1, 1, 1), 1e-5);
|
||||
BOOST_CHECK_CLOSE( 111.222 , ecl_sum_get_well_connection_var( resp, 4, "W_1", "CTFAC", 1, 1, 1), 1e-5);
|
||||
|
||||
// Cell is not active
|
||||
BOOST_CHECK( !ecl_sum_has_general_var( resp , "BPR:2,1,10"));
|
||||
@ -1861,8 +1874,8 @@ BOOST_AUTO_TEST_CASE(efficiency_factor) {
|
||||
|
||||
BOOST_CHECK_CLOSE( 300 * 0.2 * 0.01, ecl_sum_get_general_var( resp , 1 , "RWIR:1" ) , 1e-5);
|
||||
|
||||
BOOST_CHECK_CLOSE( 200.1, ecl_sum_get_well_completion_var( resp, 1, "W_2", "COPR", 2, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 200.1 * 0.2 * 0.01, ecl_sum_get_well_completion_var( resp, 1, "W_2", "COPT", 2, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 200.1, ecl_sum_get_well_connection_var( resp, 1, "W_2", "COPR", 2, 1, 1 ), 1e-5 );
|
||||
BOOST_CHECK_CLOSE( 200.1 * 0.2 * 0.01, ecl_sum_get_well_connection_var( resp, 1, "W_2", "COPT", 2, 1, 1 ), 1e-5 );
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user