diff --git a/src/opm/output/eclipse/Summary.cpp b/src/opm/output/eclipse/Summary.cpp index 8184d4e5a..4995f556b 100644 --- a/src/opm/output/eclipse/Summary.cpp +++ b/src/opm/output/eclipse/Summary.cpp @@ -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, ratel), 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 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)); } } diff --git a/src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp b/src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp index 28d3f3ff1..b6cecfcd2 100644 --- a/src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp +++ b/src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp @@ -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(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(0); + const int completion = record.getItem(1).get(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; diff --git a/src/opm/parser/eclipse/share/keywords/000_Eclipse100/W/WELL_PROBE b/src/opm/parser/eclipse/share/keywords/000_Eclipse100/W/WELL_PROBE index 8a3d075b3..52058129d 100644 --- a/src/opm/parser/eclipse/share/keywords/000_Eclipse100/W/WELL_PROBE +++ b/src/opm/parser/eclipse/share/keywords/000_Eclipse100/W/WELL_PROBE @@ -92,7 +92,6 @@ "WWCT", "WWCTH", "WGOR", - "WGORL", "WGORH", "WOGR", "WOGRH", diff --git a/tests/parser/SummaryConfigTests.cpp b/tests/parser/SummaryConfigTests.cpp index 1c3a8879e..7e99d724b 100644 --- a/tests/parser/SummaryConfigTests.cpp +++ b/tests/parser/SummaryConfigTests.cpp @@ -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); + } +} + + + + diff --git a/tests/summary_deck.DATA b/tests/summary_deck.DATA index fd1375420..2e3b6e04f 100644 --- a/tests/summary_deck.DATA +++ b/tests/summary_deck.DATA @@ -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. diff --git a/tests/test_Summary.cpp b/tests/test_Summary.cpp index 77963a1ef..949bb627a 100755 --- a/tests/test_Summary.cpp +++ b/tests/test_Summary.cpp @@ -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 ); }