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

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

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 )

View File

@@ -0,0 +1,10 @@
#include <signal.h>
void sigbus_handler(int signal) {
}
int main(int argc, char ** argv) {
signal(SIGBUS , sigbus_handler);
}

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 )

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

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

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 )

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

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/)

View File

@@ -0,0 +1,4 @@
Low level C libraries
=====================
How to use the C libraries

View File

@@ -0,0 +1,11 @@
Documentation of ert code
=========================
Contents:
.. toctree::
:maxdepth: 1
python/index
C/index

View File

@@ -0,0 +1,9 @@
The ert Python API
==================
.. toctree::
:maxdepth: 2
../../API/python/ert
../../API/python/ert_gui

View File

@@ -0,0 +1,5 @@
Using the ert.ecl classes for Eclipse manipulation
==================================================
Using the ert.ecl classes for ECLIPSE binary files

View File

@@ -0,0 +1,10 @@
Python documentation
====================
.. toctree::
:maxdepth: 1
introduction/index
eclipse/index
../../API/python/ert
../../API/python/ert_gui

View File

@@ -0,0 +1,4 @@
Simple introduction to Python
=============================
An introduction to Python

View File

@@ -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

View File

@@ -0,0 +1,11 @@
User documentation for ERT
==========================
Contents:
.. toctree::
:maxdepth: 1
tutorial/index
keywords/index
observations/index

View File

@@ -0,0 +1,7 @@
Keywords available in the ERT configuration
===========================================
.. toctree::
:maxdepth: 1
Here comes keywords ...

View File

@@ -0,0 +1,4 @@
Configuring observations for ERT
================================
Adding observations ...

View File

@@ -0,0 +1,3 @@
ERT Tutorial
============
Tutorial for ert.

View File

@@ -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 )

View File

@@ -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;
@@ -52,17 +54,7 @@ typedef struct rml_enkf_data_struct rml_enkf_data_type;
you have repeated calls to both of these functions the end result
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
@@ -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;
matrix_type *global_prior; // m_pr
matrix_type *previous_state; // m_l
bool clear_log;
char * log_file;
FILE * log_stream;
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 bool has_printed_header = false;
static int has_printed_header = 0;
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");
}
}
@@ -300,36 +193,27 @@ 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;
data->config = rml_enkf_config_alloc();
data->rml_log = rml_enkf_log_alloc();
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->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->previous_state = matrix_alloc(1,1);
data->global_prior = NULL;
data->ens_mask = NULL;
return data;
}
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,27 +256,29 @@ 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?
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 state_size = matrix_get_rows( data->prior );
int ens_size = matrix_get_columns( data->prior );
for (int row=0; row < state_size; row++) {
double sumrow = matrix_get_row_sum(prior , row);
double tmp = sumrow / ens_size;
for (int row=0; row < state_size; row++) {
double sumrow = matrix_get_row_sum(data->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,7 +332,7 @@ 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 );
}
@@ -463,8 +355,8 @@ static void rml_enkf_initA__(rml_enkf_data_type * data, matrix_type * A, matrix_
// 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);
@@ -490,12 +382,12 @@ void rml_enkf_init2__( rml_enkf_data_type * data, matrix_type *A, double * Wdr,
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:
@@ -521,8 +413,10 @@ void rml_enkf_init2__( rml_enkf_data_type * data, matrix_type *A, double * Wdr,
// 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);
}
@@ -571,25 +465,31 @@ static void rml_enkf_updateA_iter0(rml_enkf_data_type * data, matrix_type * A, m
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;
{
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, prior = A
rml_enkf_common_store_state( data->state , A , data->ens_mask );
rml_enkf_common_recover_state( A , data->prior , data->ens_mask );
// 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.
@@ -621,7 +521,7 @@ void rml_enkf_updateA(void * module_data, matrix_type * A, matrix_type * S, matr
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,7 +541,7 @@ 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.
@@ -655,8 +555,7 @@ void rml_enkf_updateA(void * module_data, matrix_type * A, matrix_type * S, matr
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) {
/*
@@ -665,25 +564,26 @@ void rml_enkf_updateA(void * module_data, matrix_type * A, matrix_type * S, matr
// Reduce Lambda
if (std_reduced)
data->lambda = data->lambda * data->lambda_reduce_factor;
data->lambda = data->lambda * rml_enkf_config_get_lambda_decrease_factor( data->config );
rml_enkf_common_store_state(data->state , A , data->ens_mask );
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);
}
@@ -695,21 +595,26 @@ void rml_enkf_updateA(void * module_data, matrix_type * A, matrix_type * S, matr
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
//**********************************************
@@ -726,7 +632,7 @@ bool rml_enkf_set_int( void * arg , const char * var_name , int value) {
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
@@ -752,11 +658,11 @@ bool rml_enkf_set_bool( void * arg , const char * var_name , bool value) {
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;
return rml_enkf_config_get_use_prior( module_data->config );
else if (strcmp(var_name , CLEAR_LOG_KEY) == 0)
return module_data->clear_log;
return rml_enkf_log_get_clear_log( module_data->rml_log );
else if (strcmp(var_name , LAMBDA_RECALCULATE_KEY) == 0)
return module_data->lambda_recalculate;
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;
}
}
@@ -825,7 +735,7 @@ bool rml_enkf_set_string( void * arg , const char * var_name , const char * valu
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;
}

View File

@@ -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 );
}

View File

@@ -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

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 );
}
}

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

View File

@@ -121,11 +121,15 @@ int enkf_linalg_svd_truncation(const matrix_type * S ,
}
}
}
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
util_abort("%s: truncation:%g ncomp:%d - invalid ambigous input.\n",__func__ , truncation , ncomp );
return num_significant;
}

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);

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

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 )

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

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 );
}

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 ) {

View File

@@ -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);

View File

@@ -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 );
}

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;
}

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"

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 )

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");
}
config_content_free( content );
}
test_assert_false( config_parse( config , "DoesNotExist" , "--" , NULL , NULL , false , true));
{
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);
}

View File

@@ -24,7 +24,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_schema_item.h>
#include <ert/config/config_error.h>
@@ -44,37 +44,47 @@ int main(int argc , char ** argv) {
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.";
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 ));
test_assert_int_equal( config_error_count( config_error ) , 1);
test_assert_string_equal( config_error_iget( config_error , 0 ) , error_msg);
{
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_clear( config );
{
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);
}
}

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);

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();
}

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,27 +31,26 @@
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 ));
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_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_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_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" ));
config_content_free( content );
}
exit(0);
}

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();
util_install_signals();
{
const char * config_file = argv[1];
config_parser_type * config = config_create_schema();
test_define( config , config_file );
test_define( config , config_file );
config_free( config );
exit(0);
config_free( config );
exit(0);
}
}

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,8 +53,8 @@ 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);
@@ -67,23 +68,24 @@ void parse_test(config_type * config ,
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_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_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_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;

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 );
config_content_type * content = 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 );
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");
@@ -50,6 +51,7 @@ int main(int argc , char ** argv) {
} else printf("Size error \n");
} else printf("Parse error");
config_content_free( content );
exit(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>

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>

View File

@@ -1,7 +1,7 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_typeFail.c' is part of ERT - Ensemble based Reservoir Tool.
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
@@ -18,8 +18,11 @@
#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,8 +33,7 @@ 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 );
@@ -45,21 +47,23 @@ int main(int argc , char ** argv) {
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);

View File

@@ -1,7 +1,7 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'config_typeOK.c' is part of ERT - Ensemble based Reservoir Tool.
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
@@ -18,19 +18,16 @@
#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 );
@@ -44,11 +41,12 @@ int main(int argc , char ** argv) {
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 );
{
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 );
}
if (OK) {
} else error("Parse error\n");
exit(0);
}

View File

@@ -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 )

View File

@@ -46,19 +46,23 @@ void file_convert(const char * src_file , const char * target_file, ecl_file_enu
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);
}

View File

@@ -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>
@@ -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,12 +226,11 @@ 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);
}
@@ -247,8 +248,8 @@ void ensemble_init( ensemble_type * ensemble , config_type * config) {
}
/*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 */
@@ -354,10 +355,10 @@ 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 );
@@ -717,16 +718,16 @@ 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 });
}
@@ -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,16 +840,17 @@ 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 );

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) {

View File

@@ -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);

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

View File

@@ -36,13 +36,12 @@ 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_header(const ecl_kw_type * ecl_kw );
@@ -104,14 +103,14 @@ 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 );

