Use plain C api for smspec_nodes

This commit is contained in:
Joakim Hove 2018-09-07 10:23:21 +02:00
parent e1948ccf99
commit 5aa0bfadf0
4 changed files with 202 additions and 80 deletions

View File

@ -24,10 +24,59 @@
#include <vector>
#include <set>
#include <ert/ecl/Smspec.hpp>
#include <ert/ecl/smspec_node.h>
namespace Opm {
/*
Very small utility class to get value semantics on the smspec_node
pointers. This should die as soon as the smspec_node class proper gets
value semantics.
*/
class SummaryNode {
public:
SummaryNode(smspec_node_type * c_ptr) :
ptr(c_ptr)
{}
SummaryNode(const SummaryNode& other) :
ptr( smspec_node_alloc_copy(other.get()))
{}
const smspec_node_type * get() const {
return this->ptr;
}
std::string wgname() const {
return smspec_node_get_wgname(this->ptr);
}
std::string keyword() const {
return smspec_node_get_keyword(this->ptr);
}
int num() const {
return smspec_node_get_num(this->ptr);
}
ecl_smspec_var_type type() const {
return smspec_node_get_var_type(this->ptr);
}
SummaryNode& operator=(const SummaryNode &other) {
this->ptr = smspec_node_alloc_copy(other.ptr);
return *this;
}
~SummaryNode() {
smspec_node_free(this->ptr);
}
private:
smspec_node_type * ptr;
};
class Deck;
class TableManager;
class EclipseState;
@ -38,7 +87,9 @@ namespace Opm {
class SummaryConfig {
public:
typedef std::vector< ERT::smspec_node >::const_iterator const_iterator;
typedef SummaryNode keyword_type;
typedef std::vector< keyword_type > keyword_list;
typedef keyword_list::const_iterator const_iterator;
SummaryConfig( const Deck&, const Schedule&,
const TableManager&, const ParseContext&);
@ -80,7 +131,7 @@ namespace Opm {
part, e.g. "WWCT", and not the qualification with
well/group name or a numerical value.
*/
std::vector< ERT::smspec_node > keywords;
keyword_list keywords;
std::set<std::string> short_keywords;
std::set<std::string> summary_keywords;
};

View File

@ -41,6 +41,7 @@
#include <opm/output/eclipse/Summary.hpp>
#include <opm/output/eclipse/RegionCache.hpp>
#include <ert/ecl/smspec_node.h>
#include <ert/ecl/ecl_smspec.h>
#include <ert/ecl/ecl_kw_magic.h>
@ -971,7 +972,7 @@ Summary::Summary( const EclipseState& st,
std::set< std::string > unsupported_keywords;
for( const auto& node : sum ) {
const auto* keyword = node.keyword();
const auto* keyword = smspec_node_get_keyword(node.get());
const auto single_value_pair = single_values_units.find( keyword );
const auto funs_pair = funs.find( keyword );
@ -985,15 +986,15 @@ Summary::Summary( const EclipseState& st,
add_timestep.
*/
if (single_value_pair != single_values_units.end()) {
if ((node.type() != ECL_SMSPEC_FIELD_VAR) && (node.type() != ECL_SMSPEC_MISC_VAR)) {
auto node_type = smspec_node_get_var_type(node.get());
if ((node_type != ECL_SMSPEC_FIELD_VAR) && (node_type != ECL_SMSPEC_MISC_VAR)) {
continue;
}
auto* nodeptr = ecl_sum_add_var( this->ecl_sum.get(),
keyword,
node.wgname(),
node.num(),
smspec_node_get_wgname(node.get()),
smspec_node_get_num(node.get()),
st.getUnits().name( single_value_pair->second ),
0 );
@ -1002,36 +1003,37 @@ Summary::Summary( const EclipseState& st,
auto* nodeptr = ecl_sum_add_var( this->ecl_sum.get(),
keyword,
node.wgname(),
node.num(),
smspec_node_get_wgname(node.get()),
smspec_node_get_num(node.get()),
st.getUnits().name( region_pair->second ),
0 );
this->handlers->region_nodes.emplace( std::make_pair(keyword, node.num()), nodeptr );
this->handlers->region_nodes.emplace( std::make_pair(keyword, smspec_node_get_num(node.get())), nodeptr );
} else if (block_pair != block_units.end()) {
if (node.type() != ECL_SMSPEC_BLOCK_VAR)
if (smspec_node_get_var_type(node.get()) != ECL_SMSPEC_BLOCK_VAR)
continue;
int global_index = node.num() - 1;
int global_index = smspec_node_get_num(node.get()) - 1;
if (!this->grid.cellActive(global_index))
continue;
auto* nodeptr = ecl_sum_add_var( this->ecl_sum.get(),
keyword,
node.wgname(),
node.num(),
smspec_node_get_wgname(node.get()),
smspec_node_get_num(node.get()),
st.getUnits().name( block_pair->second ),
0 );
this->handlers->block_nodes.emplace( std::make_pair(keyword, node.num()), nodeptr );
this->handlers->block_nodes.emplace( std::make_pair(keyword, smspec_node_get_num(node.get())), nodeptr );
} else if (funs_pair != funs.end()) {
auto node_type = smspec_node_get_var_type(node.get());
if ((node.type() == ECL_SMSPEC_COMPLETION_VAR) || (node.type() == ECL_SMSPEC_BLOCK_VAR)) {
int global_index = node.num() - 1;
if ((node_type == ECL_SMSPEC_COMPLETION_VAR) || (node_type == ECL_SMSPEC_BLOCK_VAR)) {
int global_index = smspec_node_get_num(node.get()) - 1;
if (!this->grid.cellActive(global_index))
continue;
}
@ -1043,7 +1045,7 @@ Summary::Summary( const EclipseState& st,
const fn_args no_args { dummy_wells, // Wells from Schedule object
0, // Duration of time step
0, // Simulation step
node.num(), // NUMS value for the summary output.
smspec_node_get_num(node.get()), // NUMS value for the summary output.
{}, // Well results - data::Wells
{}, // Region <-> cell mappings.
this->grid,
@ -1053,8 +1055,8 @@ Summary::Summary( const EclipseState& st,
auto* nodeptr = ecl_sum_add_var( this->ecl_sum.get(),
keyword,
node.wgname(),
node.num(),
smspec_node_get_wgname(node.get()),
smspec_node_get_num(node.get()),
st.getUnits().name( val.unit ),
0 );

View File

@ -36,7 +36,6 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <ert/ecl/Smspec.hpp>
#include <ert/ecl/ecl_smspec.h>
#include <iostream>
@ -141,15 +140,15 @@ void handleMissingGroup( const ParseContext& parseContext , const std::string& k
parseContext.handleError( ParseContext::SUMMARY_UNKNOWN_GROUP , msg );
}
inline void keywordW( std::vector< ERT::smspec_node >& list,
inline void keywordW( SummaryConfig::keyword_list& list,
const ParseContext& parseContext,
const DeckKeyword& keyword,
const Schedule& schedule ) {
const auto type = ECL_SMSPEC_WELL_VAR;
const auto hasValue = []( const DeckKeyword& kw ) {
return kw.getDataRecord().getDataItem().hasValue( 0 );
};
const std::array<int,3> dummy_dims = {1,1,1};
if (keyword.size() && hasValue(keyword)) {
for( const std::string& pattern : keyword.getStringData()) {
@ -159,20 +158,32 @@ inline void keywordW( std::vector< ERT::smspec_node >& list,
handleMissingWell( parseContext, keyword.name(), pattern );
for( const auto* well : wells )
list.emplace_back( type, well->name(), keyword.name() );
list.push_back( SummaryConfig::keyword_type( smspec_node_alloc( ECL_SMSPEC_WELL_VAR,
well->name().c_str(),
keyword.name().c_str(),
"",
":",
dummy_dims.data(),
0,0,0)));
}
} else
for (const auto* well : schedule.getWells())
list.emplace_back(type, well->name(), keyword.name());
}
list.push_back( SummaryConfig::keyword_type( smspec_node_alloc( ECL_SMSPEC_WELL_VAR,
well->name().c_str(),
keyword.name().c_str(),
"",
":",
dummy_dims.data(),
0,0,0)));
}
inline void keywordG( std::vector< ERT::smspec_node >& list,
inline void keywordG( SummaryConfig::keyword_list& list,
const ParseContext& parseContext,
const DeckKeyword& keyword,
const Schedule& schedule ) {
const auto type = ECL_SMSPEC_GROUP_VAR;
const std::array<int,3> dummy_dims = {1,1,1};
if( keyword.name() == "GMWSET" ) return;
if( keyword.size() == 0 ||
@ -180,9 +191,14 @@ inline void keywordG( std::vector< ERT::smspec_node >& list,
for( const auto& group : schedule.getGroups() ) {
if( group->name() == "FIELD" ) continue;
list.emplace_back( type, group->name(), keyword.name() );
list.push_back( SummaryConfig::keyword_type( smspec_node_alloc( ECL_SMSPEC_GROUP_VAR,
group->name().c_str(),
keyword.name().c_str(),
"",
":",
dummy_dims.data(),
0, 0, 0)));
}
return;
}
@ -190,17 +206,33 @@ inline void keywordG( std::vector< ERT::smspec_node >& list,
for( const std::string& group : item.getData< std::string >() ) {
if( schedule.hasGroup( group ) )
list.emplace_back( ECL_SMSPEC_GROUP_VAR, group, keyword.name() );
list.push_back( SummaryConfig::keyword_type( smspec_node_alloc( ECL_SMSPEC_GROUP_VAR,
group.c_str(),
keyword.name().c_str(),
"",
":",
dummy_dims.data(),
0, 0, 0)));
else
handleMissingGroup( parseContext, keyword.name(), group );
}
}
inline void keywordF( std::vector< ERT::smspec_node >& list,
const DeckKeyword& keyword ) {
if( keyword.name() == "FMWSET" ) return;
list.emplace_back( keyword.name() );
}
inline void keywordF( SummaryConfig::keyword_list& list,
const DeckKeyword& keyword ) {
const std::array<int,3> dummy_dims = {1,1,1};
if( keyword.name() == "FMWSET" ) return;
list.push_back( SummaryConfig::keyword_type( smspec_node_alloc( ECL_SMSPEC_FIELD_VAR,
NULL,
keyword.name().c_str(),
"",
":",
dummy_dims.data(),
0, 0, 0)));
}
inline std::array< int, 3 > getijk( const DeckRecord& record,
int offset = 0 ) {
@ -212,19 +244,27 @@ inline std::array< int, 3 > getijk( const DeckRecord& record,
}
inline std::array< int, 3 > getijk( const Connection& completion ) {
return {{ completion.getI(), completion.getJ(), completion.getK() }};
return { { completion.getI(), completion.getJ(), completion.getK() }};
}
inline void keywordB( std::vector< ERT::smspec_node >& list,
const DeckKeyword& keyword,
const GridDims& dims) {
inline void keywordB( SummaryConfig::keyword_list& list,
const DeckKeyword& keyword,
const GridDims& dims) {
for( const auto& record : keyword ) {
auto ijk = getijk( record );
list.emplace_back( keyword.name(), dims.getNXYZ().data(), ijk.data() );
int global_index = 1 + dims.getGlobalIndex(ijk[0], ijk[1], ijk[2]);
list.push_back( SummaryConfig::keyword_type( smspec_node_alloc(ECL_SMSPEC_BLOCK_VAR,
NULL,
keyword.name().c_str(),
"",
":",
dims.getNXYZ().data(),
global_index,0,0)));
}
}
inline void keywordR( std::vector< ERT::smspec_node >& list,
inline void keywordR( SummaryConfig::keyword_list& list,
const DeckKeyword& keyword,
const TableManager& tables,
const GridDims& dims) {
@ -249,26 +289,41 @@ inline void keywordR( std::vector< ERT::smspec_node >& list,
for( const int region : regions ) {
if (region >= 1 && region <= static_cast<int>(numfip))
list.emplace_back( keyword.name(), dims.getNXYZ().data(), region );
list.push_back( SummaryConfig::keyword_type( smspec_node_alloc( ECL_SMSPEC_REGION_VAR,
NULL,
keyword.name().c_str(),
"",
":",
dims.getNXYZ().data(),
region,
0, 0)));
else
throw std::invalid_argument("Illegal region value: " + std::to_string( region ));
}
}
inline void keywordMISC( std::vector< ERT::smspec_node >& list,
const DeckKeyword& keyword)
inline void keywordMISC( SummaryConfig::keyword_list& list,
const DeckKeyword& keyword)
{
const std::array<int,3> dummy_dims = {1,1,1};
if (meta_keywords.count( keyword.name() ) == 0)
list.emplace_back( keyword.name() );
list.push_back( SummaryConfig::keyword_type( smspec_node_alloc( ECL_SMSPEC_MISC_VAR,
NULL,
keyword.name().c_str(),
"",
":",
dummy_dims.data(),
0,
0, 0)));
}
inline void keywordC( std::vector< ERT::smspec_node >& list,
const ParseContext& parseContext,
const DeckKeyword& keyword,
const Schedule& schedule,
const GridDims& dims) {
inline void keywordC( SummaryConfig::keyword_list& list,
const ParseContext& parseContext,
const DeckKeyword& keyword,
const Schedule& schedule,
const GridDims& dims) {
const auto& keywordstring = keyword.name();
const auto last_timestep = schedule.getTimeMap().last();
@ -297,25 +352,41 @@ inline void keywordC( std::vector< ERT::smspec_node >& list,
auto cijk = getijk( connection );
if( record.getItem( 1 ).defaultApplied( 0 ) ) {
list.emplace_back( keywordstring, name, dims.getNXYZ().data(), cijk.data() );
}
else {
int global_index = 1 + dims.getGlobalIndex(cijk[0], cijk[1], cijk[2]);
list.push_back( SummaryConfig::keyword_type( smspec_node_alloc( ECL_SMSPEC_COMPLETION_VAR,
name.c_str(),
keywordstring.c_str(),
"",
":",
dims.getNXYZ().data(),
global_index,
0, 0)));
} else {
/* block coordinates specified */
auto recijk = getijk( record, 1 );
if( std::equal( recijk.begin(), recijk.end(), cijk.begin() ) )
list.emplace_back( keywordstring, name, dims.getNXYZ().data(), cijk.data() );
if( std::equal( recijk.begin(), recijk.end(), cijk.begin() ) ) {
int global_index = 1 + dims.getGlobalIndex(recijk[0], recijk[1], recijk[2]);
list.push_back( SummaryConfig::keyword_type( smspec_node_alloc( ECL_SMSPEC_COMPLETION_VAR,
name.c_str(),
keywordstring.c_str(),
"",
":",
dims.getNXYZ().data(),
global_index,
0, 0)));
}
}
}
}
}
}
inline void handleKW( std::vector< ERT::smspec_node >& list,
const DeckKeyword& keyword,
const Schedule& schedule,
const TableManager& tables,
const ParseContext& parseContext,
const GridDims& dims) {
inline void handleKW( SummaryConfig::keyword_list& list,
const DeckKeyword& keyword,
const Schedule& schedule,
const TableManager& tables,
const ParseContext& parseContext,
const GridDims& dims) {
const auto var_type = ecl_smspec_identify_var_type( keyword.name().c_str() );
switch( var_type ) {
@ -331,25 +402,23 @@ inline void handleKW( std::vector< ERT::smspec_node >& list,
}
}
inline void uniq( std::vector< ERT::smspec_node >& vec ) {
const auto lt = []( const ERT::smspec_node& lhs,
const ERT::smspec_node& rhs ) {
return ERT::smspec_node::cmp( lhs, rhs ) < 0;
inline void uniq( SummaryConfig::keyword_list& vec ) {
const auto lt = []( const SummaryConfig::keyword_type& lhs,
const SummaryConfig::keyword_type& rhs ) {
return smspec_node_cmp(lhs.get(), rhs.get()) < 0;
};
const auto eq = []( const ERT::smspec_node& lhs,
const ERT::smspec_node& rhs ) {
return ERT::smspec_node::cmp( lhs, rhs ) == 0;
const auto eq = []( const SummaryConfig::keyword_type& lhs,
const SummaryConfig::keyword_type& rhs ) {
return smspec_node_equal(lhs.get(), rhs.get());
};
std::sort( vec.begin(), vec.end(), lt );
auto logical_end = std::unique( vec.begin(), vec.end(), eq );
vec.erase( logical_end, vec.end() );
}
}
}
SummaryConfig::SummaryConfig( const Deck& deck,
const Schedule& schedule,
const TableManager& tables,
@ -373,8 +442,8 @@ SummaryConfig::SummaryConfig( const Deck& deck,
uniq( this->keywords );
for (const auto& kw: this->keywords) {
this->short_keywords.insert( kw.keyword() );
this->summary_keywords.insert( kw.key1() );
this->short_keywords.insert( smspec_node_get_keyword( kw.get() ));
this->summary_keywords.insert( smspec_node_get_gen_key1( kw.get() ));
}
}

View File

@ -98,9 +98,9 @@ static Deck createDeck( const std::string& summary ) {
static std::vector< std::string > sorted_names( const SummaryConfig& summary ) {
std::vector< std::string > ret;
for( const auto& x : summary ) {
auto wgname = x.wgname();
auto wgname = smspec_node_get_wgname(x.get());
if(wgname)
ret.push_back( x.wgname() );
ret.push_back( smspec_node_get_wgname(x.get()));
}
std::sort( ret.begin(), ret.end() );
@ -110,7 +110,7 @@ static std::vector< std::string > sorted_names( const SummaryConfig& summary ) {
static std::vector< std::string > sorted_keywords( const SummaryConfig& summary ) {
std::vector< std::string > ret;
for( const auto& x : summary )
ret.push_back( x.keyword() );
ret.push_back( smspec_node_get_keyword(x.get()));
std::sort( ret.begin(), ret.end() );
return ret;
@ -119,7 +119,7 @@ static std::vector< std::string > sorted_keywords( const SummaryConfig& summary
static std::vector< std::string > sorted_key_names( const SummaryConfig& summary ) {
std::vector< std::string > ret;
for( const auto& x : summary ) {
ret.push_back( x.key1() );
ret.push_back( smspec_node_get_gen_key1(x.get()));
}
std::sort( ret.begin(), ret.end() );