Skip to content

Commit

Permalink
Merge pull request equinor#34 from markusdregi/smspec_names_support
Browse files Browse the repository at this point in the history
Support for loading NAMES from SMSPEC
  • Loading branch information
markusdregi authored May 4, 2017
2 parents 189fe99 + b61b24f commit 244b445
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 144 deletions.
1 change: 1 addition & 0 deletions libecl/include/ert/ecl/ecl_kw_magic.h
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ values (2e20) are denoted with '*'.
#define MINISTEP_KW "MINISTEP"
#define STARTDAT_KW "STARTDAT" /* Intgere keyword containing day,month,year. */
#define WGNAMES_KW "WGNAMES" /* The names of wells/groups for the summary vectors. */
#define NAMES_KW "NAMES" /* Alias for WGNAMES_KW. */
#define KEYWORDS_KW "KEYWORDS" /* The variable type for the various summary vectors. */
#define UNITS_KW "UNITS" /* The units, i.e SM^3/DAY the summary vectors. */
#define DIMENS_KW "DIMENS" /* The dimensions of the grid - also used in the GRID files. */
Expand Down
4 changes: 2 additions & 2 deletions libecl/src/ecl_kw.c
Original file line number Diff line number Diff line change
Expand Up @@ -858,9 +858,9 @@ void ecl_kw_iset_char_ptr( ecl_kw_type * ecl_kw , int index, const char * s) {
* written to the @ecl_kw string array starting at @index.
*/
void ecl_kw_iset_string_ptr( ecl_kw_type * ecl_kw, int index, const char * s) {
if(!ecl_type_is_string(ecl_kw_get_data_type(ecl_kw))) {
if(!ecl_type_is_alpha(ecl_kw_get_data_type(ecl_kw))) {
char * type_name = ecl_type_alloc_name(ecl_kw_get_data_type(ecl_kw));
util_abort("%s: Expected CXXX data type, was %s\n", __func__, type_name);
util_abort("%s: Expected alphabetic data type (CHAR, CXXX or MESS), was %s\n", __func__, type_name);
}

size_t input_len = strlen(s);
Expand Down
91 changes: 64 additions & 27 deletions libecl/src/ecl_smspec.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,14 @@ static const char* special_vars[] = {"NEWTON",
this simple list.
*/

static const char* smspec_required_keywords[] = {WGNAMES_KW,
KEYWORDS_KW,
STARTDAT_KW,
UNITS_KW,
DIMENS_KW};
static const size_t num_req_keywords = 5;
static const char* smspec_required_keywords[] = {
WGNAMES_KW,
KEYWORDS_KW,
STARTDAT_KW,
UNITS_KW,
DIMENS_KW
};


/*****************************************************************/
Expand Down Expand Up @@ -333,6 +336,21 @@ void ecl_smspec_lock( ecl_smspec_type * smspec ) {
smspec->locked = true;
}

/**
* Returns an ecl data type for which all names will fit. If the maximum name
* length is at most 8, an ECL_CHAR is returned and otherwise a large enough
* ECL_STRING.
*/
static ecl_data_type get_wgnames_type(const ecl_smspec_type * smspec) {
size_t max_len = 0;
for(int i = 0; i < ecl_smspec_num_nodes(smspec); ++i) {
const char * name = smspec_node_get_wgname(ecl_smspec_iget_node(smspec, i));
if(name != NULL)
max_len = util_size_t_max(max_len, strlen(name));
}

return max_len <= 8 ? ECL_CHAR : ECL_STRING(max_len);
}

// DIMENS
// KEYWORDS
Expand Down Expand Up @@ -371,10 +389,18 @@ static void ecl_smspec_fortio_fwrite( const ecl_smspec_type * smspec , fortio_ty

{
ecl_kw_type * keywords_kw = ecl_kw_alloc( KEYWORDS_KW , num_nodes , ECL_CHAR );
ecl_kw_type * wgnames_kw = ecl_kw_alloc( WGNAMES_KW , num_nodes , ECL_CHAR );
ecl_kw_type * units_kw = ecl_kw_alloc( UNITS_KW , num_nodes , ECL_CHAR );
ecl_kw_type * nums_kw = NULL;

// If the names_type is an ECL_STRING we expect this to be an INTERSECT
// summary, otherwise an ECLIPSE summary.
ecl_data_type names_type = get_wgnames_type(smspec);
ecl_kw_type * wgnames_kw = ecl_kw_alloc(
ecl_type_is_char(names_type) ? WGNAMES_KW : NAMES_KW,
num_nodes,
names_type
);

if (smspec->need_nums)
nums_kw = ecl_kw_alloc( NUMS_KW , num_nodes , ECL_INT);
{
Expand Down Expand Up @@ -403,15 +429,15 @@ static void ecl_smspec_fortio_fwrite( const ecl_smspec_type * smspec , fortio_ty
if (smspec_node_get_var_type( smspec_node ) == ECL_SMSPEC_INVALID_VAR) {
ecl_kw_iset_string8( keywords_kw , i , "WWCT" );
ecl_kw_iset_string8( units_kw , i , "????????");
ecl_kw_iset_string8( wgnames_kw , i , DUMMY_WELL);
ecl_kw_iset_string_ptr( wgnames_kw , i , DUMMY_WELL);
} else {
ecl_kw_iset_string8( keywords_kw , i , smspec_node_get_keyword( smspec_node ));
ecl_kw_iset_string8( units_kw , i , smspec_node_get_unit( smspec_node ));
{
const char * wgname = DUMMY_WELL;
if (smspec_node_get_wgname( smspec_node ) != NULL)
wgname = smspec_node_get_wgname( smspec_node );
ecl_kw_iset_string8( wgnames_kw , i , wgname);
ecl_kw_iset_string_ptr( wgnames_kw , i , wgname);
}
}

Expand Down Expand Up @@ -958,7 +984,7 @@ bool ecl_smspec_equal( const ecl_smspec_type * self , const ecl_smspec_type * ot

static void ecl_smspec_load_restart( ecl_smspec_type * ecl_smspec , const ecl_file_type * header ) {
if (ecl_file_has_kw( header , RESTART_KW )) {
const ecl_kw_type * restart_kw = ecl_file_iget_kw( header , 0 );
const ecl_kw_type * restart_kw = ecl_file_iget_named_kw(header, RESTART_KW , 0);
char tmp_base[73]; /* To accomodate a maximum of 9 items which consist of 8 characters each. */
char * restart_base;
int i;
Expand Down Expand Up @@ -1058,16 +1084,25 @@ const int_vector_type * ecl_smspec_get_index_map( const ecl_smspec_type * smspec
return smspec->index_map;
}

/**
* This function is to support the NAMES alias for WGNAMES. If similar
* situations occur in the future, this is a sane starting point for general
* support.
*/
static const char * get_active_keyword_alias(ecl_file_type * header, const char * keyword) {
if (strcmp(keyword, WGNAMES_KW) == 0 || strcmp(keyword, NAMES_KW) == 0)
return ecl_file_has_kw(header, WGNAMES_KW) ? WGNAMES_KW : NAMES_KW;

return keyword;
}

static bool ecl_smspec_check_header( ecl_file_type * header ) {
bool OK = true;
int num_required = sizeof( smspec_required_keywords ) / sizeof( smspec_required_keywords[0] );
int i;

for (i=0; i < num_required; i++) {
if (!ecl_file_has_kw( header , smspec_required_keywords[i])) {
OK = false;
break;
}
for (int i=0; i < num_req_keywords && OK; i++) {
OK &= ecl_file_has_kw(
header,
get_active_keyword_alias(header, smspec_required_keywords[i])
);
}

return OK;
Expand All @@ -1077,16 +1112,18 @@ static bool ecl_smspec_check_header( ecl_file_type * header ) {
static bool ecl_smspec_fread_header(ecl_smspec_type * ecl_smspec, const char * header_file , bool include_restart) {
ecl_file_type * header = ecl_file_open( header_file , 0);
if (header && ecl_smspec_check_header( header )) {
ecl_kw_type *wells = ecl_file_iget_named_kw(header, WGNAMES_KW , 0);
ecl_kw_type *keywords = ecl_file_iget_named_kw(header, KEYWORDS_KW , 0);
ecl_kw_type *startdat = ecl_file_iget_named_kw(header, STARTDAT_KW , 0);
ecl_kw_type *units = ecl_file_iget_named_kw(header, UNITS_KW , 0);
ecl_kw_type *dimens = ecl_file_iget_named_kw(header, DIMENS_KW , 0);
ecl_kw_type *nums = NULL;
ecl_kw_type *lgrs = NULL;
ecl_kw_type *numlx = NULL;
ecl_kw_type *numly = NULL;
ecl_kw_type *numlz = NULL;
const char * names_alias = get_active_keyword_alias(header, WGNAMES_KW);
ecl_kw_type *wells = ecl_file_iget_named_kw(header, names_alias , 0);
ecl_kw_type *keywords = ecl_file_iget_named_kw(header, KEYWORDS_KW , 0);
ecl_kw_type *startdat = ecl_file_iget_named_kw(header, STARTDAT_KW , 0);
ecl_kw_type *units = ecl_file_iget_named_kw(header, UNITS_KW , 0);
ecl_kw_type *dimens = ecl_file_iget_named_kw(header, DIMENS_KW , 0);
ecl_kw_type *nums = NULL;
ecl_kw_type *lgrs = NULL;
ecl_kw_type *numlx = NULL;
ecl_kw_type *numly = NULL;
ecl_kw_type *numlz = NULL;

int params_index;
ecl_smspec->num_regions = 0;
if (startdat == NULL)
Expand Down
10 changes: 1 addition & 9 deletions libecl/src/smspec_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -407,20 +407,12 @@ smspec_node_type * smspec_node_alloc_new(int params_index, float default_value)
}


/**
Observe that the wellname can have max 8 characters; anything
beyond that is silently dropped.
*/

static void smspec_node_set_wgname( smspec_node_type * index , const char * wgname ) {
if (wgname == NULL) {
util_safe_free( index->wgname );
index->wgname = NULL;
} else {
if (strlen(wgname) > 8)
index->wgname = util_realloc_substring_copy(index->wgname , wgname , 8);
else
index->wgname = util_realloc_string_copy(index->wgname , wgname );
index->wgname = util_realloc_string_copy(index->wgname , wgname );
}
}

Expand Down
103 changes: 103 additions & 0 deletions python/tests/ecl/test_ecl_file_statoil.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,106 @@ def test_restart_view(self):
v = f.restartView( sim_time = datetime.date( 2004,1,1) )
v = f.restartView( report_step = 30 )
v = f.restartView( seqnum_index = 30 )

def test_ix_case(self):
f = EclFile( self.createTestPath( "Statoil/ECLIPSE/ix/summary/Create_Region_Around_Well.SMSPEC"))

# Keywords
self.assertTrue( "KEYWORDS" in f )
keywords_loaded = list(f["KEYWORDS"][0])
keywords_from_file = [
'TIME', 'YEARS', 'AAQR', 'AAQT', 'AAQP', 'AAQR', 'AAQT',
'AAQP', 'AAQR', 'AAQT', 'AAQP', 'FPPW', 'FPPO', 'FPPG', 'FNQT',
'FNQR', 'FEIP', 'FWPT', 'FWIT', 'FWIP', 'FWGR', 'FVPT', 'FVPR',
'FVIT', 'FVIR', 'FPR', 'FOPT', 'FOIT', 'FOIR', 'FOIPL',
'FOIPG', 'FOIP', 'FGPT', 'FGIT', 'FGIPL', 'FGIPG', 'FGIP',
'FAQT', 'FAQR', 'FGOR', 'FWCT', 'FGSR', 'FGIR', 'FGPR', 'FWIR',
'FWPR', 'FOPR', 'MEMORYTS', 'NAIMFRAC', 'TCPUDAY', 'TCPUTS',
'NBAKFL', 'NNUMST', 'NNUMFL', 'NEWTFL', 'MSUMNEWT', 'MSUMLINS',
'MLINEARS', 'NLINEARS', 'NEWTON', 'ELAPSED', 'TCPU',
'TIMESTEP', 'GOPR', 'GOPR', 'GOPR', 'GWPR', 'GWPR', 'GWPR',
'GWIR', 'GWIR', 'GWIR', 'GGPR', 'GGPR', 'GGPR', 'GWCT', 'GWCT',
'GWCT', 'GGOR', 'GGOR', 'GGOR', 'GGIR', 'GGIR', 'GGIR', 'GGIT',
'GGIT', 'GGIT', 'GGPT', 'GGPT', 'GGPT', 'GOIR', 'GOIR', 'GOIR',
'GOIT', 'GOIT', 'GOIT', 'GOPT', 'GOPT', 'GOPT', 'GVIR', 'GVIR',
'GVIR', 'GVIT', 'GVIT', 'GVIT', 'GVPR', 'GVPR', 'GVPR', 'GVPT',
'GVPT', 'GVPT', 'GWGR', 'GWGR', 'GWGR', 'GWIT', 'GWIT', 'GWIT',
'GWPT', 'GWPT', 'GWPT', 'WOPR', 'WOPR', 'WOPR', 'WOPR', 'WOPR',
'WOPR', 'WWPR', 'WWPR', 'WWPR', 'WWPR', 'WWPR', 'WWPR', 'WWIR',
'WWIR', 'WWIR', 'WWIR', 'WWIR', 'WWIR', 'WGPR', 'WGPR', 'WGPR',
'WGPR', 'WGPR', 'WGPR', 'WWCT', 'WWCT', 'WWCT', 'WWCT', 'WWCT',
'WWCT', 'WMCTL', 'WMCTL', 'WMCTL', 'WMCTL', 'WMCTL', 'WMCTL',
'WGOR', 'WGOR', 'WGOR', 'WGOR', 'WGOR', 'WGOR', 'WAPI', 'WAPI',
'WAPI', 'WAPI', 'WAPI', 'WAPI', 'WBHP', 'WBHP', 'WBHP', 'WBHP',
'WBHP', 'WBHP', 'WGIR', 'WGIR', 'WGIR', 'WGIR', 'WGIR', 'WGIR',
'WGIT', 'WGIT', 'WGIT', 'WGIT', 'WGIT', 'WGIT', 'WGPT', 'WGPT',
'WGPT', 'WGPT', 'WGPT', 'WGPT', 'WOIR', 'WOIR', 'WOIR', 'WOIR',
'WOIR', 'WOIR', 'WOIT', 'WOIT', 'WOIT', 'WOIT', 'WOIT', 'WOIT',
'WOPT', 'WOPT', 'WOPT', 'WOPT', 'WOPT', 'WOPT', 'WPIG', 'WPIG',
'WPIG', 'WPIG', 'WPIG', 'WPIG', 'WPIO', 'WPIO', 'WPIO', 'WPIO',
'WPIO', 'WPIO', 'WPIW', 'WPIW', 'WPIW', 'WPIW', 'WPIW', 'WPIW',
'WTHP', 'WTHP', 'WTHP', 'WTHP', 'WTHP', 'WTHP', 'WVIR', 'WVIR',
'WVIR', 'WVIR', 'WVIR', 'WVIR', 'WVIT', 'WVIT', 'WVIT', 'WVIT',
'WVIT', 'WVIT', 'WVPR', 'WVPR', 'WVPR', 'WVPR', 'WVPR', 'WVPR',
'WVPT', 'WVPT', 'WVPT', 'WVPT', 'WVPT', 'WVPT', 'WWGR', 'WWGR',
'WWGR', 'WWGR', 'WWGR', 'WWGR', 'WWIT', 'WWIT', 'WWIT', 'WWIT',
'WWIT', 'WWIT', 'WWPT', 'WWPT', 'WWPT', 'WWPT', 'WWPT', 'WWPT',
'WBHT', 'WBHT', 'WBHT', 'WBHT', 'WBHT', 'WBHT', 'WBP', 'WBP',
'WBP', 'WBP', 'WBP', 'WBP', 'WWCT', 'WWCT', 'WWCT', 'WWCT',
'WWCT', 'WWCT', 'WWCT', 'WWCT', 'WWCT', 'WWCT', 'WWCT', 'WWCT',
'WWCT', 'WWCT', 'WWCT', 'WWCT', 'WWCT', 'WWCT', 'WWCT', 'WWCT',
'WWCT', 'WWCT', 'WWCT', 'WWCT', 'WWCT', 'WWCT', 'WWCT', 'WWCT'
]

padd = lambda str_len : (lambda s : s + (" " * (max(0, str_len-len(s)))))
self.assertEqual(map(padd(8), keywords_from_file), keywords_loaded)

# Names
self.assertTrue( "NAMES" in f )
names_loaded = list(f["NAMES"][0])
names_from_file = [
'', '', 'AQFR_1', 'AQFR_1', 'AQFR_1', 'AQFR_2', 'AQFR_2',
'AQFR_2', 'AQFR_3', 'AQFR_3', 'AQFR_3', 'FIELD', 'FIELD',
'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD',
'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD',
'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD',
'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD',
'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD',
'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD',
'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD', 'FIELD',
'FIELD', 'ONE', 'TWO', 'FIELD', 'ONE', 'TWO', 'FIELD', 'ONE',
'TWO', 'FIELD', 'ONE', 'TWO', 'FIELD', 'ONE', 'TWO', 'FIELD',
'ONE', 'TWO', 'FIELD', 'ONE', 'TWO', 'FIELD', 'ONE', 'TWO',
'FIELD', 'ONE', 'TWO', 'FIELD', 'ONE', 'TWO', 'FIELD', 'ONE',
'TWO', 'FIELD', 'ONE', 'TWO', 'FIELD', 'ONE', 'TWO', 'FIELD',
'ONE', 'TWO', 'FIELD', 'ONE', 'TWO', 'FIELD', 'ONE', 'TWO',
'FIELD', 'ONE', 'TWO', 'FIELD', 'ONE', 'TWO', 'FIELD', 'ONE',
'TWO', 'FIELD', 'HWELL_PROD', 'GI', 'I2', 'I4', 'I6', 'I8',
'HWELL_PROD', 'GI', 'I2', 'I4', 'I6', 'I8', 'HWELL_PROD', 'GI',
'I2', 'I4', 'I6', 'I8', 'HWELL_PROD', 'GI', 'I2', 'I4', 'I6',
'I8', 'HWELL_PROD', 'GI', 'I2', 'I4', 'I6', 'I8', 'HWELL_PROD',
'GI', 'I2', 'I4', 'I6', 'I8', 'HWELL_PROD', 'GI', 'I2', 'I4',
'I6', 'I8', 'HWELL_PROD', 'GI', 'I2', 'I4', 'I6', 'I8',
'HWELL_PROD', 'GI', 'I2', 'I4', 'I6', 'I8', 'HWELL_PROD', 'GI',
'I2', 'I4', 'I6', 'I8', 'HWELL_PROD', 'GI', 'I2', 'I4', 'I6',
'I8', 'HWELL_PROD', 'GI', 'I2', 'I4', 'I6', 'I8', 'HWELL_PROD',
'GI', 'I2', 'I4', 'I6', 'I8', 'HWELL_PROD', 'GI', 'I2', 'I4',
'I6', 'I8', 'HWELL_PROD', 'GI', 'I2', 'I4', 'I6', 'I8',
'HWELL_PROD', 'GI', 'I2', 'I4', 'I6', 'I8', 'HWELL_PROD', 'GI',
'I2', 'I4', 'I6', 'I8', 'HWELL_PROD', 'GI', 'I2', 'I4', 'I6',
'I8', 'HWELL_PROD', 'GI', 'I2', 'I4', 'I6', 'I8', 'HWELL_PROD',
'GI', 'I2', 'I4', 'I6', 'I8', 'HWELL_PROD', 'GI', 'I2', 'I4',
'I6', 'I8', 'HWELL_PROD', 'GI', 'I2', 'I4', 'I6', 'I8',
'HWELL_PROD', 'GI', 'I2', 'I4', 'I6', 'I8', 'HWELL_PROD', 'GI',
'I2', 'I4', 'I6', 'I8', 'HWELL_PROD', 'GI', 'I2', 'I4', 'I6',
'I8', 'HWELL_PROD', 'GI', 'I2', 'I4', 'I6', 'I8', 'HWELL_PROD',
'GI', 'I2', 'I4', 'I6', 'I8', 'HWELL_PROD', 'GI', 'I2', 'I4',
'I6', 'I8', ':+:+:+:+', ':+:+:+:+', ':+:+:+:+', ':+:+:+:+',
':+:+:+:+', ':+:+:+:+', ':+:+:+:+', ':+:+:+:+', ':+:+:+:+',
':+:+:+:+', ':+:+:+:+', ':+:+:+:+', ':+:+:+:+', ':+:+:+:+',
':+:+:+:+', ':+:+:+:+', ':+:+:+:+', ':+:+:+:+', ':+:+:+:+',
':+:+:+:+', ':+:+:+:+', ':+:+:+:+', ':+:+:+:+', ':+:+:+:+',
':+:+:+:+', ':+:+:+:+', ':+:+:+:+', ':+:+:+:+'
]

self.assertEqual(map(padd(10), names_from_file), names_loaded)
Loading

0 comments on commit 244b445

Please sign in to comment.