View File

@@ -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. */

View File

@@ -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,7 +43,7 @@ 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 );

View File

@@ -26,6 +26,8 @@ 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;
@@ -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
}

View File

@@ -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
}

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

View File

@@ -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
}

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 );

View File

@@ -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 ;
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);
@@ -85,6 +86,7 @@ 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
}

View File

@@ -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

View File

@@ -75,11 +75,10 @@ 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
/*****************************************************************/
/*
@@ -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
@@ -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
}

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 );

View File

@@ -18,6 +18,7 @@ set( source_files
ecl_util.c
ecl_kw.c
ecl_sum.c
ecl_sum_vector.c
fortio.c
ecl_rft_file.c
ecl_rft_node.c
@@ -58,6 +59,7 @@ set( header_files
ecl_util.h
ecl_kw.h
ecl_sum.h
ecl_sum_vector.h
fortio.h
ecl_rft_file.h
ecl_rft_node.h

View File

@@ -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);
}
}
@@ -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;
}
@@ -872,7 +886,7 @@ void ecl_file_select_global( ecl_file_type * ecl_file ) {
*/
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;
@@ -890,32 +904,22 @@ static ecl_file_type * ecl_file_open__( const char * filename , int flags) {
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 );
if (FILE_FLAGS_SET( ecl_file->flags , ECL_FILE_CLOSE_STREAM))
fortio_fclose_stream( ecl_file->fortio );
return ecl_file;
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 );
}

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 );
}

View File

