Internalisation of SUMMARY C keywords

Implement support for creating and instantiation smspec_nodes for the
C-family of keywords of the SUMMARY section. Covers all defaulting
mechanisms.

Due to poor map/concat/filter support, this was written in a more
traditional foreach-if-then-append style.
This commit is contained in:
Jørgen Kvalsvik 2016-03-29 14:15:03 +02:00
parent 6ce846ca0b
commit 44b19a04ea
2 changed files with 97 additions and 5 deletions

View File

@ -25,15 +25,18 @@
#include <opm/parser/eclipse/Deck/Section.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Completion.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/CompletionSet.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Summary/Summary.hpp>
#include <opm/parser/eclipse/Utility/Functional.hpp>
#include <ert/ecl/ecl_smspec.h>
#include <numeric>
#include <algorithm>
#include <array>
namespace Opm {
@ -97,6 +100,10 @@ namespace Opm {
};
}
static inline std::array< int, 3 > getijk( const Completion& completion ) {
return { completion.getI(), completion.getJ(), completion.getK() };
}
static inline std::vector< ERT::smspec_node > keywordB(
const DeckKeyword& keyword,
const EclipseState& es ) {
@ -129,6 +136,60 @@ namespace Opm {
return fun::map( mknode, regions );
}
static inline std::vector< ERT::smspec_node > keywordC(
const DeckKeyword& keyword,
const EclipseState& es ) {
std::vector< ERT::smspec_node > nodes;
const auto& keywordstring = keyword.name();
const auto& schedule = es.getSchedule();
const auto last_timestep = schedule->getTimeMap()->last();
auto dims = dimensions( *es.getEclipseGrid() );
for( const auto& record : keyword ) {
const auto& wellname = record.getItem( 0 ).get< std::string >( 0 );
if( wellname == "*" ) {
for( const auto& well : schedule->getWells() ) {
const auto& name = wellName( well );
for( const auto& completion : *well->getCompletions( last_timestep ) ) {
auto cijk = getijk( *completion );
/* well defaulted, block coordinates defaulted */
if( record.size() != 4 ) {
nodes.emplace_back( keywordstring, name, dims.data(), cijk.data() );
}
/* well defaulted, block coordinates specified */
else {
auto recijk = getijk( record, 1 );
if( std::equal( recijk.begin(), recijk.end(), cijk.begin() ) )
nodes.emplace_back( keywordstring, name, dims.data(), cijk.data() );
}
}
}
} else {
/* all specified */
if( !record.getItem( 1 ).defaultApplied( 0 ) ) {
auto ijk = getijk( record, 1 );
nodes.emplace_back( keywordstring, wellname, dims.data(), ijk.data() );
}
else {
/* well specified, block coordinates defaulted */
for( const auto& completion : *schedule->getWell( wellname ).getCompletions( last_timestep ) ) {
auto ijk = getijk( *completion );
nodes.emplace_back( keywordstring, wellname, dims.data(), ijk.data() );
}
}
}
}
return nodes;
}
std::vector< ERT::smspec_node > handleKW( const DeckKeyword& keyword, const EclipseState& es ) {
const auto var_type = ecl_smspec_identify_var_type( keyword.name().c_str() );
@ -138,6 +199,7 @@ namespace Opm {
case ECL_SMSPEC_FIELD_VAR: return keywordF( keyword, es );
case ECL_SMSPEC_BLOCK_VAR: return keywordB( keyword, es );
case ECL_SMSPEC_REGION_VAR: return keywordR( keyword, es );
case ECL_SMSPEC_COMPLETION_VAR: return keywordC( keyword, es );
default: return {};
}

View File

@ -39,14 +39,24 @@ static DeckPtr createDeck( const std::string& summary ) {
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"DXV \n 10*400 /\n"
"DYV \n 10*400 /\n"
"DZV \n 10*400 /\n"
"TOPS \n 100*2202 / \n"
"REGIONS\n"
"FIPNUM\n"
"200*1 300*2 500*3 /\n"
"SCHEDULE\n"
"WELSPECS\n"
" \'W_1\' \'OP\' 30 37 3.33 \'OIL\' 7* / \n"
" \'WX2\' \'OP\' 30 37 3.33 \'OIL\' 7* / \n"
" \'W_3\' \'OP\' 20 51 3.92 \'OIL\' 7* / \n"
" \'W_1\' \'OP\' 1 1 3.33 \'OIL\' 7* / \n"
" \'WX2\' \'OP\' 2 2 3.33 \'OIL\' 7* / \n"
" \'W_3\' \'OP\' 2 5 3.92 \'OIL\' 7* / \n"
" 'PRODUCER' 'G' 5 5 2000 'GAS' /\n"
"/\n"
"COMPDAT\n"
"'PRODUCER' 5 5 1 1 'OPEN' 1* -1 0.5 / \n"
"'W_1' 3 7 1 3 'OPEN' 1* 32.948 0.311 3047.839 2* 'X' 22.100 / \n"
"'W_1' 3 7 2 2 'OPEN' 1* * 0.311 4332.346 2* 'X' 22.123 / \n"
"/\n"
"SUMMARY\n"
+ summary;
@ -82,7 +92,7 @@ BOOST_AUTO_TEST_CASE(wells_all) {
const auto input = "WWCT\n/\n";
const auto summary = createSummary( input );
const auto wells = { "WX2", "W_1", "W_3" };
const auto wells = { "PRODUCER", "WX2", "W_1", "W_3" };
const auto names = sorted_names( summary );
BOOST_CHECK_EQUAL_COLLECTIONS(
@ -144,3 +154,23 @@ BOOST_AUTO_TEST_CASE(regions) {
keywords.begin(), keywords.end(),
names.begin(), names.end() );
}
BOOST_AUTO_TEST_CASE(completions) {
const auto input = "CWIR\n"
"'PRODUCER' /\n"
"'WX2' 1 1 1 /\n"
"'WX2' 2 2 2 /\n"
"/\n"
"CWIT\n"
"'W_1' /\n"
"/\n";
const auto summary = createSummary( input );
const auto keywords = { "CWIR", "CWIR", "CWIR",
"CWIT", "CWIT", "CWIT" };
const auto names = sorted_keywords( summary );
BOOST_CHECK_EQUAL_COLLECTIONS(
keywords.begin(), keywords.end(),
names.begin(), names.end() );
}