Merge pull request #2059 from joakim-hove/summary-completion

Summary completion
This commit is contained in:
Joakim Hove 2020-11-09 14:33:10 +01:00 committed by GitHub
commit bb905eb545
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 442 additions and 84 deletions

View File

@ -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));
}
}

View File

@ -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;

View File

@ -92,7 +92,6 @@
"WWCT",
"WWCTH",
"WGOR",
"WGORL",
"WGORH",
"WOGR",
"WOGRH",

View File

@ -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);
}
}

View File

@ -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.

View File

@ -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 );
}