@@ -2410,30 +2410,33 @@ static ecl_grid_type * ecl_grid_alloc_EGRID(const char * grid_file) {
util_abort("%s: %s wrong file type - expected .EGRID file - aborting \n",__func__ , grid_file);
{
ecl_file_type * ecl_file = ecl_file_open( grid_file , 0);
int num_grid = ecl_file_get_num_named_kw( ecl_file , GRIDHEAD_KW );
ecl_grid_type * main_grid = ecl_grid_alloc_EGRID__( NULL , ecl_file , 0 );
int grid_nr;
if (ecl_file) {
int num_grid = ecl_file_get_num_named_kw( ecl_file , GRIDHEAD_KW );
ecl_grid_type * main_grid = ecl_grid_alloc_EGRID__( NULL , ecl_file , 0 );
int grid_nr;
for ( grid_nr = 1; grid_nr < num_grid; grid_nr++) {
ecl_grid_type * lgr_grid = ecl_grid_alloc_EGRID__( main_grid , ecl_file , grid_nr );
ecl_grid_add_lgr( main_grid , lgr_grid );
{
ecl_grid_type * host_grid;
ecl_kw_type * hostnum_kw = ecl_file_iget_named_kw( ecl_file , HOSTNUM_KW , grid_nr - 1);
if (lgr_grid->parent_name == NULL)
host_grid = main_grid;
else
host_grid = ecl_grid_get_lgr( main_grid , lgr_grid->parent_name );
for ( grid_nr = 1; grid_nr < num_grid; grid_nr++) {
ecl_grid_type * lgr_grid = ecl_grid_alloc_EGRID__( main_grid , ecl_file , grid_nr );
ecl_grid_add_lgr( main_grid , lgr_grid );
{
ecl_grid_type * host_grid;
ecl_kw_type * hostnum_kw = ecl_file_iget_named_kw( ecl_file , HOSTNUM_KW , grid_nr - 1);
if (lgr_grid->parent_name == NULL)
host_grid = main_grid;
else
host_grid = ecl_grid_get_lgr( main_grid , lgr_grid->parent_name );
ecl_grid_install_lgr_EGRID( host_grid , lgr_grid , ecl_kw_get_int_ptr( hostnum_kw) );
ecl_grid_install_lgr_EGRID( host_grid , lgr_grid , ecl_kw_get_int_ptr( hostnum_kw) );
}
}
}
main_grid->name = util_alloc_string_copy( grid_file );
ecl_grid_init_nnc(main_grid, ecl_file);
ecl_grid_init_nnc_amalgamated(main_grid, ecl_file);
main_grid->name = util_alloc_string_copy( grid_file );
ecl_grid_init_nnc(main_grid, ecl_file);
ecl_grid_init_nnc_amalgamated(main_grid, ecl_file);
ecl_file_close( ecl_file );
return main_grid;
ecl_file_close( ecl_file );
return main_grid;
} else
return NULL;
}
}

View File

@@ -33,6 +33,10 @@
#define ECL_KW_TYPE_ID 6111098
struct ecl_kw_struct {
UTIL_TYPE_ID_DECLARATION;
int size;
@@ -509,11 +513,12 @@ static size_t ecl_kw_fortio_data_size( const ecl_kw_type * ecl_kw) {
/**
Returns the number of bytes this ecl_kw instance would occupy in
BINARY file.
BINARY file; we add 2*4 to the header size to include the size of
the fortran header and trailer combo.
*/
size_t ecl_kw_fortio_size( const ecl_kw_type * ecl_kw ) {
size_t size = ECL_KW_FORTIO_HEADER_SIZE;
size_t size = ECL_KW_HEADER_FORTIO_SIZE;
size += ecl_kw_fortio_data_size(ecl_kw );
return size;
}
@@ -1054,107 +1059,118 @@ static double __fscanf_ECL_double( FILE * stream , const char * fmt) {
return value;
}
void ecl_kw_fread_data(ecl_kw_type *ecl_kw, fortio_type *fortio) {
{
const char null_char = '\0';
bool fmt_file = fortio_fmt_file( fortio );
if (ecl_kw->size > 0) {
const int blocksize = get_blocksize( ecl_kw->ecl_type );
if (fmt_file) {
const int blocks = ecl_kw->size / blocksize + (ecl_kw->size % blocksize == 0 ? 0 : 1);
const char * read_fmt = get_read_fmt( ecl_kw->ecl_type );
FILE * stream = fortio_get_FILE(fortio);
int offset = 0;
int index = 0;
int ib,ir;
for (ib = 0; ib < blocks; ib++) {
int read_elm = util_int_min((ib + 1) * blocksize , ecl_kw->size) - ib * blocksize;
for (ir = 0; ir < read_elm; ir++) {
switch(ecl_kw->ecl_type) {
case(ECL_CHAR_TYPE):
ecl_kw_fscanf_qstring(&ecl_kw->data[offset] , read_fmt , 8, stream);
break;
case(ECL_INT_TYPE):
{
int iread = fscanf(stream , read_fmt , (int *) &ecl_kw->data[offset]);
if (iread != 1)
util_abort("%s: after reading %d values reading of keyword:%s from:%s failed - aborting \n",__func__ , offset / ecl_kw->sizeof_ctype , ecl_kw->header8 , fortio_filename_ref(fortio));
}
break;
case(ECL_FLOAT_TYPE):
{
int iread = fscanf(stream , read_fmt , (float *) &ecl_kw->data[offset]);
if (iread != 1) {
util_abort("%s: after reading %d values reading of keyword:%s from:%s failed - aborting \n",__func__ ,
offset / ecl_kw->sizeof_ctype ,
ecl_kw->header8 ,
fortio_filename_ref(fortio));
}
}
break;
case(ECL_DOUBLE_TYPE):
{
double value = __fscanf_ECL_double( stream , read_fmt );
ecl_kw_iset(ecl_kw , index , &value);
}
break;
case(ECL_BOOL_TYPE):
{
char bool_char;
if (fscanf(stream , read_fmt , &bool_char) == 1) {
if (bool_char == BOOL_TRUE_CHAR)
ecl_kw_iset_bool(ecl_kw , index , true);
else if (bool_char == BOOL_FALSE_CHAR)
ecl_kw_iset_bool(ecl_kw , index , false);
else
util_abort("%s: Logical value: [%c] not recogniced - aborting \n", __func__ , bool_char);
} else
util_abort("%s: read failed - premature file end? \n",__func__ );
}
break;
case(ECL_MESS_TYPE):
ecl_kw_fscanf_qstring(&ecl_kw->data[offset] , read_fmt , 8 , stream);
break;
default:
util_abort("%s: Internal error: internal eclipse_type: %d not recognized - aborting \n",__func__ , ecl_kw->ecl_type);
bool ecl_kw_fread_data(ecl_kw_type *ecl_kw, fortio_type *fortio) {
const char null_char = '\0';
bool fmt_file = fortio_fmt_file( fortio );
if (ecl_kw->size > 0) {
const int blocksize = get_blocksize( ecl_kw->ecl_type );
if (fmt_file) {
const int blocks = ecl_kw->size / blocksize + (ecl_kw->size % blocksize == 0 ? 0 : 1);
const char * read_fmt = get_read_fmt( ecl_kw->ecl_type );
FILE * stream = fortio_get_FILE(fortio);
int offset = 0;
int index = 0;
int ib,ir;
for (ib = 0; ib < blocks; ib++) {
int read_elm = util_int_min((ib + 1) * blocksize , ecl_kw->size) - ib * blocksize;
for (ir = 0; ir < read_elm; ir++) {
switch(ecl_kw->ecl_type) {
case(ECL_CHAR_TYPE):
ecl_kw_fscanf_qstring(&ecl_kw->data[offset] , read_fmt , 8, stream);
break;
case(ECL_INT_TYPE):
{
int iread = fscanf(stream , read_fmt , (int *) &ecl_kw->data[offset]);
if (iread != 1)
util_abort("%s: after reading %d values reading of keyword:%s from:%s failed - aborting \n",__func__ , offset / ecl_kw->sizeof_ctype , ecl_kw->header8 , fortio_filename_ref(fortio));
}
offset += ecl_kw->sizeof_ctype;
index++;
break;
case(ECL_FLOAT_TYPE):
{
int iread = fscanf(stream , read_fmt , (float *) &ecl_kw->data[offset]);
if (iread != 1) {
util_abort("%s: after reading %d values reading of keyword:%s from:%s failed - aborting \n",__func__ ,
offset / ecl_kw->sizeof_ctype ,
ecl_kw->header8 ,
fortio_filename_ref(fortio));
}
}
break;
case(ECL_DOUBLE_TYPE):
{
double value = __fscanf_ECL_double( stream , read_fmt );
ecl_kw_iset(ecl_kw , index , &value);
}
break;
case(ECL_BOOL_TYPE):
{
char bool_char;
if (fscanf(stream , read_fmt , &bool_char) == 1) {
if (bool_char == BOOL_TRUE_CHAR)
ecl_kw_iset_bool(ecl_kw , index , true);
else if (bool_char == BOOL_FALSE_CHAR)
ecl_kw_iset_bool(ecl_kw , index , false);
else
util_abort("%s: Logical value: [%c] not recogniced - aborting \n", __func__ , bool_char);
} else
util_abort("%s: read failed - premature file end? \n",__func__ );
}
break;
case(ECL_MESS_TYPE):
ecl_kw_fscanf_qstring(&ecl_kw->data[offset] , read_fmt , 8 , stream);
break;
default:
util_abort("%s: Internal error: internal eclipse_type: %d not recognized - aborting \n",__func__ , ecl_kw->ecl_type);
}
offset += ecl_kw->sizeof_ctype;
index++;
}
} else {
if (ecl_kw->ecl_type == ECL_CHAR_TYPE || ecl_kw->ecl_type == ECL_MESS_TYPE) {
const int blocks = ecl_kw->size / blocksize + (ecl_kw->size % blocksize == 0 ? 0 : 1);
int ib;
for (ib = 0; ib < blocks; ib++) {
/*
Due to the necessary terminating \0 characters there is
not a continous file/memory mapping.
*/
int read_elm = util_int_min((ib + 1) * blocksize , ecl_kw->size) - ib * blocksize;
FILE * stream = fortio_get_FILE(fortio);
}
return true;
} else {
bool read_ok = true;
if (ecl_kw->ecl_type == ECL_CHAR_TYPE || ecl_kw->ecl_type == ECL_MESS_TYPE) {
const int blocks = ecl_kw->size / blocksize + (ecl_kw->size % blocksize == 0 ? 0 : 1);
int ib = 0;
while (true) {
/*
Due to the necessary terminating \0 characters there is
not a continous file/memory mapping.
*/
int read_elm = util_int_min((ib + 1) * blocksize , ecl_kw->size) - ib * blocksize;
FILE * stream = fortio_get_FILE(fortio);
int record_size = fortio_init_read(fortio);
if (record_size >= 0) {
int ir;
fortio_init_read(fortio);
for (ir = 0; ir < read_elm; ir++) {
util_fread( &ecl_kw->data[(ib * blocksize + ir) * ecl_kw->sizeof_ctype] , 1 , ECL_STRING_LENGTH , stream , __func__);
ecl_kw->data[(ib * blocksize + ir) * ecl_kw->sizeof_ctype + ECL_STRING_LENGTH] = null_char;
}
read_ok = fortio_complete_read(fortio , record_size);
} else
read_ok = false;
fortio_complete_read(fortio);
}
} else
/**
This function handles the fuc***g blocks transparently at a
low level.
*/
fortio_fread_buffer(fortio , ecl_kw->data , ecl_kw->size * ecl_kw->sizeof_ctype);
if (!read_ok)
break;
if (ECL_ENDIAN_FLIP)
ib++;
if (ib == blocks)
break;
}
} else {
/**
This function handles the fuc***g blocks transparently at a
low level.
*/
read_ok = fortio_fread_buffer(fortio , ecl_kw->data , ecl_kw->size * ecl_kw->sizeof_ctype);
if (read_ok && ECL_ENDIAN_FLIP)
ecl_kw_endian_convert_data(ecl_kw);
}
return read_ok;
}
}
} else
/* The keyword has zero size - and reading data is trivially OK. */
return true;
}
@@ -1187,17 +1203,18 @@ void ecl_kw_fread_indexed_data(fortio_type * fortio, offset_type data_offset, ec
/**
Allocates storage and reads data.
*/
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_kw_alloc_data(ecl_kw);
ecl_kw_fread_data(ecl_kw , fortio);
return ecl_kw_fread_data(ecl_kw , fortio);
}
/**
Static method without a class instance.
*/
void ecl_kw_fskip_data__( ecl_type_enum ecl_type , const int element_count , fortio_type * fortio) {
bool ecl_kw_fskip_data__( ecl_type_enum ecl_type , const int element_count , fortio_type * fortio) {
bool fmt_file = fortio_fmt_file(fortio);
bool skip_ok = true;
if (element_count > 0) {
if (fmt_file) {
/* Formatted skipping actually involves reading the data - nice ??? */
@@ -1215,14 +1232,15 @@ void ecl_kw_fskip_data__( ecl_type_enum ecl_type , const int element_count , for
element_size = ECL_STRING_LENGTH;
}
fortio_data_fskip(fortio, element_size, element_count, block_count);
skip_ok = fortio_data_fskip(fortio, element_size, element_count, block_count);
}
}
return skip_ok;
}
void ecl_kw_fskip_data(ecl_kw_type *ecl_kw, fortio_type *fortio) {
ecl_kw_fskip_data__( ecl_kw->ecl_type , ecl_kw->size , fortio );
bool ecl_kw_fskip_data(ecl_kw_type *ecl_kw, fortio_type *fortio) {
return ecl_kw_fskip_data__( ecl_kw->ecl_type , ecl_kw->size , fortio );
}
@@ -1254,7 +1272,7 @@ bool ecl_kw_fread_header(ecl_kw_type *ecl_kw , fortio_type * fortio) {
char ecl_type_str[ECL_TYPE_LENGTH + 1];
int record_size;
int size;
bool OK;
bool OK = true;
if (fmt_file) {
OK = ecl_kw_fscanf_qstring(header , "%8c" , 8 , stream);
@@ -1271,13 +1289,19 @@ bool ecl_kw_fread_header(ecl_kw_type *ecl_kw , fortio_type * fortio) {
ecl_type_str[ECL_TYPE_LENGTH] = null_char;
record_size = fortio_init_read(fortio);
if (record_size > 0) {
util_fread(header , sizeof(char) , ECL_STRING_LENGTH , stream , __func__);
util_fread(&size , sizeof(size) , 1 , stream , __func__);
util_fread(ecl_type_str , sizeof(char) , ECL_TYPE_LENGTH , stream , __func__);
fortio_complete_read(fortio);
char buffer[ECL_KW_HEADER_DATA_SIZE];
size_t read_bytes = fread(buffer , 1 , ECL_KW_HEADER_DATA_SIZE , stream);
OK = true;
if (ECL_ENDIAN_FLIP)
if (read_bytes == ECL_KW_HEADER_DATA_SIZE) {
memcpy( header , &buffer[0] , ECL_STRING_LENGTH);
size = *( (int *) &buffer[ECL_STRING_LENGTH] );
memcpy( ecl_type_str , &buffer[ECL_STRING_LENGTH + sizeof(size)] , ECL_TYPE_LENGTH);
OK = fortio_complete_read(fortio , record_size);
} else
OK = false;
if (OK && ECL_ENDIAN_FLIP)
util_endian_flip_vector(&size , sizeof size , 1);
} else
OK = false;
@@ -1434,12 +1458,11 @@ void ecl_kw_set_header_alloc(ecl_kw_type *ecl_kw , const char *header , int siz
bool ecl_kw_fread_realloc(ecl_kw_type *ecl_kw , fortio_type *fortio) {
bool OK;
OK = ecl_kw_fread_header(ecl_kw , fortio);
bool OK = ecl_kw_fread_header(ecl_kw , fortio);
if (OK)
ecl_kw_fread_realloc_data( ecl_kw , fortio );
return OK;
return ecl_kw_fread_realloc_data( ecl_kw , fortio );
else
return false;
}
@@ -1459,7 +1482,6 @@ ecl_kw_type *ecl_kw_fread_alloc(fortio_type *fortio) {
bool OK;
ecl_kw_type *ecl_kw = ecl_kw_alloc_empty();
OK = ecl_kw_fread_realloc(ecl_kw , fortio);
if (!OK) {
free(ecl_kw);
ecl_kw = NULL;
@@ -1502,7 +1524,7 @@ static void ecl_kw_fwrite_data_unformatted( ecl_kw_type * ecl_kw , fortio_type *
fortio_init_write(fortio , record_size );
for (i = 0; i < this_blocksize; i++)
fwrite(&ecl_kw->data[(block_nr * blocksize + i) * ecl_kw->sizeof_ctype] , 1 , ECL_STRING_LENGTH , stream);
fortio_complete_write(fortio);
fortio_complete_write(fortio , record_size);
} else {
int record_size = this_blocksize * ecl_kw->sizeof_ctype; /* The total size in bytes of the record written by the fortio layer. */
fortio_fwrite_record(fortio , &ecl_kw->data[block_nr * blocksize * ecl_kw->sizeof_ctype] , record_size);
@@ -1638,13 +1660,14 @@ void ecl_kw_fwrite_header(const ecl_kw_type *ecl_kw , fortio_type *fortio) {
if (ECL_ENDIAN_FLIP)
util_endian_flip_vector(&size , sizeof size , 1);
fortio_init_write(fortio , ECL_STRING_LENGTH + sizeof(int) + ECL_TYPE_LENGTH);
fortio_init_write(fortio , ECL_KW_HEADER_DATA_SIZE );
fwrite(ecl_kw->header8 , sizeof(char) , ECL_STRING_LENGTH , stream);
fwrite(&size , sizeof(int) , 1 , stream);
fwrite(ecl_util_get_type_name( ecl_kw->ecl_type ) , sizeof(char) , ECL_TYPE_LENGTH , stream);
fortio_complete_write(fortio);
fortio_complete_write(fortio , ECL_KW_HEADER_DATA_SIZE);
}
}
@@ -2424,15 +2447,14 @@ void ecl_kw_inplace_update_file(const ecl_kw_type * ecl_kw , const char * filena
/******************************************************************/
bool ecl_kw_is_kw_file(FILE * stream , bool fmt_file ) {
const long int init_pos = util_ftell(stream);
bool ecl_kw_is_kw_file(fortio_type * fortio) {
const long int init_pos = fortio_ftell( fortio );
bool kw_file;
{
ecl_kw_type * ecl_kw = ecl_kw_alloc_empty();
fortio_type * fortio = fortio_alloc_FILE_wrapper(NULL , ECL_ENDIAN_FLIP , fmt_file , stream);
if (fmt_file)
if (fortio_fmt_file( fortio ))
kw_file = ecl_kw_fread_header(ecl_kw , fortio);
else {
if (fortio_is_fortio_file(fortio))
@@ -2441,11 +2463,10 @@ bool ecl_kw_is_kw_file(FILE * stream , bool fmt_file ) {
kw_file = false;
}
fortio_free_FILE_wrapper(fortio);
ecl_kw_free(ecl_kw);
}
util_fseek(stream , init_pos , SEEK_SET);
fortio_fseek(fortio , init_pos , SEEK_SET);
return kw_file;
}

View File

@@ -648,7 +648,7 @@ void ecl_kw_fprintf_grdecl__(const ecl_kw_type * ecl_kw , const char * special_h
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 );
}

View File

@@ -33,10 +33,11 @@ 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)
@@ -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;
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;
}
@@ -166,43 +176,43 @@ 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;
bool correct_lgrheadi = false;
int head_index = 0;
int steps = 0;
if (strcmp(kw , TRANNNC_KW) == 0)
tran_kw_forward_skip = 3;
else
tran_kw_forward_skip = 4;
while (!finished) {
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;

View 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);
}
@@ -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);
}

View File

@@ -34,6 +34,7 @@
#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
@@ -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) {
@@ -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;
}
@@ -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;
}

View File

@@ -35,6 +35,7 @@
#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;
@@ -43,6 +44,7 @@ struct ecl_rst_file_struct {
};
static ecl_rst_file_type * ecl_rst_file_alloc( const char * filename ) {
bool unified = ecl_util_unified_file( filename );
bool fmt_file;
@@ -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 );
}

View File

@@ -417,10 +417,12 @@ bool ecl_file_select_rstblock_report_step( ecl_file_type * ecl_file , int report
/******************************************************************/
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;
}

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);

View File

@@ -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;
}

View File

@@ -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};
/*****************************************************************/
@@ -939,15 +954,17 @@ static void ecl_smspec_load_restart( ecl_smspec_type * ecl_smspec , const ecl_fi
*/
if (!stringlist_contains( ecl_smspec->restart_list , restart_base)) {
ecl_file_type * restart_header = ecl_file_open( smspec_header , 0);
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));
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 */
ecl_file_close( restart_header );
} 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 );
fprintf(stderr,"** Warning: failed to historical case:%s - ignored.\n", smspec_header);
}
}
}
@@ -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);
@@ -1110,12 +1140,16 @@ static void ecl_smspec_fread_header(ecl_smspec_type * ecl_smspec, const char * h
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;
}
@@ -1130,29 +1164,33 @@ ecl_smspec_type * ecl_smspec_fread_alloc(const char *header_file, const char * k
util_safe_free(path);
}
ecl_smspec_fread_header(ecl_smspec , header_file , include_restart);
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 , "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 (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.
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.
*/
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__);
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;
}

