Upgraded ERT from github master commit d9955e849

Startup on new project
This commit is contained in:
Jacob Støren
2015-04-14 15:47:22 +02:00
parent 02e47c6679
commit 09744af4b8
1119 changed files with 28508 additions and 12532 deletions
+5 -15
View File
@@ -5,31 +5,21 @@
*.pyc
*~
*.user
#pyCharm project
*.user.*
.idea
#to make python tests run in-source
devel/python/lib64
# /devel/libenkf/src/
/devel/libenkf/src/.faultlist
# /develbranch/libenkf/src/
/develbranch/libenkf/src/.faultlist
# Ignore build catalog
/build
# Ignore pdf from tex-test
/devel/libert_util/tests/data/latex_OK.pdf
# Ignore Statoil test data
/devel/test-data/Statoil
# Ignore the ert_local python file which is needed to run some python tests
/devel/python/python/ert/ecl/ecl_local.py
/devel/GPATH
/devel/GRTAGS
/devel/GTAGS
/devel/gtags.sh
/cmake.sh
scratch.sparsebundle
*.iml
*.DS_Store
TestCase
+5 -1
View File
@@ -6,7 +6,7 @@ if(POLICY CMP0042)
endif()
set( ERT_VERSION_MAJOR 1 )
set( ERT_VERSION_MINOR 7 )
set( ERT_VERSION_MINOR 8 )
set( ERT_VERSION_MICRO X )
@@ -143,6 +143,10 @@ add_subdirectory( libecl_well )
#-----------------------------------------------------------------
if (BUILD_ERT)
#-----------------------------------------------------------------
if (BUILD_TESTS)
option( ERT_LSF_SUBMIT_TEST "Build and run tests of LSF submit" OFF)
endif()
include(cmake/ert_module_name.cmake)
include_directories( ${PROJECT_SOURCE_DIR}/libconfig/include )
+10
View File
@@ -0,0 +1,10 @@
#include <signal.h>
void sigbus_handler(int signal) {
}
int main(int argc, char ** argv) {
signal(SIGBUS , sigbus_handler);
}
+19 -1
View File
@@ -106,10 +106,22 @@ endif()
# underscore to avoid conflict with plplot which defines the
# HAVE_USLEEP symbol.
check_function_exists( usleep HAVE__USLEEP )
if (HAVE_OPENDIR)
if (HAVE__USLEEP)
add_definitions( -DHAVE__USLEEP )
endif()
check_function_exists(pthread_yield_np HAVE_YIELD_NP)
if (HAVE_YIELD_NP)
add_definitions(-DHAVE_YIELD_NP)
endif()
check_function_exists(pthread_yield HAVE_YIELD)
if (HAVE_YIELD)
add_definitions(-DHAVE_YIELD)
endif()
# Checking based on compiling. Some of the code generates warnings, so we just cut down to bare-bone compiler flags.
set( CMAKE_C_FLAGS_main ${CMAKE_C_FLAGS} )
@@ -146,6 +158,12 @@ if (ISREG_POSIX)
add_definitions( -DHAVE_ISREG )
endif()
try_compile( HAVE_SIGBUS ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/Tests/test_have_sigbus.c )
if (HAVE_SIGBUS)
add_definitions( -DHAVE_SIGBUS )
endif()
check_type_size(time_t SIZE_OF_TIME_T)
if (${SIZE_OF_TIME_T} EQUAL 8)
try_run( RUN_RESULT COMPILE_RESULT ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/Tests/test_mktime_before1970.c )
+1 -1
View File
@@ -2,7 +2,7 @@ Source: ert.ecl
Priority: extra
Maintainer: Arne Morten Kvarving <arne.morten.kvarving@sintef.no>
Build-Depends: debhelper (>= 8.0.0), cmake, liblapack-dev, libquadmath0,
iputils-ping, zlib1g-dev
iputils-ping, zlib1g-dev, git
Standards-Version: 3.9.2
Section: libs
Homepage: http://ert.nr.no
+1 -1
View File
@@ -13,4 +13,4 @@
dh $@
override_dh_auto_configure:
dh_auto_configure -- -DSHARED_LIB=1 -DBUILD_ECL_SUMMARY=1 -DCMAKE_BUILD_TYPE=Release
dh_auto_configure -- -DBUILD_SHARED_LIBS=1 -DBUILD_ECL_SUMMARY=1 -DCMAKE_BUILD_TYPE=Release
+16 -2
View File
@@ -1,6 +1,20 @@
set( ERT_DOC_INSTALL_PATH "" CACHE PATH "Absolute path to install documentation *in addition* to $PREFIX/documentation")
set( ERT_DOC_INSTALL_PATH "" CACHE PATH "Absolute path to install documentation *in addition* to $PREFIX/documentation")
set( ERT_DOC_EXTERNAL_ROOT "" CACHE PATH "Path to site local ERT documentation")
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/tmp_doc")
EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_SOURCE_DIR}/user" "${PROJECT_BINARY_DIR}/tmp_doc/user")
EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_SOURCE_DIR}/code" "${PROJECT_BINARY_DIR}/tmp_doc/code")
if (ERT_DOC_EXTERNAL_ROOT)
EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E create_symlink "${ERT_DOC_EXTERNAL_ROOT}" "${PROJECT_BINARY_DIR}/tmp_doc/external-doc")
message(STATUS "Adding documentation link ${PROJECT_BINARY_DIR}/tmp_doc/external-doc -> ${ERT_DOC_EXTERNAL_ROOT}")
set( ERT_DOC_LINK external-doc/index )
else()
set( ERT_DOC_LINK "" )
endif()
configure_file(index.rst.in ${PROJECT_BINARY_DIR}/tmp_doc/index.rst )
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/Static DESTINATION ${PROJECT_BINARY_DIR}/tmp_doc/)
add_custom_target(doc_out ALL
COMMAND ${CMAKE_COMMAND} -Dccsd=${CMAKE_CURRENT_SOURCE_DIR} -Dpbd=${PROJECT_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/build_doc.cmake
DEPENDS enkf )
-6
View File
@@ -1,6 +0,0 @@
First page in the static ert's documentation!
===============================
Contents:
This is where we need to write the "manual" documentation
+6 -4
View File
@@ -1,6 +1,8 @@
set( ENV{PYTHONPATH} ${pbd}/python)
#set( ENV{PYTHONPATH} ${pbd}/python)
execute_process(COMMAND cmake -E copy ${ccsd}/conf.py ${pbd}/tmp_doc/conf.py )
execute_process(COMMAND cmake -E copy ${ccsd}/index.rst ${pbd}/tmp_doc/index.rst )
execute_process(COMMAND sphinx-apidoc -e -o python ${pbd}/python WORKING_DIRECTORY ${pbd}/tmp_doc/)
# The api documentation is reeferenced from code/python/index.rst, i.e. the output path used when calling
# sphinx-apidoc must match this.
execute_process(COMMAND sphinx-apidoc -e -o API/python ${pbd}/python WORKING_DIRECTORY ${pbd}/tmp_doc/)
execute_process(COMMAND sphinx-build -b html -d _build/doctrees . _build WORKING_DIRECTORY ${pbd}/tmp_doc/)
+4
View File
@@ -0,0 +1,4 @@
Low level C libraries
=====================
How to use the C libraries
+11
View File
@@ -0,0 +1,11 @@
Documentation of ert code
=========================
Contents:
.. toctree::
:maxdepth: 1
python/index
C/index
@@ -0,0 +1,9 @@
The ert Python API
==================
.. toctree::
:maxdepth: 2
../../API/python/ert
../../API/python/ert_gui
@@ -0,0 +1,5 @@
Using the ert.ecl classes for Eclipse manipulation
==================================================
Using the ert.ecl classes for ECLIPSE binary files
+10
View File
@@ -0,0 +1,10 @@
Python documentation
====================
.. toctree::
:maxdepth: 1
introduction/index
eclipse/index
../../API/python/ert
../../API/python/ert_gui
@@ -0,0 +1,4 @@
Simple introduction to Python
=============================
An introduction to Python
@@ -9,12 +9,11 @@ Welcome to ert's documentation!
Contents:
.. toctree::
:maxdepth: 2
:maxdepth: 1
Static/index
python/ert
python/ert_gui
user/index
code/index
${ERT_DOC_LINK}
Indices and tables
+11
View File
@@ -0,0 +1,11 @@
User documentation for ERT
==========================
Contents:
.. toctree::
:maxdepth: 1
tutorial/index
keywords/index
observations/index
+7
View File
@@ -0,0 +1,7 @@
Keywords available in the ERT configuration
===========================================
.. toctree::
:maxdepth: 1
Here comes keywords ...
+4
View File
@@ -0,0 +1,4 @@
Configuring observations for ERT
================================
Adding observations ...
+3
View File
@@ -0,0 +1,3 @@
ERT Tutorial
============
Tutorial for ert.
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'analysis_module.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'analysis_module.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __ANALYSIS_MODULE_H__
@@ -27,7 +27,7 @@ extern "C" {
#include <ert/util/bool_vector.h>
/*
/*
These are option flag values which are used by the core ert code to
query the module of it's needs and capabilities. For instance to to
determine whether the data should be scaled prior to analysis the
@@ -36,7 +36,7 @@ extern "C" {
if (analysis_module_get_option( module, ANALYSIS_SCALE_DATA))
obs_data_scale( obs_data , S , E , D , R , dObs );
It is the responsability of the module to set the various flags.
It is the responsability of the module to set the various flags.
*/
@@ -57,54 +57,54 @@ typedef enum {
{.value = ANALYSIS_ITERABLE , .name = "ANALYSIS_ITERABLE"}
#define EXTERNAL_MODULE_NAME "analysis_table"
#define EXTERNAL_MODULE_NAME "analysis_table"
#define EXTERNAL_MODULE_SYMBOL analysis_table
typedef enum {
LOAD_OK = 0,
DLOPEN_FAILURE = 1,
DLOPEN_FAILURE = 1,
LOAD_SYMBOL_TABLE_NOT_FOUND = 2
} analysis_module_load_status_enum;
typedef struct analysis_module_struct analysis_module_type;
analysis_module_type * analysis_module_alloc_internal__( rng_type * rng , const char * user_name , const char * symbol_table , bool verbose , analysis_module_load_status_enum * load_status);
analysis_module_type * analysis_module_alloc_internal( rng_type * rng , const char * user_name , const char * symbol_table );
analysis_module_type * analysis_module_alloc_external__(rng_type * rng , const char * user_name , const char * lib_name , bool verbose , analysis_module_load_status_enum * load_status);
analysis_module_type * analysis_module_alloc_external( rng_type * rng , const char * user_name , const char * libname );
void analysis_module_free( analysis_module_type * module );
void analysis_module_free__( void * arg);
void analysis_module_initX(analysis_module_type * module ,
matrix_type * X ,
matrix_type * A ,
matrix_type * S ,
matrix_type * R ,
matrix_type * dObs ,
matrix_type * E ,
void analysis_module_initX(analysis_module_type * module ,
matrix_type * X ,
matrix_type * A ,
matrix_type * S ,
matrix_type * R ,
matrix_type * dObs ,
matrix_type * E ,
matrix_type * D);
void analysis_module_updateA(analysis_module_type * module ,
matrix_type * A ,
matrix_type * S ,
matrix_type * R ,
matrix_type * dObs ,
matrix_type * E ,
void analysis_module_updateA(analysis_module_type * module ,
matrix_type * A ,
matrix_type * S ,
matrix_type * R ,
matrix_type * dObs ,
matrix_type * E ,
matrix_type * D );
void analysis_module_init_update( analysis_module_type * module ,
const bool_vector_type * ens_mask ,
const matrix_type * S ,
const matrix_type * R ,
const matrix_type * dObs ,
const matrix_type * E ,
void analysis_module_init_update( analysis_module_type * module ,
const bool_vector_type * ens_mask ,
const matrix_type * S ,
const matrix_type * R ,
const matrix_type * dObs ,
const matrix_type * E ,
const matrix_type * D );
const char * analysis_module_get_lib_name( const analysis_module_type * module);
bool analysis_module_internal( const analysis_module_type * module );
@@ -120,7 +120,7 @@ typedef enum {
bool analysis_module_get_bool( const analysis_module_type * module , const char * var);
void * analysis_module_get_ptr( const analysis_module_type * module , const char * var);
const char * analysis_module_flag_enum_iget( int index, int * value);
UTIL_IS_INSTANCE_HEADER( analysis_module );
@@ -1,6 +1,8 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
set( RML_SOURCE_FILES
rml_enkf_config.c
rml_enkf_log.c
rml_enkf.c
rml_enkf_common.c )
+214 -304
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'rml_enkf.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'rml_enkf.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
@@ -35,6 +35,8 @@
#include <ert/analysis/std_enkf.h>
#include <rml_enkf_common.h>
#include <rml_enkf_config.h>
#include <rml_enkf_log.h>
typedef struct rml_enkf_data_struct rml_enkf_data_type;
@@ -50,21 +52,11 @@ typedef struct rml_enkf_data_struct rml_enkf_data_type;
set_subspace_dimension() routines will set one variable, AND
INVALIDATE THE OTHER. For most situations this will be OK, but if
you have repeated calls to both of these functions the end result
might be a surprise.
might be a surprise.
*/
#define INVALID_SUBSPACE_DIMENSION -1
#define INVALID_TRUNCATION -1
#define DEFAULT_SUBSPACE_DIMENSION INVALID_SUBSPACE_DIMENSION
#define DEFAULT_USE_PRIOR true
#define DEFAULT_LAMBDA_INCREASE_FACTOR 4
#define DEFAULT_LAMBDA_REDUCE_FACTOR 0.1
#define DEFAULT_LAMBDA0 -1
#define DEFAULT_LAMBDA_MIN 0.01
#define DEFAULT_LAMBDA_RECALCULATE false
#define DEFAULT_LOG_FILE "rml_enkf.out"
#define DEFAULT_CLEAR_LOG true
#define USE_PRIOR_KEY "USE_PRIOR"
#define LAMBDA_REDUCE_FACTOR_KEY "LAMBDA_REDUCE"
@@ -74,7 +66,7 @@ typedef struct rml_enkf_data_struct rml_enkf_data_type;
#define LAMBDA_RECALCULATE_KEY "LAMBDA_RECALCULATE"
#define ITER_KEY "ITER"
#define LOG_FILE_KEY "LOG_FILE"
#define CLEAR_LOG_KEY "CLEAR_LOG"
#define CLEAR_LOG_KEY "CLEAR_LOG"
@@ -103,32 +95,31 @@ typedef struct rml_enkf_data_struct rml_enkf_data_type;
destructor or free() function registered with the .freef field of
the analysis table.
*/
struct rml_enkf_data_struct {
UTIL_TYPE_ID_DECLARATION;
double truncation; // Controlled by config key: ENKF_TRUNCATION_KEY
int subspace_dimension; // Controlled by config key: ENKF_NCOMP_KEY (-1: use Truncation instead)
long option_flags;
int iteration_nr; // Keep track of the outer iteration loop
double Sk; // Objective function value
double Std; // Standard Deviation of the Objective function
double * Csc;
bool_vector_type * ens_mask;
double * Csc; // Vector with scalings for non-dimensionalizing states
matrix_type *Am; // Scaled right singular vectors of ensemble anomalies.
matrix_type *prior; // m_pr
matrix_type *state; // m_l
bool_vector_type * ens_mask; // Tells you which of the realisations are in use.
bool use_prior; // Use exact/approximate scheme? Approximate scheme drops the "prior" term in the LM step.
double lambda; // parameter to control the setp length in Marquardt levenberg optimization
double lambda0;
double lambda_min;
double lambda_reduce_factor;
double lambda_increase_factor;
bool lambda_recalculate;
bool clear_log;
char * log_file;
FILE * log_stream;
matrix_type *global_prior; // m_pr
matrix_type *previous_state; // m_l
double lambda; // parameter to control the setp length in Marquardt levenberg optimization
rml_enkf_log_type * rml_log;
rml_enkf_config_type * config;
};
@@ -144,69 +135,7 @@ static UTIL_SAFE_CAST_FUNCTION_CONST( rml_enkf_data , RML_ENKF_TYPE_ID )
//**********************************************
// Set / Get
//**********************************************
double rml_enkf_get_truncation( rml_enkf_data_type * data ) {
return data->truncation;
}
int rml_enkf_get_subspace_dimension( rml_enkf_data_type * data ) {
return data->subspace_dimension;
}
void rml_enkf_set_truncation( rml_enkf_data_type * data , double truncation ) {
data->truncation = truncation;
if (truncation > 0.0)
data->subspace_dimension = INVALID_SUBSPACE_DIMENSION;
}
void rml_enkf_set_lambda0( rml_enkf_data_type * data , double lambda0) {
data->lambda0 = lambda0;
}
double rml_enkf_get_lambda0( const rml_enkf_data_type * data ) {
return data->lambda0;
}
void rml_enkf_set_lambda_min( rml_enkf_data_type * data , double lambda_min) {
data->lambda_min = lambda_min;
}
double rml_enkf_get_lambda_min( const rml_enkf_data_type * data ) {
return data->lambda_min;
}
void rml_enkf_set_lambda_increase_factor( rml_enkf_data_type * data , double increase_factor) {
data->lambda_increase_factor = increase_factor;
}
double rml_enkf_get_lambda_increase_factor( const rml_enkf_data_type * data ) {
return data->lambda_increase_factor;
}
void rml_enkf_set_lambda_reduce_factor( rml_enkf_data_type * data , double reduce_factor) {
data->lambda_reduce_factor = reduce_factor;
}
double rml_enkf_get_lambda_reduce_factor( const rml_enkf_data_type * data ) {
return data->lambda_reduce_factor;
}
bool rml_enkf_get_use_prior( const rml_enkf_data_type * data ) {
return data->use_prior;
}
void rml_enkf_set_use_prior( rml_enkf_data_type * data , bool use_prior) {
data->use_prior = use_prior;
}
void rml_enkf_set_lambda_recalculate( rml_enkf_data_type * data , bool lambda_recalculate) {
data->lambda_recalculate = lambda_recalculate;
}
void rml_enkf_set_subspace_dimension( rml_enkf_data_type * data , int subspace_dimension) {
data->subspace_dimension = subspace_dimension;
if (subspace_dimension > 0)
data->truncation = INVALID_TRUNCATION;
}
void rml_enkf_set_iteration_nr( rml_enkf_data_type * data , int iteration_nr) {
data->iteration_nr = iteration_nr;
@@ -223,72 +152,36 @@ int rml_enkf_get_iteration_nr( const rml_enkf_data_type * data ) {
//**********************************************
// Log-file related stuff
//**********************************************
bool rml_enkf_get_clear_log( const rml_enkf_data_type * data ) {
return data->clear_log;
}
void rml_enkf_set_clear_log( rml_enkf_data_type * data , bool clear_log) {
data->clear_log = clear_log;
}
void rml_enkf_set_log_file( rml_enkf_data_type * data , const char * log_file ) {
data->log_file = util_realloc_string_copy( data->log_file , log_file );
}
const char * rml_enkf_get_log_file( const rml_enkf_data_type * data) {
return data->log_file;
}
void rml_enkf_log_line( rml_enkf_data_type * data , const char * fmt , ...) {
if (data->log_stream) {
va_list ap;
va_start(ap , fmt);
vfprintf( data->log_stream , fmt , ap );
va_end( ap );
}
}
static void rml_enkf_write_log_header( rml_enkf_data_type * data, const char * format) {
if (data->log_stream) {
if (rml_enkf_log_is_open( data->rml_log )) {
const char * column1 = "Iter#";
const char * column2 = "Lambda";
const char * column3 = "Sk old";
const char * column4 = "Sk_new";
const char * column5 = "std(Sk)";
rml_enkf_log_line(data, format, column1, column2, column3, column4, column5);
rml_enkf_log_line(data->rml_log, format, column1, column2, column3, column4, column5);
}
}
static void rml_enkf_write_iter_info( rml_enkf_data_type * data , double Sk_new, double Std_new ) {
if (data->log_stream) {
static void rml_enkf_write_iter_info( rml_enkf_data_type * data , double prev_Sk , double Sk_new, double Std_new ) {
if (rml_enkf_log_is_open( data->rml_log )) {
const char * format = "\n%2d-->%-2d %-7.3f %-7.3f --> %-7.3f %-7.3f";
const char * format_headers = "\n%-7s %-7s %-7s --> %-7s %-7s";
static int has_printed_header = 0;
static bool has_printed_header = false;
if (!has_printed_header) {
rml_enkf_write_log_header( data, format_headers );
has_printed_header = 1;
has_printed_header = true;
}
rml_enkf_log_line( data , format, data->iteration_nr, data->iteration_nr+1, data->lambda, data->Sk, Sk_new, Std_new);
rml_enkf_log_line( data->rml_log , format, data->iteration_nr, data->iteration_nr+1, data->lambda, prev_Sk, Sk_new, Std_new);
}
}
static void rml_enkf_open_log_file( rml_enkf_data_type * data ) {
data->log_stream = NULL;
if (data->log_file) {
if ( data->iteration_nr == 0) {
if (data->clear_log){
data->log_stream = util_mkdir_fopen( data->log_file , "w");
}
else
data->log_stream = util_mkdir_fopen( data->log_file , "a");
} else
data->log_stream = util_fopen( data->log_file , "a");
}
}
@@ -299,37 +192,28 @@ static void rml_enkf_open_log_file( rml_enkf_data_type * data ) {
void * rml_enkf_data_alloc( rng_type * rng) {
rml_enkf_data_type * data = util_malloc( sizeof * data);
UTIL_TYPE_ID_INIT( data , RML_ENKF_TYPE_ID );
data->log_file = NULL;
rml_enkf_set_truncation( data , DEFAULT_ENKF_TRUNCATION_ );
rml_enkf_set_subspace_dimension( data , DEFAULT_SUBSPACE_DIMENSION );
rml_enkf_set_use_prior( data , DEFAULT_USE_PRIOR );
rml_enkf_set_lambda0( data , DEFAULT_LAMBDA0 );
rml_enkf_set_lambda_increase_factor(data , DEFAULT_LAMBDA_INCREASE_FACTOR);
rml_enkf_set_lambda_reduce_factor(data , DEFAULT_LAMBDA_REDUCE_FACTOR);
rml_enkf_set_lambda_min( data , DEFAULT_LAMBDA_MIN );
rml_enkf_set_log_file( data , DEFAULT_LOG_FILE );
rml_enkf_set_clear_log( data , DEFAULT_CLEAR_LOG );
rml_enkf_set_lambda_recalculate( data , DEFAULT_LAMBDA_RECALCULATE );
data->config = rml_enkf_config_alloc();
data->rml_log = rml_enkf_log_alloc();
data->option_flags = ANALYSIS_NEED_ED + ANALYSIS_UPDATE_A + ANALYSIS_ITERABLE + ANALYSIS_SCALE_DATA;
data->Csc = NULL;
data->iteration_nr = 0;
data->Std = 0;
data->ens_mask = bool_vector_alloc(0,false);
data->state = matrix_alloc(1,1);
data->prior = matrix_alloc(1,1);
data->Std = 0;
data->previous_state = matrix_alloc(1,1);
data->global_prior = NULL;
data->ens_mask = NULL;
return data;
}
void rml_enkf_data_free( void * arg ) {
void rml_enkf_data_free( void * arg ) {
rml_enkf_data_type * data = rml_enkf_data_safe_cast( arg );
matrix_free( data->state );
matrix_free( data->prior );
matrix_free( data->previous_state );
if (data->global_prior)
matrix_free( data->global_prior );
util_safe_free( data->log_file );
bool_vector_free( data->ens_mask );
rml_enkf_log_free( data->rml_log );
rml_enkf_config_free( data->config );
free( data );
}
@@ -346,11 +230,10 @@ void rml_enkf_data_free( void * arg ) {
* Variable name in code <-> D.Oliver notation <-> Description
* -------------------------------------------------------------------------------------------------------------
* A <-> m_l <-> Ensemble matrix. Updated in-place by iterations.
* data->state <-> m_(l-1) <-> "A" from the previous iteration. Backs up A in case the update is bad.
* data->prior <-> <-> Previously: "active_prior". Stores A from before iter0, i.e. the actual prior.
* data->previous_state <-> m_(l-1) <-> "A" from the previous iteration. Backs up A in case the update is bad.
* data->global_prior <-> <-> Previously: "active_prior". Stores A from before iter0, i.e. the actual prior.
* Acopy <-> <-> Eliminated from code. Copy of A (at each iteration, before acceptance/rejection decision)
* data->prior0 <-> m_pr <-> Eliminated from code. Same as prior, but also includes columns (j) for which ens_mask[j]==false.
* Seems pointless. Only creates confusion.
*
* Am <-> A_m <-> Am = Um*Wm^(-1)
* Csc <-> C_sc^(1/2) <-> State scalings. Note the square root.
@@ -373,28 +256,30 @@ void rml_enkf_data_free( void * arg ) {
static void rml_enkf_init1__( rml_enkf_data_type * data) {
// Differentiate this routine from init2__, which actually calculates the prior mismatch update.
// This routine does not change any ensemble matrix.
// Um*Wm^(-1) are the scaled, truncated, right singular vectors of data->prior
// Um*Wm^(-1) are the scaled, truncated, right singular vectors of data->global_prior
int state_size = matrix_get_rows( data->prior );
int ens_size = matrix_get_columns( data->prior );
int nrmin = util_int_min( ens_size , state_size);
matrix_type * Dm = matrix_alloc_copy( data->prior );
matrix_type * Um = matrix_alloc( state_size , nrmin ); /* Left singular vectors. */
matrix_type * VmT = matrix_alloc( nrmin , ens_size ); /* Right singular vectors. */
double * Wm = util_calloc( nrmin , sizeof * Wm );
double nsc = 1/sqrt(ens_size - 1);
matrix_type * prior = matrix_alloc_column_compressed_copy( data->global_prior , data->ens_mask);
int state_size = matrix_get_rows( prior );
int ens_size = matrix_get_columns( prior );
int nrmin = util_int_min( ens_size , state_size);
matrix_type * Dm = matrix_alloc_copy( prior );
matrix_type * Um = matrix_alloc( state_size , nrmin ); /* Left singular vectors. */
matrix_type * VmT = matrix_alloc( nrmin , ens_size ); /* Right singular vectors. */
double * Wm = util_calloc( nrmin , sizeof * Wm );
double nsc = 1/sqrt(ens_size - 1);
matrix_subtract_row_mean(Dm);
for (int i=0; i < state_size; i++){
double sc = nsc / (data->Csc[i]);
matrix_scale_row( Dm , i , sc);
{
const double * Csc = data->Csc;
for (int i=0; i < state_size; i++){
double sc = nsc / (Csc[i]);
matrix_scale_row( Dm , i , sc);
}
}
// Um Wm VmT = Dm; nsign1 = num of non-zero singular values.
int nsign1 = enkf_linalg_svd_truncation(Dm , data->truncation , -1 , DGESVD_MIN_RETURN , Wm , Um , VmT);
int nsign1 = enkf_linalg_svd_truncation(Dm , rml_enkf_config_get_truncation( data->config ) , -1 , DGESVD_MIN_RETURN , Wm , Um , VmT);
// Am = Um*Wm^(-1). I.e. scale *columns* of Um
enkf_linalg_rml_enkfAm(Um, Wm, nsign1);
@@ -402,25 +287,31 @@ static void rml_enkf_init1__( rml_enkf_data_type * data) {
matrix_free(Um);
matrix_free(VmT);
matrix_free(Dm);
matrix_free(prior);
free(Wm);
}
// Creates state scaling matrix
void rml_enkf_init_Csc(rml_enkf_data_type * data){
void rml_enkf_init_Csc(const rml_enkf_data_type * data ){
// This seems a strange choice of scaling matrix. Review?
int state_size = matrix_get_rows( data->prior );
int ens_size = matrix_get_columns( data->prior );
matrix_type * prior = matrix_alloc_column_compressed_copy( data->global_prior , data->ens_mask );
{
int state_size = matrix_get_rows( prior );
int ens_size = matrix_get_columns( prior );
for (int row=0; row < state_size; row++) {
double sumrow = matrix_get_row_sum(data->prior , row);
double tmp = sumrow / ens_size;
for (int row=0; row < state_size; row++) {
double sumrow = matrix_get_row_sum(prior , row);
double tmp = sumrow / ens_size;
if (abs(tmp)< 1)
data->Csc[row] = 0.05;
else
data->Csc[row] = 1.00;
if (abs(tmp)< 1)
data->Csc[row] = 0.05;
else
data->Csc[row] = 1.00;
}
matrix_free( prior );
}
}
@@ -428,6 +319,7 @@ void rml_enkf_init_Csc(rml_enkf_data_type * data){
static void rml_enkf_initA__(rml_enkf_data_type * data, matrix_type * A, matrix_type * S, matrix_type * Cd, matrix_type * E, matrix_type * D, matrix_type * Udr, double * Wdr, matrix_type * VdTr) {
int ens_size = matrix_get_columns( S );
int state_size = matrix_get_rows( A );
double nsc = 1/sqrt(ens_size-1);
int nsign;
@@ -440,37 +332,37 @@ static void rml_enkf_initA__(rml_enkf_data_type * data, matrix_type * A, matrix_
matrix_matmul(tmp , Cd , S ); //
matrix_scale(tmp , nsc); //
nsign = enkf_linalg_svd_truncation(tmp , data->truncation , -1 , DGESVD_MIN_RETURN , Wdr , Udr , VdTr);
nsign = enkf_linalg_svd_truncation(tmp , rml_enkf_config_get_truncation( data->config ) , -1 , DGESVD_MIN_RETURN , Wdr , Udr , VdTr);
matrix_free( tmp );
}
// Calc X3
{
matrix_type * X3 = matrix_alloc( ens_size, ens_size );
{
matrix_type * X1 = matrix_alloc( nsign, ens_size);
matrix_type * X2 = matrix_alloc( nsign, ens_size );
// See LM-EnRML algorithm in Oliver'2013 (Comp. Geo.) for meaning
enkf_linalg_rml_enkfX1(X1, Udr ,D ,Cd ); // X1 = Ud(T)*Cd(-1/2)*D -- D= -(dk-d0)
enkf_linalg_rml_enkfX2(X2, Wdr ,X1 ,data->lambda + 1 , nsign); // X2 = ((a*Ipd)+Wd^2)^-1 * X1
enkf_linalg_rml_enkfX3(X3, VdTr ,Wdr,X2, nsign); // X3 = Vd *Wd*X2
matrix_free(X2);
matrix_free(X1);
}
// Update A
{
matrix_type * dA1 = matrix_alloc( matrix_get_rows(A) , ens_size);
matrix_type * Dm = matrix_alloc_copy( A );
matrix_type * dA1 = matrix_alloc( state_size , ens_size);
matrix_type * Dm = matrix_alloc_copy( A );
matrix_subtract_row_mean( Dm ); /* Remove the mean from the ensemble of model parameters*/
matrix_scale(Dm, nsc);
matrix_matmul(dA1, Dm , X3);
matrix_inplace_add(A,dA1); // dA
matrix_inplace_add(A,dA1); // dA
matrix_free(Dm);
matrix_free(dA1);
@@ -487,15 +379,15 @@ void rml_enkf_init2__( rml_enkf_data_type * data, matrix_type *A, double * Wdr,
int state_size = matrix_get_rows( A );
int ens_size = matrix_get_columns( A );
double nsc = 1/sqrt(ens_size-1);
double nsc = 1/sqrt(ens_size-1);
matrix_type *Am = matrix_alloc_copy(data->Am);
matrix_type *Apr = matrix_alloc_copy(data->prior);
matrix_type *Apr = matrix_alloc_column_compressed_copy(data->global_prior , data->ens_mask );
// fprintf(stdout,"\n");
// fprintf(stdout,"A: %d x %d\n", matrix_get_rows(A), matrix_get_columns(A));
// fprintf(stdout,"prior : %d x %d\n", matrix_get_rows(data->prior), matrix_get_columns(data->prior));
// fprintf(stdout,"state : %d x %d\n", matrix_get_rows(data->state), matrix_get_columns(data->state));
// fprintf(stdout,"prior : %d x %d\n", matrix_get_rows(data->global_prior), matrix_get_columns(data->global_prior));
// fprintf(stdout,"state : %d x %d\n", matrix_get_rows(data->previous_state), matrix_get_columns(data->previous_state));
// fprintf(stdout,"Apr : %d x %d\n", matrix_get_rows(Apr), matrix_get_columns(Apr));
// fprintf(stdout,"Am : %d x %d\n", matrix_get_rows(Am), matrix_get_columns(Am));
// Example:
@@ -508,7 +400,7 @@ void rml_enkf_init2__( rml_enkf_data_type * data, matrix_type *A, double * Wdr,
int nsign1 = matrix_get_columns(data->Am);
matrix_type * X4 = matrix_alloc(nsign1,ens_size);
matrix_type * X5 = matrix_alloc(state_size,ens_size);
@@ -516,13 +408,15 @@ void rml_enkf_init2__( rml_enkf_data_type * data, matrix_type *A, double * Wdr,
matrix_type * X7 = matrix_alloc(ens_size,ens_size);
matrix_type * dA2 = matrix_alloc(state_size , ens_size);
matrix_type * Dk1 = matrix_alloc_copy( A );
// Dk = Csc^(-1) * (A - Aprior)
// X4 = Am' * Dk
{
matrix_type * Dk = matrix_alloc_copy( A );
matrix_inplace_sub(Dk, Apr);
matrix_inplace_sub( Dk , Apr );
rml_enkf_common_scaleA(Dk , data->Csc , true);
matrix_dgemm(X4 , Am , Dk , true, false, 1.0, 0.0);
matrix_free(Dk);
}
@@ -536,10 +430,10 @@ void rml_enkf_init2__( rml_enkf_data_type * data, matrix_type *A, double * Wdr,
// X6 = Dk1' * X5
matrix_dgemm(X6, Dk1, X5, true, false, 1.0, 0.0);
// X7
enkf_linalg_rml_enkfX7(X7, VdTr , Wdr , data->lambda + 1, X6);
// delta m_2
rml_enkf_common_scaleA(Dk1 , data->Csc , false);
matrix_matmul(dA2 , Dk1 , X7);
@@ -547,7 +441,7 @@ void rml_enkf_init2__( rml_enkf_data_type * data, matrix_type *A, double * Wdr,
matrix_free(Am);
matrix_free(Apr);
matrix_free(X4);
matrix_free(X4);
matrix_free(X5);
matrix_free(X6);
matrix_free(X7);
@@ -557,39 +451,45 @@ void rml_enkf_init2__( rml_enkf_data_type * data, matrix_type *A, double * Wdr,
// Initialize state and prior from A. Initialize lambda0, lambda. Call initA__, init1__
static void rml_enkf_updateA_iter0(rml_enkf_data_type * data, matrix_type * A, matrix_type * S, matrix_type * R, matrix_type * dObs, matrix_type * E, matrix_type * D, matrix_type * Cd) {
int ens_size = matrix_get_columns( S );
int nrobs = matrix_get_rows( S );
int nrmin = util_int_min( ens_size , nrobs);
int nrmin = util_int_min( ens_size , nrobs);
int state_size = matrix_get_rows( A );
matrix_type * Skm = matrix_alloc(ens_size, ens_size); // Mismatch
matrix_type * Ud = matrix_alloc( nrobs , nrmin ); /* Left singular vectors. */
matrix_type * VdT = matrix_alloc( nrmin , ens_size ); /* Right singular vectors. */
double * Wd = util_calloc( nrmin , sizeof * Wd );
double * Wd = util_calloc( nrmin , sizeof * Wd );
data->Csc = util_calloc(state_size , sizeof * data->Csc);
data->Sk = enkf_linalg_data_mismatch(D,Cd,Skm);
data->Sk = enkf_linalg_data_mismatch(D,Cd,Skm);
data->Std = matrix_diag_std(Skm,data->Sk);
if (data->lambda0 < 0)
data->lambda = pow(10 , floor(log10(data->Sk/(2*nrobs))) );
else
data->lambda = data->lambda0;
// state = A, prior = A
rml_enkf_common_store_state( data->state , A , data->ens_mask );
rml_enkf_common_recover_state( A , data->prior , data->ens_mask );
{
double lambda0 = rml_enkf_config_get_lambda0( data->config );
if (lambda0 < 0)
data->lambda = pow(10 , floor(log10(data->Sk/(2*nrobs))) );
else
data->lambda = lambda0;
}
// state = A
rml_enkf_common_store_state( data->previous_state , A , data->ens_mask );
// prior = A
data->global_prior = matrix_alloc_copy( data->previous_state );
// Update dependant on data mismatch
rml_enkf_initA__(data , A, S , Cd , E , D , Ud , Wd , VdT);
// Update dependant on prior mismatch. This should be zero (coz iter0).
// Therefore the purpose of init1__ is just to prepare some matrices.
if (data->use_prior) {
if (rml_enkf_config_get_use_prior(data->config)) {
rml_enkf_init_Csc( data );
rml_enkf_init1__(data );
rml_enkf_init1__( data );
}
rml_enkf_write_iter_info(data, data->Sk, data->Std);
rml_enkf_write_iter_info(data, data->Sk , data->Sk, data->Std);
matrix_free( Skm );
matrix_free( Ud );
@@ -597,7 +497,7 @@ static void rml_enkf_updateA_iter0(rml_enkf_data_type * data, matrix_type * A, m
free( Wd );
}
// Main routine. Controls the iterations. Called from analysis_module.c: analysis_module_updateA()
void rml_enkf_updateA(void * module_data, matrix_type * A, matrix_type * S, matrix_type * R, matrix_type * dObs, matrix_type * E, matrix_type * D) {
// A : ensemble matrix
// R : (Inv?) Obs error cov.
@@ -616,12 +516,12 @@ void rml_enkf_updateA(void * module_data, matrix_type * A, matrix_type * S, matr
double nsc = 1/sqrt(ens_size-1); // Scale factor
matrix_type * Cd = matrix_alloc( nrobs, nrobs ); // Cov(E), where E = measurement perturbations?
// Empirical error covar. R is left unused. Investigate?
// Empirical error covar. R is left unused. Investigate?
enkf_linalg_Covariance(Cd ,E ,nsc, nrobs); // Cd = SampCov(E) (including (N-1) normalization)
matrix_inv(Cd); // In-place inversion
rml_enkf_open_log_file(data);
rml_enkf_log_open(data->rml_log , data->iteration_nr);
fprintf(stdout,"\nIter %d --> %d", data->iteration_nr, data->iteration_nr + 1);
@@ -641,9 +541,9 @@ void rml_enkf_updateA(void * module_data, matrix_type * A, matrix_type * S, matr
// Lambda = Normalized data mismatch (rounded)
if (data->lambda_recalculate)
if (rml_enkf_config_get_lambda_recalculate( data->config ))
data->lambda = pow(10 , floor(log10(Sk_new / (2*nrobs))) );
// Accept/Reject update? Lambda calculation.
{
bool mismatch_reduced = false;
@@ -651,65 +551,70 @@ void rml_enkf_updateA(void * module_data, matrix_type * A, matrix_type * S, matr
if (Sk_new < data->Sk)
mismatch_reduced = true;
if (Std_new <= data->Std)
std_reduced = true;
fprintf(stdout,"\nWriting iter info to file now. Iter %d --> %d", data->iteration_nr, data->iteration_nr + 1);
rml_enkf_write_iter_info(data, Sk_new, Std_new);
rml_enkf_write_iter_info(data, data->Sk , Sk_new, Std_new);
if (mismatch_reduced) {
/*
Stop check: if ( (1- (Sk_new/data->Sk)) < .0001) // check convergence ** model change norm has to be added in this!!
*/
// Reduce Lambda
if (std_reduced)
data->lambda = data->lambda * data->lambda_reduce_factor;
rml_enkf_common_store_state(data->state , A , data->ens_mask );
if (std_reduced)
data->lambda = data->lambda * rml_enkf_config_get_lambda_decrease_factor( data->config );
rml_enkf_common_store_state(data->previous_state , A , data->ens_mask );
data->Sk = Sk_new;
data->Std=Std_new;
data->iteration_nr++;
} else {
// Increase lambda
data->lambda = data->lambda * data->lambda_increase_factor;
// A = data->state
rml_enkf_common_recover_state( data->state , A , data->ens_mask );
data->lambda = data->lambda * rml_enkf_config_get_lambda_increase_factor( data->config );
// A = data->previous_state
rml_enkf_common_recover_state( data->previous_state , A , data->ens_mask );
}
}
// Update dependant on data mismatch (delta m_1)
rml_enkf_initA__(data , A , S , Cd , E , D , Ud , Wd , VdT);
// Update dependant on prior mismatch (delta m_2)
if (data->use_prior) {
if (rml_enkf_config_get_use_prior(data->config)) {
rml_enkf_init_Csc( data );
rml_enkf_init2__(data , A , Wd , VdT);
}
// Free
matrix_free(Skm);
matrix_free( Ud );
matrix_free( VdT );
free( Wd );
}
if (data->lambda < data->lambda_min)
data->lambda = data->lambda_min;
{
double lambda_min = rml_enkf_config_get_lambda_min( data->config );
if (data->lambda < lambda_min)
data->lambda = lambda_min;
}
if (data->log_stream)
fclose( data->log_stream );
rml_enkf_log_close( data->rml_log );
matrix_free(Cd);
}
// Called from analysis_module.c: analysis_module_init_update()
void rml_enkf_init_update(void * arg, const bool_vector_type * ens_mask, const matrix_type * S, const matrix_type * R, const matrix_type * dObs, const matrix_type * E, const matrix_type * D ) {
void rml_enkf_init_update(void * arg, const bool_vector_type * ens_mask, const matrix_type * S, const matrix_type * R, const matrix_type * dObs, const matrix_type * E, const matrix_type * D ) {
rml_enkf_data_type * module_data = rml_enkf_data_safe_cast( arg );
bool_vector_memcpy( module_data->ens_mask , ens_mask );
if (module_data->ens_mask)
bool_vector_free( module_data->ens_mask );
module_data->ens_mask = bool_vector_alloc_copy( ens_mask );
}
@@ -717,6 +622,7 @@ void rml_enkf_init_update(void * arg, const bool_vector_type * ens_mask, const m
//**********************************************
// Set / Get basic types
//**********************************************
@@ -724,9 +630,9 @@ bool rml_enkf_set_int( void * arg , const char * var_name , int value) {
rml_enkf_data_type * module_data = rml_enkf_data_safe_cast( arg );
{
bool name_recognized = true;
if (strcmp( var_name , ENKF_NCOMP_KEY_) == 0)
rml_enkf_set_subspace_dimension( module_data , value );
rml_enkf_config_set_subspace_dimension(module_data->config , value);
else if (strcmp( var_name , ITER_KEY) == 0)
rml_enkf_set_iteration_nr( module_data , value );
else
@@ -750,13 +656,13 @@ bool rml_enkf_set_bool( void * arg , const char * var_name , bool value) {
rml_enkf_data_type * module_data = rml_enkf_data_safe_cast( arg );
{
bool name_recognized = true;
if (strcmp( var_name , USE_PRIOR_KEY) == 0)
rml_enkf_set_use_prior( module_data , value );
rml_enkf_config_set_use_prior( module_data->config , value);
else if (strcmp( var_name , CLEAR_LOG_KEY) == 0)
rml_enkf_set_clear_log( module_data , value );
rml_enkf_log_set_clear_log( module_data->rml_log , value );
else if (strcmp( var_name , LAMBDA_RECALCULATE_KEY) == 0)
rml_enkf_set_lambda_recalculate( module_data , value );
rml_enkf_config_set_lambda_recalculate( module_data->config , value );
else
name_recognized = false;
@@ -768,11 +674,11 @@ bool rml_enkf_get_bool( const void * arg, const char * var_name) {
const rml_enkf_data_type * module_data = rml_enkf_data_safe_cast_const( arg );
{
if (strcmp(var_name , USE_PRIOR_KEY) == 0)
return module_data->use_prior;
else if (strcmp(var_name , CLEAR_LOG_KEY) == 0)
return module_data->clear_log;
else if (strcmp(var_name , LAMBDA_RECALCULATE_KEY) == 0)
return module_data->lambda_recalculate;
return rml_enkf_config_get_use_prior( module_data->config );
else if (strcmp(var_name , CLEAR_LOG_KEY) == 0)
return rml_enkf_log_get_clear_log( module_data->rml_log );
else if (strcmp(var_name , LAMBDA_RECALCULATE_KEY) == 0)
return rml_enkf_config_get_lambda_recalculate( module_data->config );
else
return false;
}
@@ -784,15 +690,15 @@ bool rml_enkf_set_double( void * arg , const char * var_name , double value) {
bool name_recognized = true;
if (strcmp( var_name , ENKF_TRUNCATION_KEY_) == 0)
rml_enkf_set_truncation( module_data , value );
rml_enkf_config_set_truncation( module_data->config , value );
else if (strcmp( var_name , LAMBDA_INCREASE_FACTOR_KEY) == 0)
rml_enkf_set_lambda_increase_factor( module_data , value );
rml_enkf_config_set_lambda_increase_factor( module_data->config , value );
else if (strcmp( var_name , LAMBDA_REDUCE_FACTOR_KEY) == 0)
rml_enkf_set_lambda_reduce_factor( module_data , value );
rml_enkf_config_set_lambda_decrease_factor( module_data->config , value );
else if (strcmp( var_name , LAMBDA0_KEY) == 0)
rml_enkf_set_lambda0( module_data , value );
rml_enkf_config_set_lambda0( module_data->config , value );
else if (strcmp( var_name , LAMBDA_MIN_KEY) == 0)
rml_enkf_set_lambda_min( module_data , value );
rml_enkf_config_set_lambda_min( module_data->config , value );
else
name_recognized = false;
@@ -804,17 +710,21 @@ double rml_enkf_get_double( const void * arg, const char * var_name) {
const rml_enkf_data_type * module_data = rml_enkf_data_safe_cast_const( arg );
{
if (strcmp(var_name , LAMBDA_REDUCE_FACTOR_KEY) == 0)
return module_data->lambda_reduce_factor;
return rml_enkf_config_get_lambda_decrease_factor(module_data->config);
if (strcmp(var_name , LAMBDA_INCREASE_FACTOR_KEY) == 0)
return module_data->lambda_increase_factor;
return rml_enkf_config_get_lambda_increase_factor(module_data->config);
if (strcmp(var_name , LAMBDA0_KEY) == 0)
return module_data->lambda0;
return rml_enkf_config_get_lambda0(module_data->config);
if (strcmp(var_name , LAMBDA_MIN_KEY) == 0)
return module_data->lambda_min;
return rml_enkf_config_get_lambda_min(module_data->config);
if (strcmp(var_name , ENKF_TRUNCATION_KEY_) == 0)
return module_data->truncation;
else
return -1;
return rml_enkf_config_get_truncation( module_data->config );
return -1;
}
}
@@ -823,9 +733,9 @@ bool rml_enkf_set_string( void * arg , const char * var_name , const char * valu
rml_enkf_data_type * module_data = rml_enkf_data_safe_cast( arg );
{
bool name_recognized = true;
if (strcmp( var_name , LOG_FILE_KEY) == 0)
rml_enkf_set_log_file( module_data , value );
rml_enkf_log_set_log_file( module_data->rml_log , value );
else
name_recognized = false;
@@ -836,7 +746,7 @@ bool rml_enkf_set_string( void * arg , const char * var_name , const char * valu
long rml_enkf_get_options( void * arg , long flag ) {
rml_enkf_data_type * module_data = rml_enkf_data_safe_cast( arg );
{
return module_data->option_flags;
return rml_enkf_config_get_option_flags( module_data->config );
}
}
@@ -871,7 +781,7 @@ void * rml_enkf_get_ptr( const void * arg , const char * var_name ) {
const rml_enkf_data_type * module_data = rml_enkf_data_safe_cast_const( arg );
{
if (strcmp(var_name , LOG_FILE_KEY) == 0)
return module_data->log_file;
return (void *) rml_enkf_log_get_log_file( module_data->rml_log );
else
return NULL;
}
@@ -895,13 +805,13 @@ void * rml_enkf_get_ptr( const void * arg , const char * var_name ) {
analysis_table_type SYMBOL_TABLE = {
.alloc = rml_enkf_data_alloc,
.freef = rml_enkf_data_free,
.set_int = rml_enkf_set_int ,
.set_double = rml_enkf_set_double ,
.set_bool = rml_enkf_set_bool,
.set_int = rml_enkf_set_int ,
.set_double = rml_enkf_set_double ,
.set_bool = rml_enkf_set_bool,
.set_string = rml_enkf_set_string,
.get_options = rml_enkf_get_options ,
.get_options = rml_enkf_get_options ,
.initX = NULL,
.updateA = rml_enkf_updateA ,
.updateA = rml_enkf_updateA ,
.init_update = rml_enkf_init_update ,
.complete_update = NULL,
.has_var = rml_enkf_has_var,
+18 -18
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'rml_enkf.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'rml_enkf.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
@@ -38,7 +38,7 @@
// zzz_enkf_common_recover_state(state , A ,ens_mask) assigns state to A. RESIZES A to rows(state)-by-SUM(ens_mask)
void rml_enkf_common_store_state( matrix_type * state , const matrix_type * A , const bool_vector_type * ens_mask ) {
void rml_enkf_common_store_state( matrix_type * state , const matrix_type * A , const bool_vector_type * ens_mask ) {
matrix_resize( state , matrix_get_rows( A ) , bool_vector_size( ens_mask ) , false);
{
const int ens_size = bool_vector_size( ens_mask );
@@ -55,11 +55,11 @@ void rml_enkf_common_store_state( matrix_type * state , const matrix_type * A ,
void rml_enkf_common_recover_state( const matrix_type * state , matrix_type * A , const bool_vector_type * ens_mask ) {
void rml_enkf_common_recover_state( const matrix_type * state , matrix_type * A , const bool_vector_type * ens_mask ) {
const int ens_size = bool_vector_size( ens_mask );
const int active_size = bool_vector_count_equal( ens_mask , true );
const int rows = matrix_get_rows( state );
matrix_resize( A , rows , active_size , false );
{
int active_index = 0;
@@ -0,0 +1,168 @@
/*
Copyright (C) 2015 Statoil ASA, Norway.
The file 'rml_enkf_config.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <ert/util/util.h>
#include <ert/util/type_macros.h>
#include <ert/analysis/std_enkf.h>
#include <ert/analysis/analysis_module.h>
#include <rml_enkf_config.h>
#define INVALID_SUBSPACE_DIMENSION -1
#define INVALID_TRUNCATION -1
#define DEFAULT_SUBSPACE_DIMENSION INVALID_SUBSPACE_DIMENSION
#define DEFAULT_USE_PRIOR true
#define DEFAULT_LAMBDA_INCREASE_FACTOR 4
#define DEFAULT_LAMBDA_REDUCE_FACTOR 0.1
#define DEFAULT_LAMBDA0 -1
#define DEFAULT_LAMBDA_MIN 0.01
#define DEFAULT_LAMBDA_RECALCULATE false
#define RML_ENKF_CONFIG_TYPE_ID 61400061
struct rml_enkf_config_struct {
UTIL_TYPE_ID_DECLARATION;
double truncation; // Controlled by config key: ENKF_TRUNCATION_KEY
int subspace_dimension; // Controlled by config key: ENKF_NCOMP_KEY (-1: use Truncation instead)
long option_flags;
bool use_prior; // Use exact/approximate scheme? Approximate scheme drops the "prior" term in the LM step.
double lambda0;
double lambda_min;
double lambda_decrease_factor;
double lambda_increase_factor;
bool lambda_recalculate;
};
rml_enkf_config_type * rml_enkf_config_alloc() {
rml_enkf_config_type * config = util_malloc( sizeof * config );
UTIL_TYPE_ID_INIT( config , RML_ENKF_CONFIG_TYPE_ID );
rml_enkf_config_set_truncation( config , DEFAULT_ENKF_TRUNCATION_);
rml_enkf_config_set_subspace_dimension( config , DEFAULT_SUBSPACE_DIMENSION);
rml_enkf_config_set_use_prior( config , DEFAULT_USE_PRIOR );
rml_enkf_config_set_option_flags( config , ANALYSIS_NEED_ED + ANALYSIS_UPDATE_A + ANALYSIS_ITERABLE + ANALYSIS_SCALE_DATA);
rml_enkf_config_set_lambda_min( config , DEFAULT_LAMBDA_MIN );
rml_enkf_config_set_lambda0( config , DEFAULT_LAMBDA0 );
rml_enkf_config_set_lambda_decrease_factor( config , DEFAULT_LAMBDA_REDUCE_FACTOR );
rml_enkf_config_set_lambda_increase_factor( config , DEFAULT_LAMBDA_INCREASE_FACTOR );
rml_enkf_config_set_lambda_recalculate( config , DEFAULT_LAMBDA_RECALCULATE );
return config;
}
bool rml_enkf_config_get_use_prior( const rml_enkf_config_type * config ) {
return config->use_prior;
}
void rml_enkf_config_set_use_prior( rml_enkf_config_type * config , bool use_prior) {
config->use_prior = use_prior;
}
double rml_enkf_config_get_truncation( rml_enkf_config_type * config ) {
return config->truncation;
}
void rml_enkf_config_set_truncation( rml_enkf_config_type * config , double truncation) {
config->truncation = truncation;
if (truncation > 0.0)
config->subspace_dimension = INVALID_SUBSPACE_DIMENSION;
}
int rml_enkf_config_get_subspace_dimension( rml_enkf_config_type * config ) {
return config->subspace_dimension;
}
void rml_enkf_config_set_subspace_dimension( rml_enkf_config_type * config , int subspace_dimension) {
config->subspace_dimension = subspace_dimension;
if (subspace_dimension > 0)
config->truncation = INVALID_TRUNCATION;
}
void rml_enkf_config_set_option_flags( rml_enkf_config_type * config , long flags) {
config->option_flags = flags;
}
long rml_enkf_config_get_option_flags( const rml_enkf_config_type * config ) {
return config->option_flags;
}
double rml_enkf_config_get_lambda0( rml_enkf_config_type * config ) {
return config->lambda0;
}
void rml_enkf_config_set_lambda0( rml_enkf_config_type * config , double lambda0) {
config->lambda0 = lambda0;
}
double rml_enkf_config_get_lambda_min( rml_enkf_config_type * config ) {
return config->lambda_min;
}
void rml_enkf_config_set_lambda_min( rml_enkf_config_type * config , double lambda_min) {
config->lambda_min = lambda_min;
}
double rml_enkf_config_get_lambda_increase_factor( rml_enkf_config_type * config ) {
return config->lambda_increase_factor;
}
void rml_enkf_config_set_lambda_increase_factor( rml_enkf_config_type * config , double lambda_increase_factor) {
config->lambda_increase_factor = lambda_increase_factor;
}
double rml_enkf_config_get_lambda_decrease_factor( rml_enkf_config_type * config ) {
return config->lambda_decrease_factor;
}
void rml_enkf_config_set_lambda_decrease_factor( rml_enkf_config_type * config , double lambda_decrease_factor) {
config->lambda_decrease_factor = lambda_decrease_factor;
}
bool rml_enkf_config_get_lambda_recalculate( const rml_enkf_config_type * config ) {
return config->lambda_recalculate;
}
void rml_enkf_config_set_lambda_recalculate( rml_enkf_config_type * config , bool lambda_recalculate) {
config->lambda_recalculate = lambda_recalculate;
}
void rml_enkf_config_free(rml_enkf_config_type * config) {
free( config );
}
@@ -0,0 +1,64 @@
/*
Copyright (C) 2015 Statoil ASA, Norway.
The file 'rml_enkf_config.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef RML_ENKF_CONFIG_H
#define RML_ENKF_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct rml_enkf_config_struct rml_enkf_config_type;
rml_enkf_config_type * rml_enkf_config_alloc();
void rml_enkf_config_free(rml_enkf_config_type * config);
int rml_enkf_config_get_subspace_dimension( rml_enkf_config_type * config );
void rml_enkf_config_set_subspace_dimension( rml_enkf_config_type * config , int subspace_dimension);
double rml_enkf_config_get_truncation( rml_enkf_config_type * config );
void rml_enkf_config_set_truncation( rml_enkf_config_type * config , double truncation);
bool rml_enkf_config_get_use_prior( const rml_enkf_config_type * config );
void rml_enkf_config_set_use_prior( rml_enkf_config_type * config , bool use_prior);
void rml_enkf_config_set_option_flags( rml_enkf_config_type * config , long flags);
long rml_enkf_config_get_option_flags( const rml_enkf_config_type * config );
double rml_enkf_config_get_lambda0( rml_enkf_config_type * config );
void rml_enkf_config_set_lambda0( rml_enkf_config_type * config , double lambda0);
double rml_enkf_config_get_lambda_min( rml_enkf_config_type * config );
void rml_enkf_config_set_lambda_min( rml_enkf_config_type * config , double lambda_min);
double rml_enkf_config_get_lambda_increase_factor( rml_enkf_config_type * config );
void rml_enkf_config_set_lambda_increase_factor( rml_enkf_config_type * config , double lambda_increase_factor);
double rml_enkf_config_get_lambda_decrease_factor( rml_enkf_config_type * config );
void rml_enkf_config_set_lambda_decrease_factor( rml_enkf_config_type * config , double lambda_decrease_factor);
bool rml_enkf_config_get_lambda_recalculate( const rml_enkf_config_type * config );
void rml_enkf_config_set_lambda_recalculate( rml_enkf_config_type * config , bool lambda_recalculate);
#ifdef __cplusplus
}
#endif
#endif
+108
View File
@@ -0,0 +1,108 @@
/*
Copyright (C) 2015 Statoil ASA, Norway.
The file 'rml_enkf_log.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ert/util/util.h>
#include <rml_enkf_log.h>
#define DEFAULT_LOG_FILE "rml_enkf.out"
#define DEFAULT_CLEAR_LOG true
struct rml_enkf_log_struct {
bool clear_log;
char * log_file;
FILE * log_stream;
};
rml_enkf_log_type * rml_enkf_log_alloc() {
rml_enkf_log_type * rml_log = util_malloc( sizeof * rml_log );
rml_log->log_file = NULL;
rml_log->log_stream = NULL;
rml_enkf_log_set_clear_log( rml_log , DEFAULT_CLEAR_LOG );
return rml_log;
}
bool rml_enkf_log_get_clear_log( const rml_enkf_log_type * data ) {
return data->clear_log;
}
void rml_enkf_log_set_clear_log( rml_enkf_log_type * data , bool clear_log) {
data->clear_log = clear_log;
}
void rml_enkf_log_set_log_file( rml_enkf_log_type * data , const char * log_file ) {
data->log_file = util_realloc_string_copy( data->log_file , log_file );
}
const char * rml_enkf_log_get_log_file( const rml_enkf_log_type * data) {
return data->log_file;
}
void rml_enkf_log_free(rml_enkf_log_type * rml_log) {
rml_enkf_log_close( rml_log );
util_safe_free( rml_log->log_file );
free( rml_log );
}
void rml_enkf_log_open( rml_enkf_log_type * rml_log , int iteration_nr ) {
if (rml_log->log_file) {
if ( iteration_nr == 0) {
if (rml_log->clear_log)
rml_log->log_stream = util_mkdir_fopen( rml_log->log_file , "w");
else
rml_log->log_stream = util_mkdir_fopen( rml_log->log_file , "a");
} else
rml_log->log_stream = util_fopen( rml_log->log_file , "a");
}
}
bool rml_enkf_log_is_open( const rml_enkf_log_type * rml_log ) {
if (rml_log->log_stream)
return true;
else
return false;
}
void rml_enkf_log_close( rml_enkf_log_type * rml_log ) {
if (rml_log->log_stream)
fclose( rml_log->log_stream );
rml_log->log_stream = NULL;
}
void rml_enkf_log_line( rml_enkf_log_type * rml_log , const char * fmt , ...) {
if (rml_log->log_stream) {
va_list ap;
va_start(ap , fmt);
vfprintf( rml_log->log_stream , fmt , ap );
va_end( ap );
}
}
+45
View File
@@ -0,0 +1,45 @@
/*
Copyright (C) 2015 Statoil ASA, Norway.
The file 'rml_enkf_log.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef RML_ENKF_LOG_H
#define RML_ENKF_LOG_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
typedef struct rml_enkf_log_struct rml_enkf_log_type;
rml_enkf_log_type * rml_enkf_log_alloc();
void rml_enkf_log_free(rml_enkf_log_type * rml_log);
bool rml_enkf_log_get_clear_log( const rml_enkf_log_type * data );
void rml_enkf_log_set_clear_log( rml_enkf_log_type * data , bool clear_log);
void rml_enkf_log_set_log_file( rml_enkf_log_type * data , const char * log_file );
const char * rml_enkf_log_get_log_file( const rml_enkf_log_type * data);
void rml_enkf_log_open( rml_enkf_log_type * rml_log , int iteration_nr );
void rml_enkf_log_close( rml_enkf_log_type * rml_log );
void rml_enkf_log_line( rml_enkf_log_type * rml_log , const char * fmt , ...);
bool rml_enkf_log_is_open( const rml_enkf_log_type * rml_log );
#ifdef __cplusplus
}
#endif
#endif
+74 -74
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'analysis_module.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'analysis_module.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
@@ -36,7 +36,7 @@ struct analysis_module_struct {
UTIL_TYPE_ID_DECLARATION;
void * lib_handle;
void * module_data;
char * symbol_table;
char * symbol_table;
char * lib_name;
analysis_free_ftype * freef;
@@ -49,17 +49,17 @@ struct analysis_module_struct {
analysis_get_options_ftype * get_options;
analysis_set_int_ftype * set_int;
analysis_set_double_ftype * set_double;
analysis_set_bool_ftype * set_bool;
analysis_set_bool_ftype * set_bool;
analysis_set_string_ftype * set_string;
analysis_has_var_ftype * has_var;
analysis_get_int_ftype * get_int;
analysis_get_double_ftype * get_double;
analysis_get_bool_ftype * get_bool;
analysis_get_ptr_ftype * get_ptr;
bool internal;
char * user_name; /* String used to identify this module for the user; not used in
bool internal;
char * user_name; /* String used to identify this module for the user; not used in
the linking process. */
};
@@ -99,15 +99,15 @@ static bool analysis_module_internal_check( analysis_module_type * module ) {
}
static analysis_module_type * analysis_module_alloc__( rng_type * rng ,
const analysis_table_type * table ,
const char * symbol_table ,
const char * lib_name ,
const char * user_name ,
static analysis_module_type * analysis_module_alloc__( rng_type * rng ,
const analysis_table_type * table ,
const char * symbol_table ,
const char * lib_name ,
const char * user_name ,
void * lib_handle ) {
analysis_module_type * module = analysis_module_alloc_empty( user_name , symbol_table , lib_name );
module->lib_handle = lib_handle;
module->initX = table->initX;
module->updateA = table->updateA;
@@ -119,7 +119,7 @@ static analysis_module_type * analysis_module_alloc__( rng_type * rng ,
module->set_bool = table->set_bool;
module->alloc = table->alloc;
module->freef = table->freef;
module->get_options = table->get_options;
module->get_options = table->get_options;
module->has_var = table->has_var;
module->get_int = table->get_int;
module->get_double = table->get_double;
@@ -142,11 +142,11 @@ static analysis_module_type * analysis_module_alloc__( rng_type * rng ,
static analysis_module_type * analysis_module_alloc( rng_type * rng ,
const char * user_name ,
const char * libname ,
static analysis_module_type * analysis_module_alloc( rng_type * rng ,
const char * user_name ,
const char * libname ,
const char * table_name ,
bool verbose,
bool verbose,
analysis_module_load_status_enum * load_status) {
analysis_module_type * module = NULL;
void * lib_handle = dlopen( libname , RTLD_NOW );
@@ -160,15 +160,15 @@ static analysis_module_type * analysis_module_alloc( rng_type * rng ,
if (verbose)
fprintf(stderr , "Failed to load symbol table:%s Error:%s \n",table_name , dlerror());
}
if (module == NULL)
if (module == NULL)
dlclose( lib_handle );
} else {
*load_status = DLOPEN_FAILURE;
if (verbose)
fprintf(stderr , "Failed to load library:%s Error:%s \n",libname , dlerror());
}
if (module != NULL) {
if (libname == NULL)
module->internal = true;
@@ -226,7 +226,7 @@ UTIL_IS_INSTANCE_FUNCTION( analysis_module , ANALYSIS_MODULE_TYPE_ID )
void analysis_module_free( analysis_module_type * module ) {
if (module->freef != NULL)
module->freef( module->module_data );
util_safe_free( module->lib_name );
free( module->user_name );
free( module->symbol_table );
@@ -244,26 +244,26 @@ void analysis_module_free__( void * arg) {
/* Update functions */
void analysis_module_initX(analysis_module_type * module ,
matrix_type * X ,
matrix_type * A ,
matrix_type * S ,
matrix_type * R ,
matrix_type * dObs ,
matrix_type * E ,
void analysis_module_initX(analysis_module_type * module ,
matrix_type * X ,
matrix_type * A ,
matrix_type * S ,
matrix_type * R ,
matrix_type * dObs ,
matrix_type * E ,
matrix_type * D ) {
module->initX(module->module_data , X , A , S , R , dObs , E , D );
}
void analysis_module_updateA(analysis_module_type * module ,
matrix_type * A ,
matrix_type * S ,
matrix_type * R ,
matrix_type * dObs ,
matrix_type * E ,
void analysis_module_updateA(analysis_module_type * module ,
matrix_type * A ,
matrix_type * S ,
matrix_type * R ,
matrix_type * dObs ,
matrix_type * E ,
matrix_type * D ) {
module->updateA(module->module_data , A , S , R , dObs , E , D );
@@ -272,12 +272,12 @@ void analysis_module_updateA(analysis_module_type * module ,
void analysis_module_init_update( analysis_module_type * module ,
const bool_vector_type * ens_mask ,
const matrix_type * S ,
const matrix_type * R ,
const matrix_type * dObs ,
const matrix_type * E ,
void analysis_module_init_update( analysis_module_type * module ,
const bool_vector_type * ens_mask ,
const matrix_type * S ,
const matrix_type * R ,
const matrix_type * dObs ,
const matrix_type * E ,
const matrix_type * D ) {
if (module->init_update != NULL)
module->init_update( module->module_data , ens_mask , S , R , dObs , E , D);
@@ -296,7 +296,7 @@ void analysis_module_complete_update( analysis_module_type * module ) {
static bool analysis_module_set_int(analysis_module_type * module , const char * flag , int value) {
if (module->set_int != NULL)
if (module->set_int != NULL)
return module->set_int( module->module_data , flag , value );
else
return false;
@@ -327,7 +327,7 @@ static bool analysis_module_set_string(analysis_module_type * module , const cha
/*
/*
The input value typically comes from the configuration system and
is in terms of a string, irrespective of the fundamental type of
the underlying parameter. The algorithm for setting the parameter
@@ -346,38 +346,38 @@ bool analysis_module_set_var( analysis_module_type * module , const char * var_n
bool set_ok = false;
{
int int_value;
if (util_sscanf_int( string_value , &int_value ))
if (util_sscanf_int( string_value , &int_value ))
set_ok = analysis_module_set_int( module , var_name , int_value );
if (set_ok)
return true;
}
{
double double_value;
if (util_sscanf_double( string_value , &double_value ))
if (util_sscanf_double( string_value , &double_value ))
set_ok = analysis_module_set_double( module , var_name , double_value );
if (set_ok)
return true;
}
{
bool bool_value;
if (util_sscanf_bool( string_value , &bool_value))
if (util_sscanf_bool( string_value , &bool_value))
set_ok = analysis_module_set_bool( module , var_name , bool_value );
if (set_ok)
return true;
}
set_ok = analysis_module_set_string( module , var_name , string_value );
if (!set_ok)
fprintf(stderr,"** Warning: failed to set %s=%s for analysis module:%s\n", var_name , string_value , module->user_name);
return set_ok;
}
@@ -404,7 +404,7 @@ int analysis_module_get_int( const analysis_module_type * module , const char *
return module->get_int( module->module_data , var );
else
util_exit("%s: Tried to get integer variable:%s from module:%s - get_int() method not implemented for this module\n" , __func__ , var , module->user_name);
} else
} else
util_exit("%s: Tried to get integer variable:%s from module:%s - module does not support this variable \n" , __func__ , var , module->user_name);
return 0;
@@ -417,7 +417,7 @@ bool analysis_module_get_bool( const analysis_module_type * module , const char
return module->get_bool( module->module_data , var );
else
util_exit("%s: Tried to get bool variable:%s from module:%s - get_int() method not implemented for this module\n" , __func__ , var , module->user_name);
} else
} else
util_exit("%s: Tried to get bool variable:%s from module:%s - module does not support this variable \n" , __func__ , var , module->user_name);
return false;
@@ -430,7 +430,7 @@ double analysis_module_get_double( const analysis_module_type * module , const c
return module->get_double( module->module_data , var );
else
util_exit("%s: Tried to get double variable:%s from module:%s - get_double() method not implemented for this module\n" , __func__ , var , module->user_name);
} else
} else
util_exit("%s: Tried to get double variable:%s from module:%s - module does not support this variable \n" , __func__ , var , module->user_name);
return 0;
@@ -443,9 +443,9 @@ void * analysis_module_get_ptr( const analysis_module_type * module , const char
return module->get_ptr( module->module_data , var );
else
util_exit("%s: Tried to get pointer variable:%s from module:%s - get_ptr() method not implemented for this module\n" , __func__ , var , module->user_name);
} else
} else
util_exit("%s: Tried to get pointer variable:%s from module:%s - module does not support this variable \n" , __func__ , var , module->user_name);
return NULL;
}
+132 -128
View File
@@ -21,10 +21,10 @@ void enkf_linalg_genX3(matrix_type * X3 , const matrix_type * W , const matrix_t
for (i=0; i < nrmin; i++)
for (j=0; j < nrobs; j++)
matrix_iset(X1 , i , j , eig[i] * matrix_iget(W , j , i));
matrix_matmul(X2 , X1 , D); /* X2 = X1 * D (Eq. 14.31) */
matrix_matmul(X3 , W , X2); /* X3 = W * X2 = X1 * X2 (Eq. 14.31) */
matrix_matmul(X3 , W , X2); /* X3 = W * X2 = X1 * X2 (Eq. 14.31) */
matrix_free( X1 );
matrix_free( X2 );
}
@@ -34,7 +34,7 @@ void enkf_linalg_genX2(matrix_type * X2 , const matrix_type * S , const matrix_t
const int nrens = matrix_get_columns( S );
const int idim = matrix_get_rows( X2 );
matrix_dgemm(X2 , W , S , true , false , 1.0 , 0.0);
{
{
int i,j;
for (j=0; j < nrens; j++)
for (i=0; i < idim; i++)
@@ -53,11 +53,11 @@ void enkf_linalg_genX2(matrix_type * X2 , const matrix_type * S , const matrix_t
ncomp > 0 , truncation < 0: Use ncomp parameters.
ncomp < 0 , truncation > 0: Truncate at level 'truncation'.
The singular values are returned in the inv_sig0 vector; the values
we retain are inverted and the remaining elements in are explicitly
set to zero.
The left-hand singular vectors are returned in the matrix
U0. Depending on the value of the flag @store_V0T the right hand
singular vectors are stored in the V0T matrix, or just
@@ -74,14 +74,14 @@ void enkf_linalg_genX2(matrix_type * X2 , const matrix_type * S , const matrix_t
/*This function is similar to enkf_linalg_svdS but it returns the eigen values without its inverse and also give the matrices truncated U VT and Sig0*/
// Trunc.SVD(S) = U0 * Sig0 * V0T
int enkf_linalg_svd_truncation(const matrix_type * S ,
double truncation ,
int enkf_linalg_svd_truncation(const matrix_type * S ,
double truncation ,
int ncomp ,
dgesvd_vector_enum store_V0T ,
double * sig0,
matrix_type * U0 ,
dgesvd_vector_enum store_V0T ,
double * sig0,
matrix_type * U0 ,
matrix_type * V0T) {
int num_significant = -1;
int nrows = matrix_get_rows(S);
int ncolumns= matrix_get_columns(S);
@@ -90,9 +90,9 @@ int enkf_linalg_svd_truncation(const matrix_type * S ,
((truncation < 0) && (ncomp > 0))) {
int num_singular_values = util_int_min( matrix_get_rows( S ) , matrix_get_columns( S ));
{
{
matrix_type * workS = matrix_alloc_copy( S );
matrix_dgesvd(DGESVD_MIN_RETURN , store_V0T , workS , sig0 , U0 , V0T);
matrix_dgesvd(DGESVD_MIN_RETURN , store_V0T , workS , sig0 , U0 , V0T);
matrix_free( workS );
}
int i;
@@ -103,11 +103,11 @@ int enkf_linalg_svd_truncation(const matrix_type * S ,
double total_sigma2 = 0;
for (i=0; i < num_singular_values; i++)
total_sigma2 += sig0[i];
/*
/*
Determine the number of singular values by enforcing that
less than a fraction @truncation of the total variance be
accounted for.
accounted for.
*/
num_significant = 0;
{
@@ -116,40 +116,44 @@ int enkf_linalg_svd_truncation(const matrix_type * S ,
if (running_sigma2 / total_sigma2 < truncation) { /* Include one more singular value ? */
num_significant++;
running_sigma2 += sig0[i];
} else
} else
break;
}
}
}
matrix_resize(U0 , nrows , num_significant , true);
matrix_resize(V0T , num_significant , ncolumns , true);
if (num_significant > 0) {
matrix_resize(U0 , nrows , num_significant , true);
matrix_resize(V0T , num_significant , ncolumns , true);
} else
util_abort("%s: zero significant singular values\n",__func__);
}
else
else
util_abort("%s: truncation:%g ncomp:%d - invalid ambigous input.\n",__func__ , truncation , ncomp );
return num_significant;
}
int enkf_linalg_svdS(const matrix_type * S ,
double truncation ,
int enkf_linalg_svdS(const matrix_type * S ,
double truncation ,
int ncomp ,
dgesvd_vector_enum store_V0T ,
double * inv_sig0,
matrix_type * U0 ,
dgesvd_vector_enum store_V0T ,
double * inv_sig0,
matrix_type * U0 ,
matrix_type * V0T) {
double * sig0 = inv_sig0;
int num_significant = 0;
if (((truncation > 0) && (ncomp < 0)) ||
((truncation < 0) && (ncomp > 0))) {
int num_singular_values = util_int_min( matrix_get_rows( S ) , matrix_get_columns( S ));
{
{
matrix_type * workS = matrix_alloc_copy( S );
matrix_dgesvd(DGESVD_MIN_RETURN , store_V0T , workS , sig0 , U0 , V0T);
matrix_dgesvd(DGESVD_MIN_RETURN , store_V0T , workS , sig0 , U0 , V0T);
matrix_free( workS );
}
int i;
@@ -158,13 +162,13 @@ int enkf_linalg_svdS(const matrix_type * S ,
num_significant = ncomp;
else {
double total_sigma2 = 0;
for (i=0; i < num_singular_values; i++)
for (i=0; i < num_singular_values; i++)
total_sigma2 += sig0[i] * sig0[i];
/*
/*
Determine the number of singular values by enforcing that
less than a fraction @truncation of the total variance be
accounted for.
accounted for.
*/
num_significant = 0;
{
@@ -173,7 +177,7 @@ int enkf_linalg_svdS(const matrix_type * S ,
if (running_sigma2 / total_sigma2 < truncation) { /* Include one more singular value ? */
num_significant++;
running_sigma2 += sig0[i] * sig0[i];
} else
} else
break;
}
}
@@ -185,9 +189,9 @@ int enkf_linalg_svdS(const matrix_type * S ,
/* Explicitly setting the insignificant singular values to zero. */
for (i=num_significant; i < num_singular_values; i++)
inv_sig0[i] = 0;
} else
inv_sig0[i] = 0;
} else
util_abort("%s: truncation:%g ncomp:%d - invalid ambigous input.\n",__func__ , truncation , ncomp );
return num_significant;
}
@@ -200,14 +204,14 @@ void enkf_linalg_Cee(matrix_type * B, int nrens , const matrix_type * R , const
matrix_dgemm(X0 , U0 , R , true , false , 1.0 , 0.0); /* X0 = U0^T * R */
matrix_dgemm(B , X0 , U0 , false , false , 1.0 , 0.0); /* B = X0 * U0 */
matrix_free( X0 );
}
}
{
int i ,j;
/* Funny code ??
/* Funny code ??
Multiply B with S^(-1)from left and right
BHat = S^(-1) * B * S^(-1)
BHat = S^(-1) * B * S^(-1)
*/
for (j=0; j < matrix_get_columns( B ) ; j++)
for (i=0; i < matrix_get_rows( B ); i++)
@@ -217,26 +221,26 @@ void enkf_linalg_Cee(matrix_type * B, int nrens , const matrix_type * R , const
for (i=0; i < matrix_get_rows( B ); i++)
matrix_imul(B , i , j , inv_sig0[j]);
}
matrix_scale(B , nrens - 1.0);
}
void enkf_linalg_lowrankCinv__(const matrix_type * S ,
const matrix_type * R ,
matrix_type * V0T ,
matrix_type * Z,
double * eig ,
matrix_type * U0,
double truncation,
void enkf_linalg_lowrankCinv__(const matrix_type * S ,
const matrix_type * R ,
matrix_type * V0T ,
matrix_type * Z,
double * eig ,
matrix_type * U0,
double truncation,
int ncomp) {
const int nrobs = matrix_get_rows( S );
const int nrens = matrix_get_columns( S );
const int nrmin = util_int_min( nrobs , nrens );
double * inv_sig0 = util_calloc( nrmin , sizeof * inv_sig0);
if (V0T != NULL)
@@ -246,18 +250,18 @@ void enkf_linalg_lowrankCinv__(const matrix_type * S ,
{
matrix_type * B = matrix_alloc( nrmin , nrmin );
enkf_linalg_Cee( B , nrens , R , U0 , inv_sig0); /* B = Xo = (N-1) * Sigma0^(+) * U0'* Cee * U0 * Sigma0^(+') (14.26)*/
enkf_linalg_Cee( B , nrens , R , U0 , inv_sig0); /* B = Xo = (N-1) * Sigma0^(+) * U0'* Cee * U0 * Sigma0^(+') (14.26)*/
matrix_dgesvd(DGESVD_MIN_RETURN , DGESVD_NONE, B , eig, Z , NULL);
matrix_free( B );
}
{
int i,j;
/* Lambda1 = (I + Lambda)^(-1) */
for (i=0; i < nrmin; i++)
for (i=0; i < nrmin; i++)
eig[i] = 1.0 / (1 + eig[i]);
for (j=0; j < nrmin; j++)
for (i=0; i < nrmin; i++)
matrix_imul(Z , i , j , inv_sig0[i]); /* Z2 = Sigma0^(+) * Z; */
@@ -266,20 +270,20 @@ void enkf_linalg_lowrankCinv__(const matrix_type * S ,
}
void enkf_linalg_lowrankCinv(const matrix_type * S ,
const matrix_type * R ,
void enkf_linalg_lowrankCinv(const matrix_type * S ,
const matrix_type * R ,
matrix_type * W , /* Corresponding to X1 from Eq. 14.29 */
double * eig , /* Corresponding to 1 / (1 + Lambda_1) (14.29) */
double truncation ,
int ncomp) {
const int nrobs = matrix_get_rows( S );
const int nrens = matrix_get_columns( S );
const int nrmin = util_int_min( nrobs , nrens );
matrix_type * U0 = matrix_alloc( nrobs , nrmin );
matrix_type * Z = matrix_alloc( nrmin , nrmin );
enkf_linalg_lowrankCinv__( S , R , NULL , Z , eig , U0 , truncation , ncomp);
matrix_matmul(W , U0 , Z); /* X1 = W = U0 * Z2 = U0 * Sigma0^(+') * Z */
@@ -288,13 +292,13 @@ void enkf_linalg_lowrankCinv(const matrix_type * S ,
}
void enkf_linalg_meanX5(const matrix_type * S ,
const matrix_type * W ,
const double * eig ,
const matrix_type * dObs,
void enkf_linalg_meanX5(const matrix_type * S ,
const matrix_type * W ,
const double * eig ,
const matrix_type * dObs,
matrix_type * X5) {
const int nrens = matrix_get_columns( S );
const int nrobs = matrix_get_rows( S );
const int nrmin = util_int_min( nrobs , nrens );
@@ -304,8 +308,8 @@ void enkf_linalg_meanX5(const matrix_type * S ,
double * y1 = &work[0];
double * y2 = &work[nrmin];
double * y3 = &work[2*nrmin];
double * y4 = &work[2*nrmin + nrobs];
double * y4 = &work[2*nrmin + nrobs];
if (nrobs == 1) {
/* Is this special casing necessary ??? */
y1[0] = matrix_iget(W , 0,0) * matrix_iget( innov , 0 , 0);
@@ -317,13 +321,13 @@ void enkf_linalg_meanX5(const matrix_type * S ,
matrix_dgemv(W , matrix_get_data( innov ) , y1 , true , 1.0, 0.0); /* y1 = Trans(W) * innov */
for (int i= 0; i < nrmin; i++)
y2[i] = eig[i] * y1[i]; /* y2 = eig * y1 */
matrix_dgemv(W , y2 , y3 , false , 1.0 , 0.0); /* y3 = W * y2; */
matrix_dgemv(W , y2 , y3 , false , 1.0 , 0.0); /* y3 = W * y2; */
matrix_dgemv(S , y3 , y4 , true , 1.0 , 0.0); /* y4 = Trans(S) * y3 */
}
for (int iens = 0; iens < nrens; iens++)
matrix_set_column(X5 , y4 , iens );
matrix_shift(X5 , 1.0/nrens);
}
free( work );
@@ -332,7 +336,7 @@ void enkf_linalg_meanX5(const matrix_type * S ,
void enkf_linalg_X5sqrt(matrix_type * X2 , matrix_type * X5 , const matrix_type * randrot, int nrobs) {
void enkf_linalg_X5sqrt(matrix_type * X2 , matrix_type * X5 , const matrix_type * randrot, int nrobs) {
const int nrens = matrix_get_columns( X5 );
const int nrmin = util_int_min( nrobs , nrens );
matrix_type * VT = matrix_alloc( nrens , nrens );
@@ -348,24 +352,24 @@ void enkf_linalg_X5sqrt(matrix_type * X2 , matrix_type * X5 , const matrix_type
int i,j;
for (i = 0; i < nrmin; i++)
isig[i] = sqrt( util_double_max( 1.0 - sig[i]*sig[i] ,0.0));
for (j = 0; j < nrens; j++)
for (i = 0; i < nrens; i++)
matrix_iset(X3 , i , j , matrix_iget(VT , j , i));
for (j=0; j< nrmin; j++)
matrix_scale_column(X3 , j , isig[j]);
matrix_dgemm(X33 , X3 , VT , false , false , 1.0 , 0.0); /* X33 = X3 * VT */
if (randrot != NULL)
matrix_dgemm(X4 , X33 , randrot , false, false , 1.0 , 0.0); /* X4 = X33 * Randrot */
matrix_dgemm(X4 , X33 , randrot , false, false , 1.0 , 0.0); /* X4 = X33 * Randrot */
else
matrix_assign(X4 , X33);
matrix_set(IenN , -1.0/ nrens);
for (i = 0; i < nrens; i++)
matrix_iadd(IenN , i , i , 1.0);
matrix_dgemm(X5 , IenN , X4 , false , false , 1.0 , 1.0); /* X5 = IenN * X4 + X5 */
matrix_free( X3 );
@@ -383,51 +387,51 @@ void enkf_linalg_X5sqrt(matrix_type * X2 , matrix_type * X5 , const matrix_type
matrix_type * enkf_linalg_alloc_innov( const matrix_type * dObs , const matrix_type * S) {
matrix_type * innov = matrix_alloc_copy( dObs );
for (int iobs =0; iobs < matrix_get_row_sum( dObs , iobs); iobs++)
for (int iobs =0; iobs < matrix_get_row_sum( dObs , iobs); iobs++)
matrix_isub( innov , iobs , 0 , matrix_get_row_sum( S , iobs ));
return innov;
}
void enkf_linalg_init_stdX( matrix_type * X , const matrix_type * S , const matrix_type * D ,
void enkf_linalg_init_stdX( matrix_type * X , const matrix_type * S , const matrix_type * D ,
const matrix_type * W , const double * eig , bool bootstrap) {
int nrobs = matrix_get_rows( W );
int ens_size = matrix_get_rows( X );
matrix_type * X3 = matrix_alloc(nrobs , ens_size);
enkf_linalg_genX3(X3 , W , D , eig ); /* X2 = diag(eig) * W' * D (Eq. 14.31, Evensen (2007)) */
/* X3 = W * X2 = X1 * X2 (Eq. 14.31, Evensen (2007)) */
/* X3 = W * X2 = X1 * X2 (Eq. 14.31, Evensen (2007)) */
matrix_dgemm( X , S , X3 , true , false , 1.0 , 0.0); /* X = S' * X3 */
if (!bootstrap) {
for (int i = 0; i < ens_size ; i++)
matrix_iadd( X , i , i , 1.0); /*X = I + X */
}
matrix_free( X3 );
}
void enkf_linalg_init_sqrtX(matrix_type * X5 ,
const matrix_type * S ,
const matrix_type * randrot ,
const matrix_type * innov ,
const matrix_type * W ,
const double * eig ,
void enkf_linalg_init_sqrtX(matrix_type * X5 ,
const matrix_type * S ,
const matrix_type * randrot ,
const matrix_type * innov ,
const matrix_type * W ,
const double * eig ,
bool bootstrap) {
const int nrobs = matrix_get_rows( S );
const int nrens = matrix_get_columns( S );
const int nrmin = util_int_min( nrobs , nrens );
matrix_type * X2 = matrix_alloc(nrmin , nrens);
if (bootstrap)
util_exit("%s: Sorry bootstrap support not fully implemented for SQRT scheme\n",__func__);
enkf_linalg_meanX5( S , W , eig , innov , X5 );
enkf_linalg_genX2(X2 , S , W , eig);
enkf_linalg_X5sqrt(X2 , X5 , randrot , nrobs);
@@ -450,14 +454,14 @@ void enkf_linalg_init_sqrtX(matrix_type * X5 ,
2. Then the QR decomposition is computed, and Q will then be a random orthogonal matrix.
3. The diagonal elements of R are extracted and we construct the diagonal matrix X(j,j)=R(j,j)/|R(j,j)|
4. An updated Q'=Q X is computed, and this is now a random orthogonal matrix with a Haar measure.
The implementation is a plain reimplementation/copy of the old m_randrot.f90 function.
*/
/**
NB: This should rather use the implementation in m_mean_preserving_rotation.f90.
NB: This should rather use the implementation in m_mean_preserving_rotation.f90.
*/
void enkf_linalg_set_randrot( matrix_type * Q , rng_type * rng) {
@@ -465,8 +469,8 @@ void enkf_linalg_set_randrot( matrix_type * Q , rng_type * rng) {
double * tau = util_calloc( ens_size , sizeof * tau );
int * sign = util_calloc( ens_size , sizeof * sign);
for (int i = 0; i < ens_size; i++)
for (int j = 0; j < ens_size; j++)
for (int i = 0; i < ens_size; i++)
for (int j = 0; j < ens_size; j++)
matrix_iset(Q , i , j , rng_std_normal( rng ));
matrix_dgeqrf( Q , tau ); /* QR factorization */
@@ -482,7 +486,7 @@ void enkf_linalg_set_randrot( matrix_type * Q , rng_type * rng) {
}
free( sign );
free( tau );
free( tau );
}
@@ -492,7 +496,7 @@ void enkf_linalg_set_randrot( matrix_type * Q , rng_type * rng) {
Generates the mean preserving random rotation for the EnKF SQRT algorithm
using the algorithm from Sakov 2006-07. I.e, generate rotation Up such that
Up*Up^T=I and Up*1=1 (all rows have sum = 1) see eq 17.
From eq 18, Up=B * Upb * B^T
From eq 18, Up=B * Upb * B^T
B is a random orthonormal basis with the elements in the first column equals 1/sqrt(nrens)
Upb = | 1 0 |
@@ -507,8 +511,8 @@ matrix_type * enkf_linalg_alloc_mp_randrot(int ens_size , rng_type * rng) {
matrix_type * B = matrix_alloc( ens_size , ens_size );
matrix_type * Upb = matrix_alloc( ens_size , ens_size );
matrix_type * U = matrix_alloc_shared(Upb , 1 , 1 , ens_size - 1, ens_size - 1);
{
int k,j;
matrix_type * R = matrix_alloc( ens_size , ens_size );
@@ -517,7 +521,7 @@ matrix_type * enkf_linalg_alloc_mp_randrot(int ens_size , rng_type * rng) {
/* modified_gram_schmidt is used to create the orthonormal basis in B.*/
for (k=0; k < ens_size; k++) {
double Rkk = sqrt( matrix_column_column_dot_product( B , k , B , k));
double Rkk = sqrt( matrix_column_column_dot_product( B , k , B , k));
matrix_iset(R , k , k , Rkk);
matrix_scale_column(B , k , 1.0/Rkk);
for (j=k+1; j < ens_size; j++) {
@@ -535,23 +539,23 @@ matrix_type * enkf_linalg_alloc_mp_randrot(int ens_size , rng_type * rng) {
}
matrix_free( R );
}
enkf_linalg_set_randrot( U , rng );
matrix_iset( Upb , 0 , 0 , 1);
{
matrix_type * Q = matrix_alloc( ens_size , ens_size );
matrix_dgemm( Q , B , Upb , false , false , 1, 0); /* Q = B * Ubp */
matrix_dgemm( Up , Q , B , false , true , 1, 0); /* Up = Q * T(B) */
matrix_free( Q );
}
matrix_free( B );
matrix_free( Upb );
matrix_free( U );
}
return Up;
}
@@ -561,7 +565,7 @@ matrix_type * enkf_linalg_alloc_mp_randrot(int ens_size , rng_type * rng) {
/**
Checking that the sum through one row in the X matrix equals
@target_sum. @target_sum will be 1 normally, and zero if we are doing
bootstrap.
bootstrap.
*/
void enkf_linalg_checkX(const matrix_type * X , bool bootstrap) {
@@ -572,10 +576,10 @@ void enkf_linalg_checkX(const matrix_type * X , bool bootstrap) {
target_sum = 0;
else
target_sum = 1;
for (int icol = 0; icol < matrix_get_columns( X ); icol++) {
double col_sum = matrix_get_column_sum(X , icol);
if (fabs(col_sum - target_sum) > 0.0001)
if (fabs(col_sum - target_sum) > 0.0001)
util_abort("%s: something is seriously broken. col:%d col_sum = %g != %g - ABORTING\n",__func__ , icol , col_sum , target_sum);
}
}
@@ -584,14 +588,14 @@ void enkf_linalg_checkX(const matrix_type * X , bool bootstrap) {
/*****************************************************************/
void enkf_linalg_get_PC( const matrix_type * S0,
const matrix_type * dObs ,
void enkf_linalg_get_PC( const matrix_type * S0,
const matrix_type * dObs ,
double truncation,
int ncomp,
int ncomp,
matrix_type * PC,
matrix_type * PC_obs,
matrix_type * PC_obs,
double_vector_type * singular_values) {
const int nrobs = matrix_get_rows( S0 );
const int nrens = matrix_get_columns( S0 );
const int nrmin = util_int_min( nrobs , nrens );
@@ -607,7 +611,7 @@ void enkf_linalg_get_PC( const matrix_type * S0,
{
matrix_type * S_mean = matrix_alloc( nrobs , 1 );
int num_PC = enkf_linalg_svdS(S , truncation , ncomp, DGESVD_NONE , inv_sig0 , U0 , NULL);
matrix_assign( S , S0); // The svd routine will overwrite S - we therefor must pick it up again from S0.
matrix_subtract_and_store_row_mean( S , S_mean);
@@ -622,7 +626,7 @@ void enkf_linalg_get_PC( const matrix_type * S0,
matrix_dgemm( PC , U0 , S , true , false , 1.0 , 0.0 );
}
/* The observer projections. */
{
matrix_scale( S_mean , -1.0);
@@ -633,7 +637,7 @@ void enkf_linalg_get_PC( const matrix_type * S0,
for (int i=0; i < double_vector_size( singular_values ); i++)
inv_sig0[i] = 1.0 / inv_sig0[i];
matrix_free( S_mean );
}
matrix_free( S );
@@ -649,7 +653,7 @@ void enkf_linalg_rml_enkfX1(matrix_type *X1, matrix_type *Udr, matrix_type *D, m
here the negative sign cancels with one needed in X3 matrix computation
*/
matrix_type * tmp = matrix_alloc(matrix_get_columns(Udr),matrix_get_rows(R));
matrix_matmul_with_transpose( tmp, Udr, R, true, false);
matrix_matmul( X1 , tmp, D);
@@ -661,23 +665,23 @@ void enkf_linalg_rml_enkfX1(matrix_type *X1, matrix_type *Udr, matrix_type *D, m
void enkf_linalg_rml_enkfX2(matrix_type *X2 , double *Wdr , matrix_type * X1 , double a , int nsign)
{
/*
This routine computes X2 for RML_EnKF module as X2 = ((a*Ipd)+Wd^2)^-1 * X1
This routine computes X2 for RML_EnKF module as X2 = ((a*Ipd)+Wd^2)^-1 * X1
Since a+Ipd & Wd are diagonal in nature the computation is reduced to array operations
*/
for (int i=0; i< nsign ; i++) {
double scale_factor = 1 / (a + (Wdr[i]*Wdr[i]));
matrix_scale_row(X1 , i , scale_factor);
}
matrix_assign(X2,X1);
}
void enkf_linalg_rml_enkfX3(matrix_type *X3, matrix_type *VdTr, double *Wdr, matrix_type *X2, int nsign)
{
/*
This routine computes X3 for RML_EnKF module as X3 = Vd *Wd*X2
This routine computes X3 for RML_EnKF module as X3 = Vd *Wd*X2
*/
printf("\nWd: ");
@@ -701,9 +705,9 @@ double enkf_linalg_data_mismatch(matrix_type *D , matrix_type *R , matrix_type *
double mismatch;
matrix_matmul_with_transpose(tmp, D, R,true, false); // tmp = D' * R, i.e. N-by-p
matrix_matmul(Sk, tmp, D); // Sk = D' * R * D
// Calculate the mismatch
// Calculate the mismatch
mismatch = matrix_trace(Sk)/(matrix_get_columns(D));
return mismatch;
}
@@ -718,7 +722,7 @@ void enkf_linalg_Covariance(matrix_type *Cd, const matrix_type *E, double nsc ,i
}
}
nsc = nsc*nsc;
matrix_scale(Cd,nsc);
matrix_scale(Cd,nsc);
}
@@ -746,7 +750,7 @@ void enkf_linalg_rml_enkfX7(matrix_type * X7, matrix_type * VdT, double * Wdr, d
double scale_factor = 1 / ( a + (Wdr[i]*Wdr[i]));
matrix_scale_row( tmp1 , i , scale_factor);
}
matrix_matmul_with_transpose(tmp2, tmp1, VdT, true, false);
matrix_matmul(X7, tmp2, X6);
+1 -1
View File
@@ -24,7 +24,7 @@
int main(void) {
const char * config_file = "config_test_input";
config_type * config = config_alloc();
config_parser_type * config = config_alloc();
config_schema_item_type * item;
item = config_add_schema_item(config , "KEY1" , true , true);
@@ -1,118 +0,0 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'config.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __CONFIG_H__
#define __CONFIG_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <ert/util/stringlist.h>
#include <ert/util/subst_list.h>
#include <ert/util/hash.h>
#include <ert/config/config_schema_item.h>
#include <ert/config/config_content_item.h>
#include <ert/config/config_content_node.h>
#define ECL_COM_KW "--"
#define ENKF_COM_KW "--"
typedef struct config_struct config_type;
char ** config_alloc_active_list(const config_type *, int *);
void config_free(config_type *);
config_type * config_alloc( );
char ** config_alloc_active_list(const config_type * , int * );
bool config_parse(config_type * , const char * , const char * , const char * , const char * , config_schema_unrecognized_enum unrecognized_behaviour , bool );
bool config_has_schema_item(const config_type * config , const char * kw);
void config_clear(config_type * config);
/*****************************************************************/
config_schema_item_type * config_get_schema_item(const config_type *, const char *);
bool config_item_set(const config_type * , const char * );
void config_add_alias(config_type * , const char * , const char * );
void config_install_message(config_type * , const char * , const char * );
const char * config_safe_get(const config_type * , const char *);
char * config_alloc_joined_string(const config_type * , const char * , const char * );
void config_add_define( config_type * config , const char * key , const char * value );
/*
bool config_schema_item_is_set(const config_schema_item_type * );
void config_schema_item_set_argc_minmax(config_schema_item_type * , int , int , int type_map_size , const config_item_types * );
void config_schema_item_set_common_selection_set(config_schema_item_type * , int argc , const char ** argv);
void config_schema_item_set_indexed_selection_set(config_schema_item_type * item , int , int , const char ** );
void config_schema_item_set_required_children(config_schema_item_type * , stringlist_type * );
void config_schema_item_set_required_children_on_value(config_schema_item_type * , const char * , stringlist_type * );
void config_schema_item_add_required_children(config_schema_item_type * item , const char * child_key);
*/
config_schema_item_type * config_add_schema_item(config_type * config,
const char * kw,
bool required);
const char * config_safe_iget(const config_type * config , const char *kw, int occurence , int index);
const char * config_iget(const config_type * , const char * , int occurence , int index);
bool config_iget_as_bool(const config_type * , const char * , int occurence , int index);
double config_iget_as_double(const config_type * , const char * , int occurence , int index);
int config_iget_as_int(const config_type * , const char *, int occurence , int index);
stringlist_type * config_alloc_complete_stringlist(const config_type* , const char * );
stringlist_type * config_alloc_stringlist(const config_type * config , const char * );
hash_type * config_alloc_hash(const config_type * , const char * );
const stringlist_type * config_iget_stringlist_ref(const config_type * , const char * , int );
int config_get_occurences(const config_type * , const char * );
int config_get_occurence_size( const config_type * config , const char * kw , int occurence);
bool config_has_content_item( const config_type * config , const char * input_kw);
config_content_item_type * config_get_content_item( const config_type * config , const char * input_kw);
config_schema_item_type * config_add_key_value( config_type * config , const char * key , bool required , config_item_types item_type);
bool config_get_value_as_bool(const config_type * config , const char * kw);
int config_get_value_as_int(const config_type * config , const char * kw);
double config_get_value_as_double(const config_type * config , const char * kw);
const char * config_get_value_as_abspath( const config_type * config , const char * kw);
const char * config_get_value_as_relpath( const config_type * config , const char * kw);
const char * config_get_value_as_path( const config_type * config , const char * kw);
const char * config_get_value(const config_type * config , const char * kw);
const char * config_get_config_file( const config_type * config , bool abs_path);
void config_fprintf_errors( const config_type * config , bool add_count , FILE * stream );
const subst_list_type * config_get_define_list( const config_type * config);
int config_get_schema_size( const config_type * config );
int config_get_content_size( const config_type * config );
const config_content_node_type * config_iget_content_node( const config_type * config , int index );
config_content_node_type * config_get_value_node( const config_type * config , const char * kw);
config_error_type * config_get_errors( const config_type * config );
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,84 @@
/*
Copyright (C) 2015 Statoil ASA, Norway.
The file 'config_content.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __CONFIG_CONTENT_H__
#define __CONFIG_CONTENT_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <ert/util/type_macros.h>
#include <ert/util/stringlist.h>
#include <ert/util/subst_list.h>
#include <ert/config/config_content_item.h>
#include <ert/config/config_schema_item.h>
#include <ert/config/config_error.h>
#include <ert/config/config_root_path.h>
typedef struct config_content_struct config_content_type;
config_content_type * config_content_alloc();
void config_content_free( config_content_type * content );
void config_content_set_valid( config_content_type * content);
bool config_content_is_valid( const config_content_type * content );
bool config_content_has_item( const config_content_type * content , const char * key);
void config_content_add_item( config_content_type * content , const config_schema_item_type * schema_item , const config_path_elm_type * path_elm);
config_content_item_type * config_content_get_item( const config_content_type * content , const char * key);
void config_content_add_node( config_content_type * content , config_content_node_type * content_node );
config_error_type * config_content_get_errors( const config_content_type * content);
const char * config_content_iget( const config_content_type * content , const char * key , int occurence , int index);
int config_content_iget_as_int( const config_content_type * content , const char * key , int occurence , int index);
bool config_content_iget_as_bool( const config_content_type * content , const char * key , int occurence , int index);
double config_content_iget_as_double( const config_content_type * content , const char * key , int occurence , int index);
const char * config_content_safe_iget(const config_content_type * content , const char *kw, int occurence , int index);
int config_content_get_occurences(const config_content_type * content, const char * kw);
bool config_content_get_value_as_bool(const config_content_type * config , const char * kw);
int config_content_get_value_as_int(const config_content_type * config , const char * kw);
double config_content_get_value_as_double(const config_content_type * config , const char * kw);
const char * config_content_get_value_as_path( const config_content_type * config , const char * kw);
const char * config_content_get_value_as_abspath( const config_content_type * config , const char * kw);
const char * config_content_get_value_as_relpath( const config_content_type * config , const char * kw);
const char * config_content_get_value(const config_content_type * config , const char * kw);
char * config_content_alloc_joined_string(const config_content_type * content , const char * kw, const char * sep);
stringlist_type * config_content_alloc_complete_stringlist(const config_content_type * content , const char * kw);
const stringlist_type * config_content_iget_stringlist_ref(const config_content_type * content , const char * kw, int occurence);
config_content_node_type * config_content_get_value_node( const config_content_type * content , const char * kw);
void config_content_add_define( config_content_type * content , const char * key , const char * value );
subst_list_type * config_content_get_define_list( config_content_type * content );
const char * config_content_get_config_file( const config_content_type * content , bool abs_path );
void config_content_set_config_file( config_content_type * content , const char * config_file );
int config_content_get_size(const config_content_type * content);
const config_content_node_type * config_content_iget_node( const config_content_type * content , int index);
bool config_content_add_file( config_content_type * content , const char * config_file);
config_root_path_type * config_content_get_invoke_path( config_content_type * content );
void config_content_set_invoke_path( config_content_type * content);
config_path_elm_type * config_content_add_path_elm( config_content_type * content , const char * path );
void config_content_pop_path_stack( config_content_type * content );
UTIL_IS_INSTANCE_HEADER( config_content );
#ifdef __cplusplus
}
#endif
#endif
@@ -1,19 +1,19 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_content_item.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_content_item.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
@@ -26,6 +26,7 @@ extern "C" {
#include <ert/util/hash.h>
#include <ert/util/stringlist.h>
#include <ert/util/type_macros.h>
#include <ert/config/config_error.h>
#include <ert/config/config_schema_item.h>
@@ -59,6 +60,8 @@ typedef struct config_content_item_struct config_content_item_type;
const config_schema_item_type * config_content_item_get_schema( const config_content_item_type * item );
const config_path_elm_type * config_content_item_get_path_elm( const config_content_item_type * item );
UTIL_IS_INSTANCE_HEADER( config_content_item );
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,104 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'config.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __CONFIG_H__
#define __CONFIG_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <ert/util/stringlist.h>
#include <ert/util/subst_list.h>
#include <ert/util/hash.h>
#include <ert/config/config_schema_item.h>
#include <ert/config/config_content_item.h>
#include <ert/config/config_content_node.h>
#include <ert/config/config_content.h>
#define ECL_COM_KW "--"
#define ENKF_COM_KW "--"
typedef struct config_parser_struct config_parser_type;
void config_free(config_parser_type *);
config_parser_type * config_alloc( );
char ** config_alloc_active_list(const config_parser_type * , int * );
config_content_type * config_parse(config_parser_type * , const char * , const char * , const char * , const char * , config_schema_unrecognized_enum unrecognized_behaviour , bool );
bool config_has_schema_item(const config_parser_type * config , const char * kw);
/*****************************************************************/
config_schema_item_type * config_get_schema_item(const config_parser_type *, const char *);
bool config_item_set(const config_parser_type * , const char * );
void config_add_alias(config_parser_type * , const char * , const char * );
void config_install_message(config_parser_type * , const char * , const char * );
const char * config_safe_get(const config_parser_type * , const char *);
char * config_alloc_joined_string(const config_parser_type * , const char * , const char * );
void config_add_define( config_parser_type * config , const char * key , const char * value );
/*
bool config_schema_item_is_set(const config_schema_item_type * );
void config_schema_item_set_argc_minmax(config_schema_item_type * , int , int , int type_map_size , const config_item_types * );
void config_schema_item_set_common_selection_set(config_schema_item_type * , int argc , const char ** argv);
void config_schema_item_set_indexed_selection_set(config_schema_item_type * item , int , int , const char ** );
void config_schema_item_set_required_children(config_schema_item_type * , stringlist_type * );
void config_schema_item_set_required_children_on_value(config_schema_item_type * , const char * , stringlist_type * );
void config_schema_item_add_required_children(config_schema_item_type * item , const char * child_key);
*/
config_schema_item_type * config_add_schema_item(config_parser_type * config,
const char * kw,
bool required);
stringlist_type * config_alloc_complete_stringlist(const config_parser_type * , const char * );
stringlist_type * config_alloc_stringlist(const config_parser_type * config , const char * );
hash_type * config_alloc_hash(const config_parser_type * , const char * );
const stringlist_type * config_iget_stringlist_ref(const config_parser_type * , const char * , int );
int config_get_occurences(const config_parser_type * , const char * );
int config_get_occurence_size( const config_parser_type * config , const char * kw , int occurence);
bool config_has_content_item( const config_parser_type * config , const char * input_kw);
config_content_item_type * config_get_content_item( const config_parser_type * config , const char * input_kw);
config_schema_item_type * config_add_key_value( config_parser_type * config , const char * key , bool required , config_item_types item_type);
;
const char * config_get_value_as_relpath( const config_parser_type * config , const char * kw);
const char * config_get_value_as_path( const config_parser_type * config , const char * kw);
const char * config_get_value(const config_parser_type * config , const char * kw);
const subst_list_type * config_get_define_list( const config_parser_type * config);
int config_get_schema_size( const config_parser_type * config );
config_content_node_type * config_get_value_node( const config_parser_type * config , const char * kw);
#ifdef __cplusplus
}
#endif
#endif
@@ -1,19 +1,19 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_schema_item.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_schema_item.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
@@ -29,12 +29,12 @@ extern "C" {
#include <ert/config/config_error.h>
#include <ert/config/config_path_elm.h>
/**
/**
Types used for validation of config items.
*/
typedef enum {CONFIG_STRING = 1,
CONFIG_INT = 2,
CONFIG_FLOAT = 4,
CONFIG_FLOAT = 4,
CONFIG_PATH = 8,
CONFIG_EXISTING_PATH = 16,
CONFIG_BOOL = 32,
@@ -42,7 +42,7 @@ typedef enum {CONFIG_STRING = 1,
CONFIG_BYTESIZE = 128,
CONFIG_EXECUTABLE = 256 ,
CONFIG_INVALID = 512 } config_item_types;
#define CONFIG_ITEM_TYPE_ENUM_DEFS \
{.value = 1 , .name="CONFIG_STRING"}, \
{.value = 2 , .name="CONFIG_INT"}, \
@@ -53,10 +53,10 @@ typedef enum {CONFIG_STRING = 1,
{.value = 64 , .name="CONFIG_CONFIG"}, \
{.value = 128 , .name="CONFIG_BYTESIZE"}, \
{.value = 256 , .name="CONFIG_EXECUTABLE"}, \
{.value = 512 , .name="CONFIG_INVALID"}
{.value = 512 , .name="CONFIG_INVALID"}
#define CONFIG_ITEM_TYPE_ENUM_SIZE 10
typedef enum {
CONFIG_UNRECOGNIZED_IGNORE = 0,
CONFIG_UNRECOGNIZED_WARN = 1,
@@ -79,13 +79,13 @@ typedef enum {CONFIG_STRING = 1,
typedef struct config_schema_item_struct config_schema_item_type;
config_schema_item_type * config_schema_item_alloc(const char * kw , bool required);
bool config_schema_item_validate_set(const config_schema_item_type * item ,
stringlist_type * token_list ,
const char * config_file,
const config_path_elm_type * path_elm,
bool config_schema_item_validate_set(const config_schema_item_type * item ,
stringlist_type * token_list ,
const char * config_file,
const config_path_elm_type * path_elm,
config_error_type * error_list);
void config_schema_item_free( config_schema_item_type * item);
@@ -97,13 +97,13 @@ typedef enum {CONFIG_STRING = 1,
void config_schema_item_set_required_children(config_schema_item_type * item , stringlist_type * stringlist);
void config_schema_item_add_required_children(config_schema_item_type * item , const char * child_key);
void config_schema_item_set_envvar_expansion( config_schema_item_type * item , bool expand_envvar );
void config_schema_item_set_argc_minmax(config_schema_item_type * item ,
int argc_min ,
void config_schema_item_set_argc_minmax(config_schema_item_type * item ,
int argc_min ,
int argc_max);
void config_schema_item_assure_type(const config_schema_item_type * item , int index , int type_mask);
int config_schema_item_num_required_children(const config_schema_item_type * item);
const char * config_schema_item_iget_required_child( const config_schema_item_type * item , int index);
const char * config_schema_item_iget_required_child( const config_schema_item_type * item , int index);
const char * config_schema_item_get_kw( const config_schema_item_type * item );
bool config_schema_item_required( const config_schema_item_type * item );
bool config_schema_item_expand_envvar( const config_schema_item_type * item );
+2 -2
View File
@@ -1,5 +1,5 @@
set( source_files config.c config_error.c config_schema_item.c config_content_item.c config_content_node.c config_root_path.c config_path_elm.c conf.c conf_util.c conf_data.c)
set( header_files config.h config_error.h config_schema_item.h config_content_item.h config_content_node.h config_root_path.h config_path_elm.h conf.h conf_data.h)
set( source_files config_parser.c config_content.c config_error.c config_schema_item.c config_content_item.c config_content_node.c config_root_path.c config_path_elm.c conf.c conf_util.c conf_data.c)
set( header_files config_parser.h config_content.h config_error.h config_schema_item.h config_content_item.h config_content_node.h config_root_path.h config_path_elm.h conf.h conf_data.h)
add_library( config ${LIBRARY_TYPE} ${source_files} )
set_target_properties( config PROPERTIES VERSION 1.0 SOVERSION 1.0 )
+1 -1
View File
@@ -44,7 +44,7 @@ char * __conf_util_fscanf_alloc_token_buffer(
int num_pad_keys,
const char ** pad_keys)
{
char * buffer_wrk = parser_fread_alloc_file_content( file , NULL /* quote_set */ , NULL /* delete_set */ , "--" /* Comment start*/ , "\n" /* Comment end */);
char * buffer_wrk = basic_parser_fread_alloc_file_content( file , NULL /* quote_set */ , NULL /* delete_set */ , "--" /* Comment start*/ , "\n" /* Comment end */);
char ** padded_keys = util_calloc(num_pad_keys , sizeof * padded_keys);
for(int key_nr = 0; key_nr < num_pad_keys; key_nr++)
{
File diff suppressed because it is too large Load Diff
+409
View File
@@ -0,0 +1,409 @@
/*
Copyright (C) 2015 Statoil ASA, Norway.
The file 'config_content.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <ert/util/type_macros.h>
#include <ert/util/hash.h>
#include <ert/util/set.h>
#include <ert/util/vector.h>
#include <ert/util/subst_list.h>
#include <ert/config/config_root_path.h>
#include <ert/config/config_path_elm.h>
#include <ert/config/config_content.h>
#include <ert/config/config_content_item.h>
#include <ert/config/config_schema_item.h>
#include <ert/config/config_error.h>
#define CONFIG_CONTENT_TYPE_ID 6612520
struct config_content_struct {
UTIL_TYPE_ID_DECLARATION;
set_type * parsed_files; /* A set of config files whcih have been parsed - to protect against circular includes. */
vector_type * nodes;
hash_type * items;
config_error_type * parse_errors;
subst_list_type * define_list;
char * config_file;
char * abs_path;
config_root_path_type * invoke_path;
vector_type * path_elm_storage;
vector_type * path_elm_stack;
bool valid;
};
UTIL_IS_INSTANCE_FUNCTION( config_content , CONFIG_CONTENT_TYPE_ID )
config_content_type * config_content_alloc() {
config_content_type * content = util_malloc( sizeof * content );
UTIL_TYPE_ID_INIT( content , CONFIG_CONTENT_TYPE_ID );
content->valid = false;
content->items = hash_alloc();
content->nodes = vector_alloc_new();
content->parse_errors = config_error_alloc();
content->define_list = subst_list_alloc( NULL );
content->parsed_files = set_alloc_empty();
content->path_elm_storage = vector_alloc_new();
content->path_elm_stack = vector_alloc_new();
content->invoke_path = NULL;
content->config_file = NULL;
content->abs_path = NULL;
return content;
}
bool config_content_has_item( const config_content_type * content , const char * key) {
return hash_has_key( content->items , key );
}
config_content_item_type * config_content_get_item( const config_content_type * content , const char * key) {
return hash_get( content->items , key );
}
void config_content_add_item( config_content_type * content , const config_schema_item_type * schema_item , const config_path_elm_type * path_elm) {
const char * kw = config_schema_item_get_kw( schema_item );
config_content_item_type * content_item = config_content_item_alloc( schema_item , path_elm );
hash_insert_hash_owned_ref( content->items , kw , content_item , config_content_item_free__ );
}
void config_content_add_node( config_content_type * content , config_content_node_type * content_node ) {
vector_append_ref( content->nodes , content_node );
}
void config_content_set_valid( config_content_type * content) {
content->valid = true;
}
bool config_content_is_valid( const config_content_type * content ) {
return content->valid;
}
config_error_type * config_content_get_errors( const config_content_type * content) {
return content->parse_errors;
}
void config_content_free( config_content_type * content ) {
vector_free( content->nodes );
hash_free( content->items );
config_error_free( content->parse_errors );
subst_list_free( content->define_list );
util_safe_free( content->config_file );
util_safe_free( content->abs_path );
set_free( content->parsed_files );
if (content->invoke_path != NULL)
config_root_path_free( content->invoke_path );
free( content );
}
bool config_content_add_file( config_content_type * content , const char * config_file) {
return set_add_key( content->parsed_files , config_file);
}
config_root_path_type * config_content_get_invoke_path( config_content_type * content ) {
return content->invoke_path;
}
void config_content_set_invoke_path( config_content_type * content) {
if (content->invoke_path != NULL)
config_root_path_free( content->invoke_path );
content->invoke_path = config_root_path_alloc( NULL );
}
/*****************************************************************/
/*
Here comes some xxx_get() functions - many of them will fail if
the item has not been added in the right way (this is to ensure that
the xxx_get() request is unambigous.
*/
/**
This function can be used to get the value of a config
parameter. But to ensure that the get is unambigous we set the
following requirements to the item corresponding to 'kw':
* argc_minmax has been set to 1,1
If this is not the case - we die.
*/
/**
Assume we installed a key 'KEY' which occurs three times in the final
config file:
KEY 1 2 3
KEY 11 22 33
KEY 111 222 333
Now when accessing these values the occurence variable will
correspond to the linenumber, and the index will index along a line:
config_iget_as_int( config , "KEY" , 0 , 2) => 3
config_iget_as_int( config , "KEY" , 2 , 1) => 222
*/
const char * config_content_iget( const config_content_type * content , const char * key , int occurence , int index) {
config_content_item_type * item = config_content_get_item(content , key);
return config_content_item_iget(item , occurence , index);
}
int config_content_iget_as_int( const config_content_type * content , const char * key , int occurence , int index) {
config_content_item_type * item = config_content_get_item(content , key);
return config_content_item_iget_as_int(item , occurence , index);
}
bool config_content_iget_as_bool( const config_content_type * content , const char * key , int occurence , int index) {
config_content_item_type * item = config_content_get_item(content , key);
return config_content_item_iget_as_bool(item , occurence , index);
}
double config_content_iget_as_double( const config_content_type * content , const char * key , int occurence , int index) {
config_content_item_type * item = config_content_get_item(content , key);
return config_content_item_iget_as_double(item , occurence , index);
}
/**
This function will return NULL is the item has not been set,
however it must be installed with config_add_schema_item().
*/
const char * config_content_safe_iget(const config_content_type * content , const char *kw, int occurence , int index) {
const char * value = NULL;
if (config_content_has_item( content , kw )) {
config_content_item_type * item = config_content_get_item(content , kw);
if (occurence < config_content_item_get_size( item )) {
config_content_node_type * node = config_content_item_iget_node( item , occurence );
value = config_content_node_safe_iget( node , index );
}
}
return value;
}
/**
Return the number of times a keyword has been set - dies on unknown
'kw'. If the append_arg attribute has been set to false the
function will return 0 or 1 irrespective of how many times the item
has been set in the config file.
*/
int config_content_get_occurences(const config_content_type * content, const char * kw) {
if (config_content_has_item( content , kw ))
return config_content_item_get_size( config_content_get_item(content , kw) );
else
return 0;
}
const config_content_node_type * config_content_iget_node( const config_content_type * content , int index) {
const config_content_node_type * node = vector_iget_const(content->nodes , index );
return node;
}
int config_content_get_size(const config_content_type * content) {
return vector_get_size( content->nodes );
}
/*****************************************************************/
/* All the get_value functions will operate on the last item which has
been set with a particular key value. So assuming the config file
looks like:
KEY VALUE1
KEY VALUE2 OPTIONAL
KEY 100 VALUE3 OPTIONAL ERROR
these functions will all operate on the last line in the config file:
KEY 100 VALUE3 OPTIONAL ERROR
*/
static config_content_node_type * config_content_get_value_node__( const config_content_type * config , const char * kw) {
config_content_node_type * node = config_content_get_value_node( config , kw );
if (node == NULL)
util_abort("Tried to get value node from unset kw:%s \n",__func__ , kw );
return node;
}
config_content_node_type * config_content_get_value_node( const config_content_type * content , const char * kw) {
config_content_item_type * item = config_content_get_item(content , kw);
config_content_node_type * node = config_content_item_get_last_node( item );
config_content_node_assert_key_value( node );
return node;
}
bool config_content_get_value_as_bool(const config_content_type * config , const char * kw) {
config_content_node_type * node = config_content_get_value_node__( config , kw );
return config_content_node_iget_as_bool(node , 0);
}
int config_content_get_value_as_int(const config_content_type * config , const char * kw) {
config_content_node_type * node = config_content_get_value_node__( config , kw );
return config_content_node_iget_as_int(node , 0);
}
double config_content_get_value_as_double(const config_content_type * config , const char * kw) {
config_content_node_type * node = config_content_get_value_node__( config , kw );
return config_content_node_iget_as_double(node , 0);
}
const char * config_content_get_value_as_path( const config_content_type * config , const char * kw) {
config_content_node_type * node = config_content_get_value_node__( config , kw );
return config_content_node_iget_as_path(node , 0);
}
const char * config_content_get_value_as_abspath( const config_content_type * config , const char * kw) {
config_content_node_type * node = config_content_get_value_node__( config , kw );
return config_content_node_iget_as_abspath(node , 0);
}
const char * config_content_get_value_as_relpath( const config_content_type * config , const char * kw) {
config_content_node_type * node = config_content_get_value_node__( config , kw );
return config_content_node_iget_as_relpath(node , 0);
}
const char * config_content_get_value(const config_content_type * config , const char * kw) {
config_content_node_type * node = config_content_get_value_node__( config , kw );
return config_content_node_iget(node , 0);
}
/*****************************************************************/
char * config_content_alloc_joined_string(const config_content_type * content , const char * kw, const char * sep) {
config_content_item_type * item = config_content_get_item(content , kw);
return config_content_item_alloc_joined_string(item , sep);
}
/**
This function allocates a new stringlist containing *ALL* the
arguements for an item. With reference to the illustrated example at
the top the function call:
config_alloc_complete_strtinglist(config , "KEY1");
would produce the list: ("ARG1" "ARG2" "ARG2" "VERBOSE"), i.e. the
arguments for the various occurences of "KEY1" are collapsed to one
stringlist.
*/
stringlist_type * config_content_alloc_complete_stringlist(const config_content_type * content , const char * kw) {
bool copy = true;
config_content_item_type * item = config_content_get_item(content , kw);
return config_content_item_alloc_complete_stringlist(item , copy);
}
const stringlist_type * config_content_iget_stringlist_ref(const config_content_type * content , const char * kw, int occurence) {
config_content_item_type * item = config_content_get_item(content , kw);
return config_content_item_iget_stringlist_ref(item , occurence);
}
void config_content_add_define( config_content_type * content , const char * key , const char * value ) {
subst_list_append_copy( content->define_list , key , value , NULL );
}
subst_list_type * config_content_get_define_list( config_content_type * content ) {
return content->define_list;
}
/*****************************************************************/
void config_content_set_config_file( config_content_type * content , const char * config_file ) {
content->config_file = util_realloc_string_copy( content->config_file , config_file );
util_safe_free(content->abs_path);
content->abs_path = util_alloc_abs_path( config_file );
}
const char * config_content_get_config_file( const config_content_type * content , bool abs_path ) {
if (abs_path)
return content->abs_path;
else
return content->config_file;
}
config_path_elm_type * config_content_add_path_elm( config_content_type * content , const char * path ) {
const config_path_elm_type * current_path_elm;
if (vector_get_size( content->path_elm_stack ) == 0)
current_path_elm = NULL;
else
current_path_elm = vector_get_last_const(content->path_elm_stack);
{
config_path_elm_type * new_path_elm;
{
char * rel_path = NULL;
config_root_path_type * invoke_path = config_content_get_invoke_path( content );
if (path != NULL) {
if (current_path_elm == NULL)
rel_path = util_alloc_rel_path( config_root_path_get_abs_path(invoke_path) , path);
else
rel_path = config_path_elm_alloc_relpath( current_path_elm , path );
}
new_path_elm = config_path_elm_alloc( invoke_path , rel_path );
util_safe_free( rel_path );
}
vector_append_owned_ref( content->path_elm_storage , new_path_elm , config_path_elm_free__);
vector_append_ref( content->path_elm_stack , new_path_elm );
return new_path_elm;
}
}
void config_content_pop_path_stack( config_content_type * content ) {
vector_pop_back( content->path_elm_stack );
}
+2 -2
View File
@@ -250,8 +250,8 @@ void config_content_item_free( config_content_item_type * item ) {
UTIL_SAFE_CAST_FUNCTION( config_content_item , CONFIG_CONTENT_ITEM_ID);
UTIL_SAFE_CAST_FUNCTION( config_content_item , CONFIG_CONTENT_ITEM_ID)
UTIL_IS_INSTANCE_FUNCTION( config_content_item , CONFIG_CONTENT_ITEM_ID)
void config_content_item_free__( void * arg ) {
@@ -111,6 +111,11 @@ const char * config_content_node_safe_iget(const config_content_node_type * node
}
config_item_types config_content_node_iget_type( const config_content_node_type * node , int index) {
return config_schema_item_iget_type( node->schema , index );
}
bool config_content_node_iget_as_bool(const config_content_node_type * node , int index) {
bool value;
config_schema_item_assure_type(node->schema , index , CONFIG_BOOL);
+18 -18
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_error.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_error.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdio.h>
@@ -54,7 +54,7 @@ void config_error_free( config_error_type * error ) {
void config_error_add( config_error_type * error , char * new_error) {
stringlist_append_owned_ref( error->error_list , new_error );
stringlist_append_copy( error->error_list , new_error );
}
@@ -78,9 +78,9 @@ void config_error_fprintf( const config_error_type * error , bool add_count , FI
int error_nr;
for (error_nr = 0; error_nr < stringlist_get_size( error->error_list ); error_nr++) {
if (add_count)
if (add_count)
fprintf(stream , " %02d: " , error_nr);
fprintf( stream , "%s\n" , stringlist_iget( error->error_list , error_nr));
}
}
+11 -22
View File
@@ -32,7 +32,7 @@
*/
config_content_node_type * config_get_value_node( const config_type * config , const char * kw) {
/*config_content_node_type * config_get_value_node( const config_parser_type * config , const char * kw) {
config_content_item_type * item = config_get_content_item(config , kw);
if (item != NULL) {
config_content_node_type * node = config_content_item_get_last_node( item );
@@ -42,7 +42,7 @@ config_content_node_type * config_get_value_node( const config_type * config , c
return NULL; // Will return NULL on unset keywords - must check NULL return value?!
}
static config_content_node_type * config_get_value_node__( const config_type * config , const char * kw) {
static config_content_node_type * config_get_value_node__( const config_parser_type * config , const char * kw) {
config_content_node_type * node = config_get_value_node( config , kw );
if (node == NULL)
util_abort("Tried to get value node from unset kw:%s \n",__func__ , kw );
@@ -50,65 +50,54 @@ static config_content_node_type * config_get_value_node__( const config_type * c
return node;
}
bool config_get_value_as_bool(const config_type * config , const char * kw) {
bool config_get_value_as_bool(const config_parser_type * config , const char * kw) {
config_content_node_type * node = config_get_value_node__( config , kw );
return config_content_node_iget_as_bool(node , 0);
}
int config_get_value_as_int(const config_type * config , const char * kw) {
int config_get_value_as_int(const config_parser_type * config , const char * kw) {
config_content_node_type * node = config_get_value_node__( config , kw );
return config_content_node_iget_as_int(node , 0);
}
double config_get_value_as_double(const config_type * config , const char * kw) {
double config_get_value_as_double(const config_parser_type * config , const char * kw) {
config_content_node_type * node = config_get_value_node__( config , kw );
return config_content_node_iget_as_double(node , 0);
}
const char * config_get_value_as_path( const config_type * config , const char * kw) {
const char * config_get_value_as_path( const config_parser_type * config , const char * kw) {
config_content_node_type * node = config_get_value_node__( config , kw );
return config_content_node_iget_as_path(node , 0);
}
const char * config_get_value_as_abspath( const config_type * config , const char * kw) {
const char * config_get_value_as_abspath( const config_parser_type * config , const char * kw) {
config_content_node_type * node = config_get_value_node__( config , kw );
return config_content_node_iget_as_abspath(node , 0);
}
const char * config_get_value_as_relpath( const config_type * config , const char * kw) {
const char * config_get_value_as_relpath( const config_parser_type * config , const char * kw) {
config_content_node_type * node = config_get_value_node__( config , kw );
return config_content_node_iget_as_relpath(node , 0);
}
const char * config_get_value(const config_type * config , const char * kw) {
const char * config_get_value(const config_parser_type * config , const char * kw) {
config_content_node_type * node = config_get_value_node__( config , kw );
return config_content_node_iget(node , 0);
}
*/
/*****************************************************************/
int config_get_content_size( const config_type * config ) {
return vector_get_size(config->content_list);
}
const config_content_node_type * config_iget_content_node( const config_type * config , int index) {
return vector_iget_const( config->content_list , index );
}
int config_get_schema_size( const config_type * config ) {
int config_get_schema_size( const config_parser_type * config ) {
return hash_get_size( config->schema_items );
}
config_error_type * config_get_errors( const config_type * config ) {
return config->parse_errors;
}
+697
View File
@@ -0,0 +1,697 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'config.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <ert/util/type_macros.h>
#include <ert/util/util.h>
#include <ert/util/parser.h>
#include <ert/util/hash.h>
#include <ert/util/stringlist.h>
#include <ert/util/subst_list.h>
#include <ert/util/vector.h>
#include <ert/util/path_stack.h>
#include <ert/config/config_parser.h>
#include <ert/config/config_error.h>
#include <ert/config/config_schema_item.h>
#include <ert/config/config_content_node.h>
#include <ert/config/config_content_item.h>
#include <ert/config/config_path_elm.h>
#include <ert/config/config_root_path.h>
#define CLEAR_STRING "__RESET__"
/**
Structure to parse configuration files of this type:
KEYWORD1 ARG2 ARG2 ARG3
KEYWORD2 ARG1-2
....
KEYWORDN ARG1 ARG2
A keyword can occure many times.
*/
/**
=============================
| config_type object |
| |
| Contains 'all' the |
| configuration information.|
| |
=============================
| |
| \________________________
| \
KEY1 KEY2
| |
\|/ \|/
========================= =========================
| config_item object | | config_item object |
| | | |
| Indexed by a keyword | | Indexed by a keyword |
| which is the first | | which is the first |
| string in the | | string in the |
| config file. | | config file. |
| | | |
========================= =========================
| | |
| | |
\|/ \|/ \|/
============================ ============================ ============================
| config_item_node object | | config_item_node object | | config_item_node object |
| | | | | |
| Only containing the | | Only containing the | | Only containing the |
| stringlist object | | stringlist object | | stringlist object |
| directly parsed from the | | directly parsed from the | | directly parsed from the |
| file. | | file. | | file. |
|--------------------------| |--------------------------| |--------------------------|
| ARG1 ARG2 ARG3 | | VERBOSE | | DEBUG |
============================ ============================ ============================
The example illustrated above would correspond to the following config
file (invariant under line-permutations):
KEY1 ARG1 ARG2 ARG3
KEY1 VERBOSE
KEY2 DEBUG
Example config file(2):
OUTFILE filename
INPUT filename
OPTIONS store
OPTIONS verbose
OPTIONS optimize cache=1
In this case the whole config object will contain three items,
corresponding to the keywords OUTFILE, INPUT and OPTIONS. The two
first will again only contain one node each, whereas the OPTIONS item
will contain three nodes, corresponding to the three times the keyword
"OPTIONS" appear in the config file.
*/
struct config_parser_struct {
hash_type * schema_items;
hash_type * messages; /* Can print a (warning) message when a keyword is encountered. */
};
/*
The last argument (config_file) is only used for printing
informative error messages, and can be NULL. The config_cwd is
essential if we are looking up a filename, otherwise it can be NULL.
Returns a string with an error description, or NULL if the supplied
arguments were OK. The string is allocated here, but is assumed that
calling scope will free it.
*/
static config_content_node_type * config_content_item_set_arg__(subst_list_type * define_list ,
config_error_type * parse_errors ,
config_content_item_type * item ,
stringlist_type * token_list ,
const config_path_elm_type * path_elm ,
const char * config_file ) {
config_content_node_type * new_node = NULL;
int argc = stringlist_get_size( token_list ) - 1;
if (argc == 1 && (strcmp(stringlist_iget(token_list , 1) , CLEAR_STRING) == 0)) {
config_content_item_clear(item);
} else {
const config_schema_item_type * schema_item = config_content_item_get_schema( item );
/* Filtering based on DEFINE statements */
if (subst_list_get_size( define_list ) > 0) {
int iarg;
for (iarg = 0; iarg < argc; iarg++) {
char * filtered_copy = subst_list_alloc_filtered_string( define_list , stringlist_iget(token_list , iarg + 1));
stringlist_iset_owned_ref( token_list , iarg + 1 , filtered_copy);
}
}
/* Filtering based on environment variables */
if (config_schema_item_expand_envvar( schema_item )) {
int iarg;
for (iarg = 0; iarg < argc; iarg++) {
int env_offset = 0;
char * env_var;
do {
env_var = util_isscanf_alloc_envvar( stringlist_iget(token_list , iarg + 1) , env_offset );
if (env_var != NULL) {
const char * env_value = getenv( &env_var[1] );
if (env_value != NULL) {
char * new_value = util_string_replace_alloc( stringlist_iget( token_list , iarg + 1 ) , env_var , env_value );
stringlist_iset_owned_ref( token_list , iarg + 1 , new_value );
} else {
env_offset += 1;
fprintf(stderr,"** Warning: environment variable: %s is not defined \n", env_var);
}
}
} while (env_var != NULL);
}
}
{
if (config_schema_item_validate_set(schema_item , token_list , config_file, path_elm , parse_errors)) {
new_node = config_content_item_alloc_node( item , config_content_item_get_path_elm( item ));
config_content_node_set(new_node , token_list);
}
}
}
return new_node;
}
/*****************************************************************/
config_parser_type * config_alloc() {
config_parser_type *config = util_malloc(sizeof * config );
config->schema_items = hash_alloc();
config->messages = hash_alloc();
return config;
}
void config_free(config_parser_type * config) {
hash_free(config->schema_items);
hash_free(config->messages);
free(config);
}
static void config_insert_schema_item(config_parser_type * config , const char * kw , const config_schema_item_type * item , bool ref) {
if (ref)
hash_insert_ref(config->schema_items , kw , item);
else
hash_insert_hash_owned_ref(config->schema_items , kw , item , config_schema_item_free__);
}
/**
This function allocates a simple item with all values
defaulted. The item is added to the config object, and a pointer is
returned to the calling scope. If you want to change the properties
of the item you can do that with config_schema_item_set_xxxx() functions
from the calling scope.
*/
config_schema_item_type * config_add_schema_item(config_parser_type * config ,
const char * kw,
bool required) {
config_schema_item_type * item = config_schema_item_alloc( kw , required );
config_insert_schema_item(config , kw , item , false);
return item;
}
/**
This is a minor wrapper for adding an item with the properties.
1. It has argc_minmax = {1,1}
The value can than be extracted with config_get_value() and
config_get_value_as_xxxx functions.
*/
config_schema_item_type * config_add_key_value( config_parser_type * config , const char * key , bool required , config_item_types item_type) {
config_schema_item_type * item = config_add_schema_item( config , key , required );
config_schema_item_set_argc_minmax( item , 1 , 1 );
config_schema_item_iset_type( item , 0 , item_type );
return item;
}
bool config_has_schema_item(const config_parser_type * config , const char * kw) {
return hash_has_key(config->schema_items , kw);
}
config_schema_item_type * config_get_schema_item(const config_parser_type * config , const char * kw) {
return hash_get(config->schema_items , kw);
}
/*
Due to the possibility of aliases we must go through the canonical
keyword which is internalized in the schema_item.
*/
static void config_validate_content_item(const config_parser_type * config , config_content_type * content , const config_content_item_type * item) {
const config_schema_item_type * schema_item = config_content_item_get_schema( item );
const char * schema_kw = config_schema_item_get_kw( schema_item );
{
int i;
for (i = 0; i < config_schema_item_num_required_children(schema_item); i++) {
const char * required_child = config_schema_item_iget_required_child( schema_item , i );
if (!config_content_has_item(content , required_child)) {
char * error_message = util_alloc_sprintf("When:%s is set - you also must set:%s.",schema_kw , required_child);
config_error_add( config_content_get_errors( content ) , error_message );
free( error_message );
}
}
if (config_schema_item_has_required_children_value( schema_item )) {
int inode;
for (inode = 0; inode < config_content_item_get_size(item); inode++) {
config_content_node_type * node = config_content_item_iget_node(item , inode);
const stringlist_type * values = config_content_node_get_stringlist( node );
int is;
for (is = 0; is < stringlist_get_size(values); is++) {
const char * value = stringlist_iget(values , is);
stringlist_type * required_children = config_schema_item_get_required_children_value( schema_item , value );
if (required_children != NULL) {
int ic;
for (ic = 0; ic < stringlist_get_size( required_children ); ic++) {
const char * req_child = stringlist_iget( required_children , ic );
if (!config_content_has_item(content , req_child )) {
char * error_message = util_alloc_sprintf("When:%s is set to:%s - you also must set:%s.",schema_kw , value , req_child );
config_error_add( config_content_get_errors( content ) , error_message );
free( error_message );
}
}
}
}
}
}
}
}
static void config_validate(config_parser_type * config, config_content_type * content , const char * filename) {
int size = hash_get_size(config->schema_items);
char ** key_list = hash_alloc_keylist(config->schema_items);
int ikey;
for (ikey = 0; ikey < size; ikey++) {
const config_schema_item_type * schema_item = config_get_schema_item( config , key_list[ikey]);
const char * content_key = config_schema_item_get_kw( schema_item );
if (config_content_has_item( content , content_key)) {
const config_content_item_type * item = config_content_get_item(content , content_key);
config_validate_content_item(config , content , item );
} else {
if (config_schema_item_required( schema_item)) { /* The item is not set ... */
char * error_message = util_alloc_sprintf("Item:%s must be set - parsing:%s",content_key , config_content_get_config_file( content , true ));
config_error_add( config_content_get_errors( content ) , error_message );
free( error_message );
}
}
}
util_free_stringlist(key_list , size);
}
/**
This function parses the config file 'filename', and updated the
internal state of the config object as parsing proceeds. If
comment_string != NULL everything following 'comment_string' on a
line is discarded.
include_kw is a string identifier for an include functionality, if
an include is encountered, the included file is parsed immediately
(through a recursive call to config_parse__). if include_kw == NULL,
include files are not supported.
Observe that use of include, relative paths and all that shit is
quite tricky. The following is currently implemented:
1. The front_end function will split the path to the config file
in a path_name component and a file component.
2. Recursive calls to config_parse__() will keep control of the
parsers notion of cwd (note that the real OS'wise cwd never
changes), and every item is tagged with the config_cwd
currently active.
3. When an item has been entered with type CONFIG_FILE /
CONFIG_DIRECTORY / CONFIG_EXECUTABLE - the item is updated to
reflect to be relative (iff it is relative in the first place)
to the path of the root config file.
These are not strict rules - it is possible to get other things to
work as well, but the problem is that it very quickly becomes
dependant on 'arbitrariness' in the parsing configuration.
validate: whether we should validate when complete, that should
typically only be done at the last parsing.
define_kw: This a string which can serve as a "#define" for the
parsing. The define_kw keyword should have two arguments - a key
and a value. If the define_kw is present all __subsequent__
occurences of 'key' are replaced with 'value'. alloc_new_key
is an optinal function (can be NULL) which is used to alloc a new
key, i.e. add leading and trailing 'magic' characters.
Example:
--------
char * add_angular_brackets(const char * key) {
char * new_key = util_alloc_sprintf("<%s>" , key);
}
config_parse(... , "myDEF" , add_angular_brackets , ...)
Config file:
-------------
myDEF Name BJARNE
myDEF sexual-pref Dogs
...
...
PERSON <Name> 28 <sexual-pref>
...
------------
After parsing we will have an entry: "NAME" , "Bjarne" , "28" , "Dogs".
The key-value pairs internalized during the config parsing are NOT
returned to the calling scope in any way.
*/
static void config_parse__(config_parser_type * config ,
config_content_type * content ,
path_stack_type * path_stack ,
const char * config_input ,
const char * comment_string ,
const char * include_kw ,
const char * define_kw ,
config_schema_unrecognized_enum unrecognized,
bool validate) {
/* Guard against circular includes. */
{
char * abs_filename = util_alloc_realpath(config_input);
if (!config_content_add_file( content , abs_filename ))
util_exit("%s: file:%s already parsed - circular include ? \n",__func__ , abs_filename);
free( abs_filename );
}
config_path_elm_type * current_path_elm;
char * config_file;
{
/* Extract the path component of the current input file and chdir() */
char * config_path;
{
char * config_base;
char * config_ext;
util_alloc_file_components( config_input , &config_path , &config_base , &config_ext);
config_file = util_alloc_filename( NULL , config_base , config_ext );
free( config_base );
util_safe_free( config_ext );
}
current_path_elm = config_content_add_path_elm( content , config_path );
path_stack_push_cwd( path_stack );
if (config_path != NULL) {
util_chdir( config_path );
free( config_path );
}
}
{
basic_parser_type * parser = basic_parser_alloc(" \t" , "\"", NULL , NULL , "--" , "\n");
FILE * stream = util_fopen(config_file , "r");
bool at_eof = false;
while (!at_eof) {
int active_tokens;
stringlist_type * token_list;
char *line_buffer;
line_buffer = util_fscanf_alloc_line(stream , &at_eof);
if (line_buffer != NULL) {
token_list = basic_parser_tokenize_buffer(parser , line_buffer , true);
active_tokens = stringlist_get_size( token_list );
/*
util_split_string(line_buffer , " \t" , &tokens , &token_list);
active_tokens = tokens;
for (i = 0; i < tokens; i++) {
char * comment_ptr = NULL;
if(comment_string != NULL)
comment_ptr = strstr(token_list[i] , comment_string);
if (comment_ptr != NULL) {
if (comment_ptr == token_list[i])
active_tokens = i;
else
active_tokens = i + 1;
break;
}
}
*/
if (active_tokens > 0) {
const char * kw = stringlist_iget( token_list , 0 );
/*Treating the include keyword. */
if (include_kw != NULL && (strcmp(include_kw , kw) == 0)) {
if (active_tokens != 2)
util_abort("%s: keyword:%s must have exactly one argument. \n",__func__ ,include_kw);
{
const char *include_file = stringlist_iget( token_list , 1);
if (util_file_exists( include_file ))
config_parse__(config , content , path_stack , include_file , comment_string , include_kw , define_kw , unrecognized, false); /* Recursive call */
else {
char * error_message = util_alloc_sprintf("%s file:%s not found" , include_kw , include_file);
config_error_add( config_content_get_errors( content ) , error_message );
free( error_message );
}
}
} else if ((define_kw != NULL) && (strcmp(define_kw , kw) == 0)) {
/* Treating the define keyword. */
if (active_tokens < 3)
util_abort("%s: keyword:%s must have exactly one (or more) arguments. \n",__func__ , define_kw);
{
char * key = util_alloc_string_copy( stringlist_iget(token_list ,1) );
char * value = stringlist_alloc_joined_substring( token_list , 2 , active_tokens , " ");
{
char * filtered_value = subst_list_alloc_filtered_string( config_content_get_define_list( content ) , value);
config_content_add_define( content , key , filtered_value );
free( filtered_value );
}
free(key);
free(value);
}
} else {
if (hash_has_key(config->messages , kw))
printf("%s \n", (const char *) hash_get(config->messages , kw));
if (!config_has_schema_item(config , kw)) {
if (unrecognized == CONFIG_UNRECOGNIZED_WARN)
fprintf(stderr,"** Warning keyword:%s not recognized when parsing:%s --- \n" , kw , config_input);
else if (unrecognized == CONFIG_UNRECOGNIZED_ERROR) {
char * error_message = util_alloc_sprintf("Keyword:%s is not recognized" , kw);
config_error_add( config_content_get_errors( content ) , error_message );
free( error_message );
}
}
if (config_has_schema_item(config , kw)) {
config_schema_item_type * schema_item = config_get_schema_item( config , kw );
char * config_cwd;
util_alloc_file_components( config_file , &config_cwd , NULL , NULL );
if (!config_content_has_item( content , kw ))
config_content_add_item( content , schema_item , current_path_elm);
{
subst_list_type * define_list = config_content_get_define_list( content );
config_content_item_type * content_item = config_content_get_item( content , config_schema_item_get_kw( schema_item ) );
config_content_node_type * new_node = config_content_item_set_arg__(define_list , config_content_get_errors( content ) , content_item , token_list , current_path_elm , config_file );
if (new_node)
config_content_add_node( content , new_node );
}
}
}
}
stringlist_free(token_list);
free(line_buffer);
}
}
if (validate)
config_validate(config , content , config_file);
fclose(stream);
basic_parser_free( parser );
}
free(config_file);
path_stack_pop( path_stack );
config_content_pop_path_stack( content );
}
config_content_type * config_parse(config_parser_type * config ,
const char * filename,
const char * comment_string ,
const char * include_kw ,
const char * define_kw ,
config_schema_unrecognized_enum unrecognized_behaviour,
bool validate) {
config_content_type * content = config_content_alloc( );
if (util_file_readable( filename )) {
path_stack_type * path_stack = path_stack_alloc();
{
config_content_set_config_file( content , filename );
config_content_set_invoke_path( content );
config_parse__(config , content , path_stack , filename , comment_string , include_kw , define_kw , unrecognized_behaviour , validate);
}
path_stack_free( path_stack );
} else {
char * error_message = util_alloc_sprintf("Could not open file:%s for parsing" , filename);
config_error_add( config_content_get_errors( content ) , error_message );
free( error_message );
}
if (config_error_count( config_content_get_errors( content ) ) == 0)
config_content_set_valid( content );
return content;
}
/*****************************************************************/
/**
This function adds an alias to an existing item; so that the
value+++ of an item can be referred to by two different names.
*/
void config_add_alias(config_parser_type * config , const char * src , const char * alias) {
if (config_has_schema_item(config , src)) {
config_schema_item_type * item = config_get_schema_item(config , src);
config_insert_schema_item(config , alias , item , true);
} else
util_abort("%s: item:%s not recognized \n",__func__ , src);
}
void config_install_message(config_parser_type * config , const char * kw, const char * message) {
hash_insert_hash_owned_ref(config->messages , kw , util_alloc_string_copy(message) , free);
}
#include "config_get.c"
+56 -56
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_schema_item.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_schema_item.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
@@ -36,7 +36,7 @@
typedef struct validate_struct validate_type;
/**
/**
This is a 'support-struct' holding various pieces of information
needed during the validation process. Observe the following about
validation:
@@ -51,10 +51,10 @@ typedef struct validate_struct validate_type;
2. Validation is a two-step process, the first step is run when an
item is parsed. This includes checking:
o The number of argument.
o The number of argument.
o That the arguments have the right type.
o That the values match the selection set.
The second validation step is done when the pasing is complete,
in this pass we check dependencies - i.e. required_children and
required_children_on_value.
@@ -69,11 +69,11 @@ typedef struct validate_struct validate_type;
argc_max first.
*/
struct validate_struct {
int argc_min; /* The minimum number of arguments: -1 means no lower limit. */
int argc_max; /* The maximum number of arguments: -1 means no upper limit. */
set_type * common_selection_set; /* A selection set which will apply uniformly to all the arguments. */
int argc_max; /* The maximum number of arguments: -1 means no upper limit. */
set_type * common_selection_set; /* A selection set which will apply uniformly to all the arguments. */
set_type ** indexed_selection_set; /* A selection set which will apply for specifi (indexed) arguments. */
int_vector_type * type_map; /* A list of types for the items. Set along with argc_minmax(); */
stringlist_type * required_children; /* A list of item's which must also be set (if this item is set). (can be NULL) */
@@ -88,13 +88,13 @@ struct validate_struct {
struct config_schema_item_struct {
UTIL_TYPE_ID_DECLARATION;
char * kw; /* The kw which identifies this item· */
bool required_set;
bool required_set;
stringlist_type * required_children; /* A list of item's which must also be set (if this item is set). (can be NULL) */
hash_type * required_children_value; /* A list of item's which must also be set - depending on the value of this item. (can be NULL) */
validate_type * validate; /* Information need during validation. */
bool expand_envvar; /* Should environment variables like $HOME be expanded?*/
validate_type * validate; /* Information need during validation. */
bool expand_envvar; /* Should environment variables like $HOME be expanded?*/
};
@@ -114,7 +114,7 @@ static validate_type * validate_alloc() {
validate->indexed_selection_set = NULL;
validate->required_children = NULL;
validate->required_children_value = NULL;
validate->type_map = int_vector_alloc(0 , 0);
validate->type_map = int_vector_alloc(0 , 0);
validate_set_default_type( validate , CONFIG_STRING );
return validate;
}
@@ -128,7 +128,7 @@ static void validate_free(validate_type * validate) {
set_free(validate->indexed_selection_set[i]);
free(validate->indexed_selection_set);
}
int_vector_free( validate->type_map );
if (validate->required_children != NULL) stringlist_free(validate->required_children);
if (validate->required_children_value != NULL) hash_free(validate->required_children_value);
@@ -142,27 +142,27 @@ static void validate_iset_type( validate_type * validate , int index , config_it
static config_item_types validate_iget_type( const validate_type * validate , int index) {
return int_vector_safe_iget( validate->type_map , index );
return int_vector_safe_iget( validate->type_map , index );
}
static void validate_set_argc_minmax(validate_type * validate , int argc_min , int argc_max) {
if (validate->argc_min != CONFIG_DEFAULT_ARG_MIN)
util_abort("%s: sorry - current implementation does not allow repeated calls to: %s \n",__func__ , __func__);
if (argc_min == CONFIG_DEFAULT_ARG_MIN)
argc_min = 0;
validate->argc_min = argc_min;
validate->argc_max = argc_max;
if ((argc_max != CONFIG_DEFAULT_ARG_MAX) && (argc_max < argc_min))
util_abort("%s invalid arg min/max values. argc_min:%d argc_max:%d \n",__func__ , argc_min , argc_max);
{
int internal_type_size = 0; /* Should end up in the range [argc_min,argc_max] */
if (argc_max > 0)
if (argc_max > 0)
internal_type_size = argc_max;
else
internal_type_size = argc_min;
@@ -185,16 +185,16 @@ static void validate_set_common_selection_set(validate_type * validate , int arg
static void validate_set_indexed_selection_set(validate_type * validate , int index , int argc , const char ** argv) {
if (validate->indexed_selection_set == NULL)
util_abort("%s: must call xxx_set_argc_minmax() first - aborting \n",__func__);
if (index >= validate->argc_min)
util_abort("%s: When not not setting argc_max selection set can only be applied to indices up to argc_min\n",__func__);
if (validate->indexed_selection_set[index] != NULL)
set_free(validate->indexed_selection_set[index]);
validate->indexed_selection_set[index] = set_alloc(argc , argv);
}
@@ -206,10 +206,10 @@ static UTIL_SAFE_CAST_FUNCTION( config_schema_item , CONFIG_SCHEMA_ITEM_ID)
void config_schema_item_assure_type(const config_schema_item_type * item , int index , int type_mask) {
bool OK = false;
if (int_vector_safe_iget( item->validate->type_map , index) & type_mask)
OK = true;
if (!OK)
util_abort("%s: failed - wrong installed type \n" , __func__);
}
@@ -233,7 +233,7 @@ config_schema_item_type * config_schema_item_alloc(const char * kw , bool requir
static char * __alloc_relocated__(const config_path_elm_type * path_elm , const char * value) {
char * file;
if (util_is_abs_path(value))
file = util_alloc_string_copy( value );
else
@@ -251,11 +251,11 @@ bool config_schema_item_validate_set(const config_schema_item_type * item , stri
OK = false;
{
char * error_message;
if (config_file != NULL)
if (config_file != NULL)
error_message = util_alloc_sprintf("Error when parsing config_file:\"%s\" Keyword:%s must have at least %d arguments.",config_file , item->kw , item->validate->argc_min);
else
error_message = util_alloc_sprintf("Error:: Keyword:%s must have at least %d arguments.",item->kw , item->validate->argc_min);
config_error_add( error_list , error_message );
}
}
@@ -266,22 +266,22 @@ bool config_schema_item_validate_set(const config_schema_item_type * item , stri
OK = false;
{
char * error_message;
if (config_file != NULL)
error_message = util_alloc_sprintf("Error when parsing config_file:\"%s\" Keyword:%s must have maximum %d arguments.",config_file , item->kw , item->validate->argc_max);
else
error_message = util_alloc_sprintf("Error:: Keyword:%s must have maximum %d arguments.",item->kw , item->validate->argc_max);
config_error_add( error_list , error_message );
}
}
}
/*
/*
OK - now we have verified that the number of arguments is correct. Then
we start actually looking at the values.
we start actually looking at the values.
*/
if (OK) {
if (OK) {
/* Validating selection set - first common, then indexed */
if (item->validate->common_selection_set) {
for (int iarg = 0; iarg < argc; iarg++) {
@@ -344,14 +344,14 @@ bool config_schema_item_validate_set(const config_schema_item_type * item , stri
/*
1. If the supplied value is an abolute path - do nothing.
2. If the supplied is _not_ an absolute path:
a. Try if the relocated exists - then use that.
b. Else - try if the util_alloc_PATH_executable() exists.
*/
if (!util_is_abs_path( value )) {
char * relocated = __alloc_relocated__(path_elm , value);
char * path_exe = util_alloc_PATH_executable( value );
if (util_file_exists(relocated)) {
if (util_is_executable(relocated))
stringlist_iset_copy( token_list , iarg , relocated);
@@ -359,7 +359,7 @@ bool config_schema_item_validate_set(const config_schema_item_type * item , stri
stringlist_iset_copy( token_list , iarg , path_exe);
else
config_error_add( error_list , util_alloc_sprintf("Could not locate executable:%s ", value));
free(relocated);
util_safe_free(path_exe);
} else {
@@ -384,7 +384,7 @@ bool config_schema_item_validate_set(const config_schema_item_type * item , stri
util_abort("%s: config_item_type:%d not recognized \n",__func__ , validate_iget_type(item->validate , iarg));
}
}
}
}
}
return OK;
}
@@ -393,7 +393,7 @@ bool config_schema_item_validate_set(const config_schema_item_type * item , stri
void config_schema_item_free( config_schema_item_type * item) {
free(item->kw);
if (item->required_children != NULL) stringlist_free(item->required_children);
if (item->required_children_value != NULL) hash_free(item->required_children_value);
if (item->required_children_value != NULL) hash_free(item->required_children_value);
validate_free(item->validate);
free(item);
}
@@ -423,10 +423,10 @@ void config_schema_item_set_required_children_on_value(config_schema_item_type *
*/
void config_schema_item_set_argc_minmax(config_schema_item_type * item ,
int argc_min ,
void config_schema_item_set_argc_minmax(config_schema_item_type * item ,
int argc_min ,
int argc_max) {
validate_set_argc_minmax(item->validate , argc_min , argc_max);
}
@@ -444,7 +444,7 @@ config_item_types config_schema_item_iget_type(const config_schema_item_type * i
return validate_iget_type( item->validate , index );
}
void config_schema_item_set_envvar_expansion( config_schema_item_type * item , bool expand_envvar ) {
@@ -469,7 +469,7 @@ void config_schema_item_set_required_children(config_schema_item_type * item , s
void config_schema_item_add_required_children(config_schema_item_type * item , const char * child_key) {
if (item->required_children == NULL)
item->required_children = stringlist_alloc_new();
stringlist_append_copy( item->required_children , child_key );
}
+4
View File
@@ -35,6 +35,10 @@ add_executable( config_error config_error.c)
target_link_libraries( config_error config test_util )
add_test( config_error ${EXECUTABLE_OUTPUT_PATH}/config_error )
add_executable( config_content config_content.c)
target_link_libraries( config_content config test_util )
add_test( config_content ${EXECUTABLE_OUTPUT_PATH}/config_content )
add_executable( config_config config_config.c)
target_link_libraries( config_config config test_util )
+17 -8
View File
@@ -20,27 +20,36 @@
#include <ert/util/test_util.h>
#include <ert/config/config.h>
#include <ert/config/config_parser.h>
#include <ert/config/config_content.h>
int main(int argc , char ** argv) {
const char * config_file = argv[1];
config_type * config = config_alloc();
config_parser_type * config = config_alloc();
config_schema_item_type * item = config_add_schema_item(config , "APPEND" , false );
config_schema_item_set_argc_minmax( item , 1 , 1);
test_assert_true(config_parse(config , config_file , "--" , NULL , NULL , false , true ));
{
test_assert_int_equal( config_get_occurences( config , "APPEND" ) , 3);
config_content_type * content = config_parse(config , config_file , "--" , NULL , NULL , false , true );
test_assert_true(config_content_is_instance( content ));
test_assert_true(config_content_is_valid( content ));
test_assert_int_equal( config_content_get_occurences( content , "APPEND" ) , 3);
{
const char * value = config_get_value( config , "APPEND");
const char * value = config_content_get_value( content , "APPEND");
test_assert_string_equal( value , "VALUE3");
}
}
test_assert_false( config_parse( config , "DoesNotExist" , "--" , NULL , NULL , false , true));
config_content_free( content );
}
{
config_content_type * content = config_parse( config , "DoesNotExist" , "--" , NULL , NULL , false , true);
test_assert_false( config_content_is_valid( content ));
config_content_free( content );
}
exit(0);
}
+50 -40
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'config_argc.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2013 Statoil ASA, Norway.
The file 'config_argc.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
@@ -24,14 +24,14 @@
#include <ert/util/test_util.h>
#include <ert/util/util.h>
#include <ert/config/config.h>
#include <ert/config/config_parser.h>
#include <ert/config/config_schema_item.h>
#include <ert/config/config_error.h>
void install_SIGNALS(void) {
signal(SIGSEGV , util_abort_signal); /* Segmentation violation, i.e. overwriting memory ... */
signal(SIGINT , util_abort_signal); /* Control C */
signal(SIGTERM , util_abort_signal); /* If killing the program with SIGTERM (the default kill signal) you will get a backtrace.
signal(SIGTERM , util_abort_signal); /* If killing the program with SIGTERM (the default kill signal) you will get a backtrace.
Killing with SIGKILL (-9) will not give a backtrace.*/
}
@@ -43,38 +43,48 @@ int main(int argc , char ** argv) {
const char * argc_OK = argv[1];
const char * argc_less = argv[2];
const char * argc_more = argv[3];
config_type * config = config_alloc();
config_parser_type * config = config_alloc();
config_schema_item_type * schema_item = config_add_schema_item( config , "ITEM" , false );
config_schema_item_set_argc_minmax( schema_item , 2 , 2 );
test_assert_true( config_parse( config , argc_OK , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_ERROR , true));
config_clear( config );
test_assert_false( config_parse( config , argc_less , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_ERROR , true));
{
const config_error_type * config_error = config_get_errors( config );
const char * error_msg = "Error when parsing config_file:\"argc_less\" Keyword:ITEM must have at least 2 arguments.";
test_assert_int_equal( config_error_count( config_error ) , 1);
test_assert_string_equal( config_error_iget( config_error , 0 ) , error_msg);
config_content_type * content = config_parse( config , argc_OK , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_ERROR , true);
test_assert_true( config_content_is_instance( content ));
test_assert_true(config_content_is_valid( content ));
config_content_free( content );
}
config_clear( config );
test_assert_false( config_parse( config , argc_more , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_ERROR , true));
{
const config_error_type * config_error = config_get_errors( config );
const char * error_msg = "Error when parsing config_file:\"argc_more\" Keyword:ITEM must have maximum 2 arguments.";
test_assert_int_equal( config_error_count( config_error ) , 1);
test_assert_string_equal( config_error_iget( config_error , 0 ) , error_msg);
}
config_clear( config );
config_content_type * content = config_parse( config , argc_less , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_ERROR , true);
test_assert_true( config_content_is_instance( content ));
test_assert_false( config_content_is_valid( content ));
{
const config_error_type * config_error = config_content_get_errors( content );
const char * error_msg = "Error when parsing config_file:\"argc_less\" Keyword:ITEM must have at least 2 arguments.";
test_assert_int_equal( config_error_count( config_error ) , 1);
test_assert_string_equal( config_error_iget( config_error , 0 ) , error_msg);
}
config_content_free( content );
}
{
config_content_type * content = config_parse( config , argc_more , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_ERROR , true);
test_assert_true( config_content_is_instance( content ));
test_assert_false( config_content_is_valid( content ));
{
const config_error_type * config_error = config_content_get_errors( content );
const char * error_msg = "Error when parsing config_file:\"argc_more\" Keyword:ITEM must have maximum 2 arguments.";
test_assert_int_equal( config_error_count( config_error ) , 1);
test_assert_string_equal( config_error_iget( config_error , 0 ) , error_msg);
}
config_content_free( content );
}
config_free( config );
exit(0);
}
}
+2 -2
View File
@@ -23,12 +23,12 @@
#include <ert/util/test_util.h>
#include <ert/util/util.h>
#include <ert/config/config.h>
#include <ert/config/config_parser.h>
#include <ert/config/config_schema_item.h>
int main(int argc , char ** argv) {
config_type * config = config_alloc();
config_parser_type * config = config_alloc();
config_add_schema_item( config , "KEYWORD" , false );
config_free( config );
exit(0);
+37
View File
@@ -0,0 +1,37 @@
/*
Copyright (C) 2015 Statoil ASA, Norway.
The file 'config_content.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <ert/util/test_util.h>
#include <ert/config/config_content.h>
void test_create() {
config_content_type * content = config_content_alloc( );
test_assert_true( config_content_is_instance( content ) );
config_content_free( content );
}
int main( int argc , char ** argv) {
test_create();
}
+15 -16
View File
@@ -23,7 +23,7 @@
#include <ert/util/util.h>
#include <ert/util/hash.h>
#include <ert/config/config.h>
#include <ert/config/config_parser.h>
#include <ert/config/config_content_node.h>
#include <ert/config/config_schema_item.h>
#include <ert/config/config_path_elm.h>
@@ -31,28 +31,27 @@
int main(int argc , char ** argv) {
const char * config_file = argv[1];
config_type * config = config_alloc();
config_parser_type * config = config_alloc();
config_add_schema_item( config , "SET" , true );
config_add_schema_item( config , "NOTSET" , false );
test_assert_true( config_parse( config , config_file , "--" , "INCLUDE" , NULL , CONFIG_UNRECOGNIZED_IGNORE , true ));
{
config_content_type * content = config_parse( config , config_file , "--" , "INCLUDE" , NULL , CONFIG_UNRECOGNIZED_IGNORE , true );
test_assert_true( config_content_is_instance( content ));
test_assert_true(config_content_is_valid( content ));
test_assert_not_NULL( config_get_content_item( config , "SET" ));
test_assert_NULL( config_get_content_item( config , "NOTSET" ) );
test_assert_NULL( config_get_content_item( config , "UNKNOWN" ) );
test_assert_true( config_content_has_item( content , "SET" ));
test_assert_false( config_content_has_item( content , "NOTSET" ) );
test_assert_false( config_content_has_item( content , "UNKNOWN" ) );
test_assert_true( config_has_schema_item( config , "SET" ));
test_assert_true( config_has_schema_item( config , "NOTSET" ));
test_assert_false( config_has_schema_item( config , "UNKNOWN" ));
test_assert_true( config_has_schema_item( config , "SET" ));
test_assert_true( config_has_schema_item( config , "NOTSET" ));
test_assert_false( config_has_schema_item( config , "UNKNOWN" ));
test_assert_true( config_has_content_item( config , "SET" ));
test_assert_false( config_has_content_item( config , "NOTSET" ));
test_assert_false( config_has_content_item( config , "UNKNOWN" ));
config_content_free( content );
}
exit(0);
}
+19 -13
View File
@@ -23,16 +23,18 @@
#include <ert/util/util.h>
#include <ert/util/subst_list.h>
#include <ert/config/config.h>
#include <ert/config/config_parser.h>
#include <ert/config/config_content_node.h>
#include <ert/config/config_schema_item.h>
#include <ert/config/config_path_elm.h>
void test_define(config_type * config , const char * config_file) {
test_assert_true( config_parse( config , config_file , NULL , NULL , "DEFINE" , CONFIG_UNRECOGNIZED_IGNORE , true ));
void test_define(config_parser_type * config , const char * config_file) {
config_content_type * content = config_parse( config , config_file , NULL , NULL , "DEFINE" , CONFIG_UNRECOGNIZED_IGNORE , true );
test_assert_true( config_content_is_instance( content ));
test_assert_true(config_content_is_valid( content ));
{
const subst_list_type * define_list = config_get_define_list( config );
const subst_list_type * define_list = config_content_get_define_list( content );
test_assert_true( subst_list_has_key( define_list , "VAR1"));
test_assert_true( subst_list_has_key( define_list , "VAR2"));
test_assert_true( subst_list_has_key( define_list , "VARX"));
@@ -43,12 +45,13 @@ void test_define(config_type * config , const char * config_file) {
test_assert_string_equal( subst_list_get_value( define_list , "VAR2") , "10");
test_assert_string_equal( subst_list_get_value( define_list , "VARX") , "1");
}
config_content_free( content );
}
config_type * config_create_schema() {
config_type * config = config_alloc();
config_parser_type * config_create_schema() {
config_parser_type * config = config_alloc();
config_add_schema_item( config , "SET" , true );
config_add_schema_item( config , "NOTSET" , false );
@@ -58,12 +61,15 @@ config_type * config_create_schema() {
int main(int argc , char ** argv) {
const char * config_file = argv[1];
config_type * config = config_create_schema();
test_define( config , config_file );
config_free( config );
exit(0);
util_install_signals();
{
const char * config_file = argv[1];
config_parser_type * config = config_create_schema();
test_define( config , config_file );
config_free( config );
exit(0);
}
}
+22 -20
View File
@@ -24,10 +24,11 @@
#include <ert/util/util.h>
#include <ert/util/path_stack.h>
#include <ert/config/config.h>
#include <ert/config/config_parser.h>
#include <ert/config/config_schema_item.h>
#include <ert/config/config_content.h>
void parse_test(config_type * config ,
void parse_test(config_parser_type * config ,
const char * root_path , // The new working directory - the test will start by chdir() here.
const char * config_file ) { // The config_file, either as an absolute path - or relative from root_path
@@ -52,9 +53,9 @@ void parse_test(config_type * config ,
config_rel_path = util_alloc_rel_path( NULL , config_abs_path);
{
config_clear( config );
if (config_parse( config , config_file , "--" , "INCLUDE" , NULL , CONFIG_UNRECOGNIZED_IGNORE , true )) {
config_content_type * content = config_parse( config , config_file , "--" , "INCLUDE" , NULL , CONFIG_UNRECOGNIZED_IGNORE , true );
if (config_content_is_valid( content )) {
char * relpath0 = util_alloc_filename( config_rel_path , path0, NULL);
char * relpath1 = util_alloc_filename( config_rel_path , path1, NULL);
char * relpath2 = util_alloc_filename( config_rel_path , path2, NULL);
@@ -66,24 +67,25 @@ void parse_test(config_type * config ,
char * abspath2 = util_alloc_filename( config_abs_path , path2, NULL);
char * abspath3 = util_alloc_filename( config_abs_path , path3, NULL);
char * abspath4 = util_alloc_filename( config_abs_path , path4, NULL);
test_assert_string_equal(config_get_value_as_relpath(config , "PATH0") , relpath0 );
test_assert_string_equal(config_get_value_as_relpath(config , "PATH1") , relpath1 );
test_assert_string_equal(config_get_value_as_relpath(config , "PATH2") , relpath2 );
test_assert_string_equal(config_get_value_as_relpath(config , "PATH3") , relpath3 );
test_assert_string_equal(config_get_value_as_relpath(config , "PATH4") , relpath4 );
test_assert_string_equal(config_get_value_as_abspath(config , "PATH0") , abspath0 );
test_assert_string_equal(config_get_value_as_abspath(config , "PATH1") , abspath1 );
test_assert_string_equal(config_get_value_as_abspath(config , "PATH2") , abspath2 );
test_assert_string_equal(config_get_value_as_abspath(config , "PATH3") , abspath3 );
test_assert_string_equal(config_get_value_as_abspath(config , "PATH4") , abspath4 );
test_assert_string_equal(config_content_get_value_as_relpath(content , "PATH0") , relpath0 );
test_assert_string_equal(config_content_get_value_as_relpath(content , "PATH1") , relpath1 );
test_assert_string_equal(config_content_get_value_as_relpath(content , "PATH2") , relpath2 );
test_assert_string_equal(config_content_get_value_as_relpath(content , "PATH3") , relpath3 );
test_assert_string_equal(config_content_get_value_as_relpath(content , "PATH4") , relpath4 );
test_assert_string_equal(config_content_get_value_as_abspath(content , "PATH0") , abspath0 );
test_assert_string_equal(config_content_get_value_as_abspath(content , "PATH1") , abspath1 );
test_assert_string_equal(config_content_get_value_as_abspath(content , "PATH2") , abspath2 );
test_assert_string_equal(config_content_get_value_as_abspath(content , "PATH3") , abspath3 );
test_assert_string_equal(config_content_get_value_as_abspath(content , "PATH4") , abspath4 );
} else {
config_error_type * error = config_get_errors( config );
const config_error_type * error = config_content_get_errors( content );
config_error_fprintf( error , true , stdout );
test_error_exit("Hmm - parsing %s failed \n", config_file );
}
config_content_free( content );
}
path_stack_pop( path_stack );
}
@@ -93,7 +95,7 @@ int main(int argc , char ** argv) {
const char * abs_path = argv[1];
const char * config_file = argv[2];
char * abs_config_file = util_alloc_filename( abs_path , config_file , NULL);
config_type * config = config_alloc();
config_parser_type * config = config_alloc();
{
config_schema_item_type * schema_item;
+13 -11
View File
@@ -18,30 +18,31 @@
#include <stdlib.h>
#include <stdbool.h>
#include <ert/config/config.h>
#include <ert/config/config_parser.h>
#include <ert/config/config_content.h>
int main(int argc , char ** argv) {
const char * config_file = argv[1];
config_type * config = config_alloc();
bool OK;
config_parser_type * config = config_alloc();
{
config_schema_item_type * item = config_add_schema_item(config , "APPEND" , false );
config_schema_item_set_argc_minmax( item , 1 , 1);
}
config_add_schema_item(config , "NEXT" , false );
OK = config_parse(config , config_file , "--" , NULL , NULL , false , true );
if (OK) {
if (config_get_content_size( config ) == 4) {
const config_content_node_type * node0 = config_iget_content_node( config , 0 );
config_content_type * content = config_parse(config , config_file , "--" , NULL , NULL , false , true );
if (config_content_is_valid( content )) {
if (config_content_get_size( content ) == 4) {
const config_content_node_type * node0 = config_content_iget_node( content , 0 );
if (strcmp( config_content_node_get_kw( node0 ) , "APPEND") == 0) {
if (config_content_node_get_size(node0) == 1) {
const config_content_node_type * node3 = config_iget_content_node( config , 3 );
const config_content_node_type * node3 = config_content_iget_node( content , 3 );
if (strcmp( config_content_node_get_kw( node3 ) , "NEXT") == 0) {
if (config_content_node_get_size(node3) == 2) {
config_content_free( content );
exit(0);
} else printf("Size error node3\n");
} else printf("kw error node3 \n");
@@ -49,7 +50,8 @@ int main(int argc , char ** argv) {
} else printf("kw error node0 kw:%s \n", config_content_node_get_kw( node0 ));
} else printf("Size error \n");
} else printf("Parse error");
config_content_free( content );
exit(1);
}
+1 -1
View File
@@ -24,7 +24,7 @@
#include <ert/util/util.h>
#include <ert/util/test_work_area.h>
#include <ert/config/config.h>
#include <ert/config/config_parser.h>
#include <ert/config/config_path_elm.h>
#include <ert/config/config_root_path.h>
+1 -1
View File
@@ -22,7 +22,7 @@
#include <ert/util/test_util.h>
#include <ert/util/util.h>
#include <ert/config/config.h>
#include <ert/config/config_parser.h>
#include <ert/config/config_root_path.h>
+38 -34
View File
@@ -1,25 +1,28 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_typeFail.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_parser_typeFail.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/config/config_error.h>
#include <ert/config/config.h>
#include <ert/config/config_parser.h>
#include <ert/config/config_content.h>
void error(char * msg) {
@@ -30,36 +33,37 @@ void error(char * msg) {
int main(int argc , char ** argv) {
const char * config_file = argv[1];
config_type * config = config_alloc();
bool OK;
config_parser_type * config = config_alloc();
{
config_schema_item_type * item = config_add_schema_item(config , "TYPES_KEY" , false );
config_schema_item_set_argc_minmax( item , 4 , 4 );
config_schema_item_set_argc_minmax( item , 4 , 4 );
config_schema_item_iset_type( item , 0 , CONFIG_INT );
config_schema_item_iset_type( item , 1 , CONFIG_FLOAT );
config_schema_item_iset_type( item , 2 , CONFIG_BOOL );
item = config_add_schema_item( config , "SHORT_KEY" , false );
config_schema_item_set_argc_minmax( item , 1 , 1 );
item = config_add_schema_item( config , "LONG_KEY" , false );
config_schema_item_set_argc_minmax( item , 3 , CONFIG_DEFAULT_ARG_MAX);
}
OK = config_parse(config , config_file , "--" , NULL , NULL , false , true );
if (OK) {
error("Parse error\n");
} else {
config_error_type * cerror = config_get_errors( config );
if (config_error_count( cerror ) > 0) {
int i;
for (i=0; i < config_error_count( cerror ); i++) {
printf("Error %d: %s \n",i , config_error_iget( cerror , i ));
{
config_content_type * content = config_parse(config , config_file , "--" , NULL , NULL , false , true );
if (config_content_is_valid( content )) {
error("Parse error\n");
} else {
const config_error_type * cerror = config_content_get_errors( content );
if (config_error_count( cerror ) > 0) {
int i;
for (i=0; i < config_error_count( cerror ); i++) {
printf("Error %d: %s \n",i , config_error_iget( cerror , i ));
}
}
test_assert_int_equal( 5 , config_error_count( cerror ));
}
printf("Error count:%d \n",config_error_count( cerror ));
if (config_error_count( cerror ) != 5)
error("Wrong error count\n");
config_content_free( content );
}
printf("OK \n");
exit(0);
+27 -29
View File
@@ -1,36 +1,33 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_typeOK.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_parser_typeOK.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/config/config.h>
#include <ert/util/test_util.h>
#include <ert/config/config_parser.h>
#include <ert/config/config_content.h>
void error(char * msg) {
fprintf(stderr , msg);
exit(1);
}
int main(int argc , char ** argv) {
const char * config_file = argv[1];
config_type * config = config_alloc();
bool OK;
config_parser_type * config = config_alloc();
{
config_schema_item_type * item = config_add_schema_item(config , "TYPE_KEY" , false );
config_schema_item_set_argc_minmax( item , 4 , 4 );
@@ -40,16 +37,17 @@ int main(int argc , char ** argv) {
item = config_add_schema_item( config , "SHORT_KEY" , false );
config_schema_item_set_argc_minmax( item , 1 , 1 );
item = config_add_schema_item( config , "LONG_KEY" , false );
config_schema_item_set_argc_minmax( item , 3 , CONFIG_DEFAULT_ARG_MAX );
}
OK = config_parse(config , config_file , "--" , NULL , NULL , false , true );
if (OK) {
} else error("Parse error\n");
{
config_content_type * content = config_parse(config , config_file , "--" , NULL , NULL , false , true );
test_assert_true( config_content_is_valid( content ));
config_content_free( content );
}
exit(0);
}
@@ -32,6 +32,13 @@ if (BUILD_APPLICATIONS)
set(program_list summary2csv2 summary2csv kw_extract grdecl_grid make_grid sum_write load_test grdecl_test grid_dump_ascii select_test grid_dump convert kw_list grid_info summary)
endif()
if (BUILD_ERT)
add_executable( ecl_quantile ecl_quantile.c )
include_directories( ../../libconfig/include )
target_link_libraries( ecl_quantile config )
list( APPEND program_list ecl_quantile )
endif()
foreach(prog ${program_list})
target_link_libraries( ${prog} ecl ert_util )
+37 -33
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'convert.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'convert.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
@@ -38,33 +38,37 @@ void file_convert(const char * src_file , const char * target_file, ecl_file_enu
if (file_type != ECL_OTHER_FILE)
formatted_src = fmt_src;
else {
if (util_fmt_bit8(src_file))
if (util_fmt_bit8(src_file))
formatted_src = true;
else
formatted_src = false;
}
target = fortio_open_writer(target_file , !formatted_src , ECL_ENDIAN_FLIP );
src = fortio_open_reader(src_file , formatted_src , ECL_ENDIAN_FLIP);
ecl_kw = ecl_kw_fread_alloc(src);
if (ecl_kw == NULL) {
fprintf(stderr,"Loading: %s failed - maybe you forgot the header? \n", src_file);
abort();
while (true) {
if (fortio_read_at_eof( src ))
break;
{
ecl_kw_type * ecl_kw = ecl_kw_fread_alloc( src );
if (ecl_kw) {
ecl_kw_fwrite(ecl_kw , target);
ecl_kw_free(ecl_kw);
} else {
fprintf(stderr, "Reading keyword failed \n");
break;
}
}
}
while (ecl_kw != NULL) {
ecl_kw_fwrite(ecl_kw , target);
ecl_kw_free(ecl_kw);
ecl_kw = ecl_kw_fread_alloc(src);
}
if (ecl_kw != NULL) ecl_kw_free(ecl_kw);
fortio_fclose(src);
fortio_fclose(target);
}
int main (int argc , char **argv) {
int main (int argc , char **argv) {
if (argc == 1) {
fprintf(stderr,"Usage: convert.x <filename1> <filename2> <filename3> ...\n");
exit(1);
@@ -72,12 +76,12 @@ int main (int argc , char **argv) {
char *src_file = argv[1];
char *target_file;
int report_nr;
ecl_file_enum file_type;
bool fmt_file;
file_type = ecl_util_get_file_type(src_file , &fmt_file , &report_nr);
if (file_type == ECL_OTHER_FILE) {
if (argc != 3) {
fprintf(stderr,"When the file can not be recognized on the name as an ECLIPSE file you must give output_file as second (and final) argument \n");
@@ -99,10 +103,10 @@ int main (int argc , char **argv) {
exit(1);
}
util_alloc_file_components(src_file , &path , &basename , &extension);
target_file = ecl_util_alloc_filename(path, basename , file_type , !fmt_file , report_nr);
file_convert(src_file , target_file , file_type , fmt_file);
free(path);
free(basename);
free(extension);
+111 -106
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_quantile.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_quantile.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#define _GNU_SOURCE /* Must define this to get access to pthread_rwlock_t */
@@ -32,7 +32,9 @@
#include <ert/util/arg_pack.h>
#include <ert/util/thread_pool.h>
#include <ert/config/config.h>
#include <ert/config/config_parser.h>
#include <ert/config/config_content.h>
#include <ert/config/config_error.h>
#include <ert/config/config_content_item.h>
#include <ert/config/config_content_node.h>
@@ -41,7 +43,7 @@
#define DEFAULT_NUM_INTERP 50
#define SUMMARY_JOIN ":"
#define MIN_SIZE 10
#define LOAD_THREADS 4
#define LOAD_THREADS 4
typedef enum {
@@ -62,7 +64,7 @@ typedef struct {
/**
Microscopic data structure representing one column of data;
i.e. one ECLIPSE summary key and one accompanying quantile value.
i.e. one ECLIPSE summary key and one accompanying quantile value.
*/
typedef struct {
@@ -124,7 +126,7 @@ sum_case_type * sum_case_fread_alloc( const char * data_file , const time_t_vect
sum_case->ecl_sum = ecl_sum_fread_alloc_case( data_file , SUMMARY_JOIN );
sum_case->interp_data = double_vector_alloc(0 , 0);
sum_case->interp_time = interp_time;
sum_case->interp_time = interp_time;
sum_case->start_time = ecl_sum_get_start_time( sum_case->ecl_sum );
sum_case->end_time = ecl_sum_get_end_time( sum_case->ecl_sum );
return sum_case;
@@ -148,7 +150,7 @@ void sum_case_free__( void * sum_case) {
void ensemble_add_case( ensemble_type * ensemble , const char * data_file ) {
sum_case_type * sum_case = sum_case_fread_alloc( data_file , ensemble->interp_time );
pthread_rwlock_wrlock( &ensemble->rwlock );
{
printf("Loading case: %s \n", data_file );
@@ -157,7 +159,7 @@ void ensemble_add_case( ensemble_type * ensemble , const char * data_file ) {
ensemble->start_time = util_time_t_min( ensemble->start_time , sum_case->start_time);
else
ensemble->start_time = ecl_sum_get_start_time( sum_case->ecl_sum );
ensemble->end_time = util_time_t_max( ensemble->end_time , sum_case->end_time);
}
pthread_rwlock_unlock( &ensemble->rwlock );
@@ -216,7 +218,7 @@ ensemble_type * ensemble_alloc( ) {
}
void ensemble_init( ensemble_type * ensemble , config_type * config) {
void ensemble_init( ensemble_type * ensemble , config_content_type * config) {
/*1 : Loading ensembles and settings from the config instance */
/*1a: Loading the eclipse summary cases. */
@@ -224,33 +226,32 @@ void ensemble_init( ensemble_type * ensemble , config_type * config) {
thread_pool_type * tp = thread_pool_alloc( LOAD_THREADS , true );
{
int i,j;
const config_content_item_type * case_item = config_get_content_item( config , "CASE_LIST" );
if (case_item != NULL) {
for (j=0; j < config_content_node_get_size( case_item ); j++) {
const config_content_node_type * case_node = config_content_item_iget_node( case_item );
for (i=0; i < config_content_node_get_size( case_node ) i++) {
if (config_content_has_item( config , "CASE_LIST")) {
const config_content_item_type * case_item = config_content_get_item( config , "CASE_LIST" );
for (j=0; j < config_content_item_get_size( case_item ); j++) {
const config_content_node_type * case_node = config_content_item_iget_node( case_item , j );
for (i=0; i < config_content_node_get_size( case_node ); i++) {
const char * case_glob = config_content_node_iget( case_node , i );
ensemble_load_from_glob( ensemble , case_glob , tp);
}
}
}
}
thread_pool_join( tp );
thread_pool_free( tp );
}
{
const sum_case_type * tmp = vector_iget_const( ensemble->data , 0 );
ensemble->refcase = tmp->ecl_sum;
}
/*1b: Other config settings */
if (config_item_set( config , "NUM_INTERP" ))
ensemble->num_interp = config_iget_as_int( config , "NUM_INTERP" , 0 , 0 );
if (config_content_has_item( config , "NUM_INTERP" ))
ensemble->num_interp = config_content_iget_as_int( config , "NUM_INTERP" , 0 , 0 );
/*2: Remaining initialization */
ensemble_init_time_interp( ensemble );
if (vector_get_size( ensemble->data ) < MIN_SIZE )
@@ -269,7 +270,7 @@ void ensemble_free( ensemble_type * ensemble ) {
}
/*****************************************************************/
static output_type * output_alloc( const char * file , const char * format_string) {
output_type * output = util_malloc( sizeof * output );
output->keys = vector_alloc_new();
@@ -289,7 +290,7 @@ static output_type * output_alloc( const char * file , const char * format_strin
}
output->format = format;
}
return output;
}
@@ -322,26 +323,26 @@ static void output_add_key( const ecl_sum_type * refcase , output_type * output
util_split_string( qkey , SUMMARY_JOIN , &tokens , &tmp);
if (tokens == 1)
util_exit("Hmmm - the key:%s is malformed - must be of the form SUMMARY_KEY:QUANTILE.\n",qkey);
if (!util_sscanf_double( tmp[tokens - 1] , &quantile))
util_exit("Hmmmm - failed to interpret:%s as a quantile - must be a number (0,1).\n",tmp[tokens-1]);
if (quantile <= 0 || quantile >= 1.0)
util_exit("Invalid quantile value:%g - must be in interval (0,1)\n", quantile);
sum_key = util_alloc_joined_string( (const char **) tmp , tokens - 1 , SUMMARY_JOIN);
{
stringlist_type * matching_keys = stringlist_alloc_new();
int i;
ecl_sum_select_matching_general_var_list( refcase , sum_key , matching_keys );
for (i=0; i < stringlist_get_size( matching_keys ); i++)
for (i=0; i < stringlist_get_size( matching_keys ); i++)
vector_append_owned_ref( output->keys , quant_key_alloc( stringlist_iget( matching_keys , i ) , quantile) , quant_key_free__ );
if (stringlist_get_size( matching_keys ) == 0)
fprintf(stderr,"** Warning: No summary vectors matching:\'%s\' found?? \n", sum_key);
stringlist_free( matching_keys );
}
util_free_stringlist( tmp, tokens );
}
@@ -354,21 +355,21 @@ static void output_add_key( const ecl_sum_type * refcase , output_type * output
OUTPUT output_file key.q key.q key.q key.q ...
*/
void output_table_init( const ecl_sum_type * refcase, hash_type * output_table , const config_type * config ) {
void output_table_init( const ecl_sum_type * refcase, hash_type * output_table , const config_content_type * config ) {
int i,j;
const config_content_item_type * output_item = config_get_content_item( config , "OUTPUT");
if (output_item != NULL) {
if (config_content_has_item( config , "OUTPUT")) {
const config_content_item_type * output_item = config_content_get_item( config , "OUTPUT");
for (i = 0; i < config_content_item_get_size( output_item ); i++) {
const config_content_node_type * output_node = config_content_item_iget_node( output_item , i );
const char * file = config_content_node_iget( output_node , 0 );
const char * format_string = config_content_node_iget( output_node , 1 );
output_type * output = output_alloc( file , format_string );
/* All the keys are just added - without any check. */
for (j = 2; j < config_content_node_get_size( output_node ); j++)
output_add_key( refcase , output , config_content_node_iget( output_node , j));
hash_insert_hash_owned_ref( output_table , file , output , output_free__ );
}
}
@@ -390,9 +391,9 @@ static void print_var( FILE * stream , const char * var , double q , const char
/*
/*
** The columns are <TAB> separated! **
An ECLIPSE summary variable is generally characterized by three
variable values from SMSPEC vectors; the three vectors are
KEYWORDS, WGNAMES and NUMS.
@@ -403,7 +404,7 @@ static void print_var( FILE * stream , const char * var , double q , const char
additional information from one, or both of WGNAMES and NUMS. For
instance for a well variable or group variable we will need the
well name from WGNAMES and for a block property we will need the
block number (as i + j*nx + k*nx*ny) from the NUMS vector.
block number (as i + j*nx + k*nx*ny) from the NUMS vector.
When writing the S3Graph header I don't understand how to enter the
different parts of header information. The current implementation,
@@ -412,7 +413,7 @@ static void print_var( FILE * stream , const char * var , double q , const char
1. Write a line like this:
DATE TIME KEYWORD1:xxx KEYWORD2:xxx KEYWORD3:xxxx
Here KEYWORD is an eclipse variable memnonic from the KEYWORDS
array, i.e. FOPT or WWCT. The :xxx part is the quantile we are
looking at, i.e. 0.10 or 0.90. It seems adding the quantile
@@ -420,16 +421,16 @@ static void print_var( FILE * stream , const char * var , double q , const char
2. Write a line with units:
DATE TIME KEYWORD1:xxx KEYWORD2:xxx KEYWORD3:xxxx
DATE TIME KEYWORD1:xxx KEYWORD2:xxx KEYWORD3:xxxx
DAYS UNIT1 UNIT2 UNIT2 <---- New line
3. Write a line with keyword qualifiers, i.e. extra information:
DATE TIME WOPR:xxx FOPT:xxxx BPR
DAYS UNIT1 UNIT2 UNIT2
OP1 1000 <---- New line
DAYS UNIT1 UNIT2 UNIT2
OP1 1000 <---- New line
Now - the totally confusing part is that it is not clear what
S3Graph expects on this third line, in the case of well/group
variables it is a well/group name from the WGNAMES array,
@@ -443,14 +444,14 @@ static void print_var( FILE * stream , const char * var , double q , const char
[*] : I do not really understand why it seems to work.
*/
void output_save_S3Graph( const output_type * output, ensemble_type * ensemble , const double ** data ) {
FILE * stream = util_mkdir_fopen( output->file , "w");
FILE * stream = util_mkdir_fopen( output->file , "w");
const char * kw_fmt = "\t%s";
const char * unit_fmt = "\t%s";
const char * wgname_fmt = "\t%s";
@@ -466,14 +467,14 @@ void output_save_S3Graph( const output_type * output, ensemble_type * ensemble ,
const int data_columns = vector_get_size( output->keys );
const int data_rows = time_t_vector_size( ensemble->interp_time );
int row_nr,column_nr;
{
char * origin;
char * origin;
util_alloc_file_components( output->file , NULL ,&origin , NULL);
fprintf(stream , "ORIGIN %s\n", origin );
free( origin );
}
/* 1: Writing first header line with variables. */
fprintf(stream , time_header );
for (column_nr = 0; column_nr < data_columns; column_nr++) {
@@ -489,20 +490,20 @@ void output_save_S3Graph( const output_type * output, ensemble_type * ensemble ,
fprintf(stream , unit_fmt , ecl_sum_get_unit( ensemble->refcase , qkey->sum_key ) );
}
fprintf(stream , "\n");
/*3: Writing third header line with WGNAMES / NUMS - extra information -
/*3: Writing third header line with WGNAMES / NUMS - extra information -
breaks completely down with LGR information. */
fprintf(stream , time_blank );
{
for (column_nr = 0; column_nr < data_columns; column_nr++) {
const quant_key_type * qkey = vector_iget( output->keys , column_nr );
const char * ecl_key = qkey->sum_key;
const char * wgname = ecl_sum_get_wgname( ensemble->refcase , ecl_key );
const char * wgname = ecl_sum_get_wgname( ensemble->refcase , ecl_key );
int num = ecl_sum_get_num( ensemble->refcase , ecl_key );
ecl_smspec_var_type var_type = ecl_sum_get_var_type( ensemble->refcase , ecl_key);
bool need_num = ecl_smspec_needs_num( var_type );
bool need_wgname = ecl_smspec_needs_wgname( var_type );
bool need_wgname = ecl_smspec_needs_wgname( var_type );
if (need_num && need_wgname) {
/** Do not know how to include both - will just create a
mangled name as a combination. */
@@ -511,7 +512,7 @@ void output_save_S3Graph( const output_type * output, ensemble_type * ensemble ,
free( wgname_num );
} else if (need_num)
fprintf(stream , num_fmt , num);
else if (need_wgname)
else if (need_wgname)
fprintf(stream , wgname_fmt , wgname);
else
fprintf(stream , empty_fmt );
@@ -528,7 +529,7 @@ void output_save_S3Graph( const output_type * output, ensemble_type * ensemble ,
fprintf(stream , date_fmt , mday , month , year);
}
fprintf(stream , days_fmt , 1.0*(interp_time - ensemble->start_time) / 86400);
for (column_nr = 0; column_nr < data_columns; column_nr++) {
fprintf(stream , float_fmt , data[row_nr][column_nr]);
}
@@ -539,7 +540,7 @@ void output_save_S3Graph( const output_type * output, ensemble_type * ensemble ,
void output_save_plain__( const output_type * output , ensemble_type * ensemble , const double ** data , bool add_header) {
FILE * stream = util_mkdir_fopen( output->file , "w");
FILE * stream = util_mkdir_fopen( output->file , "w");
const char * key_fmt = " %18s:%4.2f ";
const char * time_header = "-- DAYS DATE ";
const char * time_dash = "------------------------";
@@ -560,7 +561,7 @@ void output_save_plain__( const output_type * output , ensemble_type * ensemble
fprintf(stream , "\n");
fprintf( stream , time_dash );
for (int i=0; i < vector_get_size( output->keys ); i++)
for (int i=0; i < vector_get_size( output->keys ); i++)
fprintf(stream , key_dash );
fprintf(stream , "\n");
}
@@ -574,7 +575,7 @@ void output_save_plain__( const output_type * output , ensemble_type * ensemble
util_set_datetime_values(interp_time , NULL , NULL , NULL , &mday , &month , &year);
fprintf(stream , date_fmt , mday , month , year);
}
for (column_nr = 0; column_nr < data_columns; column_nr++) {
fprintf(stream , float_fmt , data[row_nr][column_nr]);
}
@@ -600,13 +601,13 @@ void output_save( const output_type * output , ensemble_type * ensemble , const
util_exit("Sorry: output_format:%d not supported \n", output->format );
}
}
void output_run_line( const output_type * output , ensemble_type * ensemble) {
const int data_columns = vector_get_size( output->keys );
const int data_rows = time_t_vector_size( ensemble->interp_time );
double ** data;
@@ -615,15 +616,15 @@ void output_run_line( const output_type * output , ensemble_type * ensemble) {
data = util_calloc( data_rows , sizeof * data );
/*
time-direction, i.e. the row index is the first index and the
column number (i.e. the different keys) is the second index.
column number (i.e. the different keys) is the second index.
*/
for (row_nr=0; row_nr < data_rows; row_nr++)
data[row_nr] = util_calloc( data_columns , sizeof * data[row_nr] );
printf("Creating output file: %s \n",output->file );
/*
/*
Go through all the cases and check that they have this key;
exit if missing. Could also ignore the missing keys and just
continue; and even defer the checking to the inner loop.
@@ -632,35 +633,35 @@ void output_run_line( const output_type * output , ensemble_type * ensemble) {
const quant_key_type * qkey = vector_iget( output->keys , column_nr );
{
bool OK = true;
for (int iens = 0; iens < vector_get_size( ensemble->data ); iens++) {
const sum_case_type * sum_case = vector_iget_const( ensemble->data , iens );
if (!ecl_sum_has_general_var(sum_case->ecl_sum , qkey->sum_key)) {
OK = false;
fprintf(stderr,"** Sorry: the case:%s does not have the summary key:%s \n", ecl_sum_get_case( sum_case->ecl_sum ), qkey->sum_key);
}
}
if (!OK)
if (!OK)
util_exit("Exiting due to missing summary vector(s).\n");
}
}
/* The main loop - outer loop is running over time. */
{
/**
In the quite typical case that we are asking for several
quantiles of the quantity, i.e.
WWCT:OP_1:0.10 WWCT:OP_1:0.50 WWCT:OP_1:0.90
WWCT:OP_1:0.10 WWCT:OP_1:0.50 WWCT:OP_1:0.90
the interp_data_cache construction will ensure that the
underlying ecl_sum object is only queried once; and also the
sorting will be performed once.
*/
hash_type * interp_data_cache = hash_alloc();
for (row_nr = 0; row_nr < data_rows; row_nr++) {
@@ -680,10 +681,10 @@ void output_run_line( const output_type * output , ensemble_type * ensemble) {
if (double_vector_size( interp_data ) == 0) {
for (int iens = 0; iens < vector_get_size( ensemble->data ); iens++) {
const sum_case_type * sum_case = vector_iget_const( ensemble->data , iens );
if ((interp_time >= sum_case->start_time) && (interp_time <= sum_case->end_time)) /* We allow the different simulations to have differing length */
double_vector_append( interp_data , ecl_sum_get_general_var_from_sim_time( sum_case->ecl_sum , interp_time , qkey->sum_key)) ;
double_vector_sort( interp_data );
}
}
@@ -693,7 +694,7 @@ void output_run_line( const output_type * output , ensemble_type * ensemble) {
}
hash_free( interp_data_cache );
}
output_save( output , ensemble , (const double **) data);
for (row_nr=0; row_nr < data_rows; row_nr++)
free( data[row_nr] );
@@ -717,19 +718,19 @@ void output_table_run( hash_type * output_table , ensemble_type * ensemble ) {
/*****************************************************************/
void config_init( config_type * config ) {
void config_init( config_parser_type * config ) {
config_add_schema_item( config , "CASE_LIST" , true , true );
config_add_schema_item( config , "CASE_LIST" , true );
config_add_key_value( config , "NUM_INTERP" , false , CONFIG_INT);
{
config_schema_item_type * item;
item = config_add_schema_item( config , "OUTPUT" , true , true );
config_schema_item_set_argc_minmax( item , 2 , CONFIG_DEFAULT_ARG_MAX , 0 , NULL );
item = config_add_schema_item( config , "OUTPUT" , true );
config_schema_item_set_argc_minmax( item , 2 , CONFIG_DEFAULT_ARG_MAX );
config_schema_item_set_indexed_selection_set( item , 1 , 3 , (const char *[3]) { S3GRAPH_STRING , HEADER_STRING , PLAIN_STRING });
}
}
@@ -737,7 +738,7 @@ void config_init( config_type * config ) {
void usage() {
fprintf(stderr, "\nUse:\n\n ecl_quantile config_file\n\n");
printf("Help\n");
printf("----\n");
printf("\n");
@@ -786,7 +787,7 @@ void usage() {
printf("\n");
printf(" Q: The quantile we are interested in, e.g 0.10 to get the P10\n");
printf(" quantile and 0.90 to get the P90 quantile.\n");
printf("\n");
printf("\n");
printf(" For the 'VAR' and 'WG?' parts of the keys you can use shell-style\n");
printf(" wildcards to get all summary vectors matching a criteria, i.e. \n");
printf(" 'WOPR:A-*:0.50' will give the P50 quantile of WOPR for all wells \n");
@@ -824,11 +825,14 @@ int main( int argc , char ** argv ) {
hash_type * output_table = hash_alloc();
ensemble_type * ensemble = ensemble_alloc();
{
config_type * config = config_alloc( );
config_parser_type * config = config_alloc( );
config_content_type * content;
const char * config_arg = argv[1];
config_init( config );
if (config_parse( config , config_arg , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_WARN, true )) {
content = config_parse( config , config_arg , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_WARN, true );
if (config_content_is_valid( content )) {
char * config_path;
util_alloc_file_components( config_arg , &config_path , NULL , NULL);
if (config_path != NULL) {
@@ -836,17 +840,18 @@ int main( int argc , char ** argv ) {
free( config_path );
}
} else {
config_fprintf_errors( config , stderr );
config_error_type * error = config_content_get_errors( content );
config_error_fprintf( error , true , stderr );
exit(1);
}
ensemble_init( ensemble , config );
output_table_init( ensemble_get_refcase( ensemble ) , output_table , config);
ensemble_init( ensemble , content );
output_table_init( ensemble_get_refcase( ensemble ) , output_table , content );
config_content_free( content );
config_free( config );
}
}
output_table_run( output_table , ensemble );
ensemble_free( ensemble );
hash_free( output_table );
+1 -2
View File
@@ -1886,8 +1886,7 @@ int main(int argc , char ** argv) {
install_SIGNALS();
//setvbuf(stdout, NULL, _IOFBF, 0);
setenv( "PLPLOT_LIB" , "/project/res/x86_64_RH_5/plplot/plplot-5.10.0/share/plplot5.10.0" , 1);
if(argc > 1){
if(strcmp(argv[1], "-b") == 0 || strcmp(argv[1], "-s") == 0) {
+20 -20
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'kw_list.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'kw_list.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
@@ -32,14 +32,14 @@ void kw_list(const char *filename) {
ecl_kw_type * ecl_kw = ecl_kw_alloc_empty();
bool fmt_file;
if (ecl_util_fmt_file(filename , &fmt_file)) {
printf("-----------------------------------------------------------------\n");
printf("%s: \n",filename);
fortio = fortio_open_reader(filename , fmt_file , ECL_ENDIAN_FLIP);
while( ecl_kw_fread_realloc(ecl_kw , fortio) )
printf("%s: \n",filename);
fortio = fortio_open_reader(filename , fmt_file , ECL_ENDIAN_FLIP);
while( ecl_kw_fread_realloc(ecl_kw , fortio) )
ecl_kw_summarize(ecl_kw);
printf("-----------------------------------------------------------------\n");
ecl_kw_free(ecl_kw);
fortio_fclose(fortio);
} else
+25 -26
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_file.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_file.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __ECL_FILE_H__
@@ -33,7 +33,7 @@ extern "C" {
#include <ert/ecl/ecl_util.h>
typedef enum {
ECL_FILE_CLOSE_STREAM = 1 , /*
ECL_FILE_CLOSE_STREAM = 1 , /*
This flag will close the underlying FILE object between each access; this is
mainly to save filedescriptors in cases where many ecl_file instances are open at
the same time. */
@@ -60,7 +60,6 @@ extern "C" {
void ecl_file_push_block( ecl_file_type * ecl_file );
void ecl_file_pop_block( ecl_file_type * ecl_file );
ecl_file_type * ecl_file_open( const char * filename , int flags);
ecl_file_type * ecl_file_try_open( const char * filename , int flags);
void ecl_file_close( ecl_file_type * ecl_file );
void ecl_file_fortio_detach( ecl_file_type * ecl_file );
void ecl_file_free__(void * arg);
@@ -76,18 +75,18 @@ extern "C" {
ecl_version_enum ecl_file_get_ecl_version( const ecl_file_type * file );
void ecl_file_fwrite_fortio(const ecl_file_type * ec_file , fortio_type * fortio , int offset);
void ecl_file_fwrite(const ecl_file_type * ecl_file , const char * , bool fmt_file );
void ecl_file_replace_kw( ecl_file_type * ecl_file , ecl_kw_type * old_kw , ecl_kw_type * new_kw , bool insert_copy);
int ecl_file_get_phases( const ecl_file_type * init_file );
void ecl_file_fprintf_kw_list( const ecl_file_type * ecl_file , FILE * stream );
bool ecl_file_writable( const ecl_file_type * ecl_file );
int ecl_file_get_flags( const ecl_file_type * ecl_file );
void ecl_file_set_flags( ecl_file_type * ecl_file, int new_flags );
bool ecl_file_flags_set( const ecl_file_type * ecl_file , int flags);
ecl_file_kw_type * ecl_file_iget_file_kw( const ecl_file_type * file , int global_index);
ecl_file_kw_type * ecl_file_iget_named_file_kw( const ecl_file_type * file , const char * kw, int ith);
ecl_kw_type * ecl_file_iget_kw( const ecl_file_type * file , int global_index);
@@ -99,7 +98,7 @@ extern "C" {
int ecl_file_iget_named_size( const ecl_file_type * file , const char * kw , int ith);
void ecl_file_indexed_read(const ecl_file_type * file , const char * kw, int index, const int_vector_type * index_map, char* buffer);
bool ecl_file_subselect_block( ecl_file_type * ecl_file , const char * kw , int occurence);
bool ecl_file_select_block( ecl_file_type * ecl_file , const char * kw , int occurence);
void ecl_file_select_global( ecl_file_type * ecl_file );
@@ -124,13 +123,13 @@ extern "C" {
void ecl_file_close_fortio_stream(ecl_file_type * ecl_file);
ecl_file_type * ecl_file_open_rstblock_report_step( const char * filename , int report_step , int flags);
ecl_file_type * ecl_file_open_rstblock_sim_time( const char * filename , time_t sim_time , int flags);
ecl_file_type * ecl_file_open_rstblock_sim_time( const char * filename , time_t sim_time , int flags);
ecl_file_type * ecl_file_iopen_rstblock( const char * filename , int seqnum_index , int flags);
/*****************************************************************/
/* SUMMARY FILES */
bool ecl_file_select_smryblock( ecl_file_type * ecl_file , int ministep_nr );
ecl_file_type * ecl_file_open_smryblock( const char * filename , int ministep_nr , int flags);
@@ -139,5 +138,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif
#endif
#endif
+1 -1
View File
@@ -49,7 +49,7 @@ typedef struct inv_map_struct inv_map_type;
offset_type ecl_file_kw_get_offset(const ecl_file_kw_type * file_kw);
bool ecl_file_kw_ptr_eq( const ecl_file_kw_type * file_kw , const ecl_kw_type * ecl_kw);
void ecl_file_kw_replace_kw( ecl_file_kw_type * file_kw , fortio_type * target , ecl_kw_type * new_kw );
void ecl_file_kw_fskip_data( const ecl_file_kw_type * file_kw , fortio_type * fortio);
bool ecl_file_kw_fskip_data( const ecl_file_kw_type * file_kw , fortio_type * fortio);
void ecl_file_kw_inplace_fwrite( ecl_file_kw_type * file_kw , fortio_type * fortio);
#ifdef __cplusplus
+38 -38
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_grid.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_grid.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __ECL_GRID_H__
@@ -28,24 +28,24 @@ extern "C" {
#include <ert/util/stringlist.h>
#include <ert/ecl/ecl_coarse_cell.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/grid_dims.h>
#include <ert/ecl/nnc_info.h>
#define ECL_GRID_GLOBAL_GRID "Global" // used as key in hash tables over grids.
#define ECL_GRID_MAINGRID_LGR_NR 0
typedef double (block_function_ftype) ( const double_vector_type *);
typedef double (block_function_ftype) ( const double_vector_type *);
typedef struct ecl_grid_struct ecl_grid_type;
bool ecl_grid_have_coarse_cells( const ecl_grid_type * main_grid );
bool ecl_grid_cell_in_coarse_group1( const ecl_grid_type * main_grid , int global_index );
bool ecl_grid_cell_in_coarse_group3( const ecl_grid_type * main_grid , int i , int j , int k);
bool ecl_grid_cell_in_coarse_group1( const ecl_grid_type * main_grid , int global_index );
bool ecl_grid_cell_in_coarse_group3( const ecl_grid_type * main_grid , int i , int j , int k);
int ecl_grid_get_num_coarse_groups( const ecl_grid_type * main_grid );
ecl_coarse_cell_type * ecl_grid_iget_coarse_group( const ecl_grid_type * ecl_grid , int coarse_nr );
ecl_coarse_cell_type * ecl_grid_get_cell_coarse_group1( const ecl_grid_type * ecl_grid , int global_index);
ecl_coarse_cell_type * ecl_grid_get_cell_coarse_group3( const ecl_grid_type * ecl_grid , int i , int j , int k);
void ecl_grid_get_column_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j, double_vector_type * column);
int ecl_grid_get_global_index_from_xy_top( const ecl_grid_type * ecl_grid , double x , double y);
@@ -55,7 +55,7 @@ extern "C" {
void ecl_grid_get_cell_corner_xyz3(const ecl_grid_type * grid , int i , int j , int k, int corner_nr , double * xpos , double * ypos , double * zpos );
void ecl_grid_get_cell_corner_xyz1(const ecl_grid_type * grid , int global_index , int corner_nr , double * xpos , double * ypos , double * zpos );
void ecl_grid_get_corner_xyz(const ecl_grid_type * grid , int i , int j , int k, double * xpos , double * ypos , double * zpos );
double ecl_grid_get_cell_thickness3( const ecl_grid_type * grid , int i , int j , int k);
double ecl_grid_get_cell_thickness1( const ecl_grid_type * grid , int global_index );
double ecl_grid_get_cdepth1(const ecl_grid_type * grid , int global_index);
@@ -77,14 +77,14 @@ extern "C" {
int ecl_grid_get_active_fracture_index1(const ecl_grid_type * ecl_grid , int global_index);
bool ecl_grid_cell_active3(const ecl_grid_type * , int , int , int );
bool ecl_grid_cell_active1(const ecl_grid_type * , int);
bool ecl_grid_ijk_valid(const ecl_grid_type * , int , int , int );
bool ecl_grid_ijk_valid(const ecl_grid_type * , int , int , int );
int ecl_grid_get_global_index3(const ecl_grid_type * , int , int , int );
int ecl_grid_get_global_index1A(const ecl_grid_type * ecl_grid , int active_index);
int ecl_grid_get_global_index1F(const ecl_grid_type * ecl_grid , int active_fracture_index);
const nnc_info_type * ecl_grid_get_cell_nnc_info3( const ecl_grid_type * grid , int i , int j , int k);
const nnc_info_type * ecl_grid_get_cell_nnc_info1( const ecl_grid_type * grid , int global_index);
const nnc_info_type * ecl_grid_get_cell_nnc_info3( const ecl_grid_type * grid , int i , int j , int k);
const nnc_info_type * ecl_grid_get_cell_nnc_info1( const ecl_grid_type * grid , int global_index);
ecl_grid_type * ecl_grid_alloc_GRDECL_kw( int nx, int ny , int nz , const ecl_kw_type * zcorn_kw , const ecl_kw_type * coord_kw , const ecl_kw_type * actnum_kw , const ecl_kw_type * mapaxes_kw );
ecl_grid_type * ecl_grid_alloc_GRDECL_data(int , int , int , const float * , const float * , const int * , const float * mapaxes);
ecl_grid_type * ecl_grid_alloc_GRID_data(int num_coords , int nx, int ny , int nz , int coords_size , int ** coords , float ** corners , const float * mapaxes);
@@ -94,10 +94,10 @@ extern "C" {
ecl_grid_type * ecl_grid_alloc_regular( int nx, int ny , int nz , const double * ivec, const double * jvec , const double * kvec , const int * actnum);
ecl_grid_type * ecl_grid_alloc_dxv_dyv_dzv( int nx, int ny , int nz , const double * dxv , const double * dyv , const double * dzv , const int * actnum);
ecl_grid_type * ecl_grid_alloc_dxv_dyv_dzv_depthz( int nx, int ny , int nz , const double * dxv , const double * dyv , const double * dzv , const double * depthz , const int * actnum);
bool ecl_grid_exists( const char * case_input );
char * ecl_grid_alloc_case_filename( const char * case_input );
void ecl_grid_free(ecl_grid_type * );
void ecl_grid_free__( void * arg );
grid_dims_type ecl_grid_iget_dims( const ecl_grid_type * grid , int grid_nr);
@@ -118,7 +118,7 @@ extern "C" {
int ecl_grid_get_global_size( const ecl_grid_type * ecl_grid );
bool ecl_grid_compare(const ecl_grid_type * g1 , const ecl_grid_type * g2 , bool include_lgr, bool include_nnc , bool verbose);
int ecl_grid_get_active_size( const ecl_grid_type * ecl_grid );
double ecl_grid_get_bottom1(const ecl_grid_type * grid , int global_index);
double ecl_grid_get_bottom3(const ecl_grid_type * grid , int i, int j , int k);
double ecl_grid_get_bottom1A(const ecl_grid_type * grid , int active_index);
@@ -128,17 +128,17 @@ extern "C" {
double ecl_grid_get_top2(const ecl_grid_type * grid , int i, int j);
double ecl_grid_get_bottom2(const ecl_grid_type * grid , int i, int j);
int ecl_grid_locate_depth( const ecl_grid_type * grid , double depth , int i , int j );
void ecl_grid_alloc_blocking_variables(ecl_grid_type * , int );
void ecl_grid_init_blocking(ecl_grid_type * );
double ecl_grid_block_eval3d(ecl_grid_type * grid , int i, int j , int k ,block_function_ftype * blockf );
int ecl_grid_get_block_count3d(const ecl_grid_type * ecl_grid , int i , int j, int k);
bool ecl_grid_block_value_3d(ecl_grid_type * , double , double ,double , double);
bool ecl_grid_cell_invalid1(const ecl_grid_type * ecl_grid , int global_index);
bool ecl_grid_cell_invalid3(const ecl_grid_type * ecl_grid , int i , int j , int k);
double ecl_grid_cell_invalid1A(const ecl_grid_type * grid , int active_index);
void ecl_grid_dump(const ecl_grid_type * grid , FILE * stream);
void ecl_grid_dump_ascii(ecl_grid_type * grid , bool active_only , FILE * stream);
void ecl_grid_dump_ascii_cell1(ecl_grid_type * grid , int global_index , FILE * stream, const double * offset);
@@ -151,7 +151,7 @@ extern "C" {
int ecl_grid_get_num_lgr(const ecl_grid_type * main_grid );
int ecl_grid_get_lgr_nr( const ecl_grid_type * ecl_grid );
int ecl_grid_get_lgr_nr_from_name( const ecl_grid_type * grid , const char * name);
ecl_grid_type * ecl_grid_iget_lgr(const ecl_grid_type * main_grid , int lgr_index);
ecl_grid_type * ecl_grid_iget_lgr(const ecl_grid_type * main_grid , int lgr_index);
ecl_grid_type * ecl_grid_get_lgr_from_lgr_nr(const ecl_grid_type * main_grid, int lgr_nr);
ecl_grid_type * ecl_grid_get_lgr(const ecl_grid_type * main_grid, const char * __lgr_name);
bool ecl_grid_has_lgr(const ecl_grid_type * main_grid, const char * __lgr_name);
@@ -162,21 +162,21 @@ extern "C" {
int ecl_grid_get_parent_cell3( const ecl_grid_type * grid , int i , int j , int k);
const ecl_grid_type * ecl_grid_get_global_grid( const ecl_grid_type * grid );
bool ecl_grid_is_lgr( const ecl_grid_type * ecl_grid );
double ecl_grid_get_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k);
float ecl_grid_get_float_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k);
double ecl_grid_get_double_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k);
int ecl_grid_get_int_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k);
void ecl_grid_grdecl_fprintf_kw( const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , const char * special_header , FILE * stream , double double_default);
bool ecl_grid_test_lgr_consistency( const ecl_grid_type * ecl_grid );
void ecl_grid_fwrite_EGRID( ecl_grid_type * grid , const char * filename);
void ecl_grid_fwrite_GRID( const ecl_grid_type * grid , const char * filename);
void ecl_grid_fprintf_grdecl( ecl_grid_type * grid , FILE * stream );
void ecl_grid_fwrite_EGRID_header__( int dims[3] , const float mapaxes[6], int dualp_flag , fortio_type * fortio);
void ecl_grid_fwrite_EGRID_header( int dims[3] , const float mapaxes[6], fortio_type * fortio);
float * ecl_grid_alloc_zcorn_data( const ecl_grid_type * grid );
ecl_kw_type * ecl_grid_alloc_zcorn_kw( const ecl_grid_type * grid );
int * ecl_grid_alloc_actnum_data( const ecl_grid_type * grid );
@@ -197,7 +197,7 @@ extern "C" {
void ecl_grid_init_zcorn_data( const ecl_grid_type * grid , float * zcorn );
void ecl_grid_init_zcorn_data_double( const ecl_grid_type * grid , double * zcorn );
int ecl_grid_get_zcorn_size( const ecl_grid_type * grid );
void ecl_grid_init_coord_data( const ecl_grid_type * grid , float * coord );
void ecl_grid_init_coord_data_double( const ecl_grid_type * grid , double * coord );
int ecl_grid_get_coord_size( const ecl_grid_type * ecl_grid);
@@ -209,7 +209,7 @@ extern "C" {
UTIL_IS_INSTANCE_HEADER( ecl_grid );
UTIL_SAFE_CAST_HEADER( ecl_grid );
#ifdef __cplusplus
}
#endif
+46 -47
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_kw.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_kw.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __ECL_KW_H__
@@ -36,15 +36,14 @@ extern "C" {
typedef struct ecl_kw_struct ecl_kw_type;
#define ECL_KW_FORTIO_HEADER_SIZE 4 + ECL_STRING_LENGTH + 4 + ECL_TYPE_LENGTH + 4
size_t ecl_kw_fortio_size( const ecl_kw_type * ecl_kw );
void * ecl_kw_get_ptr(const ecl_kw_type *ecl_kw);
void ecl_kw_set_data_ptr(ecl_kw_type * ecl_kw , void * data);
void ecl_kw_fwrite_data(const ecl_kw_type *_ecl_kw , fortio_type *fortio);
void ecl_kw_fread_realloc_data(ecl_kw_type *ecl_kw, fortio_type *fortio);
bool ecl_kw_fread_realloc_data(ecl_kw_type *ecl_kw, fortio_type *fortio);
ecl_type_enum ecl_kw_get_type(const ecl_kw_type *);
const char * ecl_kw_get_header8(const ecl_kw_type *);
const char * ecl_kw_get_header8(const ecl_kw_type *);
const char * ecl_kw_get_header(const ecl_kw_type * ecl_kw );
ecl_kw_type * ecl_kw_alloc_empty();
bool ecl_kw_fread_header(ecl_kw_type *, fortio_type *);
@@ -104,31 +103,31 @@ extern "C" {
bool ecl_kw_block_equal( const ecl_kw_type * ecl_kw1 , const ecl_kw_type * ecl_kw2 , int cmp_elements);
bool ecl_kw_data_equal( const ecl_kw_type * ecl_kw , const void * data);
bool ecl_kw_content_equal( const ecl_kw_type * ecl_kw1 , const ecl_kw_type * ecl_kw2);
void ecl_kw_fskip_data__( ecl_type_enum ecl_type , int size , fortio_type * fortio);
void ecl_kw_fskip_data(ecl_kw_type *ecl_kw, fortio_type *fortio);
void ecl_kw_fread_data(ecl_kw_type *ecl_kw, fortio_type *fortio);
bool ecl_kw_fskip_data__( ecl_type_enum ecl_type , int size , fortio_type * fortio);
bool ecl_kw_fskip_data(ecl_kw_type *ecl_kw, fortio_type *fortio);
bool ecl_kw_fread_data(ecl_kw_type *ecl_kw, fortio_type *fortio);
void ecl_kw_fskip_header( fortio_type * fortio);
bool ecl_kw_is_grdecl_file(FILE * );
bool ecl_kw_is_kw_file(FILE * , bool );
bool ecl_kw_is_kw_file(fortio_type * fortio);
int ecl_kw_element_sum_int( const ecl_kw_type * ecl_kw );
double ecl_kw_element_sum_float( const ecl_kw_type * ecl_kw );
void ecl_kw_inplace_inv(ecl_kw_type * my_kw);
void ecl_kw_element_sum(const ecl_kw_type * , void * );
void ecl_kw_max_min(const ecl_kw_type * , void * , void *);
void * ecl_kw_get_void_ptr(const ecl_kw_type * ecl_kw);
ecl_kw_type * ecl_kw_buffer_alloc(buffer_type * buffer);
void ecl_kw_buffer_store(const ecl_kw_type * ecl_kw , buffer_type * buffer);
void ecl_kw_fprintf_data( const ecl_kw_type * ecl_kw , const char * fmt , FILE * stream);
void ecl_kw_memcpy_data( ecl_kw_type * target , const ecl_kw_type * src);
bool ecl_kw_assert_numeric( const ecl_kw_type * kw );
bool ecl_kw_assert_binary( const ecl_kw_type * kw1, const ecl_kw_type * kw2);
void ecl_kw_scalar_set_bool( ecl_kw_type * ecl_kw , bool bool_value);
void ecl_kw_scalar_set__(ecl_kw_type * ecl_kw , const void * value);
void ecl_kw_scalar_set_float_or_double( ecl_kw_type * ecl_kw , double value );
@@ -139,9 +138,9 @@ extern "C" {
ECL_KW_SCALAR_SET_TYPED_HEADER( float )
ECL_KW_SCALAR_SET_TYPED_HEADER( double )
#undef ECL_KW_SCALAR_SET_TYPED_HEADER
ecl_kw_type * ecl_kw_alloc_scatter_copy( const ecl_kw_type * src_kw , int target_size , const int * mapping, void * def_value);
void ecl_kw_inplace_add( ecl_kw_type * target_kw , const ecl_kw_type * add_kw);
void ecl_kw_inplace_sub( ecl_kw_type * target_kw , const ecl_kw_type * sub_kw);
void ecl_kw_inplace_div( ecl_kw_type * target_kw , const ecl_kw_type * div_kw);
@@ -152,68 +151,68 @@ extern "C" {
void ecl_kw_inplace_mul_indexed( ecl_kw_type * target_kw , const int_vector_type * index_set , const ecl_kw_type * mul_kw);
void ecl_kw_inplace_div_indexed( ecl_kw_type * target_kw , const int_vector_type * index_set , const ecl_kw_type * div_kw);
void ecl_kw_copy_indexed( ecl_kw_type * target_kw , const int_vector_type * index_set , const ecl_kw_type * src_kw);
bool ecl_kw_assert_binary_numeric( const ecl_kw_type * kw1, const ecl_kw_type * kw2);
#define ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER( ctype ) bool ecl_kw_assert_binary_ ## ctype( const ecl_kw_type * kw1 , const ecl_kw_type * kw2)
ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER( int );
ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER( float );
ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER( double );
#undef ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER
#define ECL_KW_SCALE_TYPED_HEADER( ctype ) void ecl_kw_scale_ ## ctype (ecl_kw_type * ecl_kw , ctype scale_factor)
ECL_KW_SCALE_TYPED_HEADER( int );
ECL_KW_SCALE_TYPED_HEADER( float );
ECL_KW_SCALE_TYPED_HEADER( double );
#undef ECL_KW_SCALE_TYPED_HEADER
void ecl_kw_scale_float_or_double( ecl_kw_type * ecl_kw , double scale_factor );
#define ECL_KW_SHIFT_TYPED_HEADER( ctype ) void ecl_kw_shift_ ## ctype (ecl_kw_type * ecl_kw , ctype shift_factor)
ECL_KW_SHIFT_TYPED_HEADER( int );
ECL_KW_SHIFT_TYPED_HEADER( float );
ECL_KW_SHIFT_TYPED_HEADER( double );
#undef ECL_KW_SHIFT_TYPED_HEADER
void ecl_kw_shift_float_or_double( ecl_kw_type * ecl_kw , double shift_value );
#define ECL_KW_IGET_TYPED_HEADER(type) type ecl_kw_iget_ ## type(const ecl_kw_type * , int)
ECL_KW_IGET_TYPED_HEADER(double);
ECL_KW_IGET_TYPED_HEADER(float);
ECL_KW_IGET_TYPED_HEADER(int);
#undef ECL_KW_IGET_TYPED_HEADER
bool ecl_kw_iget_bool( const ecl_kw_type * ecl_kw , int i );
#define ECL_KW_ISET_TYPED_HEADER(type) void ecl_kw_iset_ ## type(ecl_kw_type * , int , type )
ECL_KW_ISET_TYPED_HEADER(double);
ECL_KW_ISET_TYPED_HEADER(float);
ECL_KW_ISET_TYPED_HEADER(int);
#undef ECL_KW_ISET_TYPED_HEADER
void ecl_kw_iset_bool( ecl_kw_type * ecl_kw , int i , bool bool_value);
#define ECL_KW_GET_TYPED_PTR_HEADER(type) type * ecl_kw_get_ ## type ## _ptr(const ecl_kw_type *)
ECL_KW_GET_TYPED_PTR_HEADER(double);
ECL_KW_GET_TYPED_PTR_HEADER(float);
ECL_KW_GET_TYPED_PTR_HEADER(int);
ECL_KW_GET_TYPED_PTR_HEADER(bool);
#undef ECL_KW_GET_TYPED_PTR_HEADER
#define ECL_KW_SET_INDEXED_HEADER(ctype ) void ecl_kw_set_indexed_ ## ctype( ecl_kw_type * ecl_kw, const int_vector_type * index_list , ctype value)
ECL_KW_SET_INDEXED_HEADER( double );
ECL_KW_SET_INDEXED_HEADER( float );
ECL_KW_SET_INDEXED_HEADER( int );
#undef ECL_KW_SET_INDEXED_HEADER
#define ECL_KW_SHIFT_INDEXED_HEADER(ctype) void ecl_kw_shift_indexed_ ## ctype( ecl_kw_type * ecl_kw, const int_vector_type * index_list , ctype shift)
ECL_KW_SHIFT_INDEXED_HEADER( int );
ECL_KW_SHIFT_INDEXED_HEADER( float );
ECL_KW_SHIFT_INDEXED_HEADER( double );
#undef ECL_KW_SHIFT_INDEXED_HEADER
#define ECL_KW_SCALE_INDEXED_HEADER(ctype) void ecl_kw_scale_indexed_ ## ctype( ecl_kw_type * ecl_kw, const int_vector_type * index_list , ctype scale)
ECL_KW_SCALE_INDEXED_HEADER( int );
ECL_KW_SCALE_INDEXED_HEADER( float );
@@ -226,9 +225,9 @@ extern "C" {
ECL_KW_MAX_MIN_HEADER( float );
ECL_KW_MAX_MIN_HEADER( double );
#undef ECL_KW_MAX_MIN_HEADER
#include <ert/ecl/ecl_kw_grdecl.h>
#ifdef __cplusplus
}
#endif
+56 -55
View File
@@ -5,7 +5,7 @@
extern "C" {
#endif
/*
/*
This header file contains names and indices of ECLIPSE keywords
which have special significance in various files. Observe that many
of the keywords like e.g. INTEHEAD occur in many different file
@@ -24,37 +24,37 @@ extern "C" {
#define DOUBHEAD_KW "DOUBHEAD"
#define RPORV_KW "RPORV"
#define PORV_KW "PORV"
#define PORMOD_KW "PORV_MOD"
#define PORMOD_KW "PORV_MOD"
#define PVTNUM_KW "PVTNUM"
#define LGRHEADI_KW "LGRHEADI"
#define LGRHEADI_LGR_NR_INDEX 0
#define LGRJOIN_KW "LGRJOIN"
#define LGRJOIN_KW "LGRJOIN"
/*
/*
Observe that many of the elements in the INTEHEAD keyword is shared
between the restart and init files. The ones listed below here are
in both the INIT and the restart files. In addition the restart
files have many well related items which are only in the restart
files.
*/
#define INTEHEAD_UNIT_INDEX 2
#define INTEHEAD_NX_INDEX 8
#define INTEHEAD_NY_INDEX 9
#define INTEHEAD_NZ_INDEX 10
#define INTEHEAD_NACTIVE_INDEX 11
#define INTEHEAD_PHASE_INDEX 14
#define INTEHEAD_DAY_INDEX 64
#define INTEHEAD_MONTH_INDEX 65
#define INTEHEAD_YEAR_INDEX 66
#define INTEHEAD_IPROG_INDEX 94
#define INTEHEAD_UNIT_INDEX 2
#define INTEHEAD_NX_INDEX 8
#define INTEHEAD_NY_INDEX 9
#define INTEHEAD_NZ_INDEX 10
#define INTEHEAD_NACTIVE_INDEX 11
#define INTEHEAD_PHASE_INDEX 14
#define INTEHEAD_DAY_INDEX 64
#define INTEHEAD_MONTH_INDEX 65
#define INTEHEAD_YEAR_INDEX 66
#define INTEHEAD_IPROG_INDEX 94
#define INTEHEAD_METRIC_VALUE 1
#define INTEHEAD_ECLIPSE100_VALUE 100
#define INTEHEAD_ECLIPSE300_VALUE 300
#define INTEHEAD_ECLIPSE300_VALUE 300
#define INTEHEAD_ECLIPSE300THERMAL_VALUE 500
#define INTEHEAD_INIT_SIZE 95
@@ -63,18 +63,18 @@ extern "C" {
#define LOGIHEAD_ECLIPSE300_RADIAL_INDEX 3
#define LOGIHEAD_ECLIPSE100_RADIAL_INDEX 4
#define LOGIHEAD_DUALP_INDEX 14
#define LOGIHEAD_INIT_SIZE 80
#define LOGIHEAD_INIT_SIZE 80
#define LOGIHEAD_RESTART_SIZE 15
#define LOGIHEAD_RS_INDEX 0
#define LOGIHEAD_RS_INDEX 0
#define LOGIHEAD_RV_INDEX 1
#define LOGIHEAD_DIR_RELPERM_INDEX 2
#define LOGIHEAD_DIR_RELPERM_INDEX 2
/*-----------------------------------------------------------------*/
#define LOGIHEAD_REV_RELPERM100_INDEX 3 /* The indices for reversible relperm and */
#define LOGIHEAD_RADIAL100_INDEX 4 /* use of radial grids is interchanged between */
#define LOGIHEAD_REV_RELPERM300_INDEX 4 /* ECLIPSE100 and ECLIPSE300. */
#define LOGIHEAD_RADIAL300_INDEX 3
#define LOGIHEAD_RADIAL300_INDEX 3
/*-----------------------------------------------------------------*/
#define LOGIHEAD_HYSTERISIS_INDEX 6
#define LOGIHEAD_DUALP_INDEX 14
@@ -82,7 +82,7 @@ extern "C" {
#define LOGIHEAD_DIR_ENDPOINT_SCALING_INDEX 17
#define LOGIHEAD_REV_ENDPOINT_SCALING_INDEX 18
#define LOGIHEAD_ALT_ENDPOINT_SCALING_INDEX 19
#define LOGIHEAD_MISC_DISPLACEMENT_INDEX 35
#define LOGIHEAD_MISC_DISPLACEMENT_INDEX 35
#define LOGIHEAD_SCALE_WATER_PC_AT_MAX_SAT_INDEX 55
#define LOGIHEAD_SCALE_GAS_PC_AT_MAX_SAT_INDEX 56
@@ -101,7 +101,7 @@ extern "C" {
present in non-unified files, where the report
step must be inferred from the filename. */
#define STARTSOL_KW "STARTSOL"
#define ENDSOL_KW "ENDSOL"
#define ENDSOL_KW "ENDSOL"
#define IWEL_KW "IWEL"
#define ZWEL_KW "ZWEL"
@@ -120,12 +120,12 @@ extern "C" {
#define FIPGAS_KW "FIPGAS"
#define FIPWAT_KW "FIPWAT"
#define FIPOIL_KW "FIPOIL"
#define FIPOIL_KW "FIPOIL"
#define RFIPGAS_KW "RFIPGAS"
#define RFIPWAT_KW "RFIPWAT"
#define RFIPOIL_KW "RFIPOIL"
#define RFIPOIL_KW "RFIPOIL"
#define INTEHEAD_NWELLS_INDEX 16 // Number of wells
#define INTEHEAD_NIWELZ_INDEX 24 // Number of elements pr. well in the IWEL array.
#define INTEHEAD_NZWELZ_INDEX 27 // Number of 8 character words pr. well
@@ -193,7 +193,7 @@ extern "C" {
#define RESTART_KW "RESTART"
#define SUMMARY_RESTART_SIZE 8
/*
/*
There are no magic indices in the summary data files, for all
interesting data the table created from the ecl_smspec file must be
consulted.
@@ -210,7 +210,7 @@ extern "C" {
special information for SEGMENT data is not internalized at all,
and there are also several additional keywords for the PLTs which
are not internalized. */
/* Common keywords */
#define TIME_KW "TIME" /* The days since simulation start when
@@ -223,6 +223,7 @@ extern "C" {
#define CONIPOS_KW "CONIPOS" /* The i-index of the connections in the well. */
#define CONJPOS_KW "CONJPOS" /* The j-index ... */
#define CONKPOS_KW "CONKPOS" /* The k-index ... */
#define HOSTGRID_KW "HOSTGRID"
/* RFT keywords */
#define SWAT_KW "SWAT" /* The kewyord containing SWAT. */
@@ -236,12 +237,12 @@ extern "C" {
#define CONGRAT_KW "CONGRAT" /* Gas ... */
#define CONORAT_KW "CONORAT" /* Oil ... */
#define CONPRES_KW "CONPRES" /* Pressure ... */
#define CONLENST_KW "CONLENST" /* Length along MSW well */
#define CONLENEN_KW "CONLENEN" /* Length to connection end for MSW well */
#define CONVTUB_KW "CONVTUB" /* Volumetric flow at tubing head conditions. */
#define CONOTUB_KW "CONOTUB" /* Volumetric oil flow at tubing head conditions. */
#define CONGTUB_KW "CONGTUB" /* Volumetric gas flow at tubing head conditions. */
#define CONWTUB_KW "CONWTUB" /* Volumetric water flow at tubing head conditions. */
#define CONLENST_KW "CONLENST" /* Length along MSW well */
#define CONLENEN_KW "CONLENEN" /* Length to connection end for MSW well */
#define CONVTUB_KW "CONVTUB" /* Volumetric flow at tubing head conditions. */
#define CONOTUB_KW "CONOTUB" /* Volumetric oil flow at tubing head conditions. */
#define CONGTUB_KW "CONGTUB" /* Volumetric gas flow at tubing head conditions. */
#define CONWTUB_KW "CONWTUB" /* Volumetric water flow at tubing head conditions. */
#define WELLETC_TYPE_INDEX 5 /* At this keyword the WELLETC keyword contains a string
@@ -263,32 +264,32 @@ extern "C" {
/* GRID and EGRID files have very different structure, and only a few
keywords are shared. */
/* Common keywords */
#define SPECGRID_KW "SPECGRID"
#define SPECGRID_NX_INDEX 0
#define SPECGRID_NY_INDEX 1
#define SPECGRID_NZ_INDEX 2
#define SPECGRID_NX_INDEX 0
#define SPECGRID_NY_INDEX 1
#define SPECGRID_NZ_INDEX 2
#define MAPAXES_KW "MAPAXES" /* Keyword used to transform from grid coordinates to
world coordinates. */
#define LGR_KW "LGR" /* Name of LGR; for GRID files it can contain two elements,
#define LGR_KW "LGR" /* Name of LGR; for GRID files it can contain two elements,
the second element will be the name of the parent. */
#define MAPUNITS_KW "MAPUNITS"
#define GRIDUNIT_KW "GRIDUNIT"
#define NNCHEAD_KW "NNCHEAD" /*Non-neighbour connection header*/
#define NNC1_KW "NNC1" /*Upstream cell numbers for non-neighbour connections*/
#define NNC2_KW "NNC2" /*Downstream cell numbers for non-neighbour connections*/
#define NNCL_KW "NNCL" /*Cell numbers for LGR cells that are connected to global grid cells*/
#define NNCG_KW "NNCG" /*Cell numbers for global cells connected to LGR cells*/
#define NNCHEAD_KW "NNCHEAD" /*Non-neighbour connection header*/
#define NNC1_KW "NNC1" /*Upstream cell numbers for non-neighbour connections*/
#define NNC2_KW "NNC2" /*Downstream cell numbers for non-neighbour connections*/
#define NNCL_KW "NNCL" /*Cell numbers for LGR cells that are connected to global grid cells*/
#define NNCG_KW "NNCG" /*Cell numbers for global cells connected to LGR cells*/
#define NNCHEAD_NUMNNC_INDEX 0 /*Item 1 in non-neighbour connection header: number of NNCs. Only present for main grid*/
#define NNCHEAD_LGR_INDEX 1 /*Item 2 in non-neighbour connection header: LGR number (0 for global grid)*/
#define NNCHEADA_KW "NNCHEADA" /*Header for NNC's between two amalgamated LGRs*/
#define NNA1_KW "NNA1" /*Cell numbers in connecting local grid ILOC1*/
#define NNA1_KW "NNA1" /*Cell numbers in connecting local grid ILOC1*/
#define NNA2_KW "NNA2" /*Cell numbers in connecting local grid ILOC2*/
#define NNCHEADA_ILOC1_INDEX 0 /*ILOC1: Index of first LGR*/
#define NNCHEADA_ILOC2_INDEX 1 /*ILOC2: Index of second LGR*/
#define NNA_NUMNNC_INDEX 0 /*Item 1 in NNA1 or NNA2 is number of NNCs*/
#define NNA_NUMNNC_INDEX 0 /*Item 1 in NNA1 or NNA2 is number of NNCs*/
#define TRANNNC_KW "TRANNNC"
#define TRANGL_KW "TRANGL"
@@ -305,7 +306,7 @@ extern "C" {
#define ENDGRID_KW "ENDGRID"
#define ENDLGR_KW "ENDLGR"
#define CORSNUM_KW "CORSNUM"
/* GRID keywords */
#define GRIDHEAD_KW "GRIDHEAD" /* Header information for GRID files. */
#define COORD_KW "COORD" /* Header information for one cell in GRID file. */
@@ -321,7 +322,7 @@ extern "C" {
#define GRIDHEAD_NZ_INDEX 3
#define GRIDHEAD_LGR_INDEX 4
#define GRIDHEAD_SIZE 100
/* Observe that these indices are one value lower than the values used
in the ecl_smspec file. */
#define DIMENS_NX_INDEX 0
@@ -340,15 +341,15 @@ extern "C" {
#define FILEHEAD_GRIDTYPE_CORNERPOINT 0 /* <----/ */
#define FILEHEAD_ORGTYPE_CORNERPOINT 1
#define FILEHEAD_SINGLE_POROSITY 0
#define FILEHEAD_DUAL_POROSITY 1
#define FILEHEAD_DUAL_PERMEABILITY 2
#define FILEHEAD_SINGLE_POROSITY 0
#define FILEHEAD_DUAL_POROSITY 1
#define FILEHEAD_DUAL_PERMEABILITY 2
#define CELL_NOT_ACTIVE 0
#define CELL_NOT_ACTIVE 0
#define CELL_ACTIVE_MATRIX 1
#define CELL_ACTIVE CELL_ACTIVE_MATRIX
#define CELL_ACTIVE_FRACTURE 2
#define CELL_ACTIVE CELL_ACTIVE_MATRIX
#define CELL_ACTIVE_FRACTURE 2
+21 -17
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'ecl_nnc_export.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2013 Statoil ASA, Norway.
The file 'ecl_nnc_export.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
@@ -24,10 +24,14 @@
extern "C" {
#endif
#include <math.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_kw.h>
#define ERT_ECL_DEFAULT_NNC_TRANS HUGE_VAL
typedef struct {
int grid_nr1;
int global_index1;
@@ -39,8 +43,8 @@ typedef struct {
int ecl_nnc_export_get_size( const ecl_grid_type * grid );
void ecl_nnc_export( const ecl_grid_type * grid , const ecl_file_type * init_file , ecl_nnc_type * nnc_data);
int ecl_nnc_export( const ecl_grid_type * grid , const ecl_file_type * init_file , ecl_nnc_type * nnc_data);
ecl_kw_type * ecl_nnc_export_get_tranx_kw( const ecl_grid_type * grid , const ecl_file_type * init_file , int lgr_nr1, int lgr_nr2 );
ecl_kw_type * ecl_nnc_export_get_tranll_kw( const ecl_grid_type * grid , const ecl_file_type * init_file , int lgr_nr1, int lgr_nr2 );
ecl_kw_type * ecl_nnc_export_get_tran_kw( const ecl_file_type * init_file , const char * kw , int lgr_nr );
+20 -17
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_rft_file.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_rft_file.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __ECL_RFT_FILE_H__
@@ -26,13 +26,15 @@ extern "C" {
#include <ert/util/stringlist.h>
#include <ert/ecl/ecl_rft_node.h>
#include <ert/util/vector.h>
#include <ert/util/int_vector.h>
typedef struct ecl_rft_file_struct ecl_rft_file_type;
char * ecl_rft_file_alloc_case_filename(const char * case_input );
const char * ecl_rft_file_get_filename( const ecl_rft_file_type * rft_file );
ecl_rft_file_type * ecl_rft_file_alloc_case(const char * case_input );
bool ecl_rft_file_case_has_rft(const char * case_input );
ecl_rft_file_type * ecl_rft_file_alloc_case(const char * case_input );
bool ecl_rft_file_case_has_rft(const char * case_input );
bool ecl_rft_file_case_has_rft( const char * case_input );
ecl_rft_file_type * ecl_rft_file_alloc(const char * );
void ecl_rft_file_free(ecl_rft_file_type * );
@@ -51,6 +53,7 @@ int ecl_rft_file_get_well_occurences( const ecl_rft_file_t
stringlist_type * ecl_rft_file_alloc_well_list(const ecl_rft_file_type * rft_file );
int ecl_rft_file_get_num_wells( const ecl_rft_file_type * rft_file );
void ecl_rft_file_free__( void * arg);
void ecl_rft_file_update(const char * rft_file_name, ecl_rft_node_type ** nodes,int num_nodes, ert_ecl_unit_enum unit_set);
#ifdef __cplusplus
}
+23 -18
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_rft_node.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_rft_node.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __ECL_RFT_NODE_H__
@@ -26,8 +26,8 @@ extern "C" {
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_rft_cell.h>
typedef enum { RFT = 1 ,
PLT = 2 ,
typedef enum { RFT = 1 ,
PLT = 2 ,
SEGMENT = 3 /* Not really implemented */ } ecl_rft_enum;
typedef struct ecl_rft_node_struct ecl_rft_node_type;
@@ -38,7 +38,6 @@ const ecl_rft_cell_type * ecl_rft_node_iget_cell( const ecl_rft_node_type * rft_
const ecl_rft_cell_type * ecl_rft_node_lookup_ijk( const ecl_rft_node_type * rft_node , int i, int j , int k);
void ecl_rft_node_fprintf_rft_obs(const ecl_rft_node_type * , double , const char * , const char * , double );
ecl_rft_node_type * ecl_rft_node_alloc(const ecl_file_type * file_map );
const char * ecl_rft_node_get_well_name(const ecl_rft_node_type * );
void ecl_rft_node_free(ecl_rft_node_type * );
void ecl_rft_node_free__(void * );
time_t ecl_rft_node_get_date(const ecl_rft_node_type * );
@@ -60,6 +59,12 @@ double ecl_rft_node_iget_orat( const ecl_rft_node_type * rft_node , int index);
double ecl_rft_node_iget_swat( const ecl_rft_node_type * rft_node , int index);
double ecl_rft_node_iget_sgas( const ecl_rft_node_type * rft_node , int index);
double ecl_rft_node_iget_soil( const ecl_rft_node_type * rft_node , int index);
void ecl_rft_node_fwrite(const ecl_rft_node_type * rft_node, fortio_type * fortio, ert_ecl_unit_enum unit_set);
double ecl_rft_node_get_days(const ecl_rft_node_type * rft_node );
int ecl_rft_node_cmp( const ecl_rft_node_type * n1 , const ecl_rft_node_type * n2);
void ecl_rft_node_append_cell( ecl_rft_node_type * rft_node , ecl_rft_cell_type * cell);
ecl_rft_node_type * ecl_rft_node_alloc_new(const char * well_name, const char * data_type_string, const time_t recording_date, const double days);
#ifdef __cplusplus
}
+6 -2
View File
@@ -20,12 +20,15 @@
#ifndef __ECL_RST_FILE_H__
#define __ECL_RST_FILE_H__
#include <ert/ecl/ecl_rsthead.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ecl_rst_file_struct ecl_rst_file_type;
typedef struct ecl_rst_file_struct ecl_rst_file_type;
ecl_rst_file_type * ecl_rst_file_open_read( const char * filename );
ecl_rst_file_type * ecl_rst_file_open_write( const char * filename );
@@ -34,9 +37,10 @@ extern "C" {
void ecl_rst_file_start_solution( ecl_rst_file_type * rst_file );
void ecl_rst_file_end_solution( ecl_rst_file_type * rst_file );
void ecl_rst_file_fwrite_header( ecl_rst_file_type * rst_file , int seqnum , time_t date , double days , int nx , int ny ,int nz , int nactive , int phases);
void ecl_rst_file_fwrite_header( ecl_rst_file_type * rst_file , int seqnum, ecl_rsthead_type * rsthead_data );
void ecl_rst_file_add_kw(ecl_rst_file_type * rst_file , const ecl_kw_type * ecl_kw );
#ifdef __cplusplus
}
#endif
+26 -24
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_RSTHEAD.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_RSTHEAD.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __ECL_RSTHEAD_H__
@@ -36,7 +36,7 @@ extern "C" {
time_t sim_time;
int version; // 100, 300, 500 (Eclipse300-Thermal)
int phase_sum; // Oil = 1 Gas = 2 Water = 4
int nx;
int ny;
int nz;
@@ -50,26 +50,26 @@ extern "C" {
// Pure well properties
int nwells; // Number of wells
int niwelz; // Number of elements pr well in IWEL array
int nzwelz; // Number of 8 character words pr well in ZWEL array
int niwelz; // Number of elements pr well in IWEL array
int nzwelz; // Number of 8 character words pr well in ZWEL array
// Connection properties
int niconz; // Number of elements per completion in ICON array
int niconz; // Number of elements per completion in ICON array
int ncwmax; // Maximum number of completions per well
int nsconz; // Number of elements per completion in SCON array
// Segment properties
int nisegz; // Number of entries pr segment in the ISEG array
int nsegmx; // The maximum number of segments pr well
int nswlmx; // The maximum number of segmented wells
int nisegz; // Number of entries pr segment in the ISEG array
int nsegmx; // The maximum number of segments pr well
int nswlmx; // The maximum number of segmented wells
int nlbrmx; // The maximum number of lateral branches pr well
int nilbrz; // The number of entries pr segment in ILBR array
int nilbrz; // The number of entries pr segment in ILBR array
int nrsegz; // The number of entries pr segment in RSEG array
// Properteies from the LOGIHEAD keyword:
bool dualp;
// Properties from the DOUBHEAD keyword:
double sim_days;
} ecl_rsthead_type;
@@ -79,10 +79,12 @@ extern "C" {
void ecl_rsthead_free( ecl_rsthead_type * rsthead );
ecl_rsthead_type * ecl_rsthead_ialloc( const ecl_file_type * rst_file , int occurence);
ecl_rsthead_type * ecl_rsthead_alloc( const ecl_file_type * rst_file );
ecl_rsthead_type * ecl_rsthead_alloc_empty();
time_t ecl_rsthead_date( const ecl_kw_type * intehead_kw );
void ecl_rsthead_fprintf( const ecl_rsthead_type * header , FILE * stream);
void ecl_rsthead_fprintf_struct( const ecl_rsthead_type * header , FILE * stream);
bool ecl_rsthead_equal( const ecl_rsthead_type * header1 , const ecl_rsthead_type * header2);
double ecl_rsthead_get_sim_days( const ecl_rsthead_type * header );
#ifdef __cplusplus
}
+2 -1
View File
@@ -46,7 +46,7 @@ typedef struct ecl_smspec_struct ecl_smspec_type;
const int_vector_type * ecl_smspec_get_index_map( const ecl_smspec_type * smspec );
void ecl_smspec_index_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node);
void ecl_smspec_insert_node(ecl_smspec_type * ecl_smspec, smspec_node_type * smspec_node);
void ecl_smspec_add_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node );
void ecl_smspec_add_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node );
ecl_smspec_var_type ecl_smspec_iget_var_type( const ecl_smspec_type * smspec , int index );
bool ecl_smspec_needs_num( ecl_smspec_var_type var_type );
bool ecl_smspec_needs_wgname( ecl_smspec_var_type var_type );
@@ -133,6 +133,7 @@ typedef struct ecl_smspec_struct ecl_smspec_type;
const int * ecl_smspec_get_grid_dims( const ecl_smspec_type * smspec );
int ecl_smspec_get_params_size( const ecl_smspec_type * smspec );
int ecl_smspec_num_nodes( const ecl_smspec_type * smspec);
const smspec_node_type * ecl_smspec_iget_node( const ecl_smspec_type * smspec , int index );
void ecl_smspec_lock( ecl_smspec_type * smspec );
+3 -3
View File
@@ -136,9 +136,9 @@ typedef struct ecl_sum_struct ecl_sum_type;
const char * ecl_sum_get_general_var_unit( const ecl_sum_type * ecl_sum , const char * var);
/***************/
void ecl_sum_fprintf(const ecl_sum_type * , FILE * , const stringlist_type * , bool report_only , const ecl_sum_fmt_type * fmt);
/* Time related functions */
int ecl_sum_get_first_gt( const ecl_sum_type * ecl_sum , int param_index , double limit);
+30 -28
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_sum_data.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_sum_data.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __ECL_SUM_DATA_H__
@@ -33,11 +33,12 @@ extern "C" {
#include <ert/ecl/ecl_sum_tstep.h>
#include <ert/ecl/smspec_node.h>
#include <ert/ecl/ecl_sum_vector.h>
typedef struct ecl_sum_data_struct ecl_sum_data_type ;
typedef struct ecl_sum_data_struct ecl_sum_data_type ;
void ecl_sum_data_fwrite_step( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case , bool unified, int report_step);
void ecl_sum_data_fwrite( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case , bool unified);
void ecl_sum_data_fread( ecl_sum_data_type * data , const stringlist_type * filelist);
bool ecl_sum_data_fread( ecl_sum_data_type * data , const stringlist_type * filelist);
void ecl_sum_data_fread_restart( ecl_sum_data_type * data , const stringlist_type * filelist);
ecl_sum_data_type * ecl_sum_data_alloc_writer( ecl_smspec_type * smspec );
ecl_sum_data_type * ecl_sum_data_alloc( ecl_smspec_type * smspec);
@@ -51,32 +52,32 @@ typedef struct ecl_sum_data_struct ecl_sum_data_type ;
void ecl_sum_data_init_data_vector( const ecl_sum_data_type * data , double_vector_type * data_vector , int data_index , bool report_only);
void ecl_sum_data_init_time_vector( const ecl_sum_data_type * data , time_t_vector_type * time_vector , bool report_only);
time_t_vector_type * ecl_sum_data_alloc_time_vector( const ecl_sum_data_type * data , bool report_only);
time_t ecl_sum_data_get_data_start( const ecl_sum_data_type * data );
time_t ecl_sum_data_get_data_start( const ecl_sum_data_type * data );
time_t ecl_sum_data_get_report_time( const ecl_sum_data_type * data , int report_step);
double ecl_sum_data_get_first_day( const ecl_sum_data_type * data);
const time_interval_type * ecl_sum_data_get_sim_time( const ecl_sum_data_type * data);
time_t ecl_sum_data_get_sim_start ( const ecl_sum_data_type * data );
time_t ecl_sum_data_get_sim_end ( const ecl_sum_data_type * data );
double ecl_sum_data_get_sim_length( const ecl_sum_data_type * data );
time_t ecl_sum_data_get_sim_start ( const ecl_sum_data_type * data );
time_t ecl_sum_data_get_sim_end ( const ecl_sum_data_type * data );
double ecl_sum_data_get_sim_length( const ecl_sum_data_type * data );
void ecl_sum_data_summarize(const ecl_sum_data_type * data , FILE * stream);
double ecl_sum_data_iget( const ecl_sum_data_type * data , int internal_index , int params_index );
double ecl_sum_data_iget_sim_days( const ecl_sum_data_type * , int );
time_t ecl_sum_data_iget_sim_time( const ecl_sum_data_type * , int );
bool ecl_sum_data_has_report_step(const ecl_sum_data_type * , int );
ecl_sum_data_type * ecl_sum_data_fread_alloc( ecl_smspec_type * , const stringlist_type * filelist , bool include_restart);
void ecl_sum_data_free( ecl_sum_data_type * );
int ecl_sum_data_get_last_report_step( const ecl_sum_data_type * data );
int ecl_sum_data_get_first_report_step( const ecl_sum_data_type * data );
int ecl_sum_data_get_first_ministep( const ecl_sum_data_type * data );
int ecl_sum_data_get_last_ministep( const ecl_sum_data_type * data );
double ecl_sum_data_get_from_sim_time( const ecl_sum_data_type * data , time_t sim_time , const smspec_node_type * smspec_node);
double ecl_sum_data_get_from_sim_days( const ecl_sum_data_type * data , double sim_days , const smspec_node_type * smspec_node);
int ecl_sum_data_get_length( const ecl_sum_data_type * data );
int ecl_sum_data_iget_report_step(const ecl_sum_data_type * data , int internal_index);
int ecl_sum_data_iget_mini_step(const ecl_sum_data_type * data , int internal_index);
@@ -85,7 +86,8 @@ typedef struct ecl_sum_data_struct ecl_sum_data_type ;
ecl_sum_tstep_type * ecl_sum_data_add_new_tstep( ecl_sum_data_type * data , int report_step , double sim_days);
bool ecl_sum_data_report_step_equal( const ecl_sum_data_type * data1 , const ecl_sum_data_type * data2);
bool ecl_sum_data_report_step_compatible( const ecl_sum_data_type * data1 , const ecl_sum_data_type * data2);
void ecl_sum_data_write_csv_file(const ecl_sum_data_type * data , time_t sim_time, const ecl_sum_vector_type * keylist, FILE *fp);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,42 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'ecl_sum_vector.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __ECL_SUM_VECTOR_H__
#define __ECL_SUM_VECTOR_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <ert/ecl/ecl_sum.h>
typedef struct ecl_sum_vector_struct ecl_sum_vector_type;
void ecl_sum_vector_free( ecl_sum_vector_type * keylist );
ecl_sum_vector_type * ecl_sum_vector_alloc(const ecl_sum_type * ecl_sum);
bool ecl_sum_vector_add_key( ecl_sum_vector_type * keylist, const char * key);
void ecl_sum_vector_add_keys( ecl_sum_vector_type * keylist, const char * pattern);
bool ecl_sum_vector_iget_is_rate(const ecl_sum_vector_type * ecl_sum_vector, int index);
int ecl_sum_vector_iget_param_index(const ecl_sum_vector_type * ecl_sum_vector, int index);
int ecl_sum_vector_get_size(const ecl_sum_vector_type * ecl_sum_vector);
#ifdef __cplusplus
}
#endif
#endif
+44 -44
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_util.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_util.h' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __ECL_UTIL_H__
@@ -27,19 +27,19 @@ extern "C" {
#include <ert/util/stringlist.h>
#include <ert/util/time_t_vector.h>
#include <ert/util/parser.h>
typedef enum { ECL_OTHER_FILE = 0 ,
ECL_RESTART_FILE = 1 ,
ECL_UNIFIED_RESTART_FILE = 2 ,
ECL_SUMMARY_FILE = 4 ,
ECL_UNIFIED_SUMMARY_FILE = 8 ,
ECL_SUMMARY_HEADER_FILE = 16 ,
ECL_GRID_FILE = 32 ,
ECL_EGRID_FILE = 64 ,
typedef enum { ECL_OTHER_FILE = 0 ,
ECL_RESTART_FILE = 1 ,
ECL_UNIFIED_RESTART_FILE = 2 ,
ECL_SUMMARY_FILE = 4 ,
ECL_UNIFIED_SUMMARY_FILE = 8 ,
ECL_SUMMARY_HEADER_FILE = 16 ,
ECL_GRID_FILE = 32 ,
ECL_EGRID_FILE = 64 ,
ECL_INIT_FILE = 128 ,
ECL_RFT_FILE = 256 ,
ECL_DATA_FILE = 512 } ecl_file_enum;
ECL_DATA_FILE = 512 } ecl_file_enum;
#define ECL_FILE_ENUM_DEFS {.value = 0 , .name="ECL_OTHER_FILE"}, \
@@ -62,7 +62,7 @@ typedef enum { ECL_OTHER_FILE = 0 ,
can be stored.
*/
typedef enum { ECL_INVALID_STORAGE = 0,
ECL_BINARY_UNIFIED = 1,
ECL_FORMATTED_UNIFIED = 2,
@@ -75,24 +75,23 @@ typedef enum { ECL_OTHER_FILE = 0 ,
i.e. 'REAL', 'INTE', ... , come as 4 character strings.
*/
#define ECL_STRING_LENGTH 8
#define ECL_TYPE_LENGTH 4
#define ECL_KW_HEADER_DATA_SIZE ECL_STRING_LENGTH + ECL_TYPE_LENGTH + 4
#define ECL_KW_HEADER_FORTIO_SIZE ECL_KW_HEADER_DATA_SIZE + 8
/*****************************************************************/
/*
/*
Observe that these type identidiers are (ab)used in both the rms and
ert/enkf libraries in situations where ECLIPSE is not at all involved.
*/
typedef enum {
ECL_CHAR_TYPE = 0,
ECL_FLOAT_TYPE = 1,
ECL_DOUBLE_TYPE = 2,
ECL_INT_TYPE = 3,
ECL_BOOL_TYPE = 4,
ECL_CHAR_TYPE = 0,
ECL_FLOAT_TYPE = 1,
ECL_DOUBLE_TYPE = 2,
ECL_INT_TYPE = 3,
ECL_BOOL_TYPE = 4,
ECL_MESS_TYPE = 5
} ecl_type_enum;
@@ -111,12 +110,12 @@ typedef enum {
The libecl library has been built and tested 99.5% with ECLIPSE100
as context, but in thye gravity code there is some very limited
functionality related to ECLIPSE100 versus ECLIPSE300 functionality.
*/
*/
typedef enum {
ECLIPSE_UNDEFINED = 0,
ECLIPSE100 = 1,
ECLIPSE300 = 2
ECLIPSE300 = 2
} ecl_version_enum;
/*
@@ -126,7 +125,7 @@ typedef enum {
The function ecl_util_get_phase_name() can be used to lookup a
string name from an enum value.
The phases in a simulation will typically be a sum of these
fundamental phases, and represented as an integer.
*/
@@ -142,10 +141,10 @@ typedef enum {
typedef enum {
ECL_METRIC_UNITS = 0,
ECL_FIELD_UNITS = 1,
ECL_LAB_UNITS = 2
} ecl_unit_enum;
ERT_ECL_METRIC_UNITS = 0,
ERT_ECL_FIELD_UNITS = 1,
ERT_ECL_LAB_UNITS = 2
} ert_ecl_unit_enum;
#define ECL_UNIT_ENUM_DEFS {.value = 0 , .name = "ECL_METRIC_UNITS"}, {.value = 1 , .name = "ECL_FIELD_UNITS"} , {.value = 2 , .name = "ECL_LAB_UNITS"}
#define ECL_UNIT_ENUM_SIZE 3
@@ -153,7 +152,7 @@ typedef enum {
// For unformatted files:
#define ECL_BOOL_TRUE_INT -1 // Binary representation: 11111111 11111111 11111111 1111111
#define ECL_BOOL_FALSE_INT 0 // Binary representation: 00000000 00000000 00000000 0000000
#define ECL_BOOL_FALSE_INT 0 // Binary representation: 00000000 00000000 00000000 0000000
#define ECL_COMMENT_STRING "--"
#define ECL_COMMENT_CHAR '-' // Need to consecutive to make an ECLIPSE comment
#define ECL_DATA_TERMINATION "/"
@@ -185,7 +184,7 @@ int ecl_util_get_month_nr(const char * month_name);
int ecl_util_fname_report_cmp(const void *f1, const void *f2);
time_t ecl_util_make_date(int mday , int month , int year);
time_t ecl_util_make_date__(int mday , int month , int year, int * year_offset);
ecl_unit_enum ecl_util_get_unit_set(const char * data_file);
ert_ecl_unit_enum ecl_util_get_unit_set(const char * data_file);
bool ecl_util_valid_basename_fmt( const char * basename_fmt );
bool ecl_util_valid_basename( const char * basename );
@@ -195,6 +194,7 @@ const char * ecl_util_file_enum_iget( int index, int * value);
int ecl_util_select_filelist( const char * path , const char * base , ecl_file_enum file_type , bool fmt_file , stringlist_type * filelist);
void ecl_util_append_month_range( time_t_vector_type * date_list , time_t start_date , time_t end_date , bool force_append_end);
void ecl_util_init_month_range( time_t_vector_type * date_list , time_t start_date , time_t end_date);
void ecl_util_set_date_values(time_t t , int * mday , int * month , int * year);
#ifdef __cplusplus
}
+9 -12
View File
@@ -43,35 +43,32 @@ typedef struct fortio_struct fortio_type;
fortio_status_type fortio_check_buffer( FILE * stream , bool endian_flip , size_t buffer_size );
fortio_status_type fortio_check_file( const char * filename , bool endian_flip);
bool fortio_guess_endian_flip(const char * , bool *);
bool fortio_is_fortran_file(const char * , bool * );
bool fortio_looks_like_fortran_file(const char * , bool );
void fortio_copy_record(fortio_type * , fortio_type * , int , void * , bool *);
fortio_type * fortio_alloc_FILE_wrapper(const char * , bool , bool , FILE * );
fortio_type * fortio_open_reader(const char *, bool fmt_file , bool endian_flip_header);
fortio_type * fortio_open_writer(const char *, bool fmt_file , bool endian_flip_header);
fortio_type * fortio_open_readwrite(const char *, bool fmt_file , bool endian_flip_header);
fortio_type * fortio_open_append(const char *filename , bool fmt_file , bool endian_flip_header);
fortio_type * fortio_alloc_FILE_wrapper(const char * , bool , bool , bool , FILE * );
void fortio_free_FILE_wrapper(fortio_type *);
void fortio_fclose(fortio_type *);
int fortio_init_read(fortio_type *);
void fortio_complete_read(fortio_type *);
bool fortio_complete_read(fortio_type *, int record_size);
void fortio_init_write(fortio_type * , int);
void fortio_complete_write(fortio_type *);
void fortio_complete_write(fortio_type * , int record_size);
void fortio_fskip_buffer(fortio_type *, int );
int fortio_fskip_record(fortio_type *);
int fortio_fread_record(fortio_type * , char *buffer);
void fortio_fread_buffer(fortio_type * , char * , int );
void fortio_fwrite_record(fortio_type * , const char *, int);
bool fortio_fread_buffer(fortio_type * , char * buffer, int buffer_size);
void fortio_fwrite_record(fortio_type * , const char * buffer, int buffer_size);
FILE * fortio_get_FILE(const fortio_type *);
void fortio_fflush(fortio_type * ) ;
int fortio_get_record_size(const fortio_type *);
bool fortio_is_fortio_file(fortio_type * );
void fortio_rewind(const fortio_type *fortio);
const char * fortio_filename_ref(const fortio_type * );
bool fortio_fmt_file(const fortio_type *);
offset_type fortio_ftell( const fortio_type * fortio );
int fortio_fseek( fortio_type * fortio , offset_type offset , int whence);
void fortio_data_fskip(fortio_type* fortio, const int element_size, const int element_count, const int block_count);
bool fortio_fseek( fortio_type * fortio , offset_type offset , int whence);
bool fortio_data_fskip(fortio_type* fortio, const int element_size, const int element_count, const int block_count);
void fortio_data_fseek(fortio_type* fortio, offset_type data_offset, size_t data_element, const int element_size, const int element_count, const int block_size);
int fortio_fileno( fortio_type * fortio );
@@ -79,7 +76,7 @@ typedef struct fortio_struct fortio_type;
bool fortio_fopen_stream( fortio_type * fortio );
bool fortio_stream_is_open( const fortio_type * fortio );
bool fortio_assert_stream_open( fortio_type * fortio );
bool fortio_read_at_eof( fortio_type * fortio );
UTIL_IS_INSTANCE_HEADER( fortio );
UTIL_SAFE_CAST_HEADER( fortio );
+4 -2
View File
@@ -17,7 +17,8 @@ set( source_files
ecl_sum_data.c
ecl_util.c
ecl_kw.c
ecl_sum.c
ecl_sum.c
ecl_sum_vector.c
fortio.c
ecl_rft_file.c
ecl_rft_node.c
@@ -57,7 +58,8 @@ set( header_files
ecl_sum_data.h
ecl_util.h
ecl_kw.h
ecl_sum.h
ecl_sum.h
ecl_sum_vector.h
fortio.h
ecl_rft_file.h
ecl_rft_node.h
+126 -122
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_file.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_file.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdio.h>
@@ -49,12 +49,12 @@
with a collection of ecl_kw instances and has various query
functions, however it does not utilize knowledge of the
structure/content of the files in the way e.g. ecl_grid.c does[1].
The main datatype here is the ecl_file type, but in addition each
ecl_kw instance is wrapped in an ecl_file_kw (implemented in
ecl_file_kw.c) structure and all the indexing is implemented with
the file_map type. The file_map type is not used outside this file.
When the file is opened an index of all the keywords is created and
stored in the field global_map, and the field active_map is set to
point to global_map, i.e. all query/get operations on the ecl_file
@@ -67,9 +67,9 @@
a keyword from name and occurence number, and then including all
keywords up to the next occurence of the same keyword:
SEQHDR ---\
MINISTEP 0 |
PARAMS ..... |
SEQHDR ---\
MINISTEP 0 |
PARAMS ..... |
MINISTEP 1 | Block 0
PARAMS ..... |
MINISTEP 2 |
@@ -83,14 +83,14 @@
SEQHDR ---+
MINISTEP 6 | Block 2
PARAMS .... |
SEQHDR ---+
MINISTEP 7 |
SEQHDR ---+
MINISTEP 7 |
PARAMS .... | Block 3
MINISTEP 8 |
PARAMS .... |
For the unified summary file depicted here e.g. the call
ecl_file_get_blockmap( ecl_file , "SEQHDR" , 2 )
Will create a sub-index consisting of the (three) keywords in what
@@ -99,7 +99,7 @@
of functionality is required to get from natural time coordinates
(i.e. simulation time or report step) to the occurence number (see
ecl_rstfile for more details).
To select a subindex as the active index you use the
ecl_file_select_block() function, or alternatively you can use
ecl_file_open_block() to directly select the relevant block
@@ -109,8 +109,8 @@
calls to create a new sub index will also use the global_map index
- i.e. the indexing is not recursive, a sub index is always created
based on the global_map, and not on the currently active map.
[1]: This is not entirely true - in the file ecl_rstfile.c; which
is included from this file are several specialized function
for working with restart files. However the restart files are
@@ -128,7 +128,7 @@ typedef struct file_map_struct file_map_type;
struct file_map_struct {
vector_type * kw_list; /* This is a vector of ecl_file_kw instances corresponding to the content of the file. */
hash_type * kw_index; /* A hash table with integer vectors of indices - see comment below. */
stringlist_type * distinct_kw; /* A stringlist of the keywords occuring in the file - each string occurs ONLY ONCE. */
stringlist_type * distinct_kw; /* A stringlist of the keywords occuring in the file - each string occurs ONLY ONCE. */
fortio_type * fortio; /* The same fortio instance pointer as in the ecl_file styructure. */
bool owner; /* Is this map the owner of the ecl_file_kw instances; only true for the global_map. */
inv_map_type * inv_map; /* Shared reference owned by the ecl_file structure. */
@@ -158,10 +158,10 @@ struct ecl_file_struct {
with entries 'SEQHDR', 'MINISTEP' and 'PARAMS'. Each entry in the
hash table is an integer vector which again contains the internal
index of the various occurences:
------------------
SEQHDR \
MINISTEP 0 |
MINISTEP 0 |
PARAMS ..... |
MINISTEP 1 |
PARAMS ..... |
@@ -172,7 +172,7 @@ struct ecl_file_struct {
kw_index = {"SEQHDR": [0], "MINISTEP": [1,3,5], "PARAMS": [2,4,6]} <== This is hash table.
kw_list = [SEQHDR , MINISTEP , PARAMS , MINISTEP , PARAMS , MINISTEP , PARAMS]
distinct_kw = [SEQHDR , MINISTEP , PARAMS]
*/
@@ -208,7 +208,7 @@ static int file_map_get_global_index( const file_map_type * file_map , const cha
int global_index = int_vector_iget( index_vector , ith);
return global_index;
}
/**
@@ -216,7 +216,7 @@ static int file_map_get_global_index( const file_map_type * file_map , const cha
internal index fields 'kw_index' and 'distinct_kw'. This function
must be called every time the content of the kw_list vector is
modified (otherwise the ecl_file instance will be in an
inconsistent state).
inconsistent state).
*/
@@ -233,7 +233,7 @@ static void file_map_make_index( file_map_type * file_map ) {
hash_insert_hash_owned_ref( file_map->kw_index , header , index_vector , int_vector_free__);
stringlist_append_copy( file_map->distinct_kw , header);
}
{
int_vector_type * index_vector = hash_get( file_map->kw_index , header);
int_vector_append( index_vector , i);
@@ -244,7 +244,7 @@ static void file_map_make_index( file_map_type * file_map ) {
static bool file_map_has_kw( const file_map_type * file_map, const char * kw) {
return hash_has_key( file_map->kw_index , kw );
}
}
static ecl_file_kw_type * file_map_iget_file_kw( const file_map_type * file_map , int global_index) {
@@ -265,7 +265,7 @@ static ecl_kw_type * file_map_iget_kw( const file_map_type * file_map , int inde
ecl_kw_type * ecl_kw = ecl_file_kw_get_kw_ptr( file_kw , file_map->fortio , file_map->inv_map);
if (!ecl_kw) {
if (fortio_assert_stream_open( file_map->fortio )) {
ecl_kw = ecl_file_kw_get_kw( file_kw , file_map->fortio , file_map->inv_map);
if (FILE_FLAGS_SET( file_map->flags[0] , ECL_FILE_CLOSE_STREAM))
@@ -283,7 +283,7 @@ static void file_map_index_fload_kw(const file_map_type * file_map, const char*
ecl_type_enum ecl_type = ecl_file_kw_get_type(file_kw);
int element_count = ecl_file_kw_get_size(file_kw);
ecl_kw_fread_indexed_data(file_map->fortio, offset + ECL_KW_FORTIO_HEADER_SIZE, ecl_type, element_count, index_map, buffer);
ecl_kw_fread_indexed_data(file_map->fortio, offset + ECL_KW_HEADER_FORTIO_SIZE, ecl_type, element_count, index_map, buffer);
}
}
@@ -339,9 +339,9 @@ static ecl_kw_type * file_map_iget_named_kw( const file_map_type * file_map , co
ecl_kw_type * ecl_kw = ecl_file_kw_get_kw_ptr( file_kw , file_map->fortio , file_map->inv_map );
if (!ecl_kw) {
if (fortio_assert_stream_open( file_map->fortio )) {
ecl_kw = ecl_file_kw_get_kw( file_kw , file_map->fortio , file_map->inv_map);
if (FILE_FLAGS_SET( file_map->flags[0] , ECL_FILE_CLOSE_STREAM))
fortio_fclose_stream( file_map->fortio );
}
@@ -365,16 +365,16 @@ static void file_map_replace_kw( file_map_type * file_map , ecl_kw_type * old_kw
while (index < vector_get_size( file_map->kw_list )) {
ecl_file_kw_type * ikw = vector_iget( file_map->kw_list , index );
if (ecl_file_kw_ptr_eq( ikw , old_kw)) {
/*
/*
Found it; observe that the vector_iset() function will
automatically invoke the destructor on the old_kw.
automatically invoke the destructor on the old_kw.
*/
ecl_kw_type * insert_kw = new_kw;
if (insert_copy)
insert_kw = ecl_kw_alloc_copy( new_kw );
ecl_file_kw_replace_kw( ikw , file_map->fortio , insert_kw );
file_map_make_index( file_map );
return;
}
@@ -386,7 +386,7 @@ static void file_map_replace_kw( file_map_type * file_map , ecl_kw_type * old_kw
static bool file_map_load_all( file_map_type * file_map ) {
bool loadOK = false;
if (fortio_assert_stream_open( file_map->fortio )) {
int index;
for (index = 0; index < vector_get_size( file_map->kw_list); index++) {
@@ -409,9 +409,9 @@ static bool file_map_load_all( file_map_type * file_map ) {
static void file_map_add_kw( file_map_type * file_map , ecl_file_kw_type * file_kw) {
if (file_map->owner)
vector_append_owned_ref( file_map->kw_list , file_kw , ecl_file_kw_free__ );
vector_append_owned_ref( file_map->kw_list , file_kw , ecl_file_kw_free__ );
else
vector_append_ref( file_map->kw_list , file_kw);
vector_append_ref( file_map->kw_list , file_kw);
}
static void file_map_free( file_map_type * file_map ) {
@@ -451,7 +451,7 @@ static int file_map_iget_occurence( const file_map_type * file_map , int global_
const char * header = ecl_file_kw_get_header( file_kw );
const int_vector_type * index_vector = hash_get( file_map->kw_index , header );
const int * index_data = int_vector_get_const_ptr( index_vector );
int occurence = -1;
{
/* Manual reverse lookup. */
@@ -471,8 +471,8 @@ static void file_map_fprintf_kw_list(const file_map_type * file_map , FILE * str
for (i=0; i < vector_get_size( file_map->kw_list ); i++) {
const ecl_file_kw_type * file_kw = vector_iget_const( file_map->kw_list , i );
fprintf(stream , "%-8s %7d:%s\n",
ecl_file_kw_get_header( file_kw ) ,
ecl_file_kw_get_size( file_kw ) ,
ecl_file_kw_get_header( file_kw ) ,
ecl_file_kw_get_size( file_kw ) ,
ecl_util_get_type_name( ecl_file_kw_get_type( file_kw )));
}
}
@@ -486,20 +486,20 @@ static file_map_type * file_map_alloc_blockmap(const file_map_type * file_map ,
if (file_map_has_kw( file_map , header )) {
int kw_index = file_map_get_global_index( file_map , header , occurence );
ecl_file_kw_type * file_kw = vector_iget( file_map->kw_list , kw_index );
while (true) {
file_map_add_kw( block_map , file_kw );
kw_index++;
if (kw_index == vector_get_size( file_map->kw_list ))
break;
break;
else {
file_kw = vector_iget(file_map->kw_list , kw_index);
if (strcmp( header , ecl_file_kw_get_header( file_kw )) == 0)
break;
}
}
}
}
file_map_make_index( block_map );
return block_map;
} else
@@ -536,7 +536,7 @@ void ecl_file_fwrite_fortio(const ecl_file_type * ecl_file , fortio_type * targe
/*
/*
Observe : if the filename is a standard filename which can be used
to infer formatted/unformatted automagically the fmt_file variable
is NOT consulted.
@@ -545,11 +545,11 @@ void ecl_file_fwrite_fortio(const ecl_file_type * ecl_file , fortio_type * targe
void ecl_file_fwrite(const ecl_file_type * ecl_file , const char * filename, bool fmt_file) {
bool __fmt_file;
ecl_file_enum file_type;
file_type = ecl_util_get_file_type( filename , &__fmt_file , NULL);
if (file_type == ECL_OTHER_FILE)
__fmt_file = fmt_file;
{
fortio_type * target = fortio_open_writer( filename , __fmt_file , ECL_ENDIAN_FLIP);
ecl_file_fwrite_fortio( ecl_file , target , 0);
@@ -591,7 +591,7 @@ void ecl_file_fwrite(const ecl_file_type * ecl_file , const char * filename, boo
....
for (ikw = 0; ikw < ecl_file_get_num_distinct_kw(ecl_file); ikw++) {
const char * kw = ecl_file_iget_distinct_kw(ecl_file , ikw);
printf("The file contains: %d occurences of \'%s\' \n",ecl_file_get_num_named_kw( ecl_file , kw) , kw);
}
....
@@ -601,7 +601,7 @@ void ecl_file_fwrite(const ecl_file_type * ecl_file , const char * filename, boo
The file contains 1 occurences of 'SEQHDR'
The file contains 3 occurences of 'MINISTEP'
The file contains 3 occurences of 'PARAMS'
*/
@@ -623,7 +623,7 @@ void ecl_file_fwrite(const ecl_file_type * ecl_file , const char * filename, boo
@old_kw can not be found the function will fail hard - to verify
that @new_kw is indeed in the ecl_file instance you should use
ecl_file_has_kw_ptr() first.
The ecl_file function typically gives out references to the
internal ecl_kw instances via the ecl_file_iget_kw() function. Use
of ecl_file_replace_kw() might lead to invalidating ecl_kw
@@ -634,22 +634,22 @@ void ecl_file_fwrite(const ecl_file_type * ecl_file , const char * filename, boo
ecl_file_type * restart_file = ecl_file_fread_alloc( "ECLIPSE.UNRST" );
ecl_kw_type * initial_pressure = ecl_file_iget_named_kw( ecl_file , "PRESSURE" , 0);
ecl_kw_type * faked_pressure = ecl_kw_alloc_copy( initial_pressure );
ecl_kw_scale( faked_pressure , 1.25 );
ecl_file_replace_kw( restart_file , initial_pressure , faked_pressure , false ); <--- This call will invalidate the inital_pressure reference
....
....
// This will fail horribly:
// This will fail horribly:
printf("The initial pressure in cell(0) was:%g \n",ecl_kw_iget_double( initial_pressure , 0 ));
/|\
|
+---------> Using initial_pressure => Crash and burn!
+---------> Using initial_pressure => Crash and burn!
The ecl_file structure takes ownership of all the keywords, and
will also take ownership of the newly instered @new_kw instance; if
the boolean @insert_copy is set to true the function will insert a
copy of @new_kw, leaving the original reference untouched.
*/
copy of @new_kw, leaving the original reference untouched.
*/
@@ -665,7 +665,7 @@ ecl_kw_type * ecl_file_icopy_named_kw( const ecl_file_type * ecl_file , const ch
return ecl_kw_alloc_copy( ecl_file_iget_named_kw( ecl_file , kw , ith ));
}
/*
Will return the number of times a particular keyword occurs in a
ecl_file instance. Will return 0 if the keyword can not be found.
@@ -692,7 +692,7 @@ int ecl_file_get_num_named_kw(const ecl_file_type * ecl_file , const char * kw)
ecl_file_iget_occurence(ecl_file , 2) -> 0; Global index 2 will
look up the first occurence of PARAMS.
ecl_file_iget_occurence(ecl_file , 5) -> 2; Global index 5 will
look up th third occurence of MINISTEP.
@@ -705,7 +705,7 @@ int ecl_file_iget_occurence( const ecl_file_type * ecl_file , int index) {
}
/**
/**
Returns the total number of ecl_kw instances in the ecl_file
instance.
*/
@@ -778,10 +778,10 @@ const char * ecl_file_iget_header( const ecl_file_type * file , int global_index
/* ---------- */
/*
/*
This function will return the ith occurence of 'kw' in
ecl_file. Will abort hard if the request can not be satisifed - use
query functions if you can not take that.
query functions if you can not take that.
*/
ecl_kw_type * ecl_file_iget_named_kw( const ecl_file_type * file , const char * kw, int ith) {
@@ -815,7 +815,7 @@ static file_map_type * ecl_file_get_blockmap( ecl_file_type * ecl_file , const c
blockmap = file_map_alloc_blockmap( ecl_file->global_map , kw , occurence );
else
blockmap = file_map_alloc_blockmap( ecl_file->active_map , kw , occurence );
if (blockmap != NULL)
ecl_file_add_map( ecl_file , blockmap );
return blockmap;
@@ -824,7 +824,7 @@ static file_map_type * ecl_file_get_blockmap( ecl_file_type * ecl_file , const c
/*****************************************************************/
/*
Different functions to open and close a file.
Different functions to open and close a file.
*/
/**
@@ -835,23 +835,37 @@ static file_map_type * ecl_file_get_blockmap( ecl_file_type * ecl_file , const c
map.
*/
static void ecl_file_scan( ecl_file_type * ecl_file ) {
static bool ecl_file_scan( ecl_file_type * ecl_file ) {
bool scan_ok = false;
fortio_fseek( ecl_file->fortio , 0 , SEEK_SET );
{
ecl_kw_type * work_kw = ecl_kw_alloc_new("WORK-KW" , 0 , ECL_INT_TYPE , NULL);
offset_type current_offset;
while (true) {
current_offset = fortio_ftell( ecl_file->fortio );
if (ecl_kw_fread_header( work_kw , ecl_file->fortio )) {
ecl_file_kw_type * file_kw = ecl_file_kw_alloc( work_kw , current_offset);
file_map_add_kw( ecl_file->global_map , file_kw );
ecl_file_kw_fskip_data( file_kw , ecl_file->fortio );
} else
if (fortio_read_at_eof(ecl_file->fortio)) {
scan_ok = true;
break;
}
{
offset_type current_offset = fortio_ftell( ecl_file->fortio );
if (ecl_kw_fread_header( work_kw , ecl_file->fortio)) {
ecl_file_kw_type * file_kw = ecl_file_kw_alloc( work_kw , current_offset);
if (ecl_file_kw_fskip_data( file_kw , ecl_file->fortio ))
file_map_add_kw( ecl_file->global_map , file_kw );
else
break;
} else
break;
}
}
ecl_kw_free( work_kw );
}
file_map_make_index( ecl_file->global_map );
if (scan_ok)
file_map_make_index( ecl_file->global_map );
return scan_ok;
}
@@ -868,54 +882,44 @@ void ecl_file_select_global( ecl_file_type * ecl_file ) {
structure. No keyword data will be loaded from the file.
The ecl_file instance will retain an open fortio reference to the
file until ecl_file_close() is called.
file until ecl_file_close() is called.
*/
static ecl_file_type * ecl_file_open__( const char * filename , int flags) {
ecl_file_type * ecl_file_open( const char * filename , int flags) {
fortio_type * fortio;
bool fmt_file;
ecl_util_fmt_file( filename , &fmt_file);
//flags |= ECL_FILE_CLOSE_STREAM; // DEBUG DEBUG DEBUG
if (FILE_FLAGS_SET(flags , ECL_FILE_WRITABLE))
fortio = fortio_open_readwrite( filename , fmt_file , ECL_ENDIAN_FLIP);
else
fortio = fortio_open_reader( filename , fmt_file , ECL_ENDIAN_FLIP);
else
fortio = fortio_open_reader( filename , fmt_file , ECL_ENDIAN_FLIP);
if (fortio) {
ecl_file_type * ecl_file = ecl_file_alloc_empty( flags );
ecl_file->fortio = fortio;
ecl_file->global_map = file_map_alloc( ecl_file->fortio , &ecl_file->flags , ecl_file->inv_map , true );
ecl_file_add_map( ecl_file , ecl_file->global_map );
ecl_file_scan( ecl_file );
ecl_file_select_global( ecl_file );
if (ecl_file_scan( ecl_file )) {
ecl_file_select_global( ecl_file );
if (FILE_FLAGS_SET( ecl_file->flags , ECL_FILE_CLOSE_STREAM))
fortio_fclose_stream( ecl_file->fortio );
return ecl_file;
} else
if (FILE_FLAGS_SET( ecl_file->flags , ECL_FILE_CLOSE_STREAM))
fortio_fclose_stream( ecl_file->fortio );
return ecl_file;
} else {
ecl_file_close( ecl_file );
return NULL;
}
} else
return NULL;
}
ecl_file_type * ecl_file_open( const char * filename , int flags) {
ecl_file_type * ecl_file = ecl_file_open__(filename , flags );
if (ecl_file)
return ecl_file;
else {
util_abort("%s: failed to open ECLIPSE file:%s \n",__func__ , filename);
return NULL;
}
}
ecl_file_type * ecl_file_try_open( const char * filename, int flags) {
return ecl_file_open__(filename , flags );
}
@@ -974,7 +978,7 @@ bool ecl_file_select_block( ecl_file_type * ecl_file , const char * kw , int occ
void ecl_file_close(ecl_file_type * ecl_file) {
if (ecl_file->fortio != NULL)
fortio_fclose( ecl_file->fortio );
inv_map_free( ecl_file->inv_map );
vector_free( ecl_file->map_list );
vector_free( ecl_file->map_stack );
@@ -1019,7 +1023,7 @@ void ecl_file_free__(void * arg) {
/* Here we include two files with functions specialized to work with
restart and summary files. Observe that the files ecl_rstfile.c and
ecl_smryfile are compiled as part of the same compilation unit as
ecl_file.c
ecl_file.c
*/
#include "ecl_rstfile.c"
@@ -1033,10 +1037,10 @@ void ecl_file_free__(void * arg) {
The input @file must be either an INIT file or a restart file. Will
fail hard if an INTEHEAD kw can not be found - or if the INTEHEAD
keyword is not sufficiently large.
The eclipse files can distinguish between ECLIPSE300 ( value == 300)
and ECLIPSE300-Thermal option (value == 500). This function will
return ECLIPSE300 in both those cases.
return ECLIPSE300 in both those cases.
*/
ecl_version_enum ecl_file_get_ecl_version( const ecl_file_type * file ) {
@@ -1079,14 +1083,14 @@ bool ecl_file_writable( const ecl_file_type * ecl_file ) {
/**
Checks if the ecl_file contains ecl_kw; this check is based on
pointer equality - i.e. we check if the ecl_file contains exactly
this keyword - not an arbitrary equivalent keyword.
this keyword - not an arbitrary equivalent keyword.
This function can be called as a safeguard before calling
ecl_file_save_kw().
ecl_file_save_kw().
*/
bool ecl_file_has_kw_ptr( const ecl_file_type * ecl_file , const ecl_kw_type * ecl_kw) {
ecl_file_kw_type * file_kw = inv_map_get_file_kw( ecl_file->inv_map , ecl_kw );
ecl_file_kw_type * file_kw = inv_map_get_file_kw( ecl_file->inv_map , ecl_kw );
if (file_kw == NULL)
return false;
else
@@ -1108,19 +1112,19 @@ bool ecl_file_has_kw_ptr( const ecl_file_type * ecl_file , const ecl_kw_type * e
will ensue if this is not satisfied.
3. The ecl_file must have been opened with one of the _writable()
open functions.
open functions.
*/
bool ecl_file_save_kw( const ecl_file_type * ecl_file , const ecl_kw_type * ecl_kw) {
ecl_file_kw_type * file_kw = inv_map_get_file_kw( ecl_file->inv_map , ecl_kw ); // We just verify that the input ecl_kw points to an ecl_kw
ecl_file_kw_type * file_kw = inv_map_get_file_kw( ecl_file->inv_map , ecl_kw ); // We just verify that the input ecl_kw points to an ecl_kw
if (file_kw != NULL) { // we manage; from then on we use the reference contained in
if (fortio_assert_stream_open( ecl_file->fortio )) { // the corresponding ecl_file_kw instance.
ecl_file_kw_inplace_fwrite( file_kw , ecl_file->fortio );
if (fortio_assert_stream_open( ecl_file->fortio )) { // the corresponding ecl_file_kw instance.
ecl_file_kw_inplace_fwrite( file_kw , ecl_file->fortio );
if (FILE_FLAGS_SET( ecl_file->flags , ECL_FILE_CLOSE_STREAM))
fortio_fclose_stream( ecl_file->fortio );
return true;
} else
return false;
+2 -2
View File
@@ -297,8 +297,8 @@ offset_type ecl_file_kw_get_offset(const ecl_file_kw_type * file_kw) {
return file_kw->file_offset;
}
void ecl_file_kw_fskip_data( const ecl_file_kw_type * file_kw , fortio_type * fortio) {
ecl_kw_fskip_data__( file_kw->ecl_type , file_kw->kw_size , fortio );
bool ecl_file_kw_fskip_data( const ecl_file_kw_type * file_kw , fortio_type * fortio) {
return ecl_kw_fskip_data__( file_kw->ecl_type , file_kw->kw_size , fortio );
}
File diff suppressed because it is too large Load Diff
+314 -293
View File
File diff suppressed because it is too large Load Diff
+90 -90
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_kw_grdecl.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_kw_grdecl.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <string.h>
@@ -47,7 +47,7 @@
3. The * notation can be used to print repeated values in a compact
form, i.e. 1000*0.25 to get 1000 conecutive 0.25 values.
The typical ECLIPSE keywords found in the datafile contain a mixture
of numeric and character data; the current code assumes that all the
data of a keyword is of the same underlying type, and do NOT support
@@ -74,7 +74,7 @@ bool ecl_kw_grdecl_fseek_next_kw( FILE * stream ) {
long start_pos = util_ftell( stream );
long current_pos;
char next_kw[256];
/*
Determine if the current position of the file pointer is at the
beginning of the line; if not skip the rest of the line; this is
@@ -83,17 +83,17 @@ bool ecl_kw_grdecl_fseek_next_kw( FILE * stream ) {
{
while (true) {
char c;
if (util_ftell(stream) == 0)
if (util_ftell(stream) == 0)
/*
We are at the very beginning of the file. Can just jump out of
the loop.
*/
break;
util_fseek( stream , -1 , SEEK_CUR );
c = fgetc( stream );
if (c == '\n') {
/*
/*
We have walked backwards reaching the start of the line. We
have not reached any !isspace() characters on the way and
can go back to start_pos and read from there.
@@ -101,9 +101,9 @@ bool ecl_kw_grdecl_fseek_next_kw( FILE * stream ) {
util_fseek( stream , start_pos , SEEK_SET );
break;
}
if (!isspace( c )) {
/*
/*
We hit a non-whitespace character; this means that start_pos
was not at the start of the line. We skip the rest of this
line, and then start reading on the next line.
@@ -114,12 +114,12 @@ bool ecl_kw_grdecl_fseek_next_kw( FILE * stream ) {
util_fseek( stream , -2 , SEEK_CUR );
}
}
while (true) {
current_pos = util_ftell( stream );
if (fscanf(stream , "%s" , next_kw) == 1) {
if ((next_kw[0] == next_kw[1]) && (next_kw[0] == ECL_COMMENT_CHAR))
if ((next_kw[0] == next_kw[1]) && (next_kw[0] == ECL_COMMENT_CHAR))
// This is a comment line - skip it.
util_fskip_lines( stream , 1 );
else {
@@ -140,7 +140,7 @@ bool ecl_kw_grdecl_fseek_next_kw( FILE * stream ) {
Will use the ecl_kw_grdecl_fseek_next_header() to seek out the next
header string, and read and return that string. If no more headers
are found the function will return NULL. The storage allocated by
this function must be free'd by the calling scope.
this function must be free'd by the calling scope.
*/
char * ecl_kw_grdecl_alloc_next_header( FILE * stream ) {
@@ -153,7 +153,7 @@ char * ecl_kw_grdecl_alloc_next_header( FILE * stream ) {
}
/**
/**
This function will search through a GRDECL file to look for the
'kw'; input variables and return vales are similar to
ecl_kw_fseek_kw(). Observe that the GRDECL files are extremely
@@ -161,7 +161,7 @@ char * ecl_kw_grdecl_alloc_next_header( FILE * stream ) {
with a malformed GRDECL file.
In particular the comparison is case sensitive; that is probably not
the case with ECLIPSE proper?
the case with ECLIPSE proper?
If the kw is not found the file pointer is repositioned.
*/
@@ -189,27 +189,27 @@ static bool ecl_kw_grdecl_fseek_kw__(const char * kw , FILE * stream) {
// static bool ecl_kw_grdecl_fseek_kw__OLD(const char * kw , FILE * stream) {
// const int newline_char = '\n';
// long int init_pos = ftell(stream);
//
//
// if (util_fseek_string(stream , kw , false , true)) {
// /*
// OK the keyword is found in the file; now we must verify that:
//
//
// 1. It is terminated with a blank, i.e. when searching for
// 'COORD' we do not want a positive on 'COORDSYS'.
//
//
// 2. That the keyword indeed starts with a isspace() character; we
// are not interested in the 'SYS' in 'COORDSYS'.
//
// are not interested in the 'SYS' in 'COORDSYS'.
//
// 3. That the current location is not a comment section.
// */
// long int kw_pos = ftell( stream );
// bool valid_kw = false;
// int c;
//
//
// fseek( stream , strlen(kw) , SEEK_CUR); // Seek to end of kw
// c = fgetc( stream ); // Read one character
// c = fgetc( stream ); // Read one character
// fseek( stream , kw_pos , SEEK_SET ); // Seek back to beginning of kw
//
//
// if (isspace(c)) {
// if (kw_pos > 0) {
// fseek( stream , kw_pos - 1 , SEEK_SET);
@@ -220,9 +220,9 @@ static bool ecl_kw_grdecl_fseek_kw__(const char * kw , FILE * stream) {
// valid_kw = true;
// } else
// valid_kw = true; // kw is at the very beginning of the file.
// }
//
//
// }
//
//
// if (valid_kw) {
// // OK - the kw is validly terminated with a space/tab/newline; now
// // we must verify that it is not in a comment section.
@@ -232,30 +232,30 @@ static bool ecl_kw_grdecl_fseek_kw__(const char * kw , FILE * stream) {
// while (true) {
// fseek( stream , -2 , SEEK_CUR );
// c = fgetc( stream );
// if ((c == newline_char) || (ftell(stream) == 0))
// if ((c == newline_char) || (ftell(stream) == 0))
// break;
// }
// {
// // We have gone as far back as necessary.
// int line_length = kw_pos - ftell( stream );
// char * line = util_malloc(line_length + 1 , __func__);
//
//
// fread( stream , sizeof * line , line_length , stream);
// line[line_length] = '\0';
//
// if (strstr( line , ECL_COMMENT_STRING) == NULL)
// // We are not in a commen section.
//
// if (strstr( line , ECL_COMMENT_STRING) == NULL)
// // We are not in a commen section.
// valid_kw = true;
// else
// valid_kw = false;
//
//
// free( line );
// }
// }
// } else
// valid_kw = false;
//
// if (valid_kw)
//
// if (valid_kw)
// return true;
// else {
// fseek( stream , strlen(kw) , SEEK_CUR ); // Skip over the kw so we don't find it again.
@@ -265,8 +265,8 @@ static bool ecl_kw_grdecl_fseek_kw__(const char * kw , FILE * stream) {
// fseek( stream , init_pos , SEEK_SET );
// return false;
// }
// }
// } else
// }
// } else
// return false;
// }
@@ -276,10 +276,10 @@ bool ecl_kw_grdecl_fseek_kw(const char * kw , bool rewind , FILE * stream) {
return true; /* OK - we found the kw between current file pos and EOF. */
else if (rewind) {
long int init_pos = util_ftell(stream);
util_fseek(stream , 0L , SEEK_SET);
if (ecl_kw_grdecl_fseek_kw__( kw , stream )) /* Try again from the beginning of the file. */
return true;
return true;
else
util_fseek(stream , init_pos , SEEK_SET); /* Could not find it - reposition to initial position. */
}
@@ -293,13 +293,13 @@ bool ecl_kw_grdecl_fseek_kw(const char * kw , bool rewind , FILE * stream) {
/**
Observe that this function does not preserve the '*' structure
which (might) have been used in the input.
which (might) have been used in the input.
*/
static void iset_range( char * data , int data_offset , int sizeof_ctype , void * value_ptr , int multiplier) {
int index;
for ( index =0; index < multiplier; index++)
for ( index =0; index < multiplier; index++)
memcpy( &data[ (index + data_offset) * sizeof_ctype ] , value_ptr , sizeof_ctype);
}
@@ -317,11 +317,11 @@ static void iset_range( char * data , int data_offset , int sizeof_ctype , void
Whatever that 'F' is - it is discarded when the SPECGRID header is
written to a GRID/EGRID file. For this reason we have the
possibility of setting @strict to false; in which case the 'F' or
other characters in the numerical input will be ignored.
other characters in the numerical input will be ignored.
If @strict is set to true the function will bomb when meeting a
non-numeric character like the 'F' above.
non-numeric character like the 'F' above.
----------------------------------------------------------------
The function supports multiplier keywords like:
@@ -329,7 +329,7 @@ static void iset_range( char * data , int data_offset , int sizeof_ctype , void
PERMX
10000*0.15 0.16 0.17 0.18 0.19 10000*0.20
/
Observe that no-spaces-are-allowed-around-the-*
*/
@@ -358,7 +358,7 @@ static char * fscanf_alloc_grdecl_data( const char * header , bool strict , ecl_
break;
}
}
} else if (strcmp(buffer , ECL_DATA_TERMINATION) == 0)
} else if (strcmp(buffer , ECL_DATA_TERMINATION) == 0)
break;
else {
// We have read a valid input string; scan numerical input values from it.
@@ -368,27 +368,27 @@ static char * fscanf_alloc_grdecl_data( const char * header , bool strict , ecl_
int multiplier;
void * value_ptr = NULL;
bool char_input = false;
if (ecl_type == ECL_INT_TYPE) {
int value;
if (sscanf(buffer , "%d*%d" , &multiplier , &value) == 2)
if (sscanf(buffer , "%d*%d" , &multiplier , &value) == 2)
{}
else if (sscanf( buffer , "%d" , &value) == 1)
else if (sscanf( buffer , "%d" , &value) == 1)
multiplier = 1;
else {
char_input = true;
if (strict)
util_abort("%s: Malformed content:\"%s\" when reading keyword:%s \n",__func__ , buffer , header);
}
value_ptr = &value;
} else if (ecl_type == ECL_FLOAT_TYPE) {
float value;
if (sscanf(buffer , "%d*%g" , &multiplier , &value) == 2)
if (sscanf(buffer , "%d*%g" , &multiplier , &value) == 2)
{}
else if (sscanf( buffer , "%g" , &value) == 1)
else if (sscanf( buffer , "%g" , &value) == 1)
multiplier = 1;
else {
char_input = true;
@@ -400,21 +400,21 @@ static char * fscanf_alloc_grdecl_data( const char * header , bool strict , ecl_
} else if (ecl_type == ECL_DOUBLE_TYPE) {
double value;
if (sscanf(buffer , "%d*%lg" , &multiplier , &value) == 2)
if (sscanf(buffer , "%d*%lg" , &multiplier , &value) == 2)
{}
else if (sscanf( buffer , "%lg" , &value) == 1)
else if (sscanf( buffer , "%lg" , &value) == 1)
multiplier = 1;
else {
char_input = true;
if (strict)
util_abort("%s: Malformed content:\"%s\" when reading keyword:%s \n",__func__ , buffer , header);
}
value_ptr = &value;
} else
} else
util_abort("%s: sorry type:%s not supported \n",__func__ , ecl_util_get_type_name(ecl_type));
if (char_input)
fprintf(stderr,"Warning: character string: \'%s\' ignored when reading keyword:%s \n",buffer , header);
else {
@@ -422,7 +422,7 @@ static char * fscanf_alloc_grdecl_data( const char * header , bool strict , ecl_
data_size = 2*(data_index + multiplier);
data = util_realloc( data , sizeof_ctype * data_size * sizeof * data);
}
iset_range( data , data_index , sizeof_ctype , value_ptr , multiplier );
data_index += multiplier;
}
@@ -430,7 +430,7 @@ static char * fscanf_alloc_grdecl_data( const char * header , bool strict , ecl_
}
if (atEOF)
break;
} else
} else
break;
}
free( buffer );
@@ -512,7 +512,7 @@ static ecl_kw_type * __ecl_kw_fscanf_alloc_grdecl__(FILE * stream , const char *
if (fscanf(stream , "%s" , file_header) == 1) {
int kw_size;
char * data = fscanf_alloc_grdecl_data( file_header , strict , ecl_type , &kw_size , stream );
// Verify size
if (size > 0)
if (size != kw_size) {
@@ -520,20 +520,20 @@ static ecl_kw_type * __ecl_kw_fscanf_alloc_grdecl__(FILE * stream , const char *
util_abort("%s: size mismatch when loading:%s. File:%d elements. Requested:%d elements \n",
__func__ , file_header , kw_size , size);
}
{
ecl_kw_type * ecl_kw = ecl_kw_alloc_new( file_header , kw_size , ecl_type , NULL );
ecl_kw_set_data_ptr( ecl_kw , data );
return ecl_kw;
}
} else
} else
/** No header read - probably at EOF */
return NULL;
}
}
/*****************************************************************/
/*
/*
Here comes the exported functions for loading a grdecl formatted
keyword. All of these function invoke the fundamental
ecl_kw_fscanf_alloc_grdecl__() function, but the set of input
@@ -541,7 +541,7 @@ static ecl_kw_type * __ecl_kw_fscanf_alloc_grdecl__(FILE * stream , const char *
accepts a @strict flag from calling scope; in general you should
use strict == true.
*/
/**
This function assumes that the file pointer has already been
@@ -564,12 +564,12 @@ ecl_kw_type * ecl_kw_fscanf_alloc_grdecl_data(FILE * stream , int size , ecl_typ
/*****************************************************************/
/*
/*
This function will seek through the file and position the file
pointer at the beginning of @kw before starting to load (this
includes rewinding the file pointer). If @kw can not be found the
function will return NULL.
function will return NULL.
As size is not supplied the function will keep loading data until
the whole keyword is loaded, and then return.
*/
@@ -585,12 +585,12 @@ ecl_kw_type * ecl_kw_fscanf_alloc_grdecl_dynamic( FILE * stream , const char * k
/*****************************************************************/
/*
/*
This function will seek through the file and position the file
pointer at the beginning of @kw before starting to load (this
includes rewinding the file pointer). If @kw can not be found the
function will return NULL.
function will return NULL.
When the data has been loaded the function will compare actual size
with the supplied size argument and verify equality; if they differ
it will crash hard. If you are uncertain of the size use the
@@ -610,7 +610,7 @@ ecl_kw_type * ecl_kw_fscanf_alloc_grdecl( FILE * stream , const char * kw , int
/*****************************************************************/
/*
/*
This function will read and allocate the next keyword in the
file. This function does not take either kw or the size of the kw
as input, and has virtually zero possibilities to check what it is
@@ -638,21 +638,21 @@ ecl_kw_type * ecl_kw_fscanf_alloc_current_grdecl( FILE * stream , ecl_type_enum
/*
This method allows to write with a different header,
i.e. PORO_XXXX. This header is even allowed to break the 8 character
length limit; i.e. loading it back naively will fail.
length limit; i.e. loading it back naively will fail.
*/
void ecl_kw_fprintf_grdecl__(const ecl_kw_type * ecl_kw , const char * special_header , FILE * stream) {
void ecl_kw_fprintf_grdecl__(const ecl_kw_type * ecl_kw , const char * special_header , FILE * stream) {
if (special_header)
fprintf(stream,"%s\n" , special_header);
else
fprintf(stream,"%s\n" , special_header);
else
fprintf(stream,"%s\n" , ecl_kw_get_header(ecl_kw));
{
fortio_type * fortio = fortio_alloc_FILE_wrapper(NULL , false , true , stream); /* Endian flip should *NOT* be used */
fortio_type * fortio = fortio_alloc_FILE_wrapper(NULL , false , true , true , stream); /* Endian flip should *NOT* be used */
ecl_kw_fwrite_data(ecl_kw , fortio);
fortio_free_FILE_wrapper( fortio );
}
fprintf(stream,"/\n");
fprintf(stream,"/\n");
}
+69 -59
View File
@@ -1,20 +1,20 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'ecl_nnc_export.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more detals.
*/
Copyright (C) 2013 Statoil ASA, Norway.
The file 'ecl_nnc_export.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more detals.
*/
#include <stdlib.h>
#include <ert/util/int_vector.h>
@@ -33,16 +33,17 @@ int ecl_nnc_export_get_size( const ecl_grid_type * grid ) {
static void ecl_nnc_export__( const ecl_grid_type * grid , int lgr_index1 , const ecl_file_type * init_file , ecl_nnc_type * nnc_data, int * nnc_offset) {
static int ecl_nnc_export__( const ecl_grid_type * grid , int lgr_index1 , const ecl_file_type * init_file , ecl_nnc_type * nnc_data, int * nnc_offset) {
int nnc_index = *nnc_offset;
int lgr_nr1 = ecl_grid_get_lgr_nr( grid );
int global_index1;
int valid_trans = 0 ;
const ecl_grid_type * global_grid = ecl_grid_get_global_grid( grid );
if (!global_grid)
global_grid = grid;
for (global_index1 = 0; global_index1 < ecl_grid_get_global_size( grid ); global_index1++) {
const nnc_info_type * nnc_info = ecl_grid_get_cell_nnc_info1( grid , global_index1 );
if (nnc_info) {
@@ -53,6 +54,7 @@ static void ecl_nnc_export__( const ecl_grid_type * grid , int lgr_index1 , con
const int_vector_type * nnc_index_list = nnc_vector_get_nnc_index_list( nnc_vector );
int lgr_nr2 = nnc_vector_get_lgr_nr( nnc_vector );
const ecl_kw_type * tran_kw = ecl_nnc_export_get_tranx_kw(global_grid , init_file , lgr_nr1 , lgr_nr2 );
int index2;
ecl_nnc_type nnc;
@@ -62,7 +64,12 @@ static void ecl_nnc_export__( const ecl_grid_type * grid , int lgr_index1 , con
for (index2 = 0; index2 < nnc_vector_get_size( nnc_vector ); index2++) {
nnc.global_index2 = int_vector_iget( grid2_index_list , index2 );
nnc.trans = ecl_kw_iget_as_double( tran_kw , int_vector_iget( nnc_index_list , index2));
if(tran_kw) {
nnc.trans = ecl_kw_iget_as_double(tran_kw, int_vector_iget(nnc_index_list, index2));
valid_trans++;
}else{
nnc.trans = ERT_ECL_DEFAULT_NNC_TRANS;
}
nnc_data[nnc_index] = nnc;
nnc_index++;
@@ -71,21 +78,24 @@ static void ecl_nnc_export__( const ecl_grid_type * grid , int lgr_index1 , con
}
}
*nnc_offset = nnc_index;
return valid_trans;
}
void ecl_nnc_export( const ecl_grid_type * grid , const ecl_file_type * init_file , ecl_nnc_type * nnc_data) {
int ecl_nnc_export( const ecl_grid_type * grid , const ecl_file_type * init_file , ecl_nnc_type * nnc_data) {
int nnc_index = 0;
ecl_nnc_export__( grid , 0 , init_file , nnc_data , &nnc_index );
int total_valid_trans = 0;
total_valid_trans = ecl_nnc_export__( grid , 0 , init_file , nnc_data , &nnc_index );
{
int lgr_index;
int lgr_index;
for (lgr_index = 0; lgr_index < ecl_grid_get_num_lgr(grid); lgr_index++) {
ecl_grid_type * igrid = ecl_grid_iget_lgr( grid , lgr_index );
ecl_nnc_export__( igrid , lgr_index , init_file , nnc_data , &nnc_index );
total_valid_trans += ecl_nnc_export__( igrid , lgr_index , init_file , nnc_data , &nnc_index );
}
}
nnc_index = ecl_nnc_export_get_size( grid );
ecl_nnc_sort( nnc_data , nnc_index );
return total_valid_trans;
}
@@ -93,21 +103,21 @@ void ecl_nnc_export( const ecl_grid_type * grid , const ecl_file_type * init_fi
int ecl_nnc_cmp( const ecl_nnc_type * nnc1 , const ecl_nnc_type * nnc2) {
if (nnc1->grid_nr1 != nnc2->grid_nr1) {
if (nnc1->grid_nr1 < nnc2->grid_nr1)
if (nnc1->grid_nr1 < nnc2->grid_nr1)
return -1;
else
return 1;
}
if (nnc1->grid_nr2 != nnc2->grid_nr2) {
if (nnc1->grid_nr2 < nnc2->grid_nr2)
if (nnc1->grid_nr2 < nnc2->grid_nr2)
return -1;
else
return 1;
}
if (nnc1->global_index1 != nnc2->global_index1) {
if (nnc1->global_index1 < nnc2->global_index1)
if (nnc1->global_index1 < nnc2->global_index1)
return -1;
else
return 1;
@@ -115,12 +125,12 @@ int ecl_nnc_cmp( const ecl_nnc_type * nnc1 , const ecl_nnc_type * nnc2) {
if (nnc1->global_index2 != nnc2->global_index2) {
if (nnc1->global_index2 < nnc2->global_index2)
if (nnc1->global_index2 < nnc2->global_index2)
return -1;
else
return 1;
}
return 0;
}
@@ -142,19 +152,19 @@ ecl_kw_type * ecl_nnc_export_get_tranll_kw( const ecl_grid_type * grid , const e
ecl_kw_type * tran_kw = NULL;
const int file_num_kw = ecl_file_get_size( init_file );
int global_kw_index = 0;
while (true) {
if (global_kw_index >= file_num_kw)
if (global_kw_index >= file_num_kw)
break;
{
ecl_kw_type * ecl_kw = ecl_file_iget_kw( init_file , global_kw_index );
if (strcmp( LGRJOIN_KW , ecl_kw_get_header( ecl_kw)) == 0) {
if (ecl_kw_icmp_string( ecl_kw , 0 , lgr_name1) && ecl_kw_icmp_string( ecl_kw , 1 , lgr_name2)) {
tran_kw = ecl_file_iget_kw( init_file , global_kw_index + 1);
break;
}
}
}
global_kw_index++;
}
}
@@ -166,47 +176,47 @@ ecl_kw_type * ecl_nnc_export_get_tranll_kw( const ecl_grid_type * grid , const e
ecl_kw_type * ecl_nnc_export_get_tran_kw( const ecl_file_type * init_file , const char * kw , int lgr_nr ) {
ecl_kw_type * tran_kw = NULL;
if (lgr_nr == 0) {
if (strcmp(kw , TRANNNC_KW) == 0)
tran_kw = ecl_file_iget_named_kw( init_file , TRANNNC_KW , 0 );
if(ecl_file_has_kw(init_file, kw)) {
tran_kw = ecl_file_iget_named_kw(init_file, TRANNNC_KW, 0);
}
} else {
if ((strcmp(kw , TRANNNC_KW) == 0) ||
(strcmp(kw , TRANGL_KW) == 0)) {
int tran_kw_forward_skip;
const int file_num_kw = ecl_file_get_size( init_file );
int global_kw_index = 0;
bool finished = false;
if (strcmp(kw , TRANNNC_KW) == 0)
tran_kw_forward_skip = 3;
else
tran_kw_forward_skip = 4;
while (!finished) {
bool correct_lgrheadi = false;
int head_index = 0;
int steps = 0;
while(!finished){
ecl_kw_type * ecl_kw = ecl_file_iget_kw( init_file , global_kw_index );
if (strcmp( LGRHEADI_KW , ecl_kw_get_header( ecl_kw )) == 0) {
const char *current_kw = ecl_kw_get_header(ecl_kw);
if (strcmp( LGRHEADI_KW , current_kw) == 0) {
if (ecl_kw_iget_int( ecl_kw , LGRHEADI_LGR_NR_INDEX) == lgr_nr) {
if ((global_kw_index + tran_kw_forward_skip) < file_num_kw) {
ecl_kw_type * ecl_kw = ecl_file_iget_kw( init_file , global_kw_index + tran_kw_forward_skip);
/* We found the TRANGL / TRANNC keyword we are after. */
if (strcmp( kw , ecl_kw_get_header( ecl_kw )) == 0) {
tran_kw = ecl_kw;
finished = true;
break;
}
correct_lgrheadi = true;
head_index = global_kw_index;
}else{
correct_lgrheadi = false;
}
}
if(correct_lgrheadi) {
if (strcmp(kw, current_kw) == 0) {
steps = global_kw_index - head_index; /* This is to calculate who fare from lgrheadi we found the TRANGL/TRANNNC key word */
if(steps == 3 || steps == 4 || steps == 6) { /* We only support a file format where TRANNNC is 3 steps and TRANGL is 4 or 6 steps from LGRHEADI */
tran_kw = ecl_kw;
finished = true;
break;
}
}
}
}
}
global_kw_index++;
if (global_kw_index == file_num_kw)
finished = true;
}
}
}
}
return tran_kw;
+116 -54
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_rft_file.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_rft_file.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <string.h>
@@ -46,9 +46,9 @@
All of this is just lumped together in one long vector, both in the
file, and in this implementation. The data for one specific RFT
(one well, one time) is internalized in the ecl_rft_node type.
(one well, one time) is internalized in the ecl_rft_node type.
*/
#define ECL_RFT_FILE_ID 6610632
@@ -73,7 +73,7 @@ static ecl_rft_file_type * ecl_rft_file_alloc_empty(const char * filename) {
/**
Generating the two functions:
bool ecl_rft_file_is_instance( void * );
ecl_rft_file_type * ecl_rft_file_safe_cast( void * );
*/
@@ -94,25 +94,25 @@ ecl_rft_file_type * ecl_rft_file_alloc(const char * filename) {
ecl_file_type * ecl_file = ecl_file_open( filename , 0);
int global_index = 0;
int block_nr = 0;
while (true) {
if (ecl_file_select_block( ecl_file , TIME_KW , block_nr)) {
ecl_rft_node_type * rft_node = ecl_rft_node_alloc( ecl_file );
if (rft_node != NULL) {
if (rft_node != NULL) {
const char * well_name = ecl_rft_node_get_well_name( rft_node );
ecl_rft_file_add_node(rft_vector , rft_node);
if (!hash_has_key( rft_vector->well_index , well_name))
if (!hash_has_key( rft_vector->well_index , well_name))
hash_insert_hash_owned_ref( rft_vector->well_index , well_name , int_vector_alloc( 0 , 0 ) , int_vector_free__);
{
int_vector_type * index_list = hash_get( rft_vector->well_index , well_name );
int_vector_append(index_list , global_index);
}
}
global_index++;
}
}
} else
break;
block_nr++;
}
}
ecl_file_close( ecl_file );
return rft_vector;
}
@@ -123,7 +123,7 @@ ecl_rft_file_type * ecl_rft_file_alloc(const char * filename) {
ecl_grid_load_case(). Will return NULL if no RFT file can be found,
and the name of RFT file if it is found. New storage is allocated
for the new name.
*/
char * ecl_rft_file_alloc_case_filename(const char * case_input ) {
@@ -140,20 +140,20 @@ char * ecl_rft_file_alloc_case_filename(const char * case_input ) {
if ((file_type == ECL_OTHER_FILE) || (file_type == ECL_DATA_FILE)) { /* Impossible to infer formatted/unformatted from the case_input */
char * RFT_file = ecl_util_alloc_filename( path , basename , ECL_RFT_FILE , false , -1 );
char * FRFT_file = ecl_util_alloc_filename( path , basename , ECL_RFT_FILE , true , -1 );
if (util_file_exists( RFT_file ))
return_file = util_alloc_string_copy( RFT_file );
else if (util_file_exists( FRFT_file ))
return_file = util_alloc_string_copy( FRFT_file );
free( RFT_file );
free( FRFT_file );
} else {
char * RFT_file = ecl_util_alloc_filename( path , basename , ECL_RFT_FILE , fmt_file , -1 );
if (util_file_exists( RFT_file ))
return_file = util_alloc_string_copy( RFT_file );
free( RFT_file );
}
return return_file;
@@ -183,7 +183,7 @@ bool ecl_rft_file_case_has_rft( const char * case_input ) {
has_rft = true;
free( file_name );
}
return has_rft;
}
@@ -202,7 +202,7 @@ void ecl_rft_file_free__(void * arg) {
}
/**
/**
Will return the number of RFT nodes in the file. If @well != NULL
only wells matching @well be included. The @well variable can
contain '*', so the function call
@@ -210,7 +210,7 @@ void ecl_rft_file_free__(void * arg) {
ecl_rft_file_get_size__( rft_file , "OP*" , -1)
will count the number of rft instances with a well name matching
well "OP*".
well "OP*".
If recording_time >= only rft_nodes with recording time ==
@recording_time are included.
@@ -262,7 +262,7 @@ const char * ecl_rft_file_get_filename( const ecl_rft_file_type * rft_file ) {
/**
Return rft_node number 'i' in the rft_file - not caring when this
particular RFT is from, or which well it is.
particular RFT is from, or which well it is.
If you ask for an index which is beyond the size of the vector it will
go up in flames - use ecl_file_get_size() first if you can not
@@ -286,9 +286,9 @@ ecl_rft_node_type * ecl_rft_file_iget_node( const ecl_rft_file_type * rft_file ,
RFT - Well P1: 01/01/2002
RFT - Well P2: 01/01/2002
The function call:
The function call:
ecl_rft_iget_well_rft(rft_file , "P2" , 1)
ecl_rft_iget_well_rft(rft_file , "P2" , 1)
will return the rft node indicated by the arrow (i.e. the second
occurence of well "P2" in the file.)
@@ -307,6 +307,29 @@ ecl_rft_node_type * ecl_rft_file_iget_well_rft( const ecl_rft_file_type * rft_fi
}
static int ecl_rft_file_get_node_index_time_rft( const ecl_rft_file_type * rft_file , const char * well , time_t recording_time) {
int global_index = -1;
if (hash_has_key( rft_file->well_index , well)) {
const int_vector_type * index_vector = hash_get(rft_file->well_index , well);
int well_index = 0;
while (true) {
if (well_index == int_vector_size( index_vector ))
break;
{
const ecl_rft_node_type * node = ecl_rft_file_iget_node( rft_file , int_vector_iget( index_vector , well_index ));
if (ecl_rft_node_get_date( node ) == recording_time) {
global_index = int_vector_iget( index_vector , well_index );
break;
}
}
well_index++;
}
}
return global_index;
}
/**
Returns an rft_node for well 'well' and time 'recording_time'. If
@@ -316,28 +339,17 @@ ecl_rft_node_type * ecl_rft_file_iget_well_rft( const ecl_rft_file_type * rft_fi
ecl_rft_node_type * ecl_rft_file_get_well_time_rft( const ecl_rft_file_type * rft_file , const char * well , time_t recording_time) {
ecl_rft_node_type * node = NULL;
if (hash_has_key( rft_file->well_index , well)) {
const int_vector_type * index_vector = hash_get(rft_file->well_index , well);
int index = 0;
while (true) {
if (index == int_vector_size( index_vector ))
break;
node = ecl_rft_file_iget_node( rft_file , int_vector_iget( index_vector , index ));
if (ecl_rft_node_get_date( node ) == recording_time)
break;
else {
node = NULL;
index++;
}
}
int index = ecl_rft_file_get_node_index_time_rft(rft_file, well, recording_time);
if (index !=-1) {
return ecl_rft_file_iget_node(rft_file, index);
} else{
return NULL;
}
return node;
}
bool ecl_rft_file_has_well( const ecl_rft_file_type * rft_file , const char * well) {
return hash_has_key(rft_file->well_index , well);
}
@@ -353,7 +365,7 @@ int ecl_rft_file_get_well_occurences( const ecl_rft_file_type * rft_file , const
}
/**
/**
Returns the number of distinct wells in RFT file.
*/
int ecl_rft_file_get_num_wells( const ecl_rft_file_type * rft_file ) {
@@ -368,5 +380,55 @@ stringlist_type * ecl_rft_file_alloc_well_list(const ecl_rft_file_type * rft_fil
void ecl_rft_file_update(const char * rft_file_name, ecl_rft_node_type ** nodes,int num_nodes, ert_ecl_unit_enum unit_set){
ecl_rft_file_type * rft_file;
if(util_file_exists(rft_file_name)){
int node_index;
rft_file = ecl_rft_file_alloc( rft_file_name );
for(node_index = 0; node_index < num_nodes; node_index++) {
ecl_rft_node_type * new_node = nodes[node_index];
int storage_index = ecl_rft_file_get_node_index_time_rft(rft_file, ecl_rft_node_get_well_name(new_node), ecl_rft_node_get_date(new_node));
if (storage_index == -1) {
ecl_rft_file_add_node(rft_file, new_node);
} else {
vector_iset_owned_ref(rft_file->data, storage_index, new_node,ecl_rft_node_free__);
}
}
}else{
int node_index;
rft_file = ecl_rft_file_alloc_empty( rft_file_name );
for(node_index = 0; node_index < num_nodes; node_index++) {
ecl_rft_file_add_node(rft_file, nodes[node_index]);
}
}
{
bool fmt_file = false;
fortio_type * fortio = fortio_open_writer( rft_file_name , fmt_file , ECL_ENDIAN_FLIP );
int node_index;
/**
The sorting here works directly on the internal node storage
rft_file->data; that might in principle ruin the indexing of
the ecl_file object - it is therefor absolutely essential
that this ecl_rft_file object does not live beyond this
function, and also that the ecl_rft_file api functions are
avoided for the rest of this function.
*/
vector_sort(rft_file->data,(vector_cmp_ftype *) ecl_rft_node_cmp);
for(node_index=0; node_index < vector_get_size( rft_file->data ); node_index++) {
const ecl_rft_node_type *new_node = vector_iget_const(rft_file->data, node_index);
ecl_rft_node_fwrite(new_node, fortio, unit_set);
}
fortio_fclose( fortio );
}
ecl_rft_file_free(rft_file);
}
+237 -63
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_rft_node.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_rft_node.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <math.h>
@@ -34,13 +34,14 @@
#include <ert/ecl/ecl_rft_node.h>
#include <ert/ecl/ecl_rft_cell.h>
/**
/**
The RFT's from several wells, and possibly also several timesteps
are lumped togeheter in one .RFT file. The ecl_rft_node
implemented in this file contains the information for one
well/report step.
well/report step.
*/
/*
@@ -57,13 +58,13 @@ struct ecl_rft_node_struct {
char * well_name; /* Name of the well. */
ecl_rft_enum data_type; /* What type of data: RFT|PLT|SEGMENT */
time_t recording_date; /* When was the RFT recorded - date.*/
time_t recording_date; /* When was the RFT recorded - date.*/
double days; /* When was the RFT recorded - days after simulaton start. */
bool MSW;
bool sort_perm_in_sync ;
bool sort_perm_in_sync ;
int_vector_type * sort_perm;
vector_type *cells;
vector_type *cells;
};
@@ -72,20 +73,39 @@ struct ecl_rft_node_struct {
Will return NULL if the data_type_string is equal to "SEGMENT" -
that is not (yet) supported.
*/
static ecl_rft_enum translate_from_sting_to_ecl_rft_enum(const char * data_type_string){
ecl_rft_enum data_type = SEGMENT;
/* According to the ECLIPSE documentaton. */
if (strchr(data_type_string , 'P') != NULL)
data_type = PLT;
else if (strchr(data_type_string, 'R') != NULL)
data_type = RFT;
else if (strchr(data_type_string , 'S') != NULL)
data_type = SEGMENT;
else
util_abort("%s: Could not determine type of RFT/PLT/SEGMENT data - aborting\n",__func__);
return data_type;
}
ecl_rft_node_type * ecl_rft_node_alloc_new(const char * well_name, const char * data_type_string, const time_t recording_date, const double days){
ecl_rft_enum data_type = translate_from_sting_to_ecl_rft_enum(data_type_string);
ecl_rft_node_type * rft_node = util_malloc(sizeof * rft_node );
UTIL_TYPE_ID_INIT( rft_node , ECL_RFT_NODE_ID );
rft_node->well_name = util_alloc_string_copy(well_name);
rft_node->cells = vector_alloc_new();
rft_node->recording_date = recording_date;
rft_node->days = days;
rft_node->data_type = data_type;
rft_node->sort_perm = NULL;
rft_node->sort_perm_in_sync = false;
return rft_node;
}
static ecl_rft_node_type * ecl_rft_node_alloc_empty(const char * data_type_string) {
ecl_rft_enum data_type = SEGMENT;
/* According to the ECLIPSE documentaton. */
if (strchr(data_type_string , 'P') != NULL)
data_type = PLT;
else if (strchr(data_type_string, 'R') != NULL)
data_type = RFT;
else if (strchr(data_type_string , 'S') != NULL)
data_type = SEGMENT;
else
util_abort("%s: Could not determine type of RFT/PLT/SEGMENT data - aborting\n",__func__);
ecl_rft_enum data_type = translate_from_sting_to_ecl_rft_enum(data_type_string);
/* Can return NULL */
if (data_type == SEGMENT) {
@@ -96,12 +116,12 @@ static ecl_rft_node_type * ecl_rft_node_alloc_empty(const char * data_type_strin
{
ecl_rft_node_type * rft_node = util_malloc(sizeof * rft_node );
UTIL_TYPE_ID_INIT( rft_node , ECL_RFT_NODE_ID );
rft_node->cells = vector_alloc_new();
rft_node->data_type = data_type;
rft_node->sort_perm = NULL;
rft_node->sort_perm_in_sync = false;
return rft_node;
}
}
@@ -111,7 +131,7 @@ UTIL_SAFE_CAST_FUNCTION( ecl_rft_node , ECL_RFT_NODE_ID );
UTIL_IS_INSTANCE_FUNCTION( ecl_rft_node , ECL_RFT_NODE_ID );
static void ecl_rft_node_append_cell( ecl_rft_node_type * rft_node , ecl_rft_cell_type * cell) {
void ecl_rft_node_append_cell( ecl_rft_node_type * rft_node , ecl_rft_cell_type * cell) {
vector_append_owned_ref( rft_node->cells , cell , ecl_rft_cell_free__ );
rft_node->sort_perm_in_sync = false;
}
@@ -134,35 +154,35 @@ static void ecl_rft_node_init_RFT_cells( ecl_rft_node_type * rft_node , const ec
const int * i = ecl_kw_get_int_ptr( conipos );
const int * j = ecl_kw_get_int_ptr( conjpos );
const int * k = ecl_kw_get_int_ptr( conkpos );
{
int c;
for (c = 0; c < ecl_kw_get_size( conipos ); c++) {
/* The connection coordinates are shifted -= 1; i.e. all internal usage is offset 0. */
ecl_rft_cell_type * cell = ecl_rft_cell_alloc_RFT( i[c] - 1 , j[c] - 1 , k[c] - 1 ,
ecl_rft_cell_type * cell = ecl_rft_cell_alloc_RFT( i[c] - 1 , j[c] - 1 , k[c] - 1 ,
depth[c] , P[c] , SW[c] , SG[c]);
ecl_rft_node_append_cell( rft_node , cell );
}
}
}
static void ecl_rft_node_init_PLT_cells( ecl_rft_node_type * rft_node , const ecl_file_type * rft) {
/* For PLT there is quite a lot of extra information which is not yet internalized. */
const ecl_kw_type * conipos = ecl_file_iget_named_kw( rft , CONIPOS_KW , 0);
const ecl_kw_type * conjpos = ecl_file_iget_named_kw( rft , CONJPOS_KW , 0);
const ecl_kw_type * conkpos = ecl_file_iget_named_kw( rft , CONKPOS_KW , 0);
const ecl_kw_type * conkpos = ecl_file_iget_named_kw( rft , CONKPOS_KW , 0);
const int * i = ecl_kw_get_int_ptr( conipos );
const int * j = ecl_kw_get_int_ptr( conjpos );
const int * k = ecl_kw_get_int_ptr( conkpos );
const float * WR = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONWRAT_KW , 0));
const float * GR = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONGRAT_KW , 0));
const float * OR = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONORAT_KW , 0));
const float * GR = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONGRAT_KW , 0));
const float * OR = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONORAT_KW , 0));
const float * P = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONPRES_KW , 0));
const float * depth = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONDEPTH_KW , 0));
const float * flowrate = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONVTUB_KW , 0));
@@ -170,12 +190,12 @@ static void ecl_rft_node_init_PLT_cells( ecl_rft_node_type * rft_node , const ec
const float * gas_flowrate = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONGTUB_KW , 0));
const float * water_flowrate = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONWTUB_KW , 0));
const float * connection_start = NULL;
const float * connection_end = NULL;
const float * connection_end = NULL;
/* The keywords CONLENST_KW and CONLENEN_KW are ONLY present if we are dealing with a MSW well. */
if (ecl_file_has_kw( rft , CONLENST_KW))
connection_start = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONLENST_KW , 0));
if (ecl_file_has_kw( rft , CONLENEN_KW))
connection_end = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONLENEN_KW , 0));
@@ -185,15 +205,15 @@ static void ecl_rft_node_init_PLT_cells( ecl_rft_node_type * rft_node , const ec
ecl_rft_cell_type * cell;
double cs = 0;
double ce = 0;
if (connection_start)
cs = connection_start[c];
if (connection_end)
ce = connection_end[c];
/* The connection coordinates are shifted -= 1; i.e. all internal usage is offset 0. */
cell = ecl_rft_cell_alloc_PLT( i[c] -1 , j[c] -1 , k[c] -1 ,
cell = ecl_rft_cell_alloc_PLT( i[c] -1 , j[c] -1 , k[c] -1 ,
depth[c] , P[c] , OR[c] , GR[c] , WR[c] , cs , ce, flowrate[c] , oil_flowrate[c] , gas_flowrate[c] , water_flowrate[c]);
ecl_rft_node_append_cell( rft_node , cell );
}
@@ -210,18 +230,18 @@ static void ecl_rft_node_init_cells( ecl_rft_node_type * rft_node , const ecl_fi
ecl_rft_node_init_RFT_cells( rft_node , rft );
else if (rft_node->data_type == PLT)
ecl_rft_node_init_PLT_cells( rft_node , rft );
}
ecl_rft_node_type * ecl_rft_node_alloc(const ecl_file_type * rft) {
ecl_kw_type * welletc = ecl_file_iget_named_kw(rft , WELLETC_KW , 0);
ecl_rft_node_type * rft_node = ecl_rft_node_alloc_empty(ecl_kw_iget_ptr(welletc , WELLETC_TYPE_INDEX));
if (rft_node != NULL) {
ecl_kw_type * date_kw = ecl_file_iget_named_kw( rft , DATE_KW , 0);
rft_node->well_name = util_alloc_strip_copy( ecl_kw_iget_ptr(welletc , WELLETC_NAME_INDEX));
/* Time information. */
{
int * time = ecl_kw_get_int_ptr( date_kw );
@@ -238,9 +258,9 @@ ecl_rft_node_type * ecl_rft_node_alloc(const ecl_file_type * rft) {
return rft_node;
}
const char * ecl_rft_node_get_well_name(const ecl_rft_node_type * rft_node) {
return rft_node->well_name;
const char * ecl_rft_node_get_well_name(const ecl_rft_node_type * rft_node) {
return rft_node->well_name;
}
@@ -279,7 +299,7 @@ const ecl_rft_cell_type * ecl_rft_node_iget_cell( const ecl_rft_node_type * rft_
static void ecl_rft_node_create_sort_perm( ecl_rft_node_type * rft_node ) {
if (rft_node->sort_perm)
int_vector_free( rft_node->sort_perm );
rft_node->sort_perm = vector_alloc_sort_perm( rft_node->cells , ecl_rft_cell_cmp__ );
rft_node->sort_perm_in_sync = true;
}
@@ -295,7 +315,7 @@ const ecl_rft_cell_type * ecl_rft_node_iget_cell_sorted( ecl_rft_node_type * rft
else {
if (!rft_node->sort_perm_in_sync)
ecl_rft_node_create_sort_perm( rft_node );
return vector_iget_const( rft_node->cells , int_vector_iget( rft_node->sort_perm , index ));
}
}
@@ -317,20 +337,20 @@ double ecl_rft_node_iget_pressure( const ecl_rft_node_type * rft_node , int inde
void ecl_rft_node_iget_ijk( const ecl_rft_node_type * rft_node , int index , int *i , int *j , int *k) {
const ecl_rft_cell_type * cell = ecl_rft_node_iget_cell( rft_node , index );
ecl_rft_cell_get_ijk( cell , i,j,k);
}
const ecl_rft_cell_type * ecl_rft_node_lookup_ijk( const ecl_rft_node_type * rft_node , int i, int j , int k) {
int index = 0;
const ecl_rft_cell_type * ecl_rft_node_lookup_ijk( const ecl_rft_node_type * rft_node , int i, int j , int k) {
int index = 0;
int size = ecl_rft_node_get_size( rft_node );
while (true) {
const ecl_rft_cell_type * cell = ecl_rft_node_iget_cell( rft_node , index );
if (ecl_rft_cell_ijk_equal( cell , i , j , k ))
return cell;
index++;
if (index == size) /* Could not find it. */
return NULL;
@@ -364,6 +384,9 @@ double ecl_rft_node_iget_swat( const ecl_rft_node_type * rft_node , int index) {
}
}
double ecl_rft_node_get_days(const ecl_rft_node_type * rft_node ){
return rft_node->days;
}
double ecl_rft_node_iget_soil( const ecl_rft_node_type * rft_node , int index) {
assert_type_and_index( rft_node , RFT , index );
@@ -429,4 +452,155 @@ bool ecl_rft_node_is_RFT( const ecl_rft_node_type * rft_node ) {
return false;
}
static void ecl_rft_node_fill_welletc(ecl_kw_type * welletc, ert_ecl_unit_enum unit_set){
if(unit_set==ERT_ECL_METRIC_UNITS) {
ecl_kw_iset_string8(welletc, 0, " DAYS");
ecl_kw_iset_string8(welletc, 2, "");
ecl_kw_iset_string8(welletc, 3, " METRES");
ecl_kw_iset_string8(welletc, 4, " BARSA");
ecl_kw_iset_string8(welletc, 6, "STANDARD");
ecl_kw_iset_string8(welletc, 7, " SM3/DAY");
ecl_kw_iset_string8(welletc, 8, " SM3/DAY");
ecl_kw_iset_string8(welletc, 9, " RM3/DAY");
ecl_kw_iset_string8(welletc, 10, " M/SEC");
ecl_kw_iset_string8(welletc, 11, "");
ecl_kw_iset_string8(welletc, 12, " CP");
ecl_kw_iset_string8(welletc, 13, " KG/SM3");
ecl_kw_iset_string8(welletc, 14, " KG/DAY");
ecl_kw_iset_string8(welletc, 15, " KG/KG");
}else if(unit_set==ERT_ECL_FIELD_UNITS){
ecl_kw_iset_string8(welletc, 0, " DAYS");
ecl_kw_iset_string8(welletc, 2, "");
ecl_kw_iset_string8(welletc, 3, " FEET");
ecl_kw_iset_string8(welletc, 4, " PISA");
ecl_kw_iset_string8(welletc, 6, "STANDARD");
ecl_kw_iset_string8(welletc, 7, " STB/DAY");
ecl_kw_iset_string8(welletc, 8, " MSCF/DAY");
ecl_kw_iset_string8(welletc, 9, " RB/DAY");
ecl_kw_iset_string8(welletc, 10, " FT/SEC");
ecl_kw_iset_string8(welletc, 11, "");
ecl_kw_iset_string8(welletc, 12, " CP");
ecl_kw_iset_string8(welletc, 13, " LB/STB");
ecl_kw_iset_string8(welletc, 14, " LB/DAY");
ecl_kw_iset_string8(welletc, 15, " LB/LB");
}else if(unit_set==ERT_ECL_LAB_UNITS){
ecl_kw_iset_string8(welletc, 0, " HR");
ecl_kw_iset_string8(welletc, 2, "");
ecl_kw_iset_string8(welletc, 3, " CM");
ecl_kw_iset_string8(welletc, 4, " ATMA");
ecl_kw_iset_string8(welletc, 6, "STANDARD");
ecl_kw_iset_string8(welletc, 7, " SCC/HR");
ecl_kw_iset_string8(welletc, 8, " SCC/HR");
ecl_kw_iset_string8(welletc, 9, " RCC/SCC");
ecl_kw_iset_string8(welletc, 10, " CM/SEC");
ecl_kw_iset_string8(welletc, 11, "");
ecl_kw_iset_string8(welletc, 12, " CP");
ecl_kw_iset_string8(welletc, 13, " GM/SCC");
ecl_kw_iset_string8(welletc, 14, " GH/HR");
ecl_kw_iset_string8(welletc, 15, " GM/GM");
}
}
void ecl_rft_node_fwrite(const ecl_rft_node_type * rft_node, fortio_type * fortio, ert_ecl_unit_enum unit_set){
ecl_rft_enum type = ecl_rft_node_get_type(rft_node);
if (type != RFT)
util_abort("%s: sorry - only writing of simple RFT is currently implemented",__func__);
{
ecl_kw_type * time = ecl_kw_alloc(TIME_KW, 1, ECL_FLOAT_TYPE);
ecl_kw_iset_float(time, 0, ecl_rft_node_get_days(rft_node));
ecl_kw_fwrite(time, fortio);
ecl_kw_free(time);
}
{
ecl_kw_type * datevalue = ecl_kw_alloc(DATE_KW, 3, ECL_INT_TYPE);
time_t date = ecl_rft_node_get_date(rft_node);
int day;
int month;
int year;
ecl_util_set_date_values(date , &day , &month , &year);
ecl_kw_iset_int(datevalue, 0, day);
ecl_kw_iset_int(datevalue, 1, month);
ecl_kw_iset_int(datevalue, 2, year);
ecl_kw_fwrite(datevalue, fortio);
ecl_kw_free(datevalue);
}
{
ecl_kw_type * welletc = ecl_kw_alloc(WELLETC_KW, 16, ECL_CHAR_TYPE);
ecl_rft_enum type = ecl_rft_node_get_type(rft_node);
ecl_kw_iset_string8(welletc, 1, ecl_rft_node_get_well_name(rft_node));
if(type == PLT) {
ecl_kw_iset_string8(welletc, 5, "P");
}else if(type == RFT){
ecl_kw_iset_string8(welletc, 5, "R");
}else if(type == SEGMENT){
ecl_kw_iset_string8(welletc, 5, "S");
}
ecl_rft_node_fill_welletc(welletc, unit_set);
ecl_kw_fwrite(welletc, fortio);
ecl_kw_free(welletc);
}
{
int size_cells = ecl_rft_node_get_size(rft_node);
ecl_kw_type * conipos = ecl_kw_alloc(CONIPOS_KW, size_cells, ECL_INT_TYPE);
ecl_kw_type * conjpos = ecl_kw_alloc(CONJPOS_KW, size_cells, ECL_INT_TYPE);
ecl_kw_type * conkpos = ecl_kw_alloc(CONKPOS_KW, size_cells, ECL_INT_TYPE);
ecl_kw_type * hostgrid = ecl_kw_alloc(HOSTGRID_KW, size_cells, ECL_CHAR_TYPE);
ecl_kw_type * depth = ecl_kw_alloc(DEPTH_KW, size_cells, ECL_FLOAT_TYPE);
ecl_kw_type * pressure = ecl_kw_alloc(PRESSURE_KW, size_cells, ECL_FLOAT_TYPE);
ecl_kw_type * swat = ecl_kw_alloc(SWAT_KW, size_cells, ECL_FLOAT_TYPE);
ecl_kw_type * sgas = ecl_kw_alloc(SGAS_KW, size_cells, ECL_FLOAT_TYPE);
int i;
for(i =0;i<size_cells;i++){
const ecl_rft_cell_type * cell = vector_iget_const( rft_node->cells , i);
ecl_kw_iset_int(conipos, i, ecl_rft_cell_get_i(cell)+1);
ecl_kw_iset_int(conjpos, i, ecl_rft_cell_get_j(cell)+1);
ecl_kw_iset_int(conkpos, i, ecl_rft_cell_get_k(cell)+1);
ecl_kw_iset_float(depth, i, ecl_rft_cell_get_depth(cell));
ecl_kw_iset_float(pressure, i, ecl_rft_cell_get_pressure(cell));
ecl_kw_iset_float(swat, i, ecl_rft_cell_get_swat(cell));
ecl_kw_iset_float(sgas, i, ecl_rft_cell_get_sgas(cell));
}
ecl_kw_fwrite(conipos, fortio);
ecl_kw_fwrite(conjpos, fortio);
ecl_kw_fwrite(conkpos, fortio);
ecl_kw_fwrite(hostgrid, fortio);
ecl_kw_fwrite(depth, fortio);
ecl_kw_fwrite(pressure, fortio);
ecl_kw_fwrite(swat, fortio);
ecl_kw_fwrite(sgas, fortio);
ecl_kw_free(conipos);
ecl_kw_free(conjpos);
ecl_kw_free(conkpos);
ecl_kw_free(hostgrid);
ecl_kw_free(depth);
ecl_kw_free(pressure);
ecl_kw_free(swat);
ecl_kw_free(sgas);
}
}
int ecl_rft_node_cmp( const ecl_rft_node_type * n1 , const ecl_rft_node_type * n2) {
time_t val1 = ecl_rft_node_get_date(n1);
time_t val2 = ecl_rft_node_get_date(n2);
if (val1 < val2)
return -1;
else if (val1 == val2)
return 0;
else
return 1;
}
+27 -26
View File
@@ -35,13 +35,15 @@
#include <ert/ecl/ecl_kw_magic.h>
#include <ert/ecl/ecl_file_kw.h>
#include <ert/ecl/ecl_rst_file.h>
#include <ert/ecl/ecl_rsthead.h>
struct ecl_rst_file_struct {
fortio_type * fortio;
bool unified;
bool fmt_file;
};
static ecl_rst_file_type * ecl_rst_file_alloc( const char * filename ) {
bool unified = ecl_util_unified_file( filename );
@@ -112,46 +114,42 @@ void ecl_rst_file_end_solution( ecl_rst_file_type * rst_file ) {
static ecl_kw_type * ecl_rst_file_alloc_INTEHEAD( ecl_rst_file_type * rst_file , time_t date , int nx , int ny , int nz , int nactive , int phases, int simulator ) {
static ecl_kw_type * ecl_rst_file_alloc_INTEHEAD( ecl_rst_file_type * rst_file,
ecl_rsthead_type * rsthead,
int simulator ) {
ecl_kw_type * intehead_kw = ecl_kw_alloc( INTEHEAD_KW , INTEHEAD_RESTART_SIZE , ECL_INT_TYPE );
ecl_kw_scalar_set_int( intehead_kw , 0 );
ecl_kw_iset_int( intehead_kw , INTEHEAD_UNIT_INDEX , INTEHEAD_METRIC_VALUE );
ecl_kw_iset_int( intehead_kw , INTEHEAD_NX_INDEX , nx);
ecl_kw_iset_int( intehead_kw , INTEHEAD_NY_INDEX , ny);
ecl_kw_iset_int( intehead_kw , INTEHEAD_NZ_INDEX , nz);
ecl_kw_iset_int( intehead_kw , INTEHEAD_NACTIVE_INDEX , nactive);
ecl_kw_iset_int( intehead_kw , INTEHEAD_PHASE_INDEX , phases );
ecl_kw_iset_int( intehead_kw , INTEHEAD_NX_INDEX , rsthead->nx);
ecl_kw_iset_int( intehead_kw , INTEHEAD_NY_INDEX , rsthead->ny);
ecl_kw_iset_int( intehead_kw , INTEHEAD_NZ_INDEX , rsthead->nz);
ecl_kw_iset_int( intehead_kw , INTEHEAD_NACTIVE_INDEX , rsthead->nactive);
ecl_kw_iset_int( intehead_kw , INTEHEAD_PHASE_INDEX , rsthead->phase_sum );
/* All well properties are hardcoded to zero. */
{
int NIWELZ = 0;
int NGMAXZ = 0;
int NWGMAX = 0;
int NWELLS = 0;
int NCWMAX = 0;
int NZWELZ = 0;
int NICONZ = 0;
int NIGRPZ = 0;
int NSWLMX = 0;
int NSEGMX = 0;
int NISEGZ = 0;
ecl_kw_iset_int( intehead_kw , INTEHEAD_NWELLS_INDEX , NWELLS );
ecl_kw_iset_int( intehead_kw , INTEHEAD_NCWMAX_INDEX , NCWMAX );
ecl_kw_iset_int( intehead_kw , INTEHEAD_NWELLS_INDEX , rsthead->nwells );
ecl_kw_iset_int( intehead_kw , INTEHEAD_NCWMAX_INDEX , rsthead->ncwmax );
ecl_kw_iset_int( intehead_kw , INTEHEAD_NWGMAX_INDEX , NWGMAX );
ecl_kw_iset_int( intehead_kw , INTEHEAD_NGMAXZ_INDEX , NGMAXZ );
ecl_kw_iset_int( intehead_kw , INTEHEAD_NIWELZ_INDEX , NIWELZ );
ecl_kw_iset_int( intehead_kw , INTEHEAD_NZWELZ_INDEX , NZWELZ );
ecl_kw_iset_int( intehead_kw , INTEHEAD_NICONZ_INDEX , NICONZ );
ecl_kw_iset_int( intehead_kw , INTEHEAD_NIWELZ_INDEX , rsthead->niwelz );
ecl_kw_iset_int( intehead_kw , INTEHEAD_NZWELZ_INDEX , rsthead->nzwelz );
ecl_kw_iset_int( intehead_kw , INTEHEAD_NICONZ_INDEX , rsthead->niconz );
ecl_kw_iset_int( intehead_kw , INTEHEAD_NIGRPZ_INDEX , NIGRPZ );
{
int mday,month,year;
util_set_date_values( date , &mday , &month , &year );
ecl_kw_iset_int( intehead_kw , INTEHEAD_DAY_INDEX , mday );
ecl_kw_iset_int( intehead_kw , INTEHEAD_MONTH_INDEX , month );
ecl_kw_iset_int( intehead_kw , INTEHEAD_YEAR_INDEX , year );
util_set_date_values( rsthead->sim_time , &rsthead->day , &rsthead->month , &rsthead->year );
ecl_kw_iset_int( intehead_kw , INTEHEAD_DAY_INDEX , rsthead->day );
ecl_kw_iset_int( intehead_kw , INTEHEAD_MONTH_INDEX , rsthead->month );
ecl_kw_iset_int( intehead_kw , INTEHEAD_YEAR_INDEX , rsthead->year );
}
ecl_kw_iset_int( intehead_kw , INTEHEAD_IPROG_INDEX , simulator);
@@ -195,12 +193,15 @@ static ecl_kw_type * ecl_rst_file_alloc_DOUBHEAD( ecl_rst_file_type * rst_file ,
void ecl_rst_file_fwrite_header( ecl_rst_file_type * rst_file , int seqnum , time_t date , double days , int nx , int ny ,int nz , int nactive , int phases) {
void ecl_rst_file_fwrite_header( ecl_rst_file_type * rst_file ,
int seqnum ,
ecl_rsthead_type * rsthead_data ) {
if (rst_file->unified)
ecl_rst_file_fwrite_SEQNUM( rst_file , seqnum );
{
ecl_kw_type * intehead_kw = ecl_rst_file_alloc_INTEHEAD( rst_file , date , nx , ny , nz , nactive , phases , INTEHEAD_ECLIPSE100_VALUE);
ecl_kw_type * intehead_kw = ecl_rst_file_alloc_INTEHEAD( rst_file , rsthead_data , INTEHEAD_ECLIPSE100_VALUE);
ecl_kw_fwrite( intehead_kw , rst_file->fortio );
ecl_kw_free( intehead_kw );
}
@@ -213,14 +214,14 @@ void ecl_rst_file_fwrite_header( ecl_rst_file_type * rst_file , int seqnum , tim
{
ecl_kw_type * doubhead_kw = ecl_rst_file_alloc_DOUBHEAD( rst_file , days );
ecl_kw_type * doubhead_kw = ecl_rst_file_alloc_DOUBHEAD( rst_file , rsthead_data->sim_days );
ecl_kw_fwrite( doubhead_kw , rst_file->fortio );
ecl_kw_free( doubhead_kw );
}
}
void ecl_rst_file_add_kw(ecl_rst_file_type * rst_file , const ecl_kw_type * ecl_kw ) {
ecl_kw_fwrite( ecl_kw , rst_file->fortio );
}
+65 -59
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_rstfile.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_rstfile.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
/*****************************************************************/
@@ -24,10 +24,10 @@
/*
This file is included from the ecl_file.c file with a #include
statement, i.e. it is the same compilation unit as ecl_file. The
separation is only to increase readability.
separation is only to increase readability.
*/
/*
/*
There is no special datastructure for working with restart files,
they are 100% stock ecl_file instances with the following limited
structure:
@@ -61,12 +61,12 @@ keyword, the value in [] corresponds to the relevant part of the
content of the keyword on the line, the labels A,B,C,D,E are used for
references in the text below.
0 | SEQNUM [0] \ A
0 | SEQNUM [0] \ A
1 | INTEHEAD [01.01.2005] |
2 | PRESSURE [... ] |
3 | SWAT [...] |
2 | PRESSURE [... ] |
3 | SWAT [...] |
| -----------------------+
4 | SEQNUM [5] | B
4 | SEQNUM [5] | B
5 | INTEHEAD [01.06.2005] |
6 | PRESSURE [... ] |
7 | SWAT [...] |
@@ -86,7 +86,7 @@ references in the text below.
13 | INTEHEAD [01.12.2009] |
14 | PRESSURE [...] |
15 | SWAT [...] /
This restart file has the following features:
@@ -98,7 +98,7 @@ This restart file has the following features:
datafile. Observe that the file does not have the block structure
visualized on this figure, the only thing separating the blocks in
the file is the occurence of a SEQNUM keyword.
o Only a few of the report steps are present, namely 0, 5, 10, 20 and
40.
@@ -124,7 +124,7 @@ we have introduced the following concepts:
the DAY, MONTH and YEAR values from an INTEHEAD keyword instance
and convert to a time_t instance. The functions:
ecl_file_get_unrstmap_sim_time() and ecl_file_has_has_sim_time()
ecl_file_get_unrstmap_sim_time() and ecl_file_has_has_sim_time()
can be used to query for simulation times and get the
corresponding block maps.
@@ -160,8 +160,8 @@ static time_t file_map_iget_restart_sim_date(const file_map_type * file_map , in
ecl_kw_type * intehead_kw = file_map_iget_named_kw( seqnum_map , INTEHEAD_KW , 0);
sim_time = ecl_rsthead_date( intehead_kw );
file_map_free( seqnum_map );
}
}
return sim_time;
}
@@ -174,8 +174,8 @@ static double file_map_iget_restart_sim_days(const file_map_type * file_map , in
ecl_kw_type * doubhead_kw = file_map_iget_named_kw( seqnum_map , DOUBHEAD_KW , 0);
sim_days = ecl_kw_iget_double( doubhead_kw , DOUBHEAD_DAYS_INDEX);
file_map_free( seqnum_map );
}
}
return sim_days;
}
@@ -232,13 +232,13 @@ static int file_map_find_sim_time(const file_map_type * file_map , time_t sim_ti
If the sim_time can not be found the function will return -1, that
includes the case when the file in question is not a restart file
at all, and no INTEHEAD headers can be found.
Observe that the function requires on-the-second-equality; which is
of course quite strict.
Each report step only has one occurence of SEQNUM, but one INTEHEAD
for each LGR; i.e. one should call iselect_rstblock() prior to
calling this function.
calling this function.
*/
@@ -255,13 +255,13 @@ static bool file_map_has_sim_time( const file_map_type * file_map , time_t sim_t
int intehead_index = 0;
while (true) {
time_t itime = file_map_iget_restart_sim_date( file_map , intehead_index );
if (itime == sim_time) /* Perfect hit. */
return true;
if (itime > sim_time) /* We have gone past the target_time - i.e. we do not have it. */
return false;
intehead_index++;
if (intehead_index == num_INTEHEAD) /* We have iterated through the whole thing without finding sim_time. */
return false;
@@ -274,7 +274,7 @@ static int file_map_seqnum_index_from_sim_time( file_map_type * parent_map , tim
int num_seqnum = file_map_get_num_named_kw( parent_map , SEQNUM_KW );
int seqnum_index = 0;
file_map_type * seqnum_map;
while (true) {
seqnum_map = file_map_alloc_blockmap( parent_map , SEQNUM_KW , seqnum_index);
@@ -287,7 +287,7 @@ static int file_map_seqnum_index_from_sim_time( file_map_type * parent_map , tim
seqnum_index++;
}
}
if (num_seqnum == seqnum_index)
return -1;
}
@@ -315,17 +315,17 @@ bool ecl_file_has_sim_time( const ecl_file_type * ecl_file , time_t sim_time) {
This function will determine the restart block corresponding to the
world time @sim_time; if @sim_time can not be found the function
will return 0.
The returned index is the 'occurence number' in the restart file,
i.e. in the (quite typical case) that not all report steps are
present the return value will not agree with report step.
present the return value will not agree with report step.
The return value from this function can then be used to get a
corresponding solution field directly, or the file map can
restricted to this block.
Direct access:
int index = ecl_file_get_restart_index( ecl_file , sim_time );
if (index >= 0) {
ecl_kw_type * pressure_kw = ecl_file_iget_named_kw( ecl_file , "PRESSURE" , index );
@@ -333,7 +333,7 @@ bool ecl_file_has_sim_time( const ecl_file_type * ecl_file , time_t sim_time) {
}
Using block restriction:
Using block restriction:
int index = ecl_file_get_restart_index( ecl_file , sim_time );
if (index >= 0) {
@@ -341,10 +341,10 @@ bool ecl_file_has_sim_time( const ecl_file_type * ecl_file , time_t sim_time) {
{
ecl_kw_type * pressure_kw = ecl_file_iget_named_kw( ecl_file , "PRESSURE" , 0 );
....
}
}
}
Specially in the case of LGRs the block restriction should be used.
Specially in the case of LGRs the block restriction should be used.
*/
int ecl_file_get_restart_index( const ecl_file_type * ecl_file , time_t sim_time) {
@@ -381,14 +381,14 @@ double ecl_file_iget_restart_sim_days( const ecl_file_type * restart_file , int
/*****************************************************************/
/* Select and open functions, observe that these functions should
/* Select and open functions, observe that these functions should
only consider the global map.
*/
/*
Will select restart block nr @seqnum_index - without considering
report_steps or simulation time.
report_steps or simulation time.
*/
bool ecl_file_iselect_rstblock( ecl_file_type * ecl_file , int seqnum_index ) {
return ecl_file_select_block( ecl_file , SEQNUM_KW , seqnum_index );
@@ -397,10 +397,10 @@ bool ecl_file_iselect_rstblock( ecl_file_type * ecl_file , int seqnum_index ) {
bool ecl_file_select_rstblock_sim_time( ecl_file_type * ecl_file , time_t sim_time) {
int seqnum_index = file_map_seqnum_index_from_sim_time( ecl_file->global_map , sim_time );
if (seqnum_index >= 0)
return ecl_file_iselect_rstblock( ecl_file , seqnum_index);
else
else
return false;
}
@@ -410,17 +410,19 @@ bool ecl_file_select_rstblock_report_step( ecl_file_type * ecl_file , int report
if ( global_index >= 0) {
int seqnum_index = file_map_iget_occurence( ecl_file->global_map , global_index );
return ecl_file_iselect_rstblock( ecl_file , seqnum_index);
} else
} else
return false;
}
/******************************************************************/
static ecl_file_type * ecl_file_open_rstblock_report_step__( const char * filename , int report_step , int flags) {
ecl_file_type * ecl_file = ecl_file_open__( filename , flags );
if (!ecl_file_select_rstblock_report_step( ecl_file , report_step )) {
ecl_file_close( ecl_file );
ecl_file = NULL;
ecl_file_type * ecl_file = ecl_file_open( filename , flags );
if (ecl_file) {
if (!ecl_file_select_rstblock_report_step( ecl_file , report_step )) {
ecl_file_close( ecl_file );
ecl_file = NULL;
}
}
return ecl_file;
}
@@ -433,10 +435,12 @@ ecl_file_type * ecl_file_open_rstblock_report_step( const char * filename , int
/******************************************************************/
static ecl_file_type * ecl_file_open_rstblock_sim_time__( const char * filename , time_t sim_time, int flags ) {
ecl_file_type * ecl_file = ecl_file_open__( filename , flags );
if (!ecl_file_select_rstblock_sim_time( ecl_file , sim_time)) {
ecl_file_close( ecl_file );
ecl_file = NULL;
ecl_file_type * ecl_file = ecl_file_open( filename , flags );
if (ecl_file) {
if (!ecl_file_select_rstblock_sim_time( ecl_file , sim_time)) {
ecl_file_close( ecl_file );
ecl_file = NULL;
}
}
return ecl_file;
}
@@ -448,10 +452,12 @@ ecl_file_type * ecl_file_open_rstblock_sim_time( const char * filename , time_t
/******************************************************************/
static ecl_file_type * ecl_file_iopen_rstblock__( const char * filename , int seqnum_index, int flags ) {
ecl_file_type * ecl_file = ecl_file_open__( filename , flags );
if (!ecl_file_iselect_rstblock( ecl_file , seqnum_index )) {
ecl_file_close( ecl_file );
ecl_file = NULL;
ecl_file_type * ecl_file = ecl_file_open( filename , flags );
if (ecl_file) {
if (!ecl_file_iselect_rstblock( ecl_file , seqnum_index )) {
ecl_file_close( ecl_file );
ecl_file = NULL;
}
}
return ecl_file;
}
+40
View File
@@ -37,6 +37,10 @@ time_t ecl_rsthead_date( const ecl_kw_type * intehead_kw ) {
}
double ecl_rsthead_get_sim_days( const ecl_rsthead_type * header ) {
return header->sim_days;
}
ecl_rsthead_type * ecl_rsthead_ialloc( const ecl_file_type * rst_file , int occurence) {
@@ -91,6 +95,42 @@ ecl_rsthead_type * ecl_rsthead_alloc( const ecl_file_type * rst_file) {
}
ecl_rsthead_type * ecl_rsthead_alloc_empty() {
ecl_rsthead_type * rsthead = util_malloc( sizeof * rsthead );
rsthead->day = 0;
rsthead->month = 0;
rsthead->year = 0;
rsthead->version = 0;
rsthead->phase_sum = 0;
rsthead->nx = 0;
rsthead->ny = 0;
rsthead->nz = 0;
rsthead->nactive = 0;
rsthead->nwells = 0;
rsthead->niwelz = 0;
rsthead->nzwelz = 0;
rsthead->nsconz = 0;
rsthead->niconz = 0;
rsthead->ncwmax = 0;
rsthead->nisegz = 0;
rsthead->nsegmx = 0;
rsthead->nswlmx = 0;
rsthead->nrsegz = 0;
rsthead->sim_time = 0;
rsthead->dualp = false;
rsthead->sim_days = 0.0;
return rsthead;
}
void ecl_rsthead_fprintf( const ecl_rsthead_type * header , FILE * stream) {
fprintf(stream , "nx %d \n",header->nx);
fprintf(stream , "nwells %d \n",header->nwells);
+21 -19
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_rstfile.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_rstfile.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
/*****************************************************************/
@@ -27,10 +27,12 @@ bool ecl_file_select_smryblock( ecl_file_type * ecl_file , int report_step ) {
ecl_file_type * ecl_file_open_smryblock( const char * filename , int report_step , int flags) {
ecl_file_type * ecl_file = ecl_file_open__( filename , flags );
if (!ecl_file_select_smryblock( ecl_file , report_step )) {
ecl_file_close( ecl_file );
ecl_file = NULL;
ecl_file_type * ecl_file = ecl_file_open( filename , flags );
if (ecl_file) {
if (!ecl_file_select_smryblock( ecl_file , report_step )) {
ecl_file_close( ecl_file );
ecl_file = NULL;
}
}
return ecl_file;
}
+199 -161
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_smspec.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_smspec.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <string.h>
@@ -42,9 +42,9 @@
/**
This file implements the indexing into the ECLIPSE summary files.
This file implements the indexing into the ECLIPSE summary files.
*/
/*
Supporting a new variable type:
-------------------------------
@@ -68,7 +68,7 @@
specfic lookup method has seen less use[*]. The final step in
supporting a new variable is to update the function
ecl_smspec_fread_header().
If you want to support specific lookup of the new variable type you
must add the necessary datastructures to the ecl_smspec_struct
structure and then subsequently fill that structure in the big
@@ -88,7 +88,7 @@
*/
#define ECL_SMSPEC_ID 806647
#define PARAMS_GLOBAL_DEFAULT -99
@@ -105,10 +105,10 @@ struct ecl_smspec_struct {
hash_type * well_var_index; /* Indexes for all well variables: {well1: {var1: index1 , var2: index2} , well2: {var1: index1 , var2: index2}} */
hash_type * well_completion_var_index; /* Indexes for completion indexes .*/
hash_type * group_var_index; /* Indexes for group variables.*/
hash_type * field_var_index;
hash_type * field_var_index;
hash_type * region_var_index; /* The stored index is an offset. */
hash_type * misc_var_index; /* Variables like 'TCPU' and 'NEWTON'. */
hash_type * block_var_index; /* Block variables like BPR */
hash_type * block_var_index; /* Block variables like BPR */
hash_type * gen_var_index; /* This is "everything" - things can either be found as gen_var("WWCT:OP_X") or as well_var("WWCT" , "OP_X") */
@@ -120,11 +120,11 @@ struct ecl_smspec_struct {
/*-----------------------------------------------------------------*/
int grid_dims[3]; /* Grid dimensions - in DIMENS[1,2,3] */
int grid_dims[3]; /* Grid dimensions - in DIMENS[1,2,3] */
int num_regions;
int Nwells , param_offset;
int params_size;
const char * key_join_string; /* The string used to join keys when building gen_key keys - typically ":" -
const char * key_join_string; /* The string used to join keys when building gen_key keys - typically ":" -
but arbitrary - NOT necessary to be able to invert the joining. */
char * header_file; /* FULL path to the currenbtly loaded header_file. */
@@ -132,13 +132,13 @@ struct ecl_smspec_struct {
time_t sim_start_time; /* When did the simulation start - worldtime. */
int time_index; /* The fields time_index, day_index, month_index and year_index */
int day_index; /* are used by the ecl_sum_data object to locate per. timestep */
int month_index; /* time information. */
int day_index; /* are used by the ecl_sum_data object to locate per. timestep */
int month_index; /* time information. */
int year_index;
bool has_lgr;
float_vector_type * params_default;
stringlist_type * restart_list; /* List of ECLBASE names of restart files this case has been restarted from (if any). */
stringlist_type * restart_list; /* List of ECLBASE names of restart files this case has been restarted from (if any). */
};
@@ -186,13 +186,13 @@ general_var:
VAR_TYPE:(WELL_NAME|GROUP_NAME|NUMBER):NUMBER
Field var: VAR_TYPE
Misc var: VAR_TYPE
Misc var: VAR_TYPE
Well var: VAR_TYPE:WELL_NAME
Group var: VAR_TYPE:GROUP_NAME
Block var: VAR_TYPE:i,j,k (where i,j,k is calculated form NUM)
Region var VAR_TYPE:index (where index is NOT from the nums vector, it it is just an offset).
Completion var: VAR_TYPE:WELL_NAME:NUM
....
....
*/
@@ -202,7 +202,7 @@ Completion var: VAR_TYPE:WELL_NAME:NUM
types, when the kewyord name is in conflict with the default vector
naming convention; all the variables mentioned in the list below
are given the type ECL_SMSPEC_MISC_VAR.
For instance the keyword 'NEWTON' starts with 'N' and is
classified as a NETWORK type variable. However it should rather
be classified as a MISC type variable. (What a fucking mess).
@@ -221,6 +221,21 @@ static const char* special_vars[] = {"NEWTON",
"STEPTYPE"};
/*
The smspec_required_keywords variable contains a list of keywords
which are *absolutely* required in the SMSPEC file, but observe that
depending on the content of the "KEYWORDS" array other keywords
might bre requred as well - this typically includes the NUMS
keyword. Such 'second-order' dependencies are not accounted for with
this simple list.
*/
static const char* smspec_required_keywords[] = {WGNAMES_KW,
KEYWORDS_KW,
STARTDAT_KW,
UNITS_KW,
DIMENS_KW};
/*****************************************************************/
@@ -240,15 +255,15 @@ static ecl_smspec_type * ecl_smspec_alloc_empty(bool write_mode , const char * k
ecl_smspec->sim_start_time = -1;
ecl_smspec->key_join_string = key_join_string;
ecl_smspec->header_file = NULL;
ecl_smspec->smspec_nodes = vector_alloc_new();
ecl_smspec->time_index = -1;
ecl_smspec->day_index = -1;
ecl_smspec->year_index = -1;
ecl_smspec->month_index = -1;
ecl_smspec->locked = false;
ecl_smspec->index_map = int_vector_alloc(0,0);
ecl_smspec->restart_list = stringlist_alloc_new();
ecl_smspec->params_default = float_vector_alloc(0 , PARAMS_GLOBAL_DEFAULT);
@@ -306,7 +321,7 @@ static void ecl_smspec_fortio_fwrite( const ecl_smspec_type * smspec , fortio_ty
int i;
for (i=0; i < SUMMARY_RESTART_SIZE; i++)
ecl_kw_iset_string8( restart_kw , i , "");
ecl_kw_fwrite( restart_kw , fortio );
ecl_kw_free( restart_kw );
}
@@ -331,7 +346,7 @@ static void ecl_smspec_fortio_fwrite( const ecl_smspec_type * smspec , fortio_ty
ecl_kw_type * wgnames_kw = ecl_kw_alloc( WGNAMES_KW , num_nodes , ECL_CHAR_TYPE );
ecl_kw_type * units_kw = ecl_kw_alloc( UNITS_KW , num_nodes , ECL_CHAR_TYPE );
ecl_kw_type * nums_kw = NULL;
if (smspec->need_nums)
nums_kw = ecl_kw_alloc( NUMS_KW , num_nodes , ECL_INT_TYPE);
{
@@ -383,8 +398,8 @@ static void ecl_smspec_fortio_fwrite( const ecl_smspec_type * smspec , fortio_ty
if (nums_kw != NULL)
ecl_kw_fwrite( nums_kw , fortio );
ecl_kw_fwrite( units_kw , fortio );
ecl_kw_free( keywords_kw );
ecl_kw_free( wgnames_kw );
ecl_kw_free( units_kw );
@@ -396,11 +411,11 @@ static void ecl_smspec_fortio_fwrite( const ecl_smspec_type * smspec , fortio_ty
ecl_kw_type * startdat_kw = ecl_kw_alloc( STARTDAT_KW , STARTDAT_SIZE , ECL_INT_TYPE );
int day,month,year;
util_set_date_values( smspec->sim_start_time , &day, &month , &year);
ecl_kw_iset_int( startdat_kw , STARTDAT_DAY_INDEX , day );
ecl_kw_iset_int( startdat_kw , STARTDAT_MONTH_INDEX , month );
ecl_kw_iset_int( startdat_kw , STARTDAT_YEAR_INDEX , year );
ecl_kw_fwrite( startdat_kw , fortio );
ecl_kw_free( startdat_kw );
}
@@ -410,30 +425,30 @@ static void ecl_smspec_fortio_fwrite( const ecl_smspec_type * smspec , fortio_ty
void ecl_smspec_fwrite( const ecl_smspec_type * smspec , const char * ecl_case , bool fmt_file ) {
char * filename = ecl_util_alloc_filename( NULL , ecl_case , ECL_SUMMARY_HEADER_FILE , fmt_file , 0 );
fortio_type * fortio = fortio_open_writer( filename , fmt_file , ECL_ENDIAN_FLIP);
ecl_smspec_fortio_fwrite( smspec , fortio );
fortio_fclose( fortio );
free( filename );
}
ecl_smspec_type * ecl_smspec_alloc_writer( const char * key_join_string , time_t sim_start , int nx , int ny , int nz) {
ecl_smspec_type * ecl_smspec = ecl_smspec_alloc_empty( true , key_join_string );
ecl_smspec->grid_dims[0] = nx;
ecl_smspec->grid_dims[1] = ny;
ecl_smspec->grid_dims[2] = nz;
ecl_smspec->sim_start_time = sim_start;
{
smspec_node_type * time_node = smspec_node_alloc( ECL_SMSPEC_MISC_VAR ,
NULL ,
"TIME" ,
smspec_node_type * time_node = smspec_node_alloc( ECL_SMSPEC_MISC_VAR ,
NULL ,
"TIME" ,
"DAYS" , // There are significant hardcoded assumptions of days around; would have been cool to be able to set seconds.
key_join_string ,
ecl_smspec->grid_dims ,
0 ,
-1 ,
key_join_string ,
ecl_smspec->grid_dims ,
0 ,
-1 ,
0 );
ecl_smspec_add_node( ecl_smspec , time_node );
ecl_smspec->time_index = smspec_node_get_params_index( time_node );
@@ -468,12 +483,12 @@ static ecl_smspec_var_type ecl_smspec_identify_special_var( const char * var ) {
break;
}
}
return var_type;
}
/*
/*
See table 3.4 in the ECLIPSE file format reference manual.
Observe that the combined ecl_sum style keys like e.g. WWCT:OP1
@@ -485,7 +500,7 @@ static ecl_smspec_var_type ecl_smspec_identify_special_var( const char * var ) {
ecl_smspec_var_type ecl_smspec_identify_var_type(const char * var) {
ecl_smspec_var_type var_type = ecl_smspec_identify_special_var( var );
int str_length = strlen(var);
int str_length = strlen(var);
if (var_type == ECL_SMSPEC_INVALID_VAR) {
switch(var[0]) {
case('A'):
@@ -529,7 +544,7 @@ ecl_smspec_var_type ecl_smspec_identify_var_type(const char * var) {
var_type = ECL_SMSPEC_NETWORK_VAR;
break;
case('R'):
if (((3 == str_length) && var[2] == 'F') ||
if (((3 == str_length) && var[2] == 'F') ||
((4 == str_length) && var[3] == 'F')) {
var_type = ECL_SMSPEC_REGION_2_REGION_VAR;
}
@@ -559,7 +574,7 @@ static bool ecl_smspec_lgr_var_type( ecl_smspec_var_type var_type) {
if ((var_type == ECL_SMSPEC_LOCAL_BLOCK_VAR) ||
(var_type == ECL_SMSPEC_LOCAL_WELL_VAR) ||
(var_type == ECL_SMSPEC_LOCAL_COMPLETION_VAR))
return true;
else
return false;
@@ -646,10 +661,10 @@ static int ecl_smspec_get_global_grid_index(const ecl_smspec_type * smspec , int
/**
This function takes a fully initialized smspec_node instance, generates the
corresponding key and inserts smspec_node instance in the main hash table
smspec->gen_var_index.
smspec->gen_var_index.
The format strings used, i.e. VAR:WELL for well based variables is implicitly
defined through the format strings used in this function.
defined through the format strings used in this function.
*/
static void ecl_smspec_install_gen_keys( ecl_smspec_type * smspec , smspec_node_type * smspec_node ) {
@@ -663,17 +678,17 @@ static void ecl_smspec_install_gen_keys( ecl_smspec_type * smspec , smspec_node_
/* Insert the (optional) extra mapping for block related variables and region_2_region variables: */
{
const char * gen_key2 = smspec_node_get_gen_key2( smspec_node );
if (gen_key2 != NULL)
if (gen_key2 != NULL)
hash_insert_ref(smspec->gen_var_index , gen_key2 , smspec_node);
}
}
static void ecl_smspec_install_special_keys( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node) {
/**
/**
This large switch is for installing keys which have custom lookup
paths, in addition to the lookup based on general keys. Examples
of this is e.g. well variables which can be looked up through:
of this is e.g. well variables which can be looked up through:
ecl_smspec_get_well_var_index( smspec , well_name , var );
*/
@@ -682,7 +697,7 @@ static void ecl_smspec_install_special_keys( ecl_smspec_type * ecl_smspec , smsp
const int num = smspec_node_get_num(smspec_node);
const char * keyword = smspec_node_get_keyword(smspec_node);
ecl_smspec_var_type var_type = smspec_node_get_var_type( smspec_node );
switch(var_type) {
case(ECL_SMSPEC_COMPLETION_VAR):
/* Three level indexing: variable -> well -> string(cell_nr)*/
@@ -715,7 +730,7 @@ static void ecl_smspec_install_special_keys( ecl_smspec_type * ecl_smspec , smsp
}
break;
case(ECL_SMSPEC_REGION_VAR):
if (!hash_has_key(ecl_smspec->region_var_index , keyword))
if (!hash_has_key(ecl_smspec->region_var_index , keyword))
hash_insert_hash_owned_ref( ecl_smspec->region_var_index , keyword , hash_alloc() , hash_free__);
{
hash_type * var_hash = hash_get(ecl_smspec->region_var_index , keyword);
@@ -748,7 +763,7 @@ static void ecl_smspec_install_special_keys( ecl_smspec_type * ecl_smspec , smsp
hash_insert_ref(block_hash , block_nr , smspec_node);
}
break;
/**
/**
The variables below are ONLY accesable through the gen_key
setup; but the must be mentioned in this switch statement,
otherwise they will induce a hard failure in the default: target
@@ -769,7 +784,7 @@ static void ecl_smspec_install_special_keys( ecl_smspec_type * ecl_smspec , smsp
break;
}
}
/**
The usage of this functon breaks down completely if LGR's are involved.
*/
@@ -858,7 +873,7 @@ static bool ecl_smspec_kw_equal(const ecl_file_type * header , const ecl_file_ty
if (ecl_file_has_kw( header , kw)) {
ecl_kw_type *ecl_kw1 = ecl_file_iget_named_kw(header, kw , 0);
ecl_kw_type *ecl_kw2 = ecl_file_iget_named_kw(restart_header, kw , 0);
return ecl_kw_block_equal( ecl_kw1 , ecl_kw2 , cmp_elements);
} else
return true; // None of the headers have this keyword - that is equality!
@@ -872,7 +887,7 @@ static bool ecl_smspec_kw_equal(const ecl_file_type * header , const ecl_file_ty
historical results is not internalized, i.e. it is essential that
the historical case has identical header as the main case. This
function compares the ecl_file represeantation of two SMSPEC
headers.
headers.
Unfortunately there are legitimate reasons why some of the headers
can be different; in particular new well can appear. In the code
@@ -883,19 +898,19 @@ static bool ecl_smspec_kw_equal(const ecl_file_type * header , const ecl_file_ty
static bool ecl_smspec_file_equal( const ecl_file_type * header1 , const ecl_file_type * header2) {
if (! ecl_smspec_kw_equal( header1 , header2 , KEYWORDS_KW , 0))
return false;
if (! ecl_smspec_kw_equal( header1 , header2 , STARTDAT_KW , 0))
return false;
if (! ecl_smspec_kw_equal( header1 , header2 , UNITS_KW , 0))
return false;
if (! ecl_smspec_kw_equal( header1 , header2 , DIMENS_KW , 4)) // Only the first four elements are compared.
return false;
if (!ecl_smspec_kw_equal( header1, header2 , LGRS_KW , 0))
return false;
return true;
}
@@ -903,7 +918,7 @@ static bool ecl_smspec_file_equal( const ecl_file_type * header1 , const ecl_fil
/**
This will iterate backwards through the RESTART header in the
SMSPEC files to find names of the case(s) this case has been
restarted from.
restarted from.
The case names are internalized in the restart_list field of the
ecl_smspec instance. The actual loading of the restart summary data
@@ -917,9 +932,9 @@ static void ecl_smspec_load_restart( ecl_smspec_type * ecl_smspec , const ecl_fi
char * restart_base;
int i;
tmp_base[0] = '\0';
for (i=0; i < ecl_kw_get_size( restart_kw ); i++)
for (i=0; i < ecl_kw_get_size( restart_kw ); i++)
strcat( tmp_base , ecl_kw_iget_ptr( restart_kw , i ));
restart_base = util_alloc_strip_copy( tmp_base );
if (strlen(restart_base)) { /* We ignore the empty ones. */
char * path;
@@ -927,27 +942,29 @@ static void ecl_smspec_load_restart( ecl_smspec_type * ecl_smspec , const ecl_fi
util_alloc_file_components( ecl_smspec->header_file , &path , NULL , NULL );
smspec_header = ecl_util_alloc_exfilename( path , restart_base , ECL_SUMMARY_HEADER_FILE , ecl_smspec->formatted , 0);
if (smspec_header == NULL)
if (smspec_header == NULL)
fprintf(stderr,"Warning - the header file: %s refers to restart from case: %s - which was not found.... \n", ecl_smspec->header_file , restart_base);
else {
if (!util_same_file(smspec_header , ecl_smspec->header_file)) { /* Restart from the current case is ignored. */
/*
/*
Verify that this smspec_header is not already in the list of restart
cases. Don't know if this is at all possible, but this test
nevertheless prevents against a recursive death.
*/
if (!stringlist_contains( ecl_smspec->restart_list , restart_base)) {
ecl_file_type * restart_header = ecl_file_open( smspec_header , 0);
if (ecl_smspec_file_equal( header , restart_header)) {
stringlist_insert_copy( ecl_smspec->restart_list , 0 , restart_base );
ecl_smspec_load_restart( ecl_smspec , restart_header); /* Recursive call */
} else
fprintf(stderr,"** Warning: the historical case: %s is not compatible with the current case - ignored.\n" ,
ecl_file_get_src_file( restart_header));
ecl_file_close( restart_header );
if (restart_header) {
if (ecl_smspec_file_equal( header , restart_header)) {
stringlist_insert_copy( ecl_smspec->restart_list , 0 , restart_base );
ecl_smspec_load_restart( ecl_smspec , restart_header); /* Recursive call */
} else
fprintf(stderr,"** Warning: the historical case: %s is not compatible with the current case - ignored.\n" ,
ecl_file_get_src_file( restart_header));
ecl_file_close( restart_header );
} else
fprintf(stderr,"** Warning: failed to historical case:%s - ignored.\n", smspec_header);
}
}
}
@@ -958,13 +975,13 @@ static void ecl_smspec_load_restart( ecl_smspec_type * ecl_smspec , const ecl_fi
}
}
void ecl_smspec_index_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node) {
/*
It is possible crate a node which is not fully specified, e.g. the
well or group name can be left at NULL. In that case the node is
not installed in the different indexes.
not installed in the different indexes.
*/
// var_type == ECL_SMSPEC_INVALID_VAR??
if (smspec_node_get_gen_key1( smspec_node ) != NULL) {
@@ -983,27 +1000,27 @@ static void ecl_smspec_set_params_size( ecl_smspec_type * ecl_smspec , int param
void ecl_smspec_insert_node(ecl_smspec_type * ecl_smspec, smspec_node_type * smspec_node){
void ecl_smspec_insert_node(ecl_smspec_type * ecl_smspec, smspec_node_type * smspec_node){
if (!ecl_smspec->locked) {
int internal_index = vector_get_size( ecl_smspec->smspec_nodes );
/* This IF test should only apply in write_mode. */
if (smspec_node_get_params_index( smspec_node ) < 0) {
if (!ecl_smspec->write_mode)
util_abort("%s: internal error \n",__func__);
smspec_node_set_params_index( smspec_node , internal_index);
if (internal_index >= ecl_smspec->params_size)
ecl_smspec_set_params_size( ecl_smspec , internal_index + 1);
}
vector_append_owned_ref( ecl_smspec->smspec_nodes , smspec_node , smspec_node_free__ );
{
int params_index = smspec_node_get_params_index( smspec_node );
/* This indexing must be used when writing. */
int_vector_iset( ecl_smspec->index_map , internal_index , params_index);
float_vector_iset( ecl_smspec->params_default , params_index , smspec_node_get_default(smspec_node) );
}
} else
@@ -1030,12 +1047,25 @@ const int_vector_type * ecl_smspec_get_index_map( const ecl_smspec_type * smspec
return smspec->index_map;
}
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;
}
}
return OK;
}
static void ecl_smspec_fread_header(ecl_smspec_type * ecl_smspec, const char * header_file , bool include_restart) {
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);
@@ -1048,17 +1078,17 @@ static void ecl_smspec_fread_header(ecl_smspec_type * ecl_smspec, const char * h
ecl_kw_type *numlz = NULL;
int params_index;
ecl_smspec->num_regions = 0;
if (startdat == NULL)
if (startdat == NULL)
util_abort("%s: could not locate STARTDAT keyword in header - aborting \n",__func__);
if (ecl_file_has_kw(header , NUMS_KW))
nums = ecl_file_iget_named_kw(header , NUMS_KW , 0);
if (ecl_file_has_kw( header , LGRS_KW )) {/* The file has LGR information. */
lgrs = ecl_file_iget_named_kw( header , LGRS_KW , 0 );
numlx = ecl_file_iget_named_kw( header , NUMLX_KW , 0 );
numly = ecl_file_iget_named_kw( header , NUMLY_KW , 0 );
numlz = ecl_file_iget_named_kw( header , NUMLZ_KW , 0 );
numlx = ecl_file_iget_named_kw( header , NUMLX_KW , 0 );
numly = ecl_file_iget_named_kw( header , NUMLY_KW , 0 );
numlz = ecl_file_iget_named_kw( header , NUMLZ_KW , 0 );
ecl_smspec->has_lgr = true;
} else
ecl_smspec->has_lgr = false;
@@ -1069,14 +1099,14 @@ static void ecl_smspec_fread_header(ecl_smspec_type * ecl_smspec, const char * h
date[STARTDAT_MONTH_INDEX] ,
date[STARTDAT_YEAR_INDEX]);
}
ecl_smspec->grid_dims[0] = ecl_kw_iget_int(dimens , DIMENS_SMSPEC_NX_INDEX );
ecl_smspec->grid_dims[1] = ecl_kw_iget_int(dimens , DIMENS_SMSPEC_NY_INDEX );
ecl_smspec->grid_dims[2] = ecl_kw_iget_int(dimens , DIMENS_SMSPEC_NZ_INDEX );
ecl_smspec_set_params_size( ecl_smspec , ecl_kw_get_size(keywords));
ecl_util_get_file_type( header_file , &ecl_smspec->formatted , NULL );
{
for (params_index=0; params_index < ecl_kw_get_size(wells); params_index++) {
float default_value = PARAMS_GLOBAL_DEFAULT;
@@ -1084,75 +1114,83 @@ static void ecl_smspec_fread_header(ecl_smspec_type * ecl_smspec, const char * h
char * well = util_alloc_strip_copy(ecl_kw_iget_ptr(wells , params_index));
char * kw = util_alloc_strip_copy(ecl_kw_iget_ptr(keywords , params_index));
char * unit = util_alloc_strip_copy(ecl_kw_iget_ptr(units , params_index));
char * lgr_name = NULL;
char * lgr_name = NULL;
smspec_node_type * smspec_node;
ecl_smspec_var_type var_type = ecl_smspec_identify_var_type( kw );
if (nums != NULL) num = ecl_kw_iget_int(nums , params_index);
if (ecl_smspec_lgr_var_type( var_type )) {
if (ecl_smspec_lgr_var_type( var_type )) {
int lgr_i = ecl_kw_iget_int( numlx , params_index );
int lgr_j = ecl_kw_iget_int( numly , params_index );
int lgr_k = ecl_kw_iget_int( numlz , params_index );
lgr_name = util_alloc_strip_copy( ecl_kw_iget_ptr( lgrs , params_index ));
smspec_node = smspec_node_alloc_lgr( var_type , well , kw , unit , lgr_name , ecl_smspec->key_join_string , lgr_i , lgr_j , lgr_k , params_index, default_value);
} else
} else
smspec_node = smspec_node_alloc( var_type , well , kw , unit , ecl_smspec->key_join_string , ecl_smspec->grid_dims , num , params_index , default_value);
if (smspec_node != NULL) {
/** OK - we know this is valid shit. */
ecl_smspec_add_node( ecl_smspec , smspec_node );
}
free( kw );
free( well );
free( unit );
util_safe_free( lgr_name );
}
}
}
ecl_smspec->header_file = util_alloc_realpath( header_file );
if (include_restart)
ecl_smspec_load_restart( ecl_smspec , header );
ecl_file_close( header );
ecl_smspec->header_file = util_alloc_realpath( header_file );
if (include_restart)
ecl_smspec_load_restart( ecl_smspec , header );
ecl_file_close( header );
return true;
} else
return false;
}
ecl_smspec_type * ecl_smspec_fread_alloc(const char *header_file, const char * key_join_string , bool include_restart) {
ecl_smspec_type *ecl_smspec;
{
char *path;
util_alloc_file_components(header_file , &path , NULL , NULL);
ecl_smspec = ecl_smspec_alloc_empty(false , key_join_string);
util_safe_free(path);
}
ecl_smspec_fread_header(ecl_smspec , header_file , include_restart);
if (hash_has_key( ecl_smspec->misc_var_index , "TIME"))
ecl_smspec->time_index = smspec_node_get_params_index( hash_get(ecl_smspec->misc_var_index , "TIME") );
if (hash_has_key(ecl_smspec->misc_var_index , "DAY")) {
ecl_smspec->day_index = smspec_node_get_params_index( hash_get(ecl_smspec->misc_var_index , "DAY") );
ecl_smspec->month_index = smspec_node_get_params_index( hash_get(ecl_smspec->misc_var_index , "MONTH") );
ecl_smspec->year_index = smspec_node_get_params_index( hash_get(ecl_smspec->misc_var_index , "YEAR") );
}
if ((ecl_smspec->time_index == -1) && ( ecl_smspec->day_index == -1)) {
/* Unusable configuration.
Seems the ECLIPSE file can also have time specified with
'YEARS' as basic time unit; that mode is not supported.
*/
util_abort("%s: Sorry the SMSPEC file seems to lack all time information, need either TIME, or DAY/MONTH/YEAR information. Can not proceed.",__func__);
if (ecl_smspec_fread_header(ecl_smspec , header_file , include_restart)) {
if (hash_has_key( ecl_smspec->misc_var_index , "TIME"))
ecl_smspec->time_index = smspec_node_get_params_index( hash_get(ecl_smspec->misc_var_index , "TIME") );
if (hash_has_key(ecl_smspec->misc_var_index , "DAY")) {
ecl_smspec->day_index = smspec_node_get_params_index( hash_get(ecl_smspec->misc_var_index , "DAY") );
ecl_smspec->month_index = smspec_node_get_params_index( hash_get(ecl_smspec->misc_var_index , "MONTH") );
ecl_smspec->year_index = smspec_node_get_params_index( hash_get(ecl_smspec->misc_var_index , "YEAR") );
}
if ((ecl_smspec->time_index == -1) && ( ecl_smspec->day_index == -1)) {
/* Unusable configuration.
Seems the ECLIPSE file can also have time specified with
'YEARS' as basic time unit; that mode is not supported.
*/
util_abort("%s: Sorry the SMSPEC file seems to lack all time information, need either TIME, or DAY/MONTH/YEAR information. Can not proceed.",__func__);
return NULL;
}
return ecl_smspec;
} else {
/** Failed to load from disk. */
ecl_smspec_free( ecl_smspec );
return NULL;
}
return ecl_smspec;
}
@@ -1172,7 +1210,7 @@ int ecl_smspec_get_num_regions(const ecl_smspec_type * ecl_smspec) {
/******************************************************************/
/*
/*
For each type of summary data (according to the types in
ecl_smcspec_var_type there are a set accessor functions:
@@ -1272,7 +1310,7 @@ const smspec_node_type * ecl_smspec_get_field_var_node(const ecl_smspec_type * e
const smspec_node_type * node = NULL;
if (hash_has_key(ecl_smspec->field_var_index , var))
node = hash_get(ecl_smspec->field_var_index , var);
return node;
}
@@ -1296,7 +1334,7 @@ bool ecl_smspec_has_field_var(const ecl_smspec_type * ecl_smspec , const char *v
/**
Observe that block_nr is represented as char literal,
i.e. "2345". This is because it will be used as a hash key.
This is the final low level function which actually consults the
hash tables.
*/
@@ -1331,7 +1369,7 @@ const smspec_node_type * ecl_smspec_get_block_var_node_ijk(const ecl_smspec_type
bool ecl_smspec_has_block_var(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr) {
const smspec_node_type * node = ecl_smspec_get_block_var_node( ecl_smspec , block_var , block_nr );
NODE_RETURN_EXISTS(node);
}
}
bool ecl_smspec_has_block_var_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k) {
@@ -1343,7 +1381,7 @@ bool ecl_smspec_has_block_var_ijk(const ecl_smspec_type * ecl_smspec , const cha
int ecl_smspec_get_block_var_params_index(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr) {
const smspec_node_type * node = ecl_smspec_get_block_var_node( ecl_smspec , block_var , block_nr );
NODE_RETURN_INDEX(node);
}
}
int ecl_smspec_get_block_var_params_index_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k) {
@@ -1366,11 +1404,11 @@ const smspec_node_type * ecl_smspec_get_region_var_node(const ecl_smspec_type *
if (hash_has_key(ecl_smspec->region_var_index , region_var)) {
char * nr_str = util_alloc_sprintf( "%d" , region_nr );
hash_type * nr_hash = hash_get(ecl_smspec->region_var_index , region_var);
if (hash_has_key( nr_hash , nr_str))
if (hash_has_key( nr_hash , nr_str))
node = hash_get( nr_hash , nr_str );
free( nr_str );
}
return node;
}
@@ -1394,7 +1432,7 @@ const smspec_node_type * ecl_smspec_get_misc_var_node(const ecl_smspec_type * ec
if (hash_has_key(ecl_smspec->misc_var_index , var))
node = hash_get(ecl_smspec->misc_var_index , var);
return node;
}
@@ -1420,7 +1458,7 @@ const smspec_node_type * ecl_smspec_get_well_completion_var_node(const ecl_smspe
char * cell_str = util_alloc_sprintf("%d" , cell_nr);
if (hash_has_key(ecl_smspec->well_completion_var_index , well)) {
hash_type * cell_hash = hash_get(ecl_smspec->well_completion_var_index , well);
if (hash_has_key(cell_hash , cell_str)) {
hash_type * var_hash = hash_get(cell_hash , cell_str);
if (hash_has_key(var_hash , var))
@@ -1472,7 +1510,7 @@ int ecl_smspec_get_general_var_params_index(const ecl_smspec_type * ecl_smspec ,
bool ecl_smspec_has_general_var(const ecl_smspec_type * ecl_smspec , const char * lookup_kw) {
const smspec_node_type * node = ecl_smspec_get_general_var_node( ecl_smspec , lookup_kw );
NODE_RETURN_EXISTS( node );
}
}
/** DIES if the lookup_kw is not present. */
@@ -1483,7 +1521,7 @@ const char * ecl_smspec_get_general_var_unit( const ecl_smspec_type * ecl_smspec
/*****************************************************************/
/*
/*
Pure indexed lookup - these functions can be used after one of the
ecl_smspec_get_xxx_index() functions has been used first.
*/
@@ -1609,7 +1647,7 @@ bool ecl_smspec_general_is_total( const ecl_smspec_type * smspec , const char *
unfortunately not as useful as one might think because ECLIPSE is
quite stupid; it will for instance happily give you the WOPR for a
water injector or WWIR for an oil producer.
The function can be called several times with different patterns,
the stringlist is not cleared on startup; the keys in the list are
unique - keys are not added multiple times. If pattern == NULL all
@@ -1620,7 +1658,7 @@ bool ecl_smspec_general_is_total( const ecl_smspec_type * smspec , const char *
void ecl_smspec_select_matching_general_var_list( const ecl_smspec_type * smspec , const char * pattern , stringlist_type * keys) {
hash_type * ex_keys = hash_alloc( );
int i;
for (i=0; i < stringlist_get_size( keys ); i++)
for (i=0; i < stringlist_get_size( keys ); i++)
hash_insert_int( ex_keys , stringlist_iget( keys , i ) , 1);
{
@@ -1634,7 +1672,7 @@ void ecl_smspec_select_matching_general_var_list( const ecl_smspec_type * smspec
}
hash_iter_free( iter );
}
hash_free( ex_keys );
}
@@ -1658,12 +1696,12 @@ const char * ecl_smspec_get_join_string( const ecl_smspec_type * smspec) {
/**
/**
Returns a stringlist instance with all the (valid) well names. It
is the responsability of the calling scope to free the stringlist
with stringlist_free();
If @pattern is different from NULL only wells which 'match' the
pattern is included; if @pattern == NULL all wells are
included. The match is done with function fnmatch() -
@@ -1674,12 +1712,12 @@ stringlist_type * ecl_smspec_alloc_well_list( const ecl_smspec_type * smspec , c
stringlist_type * well_list = stringlist_alloc_new( );
{
hash_iter_type * iter = hash_iter_alloc( smspec->well_var_index );
while (!hash_iter_is_complete( iter )) {
const char * well_name = hash_iter_get_next_key( iter );
if (pattern == NULL)
stringlist_append_copy( well_list , well_name );
else if (util_fnmatch( pattern , well_name) == 0)
else if (util_fnmatch( pattern , well_name) == 0)
stringlist_append_copy( well_list , well_name );
}
hash_iter_free(iter);
@@ -1689,7 +1727,7 @@ stringlist_type * ecl_smspec_alloc_well_list( const ecl_smspec_type * smspec , c
}
/**
/**
Returns a stringlist instance with all the (valid) group names. It
is the responsability of the calling scope to free the stringlist
with stringlist_free();
@@ -1699,12 +1737,12 @@ stringlist_type * ecl_smspec_alloc_group_list( const ecl_smspec_type * smspec ,
stringlist_type * group_list = stringlist_alloc_new( );
{
hash_iter_type * iter = hash_iter_alloc( smspec->group_var_index );
while (!hash_iter_is_complete( iter )) {
const char * group_name = hash_iter_get_next_key( iter );
if (pattern == NULL)
stringlist_append_copy( group_list , group_name );
else if (util_fnmatch( pattern , group_name) == 0)
else if (util_fnmatch( pattern , group_name) == 0)
stringlist_append_copy( group_list , group_name );
}
hash_iter_free(iter);
@@ -1715,7 +1753,7 @@ stringlist_type * ecl_smspec_alloc_group_list( const ecl_smspec_type * smspec ,
/**
/**
Returns a stringlist instance with all the well variables. It is
the responsability of the calling scope to free the stringlist
with stringlist_free();
+94 -86
View File
@@ -79,7 +79,7 @@
combined to create a unique key; and the corresponding index is
used to lookup a numerical value from the PARAMS vector with actual
data.
These matters are documented further in the ecl_smspec.c and
ecl_sum_data.c files.
*/
@@ -104,7 +104,7 @@ struct ecl_sum_struct {
char * abs_path; /* Absolute path. */
char * base; /* Only the basename. */
char * ecl_case; /* This is the current case, with optional path component. == path + base*/
char * ext; /* Only to support selective loading of formatted|unformatted and unified|multiple. (can be NULL) */
char * ext; /* Only to support selective loading of formatted|unformatted and unified|multiple. (can be NULL) */
};
@@ -129,7 +129,7 @@ void ecl_sum_set_case( ecl_sum_type * ecl_sum , const char * ecl_case) {
util_safe_free( ecl_sum->ext );
{
char *path , *base, *ext;
util_alloc_file_components( ecl_case , &path , &base , &ext);
ecl_sum->ecl_case = util_alloc_string_copy( ecl_case );
@@ -140,7 +140,7 @@ void ecl_sum_set_case( ecl_sum_type * ecl_sum , const char * ecl_case) {
ecl_sum->abs_path = util_alloc_abs_path( path );
else
ecl_sum->abs_path = util_alloc_cwd();
util_safe_free( base );
util_safe_free( path );
util_safe_free( ext );
@@ -151,7 +151,7 @@ void ecl_sum_set_case( ecl_sum_type * ecl_sum , const char * ecl_case) {
static ecl_sum_type * ecl_sum_alloc__( const char * input_arg , const char * key_join_string) {
ecl_sum_type * ecl_sum = util_malloc( sizeof * ecl_sum );
UTIL_TYPE_ID_INIT( ecl_sum , ECL_SUM_ID );
ecl_sum->ecl_case = NULL;
ecl_sum->path = NULL;
ecl_sum->base = NULL;
@@ -159,7 +159,7 @@ static ecl_sum_type * ecl_sum_alloc__( const char * input_arg , const char * key
ecl_sum->abs_path = NULL;
ecl_sum_set_case( ecl_sum , input_arg );
ecl_sum->key_join_string = util_alloc_string_copy( key_join_string );
ecl_sum->smspec = NULL;
ecl_sum->data = NULL;
@@ -167,69 +167,72 @@ static ecl_sum_type * ecl_sum_alloc__( const char * input_arg , const char * key
}
static void ecl_sum_fread_data( ecl_sum_type * ecl_sum , const stringlist_type * data_files , bool include_restart) {
static bool ecl_sum_fread_data( ecl_sum_type * ecl_sum , const stringlist_type * data_files , bool include_restart) {
if (ecl_sum->data != NULL)
ecl_sum_free_data( ecl_sum );
ecl_sum->data = ecl_sum_data_alloc( ecl_sum->smspec );
ecl_sum_data_fread( ecl_sum->data , data_files );
if (include_restart) {
const char * path = ecl_sum->path;
const stringlist_type * restart_cases = ecl_smspec_get_restart_list( ecl_sum->smspec );
stringlist_type * restart_files = stringlist_alloc_new();
int restart_nr;
for (restart_nr = 0; restart_nr < stringlist_get_size( restart_cases ); restart_nr++) {
ecl_util_alloc_summary_data_files(path , stringlist_iget( restart_cases , restart_nr ) , ecl_sum->fmt_case , restart_files );
ecl_sum_data_fread_restart( ecl_sum->data , restart_files );
}
stringlist_free( restart_files );
}
ecl_sum->data = ecl_sum_data_alloc( ecl_sum->smspec );
if (ecl_sum_data_fread( ecl_sum->data , data_files )) {
if (include_restart) {
const char * path = ecl_sum->path;
const stringlist_type * restart_cases = ecl_smspec_get_restart_list( ecl_sum->smspec );
stringlist_type * restart_files = stringlist_alloc_new();
int restart_nr;
for (restart_nr = 0; restart_nr < stringlist_get_size( restart_cases ); restart_nr++) {
ecl_util_alloc_summary_data_files(path , stringlist_iget( restart_cases , restart_nr ) , ecl_sum->fmt_case , restart_files );
ecl_sum_data_fread_restart( ecl_sum->data , restart_files );
}
stringlist_free( restart_files );
}
return true;
} else
return false;
}
static void ecl_sum_fread(ecl_sum_type * ecl_sum , const char *header_file , const stringlist_type *data_files , bool include_restart) {
static bool ecl_sum_fread(ecl_sum_type * ecl_sum , const char *header_file , const stringlist_type *data_files , bool include_restart) {
ecl_sum->smspec = ecl_smspec_fread_alloc( header_file , ecl_sum->key_join_string , include_restart);
{
if (ecl_sum->smspec) {
bool fmt_file;
ecl_util_get_file_type( header_file , &fmt_file , NULL);
ecl_sum_set_fmt_case( ecl_sum , fmt_file );
}
ecl_sum_fread_data( ecl_sum , data_files , include_restart );
} else
return false;
{
if (ecl_sum_fread_data( ecl_sum , data_files , include_restart )) {
ecl_file_enum file_type = ecl_util_get_file_type( stringlist_iget( data_files , 0 ) , NULL , NULL);
if (file_type == ECL_SUMMARY_FILE)
ecl_sum_set_unified( ecl_sum , false );
else if (file_type == ECL_UNIFIED_SUMMARY_FILE)
ecl_sum_set_unified( ecl_sum , true);
else
util_abort("%s: what the fuck? \n",__func__);
}
} else
return false;
return true;
}
static bool ecl_sum_fread_case( ecl_sum_type * ecl_sum , bool include_restart) {
char * header_file;
stringlist_type * summary_file_list = stringlist_alloc_new();
bool caseOK = false;
ecl_util_alloc_summary_files( ecl_sum->path , ecl_sum->base , ecl_sum->ext , &header_file , summary_file_list );
if ((header_file != NULL) && (stringlist_get_size( summary_file_list ) > 0)) {
ecl_sum_fread( ecl_sum , header_file , summary_file_list , include_restart );
caseOK = true;
caseOK = ecl_sum_fread( ecl_sum , header_file , summary_file_list , include_restart );
}
util_safe_free( header_file );
stringlist_free( summary_file_list );
return caseOK;
}
/**
This will explicitly load the summary specified by @header_file and
@@ -240,8 +243,8 @@ static bool ecl_sum_fread_case( ecl_sum_type * ecl_sum , bool include_restart) {
initializing the data_files list with files from the restarted
case.
*/
ecl_sum_type * ecl_sum_fread_alloc(const char *header_file , const stringlist_type *data_files , const char * key_join_string) {
ecl_sum_type * ecl_sum = ecl_sum_alloc__( header_file , key_join_string );
ecl_sum_fread( ecl_sum , header_file , data_files , false );
@@ -293,7 +296,7 @@ ecl_sum_type * ecl_sum_alloc_writer( const char * ecl_case , bool fmt_output , b
ecl_sum->smspec = ecl_smspec_alloc_writer( key_join_string , sim_start , nx , ny , nz );
ecl_sum->data = ecl_sum_data_alloc_writer( ecl_sum->smspec );
return ecl_sum;
}
@@ -330,14 +333,14 @@ void ecl_sum_free( ecl_sum_type * ecl_sum ) {
if (ecl_sum->smspec != NULL)
ecl_smspec_free( ecl_sum->smspec );
util_safe_free( ecl_sum->path );
util_safe_free( ecl_sum->ext );
util_safe_free( ecl_sum->abs_path );
free( ecl_sum->base );
free( ecl_sum->ecl_case );
free( ecl_sum->key_join_string );
free( ecl_sum );
}
@@ -410,7 +413,7 @@ bool ecl_sum_case_exists( const char * input_file ) {
util_safe_free( extension );
util_safe_free( smspec_file );
stringlist_free( data_files );
return case_exists;
}
@@ -450,8 +453,8 @@ double ecl_sum_time2days( const ecl_sum_type * ecl_sum , time_t sim_time) {
/*****************************************************************/
/* Well variables */
bool ecl_sum_has_well_var(const ecl_sum_type * ecl_sum , const char * well , const char *var) {
return ecl_smspec_has_well_var(ecl_sum->smspec , well , var);
bool ecl_sum_has_well_var(const ecl_sum_type * ecl_sum , const char * well , const char *var) {
return ecl_smspec_has_well_var(ecl_sum->smspec , well , var);
}
double ecl_sum_get_well_var(const ecl_sum_type * ecl_sum , int time_index , const char * well , const char *var) {
@@ -473,8 +476,8 @@ double ecl_sum_get_well_var_from_sim_days( const ecl_sum_type * ecl_sum , double
/*****************************************************************/
/* Group variables */
bool ecl_sum_has_group_var(const ecl_sum_type * ecl_sum , const char * group , const char *var) {
return ecl_smspec_has_group_var( ecl_sum->smspec , group , var);
bool ecl_sum_has_group_var(const ecl_sum_type * ecl_sum , const char * group , const char *var) {
return ecl_smspec_has_group_var( ecl_sum->smspec , group , var);
}
double ecl_sum_get_group_var(const ecl_sum_type * ecl_sum , int time_index , const char * group , const char *var) {
@@ -496,8 +499,8 @@ double ecl_sum_get_group_var_from_sim_days( const ecl_sum_type * ecl_sum , doubl
/*****************************************************************/
/* Field variables */
bool ecl_sum_has_field_var(const ecl_sum_type * ecl_sum , const char *var) {
return ecl_smspec_has_field_var( ecl_sum->smspec , var);
bool ecl_sum_has_field_var(const ecl_sum_type * ecl_sum , const char *var) {
return ecl_smspec_has_field_var( ecl_sum->smspec , var);
}
double ecl_sum_get_field_var(const ecl_sum_type * ecl_sum , int time_index , const char * var) {
@@ -519,8 +522,8 @@ double ecl_sum_get_field_var_from_sim_days( const ecl_sum_type * ecl_sum , doubl
/*****************************************************************/
/* Block variables */
bool ecl_sum_has_block_var(const ecl_sum_type * ecl_sum , const char * block_var , int block_nr) {
return ecl_smspec_has_block_var( ecl_sum->smspec , block_var , block_nr );
bool ecl_sum_has_block_var(const ecl_sum_type * ecl_sum , const char * block_var , int block_nr) {
return ecl_smspec_has_block_var( ecl_sum->smspec , block_var , block_nr );
}
double ecl_sum_get_block_var(const ecl_sum_type * ecl_sum , int time_index , const char * block_var , int block_nr) {
@@ -559,8 +562,8 @@ double ecl_sum_get_block_var_ijk_from_sim_days( const ecl_sum_type * ecl_sum , d
region_nr: [1...num_regions] (NOT C-based indexing)
*/
bool ecl_sum_has_region_var(const ecl_sum_type * ecl_sum , const char *var , int region_nr ) {
return ecl_smspec_has_region_var( ecl_sum->smspec , var , region_nr);
bool ecl_sum_has_region_var(const ecl_sum_type * ecl_sum , const char *var , int region_nr ) {
return ecl_smspec_has_region_var( ecl_sum->smspec , var , region_nr);
}
double ecl_sum_get_region_var(const ecl_sum_type * ecl_sum , int time_index , const char *var , int region_nr) {
@@ -583,12 +586,12 @@ double ecl_sum_get_region_var_from_sim_days( const ecl_sum_type * ecl_sum , doub
/*****************************************************************/
/* Misc variables */
int ecl_sum_get_misc_var_index(const ecl_sum_type * ecl_sum , const char *var) {
return ecl_smspec_get_misc_var_params_index( ecl_sum->smspec , var );
int ecl_sum_get_misc_var_index(const ecl_sum_type * ecl_sum , const char *var) {
return ecl_smspec_get_misc_var_params_index( ecl_sum->smspec , var );
}
bool ecl_sum_has_misc_var(const ecl_sum_type * ecl_sum , const char *var) {
return ecl_smspec_has_misc_var( ecl_sum->smspec , var );
bool ecl_sum_has_misc_var(const ecl_sum_type * ecl_sum , const char *var) {
return ecl_smspec_has_misc_var( ecl_sum->smspec , var );
}
double ecl_sum_get_misc_var(const ecl_sum_type * ecl_sum , int time_index , const char *var) {
@@ -631,11 +634,11 @@ int ecl_sum_get_general_var_params_index(const ecl_sum_type * ecl_sum , const ch
}
bool ecl_sum_has_general_var(const ecl_sum_type * ecl_sum , const char * lookup_kw) {
return ecl_smspec_has_general_var( ecl_sum->smspec , lookup_kw);
bool ecl_sum_has_general_var(const ecl_sum_type * ecl_sum , const char * lookup_kw) {
return ecl_smspec_has_general_var( ecl_sum->smspec , lookup_kw);
}
bool ecl_sum_has_key(const ecl_sum_type * ecl_sum , const char * lookup_kw) {
bool ecl_sum_has_key(const ecl_sum_type * ecl_sum , const char * lookup_kw) {
return ecl_sum_has_general_var( ecl_sum , lookup_kw );
}
@@ -646,6 +649,11 @@ double ecl_sum_get_general_var(const ecl_sum_type * ecl_sum , int time_index , c
}
void ecl_sum_dump_line_to_csv_file(const ecl_sum_type * ecl_sum, time_t sim_time, const ecl_sum_vector_type * key_words, FILE *fp){
ecl_sum_data_write_csv_file(ecl_sum->data, sim_time, key_words, fp);
}
double ecl_sum_get_general_var_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const char * var) {
const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum , var );
@@ -836,7 +844,7 @@ time_t ecl_sum_iget_sim_time( const ecl_sum_type * ecl_sum , int index ) {
return ecl_sum_data_iget_sim_time( ecl_sum->data , index );
}
const time_interval_type * ecl_sum_get_sim_time( const ecl_sum_type * ecl_sum) {
const time_interval_type * ecl_sum_get_sim_time( const ecl_sum_type * ecl_sum) {
return ecl_sum_data_get_sim_time( ecl_sum->data );
}
@@ -905,52 +913,52 @@ void ecl_sum_fmt_init_summary_x( ecl_sum_fmt_type * fmt ) {
static void __ecl_sum_fprintf_line( const ecl_sum_type * ecl_sum , FILE * stream , int internal_index , const bool_vector_type * has_var , const int_vector_type * var_index , char * date_string , const ecl_sum_fmt_type * fmt) {
fprintf(stream , fmt->days_fmt , ecl_sum_iget_sim_days(ecl_sum , internal_index));
fprintf(stream , fmt->sep );
fprintf(stream , "%s", fmt->sep );
{
{
struct tm ts;
time_t sim_time = ecl_sum_iget_sim_time(ecl_sum , internal_index );
util_localtime( &sim_time , &ts);
strftime( date_string , DATE_STRING_LENGTH - 1 , fmt->date_fmt , &ts);
fprintf(stream , date_string );
}
fprintf(stream , "%s", date_string );
}
{
int ivar;
for (ivar = 0; ivar < int_vector_size( var_index ); ivar++) {
for (ivar = 0; ivar < int_vector_size( var_index ); ivar++) {
if (bool_vector_iget( has_var , ivar )) {
fprintf(stream , fmt->sep);
fprintf(stream , "%s", fmt->sep);
fprintf(stream , fmt->value_fmt , ecl_sum_iget(ecl_sum , internal_index, int_vector_iget( var_index , ivar )));
}
}
}
}
}
fprintf(stream , fmt->newline);
fprintf(stream , "%s", fmt->newline);
}
static void ecl_sum_fprintf_header( const ecl_sum_type * ecl_sum , const stringlist_type * key_list , const bool_vector_type * has_var , FILE * stream, const ecl_sum_fmt_type * fmt) {
fprintf(stream , fmt->date_header);
{
fprintf(stream , "%s", fmt->date_header);
{
int i;
for (i=0; i < stringlist_get_size( key_list ); i++)
if (bool_vector_iget( has_var , i )) {
fprintf(stream , fmt->sep);
if (bool_vector_iget( has_var , i )) {
fprintf(stream , "%s", fmt->sep);
fprintf(stream , fmt->header_fmt , stringlist_iget( key_list , i ));
}
}
fprintf( stream , fmt->newline);
fprintf( stream , "%s", fmt->newline);
if (fmt->print_dash) {
fprintf(stream , fmt->date_dash);
fprintf(stream , "%s", fmt->date_dash);
{
int i;
for (i=0; i < stringlist_get_size( key_list ); i++)
if (bool_vector_iget( has_var , i ))
fprintf(stream , fmt->value_dash);
fprintf(stream , "%s", fmt->value_dash);
}
fprintf( stream , fmt->newline);
fprintf( stream , "%s", fmt->newline);
}
}
@@ -964,7 +972,7 @@ void ecl_sum_fprintf(const ecl_sum_type * ecl_sum , FILE * stream , const string
char * current_locale = NULL;
if (fmt->locale != NULL)
current_locale = setlocale(LC_NUMERIC , fmt->locale);
{
int ivar;
for (ivar = 0; ivar < stringlist_get_size( var_list ); ivar++) {
@@ -977,7 +985,7 @@ void ecl_sum_fprintf(const ecl_sum_type * ecl_sum , FILE * stream , const string
}
}
}
if (fmt->print_header)
ecl_sum_fprintf_header( ecl_sum , var_list , has_var , stream , fmt);
@@ -1175,10 +1183,10 @@ void ecl_sum_update_wgname( ecl_sum_type * ecl_sum , smspec_node_type * node , c
/*****************************************************************/
/*
/*
The functions below are extremly simple functions which only serve
as an easy access to the smspec_alloc_xxx_key() functions which
know how to create the various composite keys.
know how to create the various composite keys.
*/
char * ecl_sum_alloc_well_key( const ecl_sum_type * ecl_sum , const char * keyword , const char * wgname) {
@@ -1198,7 +1206,7 @@ bool ecl_sum_is_oil_producer( const ecl_sum_type * ecl_sum , const char * well)
if (wopt > 0)
oil_producer = true;
}
return oil_producer;
}
@@ -1206,7 +1214,7 @@ bool ecl_sum_is_oil_producer( const ecl_sum_type * ecl_sum , const char * well)
bool ecl_sum_report_step_equal( const ecl_sum_type * ecl_sum1 , const ecl_sum_type * ecl_sum2) {
if (ecl_sum1 == ecl_sum2)
return true;
return true;
else
return ecl_sum_data_report_step_equal( ecl_sum1->data , ecl_sum2->data );
}
@@ -1214,7 +1222,7 @@ bool ecl_sum_report_step_equal( const ecl_sum_type * ecl_sum1 , const ecl_sum_ty
bool ecl_sum_report_step_compatible( const ecl_sum_type * ecl_sum1 , const ecl_sum_type * ecl_sum2) {
if (ecl_sum1 == ecl_sum2)
return true;
return true;
else
return ecl_sum_data_report_step_compatible( ecl_sum1->data , ecl_sum2->data );
}
+230 -188
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_sum_data.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_sum_data.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <string.h>
@@ -34,14 +34,15 @@
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_endian_flip.h>
#include <ert/ecl/ecl_kw_magic.h>
#include <ert/ecl/ecl_sum_vector.h>
/*
This file implements the type ecl_sum_data_type. The data structure
This file implements the type ecl_sum_data_type. The data structure
is involved with holding all the actual summary data (i.e. the
PARAMS vectors in ECLIPSE speak), in addition the time-information
with MINISTEPS / REPORT_STEPS and so on is implemented here.
with MINISTEPS / REPORT_STEPS and so on is implemented here.
This file has no information about how to index into the PARAMS
vector, i.e. at which location can the WWCT for well P6 be found,
@@ -62,7 +63,7 @@
------------------
SEQHDR \
MINISTEP 0 |
MINISTEP 0 |
PARAMS ..... |
MINISTEP 1 |==> This is REPORT STEP 1, in file BASE.S00001
PARAMS ..... |
@@ -92,7 +93,7 @@
* When using multiple files we can read off the report number
from the filename, for unified files this is IMPOSSIBLE, and we
just have to assume that the first block corresponds to
report_step 1 and then count afterwards.
report_step 1 and then count afterwards.
* When asking for a summary variable at a particular REPORT STEP
(as we do in enkf) it is ambigous as to which ministep within
@@ -101,7 +102,7 @@
use the last ministep in the block.
* There is no BASE.SOOOO file
* The report steps are halfopen intervals in the "wrong way":
(....]
@@ -116,7 +117,7 @@
underlying partial differential equation, i.e. the length of the
timesteps is controlled by the simulator itself - there is no finer
temporal resolution.
The user has told the simulator to store (i.e. save to file
results) the results at reportsteps. A reportstep will typically
consist of several ministeps. The timeline below shows a simulation
@@ -125,8 +126,8 @@
S0001 S0002
||------|------|------------|------------------||----------------------|----------------------||
M1 M2 M3 M4 M5 M6
M1 M2 M3 M4 M5 M6
The first reportstep consist of four ministeps, the second
reportstep consits of only two ministeps. As a user you have no
control over the length/number of ministeps apart from:
@@ -163,7 +164,7 @@
S0000 S0001
||--------------|---------------|------------X-------------||
M1 M2 /|\ M3
|
|
|
We have enteeed the sim_days/sim_time cooresponding to the location
@@ -179,9 +180,9 @@
ecl_smspec_set_rate_var() function in ecl_smspec.c.
Indexing and _get() versus _iget()
----------------------------------
----------------------------------
As already mentionded the set of ministeps is not necessarrily a
continous series, we can easily have a series of ministeps with
"holes" in it, and the series can also start on a non-zero
@@ -196,11 +197,11 @@
data by giving an internal (not that internal ...) index. In
ecl_sum_data.c the latter functions have _iget():
ecl_sum_data_get_xxx : Expects the time direction given as a ministep_nr.
ecl_sum_data_iget_xxx: Expects the time direction given as an internal index.
*/
*/
@@ -211,14 +212,14 @@ struct ecl_sum_data_struct {
ecl_smspec_type * smspec; /* A shared reference - only used for providing good error messages. */
vector_type * data; /* Vector of ecl_sum_tstep_type instances. */
int first_ministep;
int last_ministep;
int last_ministep;
double days_start;
double sim_length;
int_vector_type * report_first_index ; /* Indexed by report_step - giving first internal_index in report_step. */
int_vector_type * report_last_index; /* Indexed by report_step - giving last internal_index in report_step. */
int_vector_type * report_last_index; /* Indexed by report_step - giving last internal_index in report_step. */
int first_report_step;
int last_report_step;
time_t __min_time; /* An internal member used during the load of
time_t __min_time; /* An internal member used during the load of
restarted cases; see doc in ecl_sum_data_append_tstep. */
bool index_valid;
time_interval_type * sim_time; /* The time interval sim_time goes from the first time value where we have
@@ -250,13 +251,13 @@ struct ecl_sum_data_struct {
static void ecl_sum_data_clear_index( ecl_sum_data_type * data ) {
int_vector_reset( data->report_first_index);
int_vector_reset( data->report_last_index);
data->first_report_step = 1024 * 1024;
data->last_report_step = -1024 * 1024;
data->days_start = 0;
data->sim_length = -1;
data->first_ministep = INVALID_MINISTEP_NR;
data->last_ministep = INVALID_MINISTEP_NR;
data->last_ministep = INVALID_MINISTEP_NR;
data->index_valid = false;
time_interval_reopen( data->sim_time );
}
@@ -267,8 +268,8 @@ ecl_sum_data_type * ecl_sum_data_alloc(ecl_smspec_type * smspec) {
data->data = vector_alloc_new();
data->smspec = smspec;
data->__min_time = 0;
data->report_first_index = int_vector_alloc( 0 , INVALID_MINISTEP_NR );
data->report_first_index = int_vector_alloc( 0 , INVALID_MINISTEP_NR );
data->report_last_index = int_vector_alloc( 0 , INVALID_MINISTEP_NR );
data->sim_time = time_interval_alloc_open();
@@ -280,17 +281,17 @@ ecl_sum_data_type * ecl_sum_data_alloc(ecl_smspec_type * smspec) {
/**
This function will take a report as input , and update the two
pointers ministep1 and ministep2 with the range of the report step
(in terms of ministeps).
(in terms of ministeps).
Calling this function with report_step == 2 for the example
documented at the top of the file will yield: *ministep1 = 3 and
*ministep2 = 7. If you are only interested in one of the limits you
can pass in NULL for the other limit, i.e.
can pass in NULL for the other limit, i.e.
xxx(data , report_step , NULL , &ministep2);
xxx(data , report_step , NULL , &ministep2);
to get the last step.
If the supplied report_step is invalid the function will set both
return values to -1 (the return value from safe_iget). In that case
it is the responsability of the calling scope to check the return
@@ -308,9 +309,9 @@ static const ecl_sum_tstep_type * ecl_sum_data_iget_ministep( const ecl_sum_data
void ecl_sum_data_report2internal_range(const ecl_sum_data_type * data , int report_step , int * index1 , int * index2 ){
if (index1 != NULL)
*index1 = int_vector_safe_iget( data->report_first_index , report_step );
if (index2 != NULL)
*index2 = int_vector_safe_iget( data->report_last_index , report_step );
*index2 = int_vector_safe_iget( data->report_last_index , report_step );
}
@@ -331,7 +332,7 @@ static void ecl_sum_data_fwrite_report__( const ecl_sum_data_type * data , int r
{
int index , index1 , index2;
ecl_sum_data_report2internal_range( data , report_step , &index1 , &index2);
for (index = index1; index <= index2; index++) {
const ecl_sum_tstep_type * tstep = ecl_sum_data_iget_ministep( data , index );
@@ -345,9 +346,9 @@ static void ecl_sum_data_fwrite_report__( const ecl_sum_data_type * data , int r
static void ecl_sum_data_fwrite_multiple_step( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case , int report_step) {
char * filename = ecl_util_alloc_filename( NULL , ecl_case , ECL_UNIFIED_SUMMARY_FILE , fmt_case , 0 );
fortio_type * fortio = fortio_open_readwrite( filename , fmt_case , ECL_ENDIAN_FLIP );
ecl_sum_data_fwrite_report__( data , report_step , fortio );
fortio_fclose( fortio );
free(filename);
}
@@ -356,7 +357,7 @@ static void ecl_sum_data_fwrite_multiple_step( const ecl_sum_data_type * data ,
static void ecl_sum_data_fwrite_unified_step( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case , int report_step) {
char * filename = ecl_util_alloc_filename( NULL , ecl_case , ECL_UNIFIED_SUMMARY_FILE , fmt_case , 0 );
fortio_type * fortio = fortio_open_readwrite( filename , fmt_case , ECL_ENDIAN_FLIP );
int current_step = 1;
if (report_step > 1) {
while (true) {
@@ -370,15 +371,15 @@ static void ecl_sum_data_fwrite_unified_step( const ecl_sum_data_type * data , c
}
}
}
if (current_step == report_step) { // We found the position:
long size = fortio_ftell( fortio );
util_ftruncate( fortio_get_FILE( fortio ) , size );
ecl_sum_data_fwrite_report__( data , report_step , fortio );
} else
util_abort("%s: hmm could not locate the position for report step:%d in summary file:%s \n",__func__ , report_step , filename);
fortio_fclose( fortio );
free( filename );
}
@@ -389,12 +390,12 @@ static void ecl_sum_data_fwrite_unified( const ecl_sum_data_type * data , const
char * filename = ecl_util_alloc_filename( NULL , ecl_case , ECL_UNIFIED_SUMMARY_FILE , fmt_case , 0 );
fortio_type * fortio = fortio_open_writer( filename , fmt_case , ECL_ENDIAN_FLIP );
int report_step;
for (report_step = data->first_report_step; report_step <= data->last_report_step; report_step++) {
if (ecl_sum_data_has_report_step( data , report_step ))
ecl_sum_data_fwrite_report__( data , report_step , fortio );
}
}
fortio_fclose( fortio );
free( filename );
}
@@ -407,14 +408,14 @@ static void ecl_sum_data_fwrite_multiple( const ecl_sum_data_type * data , const
if (ecl_sum_data_has_report_step( data , report_step )) {
char * filename = ecl_util_alloc_filename( NULL , ecl_case , ECL_SUMMARY_FILE , fmt_case , report_step );
fortio_type * fortio = fortio_open_writer( filename , fmt_case , ECL_ENDIAN_FLIP );
ecl_sum_data_fwrite_report__( data , report_step , fortio );
fortio_fclose( fortio );
free( filename );
}
}
}
}
@@ -451,8 +452,8 @@ double ecl_sum_data_get_first_day( const ecl_sum_data_type * data) { return data
actually been loaded) to the last loaded simulation step.
*/
double ecl_sum_data_get_sim_length( const ecl_sum_data_type * data ) {
return data->sim_length;
double ecl_sum_data_get_sim_length( const ecl_sum_data_type * data ) {
return data->sim_length;
}
@@ -466,7 +467,7 @@ double ecl_sum_data_get_sim_length( const ecl_sum_data_type * data ) {
have summary data for the requested date/days value. In the case of
a restarted case, where the original case is missing - this will
return false if the input values are in the region after simulation
start with no data.
start with no data.
*/
bool ecl_sum_data_check_sim_time( const ecl_sum_data_type * data , time_t sim_time) {
@@ -527,7 +528,7 @@ bool ecl_sum_data_check_sim_days( const ecl_sum_data_type * data , double sim_da
static int ecl_sum_data_get_index_from_sim_time( const ecl_sum_data_type * data , time_t sim_time) {
time_t data_start_time = time_interval_get_start( data->sim_time );
time_t sim_end = time_interval_get_end( data->sim_time );
if (!ecl_sum_data_check_sim_time( data , sim_time )) {
fprintf(stderr , "Simulation start: "); util_fprintf_date( ecl_smspec_get_start_time( data->smspec ) , stderr );
fprintf(stderr , "Data start......: "); util_fprintf_date( data_start_time , stderr );
@@ -535,8 +536,8 @@ static int ecl_sum_data_get_index_from_sim_time( const ecl_sum_data_type * data
fprintf(stderr , "Requested date .: "); util_fprintf_date( sim_time , stderr );
util_abort("%s: invalid time_t instance:%d interval: [%d,%d]\n",__func__, sim_time , data_start_time , sim_end);
}
/*
/*
The moment we have passed the intial test we MUST find a valid
ministep index, however care should be taken that there can
perfectly well be 'holes' in the time domain, because of e.g. the
@@ -546,7 +547,7 @@ static int ecl_sum_data_get_index_from_sim_time( const ecl_sum_data_type * data
int low_index = 0;
int high_index = vector_get_size( data->data );
int internal_index = INVALID_MINISTEP_NR;
while (internal_index < 0) {
if (low_index == high_index)
@@ -554,7 +555,7 @@ static int ecl_sum_data_get_index_from_sim_time( const ecl_sum_data_type * data
else {
int center_index = 0.5*( low_index + high_index );
const ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep( data , center_index );
if ((high_index - low_index) == 1) {
/* Degenerate special case. */
if (sim_time < ecl_sum_tstep_get_sim_time( ministep ))
@@ -570,7 +571,7 @@ static int ecl_sum_data_get_index_from_sim_time( const ecl_sum_data_type * data
const ecl_sum_tstep_type * prev_step = ecl_sum_data_iget_ministep( data , center_index - 1 );
prev_time = ecl_sum_tstep_get_sim_time( prev_step );
}
if (prev_time < sim_time)
internal_index = center_index; /* Found it */
else
@@ -594,7 +595,7 @@ int ecl_sum_data_get_index_from_sim_days( const ecl_sum_data_type * data , doubl
/**
This function will take a true time 'sim_time' as input. The
ministep indices bracketing this sim_time is identified, and the
corresponding weights are calculated.
corresponding weights are calculated.
The actual value we are interested in can then be computed with the
ecl_sum_data_interp_get() function:
@@ -609,8 +610,8 @@ int ecl_sum_data_get_index_from_sim_days( const ecl_sum_data_type * data , doubl
ecl_sum_data_init_interp_from_sim_time( data , sim_time , &ministep1 , &ministep2 , &weight1 , &weight2);
return ecl_sum_data_interp_get( data , ministep1 , ministep2 , weight1 , weight2 , param_index );
}
For further explanation (in particular for which keywords the
function should be used), consult documentation at the top of this
file.
@@ -624,8 +625,8 @@ void ecl_sum_data_init_interp_from_sim_time( const ecl_sum_data_type * data , ti
const ecl_sum_tstep_type * ministep2 = ecl_sum_data_iget_ministep( data , index2 );
const ecl_sum_tstep_type * ministep1;
time_t sim_time2 = ecl_sum_tstep_get_sim_time( ministep2 );
index1 = index2;
while (true) {
index1--;
@@ -638,12 +639,12 @@ void ecl_sum_data_init_interp_from_sim_time( const ecl_sum_data_type * data , ti
if (index1 == 0)
util_abort("%s: Hmm internal error?? \n",__func__);
}
{
double weight2 = (sim_time - ecl_sum_tstep_get_sim_time( ministep1 ));
double weight1 = -(sim_time - ecl_sum_tstep_get_sim_time( ministep2 ));
*_index1 = index1;
*_index2 = index2;
*_weight1 = weight1 / ( weight1 + weight2 );
@@ -664,7 +665,7 @@ void ecl_sum_data_init_interp_from_sim_days( const ecl_sum_data_type * data , do
static void ecl_sum_data_append_tstep__( ecl_sum_data_type * data , int ministep_nr , ecl_sum_tstep_type * tstep) {
/*
/*
Here the tstep is just appended naively, the vector will be
sorted by ministep_nr before the data instance is returned.
*/
@@ -681,8 +682,8 @@ static void ecl_sum_data_append_tstep__( ecl_sum_data_type * data , int ministep
the initial simulation:
Simulation 1: T1-------------TR------------T2
|
Simulation 2: \-----------------------T3
|
Simulation 2: \-----------------------T3
In the time interval [TR,T2] we have data from two simulations, we
@@ -691,14 +692,14 @@ static void ecl_sum_data_append_tstep__( ecl_sum_data_type * data , int ministep
have been performed by the scope calling this function; when a
ministep has arrived here it will be added.
*/
if (data->__min_time == 0)
data->__min_time = ecl_sum_tstep_get_sim_time( tstep );
else {
if (ecl_sum_tstep_get_sim_time( tstep ) < data->__min_time)
data->__min_time = ecl_sum_tstep_get_sim_time( tstep );
}
vector_append_owned_ref( data->data , tstep , ecl_sum_tstep_free__);
data->index_valid = false;
}
@@ -706,15 +707,15 @@ static void ecl_sum_data_append_tstep__( ecl_sum_data_type * data , int ministep
static void ecl_sum_data_update_end_info( ecl_sum_data_type * sum_data ) {
const ecl_sum_tstep_type * last_ministep = vector_get_last_const( sum_data->data );
sum_data->last_ministep = ecl_sum_tstep_get_ministep( last_ministep );
sum_data->sim_length = ecl_sum_tstep_get_sim_days( last_ministep );
time_interval_update_end( sum_data->sim_time , ecl_sum_tstep_get_sim_time( last_ministep ));
}
static int cmp_ministep( const void * arg1 , const void * arg2) {
const ecl_sum_tstep_type * ministep1 = ecl_sum_tstep_safe_cast_const( arg1 );
const ecl_sum_tstep_type * ministep2 = ecl_sum_tstep_safe_cast_const( arg2 );
const ecl_sum_tstep_type * ministep2 = ecl_sum_tstep_safe_cast_const( arg2 );
time_t time1 = ecl_sum_tstep_get_sim_time( ministep1 );
time_t time2 = ecl_sum_tstep_get_sim_time( ministep2 );
@@ -731,19 +732,19 @@ static int cmp_ministep( const void * arg1 , const void * arg2) {
static void ecl_sum_data_build_index( ecl_sum_data_type * sum_data ) {
/* Clear the existing index (if any): */
ecl_sum_data_clear_index( sum_data );
/*
Sort the internal storage vector after sim_time.
Sort the internal storage vector after sim_time.
*/
vector_sort( sum_data->data , cmp_ministep );
/* Identify various global first and last values. */
{
const ecl_sum_tstep_type * first_ministep = ecl_sum_data_iget_ministep( sum_data , 0 );
sum_data->first_ministep = ecl_sum_tstep_get_ministep( first_ministep );
/*
/*
In most cases the days_start and data_start_time will agree
with the global simulation start; however in the case where we
have loaded a summary case from a restarted simulation where
@@ -754,14 +755,14 @@ static void ecl_sum_data_build_index( ecl_sum_data_type * sum_data ) {
time_interval_update_start( sum_data->sim_time , ecl_sum_tstep_get_sim_time( first_ministep ));
}
ecl_sum_data_update_end_info( sum_data );
/* Build up the report -> ministep mapping. */
{
int internal_index;
for (internal_index = 0; internal_index < vector_get_size( sum_data->data ); internal_index++) {
const ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep( sum_data , internal_index );
int report_step = ecl_sum_tstep_get_report(ministep);
/* Indexing internal_index - report_step */
{
int current_first_index = int_vector_safe_iget( sum_data->report_first_index , report_step );
@@ -771,7 +772,7 @@ static void ecl_sum_data_build_index( ecl_sum_data_type * sum_data ) {
if (internal_index < current_first_index)
int_vector_iset( sum_data->report_first_index , report_step , internal_index);
}
{
int current_last_index = int_vector_safe_iget( sum_data->report_last_index , report_step );
if (current_last_index < 0)
@@ -780,7 +781,7 @@ static void ecl_sum_data_build_index( ecl_sum_data_type * sum_data ) {
if (internal_index > current_last_index)
int_vector_iset( sum_data->report_last_index , report_step , internal_index);
}
sum_data->first_report_step = util_int_min( sum_data->first_report_step , report_step );
sum_data->last_report_step = util_int_max( sum_data->last_report_step , report_step );
}
@@ -796,7 +797,7 @@ static void ecl_sum_data_build_index( ecl_sum_data_type * sum_data ) {
will also be returned, so the calling scope can call
ecl_sum_tstep_iset() to set elements in the tstep.
*/
ecl_sum_tstep_type * ecl_sum_data_add_new_tstep( ecl_sum_data_type * data , int report_step , double sim_days) {
int ministep_nr = vector_get_size( data->data );
ecl_sum_tstep_type * tstep = ecl_sum_tstep_alloc_new( report_step , ministep_nr , sim_days , data->smspec );
@@ -804,7 +805,7 @@ ecl_sum_tstep_type * ecl_sum_data_add_new_tstep( ecl_sum_data_type * data , int
if (vector_get_size( data->data ) > 0)
prev_tstep = vector_get_last( data->data );
ecl_sum_data_append_tstep__( data , ministep_nr , tstep );
{
bool rebuild_index = true;
@@ -815,12 +816,12 @@ ecl_sum_tstep_type * ecl_sum_data_add_new_tstep( ecl_sum_data_type * data , int
index, otherwise we call ecl_sum_data_build_index() to get a
full recalculation of the index.
*/
if (prev_tstep != NULL) {
if (ecl_sum_tstep_get_report( prev_tstep ) == ecl_sum_tstep_get_report( tstep )) { // Same report step
if (ecl_sum_tstep_get_sim_days( prev_tstep ) < ecl_sum_tstep_get_sim_days( tstep )) { // This tstep will become the new latest tstep
int internal_index = vector_get_size( data->data ) - 1;
ecl_sum_data_update_end_info( data );
int_vector_iset( data->report_last_index , report_step , internal_index );
rebuild_index = false;
@@ -831,7 +832,7 @@ ecl_sum_tstep_type * ecl_sum_data_add_new_tstep( ecl_sum_data_type * data , int
ecl_sum_data_build_index( data );
}
ecl_smspec_lock( data->smspec );
return tstep;
}
@@ -863,13 +864,13 @@ ecl_sum_tstep_type * ecl_sum_data_add_new_tstep( ecl_sum_data_type * data , int
calling routine will read the unified summary file partly.
*/
static void ecl_sum_data_add_ecl_file(ecl_sum_data_type * data ,
time_t load_end ,
int report_step ,
const ecl_file_type * ecl_file ,
static void ecl_sum_data_add_ecl_file(ecl_sum_data_type * data ,
time_t load_end ,
int report_step ,
const ecl_file_type * ecl_file ,
const ecl_smspec_type * smspec) {
int num_ministep = ecl_file_get_num_named_kw( ecl_file , PARAMS_KW);
if (num_ministep > 0) {
int ikw;
@@ -881,16 +882,16 @@ static void ecl_sum_data_add_ecl_file(ecl_sum_data_type * data ,
{
ecl_sum_tstep_type * tstep;
int ministep_nr = ecl_kw_iget_int( ministep_kw , 0 );
tstep = ecl_sum_tstep_alloc_from_file( report_step ,
tstep = ecl_sum_tstep_alloc_from_file( report_step ,
ministep_nr ,
params_kw ,
params_kw ,
ecl_file_get_src_file( ecl_file ),
smspec );
if (tstep != NULL) {
if (load_end == 0 || (ecl_sum_tstep_get_sim_time( tstep ) < load_end))
ecl_sum_data_append_tstep__( data , ministep_nr , tstep );
else
else
/* This tstep is in a time-period overlapping with data we
already have; discard this. */
ecl_sum_tstep_free( tstep );
@@ -901,76 +902,87 @@ static void ecl_sum_data_add_ecl_file(ecl_sum_data_type * data ,
}
static bool ecl_sum_data_check_file( ecl_file_type * ecl_file ) {
if (ecl_file_has_kw( ecl_file , PARAMS_KW ) &&
(ecl_file_get_num_named_kw( ecl_file , PARAMS_KW ) == ecl_file_get_num_named_kw( ecl_file , MINISTEP_KW)))
return true;
else
return false;
}
/*
Observe that this can be called several times (but not with the same
data - that will die).
data - that will die).
Warning: The index information of the ecl_sum_data instance has
__NOT__ been updated when leaving this function. That is done with a
call to ecl_sum_data_build_index().
*/
static void ecl_sum_data_fread__( ecl_sum_data_type * data , time_t load_end , const stringlist_type * filelist) {
ecl_file_enum file_type;
static bool ecl_sum_data_fread__( ecl_sum_data_type * data , time_t load_end , const stringlist_type * filelist) {
if (stringlist_get_size( filelist ) == 0)
util_abort("%s: internal error - function called with empty list of data files.\n",__func__);
file_type = ecl_util_get_file_type( stringlist_iget( filelist , 0 ) , NULL , NULL);
if ((stringlist_get_size( filelist ) > 1) && (file_type != ECL_SUMMARY_FILE))
util_abort("%s: internal error - when calling with more than one file - you can not supply a unified file - come on?! \n",__func__);
return false;
{
int filenr;
if (file_type == ECL_SUMMARY_FILE) {
/* Not unified. */
for (filenr = 0; filenr < stringlist_get_size( filelist ); filenr++) {
const char * data_file = stringlist_iget( filelist , filenr);
ecl_file_enum file_type;
int report_step;
file_type = ecl_util_get_file_type( data_file , NULL , &report_step);
/**
ECLIPSE starts a report step by writing an empty summary
file, therefor we must verify that the ecl_file instance
returned by ecl_file_fread_alloc() is different from NULL
before adding it to the ecl_sum_data instance.
*/
if (file_type != ECL_SUMMARY_FILE)
util_abort("%s: file:%s has wrong type \n",__func__ , data_file);
{
ecl_file_type * ecl_file = ecl_file_open( data_file , 0);
ecl_sum_data_add_ecl_file( data , load_end , report_step , ecl_file , data->smspec);
ecl_file_enum file_type = ecl_util_get_file_type( stringlist_iget( filelist , 0 ) , NULL , NULL);
if ((stringlist_get_size( filelist ) > 1) && (file_type != ECL_SUMMARY_FILE))
util_abort("%s: internal error - when calling with more than one file - you can not supply a unified file - come on?! \n",__func__);
{
int filenr;
if (file_type == ECL_SUMMARY_FILE) {
/* Not unified. */
for (filenr = 0; filenr < stringlist_get_size( filelist ); filenr++) {
const char * data_file = stringlist_iget( filelist , filenr);
ecl_file_enum file_type;
int report_step;
file_type = ecl_util_get_file_type( data_file , NULL , &report_step);
if (file_type != ECL_SUMMARY_FILE)
util_abort("%s: file:%s has wrong type \n",__func__ , data_file);
{
ecl_file_type * ecl_file = ecl_file_open( data_file , 0);
if (ecl_file && ecl_sum_data_check_file( ecl_file )) {
ecl_sum_data_add_ecl_file( data , load_end , report_step , ecl_file , data->smspec);
ecl_file_close( ecl_file );
}
}
}
} else if (file_type == ECL_UNIFIED_SUMMARY_FILE) {
ecl_file_type * ecl_file = ecl_file_open( stringlist_iget(filelist ,0 ) , 0);
if (ecl_file && ecl_sum_data_check_file( ecl_file )) {
int report_step = 1; /* <- ECLIPSE numbering - starting at 1. */
while (true) {
/*
Observe that there is a number discrepancy between ECLIPSE
and the ecl_file_select_smryblock() function. ECLIPSE
starts counting report steps at 1; whereas the first
SEQHDR block in the unified summary file is block zero (in
ert counting).
*/
if (ecl_file_select_smryblock( ecl_file , report_step - 1)) {
ecl_sum_data_add_ecl_file( data , load_end , report_step , ecl_file , data->smspec);
report_step++;
} else break;
}
ecl_file_close( ecl_file );
}
}
} else if (file_type == ECL_UNIFIED_SUMMARY_FILE) {
ecl_file_type * ecl_file = ecl_file_open( stringlist_iget(filelist ,0 ) , 0);
int report_step = 1; /* <- ECLIPSE numbering - starting at 1. */
while (true) {
/*
Observe that there is a number discrepancy between ECLIPSE
and the ecl_file_select_smryblock() function. ECLIPSE
starts counting report steps at 1; whereas the first
SEQHDR block in the unified summary file is block zero (in
ert counting).
*/
if (ecl_file_select_smryblock( ecl_file , report_step - 1)) {
ecl_sum_data_add_ecl_file( data , load_end , report_step , ecl_file , data->smspec);
report_step++;
} else break;
}
ecl_file_close( ecl_file );
} else
util_abort("%s: invalid file type:%s \n",__func__ , ecl_util_file_type_name(file_type ));
}
ecl_sum_data_build_index( data );
} else
util_abort("%s: invalid file type:%s \n",__func__ , ecl_util_file_type_name(file_type ));
}
if (ecl_sum_data_get_length( data ) > 0) {
ecl_sum_data_build_index( data );
return true;
} else
return false;
}
}
void ecl_sum_data_fread( ecl_sum_data_type * data , const stringlist_type * filelist) {
ecl_sum_data_fread__( data , 0 , filelist );
bool ecl_sum_data_fread( ecl_sum_data_type * data , const stringlist_type * filelist) {
return ecl_sum_data_fread__( data , 0 , filelist );
}
@@ -1012,7 +1024,7 @@ ecl_sum_data_type * ecl_sum_data_fread_alloc( ecl_smspec_type * smspec , const s
}
void ecl_sum_data_summarize(const ecl_sum_data_type * data , FILE * stream) {
void ecl_sum_data_summarize(const ecl_sum_data_type * data , FILE * stream) {
fprintf(stream , "REPORT INDEX DATE DAYS\n");
fprintf(stream , "---------------------------------------------------------------\n");
{
@@ -1048,7 +1060,7 @@ bool ecl_sum_data_has_report_step(const ecl_sum_data_type * data , int report_st
*/
int ecl_sum_data_iget_report_end( const ecl_sum_data_type * data , int report_step ) {
return int_vector_safe_iget( data->report_last_index , report_step );
return int_vector_safe_iget( data->report_last_index , report_step );
}
@@ -1062,7 +1074,7 @@ int ecl_sum_data_iget_report_end( const ecl_sum_data_type * data , int report_st
int ecl_sum_data_iget_report_start( const ecl_sum_data_type * data , int report_step ) {
return int_vector_safe_iget( data->report_first_index , report_step );
return int_vector_safe_iget( data->report_first_index , report_step );
}
@@ -1086,7 +1098,7 @@ int ecl_sum_data_iget_mini_step(const ecl_sum_data_type * data , int internal_in
/**
/**
This will look up a value based on an internal index. The internal
index will ALWAYS run in the interval [0,num_ministep), without
any holes.
@@ -1095,16 +1107,16 @@ int ecl_sum_data_iget_mini_step(const ecl_sum_data_type * data , int internal_in
double ecl_sum_data_iget( const ecl_sum_data_type * data , int time_index , int params_index ) {
const ecl_sum_tstep_type * ministep_data = ecl_sum_data_iget_ministep( data , time_index );
return ecl_sum_tstep_iget( ministep_data , params_index);
return ecl_sum_tstep_iget( ministep_data , params_index);
}
/**
This function will form a weight average of the two ministeps
@ministep1 and @ministep2. The weights and the ministep indices
should (typically) be determined by the
should (typically) be determined by the
ecl_sum_data_init_interp_from_sim_xxx()
ecl_sum_data_init_interp_from_sim_xxx()
functions. The function will typically the last function called
when we seek a reservoir state variable at an intermediate time
@@ -1112,13 +1124,43 @@ double ecl_sum_data_iget( const ecl_sum_data_type * data , int time_index , int
*/
double ecl_sum_data_interp_get(const ecl_sum_data_type * data , int time_index1 , int time_index2 , double weight1 , double weight2 , int params_index) {
const ecl_sum_tstep_type * ministep_data1 = ecl_sum_data_iget_ministep( data , time_index1 );
const ecl_sum_tstep_type * ministep_data2 = ecl_sum_data_iget_ministep( data , time_index2 );
const ecl_sum_tstep_type * ministep_data1 = ecl_sum_data_iget_ministep( data , time_index1 );
const ecl_sum_tstep_type * ministep_data2 = ecl_sum_data_iget_ministep( data , time_index2 );
return ecl_sum_tstep_iget( ministep_data1 , params_index ) * weight1 + ecl_sum_tstep_iget( ministep_data2 , params_index ) * weight2;
}
void ecl_sum_data_write_csv_file(const ecl_sum_data_type * data , time_t sim_time, const ecl_sum_vector_type * keylist, FILE *fp){
int num_keywords = ecl_sum_vector_get_size(keylist);
double weight1 , weight2;
int time_index1 , time_index2;
double value = 0.0;
int i;
ecl_sum_data_init_interp_from_sim_time( data , sim_time , &time_index1 , &time_index2 , &weight1 , &weight2);
for(i = 0; i< num_keywords; i++ ){
bool is_rate = ecl_sum_vector_iget_is_rate(keylist, i);
int params_index = ecl_sum_vector_iget_param_index(keylist , i);
if(is_rate){
int time_index;
if (sim_time == time_interval_get_start( data->sim_time ))
time_index = 0;
else
time_index = ecl_sum_data_get_index_from_sim_time( data , sim_time );
value = ecl_sum_data_iget( data , time_index , params_index);
} else {
value = ecl_sum_data_interp_get( data , time_index1 , time_index2 , weight1 , weight2 , params_index);
}
if(i == 0){
fprintf(fp , "%f",value);
}else{
fprintf(fp , ",%f",value);
}
}
}
@@ -1133,14 +1175,14 @@ double ecl_sum_data_get_from_sim_time( const ecl_sum_data_type * data , time_t s
[]<------------]<--------------]<-----------]
t0 t1 t2 t3
However - as indicated on the figure above there is a zero
measure point right at the start which corresponds to
time_index == 0; this is to ensure that there is correspondance
with the ECLIPSE results if you ask for a value interpolated to
the starting time.
*/
if (sim_time == time_interval_get_start( data->sim_time ))
if (sim_time == time_interval_get_start( data->sim_time ))
time_index = 0;
else
time_index = ecl_sum_data_get_index_from_sim_time( data , sim_time );
@@ -1150,7 +1192,7 @@ double ecl_sum_data_get_from_sim_time( const ecl_sum_data_type * data , time_t s
/* Interpolated lookup based on two (hopefully) consecutive ministeps. */
double weight1 , weight2;
int time_index1 , time_index2;
ecl_sum_data_init_interp_from_sim_time( data , sim_time , &time_index1 , &time_index2 , &weight1 , &weight2);
return ecl_sum_data_interp_get( data , time_index1 , time_index2 , weight1 , weight2 , params_index);
@@ -1171,19 +1213,19 @@ int ecl_sum_data_get_report_step_from_days(const ecl_sum_data_type * data , doub
for (i=1; i < int_vector_size( data->report_last_index ); i++) {
int ministep_index = int_vector_iget( data->report_last_index , i );
const ecl_sum_tstep_type * ministep = vector_iget_const( data->data , ministep_index );
double_vector_iset( days_map , i , ecl_sum_tstep_get_sim_days( ministep ));
int_vector_iset( report_map , i , ecl_sum_tstep_get_report( ministep ));
}
{
/** Hmmmm - double == comparison ... */
int index = double_vector_index_sorted( days_map , sim_days );
if (index >= 0)
report_step = int_vector_iget( report_map , index );
}
int_vector_free( report_map );
double_vector_free( days_map );
return report_step;
@@ -1193,14 +1235,14 @@ int ecl_sum_data_get_report_step_from_days(const ecl_sum_data_type * data , doub
/**
Will go through the data and find the report step which EXACTLY
matches the input sim_time. If no report step matches exactly the
function will return -1.
function will return -1.
Observe that by default the report steps consist of half-open time
intervals like this: (t1, t2]. However the first report step
(i.e. report step 1, is a fully inclusive interval: [t0 , t1] where
t0 is the simulation start time. That is not implemented here;
meaning that if you supply the start time as @sim_time argument you
will get -1 and not 0 as you might expect.
will get -1 and not 0 as you might expect.
It would certainly be possible to detect the start_time input
argument and special case the return, but the opposite would be
@@ -1211,7 +1253,7 @@ int ecl_sum_data_get_report_step_from_days(const ecl_sum_data_type * data , doub
int ecl_sum_data_get_report_step_from_time(const ecl_sum_data_type * data , time_t sim_time) {
if (!ecl_sum_data_check_sim_time(data , sim_time))
return -1;
@@ -1225,19 +1267,19 @@ int ecl_sum_data_get_report_step_from_time(const ecl_sum_data_type * data , time
for (i=1; i < int_vector_size( data->report_last_index ); i++) {
int ministep_index = int_vector_iget( data->report_last_index , i );
const ecl_sum_tstep_type * ministep = vector_iget_const( data->data , ministep_index );
time_t_vector_iset( time_map , i , ecl_sum_tstep_get_sim_time( ministep ));
int_vector_iset( report_map , i , ecl_sum_tstep_get_report( ministep ));
}
{
int index = time_t_vector_index_sorted( time_map , sim_time );
if (index >= 0)
report_step = int_vector_iget( report_map , index );
}
int_vector_free( report_map );
time_t_vector_free( time_map );
return report_step;
@@ -1371,7 +1413,7 @@ int ecl_sum_data_get_length( const ecl_sum_data_type * data ) {
bool ecl_sum_data_report_step_equal( const ecl_sum_data_type * data1 , const ecl_sum_data_type * data2) {
bool equal = true;
if (int_vector_size( data1->report_last_index ) == int_vector_size(data2->report_last_index)) {
int i;
int i;
for (i = 0; i < int_vector_size( data1->report_last_index ); i++) {
int time_index1 = int_vector_iget( data1->report_last_index , i );
int time_index2 = int_vector_iget( data2->report_last_index , i );
@@ -1379,7 +1421,7 @@ bool ecl_sum_data_report_step_equal( const ecl_sum_data_type * data1 , const ecl
if ((time_index1 != INVALID_MINISTEP_NR) && (time_index2 != INVALID_MINISTEP_NR)) {
const ecl_sum_tstep_type * ministep1 = ecl_sum_data_iget_ministep( data1 , time_index1 );
const ecl_sum_tstep_type * ministep2 = ecl_sum_data_iget_ministep( data2 , time_index2 );
if (!ecl_sum_tstep_sim_time_equal( ministep1 , ministep2)) {
equal = false;
break;
@@ -1399,7 +1441,7 @@ bool ecl_sum_data_report_step_equal( const ecl_sum_data_type * data1 , const ecl
bool ecl_sum_data_report_step_compatible( const ecl_sum_data_type * data1 , const ecl_sum_data_type * data2) {
bool compatible = true;
int min_size = util_int_min( int_vector_size( data1->report_last_index ) , int_vector_size( data2->report_last_index));
int i;
int i;
for (i = 0; i < min_size; i++) {
int time_index1 = int_vector_iget( data1->report_last_index , i );
int time_index2 = int_vector_iget( data2->report_last_index , i );
@@ -1407,12 +1449,12 @@ bool ecl_sum_data_report_step_compatible( const ecl_sum_data_type * data1 , cons
if ((time_index1 != INVALID_MINISTEP_NR) && (time_index2 != INVALID_MINISTEP_NR)) {
const ecl_sum_tstep_type * ministep1 = ecl_sum_data_iget_ministep( data1 , time_index1 );
const ecl_sum_tstep_type * ministep2 = ecl_sum_data_iget_ministep( data2 , time_index2 );
if (!ecl_sum_tstep_sim_time_equal( ministep1 , ministep2)) {
compatible = false;
break;
}
}
}
}
}
return compatible;
}
+94
View File
@@ -0,0 +1,94 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'ecl_sum_vector.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <ert/ecl/ecl_sum_vector.h>
#include <ert/ecl/ecl_sum.h>
#include <ert/ecl/ecl_smspec.h>
#include <ert/util/util.h>
#include <ert/util/vector.h>
#include <ert/util/type_macros.h>
#include <ert/util/int_vector.h>
#include <ert/util/bool_vector.h>
#define ECL_SUM_VECTOR_TYPE_ID 8756667078
struct ecl_sum_vector_struct {
int_vector_type * node_index_list;
bool_vector_type * is_rate_list;
const ecl_sum_type * ecl_sum;
};
void ecl_sum_vector_free( ecl_sum_vector_type * ecl_sum_vector ){
int_vector_free(ecl_sum_vector->node_index_list);
bool_vector_free(ecl_sum_vector->is_rate_list);
}
ecl_sum_vector_type * ecl_sum_vector_alloc(const ecl_sum_type * ecl_sum){
ecl_sum_vector_type * ecl_sum_vector = util_malloc( sizeof * ecl_sum_vector );
ecl_sum_vector->ecl_sum = ecl_sum;
ecl_sum_vector->node_index_list = int_vector_alloc(0,0);
ecl_sum_vector->is_rate_list = bool_vector_alloc(0,false);
return ecl_sum_vector;
}
bool ecl_sum_vector_add_key( ecl_sum_vector_type * ecl_sum_vector, const char * key){
if (ecl_sum_has_general_var( ecl_sum_vector->ecl_sum , key)) {
const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum_vector->ecl_sum , key );
int params_index = smspec_node_get_params_index( node );
bool is_rate_key = smspec_node_is_rate( node);
int_vector_append(ecl_sum_vector->node_index_list, params_index);
bool_vector_append(ecl_sum_vector->is_rate_list, is_rate_key);
return true;
} else
return false;
}
void ecl_sum_vector_add_keys( ecl_sum_vector_type * ecl_sum_vector, const char * pattern){
stringlist_type * keylist = ecl_sum_alloc_matching_general_var_list(ecl_sum_vector->ecl_sum , pattern);
int num_keywords = stringlist_get_size(keylist);
int i;
for(i = 0; i < num_keywords ;i++){
const char * key = stringlist_iget(keylist, i);
const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum_vector->ecl_sum , key );
int params_index = smspec_node_get_params_index( node );
bool is_rate_key = smspec_node_is_rate( node);
int_vector_append(ecl_sum_vector->node_index_list, params_index);
bool_vector_append(ecl_sum_vector->is_rate_list, is_rate_key);
}
stringlist_free(keylist);
}
int ecl_sum_vector_get_size(const ecl_sum_vector_type * ecl_sum_vector){
return int_vector_size(ecl_sum_vector->node_index_list);
}
bool ecl_sum_vector_iget_is_rate(const ecl_sum_vector_type * ecl_sum_vector, int index){
return bool_vector_iget(ecl_sum_vector->is_rate_list, index);
}
int ecl_sum_vector_iget_param_index(const ecl_sum_vector_type * ecl_sum_vector, int index){
return int_vector_iget(ecl_sum_vector->node_index_list, index);
}
+29 -23
View File
@@ -1206,12 +1206,12 @@ int ecl_util_get_month_nr(const char * month_name) {
time_t ecl_util_get_start_date(const char * data_file) {
parser_type * parser = parser_alloc(" \t\r\n" , "\"\'" , NULL , NULL , "--" , "\n");
basic_parser_type * parser = basic_parser_alloc(" \t\r\n" , "\"\'" , NULL , NULL , "--" , "\n");
time_t start_date = -1;
FILE * stream = util_fopen(data_file , "r");
char * buffer;
if (!parser_fseek_string( parser , stream , "START" , true , true)) /* Seeks case insensitive. */
if (!basic_parser_fseek_string( parser , stream , "START" , true , true)) /* Seeks case insensitive. */
util_abort("%s: sorry - could not find START in DATA file %s \n",__func__ , data_file);
{
@@ -1219,7 +1219,7 @@ time_t ecl_util_get_start_date(const char * data_file) {
int buffer_size;
/* Look for terminating '/' */
if (!parser_fseek_string( parser , stream , "/" , false , true))
if (!basic_parser_fseek_string( parser , stream , "/" , false , true))
util_abort("%s: sorry - could not find \"/\" termination of START keyword in data_file: \n",__func__ , data_file);
buffer_size = (util_ftell(stream) - start_pos) ;
@@ -1231,7 +1231,7 @@ time_t ecl_util_get_start_date(const char * data_file) {
{
stringlist_type * tokens = parser_tokenize_buffer( parser , buffer , true );
stringlist_type * tokens = basic_parser_tokenize_buffer( parser , buffer , true );
int day, year, month_nr;
if ( util_sscanf_int( stringlist_iget( tokens , 0 ) , &day) && util_sscanf_int( stringlist_iget(tokens , 2) , &year)) {
month_nr = ecl_util_get_month_nr(stringlist_iget( tokens , 1));
@@ -1242,21 +1242,21 @@ time_t ecl_util_get_start_date(const char * data_file) {
}
free( buffer );
parser_free( parser );
basic_parser_free( parser );
fclose(stream);
return start_date;
}
static int ecl_util_get_num_parallel_cpu__(parser_type* parser, FILE* stream, const char * data_file) {
static int ecl_util_get_num_parallel_cpu__(basic_parser_type* parser, FILE* stream, const char * data_file) {
int num_cpu = 1;
char * buffer;
long int start_pos = util_ftell( stream );
int buffer_size;
/* Look for terminating '/' */
if (!parser_fseek_string( parser , stream , "/" , false , true))
if (!basic_parser_fseek_string( parser , stream , "/" , false , true))
util_abort("%s: sorry - could not find \"/\" termination of PARALLEL keyword in data_file: \n",__func__ , data_file);
buffer_size = (util_ftell(stream) - start_pos) ;
@@ -1266,7 +1266,7 @@ static int ecl_util_get_num_parallel_cpu__(parser_type* parser, FILE* stream, co
buffer[buffer_size] = '\0';
{
stringlist_type * tokens = parser_tokenize_buffer( parser , buffer , true );
stringlist_type * tokens = basic_parser_tokenize_buffer( parser , buffer , true );
if (stringlist_get_size( tokens ) > 0) {
const char * num_cpu_string = stringlist_iget( tokens , 0 );
@@ -1283,11 +1283,11 @@ static int ecl_util_get_num_parallel_cpu__(parser_type* parser, FILE* stream, co
static int ecl_util_get_num_slave_cpu__(parser_type* parser, FILE* stream, const char * data_file) {
static int ecl_util_get_num_slave_cpu__(basic_parser_type* parser, FILE* stream, const char * data_file) {
int num_cpu = 0;
int linecount = 0;
parser_fseek_string( parser , stream , "\n" , true , true); /* Go to next line after the SLAVES keyword*/
basic_parser_fseek_string( parser , stream , "\n" , true , true); /* Go to next line after the SLAVES keyword*/
while (true) {
char * buffer = util_fscanf_alloc_line( stream , NULL);
@@ -1296,7 +1296,7 @@ static int ecl_util_get_num_slave_cpu__(parser_type* parser, FILE* stream, const
util_abort("%s: Did not find ending \"/\" character after SLAVES keyword, aborting \n", __func__);
{
stringlist_type * tokens = parser_tokenize_buffer( parser , buffer , true );
stringlist_type * tokens = basic_parser_tokenize_buffer( parser , buffer , true );
if (stringlist_get_size(tokens) > 0 ) {
const char * first_item = stringlist_iget(tokens, 0);
@@ -1322,34 +1322,34 @@ static int ecl_util_get_num_slave_cpu__(parser_type* parser, FILE* stream, const
int ecl_util_get_num_cpu(const char * data_file) {
int num_cpu = 1;
parser_type * parser = parser_alloc(" \t\r\n" , "\"\'" , NULL , NULL , "--" , "\n");
basic_parser_type * parser = basic_parser_alloc(" \t\r\n" , "\"\'" , NULL , NULL , "--" , "\n");
FILE * stream = util_fopen(data_file , "r");
if (parser_fseek_string( parser , stream , "PARALLEL" , true , true)) { /* Seeks case insensitive. */
if (basic_parser_fseek_string( parser , stream , "PARALLEL" , true , true)) { /* Seeks case insensitive. */
num_cpu = ecl_util_get_num_parallel_cpu__(parser, stream, data_file);
} else if (parser_fseek_string( parser , stream , "SLAVES" , true , true)) { /* Seeks case insensitive. */
} else if (basic_parser_fseek_string( parser , stream , "SLAVES" , true , true)) { /* Seeks case insensitive. */
num_cpu = ecl_util_get_num_slave_cpu__(parser, stream, data_file) + 1;
fprintf(stderr, "Information: \"SLAVES\" option found, returning %d number of CPUs", num_cpu);
}
parser_free( parser );
basic_parser_free( parser );
fclose(stream);
return num_cpu;
}
ecl_unit_enum ecl_util_get_unit_set(const char * data_file) {
ecl_unit_enum units = ECL_METRIC_UNITS;
parser_type * parser = parser_alloc(" \t\r\n" , "\"\'" , NULL , NULL , "--" , "\n");
ert_ecl_unit_enum ecl_util_get_unit_set(const char * data_file) {
ert_ecl_unit_enum units = ERT_ECL_METRIC_UNITS;
basic_parser_type * parser = basic_parser_alloc(" \t\r\n" , "\"\'" , NULL , NULL , "--" , "\n");
FILE * stream = util_fopen(data_file , "r");
if (parser_fseek_string( parser , stream , "FIELD" , true , true)) { /* Seeks case insensitive. */
units = ECL_FIELD_UNITS;
} else if (parser_fseek_string( parser , stream , "LAB" , true , true)) { /* Seeks case insensitive. */
units = ECL_LAB_UNITS;
if (basic_parser_fseek_string( parser , stream , "FIELD" , true , true)) { /* Seeks case insensitive. */
units = ERT_ECL_FIELD_UNITS;
} else if (basic_parser_fseek_string( parser , stream , "LAB" , true , true)) { /* Seeks case insensitive. */
units = ERT_ECL_LAB_UNITS;
}
parser_free( parser );
basic_parser_free( parser );
fclose(stream);
return units;
}
@@ -1534,4 +1534,10 @@ const char * ecl_util_type_enum_iget( int index, int * value) {
return util_enum_iget( index , ECL_TYPE_ENUM_SIZE , (const util_enum_element_type []) { ECL_TYPE_ENUM_DEFS }, value);
}
void ecl_util_set_date_values(time_t t , int * mday , int * month , int * year) {
return util_set_date_values(t,mday,month,year);
}
#endif
+205 -145
View File
@@ -1,19 +1,19 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'fortio.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
Copyright (C) 2011 Statoil ASA, Norway.
The file 'fortio.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdbool.h>
@@ -51,7 +51,7 @@ Where the "400" head and tail is the number of bytes in the following
record. Fortran IO handles this transparently, but when mixing with
other programming languages care must be taken. This file implements
functionality to read and write these fortran generated files
transparently. The three functions:
transparently. The three functions:
1. fortio_fopen()
2. fortio_fread_record()
@@ -65,47 +65,54 @@ fwrite() from the standard library.
#define READ_MODE_TXT "r"
#define READ_MODE_BINARY "rb"
#define WRITE_MODE_TXT "w"
#define WRITE_MODE_BINARY "wb"
#define WRITE_MODE_BINARY "wb"
#define READ_WRITE_MODE_TXT "r+"
#define READ_WRITE_MODE_BINARY "r+b"
#define APPEND_MODE_TXT "a"
#define APPEND_MODE_BINARY "ab"
#define APPEND_MODE_BINARY "ab"
struct fortio_struct {
UTIL_TYPE_ID_DECLARATION;
FILE * stream;
char * filename;
bool endian_flip_header;
bool endian_flip_header;
bool fmt_file; /* This is not really used by the fortio instance - but it is very convenient to store it here. */
const char * fopen_mode;
bool stream_owner;
/* Internal variables used during partial read.*/
int active_header;
int rec_nr;
/*
The internal variable read_size is used in the functions
fortio_fseek() and fortio_read_at_eof() - if-and-only-if - the
file is opened in read only mode.
Observe that the semantics of the fortio_fseek() function depends
on whether the file is writable.
*/
bool readable;
offset_type read_size;
};
UTIL_IS_INSTANCE_FUNCTION( fortio , FORTIO_ID );
UTIL_SAFE_CAST_FUNCTION( fortio, FORTIO_ID );
static fortio_type * fortio_alloc__(const char *filename , bool fmt_file , bool endian_flip_header , bool stream_owner) {
static fortio_type * fortio_alloc__(const char *filename , bool fmt_file , bool endian_flip_header , bool stream_owner , bool readable) {
fortio_type * fortio = util_malloc(sizeof * fortio );
UTIL_TYPE_ID_INIT( fortio, FORTIO_ID );
fortio->filename = util_alloc_string_copy(filename);
fortio->endian_flip_header = endian_flip_header;
fortio->active_header = 0;
fortio->rec_nr = 0;
fortio->fmt_file = fmt_file;
fortio->stream_owner = stream_owner;
fortio->read_size = 0;
fortio->readable = readable;
return fortio;
}
/**
Helper function for fortio_is_fortran_stream__().
Helper function for fortio_is_fortran_stream__().
*/
static bool __read_int(FILE * stream , int * value, bool endian_flip) {
@@ -139,7 +146,7 @@ static bool fortio_is_fortran_stream__(FILE * stream , bool endian_flip) {
if (util_fseek(stream , (offset_type) header , SEEK_CUR) == 0) {
if (__read_int(stream , &tail , endian_flip)) {
cont = true;
/*
/*
OK - now we have read a header and a tail - it might be
a fortran file.
*/
@@ -148,7 +155,7 @@ static bool fortio_is_fortran_stream__(FILE * stream , bool endian_flip) {
/* This is (most probably) a fortran file */
is_fortran_stream = true;
if (strict_checking)
cont = true;
cont = true;
else
cont = false;
}
@@ -160,7 +167,7 @@ static bool fortio_is_fortran_stream__(FILE * stream , bool endian_flip) {
}
}
}
}
}
}
} while (cont);
util_fseek(stream , init_pos , SEEK_SET);
@@ -170,68 +177,41 @@ static bool fortio_is_fortran_stream__(FILE * stream , bool endian_flip) {
/**
This function tries (using some heuristic) to guess whether a
particular file is a Fortran file. To complicate the matters
further we make no assumptions regarding endian ness, if it is
indeed determined that this is fortran file, the endian ness is
returned by reference (if it is not recognized as a fortran file,
the returned endian ness will be garbage).
particular file is a Fortran file.
The heuristic algorithm which is used is as follows:
1. Read four bytes as an integer (header)
2. Skip that number of bytes forward.
3. Read four bytes again (tail).
Now, when this is done we do the following tests:
Now, when this is done we do the following test:
1. If header == tail. This is (probably) a fortran file, however
if header == 0, we might have a normal file with two
consequitive zeroes. In that case it is difficult to determine,
and we continue.
If header == tail. This is (probably) a fortran file, however if
header == 0, we might have a normal file with two consequitive
zeroes. In that case it is difficult to determine, and we continue.
2. If header != tail we try to reinterpret header with an endian
swap and read a new tail. If they are now equal we repeat test1, or
return false (i.e. *not* a fortran file).
*/
bool fortio_is_fortran_file(const char * filename, bool * _endian_flip) {
bool fortio_looks_like_fortran_file(const char * filename, bool endian_flip) {
FILE * stream = util_fopen(filename , "rb");
bool endian_flip = false;
bool is_fortran_stream = fortio_is_fortran_stream__(stream , endian_flip);
if (!is_fortran_stream) {
endian_flip = !endian_flip;
is_fortran_stream = fortio_is_fortran_stream__(stream , endian_flip);
}
*_endian_flip = endian_flip;
fclose(stream);
return is_fortran_stream;
}
/**
This function tries to determine automatically whether a certain
file has endian flip or not.
Observe that the return value is whether we managed to determine the
endian-ness or not, whereas the endian_flip flag is returned by
reference.
To be able to determine endianness the file *must* be a binary
fortran file - this is essentially the return value.
*/
bool fortio_guess_endian_flip(const char * filename , bool * _endian_flip) {
return fortio_is_fortran_file(filename , _endian_flip);
static void fortio_init_size(fortio_type * fortio) {
fortio->read_size = util_fd_size( fortio_fileno( fortio ));
}
fortio_type * fortio_alloc_FILE_wrapper(const char *filename , bool endian_flip_header , bool fmt_file , FILE * stream) {
fortio_type * fortio = fortio_alloc__(filename , fmt_file , endian_flip_header , false);
fortio_type * fortio_alloc_FILE_wrapper(const char *filename , bool endian_flip_header , bool fmt_file , bool readable , FILE * stream) {
fortio_type * fortio = fortio_alloc__(filename , fmt_file , endian_flip_header , false , readable);
fortio->stream = stream;
fortio_init_size( fortio );
return fortio;
}
@@ -312,9 +292,10 @@ static FILE * fortio_fopen_append( const char * filename , bool fmt_file ) {
fortio_type * fortio_open_reader(const char *filename , bool fmt_file , bool endian_flip_header) {
FILE * stream = fortio_fopen_read( filename , fmt_file );
if (stream) {
fortio_type *fortio = fortio_alloc__(filename , fmt_file , endian_flip_header , true);
fortio_type *fortio = fortio_alloc__(filename , fmt_file , endian_flip_header , true , true);
fortio->stream = stream;
fortio->fopen_mode = fortio_fopen_read_mode( fmt_file );
fortio_init_size( fortio );
return fortio;
} else
return NULL;
@@ -326,9 +307,10 @@ fortio_type * fortio_open_reader(const char *filename , bool fmt_file , bool end
fortio_type * fortio_open_writer(const char *filename , bool fmt_file , bool endian_flip_header ) {
FILE * stream = fortio_fopen_write( filename , fmt_file );
if (stream) {
fortio_type *fortio = fortio_alloc__(filename , fmt_file , endian_flip_header, true);
fortio_type *fortio = fortio_alloc__(filename , fmt_file , endian_flip_header, true , false);
fortio->stream = stream;
fortio->fopen_mode = fortio_fopen_write_mode( fmt_file );
fortio_init_size( fortio );
return fortio;
} else
return NULL;
@@ -339,9 +321,10 @@ fortio_type * fortio_open_writer(const char *filename , bool fmt_file , bool end
fortio_type * fortio_open_readwrite(const char *filename , bool fmt_file , bool endian_flip_header) {
FILE * stream = fortio_fopen_readwrite( filename , fmt_file );
if (stream) {
fortio_type *fortio = fortio_alloc__(filename , fmt_file , endian_flip_header , true);
fortio_type *fortio = fortio_alloc__(filename , fmt_file , endian_flip_header , true , true);
fortio->stream = stream;
fortio->fopen_mode = fortio_fopen_readwrite_mode( fmt_file );
fortio_init_size( fortio );
return fortio;
} else
return NULL;
@@ -351,9 +334,12 @@ fortio_type * fortio_open_readwrite(const char *filename , bool fmt_file , bool
fortio_type * fortio_open_append(const char *filename , bool fmt_file , bool endian_flip_header) {
FILE * stream = fortio_fopen_append( filename , fmt_file );
if (stream) {
fortio_type *fortio = fortio_alloc__(filename , fmt_file , endian_flip_header , true);
fortio_type *fortio = fortio_alloc__(filename , fmt_file , endian_flip_header , true , false);
fortio->stream = stream;
fortio->fopen_mode = fortio_fopen_append_mode( fmt_file );
fortio_init_size( fortio );
return fortio;
} else
return NULL;
@@ -433,22 +419,23 @@ bool fortio_is_fortio_file(fortio_type * fortio) {
offset_type init_pos = fortio_ftell(fortio);
int elm_read;
bool is_fortio_file = false;
elm_read = fread(&fortio->active_header , sizeof(fortio->active_header) , 1 , fortio->stream);
int record_size;
elm_read = fread(&record_size , sizeof(record_size) , 1 , fortio->stream);
if (elm_read == 1) {
int trailer;
if (fortio->endian_flip_header)
util_endian_flip_vector(&fortio->active_header , sizeof fortio->active_header , 1);
util_endian_flip_vector(&record_size , sizeof record_size , 1);
if (fortio_fseek(fortio , (offset_type) fortio->active_header , SEEK_CUR) == 0) {
if (fread(&trailer , sizeof(fortio->active_header) , 1 , fortio->stream) == 1) {
if (fortio_fseek(fortio , (offset_type) record_size , SEEK_CUR) == 0) {
if (fread(&trailer , sizeof(record_size) , 1 , fortio->stream) == 1) {
if (fortio->endian_flip_header)
util_endian_flip_vector(&trailer , sizeof trailer , 1);
if (trailer == fortio->active_header)
if (trailer == record_size)
is_fortio_file = true;
}
}
}
}
fortio_fseek(fortio , init_pos , SEEK_SET);
@@ -465,24 +452,25 @@ bool fortio_is_fortio_file(fortio_type * fortio) {
int fortio_init_read(fortio_type *fortio) {
int elm_read;
elm_read = fread(&fortio->active_header , sizeof(fortio->active_header) , 1 , fortio->stream);
int record_size;
elm_read = fread(&record_size , sizeof(record_size) , 1 , fortio->stream);
if (elm_read == 1) {
if (fortio->endian_flip_header)
util_endian_flip_vector(&fortio->active_header , sizeof fortio->active_header , 1);
util_endian_flip_vector(&record_size , sizeof record_size , 1);
fortio->rec_nr++;
return fortio->active_header;
} else
return record_size;
} else
return -1;
}
void fortio_data_fskip(fortio_type* fortio, const int element_size, const int element_count, const int block_count) {
int headers = block_count * 4;
int trailers = block_count * 4;
int bytes_to_skip = headers + trailers + (element_size * element_count);
bool fortio_data_fskip(fortio_type* fortio, const int element_size, const int element_count, const int block_count) {
int headers = block_count * 4;
int trailers = block_count * 4;
int bytes_to_skip = headers + trailers + (element_size * element_count);
fortio_fseek(fortio, bytes_to_skip, SEEK_CUR);
return fortio_fseek(fortio, bytes_to_skip, SEEK_CUR);
}
@@ -501,34 +489,40 @@ void fortio_data_fseek(fortio_type* fortio, offset_type data_offset, size_t data
}
void fortio_complete_read(fortio_type *fortio) {
bool fortio_complete_read(fortio_type *fortio , int record_size) {
int trailer;
trailer = util_fread_int( fortio->stream );
if (fortio->endian_flip_header)
util_endian_flip_vector(&trailer , sizeof trailer , 1);
if (trailer != fortio->active_header) {
fprintf(stderr,"%s: fatal error reading record:%d in file: %s - aborting \n",__func__ , fortio->rec_nr , fortio->filename);
util_abort("%s: Header: %d Trailer: %d \n",__func__ , fortio->active_header , trailer);
size_t read_count = fread(&trailer , sizeof trailer , 1 , fortio->stream );
if (read_count == 1) {
if (fortio->endian_flip_header)
util_endian_flip_vector(&trailer , sizeof trailer , 1);
if (record_size == trailer)
return true;
}
fortio->active_header = 0;
return false;
}
/**
This function reads one record from the fortio stream, and fills
the buffer with the content. The return value is the number of bytes read.
the buffer with the content. The return value is the number of
bytes read; the function will return -1 on failure.
*/
int fortio_fread_record(fortio_type *fortio, char *buffer) {
fortio_init_read(fortio);
{
int record_size = fortio->active_header; /* This is reset in fortio_complete_read - must store it for the return. */
util_fread(buffer , 1 , fortio->active_header , fortio->stream , __func__);
fortio_complete_read(fortio);
return record_size;
static int fortio_fread_record(fortio_type *fortio , char *buffer) {
int record_size = fortio_init_read(fortio);
if (record_size >= 0) {
size_t items_read = fread(buffer , 1 , record_size , fortio->stream);
if (items_read == record_size) {
bool complete_ok = fortio_complete_read(fortio , record_size);
if (!complete_ok)
record_size = -1;
} else
record_size = -1; /* Failure */
}
return record_size;
}
@@ -541,38 +535,53 @@ int fortio_fread_record(fortio_type *fortio, char *buffer) {
transparent, low-level way.
*/
void fortio_fread_buffer(fortio_type * fortio, char * buffer , int buffer_size) {
int bytes_read = 0;
while (bytes_read < buffer_size) {
char * buffer_ptr = &buffer[bytes_read];
bytes_read += fortio_fread_record(fortio , buffer_ptr);
bool fortio_fread_buffer(fortio_type * fortio, char * buffer , int buffer_size) {
int total_bytes_read = 0;
while (true) {
char * buffer_ptr = &buffer[total_bytes_read];
int bytes_read = fortio_fread_record(fortio , buffer_ptr);
if (bytes_read < 0)
break;
else {
total_bytes_read += bytes_read;
if (total_bytes_read >= buffer_size)
break;
}
}
if (bytes_read > buffer_size)
util_abort("%s: hmmmm - something is broken. The individual records in %s did not sum up to the expected buffer size \n",__func__ , fortio->filename);
if (total_bytes_read == buffer_size)
return true;
if (total_bytes_read < buffer_size)
return false;
util_abort("%s: internal inconsistency: buffer_size:%d read %d bytes \n",__func__ , buffer_size , total_bytes_read);
return false;
}
int fortio_fskip_record(fortio_type *fortio) {
int record_size = fortio_init_read(fortio);
fortio_fseek(fortio , (offset_type) record_size , SEEK_CUR);
fortio_complete_read(fortio);
fortio_complete_read(fortio , record_size);
return record_size;
}
void fortio_fskip_buffer(fortio_type * fortio, int buffer_size) {
int bytes_skipped = 0;
while (bytes_skipped < buffer_size)
while (bytes_skipped < buffer_size)
bytes_skipped += fortio_fskip_record(fortio);
if (bytes_skipped > buffer_size)
if (bytes_skipped > buffer_size)
util_abort("%s: hmmmm - something is broken. The individual records in %s did not sum up to the expected buffer size \n",__func__ , fortio->filename);
}
void fortio_copy_record(fortio_type * src_stream , fortio_type * target_stream , int buffer_size , void * buffer , bool *at_eof) {
int bytes_read;
int record_size = fortio_init_read(src_stream);
int record_size = fortio_init_read(src_stream);
fortio_init_write(target_stream , record_size);
bytes_read = 0;
@@ -585,12 +594,12 @@ void fortio_copy_record(fortio_type * src_stream , fortio_type * target_stream ,
util_fread(buffer , 1 , bytes , src_stream->stream , __func__);
util_fwrite(buffer , 1 , bytes , target_stream->stream , __func__);
bytes_read += bytes;
}
fortio_complete_read(src_stream);
fortio_complete_write(target_stream);
fortio_complete_read(src_stream , record_size);
fortio_complete_write(target_stream , record_size);
if (feof(src_stream->stream))
*at_eof = true;
@@ -603,38 +612,35 @@ void fortio_copy_record(fortio_type * src_stream , fortio_type * target_stream ,
void fortio_init_write(fortio_type *fortio , int record_size) {
int file_header;
fortio->active_header = record_size;
file_header = fortio->active_header;
file_header = record_size;
if (fortio->endian_flip_header)
util_endian_flip_vector(&file_header , sizeof file_header , 1);
util_fwrite_int( file_header , fortio->stream );
fortio->rec_nr++;
}
void fortio_complete_write(fortio_type *fortio) {
int file_header = fortio->active_header;
void fortio_complete_write(fortio_type *fortio , int record_size) {
int file_header = record_size;
if (fortio->endian_flip_header)
util_endian_flip_vector(&file_header , sizeof file_header , 1);
util_fwrite_int( file_header , fortio->stream );
fortio->active_header = 0;
}
void fortio_fwrite_record(fortio_type *fortio, const char *buffer , int record_size) {
fortio_init_write(fortio , record_size);
util_fwrite( buffer , 1 , record_size , fortio->stream , __func__);
fortio_complete_write(fortio);
fortio_complete_write(fortio , record_size);
}
void * fortio_fread_alloc_record(fortio_type * fortio) {
void * buffer;
fortio_init_read(fortio);
buffer = util_malloc(fortio->active_header );
util_fread(buffer , 1 , fortio->active_header , fortio->stream , __func__);
fortio_complete_read(fortio);
int record_size = fortio_init_read(fortio);
buffer = util_malloc( record_size );
util_fread(buffer , 1 , record_size , fortio->stream , __func__);
fortio_complete_read(fortio , record_size);
return buffer;
}
@@ -651,8 +657,8 @@ static fortio_status_type fortio_check_record( FILE * stream , bool endian_flip
else {
if (endian_flip)
util_endian_flip_vector(&header , sizeof header , 1);
if (util_fseek( stream , (offset_type) header , SEEK_CUR ) != 0)
if (util_fseek( stream , (offset_type) header , SEEK_CUR ) != 0)
/* The fseek() failed - i.e. the data section was not sufficiently long. */
status = FORTIO_MISSING_DATA;
else {
@@ -660,14 +666,14 @@ static fortio_status_type fortio_check_record( FILE * stream , bool endian_flip
if (read_count == 1) {
if (endian_flip)
util_endian_flip_vector(&tail , sizeof tail , 1);
if (tail == header)
/* All OK */
status = FORTIO_OK;
else if ( tail != header )
else if ( tail != header )
/* The numerical value of the tail did not agree with the header. */
status = FORTIO_HEADER_MISMATCH;
} else
} else
/* The file ended before we could read the tail mark. */
status = FORTIO_MISSING_TAIL;
}
@@ -698,7 +704,7 @@ fortio_status_type fortio_check_buffer( FILE * stream , bool endian_flip , size_
return record_status;
}
fortio_status_type fortio_check_file( const char * filename , bool endian_flip) {
if (util_file_exists( filename )) {
@@ -730,12 +736,52 @@ offset_type fortio_ftell( const fortio_type * fortio ) {
}
int fortio_fseek( fortio_type * fortio , offset_type offset , int whence) {
static bool fortio_fseek__(fortio_type * fortio , offset_type offset , int whence) {
int fseek_return = util_fseek( fortio->stream , offset , whence );
/*
if fseek_return != 0 -> util_abort().
*/
return fseek_return;
if (fseek_return == 0)
return true;
else
return false;
}
/*
The semantics of this function depends on the readbale flag of the
fortio structure:
readable == false: Ordinary fseek() semantics.
readable == true: The function will only seek within the range of
the file, and fail if you try to seek beyond the EOF marker.
*/
bool fortio_fseek( fortio_type * fortio , offset_type offset , int whence) {
if (!fortio->readable)
return fortio_fseek__( fortio , offset , whence );
else {
offset_type new_offset = 0;
switch (whence) {
case( SEEK_CUR ):
new_offset = fortio_ftell( fortio ) + offset;
break;
case (SEEK_END):
new_offset = fortio->read_size + offset;
break;
case (SEEK_SET):
new_offset = offset;
break;
default:
util_abort("%s: invalid seek flag \n",__func__);
}
if (new_offset <= fortio->read_size)
return fortio_fseek__( fortio , new_offset , SEEK_SET );
else
return false;
}
}
@@ -744,11 +790,25 @@ int fortio_fileno( fortio_type * fortio ) {
}
/*
It is massively undefined behaviour to call this function for a file
which has been updated; in that case the util_fd_size() function
will return the size of the file *when it was opened*.
*/
bool fortio_read_at_eof( fortio_type * fortio ) {
if (fortio_ftell(fortio) == fortio->read_size)
return true;
else
return false;
}
/*****************************************************************/
void fortio_fflush(fortio_type * fortio) { fflush( fortio->stream); }
FILE * fortio_get_FILE(const fortio_type *fortio) { return fortio->stream; }
int fortio_get_record_size(const fortio_type *fortio) { return fortio->active_header; }
//bool fortio_endian_flip(const fortio_type *fortio) { return fortio->endian_flip_header; }
bool fortio_fmt_file(const fortio_type *fortio) { return fortio->fmt_file; }
void fortio_rewind(const fortio_type *fortio) { util_rewind(fortio->stream); }
+7 -7
View File
@@ -447,8 +447,8 @@ static void smspec_node_set_gen_keys( smspec_node_type * smspec_node , const cha
switch( smspec_node->var_type) {
case(ECL_SMSPEC_COMPLETION_VAR):
// KEYWORD:WGNAME:NUM
smspec_node->gen_key1 = smspec_alloc_completion_num_key( key_join_string , smspec_node->keyword , smspec_node->wgname , smspec_node->num);
smspec_node->gen_key2 = smspec_alloc_completion_ijk_key( key_join_string , smspec_node->keyword , smspec_node->wgname , smspec_node->ijk[0], smspec_node->ijk[1], smspec_node->ijk[2]);
smspec_node->gen_key1 = smspec_alloc_completion_ijk_key( key_join_string , smspec_node->keyword , smspec_node->wgname , smspec_node->ijk[0], smspec_node->ijk[1], smspec_node->ijk[2]);
smspec_node->gen_key2 = smspec_alloc_completion_num_key( key_join_string , smspec_node->keyword , smspec_node->wgname , smspec_node->num);
break;
case(ECL_SMSPEC_FIELD_VAR):
// KEYWORD
@@ -472,12 +472,12 @@ static void smspec_node_set_gen_keys( smspec_node_type * smspec_node , const cha
break;
case(ECL_SMSPEC_REGION_2_REGION_VAR):
// KEYWORDS:RXF:NUM and RXF:R1-R2
smspec_node->gen_key1 = smspec_alloc_region_2_region_num_key( key_join_string , smspec_node->keyword , smspec_node->num);
{
int r1 = smspec_node->num % 32768;
int r2 = ((smspec_node->num-r1) / 32768)-10;
smspec_node->gen_key2 = smspec_alloc_region_2_region_r1r2_key( key_join_string , smspec_node->keyword , r1, r2);
smspec_node->gen_key1 = smspec_alloc_region_2_region_r1r2_key( key_join_string , smspec_node->keyword , r1, r2);
}
smspec_node->gen_key2 = smspec_alloc_region_2_region_num_key( key_join_string , smspec_node->keyword , smspec_node->num);
break;
case(ECL_SMSPEC_MISC_VAR):
// KEYWORD
@@ -486,8 +486,8 @@ static void smspec_node_set_gen_keys( smspec_node_type * smspec_node , const cha
break;
case(ECL_SMSPEC_BLOCK_VAR):
// KEYWORD:NUM
smspec_node->gen_key1 = smspec_alloc_block_num_key( key_join_string , smspec_node->keyword , smspec_node->num);
smspec_node->gen_key2 = smspec_alloc_block_ijk_key( key_join_string , smspec_node->keyword , smspec_node->ijk[0], smspec_node->ijk[1], smspec_node->ijk[2]);
smspec_node->gen_key1 = smspec_alloc_block_ijk_key( key_join_string , smspec_node->keyword , smspec_node->ijk[0], smspec_node->ijk[1], smspec_node->ijk[2]);
smspec_node->gen_key2 = smspec_alloc_block_num_key( key_join_string , smspec_node->keyword , smspec_node->num);
break;
case(ECL_SMSPEC_LOCAL_WELL_VAR):
/** KEYWORD:LGR:WGNAME */
@@ -733,7 +733,7 @@ smspec_node_type * smspec_node_alloc_lgr( ecl_smspec_var_type var_type ,
int param_index , float default_value) {
smspec_node_type * smspec_node = smspec_node_alloc_new( param_index , default_value );
if (smspec_node_init_lgr( smspec_node , var_type , wgname , keyword , lgr , unit , key_join_string , lgr_i, lgr_j , lgr_k))
if (smspec_node_init_lgr( smspec_node , var_type , wgname , keyword , unit , lgr , key_join_string , lgr_i, lgr_j , lgr_k))
return smspec_node;
else {
smspec_node_free( smspec_node );

Some files were not shown because too many files have changed in this diff Show More