View File

@@ -167,40 +167,41 @@ 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 (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();
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 );
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 );
}
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)
@@ -209,7 +210,10 @@ static void ecl_sum_fread(ecl_sum_type * ecl_sum , const char *header_file , con
ecl_sum_set_unified( ecl_sum , true);
else
util_abort("%s: what the fuck? \n",__func__);
}
} else
return false;
return true;
}
@@ -221,8 +225,7 @@ static bool ecl_sum_fread_case( ecl_sum_type * ecl_sum , bool include_restart) {
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 );
@@ -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 );
@@ -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++) {
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);
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);
}
}

View File

@@ -34,6 +34,7 @@
#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>
@@ -901,7 +902,13 @@ 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;
}
/*
@@ -913,64 +920,69 @@ static void ecl_sum_data_add_ecl_file(ecl_sum_data_type * data ,
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__);
return false;
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) {
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__);
/* 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);
{
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 ));
}
if (ecl_sum_data_get_length( data ) > 0) {
ecl_sum_data_build_index( data );
return true;
} else
util_abort("%s: invalid file type:%s \n",__func__ , ecl_util_file_type_name(file_type ));
return false;
}
ecl_sum_data_build_index( data );
}
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 );
}
@@ -1119,6 +1131,36 @@ double ecl_sum_data_interp_get(const ecl_sum_data_type * data , int time_index1
}
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);
}
}
}

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);
}

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

View File

@@ -81,24 +81,31 @@ struct fortio_struct {
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;
}
@@ -170,11 +177,7 @@ 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:
@@ -182,56 +185,33 @@ static bool fortio_is_fortran_stream__(FILE * stream , bool endian_flip) {
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,19 +419,20 @@ 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;
}
}
@@ -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;
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 );
size_t read_count = fread(&trailer , sizeof trailer , 1 , fortio->stream );
if (fortio->endian_flip_header)
util_endian_flip_vector(&trailer , sizeof trailer , 1);
if (read_count == 1) {
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);
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,22 +535,37 @@ 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;
}
@@ -589,8 +598,8 @@ void fortio_copy_record(fortio_type * src_stream , fortio_type * target_stream ,
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;
}
@@ -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); }

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 );

View File

@@ -1,3 +1,4 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
@@ -24,6 +25,7 @@
#include <ert/util/test_work_area.h>
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl/ecl_endian_flip.h>
@@ -126,6 +128,34 @@ void test_writable(const char * src_file ) {
}
void test_truncated() {
test_work_area_type * work_area = test_work_area_alloc("ecl_file_truncated" );
{
ecl_grid_type * grid = ecl_grid_alloc_rectangular(20,20,20,1,1,1,NULL);
ecl_grid_fwrite_EGRID( grid , "TEST.EGRID");
ecl_grid_free( grid );
}
{
ecl_file_type * ecl_file = ecl_file_open("TEST.EGRID" , 0 );
test_assert_true( ecl_file_is_instance( ecl_file ) );
ecl_file_close( ecl_file );
}
{
offset_type file_size = util_file_size( "TEST.EGRID");
FILE * stream = util_fopen("TEST.EGRID" , "r+");
util_ftruncate( stream , file_size / 2 );
fclose( stream );
}
{
ecl_file_type * ecl_file = ecl_file_open("TEST.EGRID" , 0 );
test_assert_NULL( ecl_file );
}
test_work_area_free( work_area );
}
int main( int argc , char ** argv) {
const char * src_file = argv[1];
const char * target_file = argv[2];
@@ -143,5 +173,6 @@ int main( int argc , char ** argv) {
test_work_area_free( work_area );
}
test_truncated();
exit(0);
}

View File

@@ -49,7 +49,7 @@ void test_fortio_is_instance(const char * filename ) {
void test_fortio_safe_cast(const char * filename ) {
void * i_am_a_fortio = fortio_open_reader( filename , false , ECL_ENDIAN_FLIP);
void * i_am_a_fortio = fortio_open_reader( filename , false , ECL_ENDIAN_FLIP);
test_assert_not_NULL( i_am_a_fortio );
fortio_type * fortio = fortio_safe_cast(i_am_a_fortio);
test_assert_true(fortio_is_instance(fortio));
@@ -82,12 +82,14 @@ void test_write( const char * filename , bool path_exists) {
void test_wrapper( const char * filename ) {
FILE * stream = util_fopen( filename , "r");
fortio_type * fortio = fortio_alloc_FILE_wrapper( filename , false , false , stream );
fortio_type * fortio = fortio_alloc_FILE_wrapper( filename , false , false , false , stream );
test_assert_not_NULL( fortio );
test_assert_false( fortio_fclose_stream( fortio ));
test_assert_false( fortio_fopen_stream( fortio ));
test_assert_true( fortio_stream_is_open( fortio ));
fortio_free_FILE_wrapper( fortio );
fclose( stream );
}
@@ -108,23 +110,200 @@ void test_open_close_read( const char * filename ) {
}
int main( int argc , char ** argv) {
const char * file = argv[1];
test_fortio_is_instance( file );
test_fortio_safe_cast( file );
test_assert_util_abort("fortio_safe_cast", test_fortio_unsafe_cast, NULL);
test_existing_read( file );
test_not_existing_read( );
test_open_close_read( file );
test_wrapper( file );
test_write( "/tmp/path/does/not/exist" , false );
void test_fread_truncated_data() {
test_work_area_type * work_area = test_work_area_alloc("fortio_truncated" );
{
test_work_area_type * work_area = test_work_area_alloc("ecl_fortio.write" );
util_make_path("path");
test_write( "path/file.x" , true );
test_work_area_free( work_area );
const size_t buffer_size = 1000;
void * buffer = util_malloc( buffer_size );
{
fortio_type * fortio = fortio_open_writer( "PRESSURE" , false , true );
fortio_fwrite_record( fortio , buffer , buffer_size );
fortio_fwrite_record( fortio , buffer , buffer_size );
fortio_fseek( fortio , 0 , SEEK_SET);
util_ftruncate( fortio_get_FILE(fortio) , 2 * buffer_size - 100 );
fortio_fclose( fortio );
}
test_assert_long_equal( util_file_size( "PRESSURE") , 2*buffer_size - 100);
{
fortio_type * fortio = fortio_open_reader( "PRESSURE" , false , true );
test_assert_true( fortio_fread_buffer( fortio , buffer , buffer_size ));
test_assert_false( fortio_fread_buffer( fortio , buffer , buffer_size ));
fortio_fclose( fortio );
}
free( buffer );
}
test_work_area_free( work_area );
}
void test_fread_truncated_head() {
test_work_area_type * work_area = test_work_area_alloc("fortio_truncated" );
{
{
FILE * stream = util_fopen("PRESSURE" , "w");
fclose( stream );
}
{
fortio_type * fortio = fortio_open_reader( "PRESSURE" , false , true );
void * buffer = NULL;
int buffer_size = 10;
test_assert_false( fortio_fread_buffer( fortio , buffer , buffer_size ));
test_assert_true( fortio_read_at_eof( fortio ));
fortio_fclose( fortio );
}
}
test_work_area_free( work_area );
}
void test_fread_truncated_tail() {
test_work_area_type * work_area = test_work_area_alloc("fortio_truncated2" );
{
const size_t buffer_size = 1000;
void * buffer = util_malloc( buffer_size );
{
fortio_type * fortio = fortio_open_writer( "PRESSURE" , false , true );
fortio_fwrite_record( fortio , buffer , buffer_size );
fortio_fseek( fortio , 0 , SEEK_SET);
util_ftruncate( fortio_get_FILE(fortio) , buffer_size + 4);
fortio_fclose( fortio );
}
test_assert_long_equal( util_file_size( "PRESSURE") , buffer_size + 4);
{
fortio_type * fortio = fortio_open_reader( "PRESSURE" , false , true );
test_assert_false( fortio_fread_buffer( fortio , buffer , buffer_size ));
fortio_fclose( fortio );
}
free( buffer );
}
test_work_area_free( work_area );
}
void test_fread_invalid_tail() {
test_work_area_type * work_area = test_work_area_alloc("fortio_invalid" );
int record_size = 10;
void * buffer = util_malloc( record_size );
{
FILE * stream = util_fopen("PRESSURE" , "w");
util_fwrite(&record_size , sizeof record_size , 1 , stream , __func__);
util_fwrite(buffer , 1 , record_size , stream , __func__);
util_fwrite(&record_size , sizeof record_size , 1 , stream , __func__);
util_fwrite(&record_size , sizeof record_size , 1 , stream , __func__);
util_fwrite(buffer , 1 , record_size , stream , __func__);
record_size += 1;
util_fwrite(&record_size , sizeof record_size , 1 , stream , __func__);
fclose(stream);
}
{
fortio_type * fortio = fortio_open_reader( "PRESSURE" , false , false );
record_size -= 1;
test_assert_true( fortio_fread_buffer( fortio , buffer , record_size ));
test_assert_false( fortio_fread_buffer( fortio , buffer , record_size ));
fortio_fclose( fortio );
}
exit(0);
free( buffer );
test_work_area_free( work_area );
}
void test_at_eof() {
test_work_area_type * work_area = test_work_area_alloc("fortio_truncated2" );
{
fortio_type * fortio = fortio_open_writer("PRESSURE" , false , true);
void * buffer = util_malloc( 100 );
fortio_fwrite_record( fortio , buffer , 100);
free( buffer );
fortio_fclose( fortio );
}
{
fortio_type * fortio = fortio_open_reader("PRESSURE" , false , true);
test_assert_false( fortio_read_at_eof( fortio ));
fortio_fseek( fortio , 50 , SEEK_SET );
test_assert_false( fortio_read_at_eof( fortio ));
fortio_fseek( fortio , 0 , SEEK_END );
test_assert_true( fortio_read_at_eof( fortio ));
fortio_fclose( fortio );
}
test_work_area_free( work_area );
}
void test_fseek() {
test_work_area_type * work_area = test_work_area_alloc("fortio_fseek" );
{
fortio_type * fortio = fortio_open_writer("PRESSURE" , false , true);
void * buffer = util_malloc( 100 );
fortio_fwrite_record( fortio , buffer , 100);
free( buffer );
fortio_fclose( fortio );
}
{
fortio_type * fortio = fortio_open_reader("PRESSURE" , false , true);
printf("Starting fssek test \n");
test_assert_true( fortio_fseek( fortio , 0 , SEEK_SET ));
test_assert_true( fortio_fseek( fortio , 0 , SEEK_END ));
test_assert_false( fortio_fseek( fortio , 100000 , SEEK_END));
test_assert_false( fortio_fseek( fortio , 100000 , SEEK_SET));
fortio_fclose( fortio );
}
test_work_area_free( work_area );
}
int main( int argc , char ** argv) {
util_install_signals();
{
const char * file = argv[1];
test_fortio_is_instance( file );
test_fortio_safe_cast( file );
test_assert_util_abort("fortio_safe_cast", test_fortio_unsafe_cast, NULL);
test_existing_read( file );
test_not_existing_read( );
test_open_close_read( file );
test_wrapper( file );
test_fread_truncated_head();
test_fread_truncated_data();
test_fread_truncated_tail();
test_fread_invalid_tail();
test_fseek();
test_at_eof();
test_write( "/tmp/path/does/not/exist" , false );
{
test_work_area_type * work_area = test_work_area_alloc("ecl_fortio.write" );
util_make_path("path");
test_write( "path/file.x" , true );
test_work_area_free( work_area );
}
exit(0);
}
}

View File

@@ -0,0 +1,83 @@
/*
Copyright (C) 2015 Statoil ASA, Norway.
The file 'ecl_kw_init.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/util/util.h>
#include <ert/util/test_work_area.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/fortio.h>
void test_truncated(const char * filename , offset_type truncate_size) {
{
FILE * stream = util_fopen(filename , "r+");
util_ftruncate( stream , truncate_size);
fclose( stream );
}
{
fortio_type * fortio = fortio_open_reader( filename , false , true );
ecl_kw_type * kw2 = ecl_kw_fread_alloc( fortio );
test_assert_NULL( kw2 );
fortio_fclose(fortio);
}
}
void test_fread_alloc() {
test_work_area_type * work_area = test_work_area_alloc("ecl_kw_fread" );
{
ecl_kw_type * kw1 = ecl_kw_alloc( "INT" , 100 , ECL_INT_TYPE );
int i;
for (i=0; i < 100; i++)
ecl_kw_iset_int( kw1 , i , i );
{
fortio_type * fortio = fortio_open_writer("INT" , false , true );
ecl_kw_fwrite( kw1 , fortio );
fortio_fclose( fortio );
}
{
fortio_type * fortio = fortio_open_reader("INT" , false , true );
ecl_kw_type * kw2 = ecl_kw_fread_alloc( fortio );
test_assert_true( ecl_kw_is_instance( kw2 ));
test_assert_true( ecl_kw_equal( kw1 , kw2 ));
ecl_kw_free( kw2 );
fortio_fclose( fortio );
}
{
offset_type file_size = util_file_size("INT");
test_truncated("INT" , file_size - 4 );
test_truncated("INT" , file_size - 25 );
test_truncated("INT" , 5 );
test_truncated("INT" , 0 );
}
ecl_kw_free( kw1 );
}
test_work_area_free( work_area );
}
int main(int argc , char ** argv) {
test_fread_alloc();
exit(0);
}

View File

@@ -27,6 +27,7 @@
#include <ert/ecl/ecl_nnc_export.h>
#include <ert/ecl/ecl_kw_magic.h>
int count_kw_data( const ecl_file_type * file , ecl_grid_type * grid , const char * kw1 , const char * kw2) {
int i,j;
int count = 0;
@@ -85,9 +86,22 @@ void test_count(const char * name) {
}
void test_nnc_export_missing_TRANX(const char * name ) {
char * grid_file_name = ecl_util_alloc_filename(NULL , name , ECL_EGRID_FILE , false , -1);
char * init_file_name = ecl_util_alloc_filename(NULL , name , ECL_INIT_FILE , false , -1);
if (util_entry_exists(init_file_name)) {
ecl_grid_type * grid = ecl_grid_alloc( grid_file_name );
ecl_file_type * init_file = ecl_file_open( init_file_name , 0);
ecl_nnc_type * nnc_data1 = util_calloc( ecl_nnc_export_get_size( grid ) , sizeof * nnc_data1 );
int count = ecl_nnc_export(grid, init_file, nnc_data1);
int i;
test_assert_int_equal( count , 0 );
for (i=0; i < count; i++)
test_assert_double_equal( nnc_data1[i].trans , ERT_ECL_DEFAULT_NNC_TRANS );
}
}
void test_export(const char * name) {
void test_export(const char * name, bool have_tran_data) {
char * grid_file_name = ecl_util_alloc_filename(NULL , name , ECL_EGRID_FILE , false , -1);
char * init_file_name = ecl_util_alloc_filename(NULL , name , ECL_INIT_FILE , false , -1);
if (util_entry_exists(init_file_name)) {
@@ -112,6 +126,10 @@ void test_export(const char * name) {
int lgr_nr1 = ecl_kw_iget_int( nnchead , NNCHEAD_LGR_INDEX);
int lgr_nr2 = ecl_kw_iget_int( nnchead , NNCHEAD_LGR_INDEX);
ecl_kw_type * nnc_tran = ecl_nnc_export_get_tranx_kw( grid , init_file , lgr_nr1 , lgr_nr2);
if (!have_tran_data) {
test_assert_NULL(nnc_tran);
return;
}
test_assert_not_NULL( nnc_tran );
test_assert_int_equal( ecl_kw_get_size( nnc1_kw ) , ecl_kw_get_size( nnc_tran ));
@@ -192,31 +210,16 @@ void test_export(const char * name) {
ecl_nnc_sort( nnc_data1 , nnc_offset );
}
ecl_nnc_export( grid , init_file , nnc_data2 );
{
int export_size = ecl_nnc_export( grid , init_file , nnc_data2 );
test_assert_int_equal( export_size , ecl_nnc_export_get_size( grid ));
}
if (0) {
{
int i;
int size = ecl_nnc_export_get_size( grid );
for (i=0; i < size; i++) {
if ((i % 1000) == 0)
printf("%d / %d \n",i , size);
if (ecl_nnc_cmp( &nnc_data1[i] , &nnc_data2[i]) != 0) {
printf("Comparing: %d 1:(%d,%d) 2:(%d,%d) 1:(%d,%d) 2:(%d,%d) %g , %g\n",
i ,
nnc_data1[i].grid_nr1 ,
nnc_data1[i].grid_nr2 ,
nnc_data2[i].grid_nr1 ,
nnc_data2[i].grid_nr2,
nnc_data1[i].global_index1 ,
nnc_data1[i].global_index2 ,
nnc_data2[i].global_index1 ,
nnc_data2[i].global_index2,
nnc_data1[i].trans ,
nnc_data2[i].trans);
}
for (i=0; i < size; i++)
test_assert_int_equal( 0 , ecl_nnc_cmp( &nnc_data1[i] , &nnc_data2[i]));
}
}
test_assert_int_equal( 0 , memcmp( nnc_data1 , nnc_data2 , ecl_nnc_export_get_size( grid ) * sizeof * nnc_data2 ));
@@ -309,10 +312,18 @@ void install_SIGNALS(void) {
int main(int argc, char ** argv) {
const char * base = argv[1];
bool have_tran_data;
install_SIGNALS();
test_cmp( );
test_sort();
test_count( base );
test_export( base );
exit(0);
if (util_sscanf_bool( argv[2] , &have_tran_data)) {
test_cmp( );
test_sort();
test_count( base );
test_export( base, have_tran_data );
if (!have_tran_data)
test_nnc_export_missing_TRANX(base);
exit(0);
} else
test_error_exit("Failed to parse input:%s as bool" , argv[2]);
}

View File

@@ -23,9 +23,29 @@
#include <ert/util/util.h>
#include <ert/ecl/ecl_rft_file.h>
#include <ert/util/vector.h>
#include <ert/util/int_vector.h>
#include <ert/util/test_work_area.h>
#include <ert/ecl/ecl_rft_node.h>
void test_rft_read_write(const char * rft_file){
ecl_rft_file_type * rft = ecl_rft_file_alloc( rft_file );
ecl_rft_node_type ** nodes =(ecl_rft_node_type **) malloc(sizeof(ecl_rft_node_type *) * 3);
int size = ecl_rft_file_get_size(rft);
for(int i =0;i<size;i++){
const ecl_rft_node_type * rft_node = ecl_rft_file_iget_node(rft, i);
nodes[i] =rft_node;
}
ecl_rft_node_type * old_node = ecl_rft_file_iget_node(rft, 0);
ecl_rft_node_type * new_node = ecl_rft_node_alloc_new("DUMMY", "R", ecl_rft_node_get_date(old_node), ecl_rft_node_get_days(old_node));
nodes[2]=new_node;
test_work_area_type * work_area = test_work_area_alloc("RFT_RW");
ecl_rft_file_update("eclipse.rft", nodes,3, ERT_ECL_METRIC_UNITS);
test_work_area_free(work_area);
free(nodes);
}
// Hardcoded GURBAT values
void test_rft( const char * rft_file ) {
@@ -135,8 +155,11 @@ int main( int argc , char ** argv) {
const char * rft_file = argv[1];
const char * mode_string = argv[2];
if (strcmp( mode_string , "RFT") == 0)
test_rft( rft_file );
else if (strcmp( mode_string , "RFT_RW") == 0)
test_rft_read_write(rft_file);
else if (strcmp( mode_string , "PLT") == 0)
test_plt( rft_file );
else if (strcmp( mode_string , "MSW-PLT") == 0)

View File

@@ -15,14 +15,19 @@ add_executable( ecl_kw_init ecl_kw_init.c )
target_link_libraries( ecl_kw_init ecl test_util )
add_test( ecl_kw_init ${EXECUTABLE_OUTPUT_PATH}/ecl_kw_init )
add_executable( ecl_kw_fread ecl_kw_fread.c )
target_link_libraries( ecl_kw_fread ecl test_util )
add_test( ecl_kw_fread ${EXECUTABLE_OUTPUT_PATH}/ecl_kw_fread )
add_executable( ecl_nnc_export ecl_nnc_export.c )
target_link_libraries( ecl_nnc_export ecl test_util )
add_test (ecl_nnc_export1 ${EXECUTABLE_OUTPUT_PATH}/ecl_nnc_export ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE )
add_test (ecl_nnc_export2 ${EXECUTABLE_OUTPUT_PATH}/ecl_nnc_export ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/10kcase/TEST10K_FLT_LGR_NNC )
add_test (ecl_nnc_export3 ${EXECUTABLE_OUTPUT_PATH}/ecl_nnc_export ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Troll/MSW_LGR/2BRANCHES-CCEWELLPATH-NEW-SCH-TUNED-AR3)
add_test (ecl_nnc_export4 ${EXECUTABLE_OUTPUT_PATH}/ecl_nnc_export ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/DualPoro/DUAL_DIFF )
add_test (ecl_nnc_export5 ${EXECUTABLE_OUTPUT_PATH}/ecl_nnc_export ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/DualPoro/DUALPORO )
add_test (ecl_nnc_export6 ${EXECUTABLE_OUTPUT_PATH}/ecl_nnc_export ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/nestedLGRcase/TESTCASE_NESTEDLGR)
add_test (ecl_nnc_export1 ${EXECUTABLE_OUTPUT_PATH}/ecl_nnc_export ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE TRUE)
add_test (ecl_nnc_export2 ${EXECUTABLE_OUTPUT_PATH}/ecl_nnc_export ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/10kcase/TEST10K_FLT_LGR_NNC TRUE)
add_test (ecl_nnc_export3 ${EXECUTABLE_OUTPUT_PATH}/ecl_nnc_export ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Troll/MSW_LGR/2BRANCHES-CCEWELLPATH-NEW-SCH-TUNED-AR3 TRUE)
add_test (ecl_nnc_export4 ${EXECUTABLE_OUTPUT_PATH}/ecl_nnc_export ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/DualPoro/DUAL_DIFF TRUE)
add_test (ecl_nnc_export5 ${EXECUTABLE_OUTPUT_PATH}/ecl_nnc_export ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/DualPoro/DUALPORO TRUE)
add_test (ecl_nnc_export6 ${EXECUTABLE_OUTPUT_PATH}/ecl_nnc_export ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/nestedLGRcase/TESTCASE_NESTEDLGR TRUE)
add_test (ecl_nnc_export7 ${EXECUTABLE_OUTPUT_PATH}/ecl_nnc_export ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/TYRIHANS/BASE20150218_MULTFLT FALSE)
add_executable( ecl_nnc_export_get_tran ecl_nnc_export_get_tran.c )
target_link_libraries( ecl_nnc_export_get_tran ecl test_util )
@@ -240,6 +245,7 @@ add_test( ecl_rsthead ${EXECUTABLE_OUTPUT_PATH}/ecl_rsthead ${PROJECT_SOURCE_DIR
add_executable( ecl_rft ecl_rft.c )
target_link_libraries( ecl_rft ecl test_util )
add_test( ecl_rft_rft ${EXECUTABLE_OUTPUT_PATH}/ecl_rft ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.RFT RFT)
add_test( ecl_rft_rft_rw ${EXECUTABLE_OUTPUT_PATH}/ecl_rft ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.RFT RFT_RW)
add_test( ecl_rft_plt ${EXECUTABLE_OUTPUT_PATH}/ecl_rft ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/RFT/TEST1_1A.RFT PLT)
add_test( ecl_rft_plt ${EXECUTABLE_OUTPUT_PATH}/ecl_rft ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/RFT/RFT2.RFT MSW-PLT)
@@ -333,6 +339,7 @@ set_property( TEST ecl_region2region PROPERTY LABELS StatoilData)
set_property( TEST ecl_grid_case PROPERTY LABELS StatoilData)
set_property( TEST ecl_rft_rft PROPERTY LABELS StatoilData)
set_property( TEST ecl_rft_plt PROPERTY LABELS StatoilData)
set_property( TEST ecl_rft_rft_rw PROPERTY LABELS StatoilData)
set_property( TEST ecl_sum_case_exists PROPERTY LABELS StatoilData)
set_property( TEST ecl_grid_volume1 PROPERTY LABELS StatoilData)
set_property( TEST ecl_grid_volume2 PROPERTY LABELS StatoilData)
@@ -348,6 +355,7 @@ set_property( TEST ecl_nnc_export3 PROPERTY LABELS StatoilData )
set_property( TEST ecl_nnc_export4 PROPERTY LABELS StatoilData )
set_property( TEST ecl_nnc_export5 PROPERTY LABELS StatoilData )
set_property( TEST ecl_nnc_export6 PROPERTY LABELS StatoilData )
set_property( TEST ecl_nnc_export7 PROPERTY LABELS StatoilData )
set_property( TEST ecl_nnc_export_get_tran PROPERTY LABELS StatoilData )
set_property( TEST ecl_grid_cell_contains2 PROPERTY LABELS StatoilData )
set_property( TEST ecl_grid_copy_statoil1 PROPERTY LABELS StatoilData )

View File

@@ -1,6 +1,8 @@
add_executable( segment_info segment_info.c )
add_executable( CF_dump well_CF_dump.c )
set(program_list segment_info CF_dump)
add_executable( ri_well_test ri_well_test.c )
set(program_list segment_info CF_dump ri_well_test)
foreach(prog ${program_list})
target_link_libraries( ${prog} ecl_well ecl)
if (USE_RUNPATH)

View File

@@ -0,0 +1,52 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_CF_dump.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/ecl/ecl_grid.h>
#include <ert/ecl_well/well_state.h>
#include <ert/ecl_well/well_info.h>
/*
This is a small test program which will load the well information in
the same way as Resinsight does it.
*/
void usage() {
printf("ri_well_test CASE.EGRID CASE.UNRST / { CASE.X1 CASE.X2 ... CASE.Xn } \n");
exit(1);
}
int main( int argc , char ** argv ) {
if (argc < 3)
usage();
else {
char * grid_file = argv[1];
ecl_grid_type * grid = ecl_grid_alloc( grid_file );
well_info_type * well_info = well_info_alloc( grid );
int ifile;
for (ifile = 2; ifile < argc; ifile++) {
const char * rst_file = argv[ifile];
printf("Loading restart file: %s \n",rst_file);
well_info_load_rstfile( well_info , rst_file , true );
}
ecl_grid_free( grid );
well_info_free( well_info );
}
}

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