mirror of
https://github.com/OPM/ResInsight.git
synced 2026-09-03 20:53:13 -05:00
Upgraded ERT from github master commit d9955e849
Startup on new project
This commit is contained in:
@@ -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
|
||||
|
||||
Vendored
+5
-1
@@ -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 )
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#include <signal.h>
|
||||
|
||||
void sigbus_handler(int signal) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
signal(SIGBUS , sigbus_handler);
|
||||
}
|
||||
+19
-1
@@ -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 )
|
||||
|
||||
Vendored
+1
-1
@@ -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
|
||||
|
||||
Vendored
+1
-1
@@ -13,4 +13,4 @@
|
||||
dh $@
|
||||
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure -- -DSHARED_LIB=1 -DBUILD_ECL_SUMMARY=1 -DCMAKE_BUILD_TYPE=Release
|
||||
dh_auto_configure -- -DBUILD_SHARED_LIBS=1 -DBUILD_ECL_SUMMARY=1 -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
+16
-2
@@ -1,6 +1,20 @@
|
||||
set( ERT_DOC_INSTALL_PATH "" CACHE PATH "Absolute path to install documentation *in addition* to $PREFIX/documentation")
|
||||
set( ERT_DOC_INSTALL_PATH "" CACHE PATH "Absolute path to install documentation *in addition* to $PREFIX/documentation")
|
||||
set( ERT_DOC_EXTERNAL_ROOT "" CACHE PATH "Path to site local ERT documentation")
|
||||
|
||||
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/tmp_doc")
|
||||
EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_SOURCE_DIR}/user" "${PROJECT_BINARY_DIR}/tmp_doc/user")
|
||||
EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_SOURCE_DIR}/code" "${PROJECT_BINARY_DIR}/tmp_doc/code")
|
||||
|
||||
if (ERT_DOC_EXTERNAL_ROOT)
|
||||
EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E create_symlink "${ERT_DOC_EXTERNAL_ROOT}" "${PROJECT_BINARY_DIR}/tmp_doc/external-doc")
|
||||
message(STATUS "Adding documentation link ${PROJECT_BINARY_DIR}/tmp_doc/external-doc -> ${ERT_DOC_EXTERNAL_ROOT}")
|
||||
set( ERT_DOC_LINK external-doc/index )
|
||||
else()
|
||||
set( ERT_DOC_LINK "" )
|
||||
endif()
|
||||
|
||||
configure_file(index.rst.in ${PROJECT_BINARY_DIR}/tmp_doc/index.rst )
|
||||
|
||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/Static DESTINATION ${PROJECT_BINARY_DIR}/tmp_doc/)
|
||||
add_custom_target(doc_out ALL
|
||||
COMMAND ${CMAKE_COMMAND} -Dccsd=${CMAKE_CURRENT_SOURCE_DIR} -Dpbd=${PROJECT_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/build_doc.cmake
|
||||
DEPENDS enkf )
|
||||
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
First page in the static ert's documentation!
|
||||
===============================
|
||||
|
||||
Contents:
|
||||
This is where we need to write the "manual" documentation
|
||||
|
||||
+6
-4
@@ -1,6 +1,8 @@
|
||||
set( ENV{PYTHONPATH} ${pbd}/python)
|
||||
|
||||
#set( ENV{PYTHONPATH} ${pbd}/python)
|
||||
execute_process(COMMAND cmake -E copy ${ccsd}/conf.py ${pbd}/tmp_doc/conf.py )
|
||||
execute_process(COMMAND cmake -E copy ${ccsd}/index.rst ${pbd}/tmp_doc/index.rst )
|
||||
execute_process(COMMAND sphinx-apidoc -e -o python ${pbd}/python WORKING_DIRECTORY ${pbd}/tmp_doc/)
|
||||
|
||||
|
||||
# The api documentation is reeferenced from code/python/index.rst, i.e. the output path used when calling
|
||||
# sphinx-apidoc must match this.
|
||||
execute_process(COMMAND sphinx-apidoc -e -o API/python ${pbd}/python WORKING_DIRECTORY ${pbd}/tmp_doc/)
|
||||
execute_process(COMMAND sphinx-build -b html -d _build/doctrees . _build WORKING_DIRECTORY ${pbd}/tmp_doc/)
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
Low level C libraries
|
||||
=====================
|
||||
|
||||
How to use the C libraries
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
Documentation of ert code
|
||||
=========================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
python/index
|
||||
C/index
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
The ert Python API
|
||||
==================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
../../API/python/ert
|
||||
../../API/python/ert_gui
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
Using the ert.ecl classes for Eclipse manipulation
|
||||
==================================================
|
||||
|
||||
Using the ert.ecl classes for ECLIPSE binary files
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
Python documentation
|
||||
====================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
introduction/index
|
||||
eclipse/index
|
||||
../../API/python/ert
|
||||
../../API/python/ert_gui
|
||||
@@ -0,0 +1,4 @@
|
||||
Simple introduction to Python
|
||||
=============================
|
||||
|
||||
An introduction to Python
|
||||
+4
-5
@@ -9,12 +9,11 @@ Welcome to ert's documentation!
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:maxdepth: 1
|
||||
|
||||
Static/index
|
||||
|
||||
python/ert
|
||||
python/ert_gui
|
||||
user/index
|
||||
code/index
|
||||
${ERT_DOC_LINK}
|
||||
|
||||
|
||||
Indices and tables
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
User documentation for ERT
|
||||
==========================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
tutorial/index
|
||||
keywords/index
|
||||
observations/index
|
||||
@@ -0,0 +1,7 @@
|
||||
Keywords available in the ERT configuration
|
||||
===========================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
Here comes keywords ...
|
||||
@@ -0,0 +1,4 @@
|
||||
Configuring observations for ERT
|
||||
================================
|
||||
|
||||
Adding observations ...
|
||||
@@ -0,0 +1,3 @@
|
||||
ERT Tutorial
|
||||
============
|
||||
Tutorial for ert.
|
||||
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'analysis_module.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'analysis_module.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#ifndef __ANALYSIS_MODULE_H__
|
||||
@@ -27,7 +27,7 @@ extern "C" {
|
||||
#include <ert/util/bool_vector.h>
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
These are option flag values which are used by the core ert code to
|
||||
query the module of it's needs and capabilities. For instance to to
|
||||
determine whether the data should be scaled prior to analysis the
|
||||
@@ -36,7 +36,7 @@ extern "C" {
|
||||
if (analysis_module_get_option( module, ANALYSIS_SCALE_DATA))
|
||||
obs_data_scale( obs_data , S , E , D , R , dObs );
|
||||
|
||||
It is the responsability of the module to set the various flags.
|
||||
It is the responsability of the module to set the various flags.
|
||||
*/
|
||||
|
||||
|
||||
@@ -57,54 +57,54 @@ typedef enum {
|
||||
{.value = ANALYSIS_ITERABLE , .name = "ANALYSIS_ITERABLE"}
|
||||
|
||||
|
||||
#define EXTERNAL_MODULE_NAME "analysis_table"
|
||||
#define EXTERNAL_MODULE_NAME "analysis_table"
|
||||
#define EXTERNAL_MODULE_SYMBOL analysis_table
|
||||
|
||||
typedef enum {
|
||||
LOAD_OK = 0,
|
||||
DLOPEN_FAILURE = 1,
|
||||
DLOPEN_FAILURE = 1,
|
||||
LOAD_SYMBOL_TABLE_NOT_FOUND = 2
|
||||
} analysis_module_load_status_enum;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct analysis_module_struct analysis_module_type;
|
||||
|
||||
|
||||
analysis_module_type * analysis_module_alloc_internal__( rng_type * rng , const char * user_name , const char * symbol_table , bool verbose , analysis_module_load_status_enum * load_status);
|
||||
analysis_module_type * analysis_module_alloc_internal( rng_type * rng , const char * user_name , const char * symbol_table );
|
||||
|
||||
|
||||
analysis_module_type * analysis_module_alloc_external__(rng_type * rng , const char * user_name , const char * lib_name , bool verbose , analysis_module_load_status_enum * load_status);
|
||||
analysis_module_type * analysis_module_alloc_external( rng_type * rng , const char * user_name , const char * libname );
|
||||
|
||||
|
||||
void analysis_module_free( analysis_module_type * module );
|
||||
void analysis_module_free__( void * arg);
|
||||
|
||||
void analysis_module_initX(analysis_module_type * module ,
|
||||
matrix_type * X ,
|
||||
matrix_type * A ,
|
||||
matrix_type * S ,
|
||||
matrix_type * R ,
|
||||
matrix_type * dObs ,
|
||||
matrix_type * E ,
|
||||
void analysis_module_initX(analysis_module_type * module ,
|
||||
matrix_type * X ,
|
||||
matrix_type * A ,
|
||||
matrix_type * S ,
|
||||
matrix_type * R ,
|
||||
matrix_type * dObs ,
|
||||
matrix_type * E ,
|
||||
matrix_type * D);
|
||||
|
||||
|
||||
void analysis_module_updateA(analysis_module_type * module ,
|
||||
matrix_type * A ,
|
||||
matrix_type * S ,
|
||||
matrix_type * R ,
|
||||
matrix_type * dObs ,
|
||||
matrix_type * E ,
|
||||
|
||||
|
||||
void analysis_module_updateA(analysis_module_type * module ,
|
||||
matrix_type * A ,
|
||||
matrix_type * S ,
|
||||
matrix_type * R ,
|
||||
matrix_type * dObs ,
|
||||
matrix_type * E ,
|
||||
matrix_type * D );
|
||||
|
||||
|
||||
void analysis_module_init_update( analysis_module_type * module ,
|
||||
const bool_vector_type * ens_mask ,
|
||||
const matrix_type * S ,
|
||||
const matrix_type * R ,
|
||||
const matrix_type * dObs ,
|
||||
const matrix_type * E ,
|
||||
|
||||
void analysis_module_init_update( analysis_module_type * module ,
|
||||
const bool_vector_type * ens_mask ,
|
||||
const matrix_type * S ,
|
||||
const matrix_type * R ,
|
||||
const matrix_type * dObs ,
|
||||
const matrix_type * E ,
|
||||
const matrix_type * D );
|
||||
|
||||
|
||||
|
||||
const char * analysis_module_get_lib_name( const analysis_module_type * module);
|
||||
bool analysis_module_internal( const analysis_module_type * module );
|
||||
@@ -120,7 +120,7 @@ typedef enum {
|
||||
bool analysis_module_get_bool( const analysis_module_type * module , const char * var);
|
||||
void * analysis_module_get_ptr( const analysis_module_type * module , const char * var);
|
||||
const char * analysis_module_flag_enum_iget( int index, int * value);
|
||||
|
||||
|
||||
|
||||
|
||||
UTIL_IS_INSTANCE_HEADER( analysis_module );
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
set( RML_SOURCE_FILES
|
||||
rml_enkf_config.c
|
||||
rml_enkf_log.c
|
||||
rml_enkf.c
|
||||
rml_enkf_common.c )
|
||||
|
||||
|
||||
+214
-304
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'rml_enkf.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'rml_enkf.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include <ert/analysis/std_enkf.h>
|
||||
|
||||
#include <rml_enkf_common.h>
|
||||
#include <rml_enkf_config.h>
|
||||
#include <rml_enkf_log.h>
|
||||
|
||||
typedef struct rml_enkf_data_struct rml_enkf_data_type;
|
||||
|
||||
@@ -50,21 +52,11 @@ typedef struct rml_enkf_data_struct rml_enkf_data_type;
|
||||
set_subspace_dimension() routines will set one variable, AND
|
||||
INVALIDATE THE OTHER. For most situations this will be OK, but if
|
||||
you have repeated calls to both of these functions the end result
|
||||
might be a surprise.
|
||||
might be a surprise.
|
||||
*/
|
||||
#define INVALID_SUBSPACE_DIMENSION -1
|
||||
#define INVALID_TRUNCATION -1
|
||||
#define DEFAULT_SUBSPACE_DIMENSION INVALID_SUBSPACE_DIMENSION
|
||||
#define DEFAULT_USE_PRIOR true
|
||||
#define DEFAULT_LAMBDA_INCREASE_FACTOR 4
|
||||
#define DEFAULT_LAMBDA_REDUCE_FACTOR 0.1
|
||||
#define DEFAULT_LAMBDA0 -1
|
||||
#define DEFAULT_LAMBDA_MIN 0.01
|
||||
#define DEFAULT_LAMBDA_RECALCULATE false
|
||||
#define DEFAULT_LOG_FILE "rml_enkf.out"
|
||||
#define DEFAULT_CLEAR_LOG true
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define USE_PRIOR_KEY "USE_PRIOR"
|
||||
#define LAMBDA_REDUCE_FACTOR_KEY "LAMBDA_REDUCE"
|
||||
@@ -74,7 +66,7 @@ typedef struct rml_enkf_data_struct rml_enkf_data_type;
|
||||
#define LAMBDA_RECALCULATE_KEY "LAMBDA_RECALCULATE"
|
||||
#define ITER_KEY "ITER"
|
||||
#define LOG_FILE_KEY "LOG_FILE"
|
||||
#define CLEAR_LOG_KEY "CLEAR_LOG"
|
||||
#define CLEAR_LOG_KEY "CLEAR_LOG"
|
||||
|
||||
|
||||
|
||||
@@ -103,32 +95,31 @@ typedef struct rml_enkf_data_struct rml_enkf_data_type;
|
||||
destructor or free() function registered with the .freef field of
|
||||
the analysis table.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct rml_enkf_data_struct {
|
||||
UTIL_TYPE_ID_DECLARATION;
|
||||
double truncation; // Controlled by config key: ENKF_TRUNCATION_KEY
|
||||
int subspace_dimension; // Controlled by config key: ENKF_NCOMP_KEY (-1: use Truncation instead)
|
||||
long option_flags;
|
||||
|
||||
int iteration_nr; // Keep track of the outer iteration loop
|
||||
double Sk; // Objective function value
|
||||
double Std; // Standard Deviation of the Objective function
|
||||
double * Csc;
|
||||
bool_vector_type * ens_mask;
|
||||
|
||||
double * Csc; // Vector with scalings for non-dimensionalizing states
|
||||
matrix_type *Am; // Scaled right singular vectors of ensemble anomalies.
|
||||
matrix_type *prior; // m_pr
|
||||
matrix_type *state; // m_l
|
||||
bool_vector_type * ens_mask; // Tells you which of the realisations are in use.
|
||||
bool use_prior; // Use exact/approximate scheme? Approximate scheme drops the "prior" term in the LM step.
|
||||
|
||||
double lambda; // parameter to control the setp length in Marquardt levenberg optimization
|
||||
double lambda0;
|
||||
double lambda_min;
|
||||
double lambda_reduce_factor;
|
||||
double lambda_increase_factor;
|
||||
bool lambda_recalculate;
|
||||
|
||||
bool clear_log;
|
||||
char * log_file;
|
||||
FILE * log_stream;
|
||||
matrix_type *global_prior; // m_pr
|
||||
matrix_type *previous_state; // m_l
|
||||
|
||||
|
||||
double lambda; // parameter to control the setp length in Marquardt levenberg optimization
|
||||
|
||||
|
||||
rml_enkf_log_type * rml_log;
|
||||
rml_enkf_config_type * config;
|
||||
};
|
||||
|
||||
|
||||
@@ -144,69 +135,7 @@ static UTIL_SAFE_CAST_FUNCTION_CONST( rml_enkf_data , RML_ENKF_TYPE_ID )
|
||||
//**********************************************
|
||||
// Set / Get
|
||||
//**********************************************
|
||||
double rml_enkf_get_truncation( rml_enkf_data_type * data ) {
|
||||
return data->truncation;
|
||||
}
|
||||
|
||||
int rml_enkf_get_subspace_dimension( rml_enkf_data_type * data ) {
|
||||
return data->subspace_dimension;
|
||||
}
|
||||
|
||||
void rml_enkf_set_truncation( rml_enkf_data_type * data , double truncation ) {
|
||||
data->truncation = truncation;
|
||||
if (truncation > 0.0)
|
||||
data->subspace_dimension = INVALID_SUBSPACE_DIMENSION;
|
||||
}
|
||||
|
||||
void rml_enkf_set_lambda0( rml_enkf_data_type * data , double lambda0) {
|
||||
data->lambda0 = lambda0;
|
||||
}
|
||||
|
||||
double rml_enkf_get_lambda0( const rml_enkf_data_type * data ) {
|
||||
return data->lambda0;
|
||||
}
|
||||
|
||||
void rml_enkf_set_lambda_min( rml_enkf_data_type * data , double lambda_min) {
|
||||
data->lambda_min = lambda_min;
|
||||
}
|
||||
|
||||
double rml_enkf_get_lambda_min( const rml_enkf_data_type * data ) {
|
||||
return data->lambda_min;
|
||||
}
|
||||
|
||||
void rml_enkf_set_lambda_increase_factor( rml_enkf_data_type * data , double increase_factor) {
|
||||
data->lambda_increase_factor = increase_factor;
|
||||
}
|
||||
|
||||
double rml_enkf_get_lambda_increase_factor( const rml_enkf_data_type * data ) {
|
||||
return data->lambda_increase_factor;
|
||||
}
|
||||
|
||||
void rml_enkf_set_lambda_reduce_factor( rml_enkf_data_type * data , double reduce_factor) {
|
||||
data->lambda_reduce_factor = reduce_factor;
|
||||
}
|
||||
|
||||
double rml_enkf_get_lambda_reduce_factor( const rml_enkf_data_type * data ) {
|
||||
return data->lambda_reduce_factor;
|
||||
}
|
||||
|
||||
bool rml_enkf_get_use_prior( const rml_enkf_data_type * data ) {
|
||||
return data->use_prior;
|
||||
}
|
||||
|
||||
void rml_enkf_set_use_prior( rml_enkf_data_type * data , bool use_prior) {
|
||||
data->use_prior = use_prior;
|
||||
}
|
||||
|
||||
void rml_enkf_set_lambda_recalculate( rml_enkf_data_type * data , bool lambda_recalculate) {
|
||||
data->lambda_recalculate = lambda_recalculate;
|
||||
}
|
||||
|
||||
void rml_enkf_set_subspace_dimension( rml_enkf_data_type * data , int subspace_dimension) {
|
||||
data->subspace_dimension = subspace_dimension;
|
||||
if (subspace_dimension > 0)
|
||||
data->truncation = INVALID_TRUNCATION;
|
||||
}
|
||||
|
||||
void rml_enkf_set_iteration_nr( rml_enkf_data_type * data , int iteration_nr) {
|
||||
data->iteration_nr = iteration_nr;
|
||||
@@ -223,72 +152,36 @@ int rml_enkf_get_iteration_nr( const rml_enkf_data_type * data ) {
|
||||
//**********************************************
|
||||
// Log-file related stuff
|
||||
//**********************************************
|
||||
bool rml_enkf_get_clear_log( const rml_enkf_data_type * data ) {
|
||||
return data->clear_log;
|
||||
}
|
||||
|
||||
void rml_enkf_set_clear_log( rml_enkf_data_type * data , bool clear_log) {
|
||||
data->clear_log = clear_log;
|
||||
}
|
||||
|
||||
void rml_enkf_set_log_file( rml_enkf_data_type * data , const char * log_file ) {
|
||||
data->log_file = util_realloc_string_copy( data->log_file , log_file );
|
||||
}
|
||||
|
||||
const char * rml_enkf_get_log_file( const rml_enkf_data_type * data) {
|
||||
return data->log_file;
|
||||
}
|
||||
|
||||
void rml_enkf_log_line( rml_enkf_data_type * data , const char * fmt , ...) {
|
||||
if (data->log_stream) {
|
||||
va_list ap;
|
||||
va_start(ap , fmt);
|
||||
vfprintf( data->log_stream , fmt , ap );
|
||||
va_end( ap );
|
||||
}
|
||||
}
|
||||
|
||||
static void rml_enkf_write_log_header( rml_enkf_data_type * data, const char * format) {
|
||||
if (data->log_stream) {
|
||||
if (rml_enkf_log_is_open( data->rml_log )) {
|
||||
const char * column1 = "Iter#";
|
||||
const char * column2 = "Lambda";
|
||||
const char * column3 = "Sk old";
|
||||
const char * column4 = "Sk_new";
|
||||
const char * column5 = "std(Sk)";
|
||||
|
||||
rml_enkf_log_line(data, format, column1, column2, column3, column4, column5);
|
||||
|
||||
rml_enkf_log_line(data->rml_log, format, column1, column2, column3, column4, column5);
|
||||
}
|
||||
}
|
||||
|
||||
static void rml_enkf_write_iter_info( rml_enkf_data_type * data , double Sk_new, double Std_new ) {
|
||||
if (data->log_stream) {
|
||||
static void rml_enkf_write_iter_info( rml_enkf_data_type * data , double prev_Sk , double Sk_new, double Std_new ) {
|
||||
if (rml_enkf_log_is_open( data->rml_log )) {
|
||||
|
||||
const char * format = "\n%2d-->%-2d %-7.3f %-7.3f --> %-7.3f %-7.3f";
|
||||
const char * format_headers = "\n%-7s %-7s %-7s --> %-7s %-7s";
|
||||
|
||||
static int has_printed_header = 0;
|
||||
static bool has_printed_header = false;
|
||||
|
||||
if (!has_printed_header) {
|
||||
rml_enkf_write_log_header( data, format_headers );
|
||||
has_printed_header = 1;
|
||||
has_printed_header = true;
|
||||
}
|
||||
|
||||
rml_enkf_log_line( data , format, data->iteration_nr, data->iteration_nr+1, data->lambda, data->Sk, Sk_new, Std_new);
|
||||
|
||||
rml_enkf_log_line( data->rml_log , format, data->iteration_nr, data->iteration_nr+1, data->lambda, prev_Sk, Sk_new, Std_new);
|
||||
}
|
||||
}
|
||||
|
||||
static void rml_enkf_open_log_file( rml_enkf_data_type * data ) {
|
||||
data->log_stream = NULL;
|
||||
if (data->log_file) {
|
||||
if ( data->iteration_nr == 0) {
|
||||
if (data->clear_log){
|
||||
data->log_stream = util_mkdir_fopen( data->log_file , "w");
|
||||
}
|
||||
else
|
||||
data->log_stream = util_mkdir_fopen( data->log_file , "a");
|
||||
} else
|
||||
data->log_stream = util_fopen( data->log_file , "a");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -299,37 +192,28 @@ static void rml_enkf_open_log_file( rml_enkf_data_type * data ) {
|
||||
void * rml_enkf_data_alloc( rng_type * rng) {
|
||||
rml_enkf_data_type * data = util_malloc( sizeof * data);
|
||||
UTIL_TYPE_ID_INIT( data , RML_ENKF_TYPE_ID );
|
||||
|
||||
data->log_file = NULL;
|
||||
|
||||
rml_enkf_set_truncation( data , DEFAULT_ENKF_TRUNCATION_ );
|
||||
rml_enkf_set_subspace_dimension( data , DEFAULT_SUBSPACE_DIMENSION );
|
||||
rml_enkf_set_use_prior( data , DEFAULT_USE_PRIOR );
|
||||
rml_enkf_set_lambda0( data , DEFAULT_LAMBDA0 );
|
||||
rml_enkf_set_lambda_increase_factor(data , DEFAULT_LAMBDA_INCREASE_FACTOR);
|
||||
rml_enkf_set_lambda_reduce_factor(data , DEFAULT_LAMBDA_REDUCE_FACTOR);
|
||||
rml_enkf_set_lambda_min( data , DEFAULT_LAMBDA_MIN );
|
||||
rml_enkf_set_log_file( data , DEFAULT_LOG_FILE );
|
||||
rml_enkf_set_clear_log( data , DEFAULT_CLEAR_LOG );
|
||||
rml_enkf_set_lambda_recalculate( data , DEFAULT_LAMBDA_RECALCULATE );
|
||||
data->config = rml_enkf_config_alloc();
|
||||
data->rml_log = rml_enkf_log_alloc();
|
||||
|
||||
data->option_flags = ANALYSIS_NEED_ED + ANALYSIS_UPDATE_A + ANALYSIS_ITERABLE + ANALYSIS_SCALE_DATA;
|
||||
data->Csc = NULL;
|
||||
data->iteration_nr = 0;
|
||||
data->Std = 0;
|
||||
data->ens_mask = bool_vector_alloc(0,false);
|
||||
data->state = matrix_alloc(1,1);
|
||||
data->prior = matrix_alloc(1,1);
|
||||
data->Std = 0;
|
||||
data->previous_state = matrix_alloc(1,1);
|
||||
data->global_prior = NULL;
|
||||
data->ens_mask = NULL;
|
||||
return data;
|
||||
}
|
||||
|
||||
void rml_enkf_data_free( void * arg ) {
|
||||
void rml_enkf_data_free( void * arg ) {
|
||||
rml_enkf_data_type * data = rml_enkf_data_safe_cast( arg );
|
||||
|
||||
matrix_free( data->state );
|
||||
matrix_free( data->prior );
|
||||
matrix_free( data->previous_state );
|
||||
if (data->global_prior)
|
||||
matrix_free( data->global_prior );
|
||||
|
||||
util_safe_free( data->log_file );
|
||||
bool_vector_free( data->ens_mask );
|
||||
rml_enkf_log_free( data->rml_log );
|
||||
rml_enkf_config_free( data->config );
|
||||
free( data );
|
||||
}
|
||||
|
||||
@@ -346,11 +230,10 @@ void rml_enkf_data_free( void * arg ) {
|
||||
* Variable name in code <-> D.Oliver notation <-> Description
|
||||
* -------------------------------------------------------------------------------------------------------------
|
||||
* A <-> m_l <-> Ensemble matrix. Updated in-place by iterations.
|
||||
* data->state <-> m_(l-1) <-> "A" from the previous iteration. Backs up A in case the update is bad.
|
||||
* data->prior <-> <-> Previously: "active_prior". Stores A from before iter0, i.e. the actual prior.
|
||||
* data->previous_state <-> m_(l-1) <-> "A" from the previous iteration. Backs up A in case the update is bad.
|
||||
* data->global_prior <-> <-> Previously: "active_prior". Stores A from before iter0, i.e. the actual prior.
|
||||
* Acopy <-> <-> Eliminated from code. Copy of A (at each iteration, before acceptance/rejection decision)
|
||||
* data->prior0 <-> m_pr <-> Eliminated from code. Same as prior, but also includes columns (j) for which ens_mask[j]==false.
|
||||
* Seems pointless. Only creates confusion.
|
||||
|
||||
*
|
||||
* Am <-> A_m <-> Am = Um*Wm^(-1)
|
||||
* Csc <-> C_sc^(1/2) <-> State scalings. Note the square root.
|
||||
@@ -373,28 +256,30 @@ void rml_enkf_data_free( void * arg ) {
|
||||
static void rml_enkf_init1__( rml_enkf_data_type * data) {
|
||||
// Differentiate this routine from init2__, which actually calculates the prior mismatch update.
|
||||
// This routine does not change any ensemble matrix.
|
||||
// Um*Wm^(-1) are the scaled, truncated, right singular vectors of data->prior
|
||||
|
||||
// Um*Wm^(-1) are the scaled, truncated, right singular vectors of data->global_prior
|
||||
|
||||
int state_size = matrix_get_rows( data->prior );
|
||||
int ens_size = matrix_get_columns( data->prior );
|
||||
int nrmin = util_int_min( ens_size , state_size);
|
||||
matrix_type * Dm = matrix_alloc_copy( data->prior );
|
||||
matrix_type * Um = matrix_alloc( state_size , nrmin ); /* Left singular vectors. */
|
||||
matrix_type * VmT = matrix_alloc( nrmin , ens_size ); /* Right singular vectors. */
|
||||
double * Wm = util_calloc( nrmin , sizeof * Wm );
|
||||
double nsc = 1/sqrt(ens_size - 1);
|
||||
matrix_type * prior = matrix_alloc_column_compressed_copy( data->global_prior , data->ens_mask);
|
||||
int state_size = matrix_get_rows( prior );
|
||||
int ens_size = matrix_get_columns( prior );
|
||||
int nrmin = util_int_min( ens_size , state_size);
|
||||
matrix_type * Dm = matrix_alloc_copy( prior );
|
||||
matrix_type * Um = matrix_alloc( state_size , nrmin ); /* Left singular vectors. */
|
||||
matrix_type * VmT = matrix_alloc( nrmin , ens_size ); /* Right singular vectors. */
|
||||
double * Wm = util_calloc( nrmin , sizeof * Wm );
|
||||
double nsc = 1/sqrt(ens_size - 1);
|
||||
|
||||
matrix_subtract_row_mean(Dm);
|
||||
|
||||
for (int i=0; i < state_size; i++){
|
||||
double sc = nsc / (data->Csc[i]);
|
||||
matrix_scale_row( Dm , i , sc);
|
||||
{
|
||||
const double * Csc = data->Csc;
|
||||
for (int i=0; i < state_size; i++){
|
||||
double sc = nsc / (Csc[i]);
|
||||
matrix_scale_row( Dm , i , sc);
|
||||
}
|
||||
}
|
||||
|
||||
// Um Wm VmT = Dm; nsign1 = num of non-zero singular values.
|
||||
int nsign1 = enkf_linalg_svd_truncation(Dm , data->truncation , -1 , DGESVD_MIN_RETURN , Wm , Um , VmT);
|
||||
|
||||
int nsign1 = enkf_linalg_svd_truncation(Dm , rml_enkf_config_get_truncation( data->config ) , -1 , DGESVD_MIN_RETURN , Wm , Um , VmT);
|
||||
|
||||
// Am = Um*Wm^(-1). I.e. scale *columns* of Um
|
||||
enkf_linalg_rml_enkfAm(Um, Wm, nsign1);
|
||||
|
||||
@@ -402,25 +287,31 @@ static void rml_enkf_init1__( rml_enkf_data_type * data) {
|
||||
matrix_free(Um);
|
||||
matrix_free(VmT);
|
||||
matrix_free(Dm);
|
||||
matrix_free(prior);
|
||||
free(Wm);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Creates state scaling matrix
|
||||
void rml_enkf_init_Csc(rml_enkf_data_type * data){
|
||||
void rml_enkf_init_Csc(const rml_enkf_data_type * data ){
|
||||
// This seems a strange choice of scaling matrix. Review?
|
||||
|
||||
int state_size = matrix_get_rows( data->prior );
|
||||
int ens_size = matrix_get_columns( data->prior );
|
||||
matrix_type * prior = matrix_alloc_column_compressed_copy( data->global_prior , data->ens_mask );
|
||||
{
|
||||
int state_size = matrix_get_rows( prior );
|
||||
int ens_size = matrix_get_columns( prior );
|
||||
|
||||
for (int row=0; row < state_size; row++) {
|
||||
double sumrow = matrix_get_row_sum(data->prior , row);
|
||||
double tmp = sumrow / ens_size;
|
||||
for (int row=0; row < state_size; row++) {
|
||||
double sumrow = matrix_get_row_sum(prior , row);
|
||||
double tmp = sumrow / ens_size;
|
||||
|
||||
if (abs(tmp)< 1)
|
||||
data->Csc[row] = 0.05;
|
||||
else
|
||||
data->Csc[row] = 1.00;
|
||||
if (abs(tmp)< 1)
|
||||
data->Csc[row] = 0.05;
|
||||
else
|
||||
data->Csc[row] = 1.00;
|
||||
|
||||
}
|
||||
matrix_free( prior );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,6 +319,7 @@ void rml_enkf_init_Csc(rml_enkf_data_type * data){
|
||||
static void rml_enkf_initA__(rml_enkf_data_type * data, matrix_type * A, matrix_type * S, matrix_type * Cd, matrix_type * E, matrix_type * D, matrix_type * Udr, double * Wdr, matrix_type * VdTr) {
|
||||
|
||||
int ens_size = matrix_get_columns( S );
|
||||
int state_size = matrix_get_rows( A );
|
||||
double nsc = 1/sqrt(ens_size-1);
|
||||
int nsign;
|
||||
|
||||
@@ -440,37 +332,37 @@ static void rml_enkf_initA__(rml_enkf_data_type * data, matrix_type * A, matrix_
|
||||
matrix_matmul(tmp , Cd , S ); //
|
||||
matrix_scale(tmp , nsc); //
|
||||
|
||||
nsign = enkf_linalg_svd_truncation(tmp , data->truncation , -1 , DGESVD_MIN_RETURN , Wdr , Udr , VdTr);
|
||||
nsign = enkf_linalg_svd_truncation(tmp , rml_enkf_config_get_truncation( data->config ) , -1 , DGESVD_MIN_RETURN , Wdr , Udr , VdTr);
|
||||
matrix_free( tmp );
|
||||
}
|
||||
|
||||
|
||||
// Calc X3
|
||||
{
|
||||
matrix_type * X3 = matrix_alloc( ens_size, ens_size );
|
||||
{
|
||||
matrix_type * X1 = matrix_alloc( nsign, ens_size);
|
||||
matrix_type * X2 = matrix_alloc( nsign, ens_size );
|
||||
|
||||
|
||||
|
||||
|
||||
// See LM-EnRML algorithm in Oliver'2013 (Comp. Geo.) for meaning
|
||||
enkf_linalg_rml_enkfX1(X1, Udr ,D ,Cd ); // X1 = Ud(T)*Cd(-1/2)*D -- D= -(dk-d0)
|
||||
enkf_linalg_rml_enkfX2(X2, Wdr ,X1 ,data->lambda + 1 , nsign); // X2 = ((a*Ipd)+Wd^2)^-1 * X1
|
||||
enkf_linalg_rml_enkfX3(X3, VdTr ,Wdr,X2, nsign); // X3 = Vd *Wd*X2
|
||||
|
||||
|
||||
matrix_free(X2);
|
||||
matrix_free(X1);
|
||||
}
|
||||
|
||||
|
||||
// Update A
|
||||
{
|
||||
matrix_type * dA1 = matrix_alloc( matrix_get_rows(A) , ens_size);
|
||||
matrix_type * Dm = matrix_alloc_copy( A );
|
||||
matrix_type * dA1 = matrix_alloc( state_size , ens_size);
|
||||
matrix_type * Dm = matrix_alloc_copy( A );
|
||||
|
||||
matrix_subtract_row_mean( Dm ); /* Remove the mean from the ensemble of model parameters*/
|
||||
matrix_scale(Dm, nsc);
|
||||
|
||||
matrix_matmul(dA1, Dm , X3);
|
||||
matrix_inplace_add(A,dA1); // dA
|
||||
matrix_inplace_add(A,dA1); // dA
|
||||
|
||||
matrix_free(Dm);
|
||||
matrix_free(dA1);
|
||||
@@ -487,15 +379,15 @@ void rml_enkf_init2__( rml_enkf_data_type * data, matrix_type *A, double * Wdr,
|
||||
|
||||
int state_size = matrix_get_rows( A );
|
||||
int ens_size = matrix_get_columns( A );
|
||||
double nsc = 1/sqrt(ens_size-1);
|
||||
double nsc = 1/sqrt(ens_size-1);
|
||||
|
||||
matrix_type *Am = matrix_alloc_copy(data->Am);
|
||||
matrix_type *Apr = matrix_alloc_copy(data->prior);
|
||||
matrix_type *Apr = matrix_alloc_column_compressed_copy(data->global_prior , data->ens_mask );
|
||||
|
||||
// fprintf(stdout,"\n");
|
||||
// fprintf(stdout,"A: %d x %d\n", matrix_get_rows(A), matrix_get_columns(A));
|
||||
// fprintf(stdout,"prior : %d x %d\n", matrix_get_rows(data->prior), matrix_get_columns(data->prior));
|
||||
// fprintf(stdout,"state : %d x %d\n", matrix_get_rows(data->state), matrix_get_columns(data->state));
|
||||
// fprintf(stdout,"prior : %d x %d\n", matrix_get_rows(data->global_prior), matrix_get_columns(data->global_prior));
|
||||
// fprintf(stdout,"state : %d x %d\n", matrix_get_rows(data->previous_state), matrix_get_columns(data->previous_state));
|
||||
// fprintf(stdout,"Apr : %d x %d\n", matrix_get_rows(Apr), matrix_get_columns(Apr));
|
||||
// fprintf(stdout,"Am : %d x %d\n", matrix_get_rows(Am), matrix_get_columns(Am));
|
||||
// Example:
|
||||
@@ -508,7 +400,7 @@ void rml_enkf_init2__( rml_enkf_data_type * data, matrix_type *A, double * Wdr,
|
||||
|
||||
|
||||
int nsign1 = matrix_get_columns(data->Am);
|
||||
|
||||
|
||||
|
||||
matrix_type * X4 = matrix_alloc(nsign1,ens_size);
|
||||
matrix_type * X5 = matrix_alloc(state_size,ens_size);
|
||||
@@ -516,13 +408,15 @@ void rml_enkf_init2__( rml_enkf_data_type * data, matrix_type *A, double * Wdr,
|
||||
matrix_type * X7 = matrix_alloc(ens_size,ens_size);
|
||||
matrix_type * dA2 = matrix_alloc(state_size , ens_size);
|
||||
matrix_type * Dk1 = matrix_alloc_copy( A );
|
||||
|
||||
|
||||
// Dk = Csc^(-1) * (A - Aprior)
|
||||
// X4 = Am' * Dk
|
||||
{
|
||||
matrix_type * Dk = matrix_alloc_copy( A );
|
||||
matrix_inplace_sub(Dk, Apr);
|
||||
|
||||
matrix_inplace_sub( Dk , Apr );
|
||||
rml_enkf_common_scaleA(Dk , data->Csc , true);
|
||||
|
||||
matrix_dgemm(X4 , Am , Dk , true, false, 1.0, 0.0);
|
||||
matrix_free(Dk);
|
||||
}
|
||||
@@ -536,10 +430,10 @@ void rml_enkf_init2__( rml_enkf_data_type * data, matrix_type *A, double * Wdr,
|
||||
|
||||
// X6 = Dk1' * X5
|
||||
matrix_dgemm(X6, Dk1, X5, true, false, 1.0, 0.0);
|
||||
|
||||
|
||||
// X7
|
||||
enkf_linalg_rml_enkfX7(X7, VdTr , Wdr , data->lambda + 1, X6);
|
||||
|
||||
|
||||
// delta m_2
|
||||
rml_enkf_common_scaleA(Dk1 , data->Csc , false);
|
||||
matrix_matmul(dA2 , Dk1 , X7);
|
||||
@@ -547,7 +441,7 @@ void rml_enkf_init2__( rml_enkf_data_type * data, matrix_type *A, double * Wdr,
|
||||
|
||||
matrix_free(Am);
|
||||
matrix_free(Apr);
|
||||
matrix_free(X4);
|
||||
matrix_free(X4);
|
||||
matrix_free(X5);
|
||||
matrix_free(X6);
|
||||
matrix_free(X7);
|
||||
@@ -557,39 +451,45 @@ void rml_enkf_init2__( rml_enkf_data_type * data, matrix_type *A, double * Wdr,
|
||||
|
||||
// Initialize state and prior from A. Initialize lambda0, lambda. Call initA__, init1__
|
||||
static void rml_enkf_updateA_iter0(rml_enkf_data_type * data, matrix_type * A, matrix_type * S, matrix_type * R, matrix_type * dObs, matrix_type * E, matrix_type * D, matrix_type * Cd) {
|
||||
|
||||
|
||||
int ens_size = matrix_get_columns( S );
|
||||
int nrobs = matrix_get_rows( S );
|
||||
int nrmin = util_int_min( ens_size , nrobs);
|
||||
int nrmin = util_int_min( ens_size , nrobs);
|
||||
int state_size = matrix_get_rows( A );
|
||||
matrix_type * Skm = matrix_alloc(ens_size, ens_size); // Mismatch
|
||||
matrix_type * Ud = matrix_alloc( nrobs , nrmin ); /* Left singular vectors. */
|
||||
matrix_type * VdT = matrix_alloc( nrmin , ens_size ); /* Right singular vectors. */
|
||||
double * Wd = util_calloc( nrmin , sizeof * Wd );
|
||||
double * Wd = util_calloc( nrmin , sizeof * Wd );
|
||||
|
||||
data->Csc = util_calloc(state_size , sizeof * data->Csc);
|
||||
data->Sk = enkf_linalg_data_mismatch(D,Cd,Skm);
|
||||
data->Sk = enkf_linalg_data_mismatch(D,Cd,Skm);
|
||||
data->Std = matrix_diag_std(Skm,data->Sk);
|
||||
|
||||
if (data->lambda0 < 0)
|
||||
data->lambda = pow(10 , floor(log10(data->Sk/(2*nrobs))) );
|
||||
else
|
||||
data->lambda = data->lambda0;
|
||||
|
||||
// state = A, prior = A
|
||||
rml_enkf_common_store_state( data->state , A , data->ens_mask );
|
||||
rml_enkf_common_recover_state( A , data->prior , data->ens_mask );
|
||||
|
||||
{
|
||||
double lambda0 = rml_enkf_config_get_lambda0( data->config );
|
||||
if (lambda0 < 0)
|
||||
data->lambda = pow(10 , floor(log10(data->Sk/(2*nrobs))) );
|
||||
else
|
||||
data->lambda = lambda0;
|
||||
}
|
||||
|
||||
|
||||
// state = A
|
||||
rml_enkf_common_store_state( data->previous_state , A , data->ens_mask );
|
||||
|
||||
// prior = A
|
||||
data->global_prior = matrix_alloc_copy( data->previous_state );
|
||||
|
||||
// Update dependant on data mismatch
|
||||
rml_enkf_initA__(data , A, S , Cd , E , D , Ud , Wd , VdT);
|
||||
// Update dependant on prior mismatch. This should be zero (coz iter0).
|
||||
// Therefore the purpose of init1__ is just to prepare some matrices.
|
||||
if (data->use_prior) {
|
||||
if (rml_enkf_config_get_use_prior(data->config)) {
|
||||
rml_enkf_init_Csc( data );
|
||||
rml_enkf_init1__(data );
|
||||
rml_enkf_init1__( data );
|
||||
}
|
||||
|
||||
rml_enkf_write_iter_info(data, data->Sk, data->Std);
|
||||
rml_enkf_write_iter_info(data, data->Sk , data->Sk, data->Std);
|
||||
|
||||
matrix_free( Skm );
|
||||
matrix_free( Ud );
|
||||
@@ -597,7 +497,7 @@ static void rml_enkf_updateA_iter0(rml_enkf_data_type * data, matrix_type * A, m
|
||||
free( Wd );
|
||||
}
|
||||
|
||||
// Main routine. Controls the iterations. Called from analysis_module.c: analysis_module_updateA()
|
||||
|
||||
void rml_enkf_updateA(void * module_data, matrix_type * A, matrix_type * S, matrix_type * R, matrix_type * dObs, matrix_type * E, matrix_type * D) {
|
||||
// A : ensemble matrix
|
||||
// R : (Inv?) Obs error cov.
|
||||
@@ -616,12 +516,12 @@ void rml_enkf_updateA(void * module_data, matrix_type * A, matrix_type * S, matr
|
||||
double nsc = 1/sqrt(ens_size-1); // Scale factor
|
||||
matrix_type * Cd = matrix_alloc( nrobs, nrobs ); // Cov(E), where E = measurement perturbations?
|
||||
|
||||
|
||||
// Empirical error covar. R is left unused. Investigate?
|
||||
|
||||
// Empirical error covar. R is left unused. Investigate?
|
||||
enkf_linalg_Covariance(Cd ,E ,nsc, nrobs); // Cd = SampCov(E) (including (N-1) normalization)
|
||||
matrix_inv(Cd); // In-place inversion
|
||||
|
||||
rml_enkf_open_log_file(data);
|
||||
rml_enkf_log_open(data->rml_log , data->iteration_nr);
|
||||
fprintf(stdout,"\nIter %d --> %d", data->iteration_nr, data->iteration_nr + 1);
|
||||
|
||||
|
||||
@@ -641,9 +541,9 @@ void rml_enkf_updateA(void * module_data, matrix_type * A, matrix_type * S, matr
|
||||
|
||||
|
||||
// Lambda = Normalized data mismatch (rounded)
|
||||
if (data->lambda_recalculate)
|
||||
if (rml_enkf_config_get_lambda_recalculate( data->config ))
|
||||
data->lambda = pow(10 , floor(log10(Sk_new / (2*nrobs))) );
|
||||
|
||||
|
||||
// Accept/Reject update? Lambda calculation.
|
||||
{
|
||||
bool mismatch_reduced = false;
|
||||
@@ -651,65 +551,70 @@ void rml_enkf_updateA(void * module_data, matrix_type * A, matrix_type * S, matr
|
||||
|
||||
if (Sk_new < data->Sk)
|
||||
mismatch_reduced = true;
|
||||
|
||||
|
||||
if (Std_new <= data->Std)
|
||||
std_reduced = true;
|
||||
|
||||
fprintf(stdout,"\nWriting iter info to file now. Iter %d --> %d", data->iteration_nr, data->iteration_nr + 1);
|
||||
rml_enkf_write_iter_info(data, Sk_new, Std_new);
|
||||
rml_enkf_write_iter_info(data, data->Sk , Sk_new, Std_new);
|
||||
|
||||
if (mismatch_reduced) {
|
||||
/*
|
||||
Stop check: if ( (1- (Sk_new/data->Sk)) < .0001) // check convergence ** model change norm has to be added in this!!
|
||||
*/
|
||||
|
||||
|
||||
// Reduce Lambda
|
||||
if (std_reduced)
|
||||
data->lambda = data->lambda * data->lambda_reduce_factor;
|
||||
|
||||
rml_enkf_common_store_state(data->state , A , data->ens_mask );
|
||||
if (std_reduced)
|
||||
data->lambda = data->lambda * rml_enkf_config_get_lambda_decrease_factor( data->config );
|
||||
|
||||
rml_enkf_common_store_state(data->previous_state , A , data->ens_mask );
|
||||
|
||||
data->Sk = Sk_new;
|
||||
data->Std=Std_new;
|
||||
data->iteration_nr++;
|
||||
} else {
|
||||
// Increase lambda
|
||||
data->lambda = data->lambda * data->lambda_increase_factor;
|
||||
// A = data->state
|
||||
rml_enkf_common_recover_state( data->state , A , data->ens_mask );
|
||||
data->lambda = data->lambda * rml_enkf_config_get_lambda_increase_factor( data->config );
|
||||
// A = data->previous_state
|
||||
rml_enkf_common_recover_state( data->previous_state , A , data->ens_mask );
|
||||
}
|
||||
}
|
||||
|
||||
// Update dependant on data mismatch (delta m_1)
|
||||
rml_enkf_initA__(data , A , S , Cd , E , D , Ud , Wd , VdT);
|
||||
|
||||
// Update dependant on prior mismatch (delta m_2)
|
||||
if (data->use_prior) {
|
||||
if (rml_enkf_config_get_use_prior(data->config)) {
|
||||
rml_enkf_init_Csc( data );
|
||||
rml_enkf_init2__(data , A , Wd , VdT);
|
||||
}
|
||||
|
||||
|
||||
// Free
|
||||
matrix_free(Skm);
|
||||
matrix_free( Ud );
|
||||
matrix_free( VdT );
|
||||
free( Wd );
|
||||
}
|
||||
|
||||
if (data->lambda < data->lambda_min)
|
||||
data->lambda = data->lambda_min;
|
||||
|
||||
{
|
||||
double lambda_min = rml_enkf_config_get_lambda_min( data->config );
|
||||
if (data->lambda < lambda_min)
|
||||
data->lambda = lambda_min;
|
||||
}
|
||||
|
||||
|
||||
if (data->log_stream)
|
||||
fclose( data->log_stream );
|
||||
|
||||
rml_enkf_log_close( data->rml_log );
|
||||
matrix_free(Cd);
|
||||
}
|
||||
|
||||
// Called from analysis_module.c: analysis_module_init_update()
|
||||
void rml_enkf_init_update(void * arg, const bool_vector_type * ens_mask, const matrix_type * S, const matrix_type * R, const matrix_type * dObs, const matrix_type * E, const matrix_type * D ) {
|
||||
|
||||
|
||||
|
||||
void rml_enkf_init_update(void * arg, const bool_vector_type * ens_mask, const matrix_type * S, const matrix_type * R, const matrix_type * dObs, const matrix_type * E, const matrix_type * D ) {
|
||||
rml_enkf_data_type * module_data = rml_enkf_data_safe_cast( arg );
|
||||
bool_vector_memcpy( module_data->ens_mask , ens_mask );
|
||||
|
||||
if (module_data->ens_mask)
|
||||
bool_vector_free( module_data->ens_mask );
|
||||
|
||||
module_data->ens_mask = bool_vector_alloc_copy( ens_mask );
|
||||
}
|
||||
|
||||
|
||||
@@ -717,6 +622,7 @@ void rml_enkf_init_update(void * arg, const bool_vector_type * ens_mask, const m
|
||||
|
||||
|
||||
|
||||
|
||||
//**********************************************
|
||||
// Set / Get basic types
|
||||
//**********************************************
|
||||
@@ -724,9 +630,9 @@ bool rml_enkf_set_int( void * arg , const char * var_name , int value) {
|
||||
rml_enkf_data_type * module_data = rml_enkf_data_safe_cast( arg );
|
||||
{
|
||||
bool name_recognized = true;
|
||||
|
||||
|
||||
if (strcmp( var_name , ENKF_NCOMP_KEY_) == 0)
|
||||
rml_enkf_set_subspace_dimension( module_data , value );
|
||||
rml_enkf_config_set_subspace_dimension(module_data->config , value);
|
||||
else if (strcmp( var_name , ITER_KEY) == 0)
|
||||
rml_enkf_set_iteration_nr( module_data , value );
|
||||
else
|
||||
@@ -750,13 +656,13 @@ bool rml_enkf_set_bool( void * arg , const char * var_name , bool value) {
|
||||
rml_enkf_data_type * module_data = rml_enkf_data_safe_cast( arg );
|
||||
{
|
||||
bool name_recognized = true;
|
||||
|
||||
|
||||
if (strcmp( var_name , USE_PRIOR_KEY) == 0)
|
||||
rml_enkf_set_use_prior( module_data , value );
|
||||
rml_enkf_config_set_use_prior( module_data->config , value);
|
||||
else if (strcmp( var_name , CLEAR_LOG_KEY) == 0)
|
||||
rml_enkf_set_clear_log( module_data , value );
|
||||
rml_enkf_log_set_clear_log( module_data->rml_log , value );
|
||||
else if (strcmp( var_name , LAMBDA_RECALCULATE_KEY) == 0)
|
||||
rml_enkf_set_lambda_recalculate( module_data , value );
|
||||
rml_enkf_config_set_lambda_recalculate( module_data->config , value );
|
||||
else
|
||||
name_recognized = false;
|
||||
|
||||
@@ -768,11 +674,11 @@ bool rml_enkf_get_bool( const void * arg, const char * var_name) {
|
||||
const rml_enkf_data_type * module_data = rml_enkf_data_safe_cast_const( arg );
|
||||
{
|
||||
if (strcmp(var_name , USE_PRIOR_KEY) == 0)
|
||||
return module_data->use_prior;
|
||||
else if (strcmp(var_name , CLEAR_LOG_KEY) == 0)
|
||||
return module_data->clear_log;
|
||||
else if (strcmp(var_name , LAMBDA_RECALCULATE_KEY) == 0)
|
||||
return module_data->lambda_recalculate;
|
||||
return rml_enkf_config_get_use_prior( module_data->config );
|
||||
else if (strcmp(var_name , CLEAR_LOG_KEY) == 0)
|
||||
return rml_enkf_log_get_clear_log( module_data->rml_log );
|
||||
else if (strcmp(var_name , LAMBDA_RECALCULATE_KEY) == 0)
|
||||
return rml_enkf_config_get_lambda_recalculate( module_data->config );
|
||||
else
|
||||
return false;
|
||||
}
|
||||
@@ -784,15 +690,15 @@ bool rml_enkf_set_double( void * arg , const char * var_name , double value) {
|
||||
bool name_recognized = true;
|
||||
|
||||
if (strcmp( var_name , ENKF_TRUNCATION_KEY_) == 0)
|
||||
rml_enkf_set_truncation( module_data , value );
|
||||
rml_enkf_config_set_truncation( module_data->config , value );
|
||||
else if (strcmp( var_name , LAMBDA_INCREASE_FACTOR_KEY) == 0)
|
||||
rml_enkf_set_lambda_increase_factor( module_data , value );
|
||||
rml_enkf_config_set_lambda_increase_factor( module_data->config , value );
|
||||
else if (strcmp( var_name , LAMBDA_REDUCE_FACTOR_KEY) == 0)
|
||||
rml_enkf_set_lambda_reduce_factor( module_data , value );
|
||||
rml_enkf_config_set_lambda_decrease_factor( module_data->config , value );
|
||||
else if (strcmp( var_name , LAMBDA0_KEY) == 0)
|
||||
rml_enkf_set_lambda0( module_data , value );
|
||||
rml_enkf_config_set_lambda0( module_data->config , value );
|
||||
else if (strcmp( var_name , LAMBDA_MIN_KEY) == 0)
|
||||
rml_enkf_set_lambda_min( module_data , value );
|
||||
rml_enkf_config_set_lambda_min( module_data->config , value );
|
||||
else
|
||||
name_recognized = false;
|
||||
|
||||
@@ -804,17 +710,21 @@ double rml_enkf_get_double( const void * arg, const char * var_name) {
|
||||
const rml_enkf_data_type * module_data = rml_enkf_data_safe_cast_const( arg );
|
||||
{
|
||||
if (strcmp(var_name , LAMBDA_REDUCE_FACTOR_KEY) == 0)
|
||||
return module_data->lambda_reduce_factor;
|
||||
return rml_enkf_config_get_lambda_decrease_factor(module_data->config);
|
||||
|
||||
if (strcmp(var_name , LAMBDA_INCREASE_FACTOR_KEY) == 0)
|
||||
return module_data->lambda_increase_factor;
|
||||
return rml_enkf_config_get_lambda_increase_factor(module_data->config);
|
||||
|
||||
if (strcmp(var_name , LAMBDA0_KEY) == 0)
|
||||
return module_data->lambda0;
|
||||
return rml_enkf_config_get_lambda0(module_data->config);
|
||||
|
||||
if (strcmp(var_name , LAMBDA_MIN_KEY) == 0)
|
||||
return module_data->lambda_min;
|
||||
return rml_enkf_config_get_lambda_min(module_data->config);
|
||||
|
||||
if (strcmp(var_name , ENKF_TRUNCATION_KEY_) == 0)
|
||||
return module_data->truncation;
|
||||
else
|
||||
return -1;
|
||||
return rml_enkf_config_get_truncation( module_data->config );
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -823,9 +733,9 @@ bool rml_enkf_set_string( void * arg , const char * var_name , const char * valu
|
||||
rml_enkf_data_type * module_data = rml_enkf_data_safe_cast( arg );
|
||||
{
|
||||
bool name_recognized = true;
|
||||
|
||||
|
||||
if (strcmp( var_name , LOG_FILE_KEY) == 0)
|
||||
rml_enkf_set_log_file( module_data , value );
|
||||
rml_enkf_log_set_log_file( module_data->rml_log , value );
|
||||
else
|
||||
name_recognized = false;
|
||||
|
||||
@@ -836,7 +746,7 @@ bool rml_enkf_set_string( void * arg , const char * var_name , const char * valu
|
||||
long rml_enkf_get_options( void * arg , long flag ) {
|
||||
rml_enkf_data_type * module_data = rml_enkf_data_safe_cast( arg );
|
||||
{
|
||||
return module_data->option_flags;
|
||||
return rml_enkf_config_get_option_flags( module_data->config );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -871,7 +781,7 @@ void * rml_enkf_get_ptr( const void * arg , const char * var_name ) {
|
||||
const rml_enkf_data_type * module_data = rml_enkf_data_safe_cast_const( arg );
|
||||
{
|
||||
if (strcmp(var_name , LOG_FILE_KEY) == 0)
|
||||
return module_data->log_file;
|
||||
return (void *) rml_enkf_log_get_log_file( module_data->rml_log );
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
@@ -895,13 +805,13 @@ void * rml_enkf_get_ptr( const void * arg , const char * var_name ) {
|
||||
analysis_table_type SYMBOL_TABLE = {
|
||||
.alloc = rml_enkf_data_alloc,
|
||||
.freef = rml_enkf_data_free,
|
||||
.set_int = rml_enkf_set_int ,
|
||||
.set_double = rml_enkf_set_double ,
|
||||
.set_bool = rml_enkf_set_bool,
|
||||
.set_int = rml_enkf_set_int ,
|
||||
.set_double = rml_enkf_set_double ,
|
||||
.set_bool = rml_enkf_set_bool,
|
||||
.set_string = rml_enkf_set_string,
|
||||
.get_options = rml_enkf_get_options ,
|
||||
.get_options = rml_enkf_get_options ,
|
||||
.initX = NULL,
|
||||
.updateA = rml_enkf_updateA ,
|
||||
.updateA = rml_enkf_updateA ,
|
||||
.init_update = rml_enkf_init_update ,
|
||||
.complete_update = NULL,
|
||||
.has_var = rml_enkf_has_var,
|
||||
|
||||
+18
-18
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'rml_enkf.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'rml_enkf.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -38,7 +38,7 @@
|
||||
// zzz_enkf_common_recover_state(state , A ,ens_mask) assigns state to A. RESIZES A to rows(state)-by-SUM(ens_mask)
|
||||
|
||||
|
||||
void rml_enkf_common_store_state( matrix_type * state , const matrix_type * A , const bool_vector_type * ens_mask ) {
|
||||
void rml_enkf_common_store_state( matrix_type * state , const matrix_type * A , const bool_vector_type * ens_mask ) {
|
||||
matrix_resize( state , matrix_get_rows( A ) , bool_vector_size( ens_mask ) , false);
|
||||
{
|
||||
const int ens_size = bool_vector_size( ens_mask );
|
||||
@@ -55,11 +55,11 @@ void rml_enkf_common_store_state( matrix_type * state , const matrix_type * A ,
|
||||
|
||||
|
||||
|
||||
void rml_enkf_common_recover_state( const matrix_type * state , matrix_type * A , const bool_vector_type * ens_mask ) {
|
||||
void rml_enkf_common_recover_state( const matrix_type * state , matrix_type * A , const bool_vector_type * ens_mask ) {
|
||||
const int ens_size = bool_vector_size( ens_mask );
|
||||
const int active_size = bool_vector_count_equal( ens_mask , true );
|
||||
const int rows = matrix_get_rows( state );
|
||||
|
||||
|
||||
matrix_resize( A , rows , active_size , false );
|
||||
{
|
||||
int active_index = 0;
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
Copyright (C) 2015 Statoil ASA, Norway.
|
||||
|
||||
The file 'rml_enkf_config.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include <ert/util/util.h>
|
||||
#include <ert/util/type_macros.h>
|
||||
|
||||
#include <ert/analysis/std_enkf.h>
|
||||
#include <ert/analysis/analysis_module.h>
|
||||
|
||||
#include <rml_enkf_config.h>
|
||||
|
||||
|
||||
#define INVALID_SUBSPACE_DIMENSION -1
|
||||
#define INVALID_TRUNCATION -1
|
||||
|
||||
#define DEFAULT_SUBSPACE_DIMENSION INVALID_SUBSPACE_DIMENSION
|
||||
#define DEFAULT_USE_PRIOR true
|
||||
|
||||
#define DEFAULT_LAMBDA_INCREASE_FACTOR 4
|
||||
#define DEFAULT_LAMBDA_REDUCE_FACTOR 0.1
|
||||
#define DEFAULT_LAMBDA0 -1
|
||||
#define DEFAULT_LAMBDA_MIN 0.01
|
||||
#define DEFAULT_LAMBDA_RECALCULATE false
|
||||
|
||||
|
||||
|
||||
#define RML_ENKF_CONFIG_TYPE_ID 61400061
|
||||
|
||||
struct rml_enkf_config_struct {
|
||||
UTIL_TYPE_ID_DECLARATION;
|
||||
double truncation; // Controlled by config key: ENKF_TRUNCATION_KEY
|
||||
int subspace_dimension; // Controlled by config key: ENKF_NCOMP_KEY (-1: use Truncation instead)
|
||||
long option_flags;
|
||||
bool use_prior; // Use exact/approximate scheme? Approximate scheme drops the "prior" term in the LM step.
|
||||
|
||||
|
||||
double lambda0;
|
||||
double lambda_min;
|
||||
double lambda_decrease_factor;
|
||||
double lambda_increase_factor;
|
||||
bool lambda_recalculate;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
rml_enkf_config_type * rml_enkf_config_alloc() {
|
||||
rml_enkf_config_type * config = util_malloc( sizeof * config );
|
||||
UTIL_TYPE_ID_INIT( config , RML_ENKF_CONFIG_TYPE_ID );
|
||||
|
||||
rml_enkf_config_set_truncation( config , DEFAULT_ENKF_TRUNCATION_);
|
||||
rml_enkf_config_set_subspace_dimension( config , DEFAULT_SUBSPACE_DIMENSION);
|
||||
rml_enkf_config_set_use_prior( config , DEFAULT_USE_PRIOR );
|
||||
rml_enkf_config_set_option_flags( config , ANALYSIS_NEED_ED + ANALYSIS_UPDATE_A + ANALYSIS_ITERABLE + ANALYSIS_SCALE_DATA);
|
||||
|
||||
rml_enkf_config_set_lambda_min( config , DEFAULT_LAMBDA_MIN );
|
||||
rml_enkf_config_set_lambda0( config , DEFAULT_LAMBDA0 );
|
||||
rml_enkf_config_set_lambda_decrease_factor( config , DEFAULT_LAMBDA_REDUCE_FACTOR );
|
||||
rml_enkf_config_set_lambda_increase_factor( config , DEFAULT_LAMBDA_INCREASE_FACTOR );
|
||||
rml_enkf_config_set_lambda_recalculate( config , DEFAULT_LAMBDA_RECALCULATE );
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
bool rml_enkf_config_get_use_prior( const rml_enkf_config_type * config ) {
|
||||
return config->use_prior;
|
||||
}
|
||||
|
||||
void rml_enkf_config_set_use_prior( rml_enkf_config_type * config , bool use_prior) {
|
||||
config->use_prior = use_prior;
|
||||
}
|
||||
|
||||
|
||||
double rml_enkf_config_get_truncation( rml_enkf_config_type * config ) {
|
||||
return config->truncation;
|
||||
}
|
||||
|
||||
void rml_enkf_config_set_truncation( rml_enkf_config_type * config , double truncation) {
|
||||
config->truncation = truncation;
|
||||
if (truncation > 0.0)
|
||||
config->subspace_dimension = INVALID_SUBSPACE_DIMENSION;
|
||||
}
|
||||
|
||||
int rml_enkf_config_get_subspace_dimension( rml_enkf_config_type * config ) {
|
||||
return config->subspace_dimension;
|
||||
}
|
||||
|
||||
void rml_enkf_config_set_subspace_dimension( rml_enkf_config_type * config , int subspace_dimension) {
|
||||
config->subspace_dimension = subspace_dimension;
|
||||
if (subspace_dimension > 0)
|
||||
config->truncation = INVALID_TRUNCATION;
|
||||
}
|
||||
|
||||
void rml_enkf_config_set_option_flags( rml_enkf_config_type * config , long flags) {
|
||||
config->option_flags = flags;
|
||||
}
|
||||
|
||||
long rml_enkf_config_get_option_flags( const rml_enkf_config_type * config ) {
|
||||
return config->option_flags;
|
||||
}
|
||||
|
||||
double rml_enkf_config_get_lambda0( rml_enkf_config_type * config ) {
|
||||
return config->lambda0;
|
||||
}
|
||||
|
||||
void rml_enkf_config_set_lambda0( rml_enkf_config_type * config , double lambda0) {
|
||||
config->lambda0 = lambda0;
|
||||
}
|
||||
|
||||
|
||||
double rml_enkf_config_get_lambda_min( rml_enkf_config_type * config ) {
|
||||
return config->lambda_min;
|
||||
}
|
||||
|
||||
void rml_enkf_config_set_lambda_min( rml_enkf_config_type * config , double lambda_min) {
|
||||
config->lambda_min = lambda_min;
|
||||
}
|
||||
|
||||
|
||||
double rml_enkf_config_get_lambda_increase_factor( rml_enkf_config_type * config ) {
|
||||
return config->lambda_increase_factor;
|
||||
}
|
||||
|
||||
void rml_enkf_config_set_lambda_increase_factor( rml_enkf_config_type * config , double lambda_increase_factor) {
|
||||
config->lambda_increase_factor = lambda_increase_factor;
|
||||
}
|
||||
|
||||
double rml_enkf_config_get_lambda_decrease_factor( rml_enkf_config_type * config ) {
|
||||
return config->lambda_decrease_factor;
|
||||
}
|
||||
|
||||
void rml_enkf_config_set_lambda_decrease_factor( rml_enkf_config_type * config , double lambda_decrease_factor) {
|
||||
config->lambda_decrease_factor = lambda_decrease_factor;
|
||||
}
|
||||
|
||||
|
||||
bool rml_enkf_config_get_lambda_recalculate( const rml_enkf_config_type * config ) {
|
||||
return config->lambda_recalculate;
|
||||
}
|
||||
|
||||
void rml_enkf_config_set_lambda_recalculate( rml_enkf_config_type * config , bool lambda_recalculate) {
|
||||
config->lambda_recalculate = lambda_recalculate;
|
||||
}
|
||||
|
||||
|
||||
void rml_enkf_config_free(rml_enkf_config_type * config) {
|
||||
free( config );
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright (C) 2015 Statoil ASA, Norway.
|
||||
|
||||
The file 'rml_enkf_config.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#ifndef RML_ENKF_CONFIG_H
|
||||
#define RML_ENKF_CONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct rml_enkf_config_struct rml_enkf_config_type;
|
||||
|
||||
|
||||
rml_enkf_config_type * rml_enkf_config_alloc();
|
||||
void rml_enkf_config_free(rml_enkf_config_type * config);
|
||||
|
||||
int rml_enkf_config_get_subspace_dimension( rml_enkf_config_type * config );
|
||||
void rml_enkf_config_set_subspace_dimension( rml_enkf_config_type * config , int subspace_dimension);
|
||||
|
||||
double rml_enkf_config_get_truncation( rml_enkf_config_type * config );
|
||||
void rml_enkf_config_set_truncation( rml_enkf_config_type * config , double truncation);
|
||||
|
||||
bool rml_enkf_config_get_use_prior( const rml_enkf_config_type * config );
|
||||
void rml_enkf_config_set_use_prior( rml_enkf_config_type * config , bool use_prior);
|
||||
|
||||
void rml_enkf_config_set_option_flags( rml_enkf_config_type * config , long flags);
|
||||
long rml_enkf_config_get_option_flags( const rml_enkf_config_type * config );
|
||||
|
||||
double rml_enkf_config_get_lambda0( rml_enkf_config_type * config );
|
||||
void rml_enkf_config_set_lambda0( rml_enkf_config_type * config , double lambda0);
|
||||
|
||||
double rml_enkf_config_get_lambda_min( rml_enkf_config_type * config );
|
||||
void rml_enkf_config_set_lambda_min( rml_enkf_config_type * config , double lambda_min);
|
||||
|
||||
double rml_enkf_config_get_lambda_increase_factor( rml_enkf_config_type * config );
|
||||
void rml_enkf_config_set_lambda_increase_factor( rml_enkf_config_type * config , double lambda_increase_factor);
|
||||
|
||||
double rml_enkf_config_get_lambda_decrease_factor( rml_enkf_config_type * config );
|
||||
void rml_enkf_config_set_lambda_decrease_factor( rml_enkf_config_type * config , double lambda_decrease_factor);
|
||||
|
||||
bool rml_enkf_config_get_lambda_recalculate( const rml_enkf_config_type * config );
|
||||
void rml_enkf_config_set_lambda_recalculate( rml_enkf_config_type * config , bool lambda_recalculate);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright (C) 2015 Statoil ASA, Norway.
|
||||
|
||||
The file 'rml_enkf_log.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#ifndef RML_ENKF_LOG_H
|
||||
#define RML_ENKF_LOG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct rml_enkf_log_struct rml_enkf_log_type;
|
||||
|
||||
rml_enkf_log_type * rml_enkf_log_alloc();
|
||||
void rml_enkf_log_free(rml_enkf_log_type * rml_log);
|
||||
bool rml_enkf_log_get_clear_log( const rml_enkf_log_type * data );
|
||||
void rml_enkf_log_set_clear_log( rml_enkf_log_type * data , bool clear_log);
|
||||
void rml_enkf_log_set_log_file( rml_enkf_log_type * data , const char * log_file );
|
||||
const char * rml_enkf_log_get_log_file( const rml_enkf_log_type * data);
|
||||
void rml_enkf_log_open( rml_enkf_log_type * rml_log , int iteration_nr );
|
||||
void rml_enkf_log_close( rml_enkf_log_type * rml_log );
|
||||
void rml_enkf_log_line( rml_enkf_log_type * rml_log , const char * fmt , ...);
|
||||
bool rml_enkf_log_is_open( const rml_enkf_log_type * rml_log );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+74
-74
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'analysis_module.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'analysis_module.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -36,7 +36,7 @@ struct analysis_module_struct {
|
||||
UTIL_TYPE_ID_DECLARATION;
|
||||
void * lib_handle;
|
||||
void * module_data;
|
||||
char * symbol_table;
|
||||
char * symbol_table;
|
||||
char * lib_name;
|
||||
|
||||
analysis_free_ftype * freef;
|
||||
@@ -49,17 +49,17 @@ struct analysis_module_struct {
|
||||
analysis_get_options_ftype * get_options;
|
||||
analysis_set_int_ftype * set_int;
|
||||
analysis_set_double_ftype * set_double;
|
||||
analysis_set_bool_ftype * set_bool;
|
||||
analysis_set_bool_ftype * set_bool;
|
||||
analysis_set_string_ftype * set_string;
|
||||
|
||||
|
||||
analysis_has_var_ftype * has_var;
|
||||
analysis_get_int_ftype * get_int;
|
||||
analysis_get_double_ftype * get_double;
|
||||
analysis_get_bool_ftype * get_bool;
|
||||
analysis_get_ptr_ftype * get_ptr;
|
||||
|
||||
bool internal;
|
||||
char * user_name; /* String used to identify this module for the user; not used in
|
||||
|
||||
bool internal;
|
||||
char * user_name; /* String used to identify this module for the user; not used in
|
||||
the linking process. */
|
||||
};
|
||||
|
||||
@@ -99,15 +99,15 @@ static bool analysis_module_internal_check( analysis_module_type * module ) {
|
||||
}
|
||||
|
||||
|
||||
static analysis_module_type * analysis_module_alloc__( rng_type * rng ,
|
||||
const analysis_table_type * table ,
|
||||
const char * symbol_table ,
|
||||
const char * lib_name ,
|
||||
const char * user_name ,
|
||||
static analysis_module_type * analysis_module_alloc__( rng_type * rng ,
|
||||
const analysis_table_type * table ,
|
||||
const char * symbol_table ,
|
||||
const char * lib_name ,
|
||||
const char * user_name ,
|
||||
void * lib_handle ) {
|
||||
|
||||
analysis_module_type * module = analysis_module_alloc_empty( user_name , symbol_table , lib_name );
|
||||
|
||||
|
||||
module->lib_handle = lib_handle;
|
||||
module->initX = table->initX;
|
||||
module->updateA = table->updateA;
|
||||
@@ -119,7 +119,7 @@ static analysis_module_type * analysis_module_alloc__( rng_type * rng ,
|
||||
module->set_bool = table->set_bool;
|
||||
module->alloc = table->alloc;
|
||||
module->freef = table->freef;
|
||||
module->get_options = table->get_options;
|
||||
module->get_options = table->get_options;
|
||||
module->has_var = table->has_var;
|
||||
module->get_int = table->get_int;
|
||||
module->get_double = table->get_double;
|
||||
@@ -142,11 +142,11 @@ static analysis_module_type * analysis_module_alloc__( rng_type * rng ,
|
||||
|
||||
|
||||
|
||||
static analysis_module_type * analysis_module_alloc( rng_type * rng ,
|
||||
const char * user_name ,
|
||||
const char * libname ,
|
||||
static analysis_module_type * analysis_module_alloc( rng_type * rng ,
|
||||
const char * user_name ,
|
||||
const char * libname ,
|
||||
const char * table_name ,
|
||||
bool verbose,
|
||||
bool verbose,
|
||||
analysis_module_load_status_enum * load_status) {
|
||||
analysis_module_type * module = NULL;
|
||||
void * lib_handle = dlopen( libname , RTLD_NOW );
|
||||
@@ -160,15 +160,15 @@ static analysis_module_type * analysis_module_alloc( rng_type * rng ,
|
||||
if (verbose)
|
||||
fprintf(stderr , "Failed to load symbol table:%s Error:%s \n",table_name , dlerror());
|
||||
}
|
||||
|
||||
if (module == NULL)
|
||||
|
||||
if (module == NULL)
|
||||
dlclose( lib_handle );
|
||||
} else {
|
||||
*load_status = DLOPEN_FAILURE;
|
||||
if (verbose)
|
||||
fprintf(stderr , "Failed to load library:%s Error:%s \n",libname , dlerror());
|
||||
}
|
||||
|
||||
|
||||
if (module != NULL) {
|
||||
if (libname == NULL)
|
||||
module->internal = true;
|
||||
@@ -226,7 +226,7 @@ UTIL_IS_INSTANCE_FUNCTION( analysis_module , ANALYSIS_MODULE_TYPE_ID )
|
||||
void analysis_module_free( analysis_module_type * module ) {
|
||||
if (module->freef != NULL)
|
||||
module->freef( module->module_data );
|
||||
|
||||
|
||||
util_safe_free( module->lib_name );
|
||||
free( module->user_name );
|
||||
free( module->symbol_table );
|
||||
@@ -244,26 +244,26 @@ void analysis_module_free__( void * arg) {
|
||||
/* Update functions */
|
||||
|
||||
|
||||
void analysis_module_initX(analysis_module_type * module ,
|
||||
matrix_type * X ,
|
||||
matrix_type * A ,
|
||||
matrix_type * S ,
|
||||
matrix_type * R ,
|
||||
matrix_type * dObs ,
|
||||
matrix_type * E ,
|
||||
void analysis_module_initX(analysis_module_type * module ,
|
||||
matrix_type * X ,
|
||||
matrix_type * A ,
|
||||
matrix_type * S ,
|
||||
matrix_type * R ,
|
||||
matrix_type * dObs ,
|
||||
matrix_type * E ,
|
||||
matrix_type * D ) {
|
||||
|
||||
|
||||
|
||||
module->initX(module->module_data , X , A , S , R , dObs , E , D );
|
||||
}
|
||||
|
||||
|
||||
void analysis_module_updateA(analysis_module_type * module ,
|
||||
matrix_type * A ,
|
||||
matrix_type * S ,
|
||||
matrix_type * R ,
|
||||
matrix_type * dObs ,
|
||||
matrix_type * E ,
|
||||
void analysis_module_updateA(analysis_module_type * module ,
|
||||
matrix_type * A ,
|
||||
matrix_type * S ,
|
||||
matrix_type * R ,
|
||||
matrix_type * dObs ,
|
||||
matrix_type * E ,
|
||||
matrix_type * D ) {
|
||||
|
||||
module->updateA(module->module_data , A , S , R , dObs , E , D );
|
||||
@@ -272,12 +272,12 @@ void analysis_module_updateA(analysis_module_type * module ,
|
||||
|
||||
|
||||
|
||||
void analysis_module_init_update( analysis_module_type * module ,
|
||||
const bool_vector_type * ens_mask ,
|
||||
const matrix_type * S ,
|
||||
const matrix_type * R ,
|
||||
const matrix_type * dObs ,
|
||||
const matrix_type * E ,
|
||||
void analysis_module_init_update( analysis_module_type * module ,
|
||||
const bool_vector_type * ens_mask ,
|
||||
const matrix_type * S ,
|
||||
const matrix_type * R ,
|
||||
const matrix_type * dObs ,
|
||||
const matrix_type * E ,
|
||||
const matrix_type * D ) {
|
||||
if (module->init_update != NULL)
|
||||
module->init_update( module->module_data , ens_mask , S , R , dObs , E , D);
|
||||
@@ -296,7 +296,7 @@ void analysis_module_complete_update( analysis_module_type * module ) {
|
||||
|
||||
|
||||
static bool analysis_module_set_int(analysis_module_type * module , const char * flag , int value) {
|
||||
if (module->set_int != NULL)
|
||||
if (module->set_int != NULL)
|
||||
return module->set_int( module->module_data , flag , value );
|
||||
else
|
||||
return false;
|
||||
@@ -327,7 +327,7 @@ static bool analysis_module_set_string(analysis_module_type * module , const cha
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
The input value typically comes from the configuration system and
|
||||
is in terms of a string, irrespective of the fundamental type of
|
||||
the underlying parameter. The algorithm for setting the parameter
|
||||
@@ -346,38 +346,38 @@ bool analysis_module_set_var( analysis_module_type * module , const char * var_n
|
||||
bool set_ok = false;
|
||||
{
|
||||
int int_value;
|
||||
|
||||
if (util_sscanf_int( string_value , &int_value ))
|
||||
|
||||
if (util_sscanf_int( string_value , &int_value ))
|
||||
set_ok = analysis_module_set_int( module , var_name , int_value );
|
||||
|
||||
|
||||
|
||||
|
||||
if (set_ok)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
double double_value;
|
||||
if (util_sscanf_double( string_value , &double_value ))
|
||||
if (util_sscanf_double( string_value , &double_value ))
|
||||
set_ok = analysis_module_set_double( module , var_name , double_value );
|
||||
|
||||
|
||||
if (set_ok)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
bool bool_value;
|
||||
if (util_sscanf_bool( string_value , &bool_value))
|
||||
if (util_sscanf_bool( string_value , &bool_value))
|
||||
set_ok = analysis_module_set_bool( module , var_name , bool_value );
|
||||
|
||||
if (set_ok)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
set_ok = analysis_module_set_string( module , var_name , string_value );
|
||||
if (!set_ok)
|
||||
fprintf(stderr,"** Warning: failed to set %s=%s for analysis module:%s\n", var_name , string_value , module->user_name);
|
||||
|
||||
|
||||
return set_ok;
|
||||
}
|
||||
|
||||
@@ -404,7 +404,7 @@ int analysis_module_get_int( const analysis_module_type * module , const char *
|
||||
return module->get_int( module->module_data , var );
|
||||
else
|
||||
util_exit("%s: Tried to get integer variable:%s from module:%s - get_int() method not implemented for this module\n" , __func__ , var , module->user_name);
|
||||
} else
|
||||
} else
|
||||
util_exit("%s: Tried to get integer variable:%s from module:%s - module does not support this variable \n" , __func__ , var , module->user_name);
|
||||
|
||||
return 0;
|
||||
@@ -417,7 +417,7 @@ bool analysis_module_get_bool( const analysis_module_type * module , const char
|
||||
return module->get_bool( module->module_data , var );
|
||||
else
|
||||
util_exit("%s: Tried to get bool variable:%s from module:%s - get_int() method not implemented for this module\n" , __func__ , var , module->user_name);
|
||||
} else
|
||||
} else
|
||||
util_exit("%s: Tried to get bool variable:%s from module:%s - module does not support this variable \n" , __func__ , var , module->user_name);
|
||||
|
||||
return false;
|
||||
@@ -430,7 +430,7 @@ double analysis_module_get_double( const analysis_module_type * module , const c
|
||||
return module->get_double( module->module_data , var );
|
||||
else
|
||||
util_exit("%s: Tried to get double variable:%s from module:%s - get_double() method not implemented for this module\n" , __func__ , var , module->user_name);
|
||||
} else
|
||||
} else
|
||||
util_exit("%s: Tried to get double variable:%s from module:%s - module does not support this variable \n" , __func__ , var , module->user_name);
|
||||
|
||||
return 0;
|
||||
@@ -443,9 +443,9 @@ void * analysis_module_get_ptr( const analysis_module_type * module , const char
|
||||
return module->get_ptr( module->module_data , var );
|
||||
else
|
||||
util_exit("%s: Tried to get pointer variable:%s from module:%s - get_ptr() method not implemented for this module\n" , __func__ , var , module->user_name);
|
||||
} else
|
||||
} else
|
||||
util_exit("%s: Tried to get pointer variable:%s from module:%s - module does not support this variable \n" , __func__ , var , module->user_name);
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
+132
-128
@@ -21,10 +21,10 @@ void enkf_linalg_genX3(matrix_type * X3 , const matrix_type * W , const matrix_t
|
||||
for (i=0; i < nrmin; i++)
|
||||
for (j=0; j < nrobs; j++)
|
||||
matrix_iset(X1 , i , j , eig[i] * matrix_iget(W , j , i));
|
||||
|
||||
|
||||
matrix_matmul(X2 , X1 , D); /* X2 = X1 * D (Eq. 14.31) */
|
||||
matrix_matmul(X3 , W , X2); /* X3 = W * X2 = X1 * X2 (Eq. 14.31) */
|
||||
|
||||
matrix_matmul(X3 , W , X2); /* X3 = W * X2 = X1 * X2 (Eq. 14.31) */
|
||||
|
||||
matrix_free( X1 );
|
||||
matrix_free( X2 );
|
||||
}
|
||||
@@ -34,7 +34,7 @@ void enkf_linalg_genX2(matrix_type * X2 , const matrix_type * S , const matrix_t
|
||||
const int nrens = matrix_get_columns( S );
|
||||
const int idim = matrix_get_rows( X2 );
|
||||
matrix_dgemm(X2 , W , S , true , false , 1.0 , 0.0);
|
||||
{
|
||||
{
|
||||
int i,j;
|
||||
for (j=0; j < nrens; j++)
|
||||
for (i=0; i < idim; i++)
|
||||
@@ -53,11 +53,11 @@ void enkf_linalg_genX2(matrix_type * X2 , const matrix_type * S , const matrix_t
|
||||
|
||||
ncomp > 0 , truncation < 0: Use ncomp parameters.
|
||||
ncomp < 0 , truncation > 0: Truncate at level 'truncation'.
|
||||
|
||||
|
||||
The singular values are returned in the inv_sig0 vector; the values
|
||||
we retain are inverted and the remaining elements in are explicitly
|
||||
set to zero.
|
||||
|
||||
|
||||
The left-hand singular vectors are returned in the matrix
|
||||
U0. Depending on the value of the flag @store_V0T the right hand
|
||||
singular vectors are stored in the V0T matrix, or just
|
||||
@@ -74,14 +74,14 @@ void enkf_linalg_genX2(matrix_type * X2 , const matrix_type * S , const matrix_t
|
||||
/*This function is similar to enkf_linalg_svdS but it returns the eigen values without its inverse and also give the matrices truncated U VT and Sig0*/
|
||||
|
||||
// Trunc.SVD(S) = U0 * Sig0 * V0T
|
||||
int enkf_linalg_svd_truncation(const matrix_type * S ,
|
||||
double truncation ,
|
||||
int enkf_linalg_svd_truncation(const matrix_type * S ,
|
||||
double truncation ,
|
||||
int ncomp ,
|
||||
dgesvd_vector_enum store_V0T ,
|
||||
double * sig0,
|
||||
matrix_type * U0 ,
|
||||
dgesvd_vector_enum store_V0T ,
|
||||
double * sig0,
|
||||
matrix_type * U0 ,
|
||||
matrix_type * V0T) {
|
||||
|
||||
|
||||
int num_significant = -1;
|
||||
int nrows = matrix_get_rows(S);
|
||||
int ncolumns= matrix_get_columns(S);
|
||||
@@ -90,9 +90,9 @@ int enkf_linalg_svd_truncation(const matrix_type * S ,
|
||||
((truncation < 0) && (ncomp > 0))) {
|
||||
|
||||
int num_singular_values = util_int_min( matrix_get_rows( S ) , matrix_get_columns( S ));
|
||||
{
|
||||
{
|
||||
matrix_type * workS = matrix_alloc_copy( S );
|
||||
matrix_dgesvd(DGESVD_MIN_RETURN , store_V0T , workS , sig0 , U0 , V0T);
|
||||
matrix_dgesvd(DGESVD_MIN_RETURN , store_V0T , workS , sig0 , U0 , V0T);
|
||||
matrix_free( workS );
|
||||
}
|
||||
int i;
|
||||
@@ -103,11 +103,11 @@ int enkf_linalg_svd_truncation(const matrix_type * S ,
|
||||
double total_sigma2 = 0;
|
||||
for (i=0; i < num_singular_values; i++)
|
||||
total_sigma2 += sig0[i];
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
Determine the number of singular values by enforcing that
|
||||
less than a fraction @truncation of the total variance be
|
||||
accounted for.
|
||||
accounted for.
|
||||
*/
|
||||
num_significant = 0;
|
||||
{
|
||||
@@ -116,40 +116,44 @@ int enkf_linalg_svd_truncation(const matrix_type * S ,
|
||||
if (running_sigma2 / total_sigma2 < truncation) { /* Include one more singular value ? */
|
||||
num_significant++;
|
||||
running_sigma2 += sig0[i];
|
||||
} else
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
matrix_resize(U0 , nrows , num_significant , true);
|
||||
matrix_resize(V0T , num_significant , ncolumns , true);
|
||||
if (num_significant > 0) {
|
||||
matrix_resize(U0 , nrows , num_significant , true);
|
||||
matrix_resize(V0T , num_significant , ncolumns , true);
|
||||
} else
|
||||
util_abort("%s: zero significant singular values\n",__func__);
|
||||
}
|
||||
else
|
||||
else
|
||||
util_abort("%s: truncation:%g ncomp:%d - invalid ambigous input.\n",__func__ , truncation , ncomp );
|
||||
|
||||
return num_significant;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int enkf_linalg_svdS(const matrix_type * S ,
|
||||
double truncation ,
|
||||
int enkf_linalg_svdS(const matrix_type * S ,
|
||||
double truncation ,
|
||||
int ncomp ,
|
||||
dgesvd_vector_enum store_V0T ,
|
||||
double * inv_sig0,
|
||||
matrix_type * U0 ,
|
||||
dgesvd_vector_enum store_V0T ,
|
||||
double * inv_sig0,
|
||||
matrix_type * U0 ,
|
||||
matrix_type * V0T) {
|
||||
|
||||
|
||||
double * sig0 = inv_sig0;
|
||||
int num_significant = 0;
|
||||
|
||||
|
||||
|
||||
if (((truncation > 0) && (ncomp < 0)) ||
|
||||
((truncation < 0) && (ncomp > 0))) {
|
||||
int num_singular_values = util_int_min( matrix_get_rows( S ) , matrix_get_columns( S ));
|
||||
{
|
||||
{
|
||||
matrix_type * workS = matrix_alloc_copy( S );
|
||||
matrix_dgesvd(DGESVD_MIN_RETURN , store_V0T , workS , sig0 , U0 , V0T);
|
||||
matrix_dgesvd(DGESVD_MIN_RETURN , store_V0T , workS , sig0 , U0 , V0T);
|
||||
matrix_free( workS );
|
||||
}
|
||||
int i;
|
||||
@@ -158,13 +162,13 @@ int enkf_linalg_svdS(const matrix_type * S ,
|
||||
num_significant = ncomp;
|
||||
else {
|
||||
double total_sigma2 = 0;
|
||||
for (i=0; i < num_singular_values; i++)
|
||||
for (i=0; i < num_singular_values; i++)
|
||||
total_sigma2 += sig0[i] * sig0[i];
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
Determine the number of singular values by enforcing that
|
||||
less than a fraction @truncation of the total variance be
|
||||
accounted for.
|
||||
accounted for.
|
||||
*/
|
||||
num_significant = 0;
|
||||
{
|
||||
@@ -173,7 +177,7 @@ int enkf_linalg_svdS(const matrix_type * S ,
|
||||
if (running_sigma2 / total_sigma2 < truncation) { /* Include one more singular value ? */
|
||||
num_significant++;
|
||||
running_sigma2 += sig0[i] * sig0[i];
|
||||
} else
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -185,9 +189,9 @@ int enkf_linalg_svdS(const matrix_type * S ,
|
||||
|
||||
/* Explicitly setting the insignificant singular values to zero. */
|
||||
for (i=num_significant; i < num_singular_values; i++)
|
||||
inv_sig0[i] = 0;
|
||||
|
||||
} else
|
||||
inv_sig0[i] = 0;
|
||||
|
||||
} else
|
||||
util_abort("%s: truncation:%g ncomp:%d - invalid ambigous input.\n",__func__ , truncation , ncomp );
|
||||
return num_significant;
|
||||
}
|
||||
@@ -200,14 +204,14 @@ void enkf_linalg_Cee(matrix_type * B, int nrens , const matrix_type * R , const
|
||||
matrix_dgemm(X0 , U0 , R , true , false , 1.0 , 0.0); /* X0 = U0^T * R */
|
||||
matrix_dgemm(B , X0 , U0 , false , false , 1.0 , 0.0); /* B = X0 * U0 */
|
||||
matrix_free( X0 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
int i ,j;
|
||||
|
||||
/* Funny code ??
|
||||
/* Funny code ??
|
||||
Multiply B with S^(-1)from left and right
|
||||
BHat = S^(-1) * B * S^(-1)
|
||||
BHat = S^(-1) * B * S^(-1)
|
||||
*/
|
||||
for (j=0; j < matrix_get_columns( B ) ; j++)
|
||||
for (i=0; i < matrix_get_rows( B ); i++)
|
||||
@@ -217,26 +221,26 @@ void enkf_linalg_Cee(matrix_type * B, int nrens , const matrix_type * R , const
|
||||
for (i=0; i < matrix_get_rows( B ); i++)
|
||||
matrix_imul(B , i , j , inv_sig0[j]);
|
||||
}
|
||||
|
||||
|
||||
matrix_scale(B , nrens - 1.0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void enkf_linalg_lowrankCinv__(const matrix_type * S ,
|
||||
const matrix_type * R ,
|
||||
matrix_type * V0T ,
|
||||
matrix_type * Z,
|
||||
double * eig ,
|
||||
matrix_type * U0,
|
||||
double truncation,
|
||||
void enkf_linalg_lowrankCinv__(const matrix_type * S ,
|
||||
const matrix_type * R ,
|
||||
matrix_type * V0T ,
|
||||
matrix_type * Z,
|
||||
double * eig ,
|
||||
matrix_type * U0,
|
||||
double truncation,
|
||||
int ncomp) {
|
||||
|
||||
|
||||
const int nrobs = matrix_get_rows( S );
|
||||
const int nrens = matrix_get_columns( S );
|
||||
const int nrmin = util_int_min( nrobs , nrens );
|
||||
|
||||
|
||||
double * inv_sig0 = util_calloc( nrmin , sizeof * inv_sig0);
|
||||
|
||||
if (V0T != NULL)
|
||||
@@ -246,18 +250,18 @@ void enkf_linalg_lowrankCinv__(const matrix_type * S ,
|
||||
|
||||
{
|
||||
matrix_type * B = matrix_alloc( nrmin , nrmin );
|
||||
enkf_linalg_Cee( B , nrens , R , U0 , inv_sig0); /* B = Xo = (N-1) * Sigma0^(+) * U0'* Cee * U0 * Sigma0^(+') (14.26)*/
|
||||
enkf_linalg_Cee( B , nrens , R , U0 , inv_sig0); /* B = Xo = (N-1) * Sigma0^(+) * U0'* Cee * U0 * Sigma0^(+') (14.26)*/
|
||||
matrix_dgesvd(DGESVD_MIN_RETURN , DGESVD_NONE, B , eig, Z , NULL);
|
||||
matrix_free( B );
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
int i,j;
|
||||
/* Lambda1 = (I + Lambda)^(-1) */
|
||||
|
||||
for (i=0; i < nrmin; i++)
|
||||
for (i=0; i < nrmin; i++)
|
||||
eig[i] = 1.0 / (1 + eig[i]);
|
||||
|
||||
|
||||
for (j=0; j < nrmin; j++)
|
||||
for (i=0; i < nrmin; i++)
|
||||
matrix_imul(Z , i , j , inv_sig0[i]); /* Z2 = Sigma0^(+) * Z; */
|
||||
@@ -266,20 +270,20 @@ void enkf_linalg_lowrankCinv__(const matrix_type * S ,
|
||||
}
|
||||
|
||||
|
||||
void enkf_linalg_lowrankCinv(const matrix_type * S ,
|
||||
const matrix_type * R ,
|
||||
void enkf_linalg_lowrankCinv(const matrix_type * S ,
|
||||
const matrix_type * R ,
|
||||
matrix_type * W , /* Corresponding to X1 from Eq. 14.29 */
|
||||
double * eig , /* Corresponding to 1 / (1 + Lambda_1) (14.29) */
|
||||
double truncation ,
|
||||
int ncomp) {
|
||||
|
||||
|
||||
const int nrobs = matrix_get_rows( S );
|
||||
const int nrens = matrix_get_columns( S );
|
||||
const int nrmin = util_int_min( nrobs , nrens );
|
||||
|
||||
matrix_type * U0 = matrix_alloc( nrobs , nrmin );
|
||||
matrix_type * Z = matrix_alloc( nrmin , nrmin );
|
||||
|
||||
|
||||
enkf_linalg_lowrankCinv__( S , R , NULL , Z , eig , U0 , truncation , ncomp);
|
||||
matrix_matmul(W , U0 , Z); /* X1 = W = U0 * Z2 = U0 * Sigma0^(+') * Z */
|
||||
|
||||
@@ -288,13 +292,13 @@ void enkf_linalg_lowrankCinv(const matrix_type * S ,
|
||||
}
|
||||
|
||||
|
||||
void enkf_linalg_meanX5(const matrix_type * S ,
|
||||
const matrix_type * W ,
|
||||
const double * eig ,
|
||||
const matrix_type * dObs,
|
||||
void enkf_linalg_meanX5(const matrix_type * S ,
|
||||
const matrix_type * W ,
|
||||
const double * eig ,
|
||||
const matrix_type * dObs,
|
||||
matrix_type * X5) {
|
||||
|
||||
|
||||
|
||||
const int nrens = matrix_get_columns( S );
|
||||
const int nrobs = matrix_get_rows( S );
|
||||
const int nrmin = util_int_min( nrobs , nrens );
|
||||
@@ -304,8 +308,8 @@ void enkf_linalg_meanX5(const matrix_type * S ,
|
||||
double * y1 = &work[0];
|
||||
double * y2 = &work[nrmin];
|
||||
double * y3 = &work[2*nrmin];
|
||||
double * y4 = &work[2*nrmin + nrobs];
|
||||
|
||||
double * y4 = &work[2*nrmin + nrobs];
|
||||
|
||||
if (nrobs == 1) {
|
||||
/* Is this special casing necessary ??? */
|
||||
y1[0] = matrix_iget(W , 0,0) * matrix_iget( innov , 0 , 0);
|
||||
@@ -317,13 +321,13 @@ void enkf_linalg_meanX5(const matrix_type * S ,
|
||||
matrix_dgemv(W , matrix_get_data( innov ) , y1 , true , 1.0, 0.0); /* y1 = Trans(W) * innov */
|
||||
for (int i= 0; i < nrmin; i++)
|
||||
y2[i] = eig[i] * y1[i]; /* y2 = eig * y1 */
|
||||
matrix_dgemv(W , y2 , y3 , false , 1.0 , 0.0); /* y3 = W * y2; */
|
||||
matrix_dgemv(W , y2 , y3 , false , 1.0 , 0.0); /* y3 = W * y2; */
|
||||
matrix_dgemv(S , y3 , y4 , true , 1.0 , 0.0); /* y4 = Trans(S) * y3 */
|
||||
}
|
||||
|
||||
|
||||
for (int iens = 0; iens < nrens; iens++)
|
||||
matrix_set_column(X5 , y4 , iens );
|
||||
|
||||
|
||||
matrix_shift(X5 , 1.0/nrens);
|
||||
}
|
||||
free( work );
|
||||
@@ -332,7 +336,7 @@ void enkf_linalg_meanX5(const matrix_type * S ,
|
||||
|
||||
|
||||
|
||||
void enkf_linalg_X5sqrt(matrix_type * X2 , matrix_type * X5 , const matrix_type * randrot, int nrobs) {
|
||||
void enkf_linalg_X5sqrt(matrix_type * X2 , matrix_type * X5 , const matrix_type * randrot, int nrobs) {
|
||||
const int nrens = matrix_get_columns( X5 );
|
||||
const int nrmin = util_int_min( nrobs , nrens );
|
||||
matrix_type * VT = matrix_alloc( nrens , nrens );
|
||||
@@ -348,24 +352,24 @@ void enkf_linalg_X5sqrt(matrix_type * X2 , matrix_type * X5 , const matrix_type
|
||||
int i,j;
|
||||
for (i = 0; i < nrmin; i++)
|
||||
isig[i] = sqrt( util_double_max( 1.0 - sig[i]*sig[i] ,0.0));
|
||||
|
||||
|
||||
for (j = 0; j < nrens; j++)
|
||||
for (i = 0; i < nrens; i++)
|
||||
matrix_iset(X3 , i , j , matrix_iget(VT , j , i));
|
||||
|
||||
|
||||
for (j=0; j< nrmin; j++)
|
||||
matrix_scale_column(X3 , j , isig[j]);
|
||||
|
||||
|
||||
matrix_dgemm(X33 , X3 , VT , false , false , 1.0 , 0.0); /* X33 = X3 * VT */
|
||||
if (randrot != NULL)
|
||||
matrix_dgemm(X4 , X33 , randrot , false, false , 1.0 , 0.0); /* X4 = X33 * Randrot */
|
||||
matrix_dgemm(X4 , X33 , randrot , false, false , 1.0 , 0.0); /* X4 = X33 * Randrot */
|
||||
else
|
||||
matrix_assign(X4 , X33);
|
||||
|
||||
|
||||
matrix_set(IenN , -1.0/ nrens);
|
||||
for (i = 0; i < nrens; i++)
|
||||
matrix_iadd(IenN , i , i , 1.0);
|
||||
|
||||
|
||||
matrix_dgemm(X5 , IenN , X4 , false , false , 1.0 , 1.0); /* X5 = IenN * X4 + X5 */
|
||||
|
||||
matrix_free( X3 );
|
||||
@@ -383,51 +387,51 @@ void enkf_linalg_X5sqrt(matrix_type * X2 , matrix_type * X5 , const matrix_type
|
||||
matrix_type * enkf_linalg_alloc_innov( const matrix_type * dObs , const matrix_type * S) {
|
||||
matrix_type * innov = matrix_alloc_copy( dObs );
|
||||
|
||||
for (int iobs =0; iobs < matrix_get_row_sum( dObs , iobs); iobs++)
|
||||
for (int iobs =0; iobs < matrix_get_row_sum( dObs , iobs); iobs++)
|
||||
matrix_isub( innov , iobs , 0 , matrix_get_row_sum( S , iobs ));
|
||||
|
||||
return innov;
|
||||
}
|
||||
|
||||
|
||||
void enkf_linalg_init_stdX( matrix_type * X , const matrix_type * S , const matrix_type * D ,
|
||||
void enkf_linalg_init_stdX( matrix_type * X , const matrix_type * S , const matrix_type * D ,
|
||||
const matrix_type * W , const double * eig , bool bootstrap) {
|
||||
|
||||
|
||||
int nrobs = matrix_get_rows( W );
|
||||
int ens_size = matrix_get_rows( X );
|
||||
|
||||
|
||||
matrix_type * X3 = matrix_alloc(nrobs , ens_size);
|
||||
enkf_linalg_genX3(X3 , W , D , eig ); /* X2 = diag(eig) * W' * D (Eq. 14.31, Evensen (2007)) */
|
||||
/* X3 = W * X2 = X1 * X2 (Eq. 14.31, Evensen (2007)) */
|
||||
|
||||
/* X3 = W * X2 = X1 * X2 (Eq. 14.31, Evensen (2007)) */
|
||||
|
||||
matrix_dgemm( X , S , X3 , true , false , 1.0 , 0.0); /* X = S' * X3 */
|
||||
if (!bootstrap) {
|
||||
for (int i = 0; i < ens_size ; i++)
|
||||
matrix_iadd( X , i , i , 1.0); /*X = I + X */
|
||||
}
|
||||
|
||||
|
||||
matrix_free( X3 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void enkf_linalg_init_sqrtX(matrix_type * X5 ,
|
||||
const matrix_type * S ,
|
||||
const matrix_type * randrot ,
|
||||
const matrix_type * innov ,
|
||||
const matrix_type * W ,
|
||||
const double * eig ,
|
||||
void enkf_linalg_init_sqrtX(matrix_type * X5 ,
|
||||
const matrix_type * S ,
|
||||
const matrix_type * randrot ,
|
||||
const matrix_type * innov ,
|
||||
const matrix_type * W ,
|
||||
const double * eig ,
|
||||
bool bootstrap) {
|
||||
|
||||
|
||||
const int nrobs = matrix_get_rows( S );
|
||||
const int nrens = matrix_get_columns( S );
|
||||
const int nrmin = util_int_min( nrobs , nrens );
|
||||
|
||||
|
||||
matrix_type * X2 = matrix_alloc(nrmin , nrens);
|
||||
|
||||
|
||||
if (bootstrap)
|
||||
util_exit("%s: Sorry bootstrap support not fully implemented for SQRT scheme\n",__func__);
|
||||
|
||||
|
||||
enkf_linalg_meanX5( S , W , eig , innov , X5 );
|
||||
enkf_linalg_genX2(X2 , S , W , eig);
|
||||
enkf_linalg_X5sqrt(X2 , X5 , randrot , nrobs);
|
||||
@@ -450,14 +454,14 @@ void enkf_linalg_init_sqrtX(matrix_type * X5 ,
|
||||
2. Then the QR decomposition is computed, and Q will then be a random orthogonal matrix.
|
||||
3. The diagonal elements of R are extracted and we construct the diagonal matrix X(j,j)=R(j,j)/|R(j,j)|
|
||||
4. An updated Q'=Q X is computed, and this is now a random orthogonal matrix with a Haar measure.
|
||||
|
||||
|
||||
The implementation is a plain reimplementation/copy of the old m_randrot.f90 function.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
NB: This should rather use the implementation in m_mean_preserving_rotation.f90.
|
||||
NB: This should rather use the implementation in m_mean_preserving_rotation.f90.
|
||||
*/
|
||||
|
||||
void enkf_linalg_set_randrot( matrix_type * Q , rng_type * rng) {
|
||||
@@ -465,8 +469,8 @@ void enkf_linalg_set_randrot( matrix_type * Q , rng_type * rng) {
|
||||
double * tau = util_calloc( ens_size , sizeof * tau );
|
||||
int * sign = util_calloc( ens_size , sizeof * sign);
|
||||
|
||||
for (int i = 0; i < ens_size; i++)
|
||||
for (int j = 0; j < ens_size; j++)
|
||||
for (int i = 0; i < ens_size; i++)
|
||||
for (int j = 0; j < ens_size; j++)
|
||||
matrix_iset(Q , i , j , rng_std_normal( rng ));
|
||||
|
||||
matrix_dgeqrf( Q , tau ); /* QR factorization */
|
||||
@@ -482,7 +486,7 @@ void enkf_linalg_set_randrot( matrix_type * Q , rng_type * rng) {
|
||||
}
|
||||
|
||||
free( sign );
|
||||
free( tau );
|
||||
free( tau );
|
||||
}
|
||||
|
||||
|
||||
@@ -492,7 +496,7 @@ void enkf_linalg_set_randrot( matrix_type * Q , rng_type * rng) {
|
||||
Generates the mean preserving random rotation for the EnKF SQRT algorithm
|
||||
using the algorithm from Sakov 2006-07. I.e, generate rotation Up such that
|
||||
Up*Up^T=I and Up*1=1 (all rows have sum = 1) see eq 17.
|
||||
From eq 18, Up=B * Upb * B^T
|
||||
From eq 18, Up=B * Upb * B^T
|
||||
B is a random orthonormal basis with the elements in the first column equals 1/sqrt(nrens)
|
||||
|
||||
Upb = | 1 0 |
|
||||
@@ -507,8 +511,8 @@ matrix_type * enkf_linalg_alloc_mp_randrot(int ens_size , rng_type * rng) {
|
||||
matrix_type * B = matrix_alloc( ens_size , ens_size );
|
||||
matrix_type * Upb = matrix_alloc( ens_size , ens_size );
|
||||
matrix_type * U = matrix_alloc_shared(Upb , 1 , 1 , ens_size - 1, ens_size - 1);
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
int k,j;
|
||||
matrix_type * R = matrix_alloc( ens_size , ens_size );
|
||||
@@ -517,7 +521,7 @@ matrix_type * enkf_linalg_alloc_mp_randrot(int ens_size , rng_type * rng) {
|
||||
|
||||
/* modified_gram_schmidt is used to create the orthonormal basis in B.*/
|
||||
for (k=0; k < ens_size; k++) {
|
||||
double Rkk = sqrt( matrix_column_column_dot_product( B , k , B , k));
|
||||
double Rkk = sqrt( matrix_column_column_dot_product( B , k , B , k));
|
||||
matrix_iset(R , k , k , Rkk);
|
||||
matrix_scale_column(B , k , 1.0/Rkk);
|
||||
for (j=k+1; j < ens_size; j++) {
|
||||
@@ -535,23 +539,23 @@ matrix_type * enkf_linalg_alloc_mp_randrot(int ens_size , rng_type * rng) {
|
||||
}
|
||||
matrix_free( R );
|
||||
}
|
||||
|
||||
|
||||
enkf_linalg_set_randrot( U , rng );
|
||||
matrix_iset( Upb , 0 , 0 , 1);
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
matrix_type * Q = matrix_alloc( ens_size , ens_size );
|
||||
matrix_dgemm( Q , B , Upb , false , false , 1, 0); /* Q = B * Ubp */
|
||||
matrix_dgemm( Up , Q , B , false , true , 1, 0); /* Up = Q * T(B) */
|
||||
matrix_free( Q );
|
||||
}
|
||||
|
||||
|
||||
matrix_free( B );
|
||||
matrix_free( Upb );
|
||||
matrix_free( U );
|
||||
}
|
||||
|
||||
|
||||
return Up;
|
||||
}
|
||||
|
||||
@@ -561,7 +565,7 @@ matrix_type * enkf_linalg_alloc_mp_randrot(int ens_size , rng_type * rng) {
|
||||
/**
|
||||
Checking that the sum through one row in the X matrix equals
|
||||
@target_sum. @target_sum will be 1 normally, and zero if we are doing
|
||||
bootstrap.
|
||||
bootstrap.
|
||||
*/
|
||||
|
||||
void enkf_linalg_checkX(const matrix_type * X , bool bootstrap) {
|
||||
@@ -572,10 +576,10 @@ void enkf_linalg_checkX(const matrix_type * X , bool bootstrap) {
|
||||
target_sum = 0;
|
||||
else
|
||||
target_sum = 1;
|
||||
|
||||
|
||||
for (int icol = 0; icol < matrix_get_columns( X ); icol++) {
|
||||
double col_sum = matrix_get_column_sum(X , icol);
|
||||
if (fabs(col_sum - target_sum) > 0.0001)
|
||||
if (fabs(col_sum - target_sum) > 0.0001)
|
||||
util_abort("%s: something is seriously broken. col:%d col_sum = %g != %g - ABORTING\n",__func__ , icol , col_sum , target_sum);
|
||||
}
|
||||
}
|
||||
@@ -584,14 +588,14 @@ void enkf_linalg_checkX(const matrix_type * X , bool bootstrap) {
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
void enkf_linalg_get_PC( const matrix_type * S0,
|
||||
const matrix_type * dObs ,
|
||||
void enkf_linalg_get_PC( const matrix_type * S0,
|
||||
const matrix_type * dObs ,
|
||||
double truncation,
|
||||
int ncomp,
|
||||
int ncomp,
|
||||
matrix_type * PC,
|
||||
matrix_type * PC_obs,
|
||||
matrix_type * PC_obs,
|
||||
double_vector_type * singular_values) {
|
||||
|
||||
|
||||
const int nrobs = matrix_get_rows( S0 );
|
||||
const int nrens = matrix_get_columns( S0 );
|
||||
const int nrmin = util_int_min( nrobs , nrens );
|
||||
@@ -607,7 +611,7 @@ void enkf_linalg_get_PC( const matrix_type * S0,
|
||||
{
|
||||
matrix_type * S_mean = matrix_alloc( nrobs , 1 );
|
||||
int num_PC = enkf_linalg_svdS(S , truncation , ncomp, DGESVD_NONE , inv_sig0 , U0 , NULL);
|
||||
|
||||
|
||||
matrix_assign( S , S0); // The svd routine will overwrite S - we therefor must pick it up again from S0.
|
||||
matrix_subtract_and_store_row_mean( S , S_mean);
|
||||
|
||||
@@ -622,7 +626,7 @@ void enkf_linalg_get_PC( const matrix_type * S0,
|
||||
matrix_dgemm( PC , U0 , S , true , false , 1.0 , 0.0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The observer projections. */
|
||||
{
|
||||
matrix_scale( S_mean , -1.0);
|
||||
@@ -633,7 +637,7 @@ void enkf_linalg_get_PC( const matrix_type * S0,
|
||||
|
||||
for (int i=0; i < double_vector_size( singular_values ); i++)
|
||||
inv_sig0[i] = 1.0 / inv_sig0[i];
|
||||
|
||||
|
||||
matrix_free( S_mean );
|
||||
}
|
||||
matrix_free( S );
|
||||
@@ -649,7 +653,7 @@ void enkf_linalg_rml_enkfX1(matrix_type *X1, matrix_type *Udr, matrix_type *D, m
|
||||
here the negative sign cancels with one needed in X3 matrix computation
|
||||
*/
|
||||
matrix_type * tmp = matrix_alloc(matrix_get_columns(Udr),matrix_get_rows(R));
|
||||
|
||||
|
||||
matrix_matmul_with_transpose( tmp, Udr, R, true, false);
|
||||
matrix_matmul( X1 , tmp, D);
|
||||
|
||||
@@ -661,23 +665,23 @@ void enkf_linalg_rml_enkfX1(matrix_type *X1, matrix_type *Udr, matrix_type *D, m
|
||||
void enkf_linalg_rml_enkfX2(matrix_type *X2 , double *Wdr , matrix_type * X1 , double a , int nsign)
|
||||
{
|
||||
/*
|
||||
This routine computes X2 for RML_EnKF module as X2 = ((a*Ipd)+Wd^2)^-1 * X1
|
||||
This routine computes X2 for RML_EnKF module as X2 = ((a*Ipd)+Wd^2)^-1 * X1
|
||||
Since a+Ipd & Wd are diagonal in nature the computation is reduced to array operations
|
||||
*/
|
||||
|
||||
|
||||
for (int i=0; i< nsign ; i++) {
|
||||
double scale_factor = 1 / (a + (Wdr[i]*Wdr[i]));
|
||||
matrix_scale_row(X1 , i , scale_factor);
|
||||
}
|
||||
matrix_assign(X2,X1);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void enkf_linalg_rml_enkfX3(matrix_type *X3, matrix_type *VdTr, double *Wdr, matrix_type *X2, int nsign)
|
||||
{
|
||||
/*
|
||||
This routine computes X3 for RML_EnKF module as X3 = Vd *Wd*X2
|
||||
This routine computes X3 for RML_EnKF module as X3 = Vd *Wd*X2
|
||||
*/
|
||||
|
||||
printf("\nWd: ");
|
||||
@@ -701,9 +705,9 @@ double enkf_linalg_data_mismatch(matrix_type *D , matrix_type *R , matrix_type *
|
||||
double mismatch;
|
||||
matrix_matmul_with_transpose(tmp, D, R,true, false); // tmp = D' * R, i.e. N-by-p
|
||||
matrix_matmul(Sk, tmp, D); // Sk = D' * R * D
|
||||
// Calculate the mismatch
|
||||
// Calculate the mismatch
|
||||
mismatch = matrix_trace(Sk)/(matrix_get_columns(D));
|
||||
|
||||
|
||||
return mismatch;
|
||||
}
|
||||
|
||||
@@ -718,7 +722,7 @@ void enkf_linalg_Covariance(matrix_type *Cd, const matrix_type *E, double nsc ,i
|
||||
}
|
||||
}
|
||||
nsc = nsc*nsc;
|
||||
matrix_scale(Cd,nsc);
|
||||
matrix_scale(Cd,nsc);
|
||||
}
|
||||
|
||||
|
||||
@@ -746,7 +750,7 @@ void enkf_linalg_rml_enkfX7(matrix_type * X7, matrix_type * VdT, double * Wdr, d
|
||||
double scale_factor = 1 / ( a + (Wdr[i]*Wdr[i]));
|
||||
matrix_scale_row( tmp1 , i , scale_factor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
matrix_matmul_with_transpose(tmp2, tmp1, VdT, true, false);
|
||||
matrix_matmul(X7, tmp2, X6);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
int main(void) {
|
||||
const char * config_file = "config_test_input";
|
||||
config_type * config = config_alloc();
|
||||
config_parser_type * config = config_alloc();
|
||||
config_schema_item_type * item;
|
||||
|
||||
item = config_add_schema_item(config , "KEY1" , true , true);
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'config.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H__
|
||||
#define __CONFIG_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <ert/util/subst_list.h>
|
||||
#include <ert/util/hash.h>
|
||||
|
||||
#include <ert/config/config_schema_item.h>
|
||||
#include <ert/config/config_content_item.h>
|
||||
#include <ert/config/config_content_node.h>
|
||||
|
||||
#define ECL_COM_KW "--"
|
||||
#define ENKF_COM_KW "--"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct config_struct config_type;
|
||||
|
||||
|
||||
char ** config_alloc_active_list(const config_type *, int *);
|
||||
void config_free(config_type *);
|
||||
config_type * config_alloc( );
|
||||
char ** config_alloc_active_list(const config_type * , int * );
|
||||
bool config_parse(config_type * , const char * , const char * , const char * , const char * , config_schema_unrecognized_enum unrecognized_behaviour , bool );
|
||||
bool config_has_schema_item(const config_type * config , const char * kw);
|
||||
void config_clear(config_type * config);
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
config_schema_item_type * config_get_schema_item(const config_type *, const char *);
|
||||
bool config_item_set(const config_type * , const char * );
|
||||
void config_add_alias(config_type * , const char * , const char * );
|
||||
void config_install_message(config_type * , const char * , const char * );
|
||||
const char * config_safe_get(const config_type * , const char *);
|
||||
char * config_alloc_joined_string(const config_type * , const char * , const char * );
|
||||
|
||||
void config_add_define( config_type * config , const char * key , const char * value );
|
||||
|
||||
/*
|
||||
bool config_schema_item_is_set(const config_schema_item_type * );
|
||||
void config_schema_item_set_argc_minmax(config_schema_item_type * , int , int , int type_map_size , const config_item_types * );
|
||||
void config_schema_item_set_common_selection_set(config_schema_item_type * , int argc , const char ** argv);
|
||||
void config_schema_item_set_indexed_selection_set(config_schema_item_type * item , int , int , const char ** );
|
||||
void config_schema_item_set_required_children(config_schema_item_type * , stringlist_type * );
|
||||
void config_schema_item_set_required_children_on_value(config_schema_item_type * , const char * , stringlist_type * );
|
||||
void config_schema_item_add_required_children(config_schema_item_type * item , const char * child_key);
|
||||
*/
|
||||
|
||||
config_schema_item_type * config_add_schema_item(config_type * config,
|
||||
const char * kw,
|
||||
bool required);
|
||||
|
||||
|
||||
const char * config_safe_iget(const config_type * config , const char *kw, int occurence , int index);
|
||||
const char * config_iget(const config_type * , const char * , int occurence , int index);
|
||||
bool config_iget_as_bool(const config_type * , const char * , int occurence , int index);
|
||||
double config_iget_as_double(const config_type * , const char * , int occurence , int index);
|
||||
int config_iget_as_int(const config_type * , const char *, int occurence , int index);
|
||||
stringlist_type * config_alloc_complete_stringlist(const config_type* , const char * );
|
||||
stringlist_type * config_alloc_stringlist(const config_type * config , const char * );
|
||||
hash_type * config_alloc_hash(const config_type * , const char * );
|
||||
const stringlist_type * config_iget_stringlist_ref(const config_type * , const char * , int );
|
||||
|
||||
int config_get_occurences(const config_type * , const char * );
|
||||
int config_get_occurence_size( const config_type * config , const char * kw , int occurence);
|
||||
|
||||
bool config_has_content_item( const config_type * config , const char * input_kw);
|
||||
config_content_item_type * config_get_content_item( const config_type * config , const char * input_kw);
|
||||
config_schema_item_type * config_add_key_value( config_type * config , const char * key , bool required , config_item_types item_type);
|
||||
bool config_get_value_as_bool(const config_type * config , const char * kw);
|
||||
int config_get_value_as_int(const config_type * config , const char * kw);
|
||||
double config_get_value_as_double(const config_type * config , const char * kw);
|
||||
const char * config_get_value_as_abspath( const config_type * config , const char * kw);
|
||||
const char * config_get_value_as_relpath( const config_type * config , const char * kw);
|
||||
const char * config_get_value_as_path( const config_type * config , const char * kw);
|
||||
const char * config_get_value(const config_type * config , const char * kw);
|
||||
const char * config_get_config_file( const config_type * config , bool abs_path);
|
||||
void config_fprintf_errors( const config_type * config , bool add_count , FILE * stream );
|
||||
|
||||
const subst_list_type * config_get_define_list( const config_type * config);
|
||||
int config_get_schema_size( const config_type * config );
|
||||
int config_get_content_size( const config_type * config );
|
||||
const config_content_node_type * config_iget_content_node( const config_type * config , int index );
|
||||
config_content_node_type * config_get_value_node( const config_type * config , const char * kw);
|
||||
config_error_type * config_get_errors( const config_type * config );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
Copyright (C) 2015 Statoil ASA, Norway.
|
||||
|
||||
The file 'config_content.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __CONFIG_CONTENT_H__
|
||||
#define __CONFIG_CONTENT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <ert/util/type_macros.h>
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <ert/util/subst_list.h>
|
||||
|
||||
#include <ert/config/config_content_item.h>
|
||||
#include <ert/config/config_schema_item.h>
|
||||
#include <ert/config/config_error.h>
|
||||
#include <ert/config/config_root_path.h>
|
||||
|
||||
typedef struct config_content_struct config_content_type;
|
||||
|
||||
|
||||
config_content_type * config_content_alloc();
|
||||
void config_content_free( config_content_type * content );
|
||||
void config_content_set_valid( config_content_type * content);
|
||||
bool config_content_is_valid( const config_content_type * content );
|
||||
bool config_content_has_item( const config_content_type * content , const char * key);
|
||||
void config_content_add_item( config_content_type * content , const config_schema_item_type * schema_item , const config_path_elm_type * path_elm);
|
||||
config_content_item_type * config_content_get_item( const config_content_type * content , const char * key);
|
||||
void config_content_add_node( config_content_type * content , config_content_node_type * content_node );
|
||||
config_error_type * config_content_get_errors( const config_content_type * content);
|
||||
|
||||
const char * config_content_iget( const config_content_type * content , const char * key , int occurence , int index);
|
||||
int config_content_iget_as_int( const config_content_type * content , const char * key , int occurence , int index);
|
||||
bool config_content_iget_as_bool( const config_content_type * content , const char * key , int occurence , int index);
|
||||
double config_content_iget_as_double( const config_content_type * content , const char * key , int occurence , int index);
|
||||
const char * config_content_safe_iget(const config_content_type * content , const char *kw, int occurence , int index);
|
||||
int config_content_get_occurences(const config_content_type * content, const char * kw);
|
||||
|
||||
bool config_content_get_value_as_bool(const config_content_type * config , const char * kw);
|
||||
int config_content_get_value_as_int(const config_content_type * config , const char * kw);
|
||||
double config_content_get_value_as_double(const config_content_type * config , const char * kw);
|
||||
const char * config_content_get_value_as_path( const config_content_type * config , const char * kw);
|
||||
const char * config_content_get_value_as_abspath( const config_content_type * config , const char * kw);
|
||||
const char * config_content_get_value_as_relpath( const config_content_type * config , const char * kw);
|
||||
const char * config_content_get_value(const config_content_type * config , const char * kw);
|
||||
char * config_content_alloc_joined_string(const config_content_type * content , const char * kw, const char * sep);
|
||||
stringlist_type * config_content_alloc_complete_stringlist(const config_content_type * content , const char * kw);
|
||||
const stringlist_type * config_content_iget_stringlist_ref(const config_content_type * content , const char * kw, int occurence);
|
||||
config_content_node_type * config_content_get_value_node( const config_content_type * content , const char * kw);
|
||||
void config_content_add_define( config_content_type * content , const char * key , const char * value );
|
||||
subst_list_type * config_content_get_define_list( config_content_type * content );
|
||||
const char * config_content_get_config_file( const config_content_type * content , bool abs_path );
|
||||
void config_content_set_config_file( config_content_type * content , const char * config_file );
|
||||
int config_content_get_size(const config_content_type * content);
|
||||
const config_content_node_type * config_content_iget_node( const config_content_type * content , int index);
|
||||
bool config_content_add_file( config_content_type * content , const char * config_file);
|
||||
config_root_path_type * config_content_get_invoke_path( config_content_type * content );
|
||||
void config_content_set_invoke_path( config_content_type * content);
|
||||
config_path_elm_type * config_content_add_path_elm( config_content_type * content , const char * path );
|
||||
void config_content_pop_path_stack( config_content_type * content );
|
||||
|
||||
UTIL_IS_INSTANCE_HEADER( config_content );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2012 Statoil ASA, Norway.
|
||||
|
||||
The file 'config_content_item.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2012 Statoil ASA, Norway.
|
||||
|
||||
The file 'config_content_item.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ extern "C" {
|
||||
|
||||
#include <ert/util/hash.h>
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <ert/util/type_macros.h>
|
||||
|
||||
#include <ert/config/config_error.h>
|
||||
#include <ert/config/config_schema_item.h>
|
||||
@@ -59,6 +60,8 @@ typedef struct config_content_item_struct config_content_item_type;
|
||||
const config_schema_item_type * config_content_item_get_schema( const config_content_item_type * item );
|
||||
const config_path_elm_type * config_content_item_get_path_elm( const config_content_item_type * item );
|
||||
|
||||
UTIL_IS_INSTANCE_HEADER( config_content_item );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'config.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H__
|
||||
#define __CONFIG_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <ert/util/subst_list.h>
|
||||
#include <ert/util/hash.h>
|
||||
|
||||
#include <ert/config/config_schema_item.h>
|
||||
#include <ert/config/config_content_item.h>
|
||||
#include <ert/config/config_content_node.h>
|
||||
#include <ert/config/config_content.h>
|
||||
|
||||
#define ECL_COM_KW "--"
|
||||
#define ENKF_COM_KW "--"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct config_parser_struct config_parser_type;
|
||||
|
||||
|
||||
void config_free(config_parser_type *);
|
||||
config_parser_type * config_alloc( );
|
||||
char ** config_alloc_active_list(const config_parser_type * , int * );
|
||||
config_content_type * config_parse(config_parser_type * , const char * , const char * , const char * , const char * , config_schema_unrecognized_enum unrecognized_behaviour , bool );
|
||||
bool config_has_schema_item(const config_parser_type * config , const char * kw);
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
config_schema_item_type * config_get_schema_item(const config_parser_type *, const char *);
|
||||
bool config_item_set(const config_parser_type * , const char * );
|
||||
void config_add_alias(config_parser_type * , const char * , const char * );
|
||||
void config_install_message(config_parser_type * , const char * , const char * );
|
||||
const char * config_safe_get(const config_parser_type * , const char *);
|
||||
char * config_alloc_joined_string(const config_parser_type * , const char * , const char * );
|
||||
|
||||
void config_add_define( config_parser_type * config , const char * key , const char * value );
|
||||
|
||||
/*
|
||||
bool config_schema_item_is_set(const config_schema_item_type * );
|
||||
void config_schema_item_set_argc_minmax(config_schema_item_type * , int , int , int type_map_size , const config_item_types * );
|
||||
void config_schema_item_set_common_selection_set(config_schema_item_type * , int argc , const char ** argv);
|
||||
void config_schema_item_set_indexed_selection_set(config_schema_item_type * item , int , int , const char ** );
|
||||
void config_schema_item_set_required_children(config_schema_item_type * , stringlist_type * );
|
||||
void config_schema_item_set_required_children_on_value(config_schema_item_type * , const char * , stringlist_type * );
|
||||
void config_schema_item_add_required_children(config_schema_item_type * item , const char * child_key);
|
||||
*/
|
||||
|
||||
config_schema_item_type * config_add_schema_item(config_parser_type * config,
|
||||
const char * kw,
|
||||
bool required);
|
||||
|
||||
|
||||
stringlist_type * config_alloc_complete_stringlist(const config_parser_type * , const char * );
|
||||
stringlist_type * config_alloc_stringlist(const config_parser_type * config , const char * );
|
||||
hash_type * config_alloc_hash(const config_parser_type * , const char * );
|
||||
const stringlist_type * config_iget_stringlist_ref(const config_parser_type * , const char * , int );
|
||||
|
||||
int config_get_occurences(const config_parser_type * , const char * );
|
||||
int config_get_occurence_size( const config_parser_type * config , const char * kw , int occurence);
|
||||
|
||||
bool config_has_content_item( const config_parser_type * config , const char * input_kw);
|
||||
config_content_item_type * config_get_content_item( const config_parser_type * config , const char * input_kw);
|
||||
config_schema_item_type * config_add_key_value( config_parser_type * config , const char * key , bool required , config_item_types item_type);
|
||||
;
|
||||
const char * config_get_value_as_relpath( const config_parser_type * config , const char * kw);
|
||||
const char * config_get_value_as_path( const config_parser_type * config , const char * kw);
|
||||
const char * config_get_value(const config_parser_type * config , const char * kw);
|
||||
|
||||
const subst_list_type * config_get_define_list( const config_parser_type * config);
|
||||
int config_get_schema_size( const config_parser_type * config );
|
||||
config_content_node_type * config_get_value_node( const config_parser_type * config , const char * kw);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2012 Statoil ASA, Norway.
|
||||
|
||||
The file 'config_schema_item.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2012 Statoil ASA, Norway.
|
||||
|
||||
The file 'config_schema_item.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -29,12 +29,12 @@ extern "C" {
|
||||
#include <ert/config/config_error.h>
|
||||
#include <ert/config/config_path_elm.h>
|
||||
|
||||
/**
|
||||
/**
|
||||
Types used for validation of config items.
|
||||
*/
|
||||
typedef enum {CONFIG_STRING = 1,
|
||||
CONFIG_INT = 2,
|
||||
CONFIG_FLOAT = 4,
|
||||
CONFIG_FLOAT = 4,
|
||||
CONFIG_PATH = 8,
|
||||
CONFIG_EXISTING_PATH = 16,
|
||||
CONFIG_BOOL = 32,
|
||||
@@ -42,7 +42,7 @@ typedef enum {CONFIG_STRING = 1,
|
||||
CONFIG_BYTESIZE = 128,
|
||||
CONFIG_EXECUTABLE = 256 ,
|
||||
CONFIG_INVALID = 512 } config_item_types;
|
||||
|
||||
|
||||
#define CONFIG_ITEM_TYPE_ENUM_DEFS \
|
||||
{.value = 1 , .name="CONFIG_STRING"}, \
|
||||
{.value = 2 , .name="CONFIG_INT"}, \
|
||||
@@ -53,10 +53,10 @@ typedef enum {CONFIG_STRING = 1,
|
||||
{.value = 64 , .name="CONFIG_CONFIG"}, \
|
||||
{.value = 128 , .name="CONFIG_BYTESIZE"}, \
|
||||
{.value = 256 , .name="CONFIG_EXECUTABLE"}, \
|
||||
{.value = 512 , .name="CONFIG_INVALID"}
|
||||
{.value = 512 , .name="CONFIG_INVALID"}
|
||||
#define CONFIG_ITEM_TYPE_ENUM_SIZE 10
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
CONFIG_UNRECOGNIZED_IGNORE = 0,
|
||||
CONFIG_UNRECOGNIZED_WARN = 1,
|
||||
@@ -79,13 +79,13 @@ typedef enum {CONFIG_STRING = 1,
|
||||
|
||||
|
||||
typedef struct config_schema_item_struct config_schema_item_type;
|
||||
|
||||
|
||||
|
||||
|
||||
config_schema_item_type * config_schema_item_alloc(const char * kw , bool required);
|
||||
bool config_schema_item_validate_set(const config_schema_item_type * item ,
|
||||
stringlist_type * token_list ,
|
||||
const char * config_file,
|
||||
const config_path_elm_type * path_elm,
|
||||
bool config_schema_item_validate_set(const config_schema_item_type * item ,
|
||||
stringlist_type * token_list ,
|
||||
const char * config_file,
|
||||
const config_path_elm_type * path_elm,
|
||||
config_error_type * error_list);
|
||||
|
||||
void config_schema_item_free( config_schema_item_type * item);
|
||||
@@ -97,13 +97,13 @@ typedef enum {CONFIG_STRING = 1,
|
||||
void config_schema_item_set_required_children(config_schema_item_type * item , stringlist_type * stringlist);
|
||||
void config_schema_item_add_required_children(config_schema_item_type * item , const char * child_key);
|
||||
void config_schema_item_set_envvar_expansion( config_schema_item_type * item , bool expand_envvar );
|
||||
void config_schema_item_set_argc_minmax(config_schema_item_type * item ,
|
||||
int argc_min ,
|
||||
void config_schema_item_set_argc_minmax(config_schema_item_type * item ,
|
||||
int argc_min ,
|
||||
int argc_max);
|
||||
void config_schema_item_assure_type(const config_schema_item_type * item , int index , int type_mask);
|
||||
|
||||
int config_schema_item_num_required_children(const config_schema_item_type * item);
|
||||
const char * config_schema_item_iget_required_child( const config_schema_item_type * item , int index);
|
||||
const char * config_schema_item_iget_required_child( const config_schema_item_type * item , int index);
|
||||
const char * config_schema_item_get_kw( const config_schema_item_type * item );
|
||||
bool config_schema_item_required( const config_schema_item_type * item );
|
||||
bool config_schema_item_expand_envvar( const config_schema_item_type * item );
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
set( source_files config.c config_error.c config_schema_item.c config_content_item.c config_content_node.c config_root_path.c config_path_elm.c conf.c conf_util.c conf_data.c)
|
||||
set( header_files config.h config_error.h config_schema_item.h config_content_item.h config_content_node.h config_root_path.h config_path_elm.h conf.h conf_data.h)
|
||||
set( source_files config_parser.c config_content.c config_error.c config_schema_item.c config_content_item.c config_content_node.c config_root_path.c config_path_elm.c conf.c conf_util.c conf_data.c)
|
||||
set( header_files config_parser.h config_content.h config_error.h config_schema_item.h config_content_item.h config_content_node.h config_root_path.h config_path_elm.h conf.h conf_data.h)
|
||||
|
||||
add_library( config ${LIBRARY_TYPE} ${source_files} )
|
||||
set_target_properties( config PROPERTIES VERSION 1.0 SOVERSION 1.0 )
|
||||
|
||||
+1
-1
@@ -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++)
|
||||
{
|
||||
|
||||
-1040
File diff suppressed because it is too large
Load Diff
+409
@@ -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 );
|
||||
}
|
||||
@@ -250,8 +250,8 @@ void config_content_item_free( config_content_item_type * item ) {
|
||||
|
||||
|
||||
|
||||
UTIL_SAFE_CAST_FUNCTION( config_content_item , CONFIG_CONTENT_ITEM_ID);
|
||||
|
||||
UTIL_SAFE_CAST_FUNCTION( config_content_item , CONFIG_CONTENT_ITEM_ID)
|
||||
UTIL_IS_INSTANCE_FUNCTION( config_content_item , CONFIG_CONTENT_ITEM_ID)
|
||||
|
||||
|
||||
void config_content_item_free__( void * arg ) {
|
||||
|
||||
@@ -111,6 +111,11 @@ const char * config_content_node_safe_iget(const config_content_node_type * node
|
||||
}
|
||||
|
||||
|
||||
config_item_types config_content_node_iget_type( const config_content_node_type * node , int index) {
|
||||
return config_schema_item_iget_type( node->schema , index );
|
||||
}
|
||||
|
||||
|
||||
bool config_content_node_iget_as_bool(const config_content_node_type * node , int index) {
|
||||
bool value;
|
||||
config_schema_item_assure_type(node->schema , index , CONFIG_BOOL);
|
||||
|
||||
+18
-18
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2012 Statoil ASA, Norway.
|
||||
|
||||
The file 'config_error.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2012 Statoil ASA, Norway.
|
||||
|
||||
The file 'config_error.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -54,7 +54,7 @@ void config_error_free( config_error_type * error ) {
|
||||
|
||||
|
||||
void config_error_add( config_error_type * error , char * new_error) {
|
||||
stringlist_append_owned_ref( error->error_list , new_error );
|
||||
stringlist_append_copy( error->error_list , new_error );
|
||||
}
|
||||
|
||||
|
||||
@@ -78,9 +78,9 @@ void config_error_fprintf( const config_error_type * error , bool add_count , FI
|
||||
int error_nr;
|
||||
|
||||
for (error_nr = 0; error_nr < stringlist_get_size( error->error_list ); error_nr++) {
|
||||
if (add_count)
|
||||
if (add_count)
|
||||
fprintf(stream , " %02d: " , error_nr);
|
||||
|
||||
|
||||
fprintf( stream , "%s\n" , stringlist_iget( error->error_list , error_nr));
|
||||
}
|
||||
}
|
||||
|
||||
+11
-22
@@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
|
||||
config_content_node_type * config_get_value_node( const config_type * config , const char * kw) {
|
||||
/*config_content_node_type * config_get_value_node( const config_parser_type * config , const char * kw) {
|
||||
config_content_item_type * item = config_get_content_item(config , kw);
|
||||
if (item != NULL) {
|
||||
config_content_node_type * node = config_content_item_get_last_node( item );
|
||||
@@ -42,7 +42,7 @@ config_content_node_type * config_get_value_node( const config_type * config , c
|
||||
return NULL; // Will return NULL on unset keywords - must check NULL return value?!
|
||||
}
|
||||
|
||||
static config_content_node_type * config_get_value_node__( const config_type * config , const char * kw) {
|
||||
static config_content_node_type * config_get_value_node__( const config_parser_type * config , const char * kw) {
|
||||
config_content_node_type * node = config_get_value_node( config , kw );
|
||||
if (node == NULL)
|
||||
util_abort("Tried to get value node from unset kw:%s \n",__func__ , kw );
|
||||
@@ -50,65 +50,54 @@ static config_content_node_type * config_get_value_node__( const config_type * c
|
||||
return node;
|
||||
}
|
||||
|
||||
bool config_get_value_as_bool(const config_type * config , const char * kw) {
|
||||
bool config_get_value_as_bool(const config_parser_type * config , const char * kw) {
|
||||
config_content_node_type * node = config_get_value_node__( config , kw );
|
||||
return config_content_node_iget_as_bool(node , 0);
|
||||
}
|
||||
|
||||
int config_get_value_as_int(const config_type * config , const char * kw) {
|
||||
int config_get_value_as_int(const config_parser_type * config , const char * kw) {
|
||||
config_content_node_type * node = config_get_value_node__( config , kw );
|
||||
return config_content_node_iget_as_int(node , 0);
|
||||
}
|
||||
|
||||
double config_get_value_as_double(const config_type * config , const char * kw) {
|
||||
double config_get_value_as_double(const config_parser_type * config , const char * kw) {
|
||||
config_content_node_type * node = config_get_value_node__( config , kw );
|
||||
return config_content_node_iget_as_double(node , 0);
|
||||
}
|
||||
|
||||
const char * config_get_value_as_path( const config_type * config , const char * kw) {
|
||||
const char * config_get_value_as_path( const config_parser_type * config , const char * kw) {
|
||||
config_content_node_type * node = config_get_value_node__( config , kw );
|
||||
return config_content_node_iget_as_path(node , 0);
|
||||
}
|
||||
|
||||
const char * config_get_value_as_abspath( const config_type * config , const char * kw) {
|
||||
const char * config_get_value_as_abspath( const config_parser_type * config , const char * kw) {
|
||||
config_content_node_type * node = config_get_value_node__( config , kw );
|
||||
return config_content_node_iget_as_abspath(node , 0);
|
||||
}
|
||||
|
||||
const char * config_get_value_as_relpath( const config_type * config , const char * kw) {
|
||||
const char * config_get_value_as_relpath( const config_parser_type * config , const char * kw) {
|
||||
config_content_node_type * node = config_get_value_node__( config , kw );
|
||||
return config_content_node_iget_as_relpath(node , 0);
|
||||
}
|
||||
|
||||
|
||||
const char * config_get_value(const config_type * config , const char * kw) {
|
||||
const char * config_get_value(const config_parser_type * config , const char * kw) {
|
||||
config_content_node_type * node = config_get_value_node__( config , kw );
|
||||
return config_content_node_iget(node , 0);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
int config_get_content_size( const config_type * config ) {
|
||||
return vector_get_size(config->content_list);
|
||||
}
|
||||
|
||||
|
||||
const config_content_node_type * config_iget_content_node( const config_type * config , int index) {
|
||||
return vector_iget_const( config->content_list , index );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int config_get_schema_size( const config_type * config ) {
|
||||
int config_get_schema_size( const config_parser_type * config ) {
|
||||
return hash_get_size( config->schema_items );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
config_error_type * config_get_errors( const config_type * config ) {
|
||||
return config->parse_errors;
|
||||
}
|
||||
|
||||
+697
@@ -0,0 +1,697 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'config.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <ert/util/type_macros.h>
|
||||
#include <ert/util/util.h>
|
||||
#include <ert/util/parser.h>
|
||||
#include <ert/util/hash.h>
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <ert/util/subst_list.h>
|
||||
#include <ert/util/vector.h>
|
||||
#include <ert/util/path_stack.h>
|
||||
|
||||
#include <ert/config/config_parser.h>
|
||||
#include <ert/config/config_error.h>
|
||||
#include <ert/config/config_schema_item.h>
|
||||
#include <ert/config/config_content_node.h>
|
||||
#include <ert/config/config_content_item.h>
|
||||
#include <ert/config/config_path_elm.h>
|
||||
#include <ert/config/config_root_path.h>
|
||||
|
||||
#define CLEAR_STRING "__RESET__"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Structure to parse configuration files of this type:
|
||||
|
||||
KEYWORD1 ARG2 ARG2 ARG3
|
||||
KEYWORD2 ARG1-2
|
||||
....
|
||||
KEYWORDN ARG1 ARG2
|
||||
|
||||
A keyword can occure many times.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
|
||||
=============================
|
||||
| config_type object |
|
||||
| |
|
||||
| Contains 'all' the |
|
||||
| configuration information.|
|
||||
| |
|
||||
=============================
|
||||
| |
|
||||
| \________________________
|
||||
| \
|
||||
KEY1 KEY2
|
||||
| |
|
||||
\|/ \|/
|
||||
========================= =========================
|
||||
| config_item object | | config_item object |
|
||||
| | | |
|
||||
| Indexed by a keyword | | Indexed by a keyword |
|
||||
| which is the first | | which is the first |
|
||||
| string in the | | string in the |
|
||||
| config file. | | config file. |
|
||||
| | | |
|
||||
========================= =========================
|
||||
| | |
|
||||
| | |
|
||||
\|/ \|/ \|/
|
||||
============================ ============================ ============================
|
||||
| config_item_node object | | config_item_node object | | config_item_node object |
|
||||
| | | | | |
|
||||
| Only containing the | | Only containing the | | Only containing the |
|
||||
| stringlist object | | stringlist object | | stringlist object |
|
||||
| directly parsed from the | | directly parsed from the | | directly parsed from the |
|
||||
| file. | | file. | | file. |
|
||||
|--------------------------| |--------------------------| |--------------------------|
|
||||
| ARG1 ARG2 ARG3 | | VERBOSE | | DEBUG |
|
||||
============================ ============================ ============================
|
||||
|
||||
|
||||
The example illustrated above would correspond to the following config
|
||||
file (invariant under line-permutations):
|
||||
|
||||
KEY1 ARG1 ARG2 ARG3
|
||||
KEY1 VERBOSE
|
||||
KEY2 DEBUG
|
||||
|
||||
|
||||
Example config file(2):
|
||||
|
||||
OUTFILE filename
|
||||
INPUT filename
|
||||
OPTIONS store
|
||||
OPTIONS verbose
|
||||
OPTIONS optimize cache=1
|
||||
|
||||
In this case the whole config object will contain three items,
|
||||
corresponding to the keywords OUTFILE, INPUT and OPTIONS. The two
|
||||
first will again only contain one node each, whereas the OPTIONS item
|
||||
will contain three nodes, corresponding to the three times the keyword
|
||||
"OPTIONS" appear in the config file.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct config_parser_struct {
|
||||
hash_type * schema_items;
|
||||
hash_type * messages; /* Can print a (warning) message when a keyword is encountered. */
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
The last argument (config_file) is only used for printing
|
||||
informative error messages, and can be NULL. The config_cwd is
|
||||
essential if we are looking up a filename, otherwise it can be NULL.
|
||||
|
||||
Returns a string with an error description, or NULL if the supplied
|
||||
arguments were OK. The string is allocated here, but is assumed that
|
||||
calling scope will free it.
|
||||
*/
|
||||
|
||||
static config_content_node_type * config_content_item_set_arg__(subst_list_type * define_list ,
|
||||
config_error_type * parse_errors ,
|
||||
config_content_item_type * item ,
|
||||
stringlist_type * token_list ,
|
||||
const config_path_elm_type * path_elm ,
|
||||
const char * config_file ) {
|
||||
|
||||
config_content_node_type * new_node = NULL;
|
||||
int argc = stringlist_get_size( token_list ) - 1;
|
||||
|
||||
if (argc == 1 && (strcmp(stringlist_iget(token_list , 1) , CLEAR_STRING) == 0)) {
|
||||
config_content_item_clear(item);
|
||||
} else {
|
||||
const config_schema_item_type * schema_item = config_content_item_get_schema( item );
|
||||
|
||||
/* Filtering based on DEFINE statements */
|
||||
if (subst_list_get_size( define_list ) > 0) {
|
||||
int iarg;
|
||||
for (iarg = 0; iarg < argc; iarg++) {
|
||||
char * filtered_copy = subst_list_alloc_filtered_string( define_list , stringlist_iget(token_list , iarg + 1));
|
||||
stringlist_iset_owned_ref( token_list , iarg + 1 , filtered_copy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Filtering based on environment variables */
|
||||
if (config_schema_item_expand_envvar( schema_item )) {
|
||||
int iarg;
|
||||
for (iarg = 0; iarg < argc; iarg++) {
|
||||
int env_offset = 0;
|
||||
char * env_var;
|
||||
do {
|
||||
env_var = util_isscanf_alloc_envvar( stringlist_iget(token_list , iarg + 1) , env_offset );
|
||||
if (env_var != NULL) {
|
||||
const char * env_value = getenv( &env_var[1] );
|
||||
if (env_value != NULL) {
|
||||
char * new_value = util_string_replace_alloc( stringlist_iget( token_list , iarg + 1 ) , env_var , env_value );
|
||||
stringlist_iset_owned_ref( token_list , iarg + 1 , new_value );
|
||||
} else {
|
||||
env_offset += 1;
|
||||
fprintf(stderr,"** Warning: environment variable: %s is not defined \n", env_var);
|
||||
}
|
||||
}
|
||||
} while (env_var != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (config_schema_item_validate_set(schema_item , token_list , config_file, path_elm , parse_errors)) {
|
||||
new_node = config_content_item_alloc_node( item , config_content_item_get_path_elm( item ));
|
||||
config_content_node_set(new_node , token_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new_node;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
|
||||
|
||||
config_parser_type * config_alloc() {
|
||||
config_parser_type *config = util_malloc(sizeof * config );
|
||||
config->schema_items = hash_alloc();
|
||||
config->messages = hash_alloc();
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void config_free(config_parser_type * config) {
|
||||
|
||||
hash_free(config->schema_items);
|
||||
hash_free(config->messages);
|
||||
|
||||
free(config);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void config_insert_schema_item(config_parser_type * config , const char * kw , const config_schema_item_type * item , bool ref) {
|
||||
if (ref)
|
||||
hash_insert_ref(config->schema_items , kw , item);
|
||||
else
|
||||
hash_insert_hash_owned_ref(config->schema_items , kw , item , config_schema_item_free__);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function allocates a simple item with all values
|
||||
defaulted. The item is added to the config object, and a pointer is
|
||||
returned to the calling scope. If you want to change the properties
|
||||
of the item you can do that with config_schema_item_set_xxxx() functions
|
||||
from the calling scope.
|
||||
*/
|
||||
|
||||
|
||||
config_schema_item_type * config_add_schema_item(config_parser_type * config ,
|
||||
const char * kw,
|
||||
bool required) {
|
||||
|
||||
config_schema_item_type * item = config_schema_item_alloc( kw , required );
|
||||
config_insert_schema_item(config , kw , item , false);
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
This is a minor wrapper for adding an item with the properties.
|
||||
|
||||
1. It has argc_minmax = {1,1}
|
||||
|
||||
The value can than be extracted with config_get_value() and
|
||||
config_get_value_as_xxxx functions.
|
||||
*/
|
||||
|
||||
config_schema_item_type * config_add_key_value( config_parser_type * config , const char * key , bool required , config_item_types item_type) {
|
||||
config_schema_item_type * item = config_add_schema_item( config , key , required );
|
||||
config_schema_item_set_argc_minmax( item , 1 , 1 );
|
||||
config_schema_item_iset_type( item , 0 , item_type );
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool config_has_schema_item(const config_parser_type * config , const char * kw) {
|
||||
return hash_has_key(config->schema_items , kw);
|
||||
}
|
||||
|
||||
|
||||
config_schema_item_type * config_get_schema_item(const config_parser_type * config , const char * kw) {
|
||||
return hash_get(config->schema_items , kw);
|
||||
}
|
||||
|
||||
/*
|
||||
Due to the possibility of aliases we must go through the canonical
|
||||
keyword which is internalized in the schema_item.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void config_validate_content_item(const config_parser_type * config , config_content_type * content , const config_content_item_type * item) {
|
||||
const config_schema_item_type * schema_item = config_content_item_get_schema( item );
|
||||
const char * schema_kw = config_schema_item_get_kw( schema_item );
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < config_schema_item_num_required_children(schema_item); i++) {
|
||||
const char * required_child = config_schema_item_iget_required_child( schema_item , i );
|
||||
if (!config_content_has_item(content , required_child)) {
|
||||
char * error_message = util_alloc_sprintf("When:%s is set - you also must set:%s.",schema_kw , required_child);
|
||||
config_error_add( config_content_get_errors( content ) , error_message );
|
||||
free( error_message );
|
||||
}
|
||||
}
|
||||
|
||||
if (config_schema_item_has_required_children_value( schema_item )) {
|
||||
int inode;
|
||||
for (inode = 0; inode < config_content_item_get_size(item); inode++) {
|
||||
config_content_node_type * node = config_content_item_iget_node(item , inode);
|
||||
const stringlist_type * values = config_content_node_get_stringlist( node );
|
||||
int is;
|
||||
|
||||
for (is = 0; is < stringlist_get_size(values); is++) {
|
||||
const char * value = stringlist_iget(values , is);
|
||||
stringlist_type * required_children = config_schema_item_get_required_children_value( schema_item , value );
|
||||
|
||||
if (required_children != NULL) {
|
||||
int ic;
|
||||
for (ic = 0; ic < stringlist_get_size( required_children ); ic++) {
|
||||
const char * req_child = stringlist_iget( required_children , ic );
|
||||
if (!config_content_has_item(content , req_child )) {
|
||||
char * error_message = util_alloc_sprintf("When:%s is set to:%s - you also must set:%s.",schema_kw , value , req_child );
|
||||
config_error_add( config_content_get_errors( content ) , error_message );
|
||||
free( error_message );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void config_validate(config_parser_type * config, config_content_type * content , const char * filename) {
|
||||
int size = hash_get_size(config->schema_items);
|
||||
char ** key_list = hash_alloc_keylist(config->schema_items);
|
||||
int ikey;
|
||||
for (ikey = 0; ikey < size; ikey++) {
|
||||
const config_schema_item_type * schema_item = config_get_schema_item( config , key_list[ikey]);
|
||||
const char * content_key = config_schema_item_get_kw( schema_item );
|
||||
if (config_content_has_item( content , content_key)) {
|
||||
const config_content_item_type * item = config_content_get_item(content , content_key);
|
||||
config_validate_content_item(config , content , item );
|
||||
} else {
|
||||
if (config_schema_item_required( schema_item)) { /* The item is not set ... */
|
||||
char * error_message = util_alloc_sprintf("Item:%s must be set - parsing:%s",content_key , config_content_get_config_file( content , true ));
|
||||
config_error_add( config_content_get_errors( content ) , error_message );
|
||||
free( error_message );
|
||||
}
|
||||
}
|
||||
}
|
||||
util_free_stringlist(key_list , size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
This function parses the config file 'filename', and updated the
|
||||
internal state of the config object as parsing proceeds. If
|
||||
comment_string != NULL everything following 'comment_string' on a
|
||||
line is discarded.
|
||||
|
||||
include_kw is a string identifier for an include functionality, if
|
||||
an include is encountered, the included file is parsed immediately
|
||||
(through a recursive call to config_parse__). if include_kw == NULL,
|
||||
include files are not supported.
|
||||
|
||||
Observe that use of include, relative paths and all that shit is
|
||||
quite tricky. The following is currently implemented:
|
||||
|
||||
1. The front_end function will split the path to the config file
|
||||
in a path_name component and a file component.
|
||||
|
||||
2. Recursive calls to config_parse__() will keep control of the
|
||||
parsers notion of cwd (note that the real OS'wise cwd never
|
||||
changes), and every item is tagged with the config_cwd
|
||||
currently active.
|
||||
|
||||
3. When an item has been entered with type CONFIG_FILE /
|
||||
CONFIG_DIRECTORY / CONFIG_EXECUTABLE - the item is updated to
|
||||
reflect to be relative (iff it is relative in the first place)
|
||||
to the path of the root config file.
|
||||
|
||||
These are not strict rules - it is possible to get other things to
|
||||
work as well, but the problem is that it very quickly becomes
|
||||
dependant on 'arbitrariness' in the parsing configuration.
|
||||
|
||||
validate: whether we should validate when complete, that should
|
||||
typically only be done at the last parsing.
|
||||
|
||||
|
||||
define_kw: This a string which can serve as a "#define" for the
|
||||
parsing. The define_kw keyword should have two arguments - a key
|
||||
and a value. If the define_kw is present all __subsequent__
|
||||
occurences of 'key' are replaced with 'value'. alloc_new_key
|
||||
is an optinal function (can be NULL) which is used to alloc a new
|
||||
key, i.e. add leading and trailing 'magic' characters.
|
||||
|
||||
|
||||
Example:
|
||||
--------
|
||||
|
||||
char * add_angular_brackets(const char * key) {
|
||||
char * new_key = util_alloc_sprintf("<%s>" , key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
config_parse(... , "myDEF" , add_angular_brackets , ...)
|
||||
|
||||
|
||||
Config file:
|
||||
-------------
|
||||
myDEF Name BJARNE
|
||||
myDEF sexual-pref Dogs
|
||||
...
|
||||
...
|
||||
PERSON <Name> 28 <sexual-pref>
|
||||
...
|
||||
------------
|
||||
|
||||
After parsing we will have an entry: "NAME" , "Bjarne" , "28" , "Dogs".
|
||||
|
||||
The key-value pairs internalized during the config parsing are NOT
|
||||
returned to the calling scope in any way.
|
||||
*/
|
||||
|
||||
|
||||
static void config_parse__(config_parser_type * config ,
|
||||
config_content_type * content ,
|
||||
path_stack_type * path_stack ,
|
||||
const char * config_input ,
|
||||
const char * comment_string ,
|
||||
const char * include_kw ,
|
||||
const char * define_kw ,
|
||||
config_schema_unrecognized_enum unrecognized,
|
||||
bool validate) {
|
||||
|
||||
/* Guard against circular includes. */
|
||||
{
|
||||
char * abs_filename = util_alloc_realpath(config_input);
|
||||
if (!config_content_add_file( content , abs_filename ))
|
||||
util_exit("%s: file:%s already parsed - circular include ? \n",__func__ , abs_filename);
|
||||
free( abs_filename );
|
||||
}
|
||||
config_path_elm_type * current_path_elm;
|
||||
|
||||
char * config_file;
|
||||
{
|
||||
/* Extract the path component of the current input file and chdir() */
|
||||
char * config_path;
|
||||
{
|
||||
char * config_base;
|
||||
char * config_ext;
|
||||
util_alloc_file_components( config_input , &config_path , &config_base , &config_ext);
|
||||
config_file = util_alloc_filename( NULL , config_base , config_ext );
|
||||
free( config_base );
|
||||
util_safe_free( config_ext );
|
||||
}
|
||||
current_path_elm = config_content_add_path_elm( content , config_path );
|
||||
path_stack_push_cwd( path_stack );
|
||||
if (config_path != NULL) {
|
||||
util_chdir( config_path );
|
||||
free( config_path );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
basic_parser_type * parser = basic_parser_alloc(" \t" , "\"", NULL , NULL , "--" , "\n");
|
||||
FILE * stream = util_fopen(config_file , "r");
|
||||
bool at_eof = false;
|
||||
|
||||
while (!at_eof) {
|
||||
int active_tokens;
|
||||
stringlist_type * token_list;
|
||||
char *line_buffer;
|
||||
|
||||
|
||||
line_buffer = util_fscanf_alloc_line(stream , &at_eof);
|
||||
if (line_buffer != NULL) {
|
||||
token_list = basic_parser_tokenize_buffer(parser , line_buffer , true);
|
||||
active_tokens = stringlist_get_size( token_list );
|
||||
|
||||
/*
|
||||
util_split_string(line_buffer , " \t" , &tokens , &token_list);
|
||||
active_tokens = tokens;
|
||||
for (i = 0; i < tokens; i++) {
|
||||
char * comment_ptr = NULL;
|
||||
if(comment_string != NULL)
|
||||
comment_ptr = strstr(token_list[i] , comment_string);
|
||||
|
||||
if (comment_ptr != NULL) {
|
||||
if (comment_ptr == token_list[i])
|
||||
active_tokens = i;
|
||||
else
|
||||
active_tokens = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (active_tokens > 0) {
|
||||
const char * kw = stringlist_iget( token_list , 0 );
|
||||
|
||||
/*Treating the include keyword. */
|
||||
if (include_kw != NULL && (strcmp(include_kw , kw) == 0)) {
|
||||
if (active_tokens != 2)
|
||||
util_abort("%s: keyword:%s must have exactly one argument. \n",__func__ ,include_kw);
|
||||
{
|
||||
const char *include_file = stringlist_iget( token_list , 1);
|
||||
if (util_file_exists( include_file ))
|
||||
config_parse__(config , content , path_stack , include_file , comment_string , include_kw , define_kw , unrecognized, false); /* Recursive call */
|
||||
else {
|
||||
char * error_message = util_alloc_sprintf("%s file:%s not found" , include_kw , include_file);
|
||||
config_error_add( config_content_get_errors( content ) , error_message );
|
||||
free( error_message );
|
||||
}
|
||||
}
|
||||
} else if ((define_kw != NULL) && (strcmp(define_kw , kw) == 0)) {
|
||||
/* Treating the define keyword. */
|
||||
if (active_tokens < 3)
|
||||
util_abort("%s: keyword:%s must have exactly one (or more) arguments. \n",__func__ , define_kw);
|
||||
{
|
||||
char * key = util_alloc_string_copy( stringlist_iget(token_list ,1) );
|
||||
char * value = stringlist_alloc_joined_substring( token_list , 2 , active_tokens , " ");
|
||||
|
||||
{
|
||||
char * filtered_value = subst_list_alloc_filtered_string( config_content_get_define_list( content ) , value);
|
||||
config_content_add_define( content , key , filtered_value );
|
||||
free( filtered_value );
|
||||
}
|
||||
free(key);
|
||||
free(value);
|
||||
}
|
||||
} else {
|
||||
if (hash_has_key(config->messages , kw))
|
||||
printf("%s \n", (const char *) hash_get(config->messages , kw));
|
||||
|
||||
if (!config_has_schema_item(config , kw)) {
|
||||
if (unrecognized == CONFIG_UNRECOGNIZED_WARN)
|
||||
fprintf(stderr,"** Warning keyword:%s not recognized when parsing:%s --- \n" , kw , config_input);
|
||||
else if (unrecognized == CONFIG_UNRECOGNIZED_ERROR) {
|
||||
char * error_message = util_alloc_sprintf("Keyword:%s is not recognized" , kw);
|
||||
config_error_add( config_content_get_errors( content ) , error_message );
|
||||
free( error_message );
|
||||
}
|
||||
}
|
||||
|
||||
if (config_has_schema_item(config , kw)) {
|
||||
config_schema_item_type * schema_item = config_get_schema_item( config , kw );
|
||||
char * config_cwd;
|
||||
util_alloc_file_components( config_file , &config_cwd , NULL , NULL );
|
||||
|
||||
if (!config_content_has_item( content , kw ))
|
||||
config_content_add_item( content , schema_item , current_path_elm);
|
||||
|
||||
|
||||
{
|
||||
subst_list_type * define_list = config_content_get_define_list( content );
|
||||
config_content_item_type * content_item = config_content_get_item( content , config_schema_item_get_kw( schema_item ) );
|
||||
config_content_node_type * new_node = config_content_item_set_arg__(define_list , config_content_get_errors( content ) , content_item , token_list , current_path_elm , config_file );
|
||||
if (new_node)
|
||||
config_content_add_node( content , new_node );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stringlist_free(token_list);
|
||||
free(line_buffer);
|
||||
}
|
||||
}
|
||||
if (validate)
|
||||
config_validate(config , content , config_file);
|
||||
fclose(stream);
|
||||
basic_parser_free( parser );
|
||||
}
|
||||
free(config_file);
|
||||
path_stack_pop( path_stack );
|
||||
config_content_pop_path_stack( content );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
config_content_type * config_parse(config_parser_type * config ,
|
||||
const char * filename,
|
||||
const char * comment_string ,
|
||||
const char * include_kw ,
|
||||
const char * define_kw ,
|
||||
config_schema_unrecognized_enum unrecognized_behaviour,
|
||||
bool validate) {
|
||||
|
||||
config_content_type * content = config_content_alloc( );
|
||||
|
||||
if (util_file_readable( filename )) {
|
||||
path_stack_type * path_stack = path_stack_alloc();
|
||||
{
|
||||
config_content_set_config_file( content , filename );
|
||||
config_content_set_invoke_path( content );
|
||||
config_parse__(config , content , path_stack , filename , comment_string , include_kw , define_kw , unrecognized_behaviour , validate);
|
||||
}
|
||||
path_stack_free( path_stack );
|
||||
} else {
|
||||
char * error_message = util_alloc_sprintf("Could not open file:%s for parsing" , filename);
|
||||
config_error_add( config_content_get_errors( content ) , error_message );
|
||||
free( error_message );
|
||||
}
|
||||
|
||||
if (config_error_count( config_content_get_errors( content ) ) == 0)
|
||||
config_content_set_valid( content );
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
This function adds an alias to an existing item; so that the
|
||||
value+++ of an item can be referred to by two different names.
|
||||
*/
|
||||
|
||||
|
||||
void config_add_alias(config_parser_type * config , const char * src , const char * alias) {
|
||||
if (config_has_schema_item(config , src)) {
|
||||
config_schema_item_type * item = config_get_schema_item(config , src);
|
||||
config_insert_schema_item(config , alias , item , true);
|
||||
} else
|
||||
util_abort("%s: item:%s not recognized \n",__func__ , src);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void config_install_message(config_parser_type * config , const char * kw, const char * message) {
|
||||
hash_insert_hash_owned_ref(config->messages , kw , util_alloc_string_copy(message) , free);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#include "config_get.c"
|
||||
|
||||
|
||||
+56
-56
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2012 Statoil ASA, Norway.
|
||||
|
||||
The file 'config_schema_item.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2012 Statoil ASA, Norway.
|
||||
|
||||
The file 'config_schema_item.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
typedef struct validate_struct validate_type;
|
||||
|
||||
/**
|
||||
/**
|
||||
This is a 'support-struct' holding various pieces of information
|
||||
needed during the validation process. Observe the following about
|
||||
validation:
|
||||
@@ -51,10 +51,10 @@ typedef struct validate_struct validate_type;
|
||||
2. Validation is a two-step process, the first step is run when an
|
||||
item is parsed. This includes checking:
|
||||
|
||||
o The number of argument.
|
||||
o The number of argument.
|
||||
o That the arguments have the right type.
|
||||
o That the values match the selection set.
|
||||
|
||||
|
||||
The second validation step is done when the pasing is complete,
|
||||
in this pass we check dependencies - i.e. required_children and
|
||||
required_children_on_value.
|
||||
@@ -69,11 +69,11 @@ typedef struct validate_struct validate_type;
|
||||
argc_max first.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
struct validate_struct {
|
||||
int argc_min; /* The minimum number of arguments: -1 means no lower limit. */
|
||||
int argc_max; /* The maximum number of arguments: -1 means no upper limit. */
|
||||
set_type * common_selection_set; /* A selection set which will apply uniformly to all the arguments. */
|
||||
int argc_max; /* The maximum number of arguments: -1 means no upper limit. */
|
||||
set_type * common_selection_set; /* A selection set which will apply uniformly to all the arguments. */
|
||||
set_type ** indexed_selection_set; /* A selection set which will apply for specifi (indexed) arguments. */
|
||||
int_vector_type * type_map; /* A list of types for the items. Set along with argc_minmax(); */
|
||||
stringlist_type * required_children; /* A list of item's which must also be set (if this item is set). (can be NULL) */
|
||||
@@ -88,13 +88,13 @@ struct validate_struct {
|
||||
struct config_schema_item_struct {
|
||||
UTIL_TYPE_ID_DECLARATION;
|
||||
char * kw; /* The kw which identifies this item· */
|
||||
|
||||
|
||||
bool required_set;
|
||||
|
||||
bool required_set;
|
||||
stringlist_type * required_children; /* A list of item's which must also be set (if this item is set). (can be NULL) */
|
||||
hash_type * required_children_value; /* A list of item's which must also be set - depending on the value of this item. (can be NULL) */
|
||||
validate_type * validate; /* Information need during validation. */
|
||||
bool expand_envvar; /* Should environment variables like $HOME be expanded?*/
|
||||
validate_type * validate; /* Information need during validation. */
|
||||
bool expand_envvar; /* Should environment variables like $HOME be expanded?*/
|
||||
};
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ static validate_type * validate_alloc() {
|
||||
validate->indexed_selection_set = NULL;
|
||||
validate->required_children = NULL;
|
||||
validate->required_children_value = NULL;
|
||||
validate->type_map = int_vector_alloc(0 , 0);
|
||||
validate->type_map = int_vector_alloc(0 , 0);
|
||||
validate_set_default_type( validate , CONFIG_STRING );
|
||||
return validate;
|
||||
}
|
||||
@@ -128,7 +128,7 @@ static void validate_free(validate_type * validate) {
|
||||
set_free(validate->indexed_selection_set[i]);
|
||||
free(validate->indexed_selection_set);
|
||||
}
|
||||
|
||||
|
||||
int_vector_free( validate->type_map );
|
||||
if (validate->required_children != NULL) stringlist_free(validate->required_children);
|
||||
if (validate->required_children_value != NULL) hash_free(validate->required_children_value);
|
||||
@@ -142,27 +142,27 @@ static void validate_iset_type( validate_type * validate , int index , config_it
|
||||
|
||||
|
||||
static config_item_types validate_iget_type( const validate_type * validate , int index) {
|
||||
return int_vector_safe_iget( validate->type_map , index );
|
||||
return int_vector_safe_iget( validate->type_map , index );
|
||||
}
|
||||
|
||||
|
||||
static void validate_set_argc_minmax(validate_type * validate , int argc_min , int argc_max) {
|
||||
if (validate->argc_min != CONFIG_DEFAULT_ARG_MIN)
|
||||
util_abort("%s: sorry - current implementation does not allow repeated calls to: %s \n",__func__ , __func__);
|
||||
|
||||
|
||||
if (argc_min == CONFIG_DEFAULT_ARG_MIN)
|
||||
argc_min = 0;
|
||||
|
||||
validate->argc_min = argc_min;
|
||||
validate->argc_max = argc_max;
|
||||
|
||||
|
||||
if ((argc_max != CONFIG_DEFAULT_ARG_MAX) && (argc_max < argc_min))
|
||||
util_abort("%s invalid arg min/max values. argc_min:%d argc_max:%d \n",__func__ , argc_min , argc_max);
|
||||
|
||||
|
||||
{
|
||||
int internal_type_size = 0; /* Should end up in the range [argc_min,argc_max] */
|
||||
|
||||
if (argc_max > 0)
|
||||
if (argc_max > 0)
|
||||
internal_type_size = argc_max;
|
||||
else
|
||||
internal_type_size = argc_min;
|
||||
@@ -185,16 +185,16 @@ static void validate_set_common_selection_set(validate_type * validate , int arg
|
||||
|
||||
|
||||
static void validate_set_indexed_selection_set(validate_type * validate , int index , int argc , const char ** argv) {
|
||||
|
||||
|
||||
if (validate->indexed_selection_set == NULL)
|
||||
util_abort("%s: must call xxx_set_argc_minmax() first - aborting \n",__func__);
|
||||
|
||||
|
||||
if (index >= validate->argc_min)
|
||||
util_abort("%s: When not not setting argc_max selection set can only be applied to indices up to argc_min\n",__func__);
|
||||
|
||||
|
||||
if (validate->indexed_selection_set[index] != NULL)
|
||||
set_free(validate->indexed_selection_set[index]);
|
||||
|
||||
|
||||
validate->indexed_selection_set[index] = set_alloc(argc , argv);
|
||||
}
|
||||
|
||||
@@ -206,10 +206,10 @@ static UTIL_SAFE_CAST_FUNCTION( config_schema_item , CONFIG_SCHEMA_ITEM_ID)
|
||||
|
||||
void config_schema_item_assure_type(const config_schema_item_type * item , int index , int type_mask) {
|
||||
bool OK = false;
|
||||
|
||||
|
||||
if (int_vector_safe_iget( item->validate->type_map , index) & type_mask)
|
||||
OK = true;
|
||||
|
||||
|
||||
if (!OK)
|
||||
util_abort("%s: failed - wrong installed type \n" , __func__);
|
||||
}
|
||||
@@ -233,7 +233,7 @@ config_schema_item_type * config_schema_item_alloc(const char * kw , bool requir
|
||||
|
||||
static char * __alloc_relocated__(const config_path_elm_type * path_elm , const char * value) {
|
||||
char * file;
|
||||
|
||||
|
||||
if (util_is_abs_path(value))
|
||||
file = util_alloc_string_copy( value );
|
||||
else
|
||||
@@ -251,11 +251,11 @@ bool config_schema_item_validate_set(const config_schema_item_type * item , stri
|
||||
OK = false;
|
||||
{
|
||||
char * error_message;
|
||||
if (config_file != NULL)
|
||||
if (config_file != NULL)
|
||||
error_message = util_alloc_sprintf("Error when parsing config_file:\"%s\" Keyword:%s must have at least %d arguments.",config_file , item->kw , item->validate->argc_min);
|
||||
else
|
||||
error_message = util_alloc_sprintf("Error:: Keyword:%s must have at least %d arguments.",item->kw , item->validate->argc_min);
|
||||
|
||||
|
||||
config_error_add( error_list , error_message );
|
||||
}
|
||||
}
|
||||
@@ -266,22 +266,22 @@ bool config_schema_item_validate_set(const config_schema_item_type * item , stri
|
||||
OK = false;
|
||||
{
|
||||
char * error_message;
|
||||
|
||||
|
||||
if (config_file != NULL)
|
||||
error_message = util_alloc_sprintf("Error when parsing config_file:\"%s\" Keyword:%s must have maximum %d arguments.",config_file , item->kw , item->validate->argc_max);
|
||||
else
|
||||
error_message = util_alloc_sprintf("Error:: Keyword:%s must have maximum %d arguments.",item->kw , item->validate->argc_max);
|
||||
|
||||
|
||||
config_error_add( error_list , error_message );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
OK - now we have verified that the number of arguments is correct. Then
|
||||
we start actually looking at the values.
|
||||
we start actually looking at the values.
|
||||
*/
|
||||
if (OK) {
|
||||
if (OK) {
|
||||
/* Validating selection set - first common, then indexed */
|
||||
if (item->validate->common_selection_set) {
|
||||
for (int iarg = 0; iarg < argc; iarg++) {
|
||||
@@ -344,14 +344,14 @@ bool config_schema_item_validate_set(const config_schema_item_type * item , stri
|
||||
/*
|
||||
1. If the supplied value is an abolute path - do nothing.
|
||||
2. If the supplied is _not_ an absolute path:
|
||||
|
||||
|
||||
a. Try if the relocated exists - then use that.
|
||||
b. Else - try if the util_alloc_PATH_executable() exists.
|
||||
*/
|
||||
if (!util_is_abs_path( value )) {
|
||||
char * relocated = __alloc_relocated__(path_elm , value);
|
||||
char * path_exe = util_alloc_PATH_executable( value );
|
||||
|
||||
|
||||
if (util_file_exists(relocated)) {
|
||||
if (util_is_executable(relocated))
|
||||
stringlist_iset_copy( token_list , iarg , relocated);
|
||||
@@ -359,7 +359,7 @@ bool config_schema_item_validate_set(const config_schema_item_type * item , stri
|
||||
stringlist_iset_copy( token_list , iarg , path_exe);
|
||||
else
|
||||
config_error_add( error_list , util_alloc_sprintf("Could not locate executable:%s ", value));
|
||||
|
||||
|
||||
free(relocated);
|
||||
util_safe_free(path_exe);
|
||||
} else {
|
||||
@@ -384,7 +384,7 @@ bool config_schema_item_validate_set(const config_schema_item_type * item , stri
|
||||
util_abort("%s: config_item_type:%d not recognized \n",__func__ , validate_iget_type(item->validate , iarg));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
@@ -393,7 +393,7 @@ bool config_schema_item_validate_set(const config_schema_item_type * item , stri
|
||||
void config_schema_item_free( config_schema_item_type * item) {
|
||||
free(item->kw);
|
||||
if (item->required_children != NULL) stringlist_free(item->required_children);
|
||||
if (item->required_children_value != NULL) hash_free(item->required_children_value);
|
||||
if (item->required_children_value != NULL) hash_free(item->required_children_value);
|
||||
validate_free(item->validate);
|
||||
free(item);
|
||||
}
|
||||
@@ -423,10 +423,10 @@ void config_schema_item_set_required_children_on_value(config_schema_item_type *
|
||||
*/
|
||||
|
||||
|
||||
void config_schema_item_set_argc_minmax(config_schema_item_type * item ,
|
||||
int argc_min ,
|
||||
void config_schema_item_set_argc_minmax(config_schema_item_type * item ,
|
||||
int argc_min ,
|
||||
int argc_max) {
|
||||
|
||||
|
||||
validate_set_argc_minmax(item->validate , argc_min , argc_max);
|
||||
|
||||
}
|
||||
@@ -444,7 +444,7 @@ config_item_types config_schema_item_iget_type(const config_schema_item_type * i
|
||||
return validate_iget_type( item->validate , index );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void config_schema_item_set_envvar_expansion( config_schema_item_type * item , bool expand_envvar ) {
|
||||
@@ -469,7 +469,7 @@ void config_schema_item_set_required_children(config_schema_item_type * item , s
|
||||
void config_schema_item_add_required_children(config_schema_item_type * item , const char * child_key) {
|
||||
if (item->required_children == NULL)
|
||||
item->required_children = stringlist_alloc_new();
|
||||
|
||||
|
||||
stringlist_append_copy( item->required_children , child_key );
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,10 @@ add_executable( config_error config_error.c)
|
||||
target_link_libraries( config_error config test_util )
|
||||
add_test( config_error ${EXECUTABLE_OUTPUT_PATH}/config_error )
|
||||
|
||||
add_executable( config_content config_content.c)
|
||||
target_link_libraries( config_content config test_util )
|
||||
add_test( config_content ${EXECUTABLE_OUTPUT_PATH}/config_content )
|
||||
|
||||
|
||||
add_executable( config_config config_config.c)
|
||||
target_link_libraries( config_config config test_util )
|
||||
|
||||
+17
-8
@@ -20,27 +20,36 @@
|
||||
|
||||
#include <ert/util/test_util.h>
|
||||
|
||||
#include <ert/config/config.h>
|
||||
#include <ert/config/config_parser.h>
|
||||
#include <ert/config/config_content.h>
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc , char ** argv) {
|
||||
const char * config_file = argv[1];
|
||||
config_type * config = config_alloc();
|
||||
config_parser_type * config = config_alloc();
|
||||
config_schema_item_type * item = config_add_schema_item(config , "APPEND" , false );
|
||||
config_schema_item_set_argc_minmax( item , 1 , 1);
|
||||
|
||||
test_assert_true(config_parse(config , config_file , "--" , NULL , NULL , false , true ));
|
||||
|
||||
{
|
||||
test_assert_int_equal( config_get_occurences( config , "APPEND" ) , 3);
|
||||
config_content_type * content = config_parse(config , config_file , "--" , NULL , NULL , false , true );
|
||||
test_assert_true(config_content_is_instance( content ));
|
||||
test_assert_true(config_content_is_valid( content ));
|
||||
test_assert_int_equal( config_content_get_occurences( content , "APPEND" ) , 3);
|
||||
|
||||
{
|
||||
const char * value = config_get_value( config , "APPEND");
|
||||
const char * value = config_content_get_value( content , "APPEND");
|
||||
test_assert_string_equal( value , "VALUE3");
|
||||
}
|
||||
}
|
||||
|
||||
test_assert_false( config_parse( config , "DoesNotExist" , "--" , NULL , NULL , false , true));
|
||||
config_content_free( content );
|
||||
}
|
||||
|
||||
{
|
||||
config_content_type * content = config_parse( config , "DoesNotExist" , "--" , NULL , NULL , false , true);
|
||||
test_assert_false( config_content_is_valid( content ));
|
||||
config_content_free( content );
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
+50
-40
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2013 Statoil ASA, Norway.
|
||||
|
||||
The file 'config_argc.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2013 Statoil ASA, Norway.
|
||||
|
||||
The file 'config_argc.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
@@ -24,14 +24,14 @@
|
||||
#include <ert/util/test_util.h>
|
||||
#include <ert/util/util.h>
|
||||
|
||||
#include <ert/config/config.h>
|
||||
#include <ert/config/config_parser.h>
|
||||
#include <ert/config/config_schema_item.h>
|
||||
#include <ert/config/config_error.h>
|
||||
|
||||
void install_SIGNALS(void) {
|
||||
signal(SIGSEGV , util_abort_signal); /* Segmentation violation, i.e. overwriting memory ... */
|
||||
signal(SIGINT , util_abort_signal); /* Control C */
|
||||
signal(SIGTERM , util_abort_signal); /* If killing the program with SIGTERM (the default kill signal) you will get a backtrace.
|
||||
signal(SIGTERM , util_abort_signal); /* If killing the program with SIGTERM (the default kill signal) you will get a backtrace.
|
||||
Killing with SIGKILL (-9) will not give a backtrace.*/
|
||||
}
|
||||
|
||||
@@ -43,38 +43,48 @@ int main(int argc , char ** argv) {
|
||||
const char * argc_OK = argv[1];
|
||||
const char * argc_less = argv[2];
|
||||
const char * argc_more = argv[3];
|
||||
|
||||
config_type * config = config_alloc();
|
||||
|
||||
config_parser_type * config = config_alloc();
|
||||
config_schema_item_type * schema_item = config_add_schema_item( config , "ITEM" , false );
|
||||
config_schema_item_set_argc_minmax( schema_item , 2 , 2 );
|
||||
|
||||
test_assert_true( config_parse( config , argc_OK , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_ERROR , true));
|
||||
config_clear( config );
|
||||
|
||||
test_assert_false( config_parse( config , argc_less , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_ERROR , true));
|
||||
{
|
||||
const config_error_type * config_error = config_get_errors( config );
|
||||
const char * error_msg = "Error when parsing config_file:\"argc_less\" Keyword:ITEM must have at least 2 arguments.";
|
||||
|
||||
test_assert_int_equal( config_error_count( config_error ) , 1);
|
||||
test_assert_string_equal( config_error_iget( config_error , 0 ) , error_msg);
|
||||
config_content_type * content = config_parse( config , argc_OK , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_ERROR , true);
|
||||
test_assert_true( config_content_is_instance( content ));
|
||||
test_assert_true(config_content_is_valid( content ));
|
||||
config_content_free( content );
|
||||
}
|
||||
config_clear( config );
|
||||
|
||||
|
||||
test_assert_false( config_parse( config , argc_more , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_ERROR , true));
|
||||
{
|
||||
const config_error_type * config_error = config_get_errors( config );
|
||||
const char * error_msg = "Error when parsing config_file:\"argc_more\" Keyword:ITEM must have maximum 2 arguments.";
|
||||
|
||||
test_assert_int_equal( config_error_count( config_error ) , 1);
|
||||
test_assert_string_equal( config_error_iget( config_error , 0 ) , error_msg);
|
||||
}
|
||||
config_clear( config );
|
||||
config_content_type * content = config_parse( config , argc_less , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_ERROR , true);
|
||||
test_assert_true( config_content_is_instance( content ));
|
||||
test_assert_false( config_content_is_valid( content ));
|
||||
|
||||
{
|
||||
const config_error_type * config_error = config_content_get_errors( content );
|
||||
const char * error_msg = "Error when parsing config_file:\"argc_less\" Keyword:ITEM must have at least 2 arguments.";
|
||||
|
||||
test_assert_int_equal( config_error_count( config_error ) , 1);
|
||||
test_assert_string_equal( config_error_iget( config_error , 0 ) , error_msg);
|
||||
}
|
||||
config_content_free( content );
|
||||
}
|
||||
|
||||
{
|
||||
config_content_type * content = config_parse( config , argc_more , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_ERROR , true);
|
||||
test_assert_true( config_content_is_instance( content ));
|
||||
test_assert_false( config_content_is_valid( content ));
|
||||
{
|
||||
const config_error_type * config_error = config_content_get_errors( content );
|
||||
const char * error_msg = "Error when parsing config_file:\"argc_more\" Keyword:ITEM must have maximum 2 arguments.";
|
||||
|
||||
test_assert_int_equal( config_error_count( config_error ) , 1);
|
||||
test_assert_string_equal( config_error_iget( config_error , 0 ) , error_msg);
|
||||
}
|
||||
config_content_free( content );
|
||||
}
|
||||
|
||||
|
||||
config_free( config );
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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);
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright (C) 2015 Statoil ASA, Norway.
|
||||
|
||||
The file 'config_content.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#include <ert/util/test_util.h>
|
||||
|
||||
#include <ert/config/config_content.h>
|
||||
|
||||
|
||||
void test_create() {
|
||||
config_content_type * content = config_content_alloc( );
|
||||
test_assert_true( config_content_is_instance( content ) );
|
||||
config_content_free( content );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int main( int argc , char ** argv) {
|
||||
test_create();
|
||||
}
|
||||
+15
-16
@@ -23,7 +23,7 @@
|
||||
#include <ert/util/util.h>
|
||||
#include <ert/util/hash.h>
|
||||
|
||||
#include <ert/config/config.h>
|
||||
#include <ert/config/config_parser.h>
|
||||
#include <ert/config/config_content_node.h>
|
||||
#include <ert/config/config_schema_item.h>
|
||||
#include <ert/config/config_path_elm.h>
|
||||
@@ -31,28 +31,27 @@
|
||||
|
||||
int main(int argc , char ** argv) {
|
||||
const char * config_file = argv[1];
|
||||
config_type * config = config_alloc();
|
||||
|
||||
config_parser_type * config = config_alloc();
|
||||
|
||||
config_add_schema_item( config , "SET" , true );
|
||||
config_add_schema_item( config , "NOTSET" , false );
|
||||
|
||||
test_assert_true( config_parse( config , config_file , "--" , "INCLUDE" , NULL , CONFIG_UNRECOGNIZED_IGNORE , true ));
|
||||
{
|
||||
config_content_type * content = config_parse( config , config_file , "--" , "INCLUDE" , NULL , CONFIG_UNRECOGNIZED_IGNORE , true );
|
||||
test_assert_true( config_content_is_instance( content ));
|
||||
test_assert_true(config_content_is_valid( content ));
|
||||
|
||||
test_assert_not_NULL( config_get_content_item( config , "SET" ));
|
||||
test_assert_NULL( config_get_content_item( config , "NOTSET" ) );
|
||||
test_assert_NULL( config_get_content_item( config , "UNKNOWN" ) );
|
||||
test_assert_true( config_content_has_item( content , "SET" ));
|
||||
test_assert_false( config_content_has_item( content , "NOTSET" ) );
|
||||
test_assert_false( config_content_has_item( content , "UNKNOWN" ) );
|
||||
|
||||
test_assert_true( config_has_schema_item( config , "SET" ));
|
||||
test_assert_true( config_has_schema_item( config , "NOTSET" ));
|
||||
test_assert_false( config_has_schema_item( config , "UNKNOWN" ));
|
||||
test_assert_true( config_has_schema_item( config , "SET" ));
|
||||
test_assert_true( config_has_schema_item( config , "NOTSET" ));
|
||||
test_assert_false( config_has_schema_item( config , "UNKNOWN" ));
|
||||
|
||||
test_assert_true( config_has_content_item( config , "SET" ));
|
||||
test_assert_false( config_has_content_item( config , "NOTSET" ));
|
||||
test_assert_false( config_has_content_item( config , "UNKNOWN" ));
|
||||
|
||||
|
||||
config_content_free( content );
|
||||
}
|
||||
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
+19
-13
@@ -23,16 +23,18 @@
|
||||
#include <ert/util/util.h>
|
||||
#include <ert/util/subst_list.h>
|
||||
|
||||
#include <ert/config/config.h>
|
||||
#include <ert/config/config_parser.h>
|
||||
#include <ert/config/config_content_node.h>
|
||||
#include <ert/config/config_schema_item.h>
|
||||
#include <ert/config/config_path_elm.h>
|
||||
|
||||
|
||||
void test_define(config_type * config , const char * config_file) {
|
||||
test_assert_true( config_parse( config , config_file , NULL , NULL , "DEFINE" , CONFIG_UNRECOGNIZED_IGNORE , true ));
|
||||
void test_define(config_parser_type * config , const char * config_file) {
|
||||
config_content_type * content = config_parse( config , config_file , NULL , NULL , "DEFINE" , CONFIG_UNRECOGNIZED_IGNORE , true );
|
||||
test_assert_true( config_content_is_instance( content ));
|
||||
test_assert_true(config_content_is_valid( content ));
|
||||
{
|
||||
const subst_list_type * define_list = config_get_define_list( config );
|
||||
const subst_list_type * define_list = config_content_get_define_list( content );
|
||||
test_assert_true( subst_list_has_key( define_list , "VAR1"));
|
||||
test_assert_true( subst_list_has_key( define_list , "VAR2"));
|
||||
test_assert_true( subst_list_has_key( define_list , "VARX"));
|
||||
@@ -43,12 +45,13 @@ void test_define(config_type * config , const char * config_file) {
|
||||
test_assert_string_equal( subst_list_get_value( define_list , "VAR2") , "10");
|
||||
test_assert_string_equal( subst_list_get_value( define_list , "VARX") , "1");
|
||||
}
|
||||
config_content_free( content );
|
||||
}
|
||||
|
||||
|
||||
|
||||
config_type * config_create_schema() {
|
||||
config_type * config = config_alloc();
|
||||
config_parser_type * config_create_schema() {
|
||||
config_parser_type * config = config_alloc();
|
||||
|
||||
config_add_schema_item( config , "SET" , true );
|
||||
config_add_schema_item( config , "NOTSET" , false );
|
||||
@@ -58,12 +61,15 @@ config_type * config_create_schema() {
|
||||
|
||||
|
||||
int main(int argc , char ** argv) {
|
||||
const char * config_file = argv[1];
|
||||
config_type * config = config_create_schema();
|
||||
|
||||
test_define( config , config_file );
|
||||
|
||||
config_free( config );
|
||||
exit(0);
|
||||
util_install_signals();
|
||||
{
|
||||
const char * config_file = argv[1];
|
||||
config_parser_type * config = config_create_schema();
|
||||
|
||||
test_define( config , config_file );
|
||||
|
||||
config_free( config );
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+22
-20
@@ -24,10 +24,11 @@
|
||||
#include <ert/util/util.h>
|
||||
#include <ert/util/path_stack.h>
|
||||
|
||||
#include <ert/config/config.h>
|
||||
#include <ert/config/config_parser.h>
|
||||
#include <ert/config/config_schema_item.h>
|
||||
#include <ert/config/config_content.h>
|
||||
|
||||
void parse_test(config_type * config ,
|
||||
void parse_test(config_parser_type * config ,
|
||||
const char * root_path , // The new working directory - the test will start by chdir() here.
|
||||
const char * config_file ) { // The config_file, either as an absolute path - or relative from root_path
|
||||
|
||||
@@ -52,9 +53,9 @@ void parse_test(config_type * config ,
|
||||
config_rel_path = util_alloc_rel_path( NULL , config_abs_path);
|
||||
|
||||
{
|
||||
config_clear( config );
|
||||
if (config_parse( config , config_file , "--" , "INCLUDE" , NULL , CONFIG_UNRECOGNIZED_IGNORE , true )) {
|
||||
|
||||
config_content_type * content = config_parse( config , config_file , "--" , "INCLUDE" , NULL , CONFIG_UNRECOGNIZED_IGNORE , true );
|
||||
if (config_content_is_valid( content )) {
|
||||
|
||||
char * relpath0 = util_alloc_filename( config_rel_path , path0, NULL);
|
||||
char * relpath1 = util_alloc_filename( config_rel_path , path1, NULL);
|
||||
char * relpath2 = util_alloc_filename( config_rel_path , path2, NULL);
|
||||
@@ -66,24 +67,25 @@ void parse_test(config_type * config ,
|
||||
char * abspath2 = util_alloc_filename( config_abs_path , path2, NULL);
|
||||
char * abspath3 = util_alloc_filename( config_abs_path , path3, NULL);
|
||||
char * abspath4 = util_alloc_filename( config_abs_path , path4, NULL);
|
||||
|
||||
test_assert_string_equal(config_get_value_as_relpath(config , "PATH0") , relpath0 );
|
||||
test_assert_string_equal(config_get_value_as_relpath(config , "PATH1") , relpath1 );
|
||||
test_assert_string_equal(config_get_value_as_relpath(config , "PATH2") , relpath2 );
|
||||
test_assert_string_equal(config_get_value_as_relpath(config , "PATH3") , relpath3 );
|
||||
test_assert_string_equal(config_get_value_as_relpath(config , "PATH4") , relpath4 );
|
||||
|
||||
test_assert_string_equal(config_get_value_as_abspath(config , "PATH0") , abspath0 );
|
||||
test_assert_string_equal(config_get_value_as_abspath(config , "PATH1") , abspath1 );
|
||||
test_assert_string_equal(config_get_value_as_abspath(config , "PATH2") , abspath2 );
|
||||
test_assert_string_equal(config_get_value_as_abspath(config , "PATH3") , abspath3 );
|
||||
test_assert_string_equal(config_get_value_as_abspath(config , "PATH4") , abspath4 );
|
||||
|
||||
|
||||
test_assert_string_equal(config_content_get_value_as_relpath(content , "PATH0") , relpath0 );
|
||||
test_assert_string_equal(config_content_get_value_as_relpath(content , "PATH1") , relpath1 );
|
||||
test_assert_string_equal(config_content_get_value_as_relpath(content , "PATH2") , relpath2 );
|
||||
test_assert_string_equal(config_content_get_value_as_relpath(content , "PATH3") , relpath3 );
|
||||
test_assert_string_equal(config_content_get_value_as_relpath(content , "PATH4") , relpath4 );
|
||||
|
||||
test_assert_string_equal(config_content_get_value_as_abspath(content , "PATH0") , abspath0 );
|
||||
test_assert_string_equal(config_content_get_value_as_abspath(content , "PATH1") , abspath1 );
|
||||
test_assert_string_equal(config_content_get_value_as_abspath(content , "PATH2") , abspath2 );
|
||||
test_assert_string_equal(config_content_get_value_as_abspath(content , "PATH3") , abspath3 );
|
||||
test_assert_string_equal(config_content_get_value_as_abspath(content , "PATH4") , abspath4 );
|
||||
|
||||
} else {
|
||||
config_error_type * error = config_get_errors( config );
|
||||
const config_error_type * error = config_content_get_errors( content );
|
||||
config_error_fprintf( error , true , stdout );
|
||||
test_error_exit("Hmm - parsing %s failed \n", config_file );
|
||||
}
|
||||
config_content_free( content );
|
||||
}
|
||||
path_stack_pop( path_stack );
|
||||
}
|
||||
@@ -93,7 +95,7 @@ int main(int argc , char ** argv) {
|
||||
const char * abs_path = argv[1];
|
||||
const char * config_file = argv[2];
|
||||
char * abs_config_file = util_alloc_filename( abs_path , config_file , NULL);
|
||||
config_type * config = config_alloc();
|
||||
config_parser_type * config = config_alloc();
|
||||
|
||||
{
|
||||
config_schema_item_type * schema_item;
|
||||
|
||||
+13
-11
@@ -18,30 +18,31 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <ert/config/config.h>
|
||||
#include <ert/config/config_parser.h>
|
||||
#include <ert/config/config_content.h>
|
||||
|
||||
|
||||
|
||||
int main(int argc , char ** argv) {
|
||||
const char * config_file = argv[1];
|
||||
config_type * config = config_alloc();
|
||||
bool OK;
|
||||
config_parser_type * config = config_alloc();
|
||||
{
|
||||
config_schema_item_type * item = config_add_schema_item(config , "APPEND" , false );
|
||||
config_schema_item_set_argc_minmax( item , 1 , 1);
|
||||
}
|
||||
config_add_schema_item(config , "NEXT" , false );
|
||||
|
||||
OK = config_parse(config , config_file , "--" , NULL , NULL , false , true );
|
||||
|
||||
if (OK) {
|
||||
if (config_get_content_size( config ) == 4) {
|
||||
const config_content_node_type * node0 = config_iget_content_node( config , 0 );
|
||||
|
||||
config_content_type * content = config_parse(config , config_file , "--" , NULL , NULL , false , true );
|
||||
|
||||
if (config_content_is_valid( content )) {
|
||||
if (config_content_get_size( content ) == 4) {
|
||||
const config_content_node_type * node0 = config_content_iget_node( content , 0 );
|
||||
if (strcmp( config_content_node_get_kw( node0 ) , "APPEND") == 0) {
|
||||
if (config_content_node_get_size(node0) == 1) {
|
||||
const config_content_node_type * node3 = config_iget_content_node( config , 3 );
|
||||
const config_content_node_type * node3 = config_content_iget_node( content , 3 );
|
||||
if (strcmp( config_content_node_get_kw( node3 ) , "NEXT") == 0) {
|
||||
if (config_content_node_get_size(node3) == 2) {
|
||||
config_content_free( content );
|
||||
exit(0);
|
||||
} else printf("Size error node3\n");
|
||||
} else printf("kw error node3 \n");
|
||||
@@ -49,7 +50,8 @@ int main(int argc , char ** argv) {
|
||||
} else printf("kw error node0 kw:%s \n", config_content_node_get_kw( node0 ));
|
||||
} else printf("Size error \n");
|
||||
} else printf("Parse error");
|
||||
|
||||
|
||||
config_content_free( content );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
#include <ert/util/util.h>
|
||||
#include <ert/util/test_work_area.h>
|
||||
|
||||
#include <ert/config/config.h>
|
||||
#include <ert/config/config_parser.h>
|
||||
#include <ert/config/config_path_elm.h>
|
||||
#include <ert/config/config_root_path.h>
|
||||
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@
|
||||
#include <ert/util/test_util.h>
|
||||
#include <ert/util/util.h>
|
||||
|
||||
#include <ert/config/config.h>
|
||||
#include <ert/config/config_parser.h>
|
||||
#include <ert/config/config_root_path.h>
|
||||
|
||||
|
||||
|
||||
+38
-34
@@ -1,25 +1,28 @@
|
||||
/*
|
||||
Copyright (C) 2012 Statoil ASA, Norway.
|
||||
|
||||
The file 'config_typeFail.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2012 Statoil ASA, Norway.
|
||||
|
||||
The file 'config_parser_typeFail.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <ert/util/test_util.h>
|
||||
|
||||
#include <ert/config/config_error.h>
|
||||
#include <ert/config/config.h>
|
||||
#include <ert/config/config_parser.h>
|
||||
#include <ert/config/config_content.h>
|
||||
|
||||
|
||||
void error(char * msg) {
|
||||
@@ -30,36 +33,37 @@ void error(char * msg) {
|
||||
|
||||
int main(int argc , char ** argv) {
|
||||
const char * config_file = argv[1];
|
||||
config_type * config = config_alloc();
|
||||
bool OK;
|
||||
config_parser_type * config = config_alloc();
|
||||
{
|
||||
config_schema_item_type * item = config_add_schema_item(config , "TYPES_KEY" , false );
|
||||
config_schema_item_set_argc_minmax( item , 4 , 4 );
|
||||
config_schema_item_set_argc_minmax( item , 4 , 4 );
|
||||
config_schema_item_iset_type( item , 0 , CONFIG_INT );
|
||||
config_schema_item_iset_type( item , 1 , CONFIG_FLOAT );
|
||||
config_schema_item_iset_type( item , 2 , CONFIG_BOOL );
|
||||
|
||||
|
||||
item = config_add_schema_item( config , "SHORT_KEY" , false );
|
||||
config_schema_item_set_argc_minmax( item , 1 , 1 );
|
||||
|
||||
|
||||
item = config_add_schema_item( config , "LONG_KEY" , false );
|
||||
config_schema_item_set_argc_minmax( item , 3 , CONFIG_DEFAULT_ARG_MAX);
|
||||
}
|
||||
OK = config_parse(config , config_file , "--" , NULL , NULL , false , true );
|
||||
|
||||
if (OK) {
|
||||
error("Parse error\n");
|
||||
} else {
|
||||
config_error_type * cerror = config_get_errors( config );
|
||||
if (config_error_count( cerror ) > 0) {
|
||||
int i;
|
||||
for (i=0; i < config_error_count( cerror ); i++) {
|
||||
printf("Error %d: %s \n",i , config_error_iget( cerror , i ));
|
||||
|
||||
{
|
||||
config_content_type * content = config_parse(config , config_file , "--" , NULL , NULL , false , true );
|
||||
|
||||
if (config_content_is_valid( content )) {
|
||||
error("Parse error\n");
|
||||
} else {
|
||||
const config_error_type * cerror = config_content_get_errors( content );
|
||||
if (config_error_count( cerror ) > 0) {
|
||||
int i;
|
||||
for (i=0; i < config_error_count( cerror ); i++) {
|
||||
printf("Error %d: %s \n",i , config_error_iget( cerror , i ));
|
||||
}
|
||||
}
|
||||
test_assert_int_equal( 5 , config_error_count( cerror ));
|
||||
}
|
||||
printf("Error count:%d \n",config_error_count( cerror ));
|
||||
if (config_error_count( cerror ) != 5)
|
||||
error("Wrong error count\n");
|
||||
config_content_free( content );
|
||||
}
|
||||
printf("OK \n");
|
||||
exit(0);
|
||||
|
||||
+27
-29
@@ -1,36 +1,33 @@
|
||||
/*
|
||||
Copyright (C) 2012 Statoil ASA, Norway.
|
||||
|
||||
The file 'config_typeOK.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2012 Statoil ASA, Norway.
|
||||
|
||||
The file 'config_parser_typeOK.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <ert/config/config.h>
|
||||
#include <ert/util/test_util.h>
|
||||
#include <ert/config/config_parser.h>
|
||||
#include <ert/config/config_content.h>
|
||||
|
||||
|
||||
void error(char * msg) {
|
||||
fprintf(stderr , msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc , char ** argv) {
|
||||
const char * config_file = argv[1];
|
||||
config_type * config = config_alloc();
|
||||
bool OK;
|
||||
config_parser_type * config = config_alloc();
|
||||
{
|
||||
config_schema_item_type * item = config_add_schema_item(config , "TYPE_KEY" , false );
|
||||
config_schema_item_set_argc_minmax( item , 4 , 4 );
|
||||
@@ -40,16 +37,17 @@ int main(int argc , char ** argv) {
|
||||
|
||||
item = config_add_schema_item( config , "SHORT_KEY" , false );
|
||||
config_schema_item_set_argc_minmax( item , 1 , 1 );
|
||||
|
||||
|
||||
item = config_add_schema_item( config , "LONG_KEY" , false );
|
||||
config_schema_item_set_argc_minmax( item , 3 , CONFIG_DEFAULT_ARG_MAX );
|
||||
}
|
||||
OK = config_parse(config , config_file , "--" , NULL , NULL , false , true );
|
||||
|
||||
if (OK) {
|
||||
|
||||
} else error("Parse error\n");
|
||||
|
||||
{
|
||||
config_content_type * content = config_parse(config , config_file , "--" , NULL , NULL , false , true );
|
||||
test_assert_true( config_content_is_valid( content ));
|
||||
config_content_free( content );
|
||||
}
|
||||
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,13 @@ if (BUILD_APPLICATIONS)
|
||||
set(program_list summary2csv2 summary2csv kw_extract grdecl_grid make_grid sum_write load_test grdecl_test grid_dump_ascii select_test grid_dump convert kw_list grid_info summary)
|
||||
endif()
|
||||
|
||||
if (BUILD_ERT)
|
||||
add_executable( ecl_quantile ecl_quantile.c )
|
||||
include_directories( ../../libconfig/include )
|
||||
target_link_libraries( ecl_quantile config )
|
||||
list( APPEND program_list ecl_quantile )
|
||||
endif()
|
||||
|
||||
|
||||
foreach(prog ${program_list})
|
||||
target_link_libraries( ${prog} ecl ert_util )
|
||||
|
||||
+37
-33
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'convert.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'convert.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -38,33 +38,37 @@ void file_convert(const char * src_file , const char * target_file, ecl_file_enu
|
||||
if (file_type != ECL_OTHER_FILE)
|
||||
formatted_src = fmt_src;
|
||||
else {
|
||||
if (util_fmt_bit8(src_file))
|
||||
if (util_fmt_bit8(src_file))
|
||||
formatted_src = true;
|
||||
else
|
||||
formatted_src = false;
|
||||
}
|
||||
|
||||
|
||||
target = fortio_open_writer(target_file , !formatted_src , ECL_ENDIAN_FLIP );
|
||||
src = fortio_open_reader(src_file , formatted_src , ECL_ENDIAN_FLIP);
|
||||
ecl_kw = ecl_kw_fread_alloc(src);
|
||||
if (ecl_kw == NULL) {
|
||||
fprintf(stderr,"Loading: %s failed - maybe you forgot the header? \n", src_file);
|
||||
abort();
|
||||
|
||||
while (true) {
|
||||
if (fortio_read_at_eof( src ))
|
||||
break;
|
||||
|
||||
{
|
||||
ecl_kw_type * ecl_kw = ecl_kw_fread_alloc( src );
|
||||
if (ecl_kw) {
|
||||
ecl_kw_fwrite(ecl_kw , target);
|
||||
ecl_kw_free(ecl_kw);
|
||||
} else {
|
||||
fprintf(stderr, "Reading keyword failed \n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (ecl_kw != NULL) {
|
||||
ecl_kw_fwrite(ecl_kw , target);
|
||||
|
||||
ecl_kw_free(ecl_kw);
|
||||
ecl_kw = ecl_kw_fread_alloc(src);
|
||||
}
|
||||
if (ecl_kw != NULL) ecl_kw_free(ecl_kw);
|
||||
fortio_fclose(src);
|
||||
fortio_fclose(target);
|
||||
}
|
||||
|
||||
|
||||
int main (int argc , char **argv) {
|
||||
int main (int argc , char **argv) {
|
||||
if (argc == 1) {
|
||||
fprintf(stderr,"Usage: convert.x <filename1> <filename2> <filename3> ...\n");
|
||||
exit(1);
|
||||
@@ -72,12 +76,12 @@ int main (int argc , char **argv) {
|
||||
|
||||
char *src_file = argv[1];
|
||||
char *target_file;
|
||||
|
||||
|
||||
int report_nr;
|
||||
ecl_file_enum file_type;
|
||||
bool fmt_file;
|
||||
file_type = ecl_util_get_file_type(src_file , &fmt_file , &report_nr);
|
||||
|
||||
|
||||
if (file_type == ECL_OTHER_FILE) {
|
||||
if (argc != 3) {
|
||||
fprintf(stderr,"When the file can not be recognized on the name as an ECLIPSE file you must give output_file as second (and final) argument \n");
|
||||
@@ -99,10 +103,10 @@ int main (int argc , char **argv) {
|
||||
exit(1);
|
||||
}
|
||||
util_alloc_file_components(src_file , &path , &basename , &extension);
|
||||
|
||||
|
||||
target_file = ecl_util_alloc_filename(path, basename , file_type , !fmt_file , report_nr);
|
||||
file_convert(src_file , target_file , file_type , fmt_file);
|
||||
|
||||
|
||||
free(path);
|
||||
free(basename);
|
||||
free(extension);
|
||||
|
||||
+111
-106
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_quantile.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_quantile.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* Must define this to get access to pthread_rwlock_t */
|
||||
@@ -32,7 +32,9 @@
|
||||
#include <ert/util/arg_pack.h>
|
||||
#include <ert/util/thread_pool.h>
|
||||
|
||||
#include <ert/config/config.h>
|
||||
#include <ert/config/config_parser.h>
|
||||
#include <ert/config/config_content.h>
|
||||
#include <ert/config/config_error.h>
|
||||
#include <ert/config/config_content_item.h>
|
||||
#include <ert/config/config_content_node.h>
|
||||
|
||||
@@ -41,7 +43,7 @@
|
||||
#define DEFAULT_NUM_INTERP 50
|
||||
#define SUMMARY_JOIN ":"
|
||||
#define MIN_SIZE 10
|
||||
#define LOAD_THREADS 4
|
||||
#define LOAD_THREADS 4
|
||||
|
||||
|
||||
typedef enum {
|
||||
@@ -62,7 +64,7 @@ typedef struct {
|
||||
|
||||
/**
|
||||
Microscopic data structure representing one column of data;
|
||||
i.e. one ECLIPSE summary key and one accompanying quantile value.
|
||||
i.e. one ECLIPSE summary key and one accompanying quantile value.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
@@ -124,7 +126,7 @@ sum_case_type * sum_case_fread_alloc( const char * data_file , const time_t_vect
|
||||
|
||||
sum_case->ecl_sum = ecl_sum_fread_alloc_case( data_file , SUMMARY_JOIN );
|
||||
sum_case->interp_data = double_vector_alloc(0 , 0);
|
||||
sum_case->interp_time = interp_time;
|
||||
sum_case->interp_time = interp_time;
|
||||
sum_case->start_time = ecl_sum_get_start_time( sum_case->ecl_sum );
|
||||
sum_case->end_time = ecl_sum_get_end_time( sum_case->ecl_sum );
|
||||
return sum_case;
|
||||
@@ -148,7 +150,7 @@ void sum_case_free__( void * sum_case) {
|
||||
|
||||
void ensemble_add_case( ensemble_type * ensemble , const char * data_file ) {
|
||||
sum_case_type * sum_case = sum_case_fread_alloc( data_file , ensemble->interp_time );
|
||||
|
||||
|
||||
pthread_rwlock_wrlock( &ensemble->rwlock );
|
||||
{
|
||||
printf("Loading case: %s \n", data_file );
|
||||
@@ -157,7 +159,7 @@ void ensemble_add_case( ensemble_type * ensemble , const char * data_file ) {
|
||||
ensemble->start_time = util_time_t_min( ensemble->start_time , sum_case->start_time);
|
||||
else
|
||||
ensemble->start_time = ecl_sum_get_start_time( sum_case->ecl_sum );
|
||||
|
||||
|
||||
ensemble->end_time = util_time_t_max( ensemble->end_time , sum_case->end_time);
|
||||
}
|
||||
pthread_rwlock_unlock( &ensemble->rwlock );
|
||||
@@ -216,7 +218,7 @@ ensemble_type * ensemble_alloc( ) {
|
||||
}
|
||||
|
||||
|
||||
void ensemble_init( ensemble_type * ensemble , config_type * config) {
|
||||
void ensemble_init( ensemble_type * ensemble , config_content_type * config) {
|
||||
|
||||
/*1 : Loading ensembles and settings from the config instance */
|
||||
/*1a: Loading the eclipse summary cases. */
|
||||
@@ -224,33 +226,32 @@ void ensemble_init( ensemble_type * ensemble , config_type * config) {
|
||||
thread_pool_type * tp = thread_pool_alloc( LOAD_THREADS , true );
|
||||
{
|
||||
int i,j;
|
||||
const config_content_item_type * case_item = config_get_content_item( config , "CASE_LIST" );
|
||||
|
||||
if (case_item != NULL) {
|
||||
for (j=0; j < config_content_node_get_size( case_item ); j++) {
|
||||
const config_content_node_type * case_node = config_content_item_iget_node( case_item );
|
||||
for (i=0; i < config_content_node_get_size( case_node ) i++) {
|
||||
if (config_content_has_item( config , "CASE_LIST")) {
|
||||
const config_content_item_type * case_item = config_content_get_item( config , "CASE_LIST" );
|
||||
for (j=0; j < config_content_item_get_size( case_item ); j++) {
|
||||
const config_content_node_type * case_node = config_content_item_iget_node( case_item , j );
|
||||
for (i=0; i < config_content_node_get_size( case_node ); i++) {
|
||||
const char * case_glob = config_content_node_iget( case_node , i );
|
||||
ensemble_load_from_glob( ensemble , case_glob , tp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
thread_pool_join( tp );
|
||||
thread_pool_free( tp );
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
const sum_case_type * tmp = vector_iget_const( ensemble->data , 0 );
|
||||
ensemble->refcase = tmp->ecl_sum;
|
||||
}
|
||||
|
||||
|
||||
/*1b: Other config settings */
|
||||
if (config_item_set( config , "NUM_INTERP" ))
|
||||
ensemble->num_interp = config_iget_as_int( config , "NUM_INTERP" , 0 , 0 );
|
||||
|
||||
|
||||
if (config_content_has_item( config , "NUM_INTERP" ))
|
||||
ensemble->num_interp = config_content_iget_as_int( config , "NUM_INTERP" , 0 , 0 );
|
||||
|
||||
|
||||
/*2: Remaining initialization */
|
||||
ensemble_init_time_interp( ensemble );
|
||||
if (vector_get_size( ensemble->data ) < MIN_SIZE )
|
||||
@@ -269,7 +270,7 @@ void ensemble_free( ensemble_type * ensemble ) {
|
||||
}
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
|
||||
static output_type * output_alloc( const char * file , const char * format_string) {
|
||||
output_type * output = util_malloc( sizeof * output );
|
||||
output->keys = vector_alloc_new();
|
||||
@@ -289,7 +290,7 @@ static output_type * output_alloc( const char * file , const char * format_strin
|
||||
}
|
||||
output->format = format;
|
||||
}
|
||||
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -322,26 +323,26 @@ static void output_add_key( const ecl_sum_type * refcase , output_type * output
|
||||
util_split_string( qkey , SUMMARY_JOIN , &tokens , &tmp);
|
||||
if (tokens == 1)
|
||||
util_exit("Hmmm - the key:%s is malformed - must be of the form SUMMARY_KEY:QUANTILE.\n",qkey);
|
||||
|
||||
|
||||
if (!util_sscanf_double( tmp[tokens - 1] , &quantile))
|
||||
util_exit("Hmmmm - failed to interpret:%s as a quantile - must be a number (0,1).\n",tmp[tokens-1]);
|
||||
|
||||
|
||||
if (quantile <= 0 || quantile >= 1.0)
|
||||
util_exit("Invalid quantile value:%g - must be in interval (0,1)\n", quantile);
|
||||
|
||||
|
||||
sum_key = util_alloc_joined_string( (const char **) tmp , tokens - 1 , SUMMARY_JOIN);
|
||||
{
|
||||
stringlist_type * matching_keys = stringlist_alloc_new();
|
||||
int i;
|
||||
ecl_sum_select_matching_general_var_list( refcase , sum_key , matching_keys );
|
||||
for (i=0; i < stringlist_get_size( matching_keys ); i++)
|
||||
for (i=0; i < stringlist_get_size( matching_keys ); i++)
|
||||
vector_append_owned_ref( output->keys , quant_key_alloc( stringlist_iget( matching_keys , i ) , quantile) , quant_key_free__ );
|
||||
|
||||
|
||||
if (stringlist_get_size( matching_keys ) == 0)
|
||||
fprintf(stderr,"** Warning: No summary vectors matching:\'%s\' found?? \n", sum_key);
|
||||
stringlist_free( matching_keys );
|
||||
}
|
||||
|
||||
|
||||
util_free_stringlist( tmp, tokens );
|
||||
}
|
||||
|
||||
@@ -354,21 +355,21 @@ static void output_add_key( const ecl_sum_type * refcase , output_type * output
|
||||
OUTPUT output_file key.q key.q key.q key.q ...
|
||||
*/
|
||||
|
||||
void output_table_init( const ecl_sum_type * refcase, hash_type * output_table , const config_type * config ) {
|
||||
void output_table_init( const ecl_sum_type * refcase, hash_type * output_table , const config_content_type * config ) {
|
||||
int i,j;
|
||||
const config_content_item_type * output_item = config_get_content_item( config , "OUTPUT");
|
||||
if (output_item != NULL) {
|
||||
if (config_content_has_item( config , "OUTPUT")) {
|
||||
const config_content_item_type * output_item = config_content_get_item( config , "OUTPUT");
|
||||
for (i = 0; i < config_content_item_get_size( output_item ); i++) {
|
||||
const config_content_node_type * output_node = config_content_item_iget_node( output_item , i );
|
||||
|
||||
|
||||
const char * file = config_content_node_iget( output_node , 0 );
|
||||
const char * format_string = config_content_node_iget( output_node , 1 );
|
||||
output_type * output = output_alloc( file , format_string );
|
||||
|
||||
|
||||
/* All the keys are just added - without any check. */
|
||||
for (j = 2; j < config_content_node_get_size( output_node ); j++)
|
||||
output_add_key( refcase , output , config_content_node_iget( output_node , j));
|
||||
|
||||
|
||||
hash_insert_hash_owned_ref( output_table , file , output , output_free__ );
|
||||
}
|
||||
}
|
||||
@@ -390,9 +391,9 @@ static void print_var( FILE * stream , const char * var , double q , const char
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
** The columns are <TAB> separated! **
|
||||
|
||||
|
||||
An ECLIPSE summary variable is generally characterized by three
|
||||
variable values from SMSPEC vectors; the three vectors are
|
||||
KEYWORDS, WGNAMES and NUMS.
|
||||
@@ -403,7 +404,7 @@ static void print_var( FILE * stream , const char * var , double q , const char
|
||||
additional information from one, or both of WGNAMES and NUMS. For
|
||||
instance for a well variable or group variable we will need the
|
||||
well name from WGNAMES and for a block property we will need the
|
||||
block number (as i + j*nx + k*nx*ny) from the NUMS vector.
|
||||
block number (as i + j*nx + k*nx*ny) from the NUMS vector.
|
||||
|
||||
When writing the S3Graph header I don't understand how to enter the
|
||||
different parts of header information. The current implementation,
|
||||
@@ -412,7 +413,7 @@ static void print_var( FILE * stream , const char * var , double q , const char
|
||||
1. Write a line like this:
|
||||
|
||||
DATE TIME KEYWORD1:xxx KEYWORD2:xxx KEYWORD3:xxxx
|
||||
|
||||
|
||||
Here KEYWORD is an eclipse variable memnonic from the KEYWORDS
|
||||
array, i.e. FOPT or WWCT. The :xxx part is the quantile we are
|
||||
looking at, i.e. 0.10 or 0.90. It seems adding the quantile
|
||||
@@ -420,16 +421,16 @@ static void print_var( FILE * stream , const char * var , double q , const char
|
||||
|
||||
2. Write a line with units:
|
||||
|
||||
DATE TIME KEYWORD1:xxx KEYWORD2:xxx KEYWORD3:xxxx
|
||||
DATE TIME KEYWORD1:xxx KEYWORD2:xxx KEYWORD3:xxxx
|
||||
DAYS UNIT1 UNIT2 UNIT2 <---- New line
|
||||
|
||||
|
||||
3. Write a line with keyword qualifiers, i.e. extra information:
|
||||
|
||||
DATE TIME WOPR:xxx FOPT:xxxx BPR
|
||||
DAYS UNIT1 UNIT2 UNIT2
|
||||
OP1 1000 <---- New line
|
||||
|
||||
DAYS UNIT1 UNIT2 UNIT2
|
||||
OP1 1000 <---- New line
|
||||
|
||||
Now - the totally confusing part is that it is not clear what
|
||||
S3Graph expects on this third line, in the case of well/group
|
||||
variables it is a well/group name from the WGNAMES array,
|
||||
@@ -443,14 +444,14 @@ static void print_var( FILE * stream , const char * var , double q , const char
|
||||
|
||||
|
||||
[*] : I do not really understand why it seems to work.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
void output_save_S3Graph( const output_type * output, ensemble_type * ensemble , const double ** data ) {
|
||||
FILE * stream = util_mkdir_fopen( output->file , "w");
|
||||
FILE * stream = util_mkdir_fopen( output->file , "w");
|
||||
const char * kw_fmt = "\t%s";
|
||||
const char * unit_fmt = "\t%s";
|
||||
const char * wgname_fmt = "\t%s";
|
||||
@@ -466,14 +467,14 @@ void output_save_S3Graph( const output_type * output, ensemble_type * ensemble ,
|
||||
const int data_columns = vector_get_size( output->keys );
|
||||
const int data_rows = time_t_vector_size( ensemble->interp_time );
|
||||
int row_nr,column_nr;
|
||||
|
||||
|
||||
{
|
||||
char * origin;
|
||||
char * origin;
|
||||
util_alloc_file_components( output->file , NULL ,&origin , NULL);
|
||||
fprintf(stream , "ORIGIN %s\n", origin );
|
||||
free( origin );
|
||||
}
|
||||
|
||||
|
||||
/* 1: Writing first header line with variables. */
|
||||
fprintf(stream , time_header );
|
||||
for (column_nr = 0; column_nr < data_columns; column_nr++) {
|
||||
@@ -489,20 +490,20 @@ void output_save_S3Graph( const output_type * output, ensemble_type * ensemble ,
|
||||
fprintf(stream , unit_fmt , ecl_sum_get_unit( ensemble->refcase , qkey->sum_key ) );
|
||||
}
|
||||
fprintf(stream , "\n");
|
||||
|
||||
/*3: Writing third header line with WGNAMES / NUMS - extra information -
|
||||
|
||||
/*3: Writing third header line with WGNAMES / NUMS - extra information -
|
||||
breaks completely down with LGR information. */
|
||||
fprintf(stream , time_blank );
|
||||
{
|
||||
for (column_nr = 0; column_nr < data_columns; column_nr++) {
|
||||
const quant_key_type * qkey = vector_iget( output->keys , column_nr );
|
||||
const char * ecl_key = qkey->sum_key;
|
||||
const char * wgname = ecl_sum_get_wgname( ensemble->refcase , ecl_key );
|
||||
const char * wgname = ecl_sum_get_wgname( ensemble->refcase , ecl_key );
|
||||
int num = ecl_sum_get_num( ensemble->refcase , ecl_key );
|
||||
ecl_smspec_var_type var_type = ecl_sum_get_var_type( ensemble->refcase , ecl_key);
|
||||
bool need_num = ecl_smspec_needs_num( var_type );
|
||||
bool need_wgname = ecl_smspec_needs_wgname( var_type );
|
||||
|
||||
bool need_wgname = ecl_smspec_needs_wgname( var_type );
|
||||
|
||||
if (need_num && need_wgname) {
|
||||
/** Do not know how to include both - will just create a
|
||||
mangled name as a combination. */
|
||||
@@ -511,7 +512,7 @@ void output_save_S3Graph( const output_type * output, ensemble_type * ensemble ,
|
||||
free( wgname_num );
|
||||
} else if (need_num)
|
||||
fprintf(stream , num_fmt , num);
|
||||
else if (need_wgname)
|
||||
else if (need_wgname)
|
||||
fprintf(stream , wgname_fmt , wgname);
|
||||
else
|
||||
fprintf(stream , empty_fmt );
|
||||
@@ -528,7 +529,7 @@ void output_save_S3Graph( const output_type * output, ensemble_type * ensemble ,
|
||||
fprintf(stream , date_fmt , mday , month , year);
|
||||
}
|
||||
fprintf(stream , days_fmt , 1.0*(interp_time - ensemble->start_time) / 86400);
|
||||
|
||||
|
||||
for (column_nr = 0; column_nr < data_columns; column_nr++) {
|
||||
fprintf(stream , float_fmt , data[row_nr][column_nr]);
|
||||
}
|
||||
@@ -539,7 +540,7 @@ void output_save_S3Graph( const output_type * output, ensemble_type * ensemble ,
|
||||
|
||||
|
||||
void output_save_plain__( const output_type * output , ensemble_type * ensemble , const double ** data , bool add_header) {
|
||||
FILE * stream = util_mkdir_fopen( output->file , "w");
|
||||
FILE * stream = util_mkdir_fopen( output->file , "w");
|
||||
const char * key_fmt = " %18s:%4.2f ";
|
||||
const char * time_header = "-- DAYS DATE ";
|
||||
const char * time_dash = "------------------------";
|
||||
@@ -560,7 +561,7 @@ void output_save_plain__( const output_type * output , ensemble_type * ensemble
|
||||
fprintf(stream , "\n");
|
||||
|
||||
fprintf( stream , time_dash );
|
||||
for (int i=0; i < vector_get_size( output->keys ); i++)
|
||||
for (int i=0; i < vector_get_size( output->keys ); i++)
|
||||
fprintf(stream , key_dash );
|
||||
fprintf(stream , "\n");
|
||||
}
|
||||
@@ -574,7 +575,7 @@ void output_save_plain__( const output_type * output , ensemble_type * ensemble
|
||||
util_set_datetime_values(interp_time , NULL , NULL , NULL , &mday , &month , &year);
|
||||
fprintf(stream , date_fmt , mday , month , year);
|
||||
}
|
||||
|
||||
|
||||
for (column_nr = 0; column_nr < data_columns; column_nr++) {
|
||||
fprintf(stream , float_fmt , data[row_nr][column_nr]);
|
||||
}
|
||||
@@ -600,13 +601,13 @@ void output_save( const output_type * output , ensemble_type * ensemble , const
|
||||
util_exit("Sorry: output_format:%d not supported \n", output->format );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void output_run_line( const output_type * output , ensemble_type * ensemble) {
|
||||
|
||||
|
||||
const int data_columns = vector_get_size( output->keys );
|
||||
const int data_rows = time_t_vector_size( ensemble->interp_time );
|
||||
double ** data;
|
||||
@@ -615,15 +616,15 @@ void output_run_line( const output_type * output , ensemble_type * ensemble) {
|
||||
data = util_calloc( data_rows , sizeof * data );
|
||||
/*
|
||||
time-direction, i.e. the row index is the first index and the
|
||||
column number (i.e. the different keys) is the second index.
|
||||
column number (i.e. the different keys) is the second index.
|
||||
*/
|
||||
for (row_nr=0; row_nr < data_rows; row_nr++)
|
||||
data[row_nr] = util_calloc( data_columns , sizeof * data[row_nr] );
|
||||
|
||||
|
||||
printf("Creating output file: %s \n",output->file );
|
||||
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
Go through all the cases and check that they have this key;
|
||||
exit if missing. Could also ignore the missing keys and just
|
||||
continue; and even defer the checking to the inner loop.
|
||||
@@ -632,35 +633,35 @@ void output_run_line( const output_type * output , ensemble_type * ensemble) {
|
||||
const quant_key_type * qkey = vector_iget( output->keys , column_nr );
|
||||
{
|
||||
bool OK = true;
|
||||
|
||||
|
||||
for (int iens = 0; iens < vector_get_size( ensemble->data ); iens++) {
|
||||
const sum_case_type * sum_case = vector_iget_const( ensemble->data , iens );
|
||||
|
||||
|
||||
if (!ecl_sum_has_general_var(sum_case->ecl_sum , qkey->sum_key)) {
|
||||
OK = false;
|
||||
fprintf(stderr,"** Sorry: the case:%s does not have the summary key:%s \n", ecl_sum_get_case( sum_case->ecl_sum ), qkey->sum_key);
|
||||
}
|
||||
}
|
||||
|
||||
if (!OK)
|
||||
if (!OK)
|
||||
util_exit("Exiting due to missing summary vector(s).\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* The main loop - outer loop is running over time. */
|
||||
{
|
||||
/**
|
||||
In the quite typical case that we are asking for several
|
||||
quantiles of the quantity, i.e.
|
||||
|
||||
WWCT:OP_1:0.10 WWCT:OP_1:0.50 WWCT:OP_1:0.90
|
||||
WWCT:OP_1:0.10 WWCT:OP_1:0.50 WWCT:OP_1:0.90
|
||||
|
||||
the interp_data_cache construction will ensure that the
|
||||
underlying ecl_sum object is only queried once; and also the
|
||||
sorting will be performed once.
|
||||
*/
|
||||
|
||||
|
||||
hash_type * interp_data_cache = hash_alloc();
|
||||
|
||||
for (row_nr = 0; row_nr < data_rows; row_nr++) {
|
||||
@@ -680,10 +681,10 @@ void output_run_line( const output_type * output , ensemble_type * ensemble) {
|
||||
if (double_vector_size( interp_data ) == 0) {
|
||||
for (int iens = 0; iens < vector_get_size( ensemble->data ); iens++) {
|
||||
const sum_case_type * sum_case = vector_iget_const( ensemble->data , iens );
|
||||
|
||||
|
||||
if ((interp_time >= sum_case->start_time) && (interp_time <= sum_case->end_time)) /* We allow the different simulations to have differing length */
|
||||
double_vector_append( interp_data , ecl_sum_get_general_var_from_sim_time( sum_case->ecl_sum , interp_time , qkey->sum_key)) ;
|
||||
|
||||
|
||||
double_vector_sort( interp_data );
|
||||
}
|
||||
}
|
||||
@@ -693,7 +694,7 @@ void output_run_line( const output_type * output , ensemble_type * ensemble) {
|
||||
}
|
||||
hash_free( interp_data_cache );
|
||||
}
|
||||
|
||||
|
||||
output_save( output , ensemble , (const double **) data);
|
||||
for (row_nr=0; row_nr < data_rows; row_nr++)
|
||||
free( data[row_nr] );
|
||||
@@ -717,19 +718,19 @@ void output_table_run( hash_type * output_table , ensemble_type * ensemble ) {
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
void config_init( config_type * config ) {
|
||||
void config_init( config_parser_type * config ) {
|
||||
|
||||
|
||||
config_add_schema_item( config , "CASE_LIST" , true , true );
|
||||
config_add_schema_item( config , "CASE_LIST" , true );
|
||||
config_add_key_value( config , "NUM_INTERP" , false , CONFIG_INT);
|
||||
|
||||
|
||||
{
|
||||
config_schema_item_type * item;
|
||||
item = config_add_schema_item( config , "OUTPUT" , true , true );
|
||||
config_schema_item_set_argc_minmax( item , 2 , CONFIG_DEFAULT_ARG_MAX , 0 , NULL );
|
||||
item = config_add_schema_item( config , "OUTPUT" , true );
|
||||
config_schema_item_set_argc_minmax( item , 2 , CONFIG_DEFAULT_ARG_MAX );
|
||||
config_schema_item_set_indexed_selection_set( item , 1 , 3 , (const char *[3]) { S3GRAPH_STRING , HEADER_STRING , PLAIN_STRING });
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -737,7 +738,7 @@ void config_init( config_type * config ) {
|
||||
|
||||
void usage() {
|
||||
fprintf(stderr, "\nUse:\n\n ecl_quantile config_file\n\n");
|
||||
|
||||
|
||||
printf("Help\n");
|
||||
printf("----\n");
|
||||
printf("\n");
|
||||
@@ -786,7 +787,7 @@ void usage() {
|
||||
printf("\n");
|
||||
printf(" Q: The quantile we are interested in, e.g 0.10 to get the P10\n");
|
||||
printf(" quantile and 0.90 to get the P90 quantile.\n");
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
printf(" For the 'VAR' and 'WG?' parts of the keys you can use shell-style\n");
|
||||
printf(" wildcards to get all summary vectors matching a criteria, i.e. \n");
|
||||
printf(" 'WOPR:A-*:0.50' will give the P50 quantile of WOPR for all wells \n");
|
||||
@@ -824,11 +825,14 @@ int main( int argc , char ** argv ) {
|
||||
hash_type * output_table = hash_alloc();
|
||||
ensemble_type * ensemble = ensemble_alloc();
|
||||
{
|
||||
config_type * config = config_alloc( );
|
||||
config_parser_type * config = config_alloc( );
|
||||
config_content_type * content;
|
||||
const char * config_arg = argv[1];
|
||||
|
||||
|
||||
config_init( config );
|
||||
if (config_parse( config , config_arg , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_WARN, true )) {
|
||||
content = config_parse( config , config_arg , "--" , NULL , NULL , CONFIG_UNRECOGNIZED_WARN, true );
|
||||
|
||||
if (config_content_is_valid( content )) {
|
||||
char * config_path;
|
||||
util_alloc_file_components( config_arg , &config_path , NULL , NULL);
|
||||
if (config_path != NULL) {
|
||||
@@ -836,17 +840,18 @@ int main( int argc , char ** argv ) {
|
||||
free( config_path );
|
||||
}
|
||||
} else {
|
||||
config_fprintf_errors( config , stderr );
|
||||
config_error_type * error = config_content_get_errors( content );
|
||||
config_error_fprintf( error , true , stderr );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ensemble_init( ensemble , config );
|
||||
output_table_init( ensemble_get_refcase( ensemble ) , output_table , config);
|
||||
|
||||
|
||||
ensemble_init( ensemble , content );
|
||||
output_table_init( ensemble_get_refcase( ensemble ) , output_table , content );
|
||||
config_content_free( content );
|
||||
config_free( config );
|
||||
|
||||
}
|
||||
}
|
||||
output_table_run( output_table , ensemble );
|
||||
ensemble_free( ensemble );
|
||||
hash_free( output_table );
|
||||
|
||||
+1
-2
@@ -1886,8 +1886,7 @@ int main(int argc , char ** argv) {
|
||||
install_SIGNALS();
|
||||
|
||||
//setvbuf(stdout, NULL, _IOFBF, 0);
|
||||
|
||||
|
||||
setenv( "PLPLOT_LIB" , "/project/res/x86_64_RH_5/plplot/plplot-5.10.0/share/plplot5.10.0" , 1);
|
||||
|
||||
if(argc > 1){
|
||||
if(strcmp(argv[1], "-b") == 0 || strcmp(argv[1], "-s") == 0) {
|
||||
|
||||
+20
-20
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'kw_list.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'kw_list.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -32,14 +32,14 @@ void kw_list(const char *filename) {
|
||||
ecl_kw_type * ecl_kw = ecl_kw_alloc_empty();
|
||||
bool fmt_file;
|
||||
if (ecl_util_fmt_file(filename , &fmt_file)) {
|
||||
|
||||
|
||||
printf("-----------------------------------------------------------------\n");
|
||||
printf("%s: \n",filename);
|
||||
fortio = fortio_open_reader(filename , fmt_file , ECL_ENDIAN_FLIP);
|
||||
while( ecl_kw_fread_realloc(ecl_kw , fortio) )
|
||||
printf("%s: \n",filename);
|
||||
fortio = fortio_open_reader(filename , fmt_file , ECL_ENDIAN_FLIP);
|
||||
while( ecl_kw_fread_realloc(ecl_kw , fortio) )
|
||||
ecl_kw_summarize(ecl_kw);
|
||||
printf("-----------------------------------------------------------------\n");
|
||||
|
||||
|
||||
ecl_kw_free(ecl_kw);
|
||||
fortio_fclose(fortio);
|
||||
} else
|
||||
|
||||
+25
-26
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_file.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_file.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#ifndef __ECL_FILE_H__
|
||||
@@ -33,7 +33,7 @@ extern "C" {
|
||||
#include <ert/ecl/ecl_util.h>
|
||||
|
||||
typedef enum {
|
||||
ECL_FILE_CLOSE_STREAM = 1 , /*
|
||||
ECL_FILE_CLOSE_STREAM = 1 , /*
|
||||
This flag will close the underlying FILE object between each access; this is
|
||||
mainly to save filedescriptors in cases where many ecl_file instances are open at
|
||||
the same time. */
|
||||
@@ -60,7 +60,6 @@ extern "C" {
|
||||
void ecl_file_push_block( ecl_file_type * ecl_file );
|
||||
void ecl_file_pop_block( ecl_file_type * ecl_file );
|
||||
ecl_file_type * ecl_file_open( const char * filename , int flags);
|
||||
ecl_file_type * ecl_file_try_open( const char * filename , int flags);
|
||||
void ecl_file_close( ecl_file_type * ecl_file );
|
||||
void ecl_file_fortio_detach( ecl_file_type * ecl_file );
|
||||
void ecl_file_free__(void * arg);
|
||||
@@ -76,18 +75,18 @@ extern "C" {
|
||||
ecl_version_enum ecl_file_get_ecl_version( const ecl_file_type * file );
|
||||
void ecl_file_fwrite_fortio(const ecl_file_type * ec_file , fortio_type * fortio , int offset);
|
||||
void ecl_file_fwrite(const ecl_file_type * ecl_file , const char * , bool fmt_file );
|
||||
|
||||
|
||||
void ecl_file_replace_kw( ecl_file_type * ecl_file , ecl_kw_type * old_kw , ecl_kw_type * new_kw , bool insert_copy);
|
||||
int ecl_file_get_phases( const ecl_file_type * init_file );
|
||||
void ecl_file_fprintf_kw_list( const ecl_file_type * ecl_file , FILE * stream );
|
||||
|
||||
|
||||
bool ecl_file_writable( const ecl_file_type * ecl_file );
|
||||
int ecl_file_get_flags( const ecl_file_type * ecl_file );
|
||||
void ecl_file_set_flags( ecl_file_type * ecl_file, int new_flags );
|
||||
bool ecl_file_flags_set( const ecl_file_type * ecl_file , int flags);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ecl_file_kw_type * ecl_file_iget_file_kw( const ecl_file_type * file , int global_index);
|
||||
ecl_file_kw_type * ecl_file_iget_named_file_kw( const ecl_file_type * file , const char * kw, int ith);
|
||||
ecl_kw_type * ecl_file_iget_kw( const ecl_file_type * file , int global_index);
|
||||
@@ -99,7 +98,7 @@ extern "C" {
|
||||
int ecl_file_iget_named_size( const ecl_file_type * file , const char * kw , int ith);
|
||||
void ecl_file_indexed_read(const ecl_file_type * file , const char * kw, int index, const int_vector_type * index_map, char* buffer);
|
||||
|
||||
|
||||
|
||||
bool ecl_file_subselect_block( ecl_file_type * ecl_file , const char * kw , int occurence);
|
||||
bool ecl_file_select_block( ecl_file_type * ecl_file , const char * kw , int occurence);
|
||||
void ecl_file_select_global( ecl_file_type * ecl_file );
|
||||
@@ -124,13 +123,13 @@ extern "C" {
|
||||
void ecl_file_close_fortio_stream(ecl_file_type * ecl_file);
|
||||
|
||||
ecl_file_type * ecl_file_open_rstblock_report_step( const char * filename , int report_step , int flags);
|
||||
ecl_file_type * ecl_file_open_rstblock_sim_time( const char * filename , time_t sim_time , int flags);
|
||||
ecl_file_type * ecl_file_open_rstblock_sim_time( const char * filename , time_t sim_time , int flags);
|
||||
ecl_file_type * ecl_file_iopen_rstblock( const char * filename , int seqnum_index , int flags);
|
||||
|
||||
|
||||
|
||||
/*****************************************************************/
|
||||
/* SUMMARY FILES */
|
||||
|
||||
|
||||
bool ecl_file_select_smryblock( ecl_file_type * ecl_file , int ministep_nr );
|
||||
ecl_file_type * ecl_file_open_smryblock( const char * filename , int ministep_nr , int flags);
|
||||
|
||||
@@ -139,5 +138,5 @@ extern "C" {
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -49,7 +49,7 @@ typedef struct inv_map_struct inv_map_type;
|
||||
offset_type ecl_file_kw_get_offset(const ecl_file_kw_type * file_kw);
|
||||
bool ecl_file_kw_ptr_eq( const ecl_file_kw_type * file_kw , const ecl_kw_type * ecl_kw);
|
||||
void ecl_file_kw_replace_kw( ecl_file_kw_type * file_kw , fortio_type * target , ecl_kw_type * new_kw );
|
||||
void ecl_file_kw_fskip_data( const ecl_file_kw_type * file_kw , fortio_type * fortio);
|
||||
bool ecl_file_kw_fskip_data( const ecl_file_kw_type * file_kw , fortio_type * fortio);
|
||||
void ecl_file_kw_inplace_fwrite( ecl_file_kw_type * file_kw , fortio_type * fortio);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
+38
-38
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_grid.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_grid.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#ifndef __ECL_GRID_H__
|
||||
@@ -28,24 +28,24 @@ extern "C" {
|
||||
#include <ert/util/stringlist.h>
|
||||
|
||||
#include <ert/ecl/ecl_coarse_cell.h>
|
||||
#include <ert/ecl/ecl_kw.h>
|
||||
#include <ert/ecl/ecl_kw.h>
|
||||
#include <ert/ecl/grid_dims.h>
|
||||
#include <ert/ecl/nnc_info.h>
|
||||
|
||||
#define ECL_GRID_GLOBAL_GRID "Global" // used as key in hash tables over grids.
|
||||
#define ECL_GRID_MAINGRID_LGR_NR 0
|
||||
|
||||
typedef double (block_function_ftype) ( const double_vector_type *);
|
||||
typedef double (block_function_ftype) ( const double_vector_type *);
|
||||
typedef struct ecl_grid_struct ecl_grid_type;
|
||||
|
||||
bool ecl_grid_have_coarse_cells( const ecl_grid_type * main_grid );
|
||||
bool ecl_grid_cell_in_coarse_group1( const ecl_grid_type * main_grid , int global_index );
|
||||
bool ecl_grid_cell_in_coarse_group3( const ecl_grid_type * main_grid , int i , int j , int k);
|
||||
bool ecl_grid_cell_in_coarse_group1( const ecl_grid_type * main_grid , int global_index );
|
||||
bool ecl_grid_cell_in_coarse_group3( const ecl_grid_type * main_grid , int i , int j , int k);
|
||||
int ecl_grid_get_num_coarse_groups( const ecl_grid_type * main_grid );
|
||||
ecl_coarse_cell_type * ecl_grid_iget_coarse_group( const ecl_grid_type * ecl_grid , int coarse_nr );
|
||||
ecl_coarse_cell_type * ecl_grid_get_cell_coarse_group1( const ecl_grid_type * ecl_grid , int global_index);
|
||||
ecl_coarse_cell_type * ecl_grid_get_cell_coarse_group3( const ecl_grid_type * ecl_grid , int i , int j , int k);
|
||||
|
||||
|
||||
|
||||
void ecl_grid_get_column_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j, double_vector_type * column);
|
||||
int ecl_grid_get_global_index_from_xy_top( const ecl_grid_type * ecl_grid , double x , double y);
|
||||
@@ -55,7 +55,7 @@ extern "C" {
|
||||
void ecl_grid_get_cell_corner_xyz3(const ecl_grid_type * grid , int i , int j , int k, int corner_nr , double * xpos , double * ypos , double * zpos );
|
||||
void ecl_grid_get_cell_corner_xyz1(const ecl_grid_type * grid , int global_index , int corner_nr , double * xpos , double * ypos , double * zpos );
|
||||
void ecl_grid_get_corner_xyz(const ecl_grid_type * grid , int i , int j , int k, double * xpos , double * ypos , double * zpos );
|
||||
|
||||
|
||||
double ecl_grid_get_cell_thickness3( const ecl_grid_type * grid , int i , int j , int k);
|
||||
double ecl_grid_get_cell_thickness1( const ecl_grid_type * grid , int global_index );
|
||||
double ecl_grid_get_cdepth1(const ecl_grid_type * grid , int global_index);
|
||||
@@ -77,14 +77,14 @@ extern "C" {
|
||||
int ecl_grid_get_active_fracture_index1(const ecl_grid_type * ecl_grid , int global_index);
|
||||
bool ecl_grid_cell_active3(const ecl_grid_type * , int , int , int );
|
||||
bool ecl_grid_cell_active1(const ecl_grid_type * , int);
|
||||
bool ecl_grid_ijk_valid(const ecl_grid_type * , int , int , int );
|
||||
bool ecl_grid_ijk_valid(const ecl_grid_type * , int , int , int );
|
||||
int ecl_grid_get_global_index3(const ecl_grid_type * , int , int , int );
|
||||
int ecl_grid_get_global_index1A(const ecl_grid_type * ecl_grid , int active_index);
|
||||
int ecl_grid_get_global_index1F(const ecl_grid_type * ecl_grid , int active_fracture_index);
|
||||
|
||||
const nnc_info_type * ecl_grid_get_cell_nnc_info3( const ecl_grid_type * grid , int i , int j , int k);
|
||||
const nnc_info_type * ecl_grid_get_cell_nnc_info1( const ecl_grid_type * grid , int global_index);
|
||||
|
||||
const nnc_info_type * ecl_grid_get_cell_nnc_info3( const ecl_grid_type * grid , int i , int j , int k);
|
||||
const nnc_info_type * ecl_grid_get_cell_nnc_info1( const ecl_grid_type * grid , int global_index);
|
||||
|
||||
ecl_grid_type * ecl_grid_alloc_GRDECL_kw( int nx, int ny , int nz , const ecl_kw_type * zcorn_kw , const ecl_kw_type * coord_kw , const ecl_kw_type * actnum_kw , const ecl_kw_type * mapaxes_kw );
|
||||
ecl_grid_type * ecl_grid_alloc_GRDECL_data(int , int , int , const float * , const float * , const int * , const float * mapaxes);
|
||||
ecl_grid_type * ecl_grid_alloc_GRID_data(int num_coords , int nx, int ny , int nz , int coords_size , int ** coords , float ** corners , const float * mapaxes);
|
||||
@@ -94,10 +94,10 @@ extern "C" {
|
||||
ecl_grid_type * ecl_grid_alloc_regular( int nx, int ny , int nz , const double * ivec, const double * jvec , const double * kvec , const int * actnum);
|
||||
ecl_grid_type * ecl_grid_alloc_dxv_dyv_dzv( int nx, int ny , int nz , const double * dxv , const double * dyv , const double * dzv , const int * actnum);
|
||||
ecl_grid_type * ecl_grid_alloc_dxv_dyv_dzv_depthz( int nx, int ny , int nz , const double * dxv , const double * dyv , const double * dzv , const double * depthz , const int * actnum);
|
||||
|
||||
|
||||
bool ecl_grid_exists( const char * case_input );
|
||||
char * ecl_grid_alloc_case_filename( const char * case_input );
|
||||
|
||||
|
||||
void ecl_grid_free(ecl_grid_type * );
|
||||
void ecl_grid_free__( void * arg );
|
||||
grid_dims_type ecl_grid_iget_dims( const ecl_grid_type * grid , int grid_nr);
|
||||
@@ -118,7 +118,7 @@ extern "C" {
|
||||
int ecl_grid_get_global_size( const ecl_grid_type * ecl_grid );
|
||||
bool ecl_grid_compare(const ecl_grid_type * g1 , const ecl_grid_type * g2 , bool include_lgr, bool include_nnc , bool verbose);
|
||||
int ecl_grid_get_active_size( const ecl_grid_type * ecl_grid );
|
||||
|
||||
|
||||
double ecl_grid_get_bottom1(const ecl_grid_type * grid , int global_index);
|
||||
double ecl_grid_get_bottom3(const ecl_grid_type * grid , int i, int j , int k);
|
||||
double ecl_grid_get_bottom1A(const ecl_grid_type * grid , int active_index);
|
||||
@@ -128,17 +128,17 @@ extern "C" {
|
||||
double ecl_grid_get_top2(const ecl_grid_type * grid , int i, int j);
|
||||
double ecl_grid_get_bottom2(const ecl_grid_type * grid , int i, int j);
|
||||
int ecl_grid_locate_depth( const ecl_grid_type * grid , double depth , int i , int j );
|
||||
|
||||
|
||||
void ecl_grid_alloc_blocking_variables(ecl_grid_type * , int );
|
||||
void ecl_grid_init_blocking(ecl_grid_type * );
|
||||
double ecl_grid_block_eval3d(ecl_grid_type * grid , int i, int j , int k ,block_function_ftype * blockf );
|
||||
int ecl_grid_get_block_count3d(const ecl_grid_type * ecl_grid , int i , int j, int k);
|
||||
bool ecl_grid_block_value_3d(ecl_grid_type * , double , double ,double , double);
|
||||
|
||||
|
||||
bool ecl_grid_cell_invalid1(const ecl_grid_type * ecl_grid , int global_index);
|
||||
bool ecl_grid_cell_invalid3(const ecl_grid_type * ecl_grid , int i , int j , int k);
|
||||
double ecl_grid_cell_invalid1A(const ecl_grid_type * grid , int active_index);
|
||||
|
||||
|
||||
void ecl_grid_dump(const ecl_grid_type * grid , FILE * stream);
|
||||
void ecl_grid_dump_ascii(ecl_grid_type * grid , bool active_only , FILE * stream);
|
||||
void ecl_grid_dump_ascii_cell1(ecl_grid_type * grid , int global_index , FILE * stream, const double * offset);
|
||||
@@ -151,7 +151,7 @@ extern "C" {
|
||||
int ecl_grid_get_num_lgr(const ecl_grid_type * main_grid );
|
||||
int ecl_grid_get_lgr_nr( const ecl_grid_type * ecl_grid );
|
||||
int ecl_grid_get_lgr_nr_from_name( const ecl_grid_type * grid , const char * name);
|
||||
ecl_grid_type * ecl_grid_iget_lgr(const ecl_grid_type * main_grid , int lgr_index);
|
||||
ecl_grid_type * ecl_grid_iget_lgr(const ecl_grid_type * main_grid , int lgr_index);
|
||||
ecl_grid_type * ecl_grid_get_lgr_from_lgr_nr(const ecl_grid_type * main_grid, int lgr_nr);
|
||||
ecl_grid_type * ecl_grid_get_lgr(const ecl_grid_type * main_grid, const char * __lgr_name);
|
||||
bool ecl_grid_has_lgr(const ecl_grid_type * main_grid, const char * __lgr_name);
|
||||
@@ -162,21 +162,21 @@ extern "C" {
|
||||
int ecl_grid_get_parent_cell3( const ecl_grid_type * grid , int i , int j , int k);
|
||||
const ecl_grid_type * ecl_grid_get_global_grid( const ecl_grid_type * grid );
|
||||
bool ecl_grid_is_lgr( const ecl_grid_type * ecl_grid );
|
||||
|
||||
|
||||
double ecl_grid_get_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k);
|
||||
float ecl_grid_get_float_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k);
|
||||
double ecl_grid_get_double_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k);
|
||||
int ecl_grid_get_int_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k);
|
||||
|
||||
|
||||
void ecl_grid_grdecl_fprintf_kw( const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , const char * special_header , FILE * stream , double double_default);
|
||||
bool ecl_grid_test_lgr_consistency( const ecl_grid_type * ecl_grid );
|
||||
|
||||
|
||||
void ecl_grid_fwrite_EGRID( ecl_grid_type * grid , const char * filename);
|
||||
void ecl_grid_fwrite_GRID( const ecl_grid_type * grid , const char * filename);
|
||||
void ecl_grid_fprintf_grdecl( ecl_grid_type * grid , FILE * stream );
|
||||
void ecl_grid_fwrite_EGRID_header__( int dims[3] , const float mapaxes[6], int dualp_flag , fortio_type * fortio);
|
||||
void ecl_grid_fwrite_EGRID_header( int dims[3] , const float mapaxes[6], fortio_type * fortio);
|
||||
|
||||
|
||||
float * ecl_grid_alloc_zcorn_data( const ecl_grid_type * grid );
|
||||
ecl_kw_type * ecl_grid_alloc_zcorn_kw( const ecl_grid_type * grid );
|
||||
int * ecl_grid_alloc_actnum_data( const ecl_grid_type * grid );
|
||||
@@ -197,7 +197,7 @@ extern "C" {
|
||||
void ecl_grid_init_zcorn_data( const ecl_grid_type * grid , float * zcorn );
|
||||
void ecl_grid_init_zcorn_data_double( const ecl_grid_type * grid , double * zcorn );
|
||||
int ecl_grid_get_zcorn_size( const ecl_grid_type * grid );
|
||||
|
||||
|
||||
void ecl_grid_init_coord_data( const ecl_grid_type * grid , float * coord );
|
||||
void ecl_grid_init_coord_data_double( const ecl_grid_type * grid , double * coord );
|
||||
int ecl_grid_get_coord_size( const ecl_grid_type * ecl_grid);
|
||||
@@ -209,7 +209,7 @@ extern "C" {
|
||||
|
||||
UTIL_IS_INSTANCE_HEADER( ecl_grid );
|
||||
UTIL_SAFE_CAST_HEADER( ecl_grid );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
+46
-47
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_kw.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_kw.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#ifndef __ECL_KW_H__
|
||||
@@ -36,15 +36,14 @@ extern "C" {
|
||||
|
||||
typedef struct ecl_kw_struct ecl_kw_type;
|
||||
|
||||
#define ECL_KW_FORTIO_HEADER_SIZE 4 + ECL_STRING_LENGTH + 4 + ECL_TYPE_LENGTH + 4
|
||||
|
||||
|
||||
size_t ecl_kw_fortio_size( const ecl_kw_type * ecl_kw );
|
||||
void * ecl_kw_get_ptr(const ecl_kw_type *ecl_kw);
|
||||
void ecl_kw_set_data_ptr(ecl_kw_type * ecl_kw , void * data);
|
||||
void ecl_kw_fwrite_data(const ecl_kw_type *_ecl_kw , fortio_type *fortio);
|
||||
void ecl_kw_fread_realloc_data(ecl_kw_type *ecl_kw, fortio_type *fortio);
|
||||
bool ecl_kw_fread_realloc_data(ecl_kw_type *ecl_kw, fortio_type *fortio);
|
||||
ecl_type_enum ecl_kw_get_type(const ecl_kw_type *);
|
||||
const char * ecl_kw_get_header8(const ecl_kw_type *);
|
||||
const char * ecl_kw_get_header8(const ecl_kw_type *);
|
||||
const char * ecl_kw_get_header(const ecl_kw_type * ecl_kw );
|
||||
ecl_kw_type * ecl_kw_alloc_empty();
|
||||
bool ecl_kw_fread_header(ecl_kw_type *, fortio_type *);
|
||||
@@ -104,31 +103,31 @@ extern "C" {
|
||||
bool ecl_kw_block_equal( const ecl_kw_type * ecl_kw1 , const ecl_kw_type * ecl_kw2 , int cmp_elements);
|
||||
bool ecl_kw_data_equal( const ecl_kw_type * ecl_kw , const void * data);
|
||||
bool ecl_kw_content_equal( const ecl_kw_type * ecl_kw1 , const ecl_kw_type * ecl_kw2);
|
||||
void ecl_kw_fskip_data__( ecl_type_enum ecl_type , int size , fortio_type * fortio);
|
||||
void ecl_kw_fskip_data(ecl_kw_type *ecl_kw, fortio_type *fortio);
|
||||
void ecl_kw_fread_data(ecl_kw_type *ecl_kw, fortio_type *fortio);
|
||||
bool ecl_kw_fskip_data__( ecl_type_enum ecl_type , int size , fortio_type * fortio);
|
||||
bool ecl_kw_fskip_data(ecl_kw_type *ecl_kw, fortio_type *fortio);
|
||||
bool ecl_kw_fread_data(ecl_kw_type *ecl_kw, fortio_type *fortio);
|
||||
void ecl_kw_fskip_header( fortio_type * fortio);
|
||||
|
||||
|
||||
bool ecl_kw_is_grdecl_file(FILE * );
|
||||
bool ecl_kw_is_kw_file(FILE * , bool );
|
||||
|
||||
bool ecl_kw_is_kw_file(fortio_type * fortio);
|
||||
|
||||
int ecl_kw_element_sum_int( const ecl_kw_type * ecl_kw );
|
||||
double ecl_kw_element_sum_float( const ecl_kw_type * ecl_kw );
|
||||
void ecl_kw_inplace_inv(ecl_kw_type * my_kw);
|
||||
void ecl_kw_element_sum(const ecl_kw_type * , void * );
|
||||
void ecl_kw_max_min(const ecl_kw_type * , void * , void *);
|
||||
void * ecl_kw_get_void_ptr(const ecl_kw_type * ecl_kw);
|
||||
|
||||
|
||||
ecl_kw_type * ecl_kw_buffer_alloc(buffer_type * buffer);
|
||||
void ecl_kw_buffer_store(const ecl_kw_type * ecl_kw , buffer_type * buffer);
|
||||
|
||||
|
||||
void ecl_kw_fprintf_data( const ecl_kw_type * ecl_kw , const char * fmt , FILE * stream);
|
||||
void ecl_kw_memcpy_data( ecl_kw_type * target , const ecl_kw_type * src);
|
||||
|
||||
|
||||
bool ecl_kw_assert_numeric( const ecl_kw_type * kw );
|
||||
bool ecl_kw_assert_binary( const ecl_kw_type * kw1, const ecl_kw_type * kw2);
|
||||
|
||||
|
||||
void ecl_kw_scalar_set_bool( ecl_kw_type * ecl_kw , bool bool_value);
|
||||
void ecl_kw_scalar_set__(ecl_kw_type * ecl_kw , const void * value);
|
||||
void ecl_kw_scalar_set_float_or_double( ecl_kw_type * ecl_kw , double value );
|
||||
@@ -139,9 +138,9 @@ extern "C" {
|
||||
ECL_KW_SCALAR_SET_TYPED_HEADER( float )
|
||||
ECL_KW_SCALAR_SET_TYPED_HEADER( double )
|
||||
#undef ECL_KW_SCALAR_SET_TYPED_HEADER
|
||||
|
||||
|
||||
ecl_kw_type * ecl_kw_alloc_scatter_copy( const ecl_kw_type * src_kw , int target_size , const int * mapping, void * def_value);
|
||||
|
||||
|
||||
void ecl_kw_inplace_add( ecl_kw_type * target_kw , const ecl_kw_type * add_kw);
|
||||
void ecl_kw_inplace_sub( ecl_kw_type * target_kw , const ecl_kw_type * sub_kw);
|
||||
void ecl_kw_inplace_div( ecl_kw_type * target_kw , const ecl_kw_type * div_kw);
|
||||
@@ -152,68 +151,68 @@ extern "C" {
|
||||
void ecl_kw_inplace_mul_indexed( ecl_kw_type * target_kw , const int_vector_type * index_set , const ecl_kw_type * mul_kw);
|
||||
void ecl_kw_inplace_div_indexed( ecl_kw_type * target_kw , const int_vector_type * index_set , const ecl_kw_type * div_kw);
|
||||
void ecl_kw_copy_indexed( ecl_kw_type * target_kw , const int_vector_type * index_set , const ecl_kw_type * src_kw);
|
||||
|
||||
|
||||
bool ecl_kw_assert_binary_numeric( const ecl_kw_type * kw1, const ecl_kw_type * kw2);
|
||||
#define ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER( ctype ) bool ecl_kw_assert_binary_ ## ctype( const ecl_kw_type * kw1 , const ecl_kw_type * kw2)
|
||||
ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER( int );
|
||||
ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER( float );
|
||||
ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER( double );
|
||||
#undef ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER
|
||||
|
||||
|
||||
#define ECL_KW_SCALE_TYPED_HEADER( ctype ) void ecl_kw_scale_ ## ctype (ecl_kw_type * ecl_kw , ctype scale_factor)
|
||||
ECL_KW_SCALE_TYPED_HEADER( int );
|
||||
ECL_KW_SCALE_TYPED_HEADER( float );
|
||||
ECL_KW_SCALE_TYPED_HEADER( double );
|
||||
#undef ECL_KW_SCALE_TYPED_HEADER
|
||||
void ecl_kw_scale_float_or_double( ecl_kw_type * ecl_kw , double scale_factor );
|
||||
|
||||
|
||||
|
||||
|
||||
#define ECL_KW_SHIFT_TYPED_HEADER( ctype ) void ecl_kw_shift_ ## ctype (ecl_kw_type * ecl_kw , ctype shift_factor)
|
||||
ECL_KW_SHIFT_TYPED_HEADER( int );
|
||||
ECL_KW_SHIFT_TYPED_HEADER( float );
|
||||
ECL_KW_SHIFT_TYPED_HEADER( double );
|
||||
#undef ECL_KW_SHIFT_TYPED_HEADER
|
||||
void ecl_kw_shift_float_or_double( ecl_kw_type * ecl_kw , double shift_value );
|
||||
|
||||
|
||||
|
||||
|
||||
#define ECL_KW_IGET_TYPED_HEADER(type) type ecl_kw_iget_ ## type(const ecl_kw_type * , int)
|
||||
ECL_KW_IGET_TYPED_HEADER(double);
|
||||
ECL_KW_IGET_TYPED_HEADER(float);
|
||||
ECL_KW_IGET_TYPED_HEADER(int);
|
||||
#undef ECL_KW_IGET_TYPED_HEADER
|
||||
bool ecl_kw_iget_bool( const ecl_kw_type * ecl_kw , int i );
|
||||
|
||||
|
||||
|
||||
|
||||
#define ECL_KW_ISET_TYPED_HEADER(type) void ecl_kw_iset_ ## type(ecl_kw_type * , int , type )
|
||||
ECL_KW_ISET_TYPED_HEADER(double);
|
||||
ECL_KW_ISET_TYPED_HEADER(float);
|
||||
ECL_KW_ISET_TYPED_HEADER(int);
|
||||
#undef ECL_KW_ISET_TYPED_HEADER
|
||||
void ecl_kw_iset_bool( ecl_kw_type * ecl_kw , int i , bool bool_value);
|
||||
|
||||
|
||||
|
||||
|
||||
#define ECL_KW_GET_TYPED_PTR_HEADER(type) type * ecl_kw_get_ ## type ## _ptr(const ecl_kw_type *)
|
||||
ECL_KW_GET_TYPED_PTR_HEADER(double);
|
||||
ECL_KW_GET_TYPED_PTR_HEADER(float);
|
||||
ECL_KW_GET_TYPED_PTR_HEADER(int);
|
||||
ECL_KW_GET_TYPED_PTR_HEADER(bool);
|
||||
#undef ECL_KW_GET_TYPED_PTR_HEADER
|
||||
|
||||
|
||||
|
||||
#define ECL_KW_SET_INDEXED_HEADER(ctype ) void ecl_kw_set_indexed_ ## ctype( ecl_kw_type * ecl_kw, const int_vector_type * index_list , ctype value)
|
||||
ECL_KW_SET_INDEXED_HEADER( double );
|
||||
ECL_KW_SET_INDEXED_HEADER( float );
|
||||
ECL_KW_SET_INDEXED_HEADER( int );
|
||||
#undef ECL_KW_SET_INDEXED_HEADER
|
||||
|
||||
|
||||
|
||||
|
||||
#define ECL_KW_SHIFT_INDEXED_HEADER(ctype) void ecl_kw_shift_indexed_ ## ctype( ecl_kw_type * ecl_kw, const int_vector_type * index_list , ctype shift)
|
||||
ECL_KW_SHIFT_INDEXED_HEADER( int );
|
||||
ECL_KW_SHIFT_INDEXED_HEADER( float );
|
||||
ECL_KW_SHIFT_INDEXED_HEADER( double );
|
||||
#undef ECL_KW_SHIFT_INDEXED_HEADER
|
||||
|
||||
|
||||
|
||||
|
||||
#define ECL_KW_SCALE_INDEXED_HEADER(ctype) void ecl_kw_scale_indexed_ ## ctype( ecl_kw_type * ecl_kw, const int_vector_type * index_list , ctype scale)
|
||||
ECL_KW_SCALE_INDEXED_HEADER( int );
|
||||
ECL_KW_SCALE_INDEXED_HEADER( float );
|
||||
@@ -226,9 +225,9 @@ extern "C" {
|
||||
ECL_KW_MAX_MIN_HEADER( float );
|
||||
ECL_KW_MAX_MIN_HEADER( double );
|
||||
#undef ECL_KW_MAX_MIN_HEADER
|
||||
|
||||
|
||||
#include <ert/ecl/ecl_kw_grdecl.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
+56
-55
@@ -5,7 +5,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
/*
|
||||
This header file contains names and indices of ECLIPSE keywords
|
||||
which have special significance in various files. Observe that many
|
||||
of the keywords like e.g. INTEHEAD occur in many different file
|
||||
@@ -24,37 +24,37 @@ extern "C" {
|
||||
#define DOUBHEAD_KW "DOUBHEAD"
|
||||
#define RPORV_KW "RPORV"
|
||||
#define PORV_KW "PORV"
|
||||
#define PORMOD_KW "PORV_MOD"
|
||||
#define PORMOD_KW "PORV_MOD"
|
||||
|
||||
#define PVTNUM_KW "PVTNUM"
|
||||
#define LGRHEADI_KW "LGRHEADI"
|
||||
#define LGRHEADI_LGR_NR_INDEX 0
|
||||
#define LGRJOIN_KW "LGRJOIN"
|
||||
#define LGRJOIN_KW "LGRJOIN"
|
||||
|
||||
/*
|
||||
/*
|
||||
Observe that many of the elements in the INTEHEAD keyword is shared
|
||||
between the restart and init files. The ones listed below here are
|
||||
in both the INIT and the restart files. In addition the restart
|
||||
files have many well related items which are only in the restart
|
||||
files.
|
||||
*/
|
||||
|
||||
|
||||
#define INTEHEAD_UNIT_INDEX 2
|
||||
#define INTEHEAD_NX_INDEX 8
|
||||
#define INTEHEAD_NY_INDEX 9
|
||||
#define INTEHEAD_NZ_INDEX 10
|
||||
#define INTEHEAD_NACTIVE_INDEX 11
|
||||
#define INTEHEAD_PHASE_INDEX 14
|
||||
#define INTEHEAD_DAY_INDEX 64
|
||||
#define INTEHEAD_MONTH_INDEX 65
|
||||
#define INTEHEAD_YEAR_INDEX 66
|
||||
#define INTEHEAD_IPROG_INDEX 94
|
||||
|
||||
|
||||
#define INTEHEAD_UNIT_INDEX 2
|
||||
#define INTEHEAD_NX_INDEX 8
|
||||
#define INTEHEAD_NY_INDEX 9
|
||||
#define INTEHEAD_NZ_INDEX 10
|
||||
#define INTEHEAD_NACTIVE_INDEX 11
|
||||
#define INTEHEAD_PHASE_INDEX 14
|
||||
#define INTEHEAD_DAY_INDEX 64
|
||||
#define INTEHEAD_MONTH_INDEX 65
|
||||
#define INTEHEAD_YEAR_INDEX 66
|
||||
#define INTEHEAD_IPROG_INDEX 94
|
||||
|
||||
|
||||
#define INTEHEAD_METRIC_VALUE 1
|
||||
#define INTEHEAD_ECLIPSE100_VALUE 100
|
||||
#define INTEHEAD_ECLIPSE300_VALUE 300
|
||||
#define INTEHEAD_ECLIPSE300_VALUE 300
|
||||
#define INTEHEAD_ECLIPSE300THERMAL_VALUE 500
|
||||
|
||||
#define INTEHEAD_INIT_SIZE 95
|
||||
@@ -63,18 +63,18 @@ extern "C" {
|
||||
#define LOGIHEAD_ECLIPSE300_RADIAL_INDEX 3
|
||||
#define LOGIHEAD_ECLIPSE100_RADIAL_INDEX 4
|
||||
#define LOGIHEAD_DUALP_INDEX 14
|
||||
#define LOGIHEAD_INIT_SIZE 80
|
||||
#define LOGIHEAD_INIT_SIZE 80
|
||||
#define LOGIHEAD_RESTART_SIZE 15
|
||||
|
||||
|
||||
#define LOGIHEAD_RS_INDEX 0
|
||||
#define LOGIHEAD_RS_INDEX 0
|
||||
#define LOGIHEAD_RV_INDEX 1
|
||||
#define LOGIHEAD_DIR_RELPERM_INDEX 2
|
||||
#define LOGIHEAD_DIR_RELPERM_INDEX 2
|
||||
/*-----------------------------------------------------------------*/
|
||||
#define LOGIHEAD_REV_RELPERM100_INDEX 3 /* The indices for reversible relperm and */
|
||||
#define LOGIHEAD_RADIAL100_INDEX 4 /* use of radial grids is interchanged between */
|
||||
#define LOGIHEAD_REV_RELPERM300_INDEX 4 /* ECLIPSE100 and ECLIPSE300. */
|
||||
#define LOGIHEAD_RADIAL300_INDEX 3
|
||||
#define LOGIHEAD_RADIAL300_INDEX 3
|
||||
/*-----------------------------------------------------------------*/
|
||||
#define LOGIHEAD_HYSTERISIS_INDEX 6
|
||||
#define LOGIHEAD_DUALP_INDEX 14
|
||||
@@ -82,7 +82,7 @@ extern "C" {
|
||||
#define LOGIHEAD_DIR_ENDPOINT_SCALING_INDEX 17
|
||||
#define LOGIHEAD_REV_ENDPOINT_SCALING_INDEX 18
|
||||
#define LOGIHEAD_ALT_ENDPOINT_SCALING_INDEX 19
|
||||
#define LOGIHEAD_MISC_DISPLACEMENT_INDEX 35
|
||||
#define LOGIHEAD_MISC_DISPLACEMENT_INDEX 35
|
||||
#define LOGIHEAD_SCALE_WATER_PC_AT_MAX_SAT_INDEX 55
|
||||
#define LOGIHEAD_SCALE_GAS_PC_AT_MAX_SAT_INDEX 56
|
||||
|
||||
@@ -101,7 +101,7 @@ extern "C" {
|
||||
present in non-unified files, where the report
|
||||
step must be inferred from the filename. */
|
||||
#define STARTSOL_KW "STARTSOL"
|
||||
#define ENDSOL_KW "ENDSOL"
|
||||
#define ENDSOL_KW "ENDSOL"
|
||||
|
||||
#define IWEL_KW "IWEL"
|
||||
#define ZWEL_KW "ZWEL"
|
||||
@@ -120,12 +120,12 @@ extern "C" {
|
||||
|
||||
#define FIPGAS_KW "FIPGAS"
|
||||
#define FIPWAT_KW "FIPWAT"
|
||||
#define FIPOIL_KW "FIPOIL"
|
||||
#define FIPOIL_KW "FIPOIL"
|
||||
#define RFIPGAS_KW "RFIPGAS"
|
||||
#define RFIPWAT_KW "RFIPWAT"
|
||||
#define RFIPOIL_KW "RFIPOIL"
|
||||
#define RFIPOIL_KW "RFIPOIL"
|
||||
|
||||
|
||||
|
||||
#define INTEHEAD_NWELLS_INDEX 16 // Number of wells
|
||||
#define INTEHEAD_NIWELZ_INDEX 24 // Number of elements pr. well in the IWEL array.
|
||||
#define INTEHEAD_NZWELZ_INDEX 27 // Number of 8 character words pr. well
|
||||
@@ -193,7 +193,7 @@ extern "C" {
|
||||
#define RESTART_KW "RESTART"
|
||||
#define SUMMARY_RESTART_SIZE 8
|
||||
|
||||
/*
|
||||
/*
|
||||
There are no magic indices in the summary data files, for all
|
||||
interesting data the table created from the ecl_smspec file must be
|
||||
consulted.
|
||||
@@ -210,7 +210,7 @@ extern "C" {
|
||||
special information for SEGMENT data is not internalized at all,
|
||||
and there are also several additional keywords for the PLTs which
|
||||
are not internalized. */
|
||||
|
||||
|
||||
|
||||
/* Common keywords */
|
||||
#define TIME_KW "TIME" /* The days since simulation start when
|
||||
@@ -223,6 +223,7 @@ extern "C" {
|
||||
#define CONIPOS_KW "CONIPOS" /* The i-index of the connections in the well. */
|
||||
#define CONJPOS_KW "CONJPOS" /* The j-index ... */
|
||||
#define CONKPOS_KW "CONKPOS" /* The k-index ... */
|
||||
#define HOSTGRID_KW "HOSTGRID"
|
||||
|
||||
/* RFT keywords */
|
||||
#define SWAT_KW "SWAT" /* The kewyord containing SWAT. */
|
||||
@@ -236,12 +237,12 @@ extern "C" {
|
||||
#define CONGRAT_KW "CONGRAT" /* Gas ... */
|
||||
#define CONORAT_KW "CONORAT" /* Oil ... */
|
||||
#define CONPRES_KW "CONPRES" /* Pressure ... */
|
||||
#define CONLENST_KW "CONLENST" /* Length along MSW well */
|
||||
#define CONLENEN_KW "CONLENEN" /* Length to connection end for MSW well */
|
||||
#define CONVTUB_KW "CONVTUB" /* Volumetric flow at tubing head conditions. */
|
||||
#define CONOTUB_KW "CONOTUB" /* Volumetric oil flow at tubing head conditions. */
|
||||
#define CONGTUB_KW "CONGTUB" /* Volumetric gas flow at tubing head conditions. */
|
||||
#define CONWTUB_KW "CONWTUB" /* Volumetric water flow at tubing head conditions. */
|
||||
#define CONLENST_KW "CONLENST" /* Length along MSW well */
|
||||
#define CONLENEN_KW "CONLENEN" /* Length to connection end for MSW well */
|
||||
#define CONVTUB_KW "CONVTUB" /* Volumetric flow at tubing head conditions. */
|
||||
#define CONOTUB_KW "CONOTUB" /* Volumetric oil flow at tubing head conditions. */
|
||||
#define CONGTUB_KW "CONGTUB" /* Volumetric gas flow at tubing head conditions. */
|
||||
#define CONWTUB_KW "CONWTUB" /* Volumetric water flow at tubing head conditions. */
|
||||
|
||||
|
||||
#define WELLETC_TYPE_INDEX 5 /* At this keyword the WELLETC keyword contains a string
|
||||
@@ -263,32 +264,32 @@ extern "C" {
|
||||
/* GRID and EGRID files have very different structure, and only a few
|
||||
keywords are shared. */
|
||||
|
||||
|
||||
|
||||
/* Common keywords */
|
||||
#define SPECGRID_KW "SPECGRID"
|
||||
#define SPECGRID_NX_INDEX 0
|
||||
#define SPECGRID_NY_INDEX 1
|
||||
#define SPECGRID_NZ_INDEX 2
|
||||
#define SPECGRID_NX_INDEX 0
|
||||
#define SPECGRID_NY_INDEX 1
|
||||
#define SPECGRID_NZ_INDEX 2
|
||||
#define MAPAXES_KW "MAPAXES" /* Keyword used to transform from grid coordinates to
|
||||
world coordinates. */
|
||||
#define LGR_KW "LGR" /* Name of LGR; for GRID files it can contain two elements,
|
||||
#define LGR_KW "LGR" /* Name of LGR; for GRID files it can contain two elements,
|
||||
the second element will be the name of the parent. */
|
||||
#define MAPUNITS_KW "MAPUNITS"
|
||||
#define GRIDUNIT_KW "GRIDUNIT"
|
||||
|
||||
#define NNCHEAD_KW "NNCHEAD" /*Non-neighbour connection header*/
|
||||
#define NNC1_KW "NNC1" /*Upstream cell numbers for non-neighbour connections*/
|
||||
#define NNC2_KW "NNC2" /*Downstream cell numbers for non-neighbour connections*/
|
||||
#define NNCL_KW "NNCL" /*Cell numbers for LGR cells that are connected to global grid cells*/
|
||||
#define NNCG_KW "NNCG" /*Cell numbers for global cells connected to LGR cells*/
|
||||
|
||||
#define NNCHEAD_KW "NNCHEAD" /*Non-neighbour connection header*/
|
||||
#define NNC1_KW "NNC1" /*Upstream cell numbers for non-neighbour connections*/
|
||||
#define NNC2_KW "NNC2" /*Downstream cell numbers for non-neighbour connections*/
|
||||
#define NNCL_KW "NNCL" /*Cell numbers for LGR cells that are connected to global grid cells*/
|
||||
#define NNCG_KW "NNCG" /*Cell numbers for global cells connected to LGR cells*/
|
||||
#define NNCHEAD_NUMNNC_INDEX 0 /*Item 1 in non-neighbour connection header: number of NNCs. Only present for main grid*/
|
||||
#define NNCHEAD_LGR_INDEX 1 /*Item 2 in non-neighbour connection header: LGR number (0 for global grid)*/
|
||||
#define NNCHEADA_KW "NNCHEADA" /*Header for NNC's between two amalgamated LGRs*/
|
||||
#define NNA1_KW "NNA1" /*Cell numbers in connecting local grid ILOC1*/
|
||||
#define NNA1_KW "NNA1" /*Cell numbers in connecting local grid ILOC1*/
|
||||
#define NNA2_KW "NNA2" /*Cell numbers in connecting local grid ILOC2*/
|
||||
#define NNCHEADA_ILOC1_INDEX 0 /*ILOC1: Index of first LGR*/
|
||||
#define NNCHEADA_ILOC2_INDEX 1 /*ILOC2: Index of second LGR*/
|
||||
#define NNA_NUMNNC_INDEX 0 /*Item 1 in NNA1 or NNA2 is number of NNCs*/
|
||||
#define NNA_NUMNNC_INDEX 0 /*Item 1 in NNA1 or NNA2 is number of NNCs*/
|
||||
|
||||
#define TRANNNC_KW "TRANNNC"
|
||||
#define TRANGL_KW "TRANGL"
|
||||
@@ -305,7 +306,7 @@ extern "C" {
|
||||
#define ENDGRID_KW "ENDGRID"
|
||||
#define ENDLGR_KW "ENDLGR"
|
||||
#define CORSNUM_KW "CORSNUM"
|
||||
|
||||
|
||||
/* GRID keywords */
|
||||
#define GRIDHEAD_KW "GRIDHEAD" /* Header information for GRID files. */
|
||||
#define COORD_KW "COORD" /* Header information for one cell in GRID file. */
|
||||
@@ -321,7 +322,7 @@ extern "C" {
|
||||
#define GRIDHEAD_NZ_INDEX 3
|
||||
#define GRIDHEAD_LGR_INDEX 4
|
||||
#define GRIDHEAD_SIZE 100
|
||||
|
||||
|
||||
/* Observe that these indices are one value lower than the values used
|
||||
in the ecl_smspec file. */
|
||||
#define DIMENS_NX_INDEX 0
|
||||
@@ -340,15 +341,15 @@ extern "C" {
|
||||
#define FILEHEAD_GRIDTYPE_CORNERPOINT 0 /* <----/ */
|
||||
|
||||
#define FILEHEAD_ORGTYPE_CORNERPOINT 1
|
||||
#define FILEHEAD_SINGLE_POROSITY 0
|
||||
#define FILEHEAD_DUAL_POROSITY 1
|
||||
#define FILEHEAD_DUAL_PERMEABILITY 2
|
||||
#define FILEHEAD_SINGLE_POROSITY 0
|
||||
#define FILEHEAD_DUAL_POROSITY 1
|
||||
#define FILEHEAD_DUAL_PERMEABILITY 2
|
||||
|
||||
|
||||
#define CELL_NOT_ACTIVE 0
|
||||
#define CELL_NOT_ACTIVE 0
|
||||
#define CELL_ACTIVE_MATRIX 1
|
||||
#define CELL_ACTIVE CELL_ACTIVE_MATRIX
|
||||
#define CELL_ACTIVE_FRACTURE 2
|
||||
#define CELL_ACTIVE CELL_ACTIVE_MATRIX
|
||||
#define CELL_ACTIVE_FRACTURE 2
|
||||
|
||||
|
||||
|
||||
|
||||
+21
-17
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2013 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_nnc_export.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2013 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_nnc_export.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -24,10 +24,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <ert/ecl/ecl_grid.h>
|
||||
#include <ert/ecl/ecl_file.h>
|
||||
#include <ert/ecl/ecl_kw.h>
|
||||
|
||||
#define ERT_ECL_DEFAULT_NNC_TRANS HUGE_VAL
|
||||
|
||||
typedef struct {
|
||||
int grid_nr1;
|
||||
int global_index1;
|
||||
@@ -39,8 +43,8 @@ typedef struct {
|
||||
|
||||
|
||||
int ecl_nnc_export_get_size( const ecl_grid_type * grid );
|
||||
void ecl_nnc_export( const ecl_grid_type * grid , const ecl_file_type * init_file , ecl_nnc_type * nnc_data);
|
||||
|
||||
int ecl_nnc_export( const ecl_grid_type * grid , const ecl_file_type * init_file , ecl_nnc_type * nnc_data);
|
||||
|
||||
ecl_kw_type * ecl_nnc_export_get_tranx_kw( const ecl_grid_type * grid , const ecl_file_type * init_file , int lgr_nr1, int lgr_nr2 );
|
||||
ecl_kw_type * ecl_nnc_export_get_tranll_kw( const ecl_grid_type * grid , const ecl_file_type * init_file , int lgr_nr1, int lgr_nr2 );
|
||||
ecl_kw_type * ecl_nnc_export_get_tran_kw( const ecl_file_type * init_file , const char * kw , int lgr_nr );
|
||||
|
||||
+20
-17
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_rft_file.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_rft_file.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#ifndef __ECL_RFT_FILE_H__
|
||||
@@ -26,13 +26,15 @@ extern "C" {
|
||||
#include <ert/util/stringlist.h>
|
||||
|
||||
#include <ert/ecl/ecl_rft_node.h>
|
||||
#include <ert/util/vector.h>
|
||||
#include <ert/util/int_vector.h>
|
||||
|
||||
typedef struct ecl_rft_file_struct ecl_rft_file_type;
|
||||
|
||||
char * ecl_rft_file_alloc_case_filename(const char * case_input );
|
||||
const char * ecl_rft_file_get_filename( const ecl_rft_file_type * rft_file );
|
||||
ecl_rft_file_type * ecl_rft_file_alloc_case(const char * case_input );
|
||||
bool ecl_rft_file_case_has_rft(const char * case_input );
|
||||
ecl_rft_file_type * ecl_rft_file_alloc_case(const char * case_input );
|
||||
bool ecl_rft_file_case_has_rft(const char * case_input );
|
||||
bool ecl_rft_file_case_has_rft( const char * case_input );
|
||||
ecl_rft_file_type * ecl_rft_file_alloc(const char * );
|
||||
void ecl_rft_file_free(ecl_rft_file_type * );
|
||||
@@ -51,6 +53,7 @@ int ecl_rft_file_get_well_occurences( const ecl_rft_file_t
|
||||
stringlist_type * ecl_rft_file_alloc_well_list(const ecl_rft_file_type * rft_file );
|
||||
int ecl_rft_file_get_num_wells( const ecl_rft_file_type * rft_file );
|
||||
void ecl_rft_file_free__( void * arg);
|
||||
void ecl_rft_file_update(const char * rft_file_name, ecl_rft_node_type ** nodes,int num_nodes, ert_ecl_unit_enum unit_set);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+23
-18
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_rft_node.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_rft_node.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#ifndef __ECL_RFT_NODE_H__
|
||||
@@ -26,8 +26,8 @@ extern "C" {
|
||||
#include <ert/ecl/ecl_file.h>
|
||||
#include <ert/ecl/ecl_rft_cell.h>
|
||||
|
||||
typedef enum { RFT = 1 ,
|
||||
PLT = 2 ,
|
||||
typedef enum { RFT = 1 ,
|
||||
PLT = 2 ,
|
||||
SEGMENT = 3 /* Not really implemented */ } ecl_rft_enum;
|
||||
|
||||
typedef struct ecl_rft_node_struct ecl_rft_node_type;
|
||||
@@ -38,7 +38,6 @@ const ecl_rft_cell_type * ecl_rft_node_iget_cell( const ecl_rft_node_type * rft_
|
||||
const ecl_rft_cell_type * ecl_rft_node_lookup_ijk( const ecl_rft_node_type * rft_node , int i, int j , int k);
|
||||
void ecl_rft_node_fprintf_rft_obs(const ecl_rft_node_type * , double , const char * , const char * , double );
|
||||
ecl_rft_node_type * ecl_rft_node_alloc(const ecl_file_type * file_map );
|
||||
const char * ecl_rft_node_get_well_name(const ecl_rft_node_type * );
|
||||
void ecl_rft_node_free(ecl_rft_node_type * );
|
||||
void ecl_rft_node_free__(void * );
|
||||
time_t ecl_rft_node_get_date(const ecl_rft_node_type * );
|
||||
@@ -60,6 +59,12 @@ double ecl_rft_node_iget_orat( const ecl_rft_node_type * rft_node , int index);
|
||||
double ecl_rft_node_iget_swat( const ecl_rft_node_type * rft_node , int index);
|
||||
double ecl_rft_node_iget_sgas( const ecl_rft_node_type * rft_node , int index);
|
||||
double ecl_rft_node_iget_soil( const ecl_rft_node_type * rft_node , int index);
|
||||
void ecl_rft_node_fwrite(const ecl_rft_node_type * rft_node, fortio_type * fortio, ert_ecl_unit_enum unit_set);
|
||||
double ecl_rft_node_get_days(const ecl_rft_node_type * rft_node );
|
||||
int ecl_rft_node_cmp( const ecl_rft_node_type * n1 , const ecl_rft_node_type * n2);
|
||||
|
||||
void ecl_rft_node_append_cell( ecl_rft_node_type * rft_node , ecl_rft_cell_type * cell);
|
||||
ecl_rft_node_type * ecl_rft_node_alloc_new(const char * well_name, const char * data_type_string, const time_t recording_date, const double days);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -20,12 +20,15 @@
|
||||
#ifndef __ECL_RST_FILE_H__
|
||||
#define __ECL_RST_FILE_H__
|
||||
|
||||
#include <ert/ecl/ecl_rsthead.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct ecl_rst_file_struct ecl_rst_file_type;
|
||||
typedef struct ecl_rst_file_struct ecl_rst_file_type;
|
||||
|
||||
|
||||
ecl_rst_file_type * ecl_rst_file_open_read( const char * filename );
|
||||
ecl_rst_file_type * ecl_rst_file_open_write( const char * filename );
|
||||
@@ -34,9 +37,10 @@ extern "C" {
|
||||
|
||||
void ecl_rst_file_start_solution( ecl_rst_file_type * rst_file );
|
||||
void ecl_rst_file_end_solution( ecl_rst_file_type * rst_file );
|
||||
void ecl_rst_file_fwrite_header( ecl_rst_file_type * rst_file , int seqnum , time_t date , double days , int nx , int ny ,int nz , int nactive , int phases);
|
||||
void ecl_rst_file_fwrite_header( ecl_rst_file_type * rst_file , int seqnum, ecl_rsthead_type * rsthead_data );
|
||||
void ecl_rst_file_add_kw(ecl_rst_file_type * rst_file , const ecl_kw_type * ecl_kw );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
+26
-24
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_RSTHEAD.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_RSTHEAD.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#ifndef __ECL_RSTHEAD_H__
|
||||
@@ -36,7 +36,7 @@ extern "C" {
|
||||
time_t sim_time;
|
||||
int version; // 100, 300, 500 (Eclipse300-Thermal)
|
||||
int phase_sum; // Oil = 1 Gas = 2 Water = 4
|
||||
|
||||
|
||||
int nx;
|
||||
int ny;
|
||||
int nz;
|
||||
@@ -50,26 +50,26 @@ extern "C" {
|
||||
|
||||
// Pure well properties
|
||||
int nwells; // Number of wells
|
||||
int niwelz; // Number of elements pr well in IWEL array
|
||||
int nzwelz; // Number of 8 character words pr well in ZWEL array
|
||||
int niwelz; // Number of elements pr well in IWEL array
|
||||
int nzwelz; // Number of 8 character words pr well in ZWEL array
|
||||
|
||||
// Connection properties
|
||||
int niconz; // Number of elements per completion in ICON array
|
||||
int niconz; // Number of elements per completion in ICON array
|
||||
int ncwmax; // Maximum number of completions per well
|
||||
int nsconz; // Number of elements per completion in SCON array
|
||||
|
||||
// Segment properties
|
||||
int nisegz; // Number of entries pr segment in the ISEG array
|
||||
int nsegmx; // The maximum number of segments pr well
|
||||
int nswlmx; // The maximum number of segmented wells
|
||||
int nisegz; // Number of entries pr segment in the ISEG array
|
||||
int nsegmx; // The maximum number of segments pr well
|
||||
int nswlmx; // The maximum number of segmented wells
|
||||
int nlbrmx; // The maximum number of lateral branches pr well
|
||||
int nilbrz; // The number of entries pr segment in ILBR array
|
||||
int nilbrz; // The number of entries pr segment in ILBR array
|
||||
int nrsegz; // The number of entries pr segment in RSEG array
|
||||
|
||||
// Properteies from the LOGIHEAD keyword:
|
||||
bool dualp;
|
||||
|
||||
|
||||
|
||||
// Properties from the DOUBHEAD keyword:
|
||||
double sim_days;
|
||||
} ecl_rsthead_type;
|
||||
@@ -79,10 +79,12 @@ extern "C" {
|
||||
void ecl_rsthead_free( ecl_rsthead_type * rsthead );
|
||||
ecl_rsthead_type * ecl_rsthead_ialloc( const ecl_file_type * rst_file , int occurence);
|
||||
ecl_rsthead_type * ecl_rsthead_alloc( const ecl_file_type * rst_file );
|
||||
ecl_rsthead_type * ecl_rsthead_alloc_empty();
|
||||
time_t ecl_rsthead_date( const ecl_kw_type * intehead_kw );
|
||||
void ecl_rsthead_fprintf( const ecl_rsthead_type * header , FILE * stream);
|
||||
void ecl_rsthead_fprintf_struct( const ecl_rsthead_type * header , FILE * stream);
|
||||
bool ecl_rsthead_equal( const ecl_rsthead_type * header1 , const ecl_rsthead_type * header2);
|
||||
double ecl_rsthead_get_sim_days( const ecl_rsthead_type * header );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ typedef struct ecl_smspec_struct ecl_smspec_type;
|
||||
const int_vector_type * ecl_smspec_get_index_map( const ecl_smspec_type * smspec );
|
||||
void ecl_smspec_index_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node);
|
||||
void ecl_smspec_insert_node(ecl_smspec_type * ecl_smspec, smspec_node_type * smspec_node);
|
||||
void ecl_smspec_add_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node );
|
||||
void ecl_smspec_add_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node );
|
||||
ecl_smspec_var_type ecl_smspec_iget_var_type( const ecl_smspec_type * smspec , int index );
|
||||
bool ecl_smspec_needs_num( ecl_smspec_var_type var_type );
|
||||
bool ecl_smspec_needs_wgname( ecl_smspec_var_type var_type );
|
||||
@@ -133,6 +133,7 @@ typedef struct ecl_smspec_struct ecl_smspec_type;
|
||||
|
||||
const int * ecl_smspec_get_grid_dims( const ecl_smspec_type * smspec );
|
||||
int ecl_smspec_get_params_size( const ecl_smspec_type * smspec );
|
||||
int ecl_smspec_num_nodes( const ecl_smspec_type * smspec);
|
||||
const smspec_node_type * ecl_smspec_iget_node( const ecl_smspec_type * smspec , int index );
|
||||
void ecl_smspec_lock( ecl_smspec_type * smspec );
|
||||
|
||||
|
||||
+3
-3
@@ -136,9 +136,9 @@ typedef struct ecl_sum_struct ecl_sum_type;
|
||||
const char * ecl_sum_get_general_var_unit( const ecl_sum_type * ecl_sum , const char * var);
|
||||
/***************/
|
||||
void ecl_sum_fprintf(const ecl_sum_type * , FILE * , const stringlist_type * , bool report_only , const ecl_sum_fmt_type * fmt);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Time related functions */
|
||||
int ecl_sum_get_first_gt( const ecl_sum_type * ecl_sum , int param_index , double limit);
|
||||
|
||||
+30
-28
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_sum_data.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_sum_data.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#ifndef __ECL_SUM_DATA_H__
|
||||
@@ -33,11 +33,12 @@ extern "C" {
|
||||
|
||||
#include <ert/ecl/ecl_sum_tstep.h>
|
||||
#include <ert/ecl/smspec_node.h>
|
||||
#include <ert/ecl/ecl_sum_vector.h>
|
||||
|
||||
typedef struct ecl_sum_data_struct ecl_sum_data_type ;
|
||||
typedef struct ecl_sum_data_struct ecl_sum_data_type ;
|
||||
void ecl_sum_data_fwrite_step( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case , bool unified, int report_step);
|
||||
void ecl_sum_data_fwrite( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case , bool unified);
|
||||
void ecl_sum_data_fread( ecl_sum_data_type * data , const stringlist_type * filelist);
|
||||
bool ecl_sum_data_fread( ecl_sum_data_type * data , const stringlist_type * filelist);
|
||||
void ecl_sum_data_fread_restart( ecl_sum_data_type * data , const stringlist_type * filelist);
|
||||
ecl_sum_data_type * ecl_sum_data_alloc_writer( ecl_smspec_type * smspec );
|
||||
ecl_sum_data_type * ecl_sum_data_alloc( ecl_smspec_type * smspec);
|
||||
@@ -51,32 +52,32 @@ typedef struct ecl_sum_data_struct ecl_sum_data_type ;
|
||||
void ecl_sum_data_init_data_vector( const ecl_sum_data_type * data , double_vector_type * data_vector , int data_index , bool report_only);
|
||||
void ecl_sum_data_init_time_vector( const ecl_sum_data_type * data , time_t_vector_type * time_vector , bool report_only);
|
||||
time_t_vector_type * ecl_sum_data_alloc_time_vector( const ecl_sum_data_type * data , bool report_only);
|
||||
time_t ecl_sum_data_get_data_start( const ecl_sum_data_type * data );
|
||||
time_t ecl_sum_data_get_data_start( const ecl_sum_data_type * data );
|
||||
time_t ecl_sum_data_get_report_time( const ecl_sum_data_type * data , int report_step);
|
||||
double ecl_sum_data_get_first_day( const ecl_sum_data_type * data);
|
||||
const time_interval_type * ecl_sum_data_get_sim_time( const ecl_sum_data_type * data);
|
||||
time_t ecl_sum_data_get_sim_start ( const ecl_sum_data_type * data );
|
||||
time_t ecl_sum_data_get_sim_end ( const ecl_sum_data_type * data );
|
||||
double ecl_sum_data_get_sim_length( const ecl_sum_data_type * data );
|
||||
time_t ecl_sum_data_get_sim_start ( const ecl_sum_data_type * data );
|
||||
time_t ecl_sum_data_get_sim_end ( const ecl_sum_data_type * data );
|
||||
double ecl_sum_data_get_sim_length( const ecl_sum_data_type * data );
|
||||
void ecl_sum_data_summarize(const ecl_sum_data_type * data , FILE * stream);
|
||||
double ecl_sum_data_iget( const ecl_sum_data_type * data , int internal_index , int params_index );
|
||||
|
||||
|
||||
double ecl_sum_data_iget_sim_days( const ecl_sum_data_type * , int );
|
||||
time_t ecl_sum_data_iget_sim_time( const ecl_sum_data_type * , int );
|
||||
|
||||
|
||||
|
||||
|
||||
bool ecl_sum_data_has_report_step(const ecl_sum_data_type * , int );
|
||||
|
||||
|
||||
ecl_sum_data_type * ecl_sum_data_fread_alloc( ecl_smspec_type * , const stringlist_type * filelist , bool include_restart);
|
||||
void ecl_sum_data_free( ecl_sum_data_type * );
|
||||
int ecl_sum_data_get_last_report_step( const ecl_sum_data_type * data );
|
||||
int ecl_sum_data_get_first_report_step( const ecl_sum_data_type * data );
|
||||
int ecl_sum_data_get_first_ministep( const ecl_sum_data_type * data );
|
||||
int ecl_sum_data_get_last_ministep( const ecl_sum_data_type * data );
|
||||
|
||||
|
||||
double ecl_sum_data_get_from_sim_time( const ecl_sum_data_type * data , time_t sim_time , const smspec_node_type * smspec_node);
|
||||
double ecl_sum_data_get_from_sim_days( const ecl_sum_data_type * data , double sim_days , const smspec_node_type * smspec_node);
|
||||
|
||||
|
||||
int ecl_sum_data_get_length( const ecl_sum_data_type * data );
|
||||
int ecl_sum_data_iget_report_step(const ecl_sum_data_type * data , int internal_index);
|
||||
int ecl_sum_data_iget_mini_step(const ecl_sum_data_type * data , int internal_index);
|
||||
@@ -85,7 +86,8 @@ typedef struct ecl_sum_data_struct ecl_sum_data_type ;
|
||||
ecl_sum_tstep_type * ecl_sum_data_add_new_tstep( ecl_sum_data_type * data , int report_step , double sim_days);
|
||||
bool ecl_sum_data_report_step_equal( const ecl_sum_data_type * data1 , const ecl_sum_data_type * data2);
|
||||
bool ecl_sum_data_report_step_compatible( const ecl_sum_data_type * data1 , const ecl_sum_data_type * data2);
|
||||
|
||||
void ecl_sum_data_write_csv_file(const ecl_sum_data_type * data , time_t sim_time, const ecl_sum_vector_type * keylist, FILE *fp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright (C) 2014 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_sum_vector.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#ifndef __ECL_SUM_VECTOR_H__
|
||||
#define __ECL_SUM_VECTOR_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <ert/ecl/ecl_sum.h>
|
||||
|
||||
typedef struct ecl_sum_vector_struct ecl_sum_vector_type;
|
||||
|
||||
void ecl_sum_vector_free( ecl_sum_vector_type * keylist );
|
||||
ecl_sum_vector_type * ecl_sum_vector_alloc(const ecl_sum_type * ecl_sum);
|
||||
|
||||
bool ecl_sum_vector_add_key( ecl_sum_vector_type * keylist, const char * key);
|
||||
void ecl_sum_vector_add_keys( ecl_sum_vector_type * keylist, const char * pattern);
|
||||
|
||||
bool ecl_sum_vector_iget_is_rate(const ecl_sum_vector_type * ecl_sum_vector, int index);
|
||||
int ecl_sum_vector_iget_param_index(const ecl_sum_vector_type * ecl_sum_vector, int index);
|
||||
int ecl_sum_vector_get_size(const ecl_sum_vector_type * ecl_sum_vector);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
+44
-44
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_util.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_util.h' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#ifndef __ECL_UTIL_H__
|
||||
@@ -27,19 +27,19 @@ extern "C" {
|
||||
#include <ert/util/stringlist.h>
|
||||
#include <ert/util/time_t_vector.h>
|
||||
#include <ert/util/parser.h>
|
||||
|
||||
|
||||
typedef enum { ECL_OTHER_FILE = 0 ,
|
||||
ECL_RESTART_FILE = 1 ,
|
||||
ECL_UNIFIED_RESTART_FILE = 2 ,
|
||||
ECL_SUMMARY_FILE = 4 ,
|
||||
ECL_UNIFIED_SUMMARY_FILE = 8 ,
|
||||
ECL_SUMMARY_HEADER_FILE = 16 ,
|
||||
ECL_GRID_FILE = 32 ,
|
||||
ECL_EGRID_FILE = 64 ,
|
||||
|
||||
typedef enum { ECL_OTHER_FILE = 0 ,
|
||||
ECL_RESTART_FILE = 1 ,
|
||||
ECL_UNIFIED_RESTART_FILE = 2 ,
|
||||
ECL_SUMMARY_FILE = 4 ,
|
||||
ECL_UNIFIED_SUMMARY_FILE = 8 ,
|
||||
ECL_SUMMARY_HEADER_FILE = 16 ,
|
||||
ECL_GRID_FILE = 32 ,
|
||||
ECL_EGRID_FILE = 64 ,
|
||||
ECL_INIT_FILE = 128 ,
|
||||
ECL_RFT_FILE = 256 ,
|
||||
ECL_DATA_FILE = 512 } ecl_file_enum;
|
||||
ECL_DATA_FILE = 512 } ecl_file_enum;
|
||||
|
||||
|
||||
#define ECL_FILE_ENUM_DEFS {.value = 0 , .name="ECL_OTHER_FILE"}, \
|
||||
@@ -62,7 +62,7 @@ typedef enum { ECL_OTHER_FILE = 0 ,
|
||||
can be stored.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
typedef enum { ECL_INVALID_STORAGE = 0,
|
||||
ECL_BINARY_UNIFIED = 1,
|
||||
ECL_FORMATTED_UNIFIED = 2,
|
||||
@@ -75,24 +75,23 @@ typedef enum { ECL_OTHER_FILE = 0 ,
|
||||
i.e. 'REAL', 'INTE', ... , come as 4 character strings.
|
||||
*/
|
||||
|
||||
|
||||
#define ECL_STRING_LENGTH 8
|
||||
#define ECL_TYPE_LENGTH 4
|
||||
|
||||
|
||||
#define ECL_KW_HEADER_DATA_SIZE ECL_STRING_LENGTH + ECL_TYPE_LENGTH + 4
|
||||
#define ECL_KW_HEADER_FORTIO_SIZE ECL_KW_HEADER_DATA_SIZE + 8
|
||||
|
||||
/*****************************************************************/
|
||||
/*
|
||||
/*
|
||||
Observe that these type identidiers are (ab)used in both the rms and
|
||||
ert/enkf libraries in situations where ECLIPSE is not at all involved.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
ECL_CHAR_TYPE = 0,
|
||||
ECL_FLOAT_TYPE = 1,
|
||||
ECL_DOUBLE_TYPE = 2,
|
||||
ECL_INT_TYPE = 3,
|
||||
ECL_BOOL_TYPE = 4,
|
||||
ECL_CHAR_TYPE = 0,
|
||||
ECL_FLOAT_TYPE = 1,
|
||||
ECL_DOUBLE_TYPE = 2,
|
||||
ECL_INT_TYPE = 3,
|
||||
ECL_BOOL_TYPE = 4,
|
||||
ECL_MESS_TYPE = 5
|
||||
} ecl_type_enum;
|
||||
|
||||
@@ -111,12 +110,12 @@ typedef enum {
|
||||
The libecl library has been built and tested 99.5% with ECLIPSE100
|
||||
as context, but in thye gravity code there is some very limited
|
||||
functionality related to ECLIPSE100 versus ECLIPSE300 functionality.
|
||||
*/
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
ECLIPSE_UNDEFINED = 0,
|
||||
ECLIPSE100 = 1,
|
||||
ECLIPSE300 = 2
|
||||
ECLIPSE300 = 2
|
||||
} ecl_version_enum;
|
||||
|
||||
/*
|
||||
@@ -126,7 +125,7 @@ typedef enum {
|
||||
|
||||
The function ecl_util_get_phase_name() can be used to lookup a
|
||||
string name from an enum value.
|
||||
|
||||
|
||||
The phases in a simulation will typically be a sum of these
|
||||
fundamental phases, and represented as an integer.
|
||||
*/
|
||||
@@ -142,10 +141,10 @@ typedef enum {
|
||||
|
||||
|
||||
typedef enum {
|
||||
ECL_METRIC_UNITS = 0,
|
||||
ECL_FIELD_UNITS = 1,
|
||||
ECL_LAB_UNITS = 2
|
||||
} ecl_unit_enum;
|
||||
ERT_ECL_METRIC_UNITS = 0,
|
||||
ERT_ECL_FIELD_UNITS = 1,
|
||||
ERT_ECL_LAB_UNITS = 2
|
||||
} ert_ecl_unit_enum;
|
||||
|
||||
#define ECL_UNIT_ENUM_DEFS {.value = 0 , .name = "ECL_METRIC_UNITS"}, {.value = 1 , .name = "ECL_FIELD_UNITS"} , {.value = 2 , .name = "ECL_LAB_UNITS"}
|
||||
#define ECL_UNIT_ENUM_SIZE 3
|
||||
@@ -153,7 +152,7 @@ typedef enum {
|
||||
|
||||
// For unformatted files:
|
||||
#define ECL_BOOL_TRUE_INT -1 // Binary representation: 11111111 11111111 11111111 1111111
|
||||
#define ECL_BOOL_FALSE_INT 0 // Binary representation: 00000000 00000000 00000000 0000000
|
||||
#define ECL_BOOL_FALSE_INT 0 // Binary representation: 00000000 00000000 00000000 0000000
|
||||
#define ECL_COMMENT_STRING "--"
|
||||
#define ECL_COMMENT_CHAR '-' // Need to consecutive to make an ECLIPSE comment
|
||||
#define ECL_DATA_TERMINATION "/"
|
||||
@@ -185,7 +184,7 @@ int ecl_util_get_month_nr(const char * month_name);
|
||||
int ecl_util_fname_report_cmp(const void *f1, const void *f2);
|
||||
time_t ecl_util_make_date(int mday , int month , int year);
|
||||
time_t ecl_util_make_date__(int mday , int month , int year, int * year_offset);
|
||||
ecl_unit_enum ecl_util_get_unit_set(const char * data_file);
|
||||
ert_ecl_unit_enum ecl_util_get_unit_set(const char * data_file);
|
||||
|
||||
bool ecl_util_valid_basename_fmt( const char * basename_fmt );
|
||||
bool ecl_util_valid_basename( const char * basename );
|
||||
@@ -195,6 +194,7 @@ const char * ecl_util_file_enum_iget( int index, int * value);
|
||||
int ecl_util_select_filelist( const char * path , const char * base , ecl_file_enum file_type , bool fmt_file , stringlist_type * filelist);
|
||||
void ecl_util_append_month_range( time_t_vector_type * date_list , time_t start_date , time_t end_date , bool force_append_end);
|
||||
void ecl_util_init_month_range( time_t_vector_type * date_list , time_t start_date , time_t end_date);
|
||||
void ecl_util_set_date_values(time_t t , int * mday , int * month , int * year);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+9
-12
@@ -43,35 +43,32 @@ typedef struct fortio_struct fortio_type;
|
||||
|
||||
fortio_status_type fortio_check_buffer( FILE * stream , bool endian_flip , size_t buffer_size );
|
||||
fortio_status_type fortio_check_file( const char * filename , bool endian_flip);
|
||||
bool fortio_guess_endian_flip(const char * , bool *);
|
||||
bool fortio_is_fortran_file(const char * , bool * );
|
||||
bool fortio_looks_like_fortran_file(const char * , bool );
|
||||
void fortio_copy_record(fortio_type * , fortio_type * , int , void * , bool *);
|
||||
fortio_type * fortio_alloc_FILE_wrapper(const char * , bool , bool , FILE * );
|
||||
fortio_type * fortio_open_reader(const char *, bool fmt_file , bool endian_flip_header);
|
||||
fortio_type * fortio_open_writer(const char *, bool fmt_file , bool endian_flip_header);
|
||||
fortio_type * fortio_open_readwrite(const char *, bool fmt_file , bool endian_flip_header);
|
||||
fortio_type * fortio_open_append(const char *filename , bool fmt_file , bool endian_flip_header);
|
||||
fortio_type * fortio_alloc_FILE_wrapper(const char * , bool , bool , bool , FILE * );
|
||||
void fortio_free_FILE_wrapper(fortio_type *);
|
||||
void fortio_fclose(fortio_type *);
|
||||
int fortio_init_read(fortio_type *);
|
||||
void fortio_complete_read(fortio_type *);
|
||||
bool fortio_complete_read(fortio_type *, int record_size);
|
||||
void fortio_init_write(fortio_type * , int);
|
||||
void fortio_complete_write(fortio_type *);
|
||||
void fortio_complete_write(fortio_type * , int record_size);
|
||||
void fortio_fskip_buffer(fortio_type *, int );
|
||||
int fortio_fskip_record(fortio_type *);
|
||||
int fortio_fread_record(fortio_type * , char *buffer);
|
||||
void fortio_fread_buffer(fortio_type * , char * , int );
|
||||
void fortio_fwrite_record(fortio_type * , const char *, int);
|
||||
bool fortio_fread_buffer(fortio_type * , char * buffer, int buffer_size);
|
||||
void fortio_fwrite_record(fortio_type * , const char * buffer, int buffer_size);
|
||||
FILE * fortio_get_FILE(const fortio_type *);
|
||||
void fortio_fflush(fortio_type * ) ;
|
||||
int fortio_get_record_size(const fortio_type *);
|
||||
bool fortio_is_fortio_file(fortio_type * );
|
||||
void fortio_rewind(const fortio_type *fortio);
|
||||
const char * fortio_filename_ref(const fortio_type * );
|
||||
bool fortio_fmt_file(const fortio_type *);
|
||||
offset_type fortio_ftell( const fortio_type * fortio );
|
||||
int fortio_fseek( fortio_type * fortio , offset_type offset , int whence);
|
||||
void fortio_data_fskip(fortio_type* fortio, const int element_size, const int element_count, const int block_count);
|
||||
bool fortio_fseek( fortio_type * fortio , offset_type offset , int whence);
|
||||
bool fortio_data_fskip(fortio_type* fortio, const int element_size, const int element_count, const int block_count);
|
||||
void fortio_data_fseek(fortio_type* fortio, offset_type data_offset, size_t data_element, const int element_size, const int element_count, const int block_size);
|
||||
int fortio_fileno( fortio_type * fortio );
|
||||
|
||||
@@ -79,7 +76,7 @@ typedef struct fortio_struct fortio_type;
|
||||
bool fortio_fopen_stream( fortio_type * fortio );
|
||||
bool fortio_stream_is_open( const fortio_type * fortio );
|
||||
bool fortio_assert_stream_open( fortio_type * fortio );
|
||||
|
||||
bool fortio_read_at_eof( fortio_type * fortio );
|
||||
|
||||
UTIL_IS_INSTANCE_HEADER( fortio );
|
||||
UTIL_SAFE_CAST_HEADER( fortio );
|
||||
|
||||
+4
-2
@@ -17,7 +17,8 @@ set( source_files
|
||||
ecl_sum_data.c
|
||||
ecl_util.c
|
||||
ecl_kw.c
|
||||
ecl_sum.c
|
||||
ecl_sum.c
|
||||
ecl_sum_vector.c
|
||||
fortio.c
|
||||
ecl_rft_file.c
|
||||
ecl_rft_node.c
|
||||
@@ -57,7 +58,8 @@ set( header_files
|
||||
ecl_sum_data.h
|
||||
ecl_util.h
|
||||
ecl_kw.h
|
||||
ecl_sum.h
|
||||
ecl_sum.h
|
||||
ecl_sum_vector.h
|
||||
fortio.h
|
||||
ecl_rft_file.h
|
||||
ecl_rft_node.h
|
||||
|
||||
+126
-122
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_file.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_file.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -49,12 +49,12 @@
|
||||
with a collection of ecl_kw instances and has various query
|
||||
functions, however it does not utilize knowledge of the
|
||||
structure/content of the files in the way e.g. ecl_grid.c does[1].
|
||||
|
||||
|
||||
The main datatype here is the ecl_file type, but in addition each
|
||||
ecl_kw instance is wrapped in an ecl_file_kw (implemented in
|
||||
ecl_file_kw.c) structure and all the indexing is implemented with
|
||||
the file_map type. The file_map type is not used outside this file.
|
||||
|
||||
|
||||
When the file is opened an index of all the keywords is created and
|
||||
stored in the field global_map, and the field active_map is set to
|
||||
point to global_map, i.e. all query/get operations on the ecl_file
|
||||
@@ -67,9 +67,9 @@
|
||||
a keyword from name and occurence number, and then including all
|
||||
keywords up to the next occurence of the same keyword:
|
||||
|
||||
SEQHDR ---\
|
||||
MINISTEP 0 |
|
||||
PARAMS ..... |
|
||||
SEQHDR ---\
|
||||
MINISTEP 0 |
|
||||
PARAMS ..... |
|
||||
MINISTEP 1 | Block 0
|
||||
PARAMS ..... |
|
||||
MINISTEP 2 |
|
||||
@@ -83,14 +83,14 @@
|
||||
SEQHDR ---+
|
||||
MINISTEP 6 | Block 2
|
||||
PARAMS .... |
|
||||
SEQHDR ---+
|
||||
MINISTEP 7 |
|
||||
SEQHDR ---+
|
||||
MINISTEP 7 |
|
||||
PARAMS .... | Block 3
|
||||
MINISTEP 8 |
|
||||
PARAMS .... |
|
||||
|
||||
|
||||
For the unified summary file depicted here e.g. the call
|
||||
|
||||
|
||||
ecl_file_get_blockmap( ecl_file , "SEQHDR" , 2 )
|
||||
|
||||
Will create a sub-index consisting of the (three) keywords in what
|
||||
@@ -99,7 +99,7 @@
|
||||
of functionality is required to get from natural time coordinates
|
||||
(i.e. simulation time or report step) to the occurence number (see
|
||||
ecl_rstfile for more details).
|
||||
|
||||
|
||||
To select a subindex as the active index you use the
|
||||
ecl_file_select_block() function, or alternatively you can use
|
||||
ecl_file_open_block() to directly select the relevant block
|
||||
@@ -109,8 +109,8 @@
|
||||
calls to create a new sub index will also use the global_map index
|
||||
- i.e. the indexing is not recursive, a sub index is always created
|
||||
based on the global_map, and not on the currently active map.
|
||||
|
||||
|
||||
|
||||
|
||||
[1]: This is not entirely true - in the file ecl_rstfile.c; which
|
||||
is included from this file are several specialized function
|
||||
for working with restart files. However the restart files are
|
||||
@@ -128,7 +128,7 @@ typedef struct file_map_struct file_map_type;
|
||||
struct file_map_struct {
|
||||
vector_type * kw_list; /* This is a vector of ecl_file_kw instances corresponding to the content of the file. */
|
||||
hash_type * kw_index; /* A hash table with integer vectors of indices - see comment below. */
|
||||
stringlist_type * distinct_kw; /* A stringlist of the keywords occuring in the file - each string occurs ONLY ONCE. */
|
||||
stringlist_type * distinct_kw; /* A stringlist of the keywords occuring in the file - each string occurs ONLY ONCE. */
|
||||
fortio_type * fortio; /* The same fortio instance pointer as in the ecl_file styructure. */
|
||||
bool owner; /* Is this map the owner of the ecl_file_kw instances; only true for the global_map. */
|
||||
inv_map_type * inv_map; /* Shared reference owned by the ecl_file structure. */
|
||||
@@ -158,10 +158,10 @@ struct ecl_file_struct {
|
||||
with entries 'SEQHDR', 'MINISTEP' and 'PARAMS'. Each entry in the
|
||||
hash table is an integer vector which again contains the internal
|
||||
index of the various occurences:
|
||||
|
||||
|
||||
------------------
|
||||
SEQHDR \
|
||||
MINISTEP 0 |
|
||||
MINISTEP 0 |
|
||||
PARAMS ..... |
|
||||
MINISTEP 1 |
|
||||
PARAMS ..... |
|
||||
@@ -172,7 +172,7 @@ struct ecl_file_struct {
|
||||
kw_index = {"SEQHDR": [0], "MINISTEP": [1,3,5], "PARAMS": [2,4,6]} <== This is hash table.
|
||||
kw_list = [SEQHDR , MINISTEP , PARAMS , MINISTEP , PARAMS , MINISTEP , PARAMS]
|
||||
distinct_kw = [SEQHDR , MINISTEP , PARAMS]
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ static int file_map_get_global_index( const file_map_type * file_map , const cha
|
||||
int global_index = int_vector_iget( index_vector , ith);
|
||||
return global_index;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -216,7 +216,7 @@ static int file_map_get_global_index( const file_map_type * file_map , const cha
|
||||
internal index fields 'kw_index' and 'distinct_kw'. This function
|
||||
must be called every time the content of the kw_list vector is
|
||||
modified (otherwise the ecl_file instance will be in an
|
||||
inconsistent state).
|
||||
inconsistent state).
|
||||
*/
|
||||
|
||||
|
||||
@@ -233,7 +233,7 @@ static void file_map_make_index( file_map_type * file_map ) {
|
||||
hash_insert_hash_owned_ref( file_map->kw_index , header , index_vector , int_vector_free__);
|
||||
stringlist_append_copy( file_map->distinct_kw , header);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
int_vector_type * index_vector = hash_get( file_map->kw_index , header);
|
||||
int_vector_append( index_vector , i);
|
||||
@@ -244,7 +244,7 @@ static void file_map_make_index( file_map_type * file_map ) {
|
||||
|
||||
static bool file_map_has_kw( const file_map_type * file_map, const char * kw) {
|
||||
return hash_has_key( file_map->kw_index , kw );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static ecl_file_kw_type * file_map_iget_file_kw( const file_map_type * file_map , int global_index) {
|
||||
@@ -265,7 +265,7 @@ static ecl_kw_type * file_map_iget_kw( const file_map_type * file_map , int inde
|
||||
ecl_kw_type * ecl_kw = ecl_file_kw_get_kw_ptr( file_kw , file_map->fortio , file_map->inv_map);
|
||||
if (!ecl_kw) {
|
||||
if (fortio_assert_stream_open( file_map->fortio )) {
|
||||
|
||||
|
||||
ecl_kw = ecl_file_kw_get_kw( file_kw , file_map->fortio , file_map->inv_map);
|
||||
|
||||
if (FILE_FLAGS_SET( file_map->flags[0] , ECL_FILE_CLOSE_STREAM))
|
||||
@@ -283,7 +283,7 @@ static void file_map_index_fload_kw(const file_map_type * file_map, const char*
|
||||
ecl_type_enum ecl_type = ecl_file_kw_get_type(file_kw);
|
||||
int element_count = ecl_file_kw_get_size(file_kw);
|
||||
|
||||
ecl_kw_fread_indexed_data(file_map->fortio, offset + ECL_KW_FORTIO_HEADER_SIZE, ecl_type, element_count, index_map, buffer);
|
||||
ecl_kw_fread_indexed_data(file_map->fortio, offset + ECL_KW_HEADER_FORTIO_SIZE, ecl_type, element_count, index_map, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,9 +339,9 @@ static ecl_kw_type * file_map_iget_named_kw( const file_map_type * file_map , co
|
||||
ecl_kw_type * ecl_kw = ecl_file_kw_get_kw_ptr( file_kw , file_map->fortio , file_map->inv_map );
|
||||
if (!ecl_kw) {
|
||||
if (fortio_assert_stream_open( file_map->fortio )) {
|
||||
|
||||
|
||||
ecl_kw = ecl_file_kw_get_kw( file_kw , file_map->fortio , file_map->inv_map);
|
||||
|
||||
|
||||
if (FILE_FLAGS_SET( file_map->flags[0] , ECL_FILE_CLOSE_STREAM))
|
||||
fortio_fclose_stream( file_map->fortio );
|
||||
}
|
||||
@@ -365,16 +365,16 @@ static void file_map_replace_kw( file_map_type * file_map , ecl_kw_type * old_kw
|
||||
while (index < vector_get_size( file_map->kw_list )) {
|
||||
ecl_file_kw_type * ikw = vector_iget( file_map->kw_list , index );
|
||||
if (ecl_file_kw_ptr_eq( ikw , old_kw)) {
|
||||
/*
|
||||
/*
|
||||
Found it; observe that the vector_iset() function will
|
||||
automatically invoke the destructor on the old_kw.
|
||||
automatically invoke the destructor on the old_kw.
|
||||
*/
|
||||
ecl_kw_type * insert_kw = new_kw;
|
||||
|
||||
|
||||
if (insert_copy)
|
||||
insert_kw = ecl_kw_alloc_copy( new_kw );
|
||||
ecl_file_kw_replace_kw( ikw , file_map->fortio , insert_kw );
|
||||
|
||||
|
||||
file_map_make_index( file_map );
|
||||
return;
|
||||
}
|
||||
@@ -386,7 +386,7 @@ static void file_map_replace_kw( file_map_type * file_map , ecl_kw_type * old_kw
|
||||
|
||||
static bool file_map_load_all( file_map_type * file_map ) {
|
||||
bool loadOK = false;
|
||||
|
||||
|
||||
if (fortio_assert_stream_open( file_map->fortio )) {
|
||||
int index;
|
||||
for (index = 0; index < vector_get_size( file_map->kw_list); index++) {
|
||||
@@ -409,9 +409,9 @@ static bool file_map_load_all( file_map_type * file_map ) {
|
||||
|
||||
static void file_map_add_kw( file_map_type * file_map , ecl_file_kw_type * file_kw) {
|
||||
if (file_map->owner)
|
||||
vector_append_owned_ref( file_map->kw_list , file_kw , ecl_file_kw_free__ );
|
||||
vector_append_owned_ref( file_map->kw_list , file_kw , ecl_file_kw_free__ );
|
||||
else
|
||||
vector_append_ref( file_map->kw_list , file_kw);
|
||||
vector_append_ref( file_map->kw_list , file_kw);
|
||||
}
|
||||
|
||||
static void file_map_free( file_map_type * file_map ) {
|
||||
@@ -451,7 +451,7 @@ static int file_map_iget_occurence( const file_map_type * file_map , int global_
|
||||
const char * header = ecl_file_kw_get_header( file_kw );
|
||||
const int_vector_type * index_vector = hash_get( file_map->kw_index , header );
|
||||
const int * index_data = int_vector_get_const_ptr( index_vector );
|
||||
|
||||
|
||||
int occurence = -1;
|
||||
{
|
||||
/* Manual reverse lookup. */
|
||||
@@ -471,8 +471,8 @@ static void file_map_fprintf_kw_list(const file_map_type * file_map , FILE * str
|
||||
for (i=0; i < vector_get_size( file_map->kw_list ); i++) {
|
||||
const ecl_file_kw_type * file_kw = vector_iget_const( file_map->kw_list , i );
|
||||
fprintf(stream , "%-8s %7d:%s\n",
|
||||
ecl_file_kw_get_header( file_kw ) ,
|
||||
ecl_file_kw_get_size( file_kw ) ,
|
||||
ecl_file_kw_get_header( file_kw ) ,
|
||||
ecl_file_kw_get_size( file_kw ) ,
|
||||
ecl_util_get_type_name( ecl_file_kw_get_type( file_kw )));
|
||||
}
|
||||
}
|
||||
@@ -486,20 +486,20 @@ static file_map_type * file_map_alloc_blockmap(const file_map_type * file_map ,
|
||||
if (file_map_has_kw( file_map , header )) {
|
||||
int kw_index = file_map_get_global_index( file_map , header , occurence );
|
||||
ecl_file_kw_type * file_kw = vector_iget( file_map->kw_list , kw_index );
|
||||
|
||||
|
||||
while (true) {
|
||||
file_map_add_kw( block_map , file_kw );
|
||||
|
||||
|
||||
kw_index++;
|
||||
if (kw_index == vector_get_size( file_map->kw_list ))
|
||||
break;
|
||||
break;
|
||||
else {
|
||||
file_kw = vector_iget(file_map->kw_list , kw_index);
|
||||
if (strcmp( header , ecl_file_kw_get_header( file_kw )) == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
file_map_make_index( block_map );
|
||||
return block_map;
|
||||
} else
|
||||
@@ -536,7 +536,7 @@ void ecl_file_fwrite_fortio(const ecl_file_type * ecl_file , fortio_type * targe
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
Observe : if the filename is a standard filename which can be used
|
||||
to infer formatted/unformatted automagically the fmt_file variable
|
||||
is NOT consulted.
|
||||
@@ -545,11 +545,11 @@ void ecl_file_fwrite_fortio(const ecl_file_type * ecl_file , fortio_type * targe
|
||||
void ecl_file_fwrite(const ecl_file_type * ecl_file , const char * filename, bool fmt_file) {
|
||||
bool __fmt_file;
|
||||
ecl_file_enum file_type;
|
||||
|
||||
|
||||
file_type = ecl_util_get_file_type( filename , &__fmt_file , NULL);
|
||||
if (file_type == ECL_OTHER_FILE)
|
||||
__fmt_file = fmt_file;
|
||||
|
||||
|
||||
{
|
||||
fortio_type * target = fortio_open_writer( filename , __fmt_file , ECL_ENDIAN_FLIP);
|
||||
ecl_file_fwrite_fortio( ecl_file , target , 0);
|
||||
@@ -591,7 +591,7 @@ void ecl_file_fwrite(const ecl_file_type * ecl_file , const char * filename, boo
|
||||
....
|
||||
for (ikw = 0; ikw < ecl_file_get_num_distinct_kw(ecl_file); ikw++) {
|
||||
const char * kw = ecl_file_iget_distinct_kw(ecl_file , ikw);
|
||||
|
||||
|
||||
printf("The file contains: %d occurences of \'%s\' \n",ecl_file_get_num_named_kw( ecl_file , kw) , kw);
|
||||
}
|
||||
....
|
||||
@@ -601,7 +601,7 @@ void ecl_file_fwrite(const ecl_file_type * ecl_file , const char * filename, boo
|
||||
The file contains 1 occurences of 'SEQHDR'
|
||||
The file contains 3 occurences of 'MINISTEP'
|
||||
The file contains 3 occurences of 'PARAMS'
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@@ -623,7 +623,7 @@ void ecl_file_fwrite(const ecl_file_type * ecl_file , const char * filename, boo
|
||||
@old_kw can not be found the function will fail hard - to verify
|
||||
that @new_kw is indeed in the ecl_file instance you should use
|
||||
ecl_file_has_kw_ptr() first.
|
||||
|
||||
|
||||
The ecl_file function typically gives out references to the
|
||||
internal ecl_kw instances via the ecl_file_iget_kw() function. Use
|
||||
of ecl_file_replace_kw() might lead to invalidating ecl_kw
|
||||
@@ -634,22 +634,22 @@ void ecl_file_fwrite(const ecl_file_type * ecl_file , const char * filename, boo
|
||||
ecl_file_type * restart_file = ecl_file_fread_alloc( "ECLIPSE.UNRST" );
|
||||
ecl_kw_type * initial_pressure = ecl_file_iget_named_kw( ecl_file , "PRESSURE" , 0);
|
||||
ecl_kw_type * faked_pressure = ecl_kw_alloc_copy( initial_pressure );
|
||||
|
||||
|
||||
ecl_kw_scale( faked_pressure , 1.25 );
|
||||
ecl_file_replace_kw( restart_file , initial_pressure , faked_pressure , false ); <--- This call will invalidate the inital_pressure reference
|
||||
....
|
||||
....
|
||||
// This will fail horribly:
|
||||
// This will fail horribly:
|
||||
printf("The initial pressure in cell(0) was:%g \n",ecl_kw_iget_double( initial_pressure , 0 ));
|
||||
/|\
|
||||
|
|
||||
+---------> Using initial_pressure => Crash and burn!
|
||||
|
||||
+---------> Using initial_pressure => Crash and burn!
|
||||
|
||||
The ecl_file structure takes ownership of all the keywords, and
|
||||
will also take ownership of the newly instered @new_kw instance; if
|
||||
the boolean @insert_copy is set to true the function will insert a
|
||||
copy of @new_kw, leaving the original reference untouched.
|
||||
*/
|
||||
copy of @new_kw, leaving the original reference untouched.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -665,7 +665,7 @@ ecl_kw_type * ecl_file_icopy_named_kw( const ecl_file_type * ecl_file , const ch
|
||||
return ecl_kw_alloc_copy( ecl_file_iget_named_kw( ecl_file , kw , ith ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Will return the number of times a particular keyword occurs in a
|
||||
ecl_file instance. Will return 0 if the keyword can not be found.
|
||||
@@ -692,7 +692,7 @@ int ecl_file_get_num_named_kw(const ecl_file_type * ecl_file , const char * kw)
|
||||
|
||||
ecl_file_iget_occurence(ecl_file , 2) -> 0; Global index 2 will
|
||||
look up the first occurence of PARAMS.
|
||||
|
||||
|
||||
ecl_file_iget_occurence(ecl_file , 5) -> 2; Global index 5 will
|
||||
look up th third occurence of MINISTEP.
|
||||
|
||||
@@ -705,7 +705,7 @@ int ecl_file_iget_occurence( const ecl_file_type * ecl_file , int index) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
Returns the total number of ecl_kw instances in the ecl_file
|
||||
instance.
|
||||
*/
|
||||
@@ -778,10 +778,10 @@ const char * ecl_file_iget_header( const ecl_file_type * file , int global_index
|
||||
|
||||
/* ---------- */
|
||||
|
||||
/*
|
||||
/*
|
||||
This function will return the ith occurence of 'kw' in
|
||||
ecl_file. Will abort hard if the request can not be satisifed - use
|
||||
query functions if you can not take that.
|
||||
query functions if you can not take that.
|
||||
*/
|
||||
|
||||
ecl_kw_type * ecl_file_iget_named_kw( const ecl_file_type * file , const char * kw, int ith) {
|
||||
@@ -815,7 +815,7 @@ static file_map_type * ecl_file_get_blockmap( ecl_file_type * ecl_file , const c
|
||||
blockmap = file_map_alloc_blockmap( ecl_file->global_map , kw , occurence );
|
||||
else
|
||||
blockmap = file_map_alloc_blockmap( ecl_file->active_map , kw , occurence );
|
||||
|
||||
|
||||
if (blockmap != NULL)
|
||||
ecl_file_add_map( ecl_file , blockmap );
|
||||
return blockmap;
|
||||
@@ -824,7 +824,7 @@ static file_map_type * ecl_file_get_blockmap( ecl_file_type * ecl_file , const c
|
||||
|
||||
/*****************************************************************/
|
||||
/*
|
||||
Different functions to open and close a file.
|
||||
Different functions to open and close a file.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -835,23 +835,37 @@ static file_map_type * ecl_file_get_blockmap( ecl_file_type * ecl_file , const c
|
||||
map.
|
||||
*/
|
||||
|
||||
static void ecl_file_scan( ecl_file_type * ecl_file ) {
|
||||
static bool ecl_file_scan( ecl_file_type * ecl_file ) {
|
||||
bool scan_ok = false;
|
||||
fortio_fseek( ecl_file->fortio , 0 , SEEK_SET );
|
||||
{
|
||||
ecl_kw_type * work_kw = ecl_kw_alloc_new("WORK-KW" , 0 , ECL_INT_TYPE , NULL);
|
||||
offset_type current_offset;
|
||||
|
||||
while (true) {
|
||||
current_offset = fortio_ftell( ecl_file->fortio );
|
||||
if (ecl_kw_fread_header( work_kw , ecl_file->fortio )) {
|
||||
ecl_file_kw_type * file_kw = ecl_file_kw_alloc( work_kw , current_offset);
|
||||
file_map_add_kw( ecl_file->global_map , file_kw );
|
||||
ecl_file_kw_fskip_data( file_kw , ecl_file->fortio );
|
||||
} else
|
||||
if (fortio_read_at_eof(ecl_file->fortio)) {
|
||||
scan_ok = true;
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
offset_type current_offset = fortio_ftell( ecl_file->fortio );
|
||||
if (ecl_kw_fread_header( work_kw , ecl_file->fortio)) {
|
||||
ecl_file_kw_type * file_kw = ecl_file_kw_alloc( work_kw , current_offset);
|
||||
if (ecl_file_kw_fskip_data( file_kw , ecl_file->fortio ))
|
||||
file_map_add_kw( ecl_file->global_map , file_kw );
|
||||
else
|
||||
break;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ecl_kw_free( work_kw );
|
||||
}
|
||||
file_map_make_index( ecl_file->global_map );
|
||||
if (scan_ok)
|
||||
file_map_make_index( ecl_file->global_map );
|
||||
|
||||
return scan_ok;
|
||||
}
|
||||
|
||||
|
||||
@@ -868,54 +882,44 @@ void ecl_file_select_global( ecl_file_type * ecl_file ) {
|
||||
structure. No keyword data will be loaded from the file.
|
||||
|
||||
The ecl_file instance will retain an open fortio reference to the
|
||||
file until ecl_file_close() is called.
|
||||
file until ecl_file_close() is called.
|
||||
*/
|
||||
|
||||
|
||||
static ecl_file_type * ecl_file_open__( const char * filename , int flags) {
|
||||
ecl_file_type * ecl_file_open( const char * filename , int flags) {
|
||||
fortio_type * fortio;
|
||||
bool fmt_file;
|
||||
|
||||
ecl_util_fmt_file( filename , &fmt_file);
|
||||
//flags |= ECL_FILE_CLOSE_STREAM; // DEBUG DEBUG DEBUG
|
||||
|
||||
|
||||
if (FILE_FLAGS_SET(flags , ECL_FILE_WRITABLE))
|
||||
fortio = fortio_open_readwrite( filename , fmt_file , ECL_ENDIAN_FLIP);
|
||||
else
|
||||
fortio = fortio_open_reader( filename , fmt_file , ECL_ENDIAN_FLIP);
|
||||
else
|
||||
fortio = fortio_open_reader( filename , fmt_file , ECL_ENDIAN_FLIP);
|
||||
|
||||
if (fortio) {
|
||||
ecl_file_type * ecl_file = ecl_file_alloc_empty( flags );
|
||||
ecl_file->fortio = fortio;
|
||||
ecl_file->global_map = file_map_alloc( ecl_file->fortio , &ecl_file->flags , ecl_file->inv_map , true );
|
||||
|
||||
|
||||
ecl_file_add_map( ecl_file , ecl_file->global_map );
|
||||
ecl_file_scan( ecl_file );
|
||||
ecl_file_select_global( ecl_file );
|
||||
if (ecl_file_scan( ecl_file )) {
|
||||
ecl_file_select_global( ecl_file );
|
||||
|
||||
if (FILE_FLAGS_SET( ecl_file->flags , ECL_FILE_CLOSE_STREAM))
|
||||
fortio_fclose_stream( ecl_file->fortio );
|
||||
|
||||
return ecl_file;
|
||||
} else
|
||||
if (FILE_FLAGS_SET( ecl_file->flags , ECL_FILE_CLOSE_STREAM))
|
||||
fortio_fclose_stream( ecl_file->fortio );
|
||||
|
||||
return ecl_file;
|
||||
} else {
|
||||
ecl_file_close( ecl_file );
|
||||
return NULL;
|
||||
}
|
||||
} else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
ecl_file_type * ecl_file_open( const char * filename , int flags) {
|
||||
ecl_file_type * ecl_file = ecl_file_open__(filename , flags );
|
||||
if (ecl_file)
|
||||
return ecl_file;
|
||||
else {
|
||||
util_abort("%s: failed to open ECLIPSE file:%s \n",__func__ , filename);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ecl_file_type * ecl_file_try_open( const char * filename, int flags) {
|
||||
return ecl_file_open__(filename , flags );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -974,7 +978,7 @@ bool ecl_file_select_block( ecl_file_type * ecl_file , const char * kw , int occ
|
||||
void ecl_file_close(ecl_file_type * ecl_file) {
|
||||
if (ecl_file->fortio != NULL)
|
||||
fortio_fclose( ecl_file->fortio );
|
||||
|
||||
|
||||
inv_map_free( ecl_file->inv_map );
|
||||
vector_free( ecl_file->map_list );
|
||||
vector_free( ecl_file->map_stack );
|
||||
@@ -1019,7 +1023,7 @@ void ecl_file_free__(void * arg) {
|
||||
/* Here we include two files with functions specialized to work with
|
||||
restart and summary files. Observe that the files ecl_rstfile.c and
|
||||
ecl_smryfile are compiled as part of the same compilation unit as
|
||||
ecl_file.c
|
||||
ecl_file.c
|
||||
*/
|
||||
|
||||
#include "ecl_rstfile.c"
|
||||
@@ -1033,10 +1037,10 @@ void ecl_file_free__(void * arg) {
|
||||
The input @file must be either an INIT file or a restart file. Will
|
||||
fail hard if an INTEHEAD kw can not be found - or if the INTEHEAD
|
||||
keyword is not sufficiently large.
|
||||
|
||||
|
||||
The eclipse files can distinguish between ECLIPSE300 ( value == 300)
|
||||
and ECLIPSE300-Thermal option (value == 500). This function will
|
||||
return ECLIPSE300 in both those cases.
|
||||
return ECLIPSE300 in both those cases.
|
||||
*/
|
||||
|
||||
ecl_version_enum ecl_file_get_ecl_version( const ecl_file_type * file ) {
|
||||
@@ -1079,14 +1083,14 @@ bool ecl_file_writable( const ecl_file_type * ecl_file ) {
|
||||
/**
|
||||
Checks if the ecl_file contains ecl_kw; this check is based on
|
||||
pointer equality - i.e. we check if the ecl_file contains exactly
|
||||
this keyword - not an arbitrary equivalent keyword.
|
||||
this keyword - not an arbitrary equivalent keyword.
|
||||
|
||||
This function can be called as a safeguard before calling
|
||||
ecl_file_save_kw().
|
||||
ecl_file_save_kw().
|
||||
*/
|
||||
|
||||
bool ecl_file_has_kw_ptr( const ecl_file_type * ecl_file , const ecl_kw_type * ecl_kw) {
|
||||
ecl_file_kw_type * file_kw = inv_map_get_file_kw( ecl_file->inv_map , ecl_kw );
|
||||
ecl_file_kw_type * file_kw = inv_map_get_file_kw( ecl_file->inv_map , ecl_kw );
|
||||
if (file_kw == NULL)
|
||||
return false;
|
||||
else
|
||||
@@ -1108,19 +1112,19 @@ bool ecl_file_has_kw_ptr( const ecl_file_type * ecl_file , const ecl_kw_type * e
|
||||
will ensue if this is not satisfied.
|
||||
|
||||
3. The ecl_file must have been opened with one of the _writable()
|
||||
open functions.
|
||||
open functions.
|
||||
*/
|
||||
|
||||
bool ecl_file_save_kw( const ecl_file_type * ecl_file , const ecl_kw_type * ecl_kw) {
|
||||
ecl_file_kw_type * file_kw = inv_map_get_file_kw( ecl_file->inv_map , ecl_kw ); // We just verify that the input ecl_kw points to an ecl_kw
|
||||
ecl_file_kw_type * file_kw = inv_map_get_file_kw( ecl_file->inv_map , ecl_kw ); // We just verify that the input ecl_kw points to an ecl_kw
|
||||
if (file_kw != NULL) { // we manage; from then on we use the reference contained in
|
||||
if (fortio_assert_stream_open( ecl_file->fortio )) { // the corresponding ecl_file_kw instance.
|
||||
|
||||
ecl_file_kw_inplace_fwrite( file_kw , ecl_file->fortio );
|
||||
|
||||
if (fortio_assert_stream_open( ecl_file->fortio )) { // the corresponding ecl_file_kw instance.
|
||||
|
||||
ecl_file_kw_inplace_fwrite( file_kw , ecl_file->fortio );
|
||||
|
||||
if (FILE_FLAGS_SET( ecl_file->flags , ECL_FILE_CLOSE_STREAM))
|
||||
fortio_fclose_stream( ecl_file->fortio );
|
||||
|
||||
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
|
||||
+2
-2
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
+555
-552
File diff suppressed because it is too large
Load Diff
+314
-293
File diff suppressed because it is too large
Load Diff
+90
-90
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_kw_grdecl.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_kw_grdecl.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
3. The * notation can be used to print repeated values in a compact
|
||||
form, i.e. 1000*0.25 to get 1000 conecutive 0.25 values.
|
||||
|
||||
|
||||
The typical ECLIPSE keywords found in the datafile contain a mixture
|
||||
of numeric and character data; the current code assumes that all the
|
||||
data of a keyword is of the same underlying type, and do NOT support
|
||||
@@ -74,7 +74,7 @@ bool ecl_kw_grdecl_fseek_next_kw( FILE * stream ) {
|
||||
long start_pos = util_ftell( stream );
|
||||
long current_pos;
|
||||
char next_kw[256];
|
||||
|
||||
|
||||
/*
|
||||
Determine if the current position of the file pointer is at the
|
||||
beginning of the line; if not skip the rest of the line; this is
|
||||
@@ -83,17 +83,17 @@ bool ecl_kw_grdecl_fseek_next_kw( FILE * stream ) {
|
||||
{
|
||||
while (true) {
|
||||
char c;
|
||||
if (util_ftell(stream) == 0)
|
||||
if (util_ftell(stream) == 0)
|
||||
/*
|
||||
We are at the very beginning of the file. Can just jump out of
|
||||
the loop.
|
||||
*/
|
||||
break;
|
||||
|
||||
|
||||
util_fseek( stream , -1 , SEEK_CUR );
|
||||
c = fgetc( stream );
|
||||
if (c == '\n') {
|
||||
/*
|
||||
/*
|
||||
We have walked backwards reaching the start of the line. We
|
||||
have not reached any !isspace() characters on the way and
|
||||
can go back to start_pos and read from there.
|
||||
@@ -101,9 +101,9 @@ bool ecl_kw_grdecl_fseek_next_kw( FILE * stream ) {
|
||||
util_fseek( stream , start_pos , SEEK_SET );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (!isspace( c )) {
|
||||
/*
|
||||
/*
|
||||
We hit a non-whitespace character; this means that start_pos
|
||||
was not at the start of the line. We skip the rest of this
|
||||
line, and then start reading on the next line.
|
||||
@@ -114,12 +114,12 @@ bool ecl_kw_grdecl_fseek_next_kw( FILE * stream ) {
|
||||
util_fseek( stream , -2 , SEEK_CUR );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
while (true) {
|
||||
current_pos = util_ftell( stream );
|
||||
if (fscanf(stream , "%s" , next_kw) == 1) {
|
||||
if ((next_kw[0] == next_kw[1]) && (next_kw[0] == ECL_COMMENT_CHAR))
|
||||
if ((next_kw[0] == next_kw[1]) && (next_kw[0] == ECL_COMMENT_CHAR))
|
||||
// This is a comment line - skip it.
|
||||
util_fskip_lines( stream , 1 );
|
||||
else {
|
||||
@@ -140,7 +140,7 @@ bool ecl_kw_grdecl_fseek_next_kw( FILE * stream ) {
|
||||
Will use the ecl_kw_grdecl_fseek_next_header() to seek out the next
|
||||
header string, and read and return that string. If no more headers
|
||||
are found the function will return NULL. The storage allocated by
|
||||
this function must be free'd by the calling scope.
|
||||
this function must be free'd by the calling scope.
|
||||
*/
|
||||
|
||||
char * ecl_kw_grdecl_alloc_next_header( FILE * stream ) {
|
||||
@@ -153,7 +153,7 @@ char * ecl_kw_grdecl_alloc_next_header( FILE * stream ) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
This function will search through a GRDECL file to look for the
|
||||
'kw'; input variables and return vales are similar to
|
||||
ecl_kw_fseek_kw(). Observe that the GRDECL files are extremely
|
||||
@@ -161,7 +161,7 @@ char * ecl_kw_grdecl_alloc_next_header( FILE * stream ) {
|
||||
with a malformed GRDECL file.
|
||||
|
||||
In particular the comparison is case sensitive; that is probably not
|
||||
the case with ECLIPSE proper?
|
||||
the case with ECLIPSE proper?
|
||||
|
||||
If the kw is not found the file pointer is repositioned.
|
||||
*/
|
||||
@@ -189,27 +189,27 @@ static bool ecl_kw_grdecl_fseek_kw__(const char * kw , FILE * stream) {
|
||||
// static bool ecl_kw_grdecl_fseek_kw__OLD(const char * kw , FILE * stream) {
|
||||
// const int newline_char = '\n';
|
||||
// long int init_pos = ftell(stream);
|
||||
//
|
||||
//
|
||||
// if (util_fseek_string(stream , kw , false , true)) {
|
||||
// /*
|
||||
// OK the keyword is found in the file; now we must verify that:
|
||||
//
|
||||
//
|
||||
// 1. It is terminated with a blank, i.e. when searching for
|
||||
// 'COORD' we do not want a positive on 'COORDSYS'.
|
||||
//
|
||||
//
|
||||
// 2. That the keyword indeed starts with a isspace() character; we
|
||||
// are not interested in the 'SYS' in 'COORDSYS'.
|
||||
//
|
||||
// are not interested in the 'SYS' in 'COORDSYS'.
|
||||
//
|
||||
// 3. That the current location is not a comment section.
|
||||
// */
|
||||
// long int kw_pos = ftell( stream );
|
||||
// bool valid_kw = false;
|
||||
// int c;
|
||||
//
|
||||
//
|
||||
// fseek( stream , strlen(kw) , SEEK_CUR); // Seek to end of kw
|
||||
// c = fgetc( stream ); // Read one character
|
||||
// c = fgetc( stream ); // Read one character
|
||||
// fseek( stream , kw_pos , SEEK_SET ); // Seek back to beginning of kw
|
||||
//
|
||||
//
|
||||
// if (isspace(c)) {
|
||||
// if (kw_pos > 0) {
|
||||
// fseek( stream , kw_pos - 1 , SEEK_SET);
|
||||
@@ -220,9 +220,9 @@ static bool ecl_kw_grdecl_fseek_kw__(const char * kw , FILE * stream) {
|
||||
// valid_kw = true;
|
||||
// } else
|
||||
// valid_kw = true; // kw is at the very beginning of the file.
|
||||
// }
|
||||
//
|
||||
//
|
||||
// }
|
||||
//
|
||||
//
|
||||
// if (valid_kw) {
|
||||
// // OK - the kw is validly terminated with a space/tab/newline; now
|
||||
// // we must verify that it is not in a comment section.
|
||||
@@ -232,30 +232,30 @@ static bool ecl_kw_grdecl_fseek_kw__(const char * kw , FILE * stream) {
|
||||
// while (true) {
|
||||
// fseek( stream , -2 , SEEK_CUR );
|
||||
// c = fgetc( stream );
|
||||
// if ((c == newline_char) || (ftell(stream) == 0))
|
||||
// if ((c == newline_char) || (ftell(stream) == 0))
|
||||
// break;
|
||||
// }
|
||||
// {
|
||||
// // We have gone as far back as necessary.
|
||||
// int line_length = kw_pos - ftell( stream );
|
||||
// char * line = util_malloc(line_length + 1 , __func__);
|
||||
//
|
||||
//
|
||||
// fread( stream , sizeof * line , line_length , stream);
|
||||
// line[line_length] = '\0';
|
||||
//
|
||||
// if (strstr( line , ECL_COMMENT_STRING) == NULL)
|
||||
// // We are not in a commen section.
|
||||
//
|
||||
// if (strstr( line , ECL_COMMENT_STRING) == NULL)
|
||||
// // We are not in a commen section.
|
||||
// valid_kw = true;
|
||||
// else
|
||||
// valid_kw = false;
|
||||
//
|
||||
//
|
||||
// free( line );
|
||||
// }
|
||||
// }
|
||||
// } else
|
||||
// valid_kw = false;
|
||||
//
|
||||
// if (valid_kw)
|
||||
//
|
||||
// if (valid_kw)
|
||||
// return true;
|
||||
// else {
|
||||
// fseek( stream , strlen(kw) , SEEK_CUR ); // Skip over the kw so we don't find it again.
|
||||
@@ -265,8 +265,8 @@ static bool ecl_kw_grdecl_fseek_kw__(const char * kw , FILE * stream) {
|
||||
// fseek( stream , init_pos , SEEK_SET );
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// } else
|
||||
// }
|
||||
// } else
|
||||
// return false;
|
||||
// }
|
||||
|
||||
@@ -276,10 +276,10 @@ bool ecl_kw_grdecl_fseek_kw(const char * kw , bool rewind , FILE * stream) {
|
||||
return true; /* OK - we found the kw between current file pos and EOF. */
|
||||
else if (rewind) {
|
||||
long int init_pos = util_ftell(stream);
|
||||
|
||||
|
||||
util_fseek(stream , 0L , SEEK_SET);
|
||||
if (ecl_kw_grdecl_fseek_kw__( kw , stream )) /* Try again from the beginning of the file. */
|
||||
return true;
|
||||
return true;
|
||||
else
|
||||
util_fseek(stream , init_pos , SEEK_SET); /* Could not find it - reposition to initial position. */
|
||||
}
|
||||
@@ -293,13 +293,13 @@ bool ecl_kw_grdecl_fseek_kw(const char * kw , bool rewind , FILE * stream) {
|
||||
|
||||
/**
|
||||
Observe that this function does not preserve the '*' structure
|
||||
which (might) have been used in the input.
|
||||
which (might) have been used in the input.
|
||||
*/
|
||||
|
||||
|
||||
static void iset_range( char * data , int data_offset , int sizeof_ctype , void * value_ptr , int multiplier) {
|
||||
int index;
|
||||
for ( index =0; index < multiplier; index++)
|
||||
for ( index =0; index < multiplier; index++)
|
||||
memcpy( &data[ (index + data_offset) * sizeof_ctype ] , value_ptr , sizeof_ctype);
|
||||
}
|
||||
|
||||
@@ -317,11 +317,11 @@ static void iset_range( char * data , int data_offset , int sizeof_ctype , void
|
||||
Whatever that 'F' is - it is discarded when the SPECGRID header is
|
||||
written to a GRID/EGRID file. For this reason we have the
|
||||
possibility of setting @strict to false; in which case the 'F' or
|
||||
other characters in the numerical input will be ignored.
|
||||
other characters in the numerical input will be ignored.
|
||||
|
||||
If @strict is set to true the function will bomb when meeting a
|
||||
non-numeric character like the 'F' above.
|
||||
|
||||
non-numeric character like the 'F' above.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
The function supports multiplier keywords like:
|
||||
@@ -329,7 +329,7 @@ static void iset_range( char * data , int data_offset , int sizeof_ctype , void
|
||||
PERMX
|
||||
10000*0.15 0.16 0.17 0.18 0.19 10000*0.20
|
||||
/
|
||||
|
||||
|
||||
Observe that no-spaces-are-allowed-around-the-*
|
||||
*/
|
||||
|
||||
@@ -358,7 +358,7 @@ static char * fscanf_alloc_grdecl_data( const char * header , bool strict , ecl_
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (strcmp(buffer , ECL_DATA_TERMINATION) == 0)
|
||||
} else if (strcmp(buffer , ECL_DATA_TERMINATION) == 0)
|
||||
break;
|
||||
else {
|
||||
// We have read a valid input string; scan numerical input values from it.
|
||||
@@ -368,27 +368,27 @@ static char * fscanf_alloc_grdecl_data( const char * header , bool strict , ecl_
|
||||
int multiplier;
|
||||
void * value_ptr = NULL;
|
||||
bool char_input = false;
|
||||
|
||||
|
||||
if (ecl_type == ECL_INT_TYPE) {
|
||||
int value;
|
||||
|
||||
if (sscanf(buffer , "%d*%d" , &multiplier , &value) == 2)
|
||||
if (sscanf(buffer , "%d*%d" , &multiplier , &value) == 2)
|
||||
{}
|
||||
else if (sscanf( buffer , "%d" , &value) == 1)
|
||||
else if (sscanf( buffer , "%d" , &value) == 1)
|
||||
multiplier = 1;
|
||||
else {
|
||||
char_input = true;
|
||||
if (strict)
|
||||
util_abort("%s: Malformed content:\"%s\" when reading keyword:%s \n",__func__ , buffer , header);
|
||||
}
|
||||
|
||||
|
||||
value_ptr = &value;
|
||||
} else if (ecl_type == ECL_FLOAT_TYPE) {
|
||||
float value;
|
||||
|
||||
if (sscanf(buffer , "%d*%g" , &multiplier , &value) == 2)
|
||||
if (sscanf(buffer , "%d*%g" , &multiplier , &value) == 2)
|
||||
{}
|
||||
else if (sscanf( buffer , "%g" , &value) == 1)
|
||||
else if (sscanf( buffer , "%g" , &value) == 1)
|
||||
multiplier = 1;
|
||||
else {
|
||||
char_input = true;
|
||||
@@ -400,21 +400,21 @@ static char * fscanf_alloc_grdecl_data( const char * header , bool strict , ecl_
|
||||
} else if (ecl_type == ECL_DOUBLE_TYPE) {
|
||||
double value;
|
||||
|
||||
if (sscanf(buffer , "%d*%lg" , &multiplier , &value) == 2)
|
||||
if (sscanf(buffer , "%d*%lg" , &multiplier , &value) == 2)
|
||||
{}
|
||||
else if (sscanf( buffer , "%lg" , &value) == 1)
|
||||
else if (sscanf( buffer , "%lg" , &value) == 1)
|
||||
multiplier = 1;
|
||||
else {
|
||||
char_input = true;
|
||||
if (strict)
|
||||
util_abort("%s: Malformed content:\"%s\" when reading keyword:%s \n",__func__ , buffer , header);
|
||||
}
|
||||
|
||||
|
||||
value_ptr = &value;
|
||||
} else
|
||||
} else
|
||||
util_abort("%s: sorry type:%s not supported \n",__func__ , ecl_util_get_type_name(ecl_type));
|
||||
|
||||
|
||||
|
||||
|
||||
if (char_input)
|
||||
fprintf(stderr,"Warning: character string: \'%s\' ignored when reading keyword:%s \n",buffer , header);
|
||||
else {
|
||||
@@ -422,7 +422,7 @@ static char * fscanf_alloc_grdecl_data( const char * header , bool strict , ecl_
|
||||
data_size = 2*(data_index + multiplier);
|
||||
data = util_realloc( data , sizeof_ctype * data_size * sizeof * data);
|
||||
}
|
||||
|
||||
|
||||
iset_range( data , data_index , sizeof_ctype , value_ptr , multiplier );
|
||||
data_index += multiplier;
|
||||
}
|
||||
@@ -430,7 +430,7 @@ static char * fscanf_alloc_grdecl_data( const char * header , bool strict , ecl_
|
||||
}
|
||||
if (atEOF)
|
||||
break;
|
||||
} else
|
||||
} else
|
||||
break;
|
||||
}
|
||||
free( buffer );
|
||||
@@ -512,7 +512,7 @@ static ecl_kw_type * __ecl_kw_fscanf_alloc_grdecl__(FILE * stream , const char *
|
||||
if (fscanf(stream , "%s" , file_header) == 1) {
|
||||
int kw_size;
|
||||
char * data = fscanf_alloc_grdecl_data( file_header , strict , ecl_type , &kw_size , stream );
|
||||
|
||||
|
||||
// Verify size
|
||||
if (size > 0)
|
||||
if (size != kw_size) {
|
||||
@@ -520,20 +520,20 @@ static ecl_kw_type * __ecl_kw_fscanf_alloc_grdecl__(FILE * stream , const char *
|
||||
util_abort("%s: size mismatch when loading:%s. File:%d elements. Requested:%d elements \n",
|
||||
__func__ , file_header , kw_size , size);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
ecl_kw_type * ecl_kw = ecl_kw_alloc_new( file_header , kw_size , ecl_type , NULL );
|
||||
ecl_kw_set_data_ptr( ecl_kw , data );
|
||||
return ecl_kw;
|
||||
}
|
||||
|
||||
} else
|
||||
} else
|
||||
/** No header read - probably at EOF */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/*****************************************************************/
|
||||
/*
|
||||
/*
|
||||
Here comes the exported functions for loading a grdecl formatted
|
||||
keyword. All of these function invoke the fundamental
|
||||
ecl_kw_fscanf_alloc_grdecl__() function, but the set of input
|
||||
@@ -541,7 +541,7 @@ static ecl_kw_type * __ecl_kw_fscanf_alloc_grdecl__(FILE * stream , const char *
|
||||
accepts a @strict flag from calling scope; in general you should
|
||||
use strict == true.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
This function assumes that the file pointer has already been
|
||||
@@ -564,12 +564,12 @@ ecl_kw_type * ecl_kw_fscanf_alloc_grdecl_data(FILE * stream , int size , ecl_typ
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
/*
|
||||
/*
|
||||
This function will seek through the file and position the file
|
||||
pointer at the beginning of @kw before starting to load (this
|
||||
includes rewinding the file pointer). If @kw can not be found the
|
||||
function will return NULL.
|
||||
|
||||
function will return NULL.
|
||||
|
||||
As size is not supplied the function will keep loading data until
|
||||
the whole keyword is loaded, and then return.
|
||||
*/
|
||||
@@ -585,12 +585,12 @@ ecl_kw_type * ecl_kw_fscanf_alloc_grdecl_dynamic( FILE * stream , const char * k
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
/*
|
||||
/*
|
||||
This function will seek through the file and position the file
|
||||
pointer at the beginning of @kw before starting to load (this
|
||||
includes rewinding the file pointer). If @kw can not be found the
|
||||
function will return NULL.
|
||||
|
||||
function will return NULL.
|
||||
|
||||
When the data has been loaded the function will compare actual size
|
||||
with the supplied size argument and verify equality; if they differ
|
||||
it will crash hard. If you are uncertain of the size use the
|
||||
@@ -610,7 +610,7 @@ ecl_kw_type * ecl_kw_fscanf_alloc_grdecl( FILE * stream , const char * kw , int
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
/*
|
||||
/*
|
||||
This function will read and allocate the next keyword in the
|
||||
file. This function does not take either kw or the size of the kw
|
||||
as input, and has virtually zero possibilities to check what it is
|
||||
@@ -638,21 +638,21 @@ ecl_kw_type * ecl_kw_fscanf_alloc_current_grdecl( FILE * stream , ecl_type_enum
|
||||
/*
|
||||
This method allows to write with a different header,
|
||||
i.e. PORO_XXXX. This header is even allowed to break the 8 character
|
||||
length limit; i.e. loading it back naively will fail.
|
||||
length limit; i.e. loading it back naively will fail.
|
||||
*/
|
||||
|
||||
void ecl_kw_fprintf_grdecl__(const ecl_kw_type * ecl_kw , const char * special_header , FILE * stream) {
|
||||
void ecl_kw_fprintf_grdecl__(const ecl_kw_type * ecl_kw , const char * special_header , FILE * stream) {
|
||||
if (special_header)
|
||||
fprintf(stream,"%s\n" , special_header);
|
||||
else
|
||||
fprintf(stream,"%s\n" , special_header);
|
||||
else
|
||||
fprintf(stream,"%s\n" , ecl_kw_get_header(ecl_kw));
|
||||
|
||||
{
|
||||
fortio_type * fortio = fortio_alloc_FILE_wrapper(NULL , false , true , stream); /* Endian flip should *NOT* be used */
|
||||
fortio_type * fortio = fortio_alloc_FILE_wrapper(NULL , false , true , true , stream); /* Endian flip should *NOT* be used */
|
||||
ecl_kw_fwrite_data(ecl_kw , fortio);
|
||||
fortio_free_FILE_wrapper( fortio );
|
||||
}
|
||||
fprintf(stream,"/\n");
|
||||
fprintf(stream,"/\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
+69
-59
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
Copyright (C) 2013 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_nnc_export.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more detals.
|
||||
*/
|
||||
Copyright (C) 2013 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_nnc_export.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more detals.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <ert/util/int_vector.h>
|
||||
@@ -33,16 +33,17 @@ int ecl_nnc_export_get_size( const ecl_grid_type * grid ) {
|
||||
|
||||
|
||||
|
||||
static void ecl_nnc_export__( const ecl_grid_type * grid , int lgr_index1 , const ecl_file_type * init_file , ecl_nnc_type * nnc_data, int * nnc_offset) {
|
||||
static int ecl_nnc_export__( const ecl_grid_type * grid , int lgr_index1 , const ecl_file_type * init_file , ecl_nnc_type * nnc_data, int * nnc_offset) {
|
||||
int nnc_index = *nnc_offset;
|
||||
int lgr_nr1 = ecl_grid_get_lgr_nr( grid );
|
||||
int global_index1;
|
||||
int valid_trans = 0 ;
|
||||
const ecl_grid_type * global_grid = ecl_grid_get_global_grid( grid );
|
||||
|
||||
if (!global_grid)
|
||||
global_grid = grid;
|
||||
|
||||
|
||||
|
||||
for (global_index1 = 0; global_index1 < ecl_grid_get_global_size( grid ); global_index1++) {
|
||||
const nnc_info_type * nnc_info = ecl_grid_get_cell_nnc_info1( grid , global_index1 );
|
||||
if (nnc_info) {
|
||||
@@ -53,6 +54,7 @@ static void ecl_nnc_export__( const ecl_grid_type * grid , int lgr_index1 , con
|
||||
const int_vector_type * nnc_index_list = nnc_vector_get_nnc_index_list( nnc_vector );
|
||||
int lgr_nr2 = nnc_vector_get_lgr_nr( nnc_vector );
|
||||
const ecl_kw_type * tran_kw = ecl_nnc_export_get_tranx_kw(global_grid , init_file , lgr_nr1 , lgr_nr2 );
|
||||
|
||||
int index2;
|
||||
ecl_nnc_type nnc;
|
||||
|
||||
@@ -62,7 +64,12 @@ static void ecl_nnc_export__( const ecl_grid_type * grid , int lgr_index1 , con
|
||||
|
||||
for (index2 = 0; index2 < nnc_vector_get_size( nnc_vector ); index2++) {
|
||||
nnc.global_index2 = int_vector_iget( grid2_index_list , index2 );
|
||||
nnc.trans = ecl_kw_iget_as_double( tran_kw , int_vector_iget( nnc_index_list , index2));
|
||||
if(tran_kw) {
|
||||
nnc.trans = ecl_kw_iget_as_double(tran_kw, int_vector_iget(nnc_index_list, index2));
|
||||
valid_trans++;
|
||||
}else{
|
||||
nnc.trans = ERT_ECL_DEFAULT_NNC_TRANS;
|
||||
}
|
||||
|
||||
nnc_data[nnc_index] = nnc;
|
||||
nnc_index++;
|
||||
@@ -71,21 +78,24 @@ static void ecl_nnc_export__( const ecl_grid_type * grid , int lgr_index1 , con
|
||||
}
|
||||
}
|
||||
*nnc_offset = nnc_index;
|
||||
return valid_trans;
|
||||
}
|
||||
|
||||
|
||||
void ecl_nnc_export( const ecl_grid_type * grid , const ecl_file_type * init_file , ecl_nnc_type * nnc_data) {
|
||||
int ecl_nnc_export( const ecl_grid_type * grid , const ecl_file_type * init_file , ecl_nnc_type * nnc_data) {
|
||||
int nnc_index = 0;
|
||||
ecl_nnc_export__( grid , 0 , init_file , nnc_data , &nnc_index );
|
||||
int total_valid_trans = 0;
|
||||
total_valid_trans = ecl_nnc_export__( grid , 0 , init_file , nnc_data , &nnc_index );
|
||||
{
|
||||
int lgr_index;
|
||||
int lgr_index;
|
||||
for (lgr_index = 0; lgr_index < ecl_grid_get_num_lgr(grid); lgr_index++) {
|
||||
ecl_grid_type * igrid = ecl_grid_iget_lgr( grid , lgr_index );
|
||||
ecl_nnc_export__( igrid , lgr_index , init_file , nnc_data , &nnc_index );
|
||||
total_valid_trans += ecl_nnc_export__( igrid , lgr_index , init_file , nnc_data , &nnc_index );
|
||||
}
|
||||
}
|
||||
nnc_index = ecl_nnc_export_get_size( grid );
|
||||
ecl_nnc_sort( nnc_data , nnc_index );
|
||||
return total_valid_trans;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,21 +103,21 @@ void ecl_nnc_export( const ecl_grid_type * grid , const ecl_file_type * init_fi
|
||||
int ecl_nnc_cmp( const ecl_nnc_type * nnc1 , const ecl_nnc_type * nnc2) {
|
||||
|
||||
if (nnc1->grid_nr1 != nnc2->grid_nr1) {
|
||||
if (nnc1->grid_nr1 < nnc2->grid_nr1)
|
||||
if (nnc1->grid_nr1 < nnc2->grid_nr1)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (nnc1->grid_nr2 != nnc2->grid_nr2) {
|
||||
if (nnc1->grid_nr2 < nnc2->grid_nr2)
|
||||
if (nnc1->grid_nr2 < nnc2->grid_nr2)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (nnc1->global_index1 != nnc2->global_index1) {
|
||||
if (nnc1->global_index1 < nnc2->global_index1)
|
||||
if (nnc1->global_index1 < nnc2->global_index1)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
@@ -115,12 +125,12 @@ int ecl_nnc_cmp( const ecl_nnc_type * nnc1 , const ecl_nnc_type * nnc2) {
|
||||
|
||||
|
||||
if (nnc1->global_index2 != nnc2->global_index2) {
|
||||
if (nnc1->global_index2 < nnc2->global_index2)
|
||||
if (nnc1->global_index2 < nnc2->global_index2)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -142,19 +152,19 @@ ecl_kw_type * ecl_nnc_export_get_tranll_kw( const ecl_grid_type * grid , const e
|
||||
ecl_kw_type * tran_kw = NULL;
|
||||
const int file_num_kw = ecl_file_get_size( init_file );
|
||||
int global_kw_index = 0;
|
||||
|
||||
|
||||
while (true) {
|
||||
if (global_kw_index >= file_num_kw)
|
||||
if (global_kw_index >= file_num_kw)
|
||||
break;
|
||||
{
|
||||
ecl_kw_type * ecl_kw = ecl_file_iget_kw( init_file , global_kw_index );
|
||||
if (strcmp( LGRJOIN_KW , ecl_kw_get_header( ecl_kw)) == 0) {
|
||||
|
||||
|
||||
if (ecl_kw_icmp_string( ecl_kw , 0 , lgr_name1) && ecl_kw_icmp_string( ecl_kw , 1 , lgr_name2)) {
|
||||
tran_kw = ecl_file_iget_kw( init_file , global_kw_index + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
global_kw_index++;
|
||||
}
|
||||
}
|
||||
@@ -166,47 +176,47 @@ ecl_kw_type * ecl_nnc_export_get_tranll_kw( const ecl_grid_type * grid , const e
|
||||
|
||||
ecl_kw_type * ecl_nnc_export_get_tran_kw( const ecl_file_type * init_file , const char * kw , int lgr_nr ) {
|
||||
ecl_kw_type * tran_kw = NULL;
|
||||
|
||||
if (lgr_nr == 0) {
|
||||
if (strcmp(kw , TRANNNC_KW) == 0)
|
||||
tran_kw = ecl_file_iget_named_kw( init_file , TRANNNC_KW , 0 );
|
||||
if(ecl_file_has_kw(init_file, kw)) {
|
||||
tran_kw = ecl_file_iget_named_kw(init_file, TRANNNC_KW, 0);
|
||||
}
|
||||
} else {
|
||||
if ((strcmp(kw , TRANNNC_KW) == 0) ||
|
||||
(strcmp(kw , TRANGL_KW) == 0)) {
|
||||
int tran_kw_forward_skip;
|
||||
const int file_num_kw = ecl_file_get_size( init_file );
|
||||
int global_kw_index = 0;
|
||||
bool finished = false;
|
||||
|
||||
if (strcmp(kw , TRANNNC_KW) == 0)
|
||||
tran_kw_forward_skip = 3;
|
||||
else
|
||||
tran_kw_forward_skip = 4;
|
||||
|
||||
while (!finished) {
|
||||
bool correct_lgrheadi = false;
|
||||
int head_index = 0;
|
||||
int steps = 0;
|
||||
|
||||
|
||||
while(!finished){
|
||||
ecl_kw_type * ecl_kw = ecl_file_iget_kw( init_file , global_kw_index );
|
||||
|
||||
if (strcmp( LGRHEADI_KW , ecl_kw_get_header( ecl_kw )) == 0) {
|
||||
const char *current_kw = ecl_kw_get_header(ecl_kw);
|
||||
if (strcmp( LGRHEADI_KW , current_kw) == 0) {
|
||||
if (ecl_kw_iget_int( ecl_kw , LGRHEADI_LGR_NR_INDEX) == lgr_nr) {
|
||||
|
||||
if ((global_kw_index + tran_kw_forward_skip) < file_num_kw) {
|
||||
ecl_kw_type * ecl_kw = ecl_file_iget_kw( init_file , global_kw_index + tran_kw_forward_skip);
|
||||
|
||||
/* We found the TRANGL / TRANNC keyword we are after. */
|
||||
if (strcmp( kw , ecl_kw_get_header( ecl_kw )) == 0) {
|
||||
tran_kw = ecl_kw;
|
||||
finished = true;
|
||||
break;
|
||||
}
|
||||
correct_lgrheadi = true;
|
||||
head_index = global_kw_index;
|
||||
}else{
|
||||
correct_lgrheadi = false;
|
||||
}
|
||||
}
|
||||
if(correct_lgrheadi) {
|
||||
if (strcmp(kw, current_kw) == 0) {
|
||||
steps = global_kw_index - head_index; /* This is to calculate who fare from lgrheadi we found the TRANGL/TRANNNC key word */
|
||||
if(steps == 3 || steps == 4 || steps == 6) { /* We only support a file format where TRANNNC is 3 steps and TRANGL is 4 or 6 steps from LGRHEADI */
|
||||
tran_kw = ecl_kw;
|
||||
finished = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
global_kw_index++;
|
||||
if (global_kw_index == file_num_kw)
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return tran_kw;
|
||||
|
||||
+116
-54
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_rft_file.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_rft_file.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@@ -46,9 +46,9 @@
|
||||
|
||||
All of this is just lumped together in one long vector, both in the
|
||||
file, and in this implementation. The data for one specific RFT
|
||||
(one well, one time) is internalized in the ecl_rft_node type.
|
||||
(one well, one time) is internalized in the ecl_rft_node type.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#define ECL_RFT_FILE_ID 6610632
|
||||
@@ -73,7 +73,7 @@ static ecl_rft_file_type * ecl_rft_file_alloc_empty(const char * filename) {
|
||||
|
||||
/**
|
||||
Generating the two functions:
|
||||
|
||||
|
||||
bool ecl_rft_file_is_instance( void * );
|
||||
ecl_rft_file_type * ecl_rft_file_safe_cast( void * );
|
||||
*/
|
||||
@@ -94,25 +94,25 @@ ecl_rft_file_type * ecl_rft_file_alloc(const char * filename) {
|
||||
ecl_file_type * ecl_file = ecl_file_open( filename , 0);
|
||||
int global_index = 0;
|
||||
int block_nr = 0;
|
||||
|
||||
|
||||
while (true) {
|
||||
if (ecl_file_select_block( ecl_file , TIME_KW , block_nr)) {
|
||||
ecl_rft_node_type * rft_node = ecl_rft_node_alloc( ecl_file );
|
||||
if (rft_node != NULL) {
|
||||
if (rft_node != NULL) {
|
||||
const char * well_name = ecl_rft_node_get_well_name( rft_node );
|
||||
ecl_rft_file_add_node(rft_vector , rft_node);
|
||||
if (!hash_has_key( rft_vector->well_index , well_name))
|
||||
if (!hash_has_key( rft_vector->well_index , well_name))
|
||||
hash_insert_hash_owned_ref( rft_vector->well_index , well_name , int_vector_alloc( 0 , 0 ) , int_vector_free__);
|
||||
{
|
||||
int_vector_type * index_list = hash_get( rft_vector->well_index , well_name );
|
||||
int_vector_append(index_list , global_index);
|
||||
}
|
||||
}
|
||||
global_index++;
|
||||
}
|
||||
}
|
||||
} else
|
||||
break;
|
||||
block_nr++;
|
||||
}
|
||||
}
|
||||
ecl_file_close( ecl_file );
|
||||
return rft_vector;
|
||||
}
|
||||
@@ -123,7 +123,7 @@ ecl_rft_file_type * ecl_rft_file_alloc(const char * filename) {
|
||||
ecl_grid_load_case(). Will return NULL if no RFT file can be found,
|
||||
and the name of RFT file if it is found. New storage is allocated
|
||||
for the new name.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
char * ecl_rft_file_alloc_case_filename(const char * case_input ) {
|
||||
@@ -140,20 +140,20 @@ char * ecl_rft_file_alloc_case_filename(const char * case_input ) {
|
||||
if ((file_type == ECL_OTHER_FILE) || (file_type == ECL_DATA_FILE)) { /* Impossible to infer formatted/unformatted from the case_input */
|
||||
char * RFT_file = ecl_util_alloc_filename( path , basename , ECL_RFT_FILE , false , -1 );
|
||||
char * FRFT_file = ecl_util_alloc_filename( path , basename , ECL_RFT_FILE , true , -1 );
|
||||
|
||||
|
||||
if (util_file_exists( RFT_file ))
|
||||
return_file = util_alloc_string_copy( RFT_file );
|
||||
else if (util_file_exists( FRFT_file ))
|
||||
return_file = util_alloc_string_copy( FRFT_file );
|
||||
|
||||
|
||||
free( RFT_file );
|
||||
free( FRFT_file );
|
||||
} else {
|
||||
char * RFT_file = ecl_util_alloc_filename( path , basename , ECL_RFT_FILE , fmt_file , -1 );
|
||||
|
||||
|
||||
if (util_file_exists( RFT_file ))
|
||||
return_file = util_alloc_string_copy( RFT_file );
|
||||
|
||||
|
||||
free( RFT_file );
|
||||
}
|
||||
return return_file;
|
||||
@@ -183,7 +183,7 @@ bool ecl_rft_file_case_has_rft( const char * case_input ) {
|
||||
has_rft = true;
|
||||
free( file_name );
|
||||
}
|
||||
|
||||
|
||||
return has_rft;
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ void ecl_rft_file_free__(void * arg) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
Will return the number of RFT nodes in the file. If @well != NULL
|
||||
only wells matching @well be included. The @well variable can
|
||||
contain '*', so the function call
|
||||
@@ -210,7 +210,7 @@ void ecl_rft_file_free__(void * arg) {
|
||||
ecl_rft_file_get_size__( rft_file , "OP*" , -1)
|
||||
|
||||
will count the number of rft instances with a well name matching
|
||||
well "OP*".
|
||||
well "OP*".
|
||||
|
||||
If recording_time >= only rft_nodes with recording time ==
|
||||
@recording_time are included.
|
||||
@@ -262,7 +262,7 @@ const char * ecl_rft_file_get_filename( const ecl_rft_file_type * rft_file ) {
|
||||
|
||||
/**
|
||||
Return rft_node number 'i' in the rft_file - not caring when this
|
||||
particular RFT is from, or which well it is.
|
||||
particular RFT is from, or which well it is.
|
||||
|
||||
If you ask for an index which is beyond the size of the vector it will
|
||||
go up in flames - use ecl_file_get_size() first if you can not
|
||||
@@ -286,9 +286,9 @@ ecl_rft_node_type * ecl_rft_file_iget_node( const ecl_rft_file_type * rft_file ,
|
||||
RFT - Well P1: 01/01/2002
|
||||
RFT - Well P2: 01/01/2002
|
||||
|
||||
The function call:
|
||||
The function call:
|
||||
|
||||
ecl_rft_iget_well_rft(rft_file , "P2" , 1)
|
||||
ecl_rft_iget_well_rft(rft_file , "P2" , 1)
|
||||
|
||||
will return the rft node indicated by the arrow (i.e. the second
|
||||
occurence of well "P2" in the file.)
|
||||
@@ -307,6 +307,29 @@ ecl_rft_node_type * ecl_rft_file_iget_well_rft( const ecl_rft_file_type * rft_fi
|
||||
}
|
||||
|
||||
|
||||
static int ecl_rft_file_get_node_index_time_rft( const ecl_rft_file_type * rft_file , const char * well , time_t recording_time) {
|
||||
int global_index = -1;
|
||||
if (hash_has_key( rft_file->well_index , well)) {
|
||||
const int_vector_type * index_vector = hash_get(rft_file->well_index , well);
|
||||
int well_index = 0;
|
||||
while (true) {
|
||||
if (well_index == int_vector_size( index_vector ))
|
||||
break;
|
||||
|
||||
{
|
||||
const ecl_rft_node_type * node = ecl_rft_file_iget_node( rft_file , int_vector_iget( index_vector , well_index ));
|
||||
if (ecl_rft_node_get_date( node ) == recording_time) {
|
||||
global_index = int_vector_iget( index_vector , well_index );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
well_index++;
|
||||
}
|
||||
}
|
||||
return global_index;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Returns an rft_node for well 'well' and time 'recording_time'. If
|
||||
@@ -316,28 +339,17 @@ ecl_rft_node_type * ecl_rft_file_iget_well_rft( const ecl_rft_file_type * rft_fi
|
||||
|
||||
|
||||
ecl_rft_node_type * ecl_rft_file_get_well_time_rft( const ecl_rft_file_type * rft_file , const char * well , time_t recording_time) {
|
||||
ecl_rft_node_type * node = NULL;
|
||||
if (hash_has_key( rft_file->well_index , well)) {
|
||||
const int_vector_type * index_vector = hash_get(rft_file->well_index , well);
|
||||
int index = 0;
|
||||
while (true) {
|
||||
if (index == int_vector_size( index_vector ))
|
||||
break;
|
||||
|
||||
node = ecl_rft_file_iget_node( rft_file , int_vector_iget( index_vector , index ));
|
||||
if (ecl_rft_node_get_date( node ) == recording_time)
|
||||
break;
|
||||
else {
|
||||
node = NULL;
|
||||
index++;
|
||||
}
|
||||
|
||||
}
|
||||
int index = ecl_rft_file_get_node_index_time_rft(rft_file, well, recording_time);
|
||||
if (index !=-1) {
|
||||
return ecl_rft_file_iget_node(rft_file, index);
|
||||
} else{
|
||||
return NULL;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool ecl_rft_file_has_well( const ecl_rft_file_type * rft_file , const char * well) {
|
||||
return hash_has_key(rft_file->well_index , well);
|
||||
}
|
||||
@@ -353,7 +365,7 @@ int ecl_rft_file_get_well_occurences( const ecl_rft_file_type * rft_file , const
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
Returns the number of distinct wells in RFT file.
|
||||
*/
|
||||
int ecl_rft_file_get_num_wells( const ecl_rft_file_type * rft_file ) {
|
||||
@@ -368,5 +380,55 @@ stringlist_type * ecl_rft_file_alloc_well_list(const ecl_rft_file_type * rft_fil
|
||||
|
||||
|
||||
|
||||
void ecl_rft_file_update(const char * rft_file_name, ecl_rft_node_type ** nodes,int num_nodes, ert_ecl_unit_enum unit_set){
|
||||
ecl_rft_file_type * rft_file;
|
||||
|
||||
if(util_file_exists(rft_file_name)){
|
||||
int node_index;
|
||||
rft_file = ecl_rft_file_alloc( rft_file_name );
|
||||
for(node_index = 0; node_index < num_nodes; node_index++) {
|
||||
ecl_rft_node_type * new_node = nodes[node_index];
|
||||
int storage_index = ecl_rft_file_get_node_index_time_rft(rft_file, ecl_rft_node_get_well_name(new_node), ecl_rft_node_get_date(new_node));
|
||||
if (storage_index == -1) {
|
||||
ecl_rft_file_add_node(rft_file, new_node);
|
||||
} else {
|
||||
vector_iset_owned_ref(rft_file->data, storage_index, new_node,ecl_rft_node_free__);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
int node_index;
|
||||
rft_file = ecl_rft_file_alloc_empty( rft_file_name );
|
||||
for(node_index = 0; node_index < num_nodes; node_index++) {
|
||||
ecl_rft_file_add_node(rft_file, nodes[node_index]);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
bool fmt_file = false;
|
||||
fortio_type * fortio = fortio_open_writer( rft_file_name , fmt_file , ECL_ENDIAN_FLIP );
|
||||
int node_index;
|
||||
|
||||
/**
|
||||
The sorting here works directly on the internal node storage
|
||||
rft_file->data; that might in principle ruin the indexing of
|
||||
the ecl_file object - it is therefor absolutely essential
|
||||
that this ecl_rft_file object does not live beyond this
|
||||
function, and also that the ecl_rft_file api functions are
|
||||
avoided for the rest of this function.
|
||||
*/
|
||||
|
||||
vector_sort(rft_file->data,(vector_cmp_ftype *) ecl_rft_node_cmp);
|
||||
for(node_index=0; node_index < vector_get_size( rft_file->data ); node_index++) {
|
||||
const ecl_rft_node_type *new_node = vector_iget_const(rft_file->data, node_index);
|
||||
ecl_rft_node_fwrite(new_node, fortio, unit_set);
|
||||
}
|
||||
|
||||
fortio_fclose( fortio );
|
||||
}
|
||||
ecl_rft_file_free(rft_file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+237
-63
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_rft_node.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_rft_node.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
@@ -34,13 +34,14 @@
|
||||
#include <ert/ecl/ecl_rft_node.h>
|
||||
#include <ert/ecl/ecl_rft_cell.h>
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
The RFT's from several wells, and possibly also several timesteps
|
||||
are lumped togeheter in one .RFT file. The ecl_rft_node
|
||||
implemented in this file contains the information for one
|
||||
well/report step.
|
||||
well/report step.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@@ -57,13 +58,13 @@ struct ecl_rft_node_struct {
|
||||
char * well_name; /* Name of the well. */
|
||||
|
||||
ecl_rft_enum data_type; /* What type of data: RFT|PLT|SEGMENT */
|
||||
time_t recording_date; /* When was the RFT recorded - date.*/
|
||||
time_t recording_date; /* When was the RFT recorded - date.*/
|
||||
double days; /* When was the RFT recorded - days after simulaton start. */
|
||||
bool MSW;
|
||||
|
||||
bool sort_perm_in_sync ;
|
||||
|
||||
bool sort_perm_in_sync ;
|
||||
int_vector_type * sort_perm;
|
||||
vector_type *cells;
|
||||
vector_type *cells;
|
||||
};
|
||||
|
||||
|
||||
@@ -72,20 +73,39 @@ struct ecl_rft_node_struct {
|
||||
Will return NULL if the data_type_string is equal to "SEGMENT" -
|
||||
that is not (yet) supported.
|
||||
*/
|
||||
static ecl_rft_enum translate_from_sting_to_ecl_rft_enum(const char * data_type_string){
|
||||
ecl_rft_enum data_type = SEGMENT;
|
||||
/* According to the ECLIPSE documentaton. */
|
||||
if (strchr(data_type_string , 'P') != NULL)
|
||||
data_type = PLT;
|
||||
else if (strchr(data_type_string, 'R') != NULL)
|
||||
data_type = RFT;
|
||||
else if (strchr(data_type_string , 'S') != NULL)
|
||||
data_type = SEGMENT;
|
||||
else
|
||||
util_abort("%s: Could not determine type of RFT/PLT/SEGMENT data - aborting\n",__func__);
|
||||
|
||||
return data_type;
|
||||
}
|
||||
|
||||
ecl_rft_node_type * ecl_rft_node_alloc_new(const char * well_name, const char * data_type_string, const time_t recording_date, const double days){
|
||||
ecl_rft_enum data_type = translate_from_sting_to_ecl_rft_enum(data_type_string);
|
||||
ecl_rft_node_type * rft_node = util_malloc(sizeof * rft_node );
|
||||
UTIL_TYPE_ID_INIT( rft_node , ECL_RFT_NODE_ID );
|
||||
rft_node->well_name = util_alloc_string_copy(well_name);
|
||||
rft_node->cells = vector_alloc_new();
|
||||
rft_node->recording_date = recording_date;
|
||||
rft_node->days = days;
|
||||
rft_node->data_type = data_type;
|
||||
rft_node->sort_perm = NULL;
|
||||
rft_node->sort_perm_in_sync = false;
|
||||
|
||||
return rft_node;
|
||||
}
|
||||
|
||||
|
||||
static ecl_rft_node_type * ecl_rft_node_alloc_empty(const char * data_type_string) {
|
||||
ecl_rft_enum data_type = SEGMENT;
|
||||
|
||||
/* According to the ECLIPSE documentaton. */
|
||||
if (strchr(data_type_string , 'P') != NULL)
|
||||
data_type = PLT;
|
||||
else if (strchr(data_type_string, 'R') != NULL)
|
||||
data_type = RFT;
|
||||
else if (strchr(data_type_string , 'S') != NULL)
|
||||
data_type = SEGMENT;
|
||||
else
|
||||
util_abort("%s: Could not determine type of RFT/PLT/SEGMENT data - aborting\n",__func__);
|
||||
|
||||
ecl_rft_enum data_type = translate_from_sting_to_ecl_rft_enum(data_type_string);
|
||||
|
||||
/* Can return NULL */
|
||||
if (data_type == SEGMENT) {
|
||||
@@ -96,12 +116,12 @@ static ecl_rft_node_type * ecl_rft_node_alloc_empty(const char * data_type_strin
|
||||
{
|
||||
ecl_rft_node_type * rft_node = util_malloc(sizeof * rft_node );
|
||||
UTIL_TYPE_ID_INIT( rft_node , ECL_RFT_NODE_ID );
|
||||
|
||||
|
||||
rft_node->cells = vector_alloc_new();
|
||||
rft_node->data_type = data_type;
|
||||
rft_node->sort_perm = NULL;
|
||||
rft_node->sort_perm_in_sync = false;
|
||||
|
||||
|
||||
return rft_node;
|
||||
}
|
||||
}
|
||||
@@ -111,7 +131,7 @@ UTIL_SAFE_CAST_FUNCTION( ecl_rft_node , ECL_RFT_NODE_ID );
|
||||
UTIL_IS_INSTANCE_FUNCTION( ecl_rft_node , ECL_RFT_NODE_ID );
|
||||
|
||||
|
||||
static void ecl_rft_node_append_cell( ecl_rft_node_type * rft_node , ecl_rft_cell_type * cell) {
|
||||
void ecl_rft_node_append_cell( ecl_rft_node_type * rft_node , ecl_rft_cell_type * cell) {
|
||||
vector_append_owned_ref( rft_node->cells , cell , ecl_rft_cell_free__ );
|
||||
rft_node->sort_perm_in_sync = false;
|
||||
}
|
||||
@@ -134,35 +154,35 @@ static void ecl_rft_node_init_RFT_cells( ecl_rft_node_type * rft_node , const ec
|
||||
const int * i = ecl_kw_get_int_ptr( conipos );
|
||||
const int * j = ecl_kw_get_int_ptr( conjpos );
|
||||
const int * k = ecl_kw_get_int_ptr( conkpos );
|
||||
|
||||
|
||||
{
|
||||
int c;
|
||||
for (c = 0; c < ecl_kw_get_size( conipos ); c++) {
|
||||
/* The connection coordinates are shifted -= 1; i.e. all internal usage is offset 0. */
|
||||
ecl_rft_cell_type * cell = ecl_rft_cell_alloc_RFT( i[c] - 1 , j[c] - 1 , k[c] - 1 ,
|
||||
ecl_rft_cell_type * cell = ecl_rft_cell_alloc_RFT( i[c] - 1 , j[c] - 1 , k[c] - 1 ,
|
||||
depth[c] , P[c] , SW[c] , SG[c]);
|
||||
ecl_rft_node_append_cell( rft_node , cell );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void ecl_rft_node_init_PLT_cells( ecl_rft_node_type * rft_node , const ecl_file_type * rft) {
|
||||
/* For PLT there is quite a lot of extra information which is not yet internalized. */
|
||||
const ecl_kw_type * conipos = ecl_file_iget_named_kw( rft , CONIPOS_KW , 0);
|
||||
const ecl_kw_type * conjpos = ecl_file_iget_named_kw( rft , CONJPOS_KW , 0);
|
||||
const ecl_kw_type * conkpos = ecl_file_iget_named_kw( rft , CONKPOS_KW , 0);
|
||||
const ecl_kw_type * conkpos = ecl_file_iget_named_kw( rft , CONKPOS_KW , 0);
|
||||
|
||||
const int * i = ecl_kw_get_int_ptr( conipos );
|
||||
const int * j = ecl_kw_get_int_ptr( conjpos );
|
||||
const int * k = ecl_kw_get_int_ptr( conkpos );
|
||||
|
||||
|
||||
const float * WR = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONWRAT_KW , 0));
|
||||
const float * GR = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONGRAT_KW , 0));
|
||||
const float * OR = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONORAT_KW , 0));
|
||||
const float * GR = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONGRAT_KW , 0));
|
||||
const float * OR = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONORAT_KW , 0));
|
||||
const float * P = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONPRES_KW , 0));
|
||||
const float * depth = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONDEPTH_KW , 0));
|
||||
const float * flowrate = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONVTUB_KW , 0));
|
||||
@@ -170,12 +190,12 @@ static void ecl_rft_node_init_PLT_cells( ecl_rft_node_type * rft_node , const ec
|
||||
const float * gas_flowrate = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONGTUB_KW , 0));
|
||||
const float * water_flowrate = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONWTUB_KW , 0));
|
||||
const float * connection_start = NULL;
|
||||
const float * connection_end = NULL;
|
||||
const float * connection_end = NULL;
|
||||
|
||||
/* The keywords CONLENST_KW and CONLENEN_KW are ONLY present if we are dealing with a MSW well. */
|
||||
if (ecl_file_has_kw( rft , CONLENST_KW))
|
||||
connection_start = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONLENST_KW , 0));
|
||||
|
||||
|
||||
if (ecl_file_has_kw( rft , CONLENEN_KW))
|
||||
connection_end = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONLENEN_KW , 0));
|
||||
|
||||
@@ -185,15 +205,15 @@ static void ecl_rft_node_init_PLT_cells( ecl_rft_node_type * rft_node , const ec
|
||||
ecl_rft_cell_type * cell;
|
||||
double cs = 0;
|
||||
double ce = 0;
|
||||
|
||||
|
||||
if (connection_start)
|
||||
cs = connection_start[c];
|
||||
|
||||
|
||||
if (connection_end)
|
||||
ce = connection_end[c];
|
||||
|
||||
/* The connection coordinates are shifted -= 1; i.e. all internal usage is offset 0. */
|
||||
cell = ecl_rft_cell_alloc_PLT( i[c] -1 , j[c] -1 , k[c] -1 ,
|
||||
cell = ecl_rft_cell_alloc_PLT( i[c] -1 , j[c] -1 , k[c] -1 ,
|
||||
depth[c] , P[c] , OR[c] , GR[c] , WR[c] , cs , ce, flowrate[c] , oil_flowrate[c] , gas_flowrate[c] , water_flowrate[c]);
|
||||
ecl_rft_node_append_cell( rft_node , cell );
|
||||
}
|
||||
@@ -210,18 +230,18 @@ static void ecl_rft_node_init_cells( ecl_rft_node_type * rft_node , const ecl_fi
|
||||
ecl_rft_node_init_RFT_cells( rft_node , rft );
|
||||
else if (rft_node->data_type == PLT)
|
||||
ecl_rft_node_init_PLT_cells( rft_node , rft );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
ecl_rft_node_type * ecl_rft_node_alloc(const ecl_file_type * rft) {
|
||||
ecl_kw_type * welletc = ecl_file_iget_named_kw(rft , WELLETC_KW , 0);
|
||||
ecl_rft_node_type * rft_node = ecl_rft_node_alloc_empty(ecl_kw_iget_ptr(welletc , WELLETC_TYPE_INDEX));
|
||||
|
||||
|
||||
if (rft_node != NULL) {
|
||||
ecl_kw_type * date_kw = ecl_file_iget_named_kw( rft , DATE_KW , 0);
|
||||
rft_node->well_name = util_alloc_strip_copy( ecl_kw_iget_ptr(welletc , WELLETC_NAME_INDEX));
|
||||
|
||||
|
||||
/* Time information. */
|
||||
{
|
||||
int * time = ecl_kw_get_int_ptr( date_kw );
|
||||
@@ -238,9 +258,9 @@ ecl_rft_node_type * ecl_rft_node_alloc(const ecl_file_type * rft) {
|
||||
return rft_node;
|
||||
}
|
||||
|
||||
|
||||
const char * ecl_rft_node_get_well_name(const ecl_rft_node_type * rft_node) {
|
||||
return rft_node->well_name;
|
||||
|
||||
const char * ecl_rft_node_get_well_name(const ecl_rft_node_type * rft_node) {
|
||||
return rft_node->well_name;
|
||||
}
|
||||
|
||||
|
||||
@@ -279,7 +299,7 @@ const ecl_rft_cell_type * ecl_rft_node_iget_cell( const ecl_rft_node_type * rft_
|
||||
static void ecl_rft_node_create_sort_perm( ecl_rft_node_type * rft_node ) {
|
||||
if (rft_node->sort_perm)
|
||||
int_vector_free( rft_node->sort_perm );
|
||||
|
||||
|
||||
rft_node->sort_perm = vector_alloc_sort_perm( rft_node->cells , ecl_rft_cell_cmp__ );
|
||||
rft_node->sort_perm_in_sync = true;
|
||||
}
|
||||
@@ -295,7 +315,7 @@ const ecl_rft_cell_type * ecl_rft_node_iget_cell_sorted( ecl_rft_node_type * rft
|
||||
else {
|
||||
if (!rft_node->sort_perm_in_sync)
|
||||
ecl_rft_node_create_sort_perm( rft_node );
|
||||
|
||||
|
||||
return vector_iget_const( rft_node->cells , int_vector_iget( rft_node->sort_perm , index ));
|
||||
}
|
||||
}
|
||||
@@ -317,20 +337,20 @@ double ecl_rft_node_iget_pressure( const ecl_rft_node_type * rft_node , int inde
|
||||
|
||||
void ecl_rft_node_iget_ijk( const ecl_rft_node_type * rft_node , int index , int *i , int *j , int *k) {
|
||||
const ecl_rft_cell_type * cell = ecl_rft_node_iget_cell( rft_node , index );
|
||||
|
||||
|
||||
ecl_rft_cell_get_ijk( cell , i,j,k);
|
||||
}
|
||||
|
||||
|
||||
const ecl_rft_cell_type * ecl_rft_node_lookup_ijk( const ecl_rft_node_type * rft_node , int i, int j , int k) {
|
||||
int index = 0;
|
||||
const ecl_rft_cell_type * ecl_rft_node_lookup_ijk( const ecl_rft_node_type * rft_node , int i, int j , int k) {
|
||||
int index = 0;
|
||||
int size = ecl_rft_node_get_size( rft_node );
|
||||
while (true) {
|
||||
const ecl_rft_cell_type * cell = ecl_rft_node_iget_cell( rft_node , index );
|
||||
|
||||
|
||||
if (ecl_rft_cell_ijk_equal( cell , i , j , k ))
|
||||
return cell;
|
||||
|
||||
|
||||
index++;
|
||||
if (index == size) /* Could not find it. */
|
||||
return NULL;
|
||||
@@ -364,6 +384,9 @@ double ecl_rft_node_iget_swat( const ecl_rft_node_type * rft_node , int index) {
|
||||
}
|
||||
}
|
||||
|
||||
double ecl_rft_node_get_days(const ecl_rft_node_type * rft_node ){
|
||||
return rft_node->days;
|
||||
}
|
||||
|
||||
double ecl_rft_node_iget_soil( const ecl_rft_node_type * rft_node , int index) {
|
||||
assert_type_and_index( rft_node , RFT , index );
|
||||
@@ -429,4 +452,155 @@ bool ecl_rft_node_is_RFT( const ecl_rft_node_type * rft_node ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ecl_rft_node_fill_welletc(ecl_kw_type * welletc, ert_ecl_unit_enum unit_set){
|
||||
if(unit_set==ERT_ECL_METRIC_UNITS) {
|
||||
ecl_kw_iset_string8(welletc, 0, " DAYS");
|
||||
ecl_kw_iset_string8(welletc, 2, "");
|
||||
ecl_kw_iset_string8(welletc, 3, " METRES");
|
||||
ecl_kw_iset_string8(welletc, 4, " BARSA");
|
||||
ecl_kw_iset_string8(welletc, 6, "STANDARD");
|
||||
ecl_kw_iset_string8(welletc, 7, " SM3/DAY");
|
||||
ecl_kw_iset_string8(welletc, 8, " SM3/DAY");
|
||||
ecl_kw_iset_string8(welletc, 9, " RM3/DAY");
|
||||
ecl_kw_iset_string8(welletc, 10, " M/SEC");
|
||||
ecl_kw_iset_string8(welletc, 11, "");
|
||||
ecl_kw_iset_string8(welletc, 12, " CP");
|
||||
ecl_kw_iset_string8(welletc, 13, " KG/SM3");
|
||||
ecl_kw_iset_string8(welletc, 14, " KG/DAY");
|
||||
ecl_kw_iset_string8(welletc, 15, " KG/KG");
|
||||
}else if(unit_set==ERT_ECL_FIELD_UNITS){
|
||||
ecl_kw_iset_string8(welletc, 0, " DAYS");
|
||||
ecl_kw_iset_string8(welletc, 2, "");
|
||||
ecl_kw_iset_string8(welletc, 3, " FEET");
|
||||
ecl_kw_iset_string8(welletc, 4, " PISA");
|
||||
ecl_kw_iset_string8(welletc, 6, "STANDARD");
|
||||
ecl_kw_iset_string8(welletc, 7, " STB/DAY");
|
||||
ecl_kw_iset_string8(welletc, 8, " MSCF/DAY");
|
||||
ecl_kw_iset_string8(welletc, 9, " RB/DAY");
|
||||
ecl_kw_iset_string8(welletc, 10, " FT/SEC");
|
||||
ecl_kw_iset_string8(welletc, 11, "");
|
||||
ecl_kw_iset_string8(welletc, 12, " CP");
|
||||
ecl_kw_iset_string8(welletc, 13, " LB/STB");
|
||||
ecl_kw_iset_string8(welletc, 14, " LB/DAY");
|
||||
ecl_kw_iset_string8(welletc, 15, " LB/LB");
|
||||
|
||||
}else if(unit_set==ERT_ECL_LAB_UNITS){
|
||||
ecl_kw_iset_string8(welletc, 0, " HR");
|
||||
ecl_kw_iset_string8(welletc, 2, "");
|
||||
ecl_kw_iset_string8(welletc, 3, " CM");
|
||||
ecl_kw_iset_string8(welletc, 4, " ATMA");
|
||||
ecl_kw_iset_string8(welletc, 6, "STANDARD");
|
||||
ecl_kw_iset_string8(welletc, 7, " SCC/HR");
|
||||
ecl_kw_iset_string8(welletc, 8, " SCC/HR");
|
||||
ecl_kw_iset_string8(welletc, 9, " RCC/SCC");
|
||||
ecl_kw_iset_string8(welletc, 10, " CM/SEC");
|
||||
ecl_kw_iset_string8(welletc, 11, "");
|
||||
ecl_kw_iset_string8(welletc, 12, " CP");
|
||||
ecl_kw_iset_string8(welletc, 13, " GM/SCC");
|
||||
ecl_kw_iset_string8(welletc, 14, " GH/HR");
|
||||
ecl_kw_iset_string8(welletc, 15, " GM/GM");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ecl_rft_node_fwrite(const ecl_rft_node_type * rft_node, fortio_type * fortio, ert_ecl_unit_enum unit_set){
|
||||
ecl_rft_enum type = ecl_rft_node_get_type(rft_node);
|
||||
if (type != RFT)
|
||||
util_abort("%s: sorry - only writing of simple RFT is currently implemented",__func__);
|
||||
|
||||
{
|
||||
ecl_kw_type * time = ecl_kw_alloc(TIME_KW, 1, ECL_FLOAT_TYPE);
|
||||
ecl_kw_iset_float(time, 0, ecl_rft_node_get_days(rft_node));
|
||||
ecl_kw_fwrite(time, fortio);
|
||||
ecl_kw_free(time);
|
||||
}
|
||||
|
||||
{
|
||||
ecl_kw_type * datevalue = ecl_kw_alloc(DATE_KW, 3, ECL_INT_TYPE);
|
||||
time_t date = ecl_rft_node_get_date(rft_node);
|
||||
int day;
|
||||
int month;
|
||||
int year;
|
||||
ecl_util_set_date_values(date , &day , &month , &year);
|
||||
ecl_kw_iset_int(datevalue, 0, day);
|
||||
ecl_kw_iset_int(datevalue, 1, month);
|
||||
ecl_kw_iset_int(datevalue, 2, year);
|
||||
ecl_kw_fwrite(datevalue, fortio);
|
||||
ecl_kw_free(datevalue);
|
||||
}
|
||||
|
||||
{
|
||||
ecl_kw_type * welletc = ecl_kw_alloc(WELLETC_KW, 16, ECL_CHAR_TYPE);
|
||||
ecl_rft_enum type = ecl_rft_node_get_type(rft_node);
|
||||
|
||||
ecl_kw_iset_string8(welletc, 1, ecl_rft_node_get_well_name(rft_node));
|
||||
|
||||
if(type == PLT) {
|
||||
ecl_kw_iset_string8(welletc, 5, "P");
|
||||
}else if(type == RFT){
|
||||
ecl_kw_iset_string8(welletc, 5, "R");
|
||||
}else if(type == SEGMENT){
|
||||
ecl_kw_iset_string8(welletc, 5, "S");
|
||||
}
|
||||
ecl_rft_node_fill_welletc(welletc, unit_set);
|
||||
ecl_kw_fwrite(welletc, fortio);
|
||||
ecl_kw_free(welletc);
|
||||
}
|
||||
|
||||
{
|
||||
int size_cells = ecl_rft_node_get_size(rft_node);
|
||||
ecl_kw_type * conipos = ecl_kw_alloc(CONIPOS_KW, size_cells, ECL_INT_TYPE);
|
||||
ecl_kw_type * conjpos = ecl_kw_alloc(CONJPOS_KW, size_cells, ECL_INT_TYPE);
|
||||
ecl_kw_type * conkpos = ecl_kw_alloc(CONKPOS_KW, size_cells, ECL_INT_TYPE);
|
||||
ecl_kw_type * hostgrid = ecl_kw_alloc(HOSTGRID_KW, size_cells, ECL_CHAR_TYPE);
|
||||
ecl_kw_type * depth = ecl_kw_alloc(DEPTH_KW, size_cells, ECL_FLOAT_TYPE);
|
||||
ecl_kw_type * pressure = ecl_kw_alloc(PRESSURE_KW, size_cells, ECL_FLOAT_TYPE);
|
||||
ecl_kw_type * swat = ecl_kw_alloc(SWAT_KW, size_cells, ECL_FLOAT_TYPE);
|
||||
ecl_kw_type * sgas = ecl_kw_alloc(SGAS_KW, size_cells, ECL_FLOAT_TYPE);
|
||||
int i;
|
||||
|
||||
for(i =0;i<size_cells;i++){
|
||||
const ecl_rft_cell_type * cell = vector_iget_const( rft_node->cells , i);
|
||||
ecl_kw_iset_int(conipos, i, ecl_rft_cell_get_i(cell)+1);
|
||||
ecl_kw_iset_int(conjpos, i, ecl_rft_cell_get_j(cell)+1);
|
||||
ecl_kw_iset_int(conkpos, i, ecl_rft_cell_get_k(cell)+1);
|
||||
ecl_kw_iset_float(depth, i, ecl_rft_cell_get_depth(cell));
|
||||
ecl_kw_iset_float(pressure, i, ecl_rft_cell_get_pressure(cell));
|
||||
ecl_kw_iset_float(swat, i, ecl_rft_cell_get_swat(cell));
|
||||
ecl_kw_iset_float(sgas, i, ecl_rft_cell_get_sgas(cell));
|
||||
}
|
||||
ecl_kw_fwrite(conipos, fortio);
|
||||
ecl_kw_fwrite(conjpos, fortio);
|
||||
ecl_kw_fwrite(conkpos, fortio);
|
||||
ecl_kw_fwrite(hostgrid, fortio);
|
||||
ecl_kw_fwrite(depth, fortio);
|
||||
ecl_kw_fwrite(pressure, fortio);
|
||||
ecl_kw_fwrite(swat, fortio);
|
||||
ecl_kw_fwrite(sgas, fortio);
|
||||
|
||||
ecl_kw_free(conipos);
|
||||
ecl_kw_free(conjpos);
|
||||
ecl_kw_free(conkpos);
|
||||
ecl_kw_free(hostgrid);
|
||||
ecl_kw_free(depth);
|
||||
ecl_kw_free(pressure);
|
||||
ecl_kw_free(swat);
|
||||
ecl_kw_free(sgas);
|
||||
}
|
||||
}
|
||||
|
||||
int ecl_rft_node_cmp( const ecl_rft_node_type * n1 , const ecl_rft_node_type * n2) {
|
||||
time_t val1 = ecl_rft_node_get_date(n1);
|
||||
time_t val2 = ecl_rft_node_get_date(n2);
|
||||
|
||||
if (val1 < val2)
|
||||
return -1;
|
||||
else if (val1 == val2)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+27
-26
@@ -35,13 +35,15 @@
|
||||
#include <ert/ecl/ecl_kw_magic.h>
|
||||
#include <ert/ecl/ecl_file_kw.h>
|
||||
#include <ert/ecl/ecl_rst_file.h>
|
||||
#include <ert/ecl/ecl_rsthead.h>
|
||||
|
||||
struct ecl_rst_file_struct {
|
||||
fortio_type * fortio;
|
||||
bool unified;
|
||||
bool fmt_file;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static ecl_rst_file_type * ecl_rst_file_alloc( const char * filename ) {
|
||||
bool unified = ecl_util_unified_file( filename );
|
||||
@@ -112,46 +114,42 @@ void ecl_rst_file_end_solution( ecl_rst_file_type * rst_file ) {
|
||||
|
||||
|
||||
|
||||
static ecl_kw_type * ecl_rst_file_alloc_INTEHEAD( ecl_rst_file_type * rst_file , time_t date , int nx , int ny , int nz , int nactive , int phases, int simulator ) {
|
||||
static ecl_kw_type * ecl_rst_file_alloc_INTEHEAD( ecl_rst_file_type * rst_file,
|
||||
ecl_rsthead_type * rsthead,
|
||||
int simulator ) {
|
||||
ecl_kw_type * intehead_kw = ecl_kw_alloc( INTEHEAD_KW , INTEHEAD_RESTART_SIZE , ECL_INT_TYPE );
|
||||
ecl_kw_scalar_set_int( intehead_kw , 0 );
|
||||
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_UNIT_INDEX , INTEHEAD_METRIC_VALUE );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NX_INDEX , nx);
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NY_INDEX , ny);
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NZ_INDEX , nz);
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NACTIVE_INDEX , nactive);
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_PHASE_INDEX , phases );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NX_INDEX , rsthead->nx);
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NY_INDEX , rsthead->ny);
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NZ_INDEX , rsthead->nz);
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NACTIVE_INDEX , rsthead->nactive);
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_PHASE_INDEX , rsthead->phase_sum );
|
||||
|
||||
/* All well properties are hardcoded to zero. */
|
||||
{
|
||||
int NIWELZ = 0;
|
||||
int NGMAXZ = 0;
|
||||
int NWGMAX = 0;
|
||||
int NWELLS = 0;
|
||||
int NCWMAX = 0;
|
||||
int NZWELZ = 0;
|
||||
int NICONZ = 0;
|
||||
int NIGRPZ = 0;
|
||||
int NSWLMX = 0;
|
||||
int NSEGMX = 0;
|
||||
int NISEGZ = 0;
|
||||
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NWELLS_INDEX , NWELLS );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NCWMAX_INDEX , NCWMAX );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NWELLS_INDEX , rsthead->nwells );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NCWMAX_INDEX , rsthead->ncwmax );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NWGMAX_INDEX , NWGMAX );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NGMAXZ_INDEX , NGMAXZ );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NIWELZ_INDEX , NIWELZ );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NZWELZ_INDEX , NZWELZ );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NICONZ_INDEX , NICONZ );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NIWELZ_INDEX , rsthead->niwelz );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NZWELZ_INDEX , rsthead->nzwelz );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NICONZ_INDEX , rsthead->niconz );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_NIGRPZ_INDEX , NIGRPZ );
|
||||
|
||||
{
|
||||
int mday,month,year;
|
||||
util_set_date_values( date , &mday , &month , &year );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_DAY_INDEX , mday );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_MONTH_INDEX , month );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_YEAR_INDEX , year );
|
||||
util_set_date_values( rsthead->sim_time , &rsthead->day , &rsthead->month , &rsthead->year );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_DAY_INDEX , rsthead->day );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_MONTH_INDEX , rsthead->month );
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_YEAR_INDEX , rsthead->year );
|
||||
}
|
||||
|
||||
ecl_kw_iset_int( intehead_kw , INTEHEAD_IPROG_INDEX , simulator);
|
||||
@@ -195,12 +193,15 @@ static ecl_kw_type * ecl_rst_file_alloc_DOUBHEAD( ecl_rst_file_type * rst_file ,
|
||||
|
||||
|
||||
|
||||
void ecl_rst_file_fwrite_header( ecl_rst_file_type * rst_file , int seqnum , time_t date , double days , int nx , int ny ,int nz , int nactive , int phases) {
|
||||
void ecl_rst_file_fwrite_header( ecl_rst_file_type * rst_file ,
|
||||
int seqnum ,
|
||||
ecl_rsthead_type * rsthead_data ) {
|
||||
|
||||
if (rst_file->unified)
|
||||
ecl_rst_file_fwrite_SEQNUM( rst_file , seqnum );
|
||||
|
||||
{
|
||||
ecl_kw_type * intehead_kw = ecl_rst_file_alloc_INTEHEAD( rst_file , date , nx , ny , nz , nactive , phases , INTEHEAD_ECLIPSE100_VALUE);
|
||||
ecl_kw_type * intehead_kw = ecl_rst_file_alloc_INTEHEAD( rst_file , rsthead_data , INTEHEAD_ECLIPSE100_VALUE);
|
||||
ecl_kw_fwrite( intehead_kw , rst_file->fortio );
|
||||
ecl_kw_free( intehead_kw );
|
||||
}
|
||||
@@ -213,14 +214,14 @@ void ecl_rst_file_fwrite_header( ecl_rst_file_type * rst_file , int seqnum , tim
|
||||
|
||||
|
||||
{
|
||||
ecl_kw_type * doubhead_kw = ecl_rst_file_alloc_DOUBHEAD( rst_file , days );
|
||||
ecl_kw_type * doubhead_kw = ecl_rst_file_alloc_DOUBHEAD( rst_file , rsthead_data->sim_days );
|
||||
ecl_kw_fwrite( doubhead_kw , rst_file->fortio );
|
||||
ecl_kw_free( doubhead_kw );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ecl_rst_file_add_kw(ecl_rst_file_type * rst_file , const ecl_kw_type * ecl_kw ) {
|
||||
ecl_kw_fwrite( ecl_kw , rst_file->fortio );
|
||||
}
|
||||
|
||||
|
||||
|
||||
+65
-59
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_rstfile.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_rstfile.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
/*****************************************************************/
|
||||
@@ -24,10 +24,10 @@
|
||||
/*
|
||||
This file is included from the ecl_file.c file with a #include
|
||||
statement, i.e. it is the same compilation unit as ecl_file. The
|
||||
separation is only to increase readability.
|
||||
separation is only to increase readability.
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
There is no special datastructure for working with restart files,
|
||||
they are 100% stock ecl_file instances with the following limited
|
||||
structure:
|
||||
@@ -61,12 +61,12 @@ keyword, the value in [] corresponds to the relevant part of the
|
||||
content of the keyword on the line, the labels A,B,C,D,E are used for
|
||||
references in the text below.
|
||||
|
||||
0 | SEQNUM [0] \ A
|
||||
0 | SEQNUM [0] \ A
|
||||
1 | INTEHEAD [01.01.2005] |
|
||||
2 | PRESSURE [... ] |
|
||||
3 | SWAT [...] |
|
||||
2 | PRESSURE [... ] |
|
||||
3 | SWAT [...] |
|
||||
| -----------------------+
|
||||
4 | SEQNUM [5] | B
|
||||
4 | SEQNUM [5] | B
|
||||
5 | INTEHEAD [01.06.2005] |
|
||||
6 | PRESSURE [... ] |
|
||||
7 | SWAT [...] |
|
||||
@@ -86,7 +86,7 @@ references in the text below.
|
||||
13 | INTEHEAD [01.12.2009] |
|
||||
14 | PRESSURE [...] |
|
||||
15 | SWAT [...] /
|
||||
|
||||
|
||||
|
||||
This restart file has the following features:
|
||||
|
||||
@@ -98,7 +98,7 @@ This restart file has the following features:
|
||||
datafile. Observe that the file does not have the block structure
|
||||
visualized on this figure, the only thing separating the blocks in
|
||||
the file is the occurence of a SEQNUM keyword.
|
||||
|
||||
|
||||
o Only a few of the report steps are present, namely 0, 5, 10, 20 and
|
||||
40.
|
||||
|
||||
@@ -124,7 +124,7 @@ we have introduced the following concepts:
|
||||
the DAY, MONTH and YEAR values from an INTEHEAD keyword instance
|
||||
and convert to a time_t instance. The functions:
|
||||
|
||||
ecl_file_get_unrstmap_sim_time() and ecl_file_has_has_sim_time()
|
||||
ecl_file_get_unrstmap_sim_time() and ecl_file_has_has_sim_time()
|
||||
|
||||
can be used to query for simulation times and get the
|
||||
corresponding block maps.
|
||||
@@ -160,8 +160,8 @@ static time_t file_map_iget_restart_sim_date(const file_map_type * file_map , in
|
||||
ecl_kw_type * intehead_kw = file_map_iget_named_kw( seqnum_map , INTEHEAD_KW , 0);
|
||||
sim_time = ecl_rsthead_date( intehead_kw );
|
||||
file_map_free( seqnum_map );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return sim_time;
|
||||
}
|
||||
|
||||
@@ -174,8 +174,8 @@ static double file_map_iget_restart_sim_days(const file_map_type * file_map , in
|
||||
ecl_kw_type * doubhead_kw = file_map_iget_named_kw( seqnum_map , DOUBHEAD_KW , 0);
|
||||
sim_days = ecl_kw_iget_double( doubhead_kw , DOUBHEAD_DAYS_INDEX);
|
||||
file_map_free( seqnum_map );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return sim_days;
|
||||
}
|
||||
|
||||
@@ -232,13 +232,13 @@ static int file_map_find_sim_time(const file_map_type * file_map , time_t sim_ti
|
||||
If the sim_time can not be found the function will return -1, that
|
||||
includes the case when the file in question is not a restart file
|
||||
at all, and no INTEHEAD headers can be found.
|
||||
|
||||
|
||||
Observe that the function requires on-the-second-equality; which is
|
||||
of course quite strict.
|
||||
|
||||
Each report step only has one occurence of SEQNUM, but one INTEHEAD
|
||||
for each LGR; i.e. one should call iselect_rstblock() prior to
|
||||
calling this function.
|
||||
calling this function.
|
||||
*/
|
||||
|
||||
|
||||
@@ -255,13 +255,13 @@ static bool file_map_has_sim_time( const file_map_type * file_map , time_t sim_t
|
||||
int intehead_index = 0;
|
||||
while (true) {
|
||||
time_t itime = file_map_iget_restart_sim_date( file_map , intehead_index );
|
||||
|
||||
|
||||
if (itime == sim_time) /* Perfect hit. */
|
||||
return true;
|
||||
|
||||
|
||||
if (itime > sim_time) /* We have gone past the target_time - i.e. we do not have it. */
|
||||
return false;
|
||||
|
||||
|
||||
intehead_index++;
|
||||
if (intehead_index == num_INTEHEAD) /* We have iterated through the whole thing without finding sim_time. */
|
||||
return false;
|
||||
@@ -274,7 +274,7 @@ static int file_map_seqnum_index_from_sim_time( file_map_type * parent_map , tim
|
||||
int num_seqnum = file_map_get_num_named_kw( parent_map , SEQNUM_KW );
|
||||
int seqnum_index = 0;
|
||||
file_map_type * seqnum_map;
|
||||
|
||||
|
||||
while (true) {
|
||||
seqnum_map = file_map_alloc_blockmap( parent_map , SEQNUM_KW , seqnum_index);
|
||||
|
||||
@@ -287,7 +287,7 @@ static int file_map_seqnum_index_from_sim_time( file_map_type * parent_map , tim
|
||||
seqnum_index++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (num_seqnum == seqnum_index)
|
||||
return -1;
|
||||
}
|
||||
@@ -315,17 +315,17 @@ bool ecl_file_has_sim_time( const ecl_file_type * ecl_file , time_t sim_time) {
|
||||
This function will determine the restart block corresponding to the
|
||||
world time @sim_time; if @sim_time can not be found the function
|
||||
will return 0.
|
||||
|
||||
|
||||
The returned index is the 'occurence number' in the restart file,
|
||||
i.e. in the (quite typical case) that not all report steps are
|
||||
present the return value will not agree with report step.
|
||||
present the return value will not agree with report step.
|
||||
|
||||
The return value from this function can then be used to get a
|
||||
corresponding solution field directly, or the file map can
|
||||
restricted to this block.
|
||||
|
||||
Direct access:
|
||||
|
||||
|
||||
int index = ecl_file_get_restart_index( ecl_file , sim_time );
|
||||
if (index >= 0) {
|
||||
ecl_kw_type * pressure_kw = ecl_file_iget_named_kw( ecl_file , "PRESSURE" , index );
|
||||
@@ -333,7 +333,7 @@ bool ecl_file_has_sim_time( const ecl_file_type * ecl_file , time_t sim_time) {
|
||||
}
|
||||
|
||||
|
||||
Using block restriction:
|
||||
Using block restriction:
|
||||
|
||||
int index = ecl_file_get_restart_index( ecl_file , sim_time );
|
||||
if (index >= 0) {
|
||||
@@ -341,10 +341,10 @@ bool ecl_file_has_sim_time( const ecl_file_type * ecl_file , time_t sim_time) {
|
||||
{
|
||||
ecl_kw_type * pressure_kw = ecl_file_iget_named_kw( ecl_file , "PRESSURE" , 0 );
|
||||
....
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Specially in the case of LGRs the block restriction should be used.
|
||||
|
||||
Specially in the case of LGRs the block restriction should be used.
|
||||
*/
|
||||
|
||||
int ecl_file_get_restart_index( const ecl_file_type * ecl_file , time_t sim_time) {
|
||||
@@ -381,14 +381,14 @@ double ecl_file_iget_restart_sim_days( const ecl_file_type * restart_file , int
|
||||
|
||||
|
||||
/*****************************************************************/
|
||||
/* Select and open functions, observe that these functions should
|
||||
/* Select and open functions, observe that these functions should
|
||||
only consider the global map.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Will select restart block nr @seqnum_index - without considering
|
||||
report_steps or simulation time.
|
||||
report_steps or simulation time.
|
||||
*/
|
||||
bool ecl_file_iselect_rstblock( ecl_file_type * ecl_file , int seqnum_index ) {
|
||||
return ecl_file_select_block( ecl_file , SEQNUM_KW , seqnum_index );
|
||||
@@ -397,10 +397,10 @@ bool ecl_file_iselect_rstblock( ecl_file_type * ecl_file , int seqnum_index ) {
|
||||
|
||||
bool ecl_file_select_rstblock_sim_time( ecl_file_type * ecl_file , time_t sim_time) {
|
||||
int seqnum_index = file_map_seqnum_index_from_sim_time( ecl_file->global_map , sim_time );
|
||||
|
||||
|
||||
if (seqnum_index >= 0)
|
||||
return ecl_file_iselect_rstblock( ecl_file , seqnum_index);
|
||||
else
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -410,17 +410,19 @@ bool ecl_file_select_rstblock_report_step( ecl_file_type * ecl_file , int report
|
||||
if ( global_index >= 0) {
|
||||
int seqnum_index = file_map_iget_occurence( ecl_file->global_map , global_index );
|
||||
return ecl_file_iselect_rstblock( ecl_file , seqnum_index);
|
||||
} else
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
static ecl_file_type * ecl_file_open_rstblock_report_step__( const char * filename , int report_step , int flags) {
|
||||
ecl_file_type * ecl_file = ecl_file_open__( filename , flags );
|
||||
if (!ecl_file_select_rstblock_report_step( ecl_file , report_step )) {
|
||||
ecl_file_close( ecl_file );
|
||||
ecl_file = NULL;
|
||||
ecl_file_type * ecl_file = ecl_file_open( filename , flags );
|
||||
if (ecl_file) {
|
||||
if (!ecl_file_select_rstblock_report_step( ecl_file , report_step )) {
|
||||
ecl_file_close( ecl_file );
|
||||
ecl_file = NULL;
|
||||
}
|
||||
}
|
||||
return ecl_file;
|
||||
}
|
||||
@@ -433,10 +435,12 @@ ecl_file_type * ecl_file_open_rstblock_report_step( const char * filename , int
|
||||
/******************************************************************/
|
||||
|
||||
static ecl_file_type * ecl_file_open_rstblock_sim_time__( const char * filename , time_t sim_time, int flags ) {
|
||||
ecl_file_type * ecl_file = ecl_file_open__( filename , flags );
|
||||
if (!ecl_file_select_rstblock_sim_time( ecl_file , sim_time)) {
|
||||
ecl_file_close( ecl_file );
|
||||
ecl_file = NULL;
|
||||
ecl_file_type * ecl_file = ecl_file_open( filename , flags );
|
||||
if (ecl_file) {
|
||||
if (!ecl_file_select_rstblock_sim_time( ecl_file , sim_time)) {
|
||||
ecl_file_close( ecl_file );
|
||||
ecl_file = NULL;
|
||||
}
|
||||
}
|
||||
return ecl_file;
|
||||
}
|
||||
@@ -448,10 +452,12 @@ ecl_file_type * ecl_file_open_rstblock_sim_time( const char * filename , time_t
|
||||
/******************************************************************/
|
||||
|
||||
static ecl_file_type * ecl_file_iopen_rstblock__( const char * filename , int seqnum_index, int flags ) {
|
||||
ecl_file_type * ecl_file = ecl_file_open__( filename , flags );
|
||||
if (!ecl_file_iselect_rstblock( ecl_file , seqnum_index )) {
|
||||
ecl_file_close( ecl_file );
|
||||
ecl_file = NULL;
|
||||
ecl_file_type * ecl_file = ecl_file_open( filename , flags );
|
||||
if (ecl_file) {
|
||||
if (!ecl_file_iselect_rstblock( ecl_file , seqnum_index )) {
|
||||
ecl_file_close( ecl_file );
|
||||
ecl_file = NULL;
|
||||
}
|
||||
}
|
||||
return ecl_file;
|
||||
}
|
||||
|
||||
+40
@@ -37,6 +37,10 @@ time_t ecl_rsthead_date( const ecl_kw_type * intehead_kw ) {
|
||||
}
|
||||
|
||||
|
||||
double ecl_rsthead_get_sim_days( const ecl_rsthead_type * header ) {
|
||||
return header->sim_days;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ecl_rsthead_type * ecl_rsthead_ialloc( const ecl_file_type * rst_file , int occurence) {
|
||||
@@ -91,6 +95,42 @@ ecl_rsthead_type * ecl_rsthead_alloc( const ecl_file_type * rst_file) {
|
||||
}
|
||||
|
||||
|
||||
ecl_rsthead_type * ecl_rsthead_alloc_empty() {
|
||||
ecl_rsthead_type * rsthead = util_malloc( sizeof * rsthead );
|
||||
|
||||
rsthead->day = 0;
|
||||
rsthead->month = 0;
|
||||
rsthead->year = 0;
|
||||
rsthead->version = 0;
|
||||
rsthead->phase_sum = 0;
|
||||
|
||||
rsthead->nx = 0;
|
||||
rsthead->ny = 0;
|
||||
rsthead->nz = 0;
|
||||
rsthead->nactive = 0;
|
||||
|
||||
rsthead->nwells = 0;
|
||||
rsthead->niwelz = 0;
|
||||
rsthead->nzwelz = 0;
|
||||
|
||||
rsthead->nsconz = 0;
|
||||
rsthead->niconz = 0;
|
||||
rsthead->ncwmax = 0;
|
||||
|
||||
rsthead->nisegz = 0;
|
||||
rsthead->nsegmx = 0;
|
||||
rsthead->nswlmx = 0;
|
||||
rsthead->nrsegz = 0;
|
||||
|
||||
rsthead->sim_time = 0;
|
||||
|
||||
rsthead->dualp = false;
|
||||
rsthead->sim_days = 0.0;
|
||||
|
||||
return rsthead;
|
||||
}
|
||||
|
||||
|
||||
void ecl_rsthead_fprintf( const ecl_rsthead_type * header , FILE * stream) {
|
||||
fprintf(stream , "nx %d \n",header->nx);
|
||||
fprintf(stream , "nwells %d \n",header->nwells);
|
||||
|
||||
+21
-19
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_rstfile.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_rstfile.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
/*****************************************************************/
|
||||
@@ -27,10 +27,12 @@ bool ecl_file_select_smryblock( ecl_file_type * ecl_file , int report_step ) {
|
||||
|
||||
|
||||
ecl_file_type * ecl_file_open_smryblock( const char * filename , int report_step , int flags) {
|
||||
ecl_file_type * ecl_file = ecl_file_open__( filename , flags );
|
||||
if (!ecl_file_select_smryblock( ecl_file , report_step )) {
|
||||
ecl_file_close( ecl_file );
|
||||
ecl_file = NULL;
|
||||
ecl_file_type * ecl_file = ecl_file_open( filename , flags );
|
||||
if (ecl_file) {
|
||||
if (!ecl_file_select_smryblock( ecl_file , report_step )) {
|
||||
ecl_file_close( ecl_file );
|
||||
ecl_file = NULL;
|
||||
}
|
||||
}
|
||||
return ecl_file;
|
||||
}
|
||||
|
||||
+199
-161
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_smspec.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_smspec.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@@ -42,9 +42,9 @@
|
||||
|
||||
|
||||
/**
|
||||
This file implements the indexing into the ECLIPSE summary files.
|
||||
This file implements the indexing into the ECLIPSE summary files.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Supporting a new variable type:
|
||||
-------------------------------
|
||||
@@ -68,7 +68,7 @@
|
||||
specfic lookup method has seen less use[*]. The final step in
|
||||
supporting a new variable is to update the function
|
||||
ecl_smspec_fread_header().
|
||||
|
||||
|
||||
If you want to support specific lookup of the new variable type you
|
||||
must add the necessary datastructures to the ecl_smspec_struct
|
||||
structure and then subsequently fill that structure in the big
|
||||
@@ -88,7 +88,7 @@
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#define ECL_SMSPEC_ID 806647
|
||||
#define PARAMS_GLOBAL_DEFAULT -99
|
||||
@@ -105,10 +105,10 @@ struct ecl_smspec_struct {
|
||||
hash_type * well_var_index; /* Indexes for all well variables: {well1: {var1: index1 , var2: index2} , well2: {var1: index1 , var2: index2}} */
|
||||
hash_type * well_completion_var_index; /* Indexes for completion indexes .*/
|
||||
hash_type * group_var_index; /* Indexes for group variables.*/
|
||||
hash_type * field_var_index;
|
||||
hash_type * field_var_index;
|
||||
hash_type * region_var_index; /* The stored index is an offset. */
|
||||
hash_type * misc_var_index; /* Variables like 'TCPU' and 'NEWTON'. */
|
||||
hash_type * block_var_index; /* Block variables like BPR */
|
||||
hash_type * block_var_index; /* Block variables like BPR */
|
||||
hash_type * gen_var_index; /* This is "everything" - things can either be found as gen_var("WWCT:OP_X") or as well_var("WWCT" , "OP_X") */
|
||||
|
||||
|
||||
@@ -120,11 +120,11 @@ struct ecl_smspec_struct {
|
||||
|
||||
/*-----------------------------------------------------------------*/
|
||||
|
||||
int grid_dims[3]; /* Grid dimensions - in DIMENS[1,2,3] */
|
||||
int grid_dims[3]; /* Grid dimensions - in DIMENS[1,2,3] */
|
||||
int num_regions;
|
||||
int Nwells , param_offset;
|
||||
int params_size;
|
||||
const char * key_join_string; /* The string used to join keys when building gen_key keys - typically ":" -
|
||||
const char * key_join_string; /* The string used to join keys when building gen_key keys - typically ":" -
|
||||
but arbitrary - NOT necessary to be able to invert the joining. */
|
||||
char * header_file; /* FULL path to the currenbtly loaded header_file. */
|
||||
|
||||
@@ -132,13 +132,13 @@ struct ecl_smspec_struct {
|
||||
time_t sim_start_time; /* When did the simulation start - worldtime. */
|
||||
|
||||
int time_index; /* The fields time_index, day_index, month_index and year_index */
|
||||
int day_index; /* are used by the ecl_sum_data object to locate per. timestep */
|
||||
int month_index; /* time information. */
|
||||
int day_index; /* are used by the ecl_sum_data object to locate per. timestep */
|
||||
int month_index; /* time information. */
|
||||
int year_index;
|
||||
bool has_lgr;
|
||||
float_vector_type * params_default;
|
||||
|
||||
stringlist_type * restart_list; /* List of ECLBASE names of restart files this case has been restarted from (if any). */
|
||||
|
||||
stringlist_type * restart_list; /* List of ECLBASE names of restart files this case has been restarted from (if any). */
|
||||
};
|
||||
|
||||
|
||||
@@ -186,13 +186,13 @@ general_var:
|
||||
VAR_TYPE:(WELL_NAME|GROUP_NAME|NUMBER):NUMBER
|
||||
|
||||
Field var: VAR_TYPE
|
||||
Misc var: VAR_TYPE
|
||||
Misc var: VAR_TYPE
|
||||
Well var: VAR_TYPE:WELL_NAME
|
||||
Group var: VAR_TYPE:GROUP_NAME
|
||||
Block var: VAR_TYPE:i,j,k (where i,j,k is calculated form NUM)
|
||||
Region var VAR_TYPE:index (where index is NOT from the nums vector, it it is just an offset).
|
||||
Completion var: VAR_TYPE:WELL_NAME:NUM
|
||||
....
|
||||
....
|
||||
|
||||
*/
|
||||
|
||||
@@ -202,7 +202,7 @@ Completion var: VAR_TYPE:WELL_NAME:NUM
|
||||
types, when the kewyord name is in conflict with the default vector
|
||||
naming convention; all the variables mentioned in the list below
|
||||
are given the type ECL_SMSPEC_MISC_VAR.
|
||||
|
||||
|
||||
For instance the keyword 'NEWTON' starts with 'N' and is
|
||||
classified as a NETWORK type variable. However it should rather
|
||||
be classified as a MISC type variable. (What a fucking mess).
|
||||
@@ -221,6 +221,21 @@ static const char* special_vars[] = {"NEWTON",
|
||||
"STEPTYPE"};
|
||||
|
||||
|
||||
/*
|
||||
The smspec_required_keywords variable contains a list of keywords
|
||||
which are *absolutely* required in the SMSPEC file, but observe that
|
||||
depending on the content of the "KEYWORDS" array other keywords
|
||||
might bre requred as well - this typically includes the NUMS
|
||||
keyword. Such 'second-order' dependencies are not accounted for with
|
||||
this simple list.
|
||||
*/
|
||||
|
||||
static const char* smspec_required_keywords[] = {WGNAMES_KW,
|
||||
KEYWORDS_KW,
|
||||
STARTDAT_KW,
|
||||
UNITS_KW,
|
||||
DIMENS_KW};
|
||||
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
@@ -240,15 +255,15 @@ static ecl_smspec_type * ecl_smspec_alloc_empty(bool write_mode , const char * k
|
||||
ecl_smspec->sim_start_time = -1;
|
||||
ecl_smspec->key_join_string = key_join_string;
|
||||
ecl_smspec->header_file = NULL;
|
||||
|
||||
|
||||
ecl_smspec->smspec_nodes = vector_alloc_new();
|
||||
|
||||
|
||||
ecl_smspec->time_index = -1;
|
||||
ecl_smspec->day_index = -1;
|
||||
ecl_smspec->year_index = -1;
|
||||
ecl_smspec->month_index = -1;
|
||||
ecl_smspec->locked = false;
|
||||
|
||||
|
||||
ecl_smspec->index_map = int_vector_alloc(0,0);
|
||||
ecl_smspec->restart_list = stringlist_alloc_new();
|
||||
ecl_smspec->params_default = float_vector_alloc(0 , PARAMS_GLOBAL_DEFAULT);
|
||||
@@ -306,7 +321,7 @@ static void ecl_smspec_fortio_fwrite( const ecl_smspec_type * smspec , fortio_ty
|
||||
int i;
|
||||
for (i=0; i < SUMMARY_RESTART_SIZE; i++)
|
||||
ecl_kw_iset_string8( restart_kw , i , "");
|
||||
|
||||
|
||||
ecl_kw_fwrite( restart_kw , fortio );
|
||||
ecl_kw_free( restart_kw );
|
||||
}
|
||||
@@ -331,7 +346,7 @@ static void ecl_smspec_fortio_fwrite( const ecl_smspec_type * smspec , fortio_ty
|
||||
ecl_kw_type * wgnames_kw = ecl_kw_alloc( WGNAMES_KW , num_nodes , ECL_CHAR_TYPE );
|
||||
ecl_kw_type * units_kw = ecl_kw_alloc( UNITS_KW , num_nodes , ECL_CHAR_TYPE );
|
||||
ecl_kw_type * nums_kw = NULL;
|
||||
|
||||
|
||||
if (smspec->need_nums)
|
||||
nums_kw = ecl_kw_alloc( NUMS_KW , num_nodes , ECL_INT_TYPE);
|
||||
{
|
||||
@@ -383,8 +398,8 @@ static void ecl_smspec_fortio_fwrite( const ecl_smspec_type * smspec , fortio_ty
|
||||
if (nums_kw != NULL)
|
||||
ecl_kw_fwrite( nums_kw , fortio );
|
||||
ecl_kw_fwrite( units_kw , fortio );
|
||||
|
||||
|
||||
|
||||
|
||||
ecl_kw_free( keywords_kw );
|
||||
ecl_kw_free( wgnames_kw );
|
||||
ecl_kw_free( units_kw );
|
||||
@@ -396,11 +411,11 @@ static void ecl_smspec_fortio_fwrite( const ecl_smspec_type * smspec , fortio_ty
|
||||
ecl_kw_type * startdat_kw = ecl_kw_alloc( STARTDAT_KW , STARTDAT_SIZE , ECL_INT_TYPE );
|
||||
int day,month,year;
|
||||
util_set_date_values( smspec->sim_start_time , &day, &month , &year);
|
||||
|
||||
|
||||
ecl_kw_iset_int( startdat_kw , STARTDAT_DAY_INDEX , day );
|
||||
ecl_kw_iset_int( startdat_kw , STARTDAT_MONTH_INDEX , month );
|
||||
ecl_kw_iset_int( startdat_kw , STARTDAT_YEAR_INDEX , year );
|
||||
|
||||
|
||||
ecl_kw_fwrite( startdat_kw , fortio );
|
||||
ecl_kw_free( startdat_kw );
|
||||
}
|
||||
@@ -410,30 +425,30 @@ static void ecl_smspec_fortio_fwrite( const ecl_smspec_type * smspec , fortio_ty
|
||||
void ecl_smspec_fwrite( const ecl_smspec_type * smspec , const char * ecl_case , bool fmt_file ) {
|
||||
char * filename = ecl_util_alloc_filename( NULL , ecl_case , ECL_SUMMARY_HEADER_FILE , fmt_file , 0 );
|
||||
fortio_type * fortio = fortio_open_writer( filename , fmt_file , ECL_ENDIAN_FLIP);
|
||||
|
||||
|
||||
ecl_smspec_fortio_fwrite( smspec , fortio );
|
||||
|
||||
|
||||
fortio_fclose( fortio );
|
||||
free( filename );
|
||||
}
|
||||
|
||||
ecl_smspec_type * ecl_smspec_alloc_writer( const char * key_join_string , time_t sim_start , int nx , int ny , int nz) {
|
||||
ecl_smspec_type * ecl_smspec = ecl_smspec_alloc_empty( true , key_join_string );
|
||||
|
||||
|
||||
ecl_smspec->grid_dims[0] = nx;
|
||||
ecl_smspec->grid_dims[1] = ny;
|
||||
ecl_smspec->grid_dims[2] = nz;
|
||||
ecl_smspec->sim_start_time = sim_start;
|
||||
|
||||
|
||||
{
|
||||
smspec_node_type * time_node = smspec_node_alloc( ECL_SMSPEC_MISC_VAR ,
|
||||
NULL ,
|
||||
"TIME" ,
|
||||
smspec_node_type * time_node = smspec_node_alloc( ECL_SMSPEC_MISC_VAR ,
|
||||
NULL ,
|
||||
"TIME" ,
|
||||
"DAYS" , // There are significant hardcoded assumptions of days around; would have been cool to be able to set seconds.
|
||||
key_join_string ,
|
||||
ecl_smspec->grid_dims ,
|
||||
0 ,
|
||||
-1 ,
|
||||
key_join_string ,
|
||||
ecl_smspec->grid_dims ,
|
||||
0 ,
|
||||
-1 ,
|
||||
0 );
|
||||
ecl_smspec_add_node( ecl_smspec , time_node );
|
||||
ecl_smspec->time_index = smspec_node_get_params_index( time_node );
|
||||
@@ -468,12 +483,12 @@ static ecl_smspec_var_type ecl_smspec_identify_special_var( const char * var ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return var_type;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
See table 3.4 in the ECLIPSE file format reference manual.
|
||||
|
||||
Observe that the combined ecl_sum style keys like e.g. WWCT:OP1
|
||||
@@ -485,7 +500,7 @@ static ecl_smspec_var_type ecl_smspec_identify_special_var( const char * var ) {
|
||||
|
||||
ecl_smspec_var_type ecl_smspec_identify_var_type(const char * var) {
|
||||
ecl_smspec_var_type var_type = ecl_smspec_identify_special_var( var );
|
||||
int str_length = strlen(var);
|
||||
int str_length = strlen(var);
|
||||
if (var_type == ECL_SMSPEC_INVALID_VAR) {
|
||||
switch(var[0]) {
|
||||
case('A'):
|
||||
@@ -529,7 +544,7 @@ ecl_smspec_var_type ecl_smspec_identify_var_type(const char * var) {
|
||||
var_type = ECL_SMSPEC_NETWORK_VAR;
|
||||
break;
|
||||
case('R'):
|
||||
if (((3 == str_length) && var[2] == 'F') ||
|
||||
if (((3 == str_length) && var[2] == 'F') ||
|
||||
((4 == str_length) && var[3] == 'F')) {
|
||||
var_type = ECL_SMSPEC_REGION_2_REGION_VAR;
|
||||
}
|
||||
@@ -559,7 +574,7 @@ static bool ecl_smspec_lgr_var_type( ecl_smspec_var_type var_type) {
|
||||
if ((var_type == ECL_SMSPEC_LOCAL_BLOCK_VAR) ||
|
||||
(var_type == ECL_SMSPEC_LOCAL_WELL_VAR) ||
|
||||
(var_type == ECL_SMSPEC_LOCAL_COMPLETION_VAR))
|
||||
|
||||
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
@@ -646,10 +661,10 @@ static int ecl_smspec_get_global_grid_index(const ecl_smspec_type * smspec , int
|
||||
/**
|
||||
This function takes a fully initialized smspec_node instance, generates the
|
||||
corresponding key and inserts smspec_node instance in the main hash table
|
||||
smspec->gen_var_index.
|
||||
smspec->gen_var_index.
|
||||
|
||||
The format strings used, i.e. VAR:WELL for well based variables is implicitly
|
||||
defined through the format strings used in this function.
|
||||
defined through the format strings used in this function.
|
||||
*/
|
||||
|
||||
static void ecl_smspec_install_gen_keys( ecl_smspec_type * smspec , smspec_node_type * smspec_node ) {
|
||||
@@ -663,17 +678,17 @@ static void ecl_smspec_install_gen_keys( ecl_smspec_type * smspec , smspec_node_
|
||||
/* Insert the (optional) extra mapping for block related variables and region_2_region variables: */
|
||||
{
|
||||
const char * gen_key2 = smspec_node_get_gen_key2( smspec_node );
|
||||
if (gen_key2 != NULL)
|
||||
if (gen_key2 != NULL)
|
||||
hash_insert_ref(smspec->gen_var_index , gen_key2 , smspec_node);
|
||||
}
|
||||
}
|
||||
|
||||
static void ecl_smspec_install_special_keys( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node) {
|
||||
/**
|
||||
/**
|
||||
This large switch is for installing keys which have custom lookup
|
||||
paths, in addition to the lookup based on general keys. Examples
|
||||
of this is e.g. well variables which can be looked up through:
|
||||
|
||||
of this is e.g. well variables which can be looked up through:
|
||||
|
||||
ecl_smspec_get_well_var_index( smspec , well_name , var );
|
||||
*/
|
||||
|
||||
@@ -682,7 +697,7 @@ static void ecl_smspec_install_special_keys( ecl_smspec_type * ecl_smspec , smsp
|
||||
const int num = smspec_node_get_num(smspec_node);
|
||||
const char * keyword = smspec_node_get_keyword(smspec_node);
|
||||
ecl_smspec_var_type var_type = smspec_node_get_var_type( smspec_node );
|
||||
|
||||
|
||||
switch(var_type) {
|
||||
case(ECL_SMSPEC_COMPLETION_VAR):
|
||||
/* Three level indexing: variable -> well -> string(cell_nr)*/
|
||||
@@ -715,7 +730,7 @@ static void ecl_smspec_install_special_keys( ecl_smspec_type * ecl_smspec , smsp
|
||||
}
|
||||
break;
|
||||
case(ECL_SMSPEC_REGION_VAR):
|
||||
if (!hash_has_key(ecl_smspec->region_var_index , keyword))
|
||||
if (!hash_has_key(ecl_smspec->region_var_index , keyword))
|
||||
hash_insert_hash_owned_ref( ecl_smspec->region_var_index , keyword , hash_alloc() , hash_free__);
|
||||
{
|
||||
hash_type * var_hash = hash_get(ecl_smspec->region_var_index , keyword);
|
||||
@@ -748,7 +763,7 @@ static void ecl_smspec_install_special_keys( ecl_smspec_type * ecl_smspec , smsp
|
||||
hash_insert_ref(block_hash , block_nr , smspec_node);
|
||||
}
|
||||
break;
|
||||
/**
|
||||
/**
|
||||
The variables below are ONLY accesable through the gen_key
|
||||
setup; but the must be mentioned in this switch statement,
|
||||
otherwise they will induce a hard failure in the default: target
|
||||
@@ -769,7 +784,7 @@ static void ecl_smspec_install_special_keys( ecl_smspec_type * ecl_smspec , smsp
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
The usage of this functon breaks down completely if LGR's are involved.
|
||||
*/
|
||||
@@ -858,7 +873,7 @@ static bool ecl_smspec_kw_equal(const ecl_file_type * header , const ecl_file_ty
|
||||
if (ecl_file_has_kw( header , kw)) {
|
||||
ecl_kw_type *ecl_kw1 = ecl_file_iget_named_kw(header, kw , 0);
|
||||
ecl_kw_type *ecl_kw2 = ecl_file_iget_named_kw(restart_header, kw , 0);
|
||||
|
||||
|
||||
return ecl_kw_block_equal( ecl_kw1 , ecl_kw2 , cmp_elements);
|
||||
} else
|
||||
return true; // None of the headers have this keyword - that is equality!
|
||||
@@ -872,7 +887,7 @@ static bool ecl_smspec_kw_equal(const ecl_file_type * header , const ecl_file_ty
|
||||
historical results is not internalized, i.e. it is essential that
|
||||
the historical case has identical header as the main case. This
|
||||
function compares the ecl_file represeantation of two SMSPEC
|
||||
headers.
|
||||
headers.
|
||||
|
||||
Unfortunately there are legitimate reasons why some of the headers
|
||||
can be different; in particular new well can appear. In the code
|
||||
@@ -883,19 +898,19 @@ static bool ecl_smspec_kw_equal(const ecl_file_type * header , const ecl_file_ty
|
||||
static bool ecl_smspec_file_equal( const ecl_file_type * header1 , const ecl_file_type * header2) {
|
||||
if (! ecl_smspec_kw_equal( header1 , header2 , KEYWORDS_KW , 0))
|
||||
return false;
|
||||
|
||||
|
||||
if (! ecl_smspec_kw_equal( header1 , header2 , STARTDAT_KW , 0))
|
||||
return false;
|
||||
|
||||
if (! ecl_smspec_kw_equal( header1 , header2 , UNITS_KW , 0))
|
||||
return false;
|
||||
|
||||
|
||||
if (! ecl_smspec_kw_equal( header1 , header2 , DIMENS_KW , 4)) // Only the first four elements are compared.
|
||||
return false;
|
||||
|
||||
|
||||
if (!ecl_smspec_kw_equal( header1, header2 , LGRS_KW , 0))
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -903,7 +918,7 @@ static bool ecl_smspec_file_equal( const ecl_file_type * header1 , const ecl_fil
|
||||
/**
|
||||
This will iterate backwards through the RESTART header in the
|
||||
SMSPEC files to find names of the case(s) this case has been
|
||||
restarted from.
|
||||
restarted from.
|
||||
|
||||
The case names are internalized in the restart_list field of the
|
||||
ecl_smspec instance. The actual loading of the restart summary data
|
||||
@@ -917,9 +932,9 @@ static void ecl_smspec_load_restart( ecl_smspec_type * ecl_smspec , const ecl_fi
|
||||
char * restart_base;
|
||||
int i;
|
||||
tmp_base[0] = '\0';
|
||||
for (i=0; i < ecl_kw_get_size( restart_kw ); i++)
|
||||
for (i=0; i < ecl_kw_get_size( restart_kw ); i++)
|
||||
strcat( tmp_base , ecl_kw_iget_ptr( restart_kw , i ));
|
||||
|
||||
|
||||
restart_base = util_alloc_strip_copy( tmp_base );
|
||||
if (strlen(restart_base)) { /* We ignore the empty ones. */
|
||||
char * path;
|
||||
@@ -927,27 +942,29 @@ static void ecl_smspec_load_restart( ecl_smspec_type * ecl_smspec , const ecl_fi
|
||||
|
||||
util_alloc_file_components( ecl_smspec->header_file , &path , NULL , NULL );
|
||||
smspec_header = ecl_util_alloc_exfilename( path , restart_base , ECL_SUMMARY_HEADER_FILE , ecl_smspec->formatted , 0);
|
||||
if (smspec_header == NULL)
|
||||
if (smspec_header == NULL)
|
||||
fprintf(stderr,"Warning - the header file: %s refers to restart from case: %s - which was not found.... \n", ecl_smspec->header_file , restart_base);
|
||||
|
||||
|
||||
else {
|
||||
if (!util_same_file(smspec_header , ecl_smspec->header_file)) { /* Restart from the current case is ignored. */
|
||||
/*
|
||||
/*
|
||||
Verify that this smspec_header is not already in the list of restart
|
||||
cases. Don't know if this is at all possible, but this test
|
||||
nevertheless prevents against a recursive death.
|
||||
*/
|
||||
if (!stringlist_contains( ecl_smspec->restart_list , restart_base)) {
|
||||
ecl_file_type * restart_header = ecl_file_open( smspec_header , 0);
|
||||
|
||||
if (ecl_smspec_file_equal( header , restart_header)) {
|
||||
stringlist_insert_copy( ecl_smspec->restart_list , 0 , restart_base );
|
||||
ecl_smspec_load_restart( ecl_smspec , restart_header); /* Recursive call */
|
||||
} else
|
||||
fprintf(stderr,"** Warning: the historical case: %s is not compatible with the current case - ignored.\n" ,
|
||||
ecl_file_get_src_file( restart_header));
|
||||
|
||||
ecl_file_close( restart_header );
|
||||
if (restart_header) {
|
||||
if (ecl_smspec_file_equal( header , restart_header)) {
|
||||
stringlist_insert_copy( ecl_smspec->restart_list , 0 , restart_base );
|
||||
ecl_smspec_load_restart( ecl_smspec , restart_header); /* Recursive call */
|
||||
} else
|
||||
fprintf(stderr,"** Warning: the historical case: %s is not compatible with the current case - ignored.\n" ,
|
||||
ecl_file_get_src_file( restart_header));
|
||||
|
||||
ecl_file_close( restart_header );
|
||||
} else
|
||||
fprintf(stderr,"** Warning: failed to historical case:%s - ignored.\n", smspec_header);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -958,13 +975,13 @@ static void ecl_smspec_load_restart( ecl_smspec_type * ecl_smspec , const ecl_fi
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ecl_smspec_index_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node) {
|
||||
/*
|
||||
It is possible crate a node which is not fully specified, e.g. the
|
||||
well or group name can be left at NULL. In that case the node is
|
||||
not installed in the different indexes.
|
||||
not installed in the different indexes.
|
||||
*/
|
||||
// var_type == ECL_SMSPEC_INVALID_VAR??
|
||||
if (smspec_node_get_gen_key1( smspec_node ) != NULL) {
|
||||
@@ -983,27 +1000,27 @@ static void ecl_smspec_set_params_size( ecl_smspec_type * ecl_smspec , int param
|
||||
|
||||
|
||||
|
||||
void ecl_smspec_insert_node(ecl_smspec_type * ecl_smspec, smspec_node_type * smspec_node){
|
||||
void ecl_smspec_insert_node(ecl_smspec_type * ecl_smspec, smspec_node_type * smspec_node){
|
||||
if (!ecl_smspec->locked) {
|
||||
int internal_index = vector_get_size( ecl_smspec->smspec_nodes );
|
||||
|
||||
|
||||
/* This IF test should only apply in write_mode. */
|
||||
if (smspec_node_get_params_index( smspec_node ) < 0) {
|
||||
if (!ecl_smspec->write_mode)
|
||||
util_abort("%s: internal error \n",__func__);
|
||||
smspec_node_set_params_index( smspec_node , internal_index);
|
||||
|
||||
|
||||
if (internal_index >= ecl_smspec->params_size)
|
||||
ecl_smspec_set_params_size( ecl_smspec , internal_index + 1);
|
||||
}
|
||||
vector_append_owned_ref( ecl_smspec->smspec_nodes , smspec_node , smspec_node_free__ );
|
||||
|
||||
|
||||
{
|
||||
int params_index = smspec_node_get_params_index( smspec_node );
|
||||
|
||||
|
||||
/* This indexing must be used when writing. */
|
||||
int_vector_iset( ecl_smspec->index_map , internal_index , params_index);
|
||||
|
||||
|
||||
float_vector_iset( ecl_smspec->params_default , params_index , smspec_node_get_default(smspec_node) );
|
||||
}
|
||||
} else
|
||||
@@ -1030,12 +1047,25 @@ const int_vector_type * ecl_smspec_get_index_map( const ecl_smspec_type * smspec
|
||||
return smspec->index_map;
|
||||
}
|
||||
|
||||
static bool ecl_smspec_check_header( ecl_file_type * header ) {
|
||||
bool OK = true;
|
||||
int num_required = sizeof( smspec_required_keywords ) / sizeof( smspec_required_keywords[0] );
|
||||
int i;
|
||||
|
||||
for (i=0; i < num_required; i++) {
|
||||
if (!ecl_file_has_kw( header , smspec_required_keywords[i])) {
|
||||
OK = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void ecl_smspec_fread_header(ecl_smspec_type * ecl_smspec, const char * header_file , bool include_restart) {
|
||||
static bool ecl_smspec_fread_header(ecl_smspec_type * ecl_smspec, const char * header_file , bool include_restart) {
|
||||
ecl_file_type * header = ecl_file_open( header_file , 0);
|
||||
{
|
||||
if (header && ecl_smspec_check_header( header )) {
|
||||
ecl_kw_type *wells = ecl_file_iget_named_kw(header, WGNAMES_KW , 0);
|
||||
ecl_kw_type *keywords = ecl_file_iget_named_kw(header, KEYWORDS_KW , 0);
|
||||
ecl_kw_type *startdat = ecl_file_iget_named_kw(header, STARTDAT_KW , 0);
|
||||
@@ -1048,17 +1078,17 @@ static void ecl_smspec_fread_header(ecl_smspec_type * ecl_smspec, const char * h
|
||||
ecl_kw_type *numlz = NULL;
|
||||
int params_index;
|
||||
ecl_smspec->num_regions = 0;
|
||||
if (startdat == NULL)
|
||||
if (startdat == NULL)
|
||||
util_abort("%s: could not locate STARTDAT keyword in header - aborting \n",__func__);
|
||||
|
||||
|
||||
if (ecl_file_has_kw(header , NUMS_KW))
|
||||
nums = ecl_file_iget_named_kw(header , NUMS_KW , 0);
|
||||
|
||||
|
||||
if (ecl_file_has_kw( header , LGRS_KW )) {/* The file has LGR information. */
|
||||
lgrs = ecl_file_iget_named_kw( header , LGRS_KW , 0 );
|
||||
numlx = ecl_file_iget_named_kw( header , NUMLX_KW , 0 );
|
||||
numly = ecl_file_iget_named_kw( header , NUMLY_KW , 0 );
|
||||
numlz = ecl_file_iget_named_kw( header , NUMLZ_KW , 0 );
|
||||
numlx = ecl_file_iget_named_kw( header , NUMLX_KW , 0 );
|
||||
numly = ecl_file_iget_named_kw( header , NUMLY_KW , 0 );
|
||||
numlz = ecl_file_iget_named_kw( header , NUMLZ_KW , 0 );
|
||||
ecl_smspec->has_lgr = true;
|
||||
} else
|
||||
ecl_smspec->has_lgr = false;
|
||||
@@ -1069,14 +1099,14 @@ static void ecl_smspec_fread_header(ecl_smspec_type * ecl_smspec, const char * h
|
||||
date[STARTDAT_MONTH_INDEX] ,
|
||||
date[STARTDAT_YEAR_INDEX]);
|
||||
}
|
||||
|
||||
|
||||
ecl_smspec->grid_dims[0] = ecl_kw_iget_int(dimens , DIMENS_SMSPEC_NX_INDEX );
|
||||
ecl_smspec->grid_dims[1] = ecl_kw_iget_int(dimens , DIMENS_SMSPEC_NY_INDEX );
|
||||
ecl_smspec->grid_dims[2] = ecl_kw_iget_int(dimens , DIMENS_SMSPEC_NZ_INDEX );
|
||||
ecl_smspec_set_params_size( ecl_smspec , ecl_kw_get_size(keywords));
|
||||
|
||||
|
||||
ecl_util_get_file_type( header_file , &ecl_smspec->formatted , NULL );
|
||||
|
||||
|
||||
{
|
||||
for (params_index=0; params_index < ecl_kw_get_size(wells); params_index++) {
|
||||
float default_value = PARAMS_GLOBAL_DEFAULT;
|
||||
@@ -1084,75 +1114,83 @@ static void ecl_smspec_fread_header(ecl_smspec_type * ecl_smspec, const char * h
|
||||
char * well = util_alloc_strip_copy(ecl_kw_iget_ptr(wells , params_index));
|
||||
char * kw = util_alloc_strip_copy(ecl_kw_iget_ptr(keywords , params_index));
|
||||
char * unit = util_alloc_strip_copy(ecl_kw_iget_ptr(units , params_index));
|
||||
char * lgr_name = NULL;
|
||||
char * lgr_name = NULL;
|
||||
|
||||
smspec_node_type * smspec_node;
|
||||
ecl_smspec_var_type var_type = ecl_smspec_identify_var_type( kw );
|
||||
if (nums != NULL) num = ecl_kw_iget_int(nums , params_index);
|
||||
if (ecl_smspec_lgr_var_type( var_type )) {
|
||||
if (ecl_smspec_lgr_var_type( var_type )) {
|
||||
int lgr_i = ecl_kw_iget_int( numlx , params_index );
|
||||
int lgr_j = ecl_kw_iget_int( numly , params_index );
|
||||
int lgr_k = ecl_kw_iget_int( numlz , params_index );
|
||||
lgr_name = util_alloc_strip_copy( ecl_kw_iget_ptr( lgrs , params_index ));
|
||||
smspec_node = smspec_node_alloc_lgr( var_type , well , kw , unit , lgr_name , ecl_smspec->key_join_string , lgr_i , lgr_j , lgr_k , params_index, default_value);
|
||||
} else
|
||||
} else
|
||||
smspec_node = smspec_node_alloc( var_type , well , kw , unit , ecl_smspec->key_join_string , ecl_smspec->grid_dims , num , params_index , default_value);
|
||||
|
||||
|
||||
|
||||
if (smspec_node != NULL) {
|
||||
/** OK - we know this is valid shit. */
|
||||
ecl_smspec_add_node( ecl_smspec , smspec_node );
|
||||
}
|
||||
|
||||
|
||||
free( kw );
|
||||
free( well );
|
||||
free( unit );
|
||||
util_safe_free( lgr_name );
|
||||
}
|
||||
}
|
||||
}
|
||||
ecl_smspec->header_file = util_alloc_realpath( header_file );
|
||||
if (include_restart)
|
||||
ecl_smspec_load_restart( ecl_smspec , header );
|
||||
|
||||
ecl_file_close( header );
|
||||
|
||||
ecl_smspec->header_file = util_alloc_realpath( header_file );
|
||||
if (include_restart)
|
||||
ecl_smspec_load_restart( ecl_smspec , header );
|
||||
|
||||
ecl_file_close( header );
|
||||
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ecl_smspec_type * ecl_smspec_fread_alloc(const char *header_file, const char * key_join_string , bool include_restart) {
|
||||
ecl_smspec_type *ecl_smspec;
|
||||
|
||||
|
||||
{
|
||||
char *path;
|
||||
util_alloc_file_components(header_file , &path , NULL , NULL);
|
||||
ecl_smspec = ecl_smspec_alloc_empty(false , key_join_string);
|
||||
util_safe_free(path);
|
||||
}
|
||||
|
||||
ecl_smspec_fread_header(ecl_smspec , header_file , include_restart);
|
||||
|
||||
if (hash_has_key( ecl_smspec->misc_var_index , "TIME"))
|
||||
ecl_smspec->time_index = smspec_node_get_params_index( hash_get(ecl_smspec->misc_var_index , "TIME") );
|
||||
|
||||
if (hash_has_key(ecl_smspec->misc_var_index , "DAY")) {
|
||||
ecl_smspec->day_index = smspec_node_get_params_index( hash_get(ecl_smspec->misc_var_index , "DAY") );
|
||||
ecl_smspec->month_index = smspec_node_get_params_index( hash_get(ecl_smspec->misc_var_index , "MONTH") );
|
||||
ecl_smspec->year_index = smspec_node_get_params_index( hash_get(ecl_smspec->misc_var_index , "YEAR") );
|
||||
}
|
||||
|
||||
if ((ecl_smspec->time_index == -1) && ( ecl_smspec->day_index == -1)) {
|
||||
/* Unusable configuration.
|
||||
|
||||
Seems the ECLIPSE file can also have time specified with
|
||||
'YEARS' as basic time unit; that mode is not supported.
|
||||
*/
|
||||
|
||||
util_abort("%s: Sorry the SMSPEC file seems to lack all time information, need either TIME, or DAY/MONTH/YEAR information. Can not proceed.",__func__);
|
||||
if (ecl_smspec_fread_header(ecl_smspec , header_file , include_restart)) {
|
||||
|
||||
if (hash_has_key( ecl_smspec->misc_var_index , "TIME"))
|
||||
ecl_smspec->time_index = smspec_node_get_params_index( hash_get(ecl_smspec->misc_var_index , "TIME") );
|
||||
|
||||
if (hash_has_key(ecl_smspec->misc_var_index , "DAY")) {
|
||||
ecl_smspec->day_index = smspec_node_get_params_index( hash_get(ecl_smspec->misc_var_index , "DAY") );
|
||||
ecl_smspec->month_index = smspec_node_get_params_index( hash_get(ecl_smspec->misc_var_index , "MONTH") );
|
||||
ecl_smspec->year_index = smspec_node_get_params_index( hash_get(ecl_smspec->misc_var_index , "YEAR") );
|
||||
}
|
||||
|
||||
if ((ecl_smspec->time_index == -1) && ( ecl_smspec->day_index == -1)) {
|
||||
/* Unusable configuration.
|
||||
|
||||
Seems the ECLIPSE file can also have time specified with
|
||||
'YEARS' as basic time unit; that mode is not supported.
|
||||
*/
|
||||
|
||||
util_abort("%s: Sorry the SMSPEC file seems to lack all time information, need either TIME, or DAY/MONTH/YEAR information. Can not proceed.",__func__);
|
||||
return NULL;
|
||||
}
|
||||
return ecl_smspec;
|
||||
} else {
|
||||
/** Failed to load from disk. */
|
||||
ecl_smspec_free( ecl_smspec );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ecl_smspec;
|
||||
}
|
||||
|
||||
|
||||
@@ -1172,7 +1210,7 @@ int ecl_smspec_get_num_regions(const ecl_smspec_type * ecl_smspec) {
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
/*
|
||||
/*
|
||||
For each type of summary data (according to the types in
|
||||
ecl_smcspec_var_type there are a set accessor functions:
|
||||
|
||||
@@ -1272,7 +1310,7 @@ const smspec_node_type * ecl_smspec_get_field_var_node(const ecl_smspec_type * e
|
||||
const smspec_node_type * node = NULL;
|
||||
if (hash_has_key(ecl_smspec->field_var_index , var))
|
||||
node = hash_get(ecl_smspec->field_var_index , var);
|
||||
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -1296,7 +1334,7 @@ bool ecl_smspec_has_field_var(const ecl_smspec_type * ecl_smspec , const char *v
|
||||
/**
|
||||
Observe that block_nr is represented as char literal,
|
||||
i.e. "2345". This is because it will be used as a hash key.
|
||||
|
||||
|
||||
This is the final low level function which actually consults the
|
||||
hash tables.
|
||||
*/
|
||||
@@ -1331,7 +1369,7 @@ const smspec_node_type * ecl_smspec_get_block_var_node_ijk(const ecl_smspec_type
|
||||
bool ecl_smspec_has_block_var(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr) {
|
||||
const smspec_node_type * node = ecl_smspec_get_block_var_node( ecl_smspec , block_var , block_nr );
|
||||
NODE_RETURN_EXISTS(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ecl_smspec_has_block_var_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k) {
|
||||
@@ -1343,7 +1381,7 @@ bool ecl_smspec_has_block_var_ijk(const ecl_smspec_type * ecl_smspec , const cha
|
||||
int ecl_smspec_get_block_var_params_index(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr) {
|
||||
const smspec_node_type * node = ecl_smspec_get_block_var_node( ecl_smspec , block_var , block_nr );
|
||||
NODE_RETURN_INDEX(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int ecl_smspec_get_block_var_params_index_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k) {
|
||||
@@ -1366,11 +1404,11 @@ const smspec_node_type * ecl_smspec_get_region_var_node(const ecl_smspec_type *
|
||||
if (hash_has_key(ecl_smspec->region_var_index , region_var)) {
|
||||
char * nr_str = util_alloc_sprintf( "%d" , region_nr );
|
||||
hash_type * nr_hash = hash_get(ecl_smspec->region_var_index , region_var);
|
||||
if (hash_has_key( nr_hash , nr_str))
|
||||
if (hash_has_key( nr_hash , nr_str))
|
||||
node = hash_get( nr_hash , nr_str );
|
||||
free( nr_str );
|
||||
}
|
||||
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -1394,7 +1432,7 @@ const smspec_node_type * ecl_smspec_get_misc_var_node(const ecl_smspec_type * ec
|
||||
|
||||
if (hash_has_key(ecl_smspec->misc_var_index , var))
|
||||
node = hash_get(ecl_smspec->misc_var_index , var);
|
||||
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -1420,7 +1458,7 @@ const smspec_node_type * ecl_smspec_get_well_completion_var_node(const ecl_smspe
|
||||
char * cell_str = util_alloc_sprintf("%d" , cell_nr);
|
||||
if (hash_has_key(ecl_smspec->well_completion_var_index , well)) {
|
||||
hash_type * cell_hash = hash_get(ecl_smspec->well_completion_var_index , well);
|
||||
|
||||
|
||||
if (hash_has_key(cell_hash , cell_str)) {
|
||||
hash_type * var_hash = hash_get(cell_hash , cell_str);
|
||||
if (hash_has_key(var_hash , var))
|
||||
@@ -1472,7 +1510,7 @@ int ecl_smspec_get_general_var_params_index(const ecl_smspec_type * ecl_smspec ,
|
||||
bool ecl_smspec_has_general_var(const ecl_smspec_type * ecl_smspec , const char * lookup_kw) {
|
||||
const smspec_node_type * node = ecl_smspec_get_general_var_node( ecl_smspec , lookup_kw );
|
||||
NODE_RETURN_EXISTS( node );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** DIES if the lookup_kw is not present. */
|
||||
@@ -1483,7 +1521,7 @@ const char * ecl_smspec_get_general_var_unit( const ecl_smspec_type * ecl_smspec
|
||||
|
||||
|
||||
/*****************************************************************/
|
||||
/*
|
||||
/*
|
||||
Pure indexed lookup - these functions can be used after one of the
|
||||
ecl_smspec_get_xxx_index() functions has been used first.
|
||||
*/
|
||||
@@ -1609,7 +1647,7 @@ bool ecl_smspec_general_is_total( const ecl_smspec_type * smspec , const char *
|
||||
unfortunately not as useful as one might think because ECLIPSE is
|
||||
quite stupid; it will for instance happily give you the WOPR for a
|
||||
water injector or WWIR for an oil producer.
|
||||
|
||||
|
||||
The function can be called several times with different patterns,
|
||||
the stringlist is not cleared on startup; the keys in the list are
|
||||
unique - keys are not added multiple times. If pattern == NULL all
|
||||
@@ -1620,7 +1658,7 @@ bool ecl_smspec_general_is_total( const ecl_smspec_type * smspec , const char *
|
||||
void ecl_smspec_select_matching_general_var_list( const ecl_smspec_type * smspec , const char * pattern , stringlist_type * keys) {
|
||||
hash_type * ex_keys = hash_alloc( );
|
||||
int i;
|
||||
for (i=0; i < stringlist_get_size( keys ); i++)
|
||||
for (i=0; i < stringlist_get_size( keys ); i++)
|
||||
hash_insert_int( ex_keys , stringlist_iget( keys , i ) , 1);
|
||||
|
||||
{
|
||||
@@ -1634,7 +1672,7 @@ void ecl_smspec_select_matching_general_var_list( const ecl_smspec_type * smspec
|
||||
}
|
||||
hash_iter_free( iter );
|
||||
}
|
||||
|
||||
|
||||
hash_free( ex_keys );
|
||||
}
|
||||
|
||||
@@ -1658,12 +1696,12 @@ const char * ecl_smspec_get_join_string( const ecl_smspec_type * smspec) {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
Returns a stringlist instance with all the (valid) well names. It
|
||||
is the responsability of the calling scope to free the stringlist
|
||||
with stringlist_free();
|
||||
|
||||
|
||||
|
||||
If @pattern is different from NULL only wells which 'match' the
|
||||
pattern is included; if @pattern == NULL all wells are
|
||||
included. The match is done with function fnmatch() -
|
||||
@@ -1674,12 +1712,12 @@ stringlist_type * ecl_smspec_alloc_well_list( const ecl_smspec_type * smspec , c
|
||||
stringlist_type * well_list = stringlist_alloc_new( );
|
||||
{
|
||||
hash_iter_type * iter = hash_iter_alloc( smspec->well_var_index );
|
||||
|
||||
|
||||
while (!hash_iter_is_complete( iter )) {
|
||||
const char * well_name = hash_iter_get_next_key( iter );
|
||||
if (pattern == NULL)
|
||||
stringlist_append_copy( well_list , well_name );
|
||||
else if (util_fnmatch( pattern , well_name) == 0)
|
||||
else if (util_fnmatch( pattern , well_name) == 0)
|
||||
stringlist_append_copy( well_list , well_name );
|
||||
}
|
||||
hash_iter_free(iter);
|
||||
@@ -1689,7 +1727,7 @@ stringlist_type * ecl_smspec_alloc_well_list( const ecl_smspec_type * smspec , c
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
Returns a stringlist instance with all the (valid) group names. It
|
||||
is the responsability of the calling scope to free the stringlist
|
||||
with stringlist_free();
|
||||
@@ -1699,12 +1737,12 @@ stringlist_type * ecl_smspec_alloc_group_list( const ecl_smspec_type * smspec ,
|
||||
stringlist_type * group_list = stringlist_alloc_new( );
|
||||
{
|
||||
hash_iter_type * iter = hash_iter_alloc( smspec->group_var_index );
|
||||
|
||||
|
||||
while (!hash_iter_is_complete( iter )) {
|
||||
const char * group_name = hash_iter_get_next_key( iter );
|
||||
if (pattern == NULL)
|
||||
stringlist_append_copy( group_list , group_name );
|
||||
else if (util_fnmatch( pattern , group_name) == 0)
|
||||
else if (util_fnmatch( pattern , group_name) == 0)
|
||||
stringlist_append_copy( group_list , group_name );
|
||||
}
|
||||
hash_iter_free(iter);
|
||||
@@ -1715,7 +1753,7 @@ stringlist_type * ecl_smspec_alloc_group_list( const ecl_smspec_type * smspec ,
|
||||
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
Returns a stringlist instance with all the well variables. It is
|
||||
the responsability of the calling scope to free the stringlist
|
||||
with stringlist_free();
|
||||
|
||||
+94
-86
@@ -79,7 +79,7 @@
|
||||
combined to create a unique key; and the corresponding index is
|
||||
used to lookup a numerical value from the PARAMS vector with actual
|
||||
data.
|
||||
|
||||
|
||||
These matters are documented further in the ecl_smspec.c and
|
||||
ecl_sum_data.c files.
|
||||
*/
|
||||
@@ -104,7 +104,7 @@ struct ecl_sum_struct {
|
||||
char * abs_path; /* Absolute path. */
|
||||
char * base; /* Only the basename. */
|
||||
char * ecl_case; /* This is the current case, with optional path component. == path + base*/
|
||||
char * ext; /* Only to support selective loading of formatted|unformatted and unified|multiple. (can be NULL) */
|
||||
char * ext; /* Only to support selective loading of formatted|unformatted and unified|multiple. (can be NULL) */
|
||||
};
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ void ecl_sum_set_case( ecl_sum_type * ecl_sum , const char * ecl_case) {
|
||||
util_safe_free( ecl_sum->ext );
|
||||
{
|
||||
char *path , *base, *ext;
|
||||
|
||||
|
||||
util_alloc_file_components( ecl_case , &path , &base , &ext);
|
||||
|
||||
ecl_sum->ecl_case = util_alloc_string_copy( ecl_case );
|
||||
@@ -140,7 +140,7 @@ void ecl_sum_set_case( ecl_sum_type * ecl_sum , const char * ecl_case) {
|
||||
ecl_sum->abs_path = util_alloc_abs_path( path );
|
||||
else
|
||||
ecl_sum->abs_path = util_alloc_cwd();
|
||||
|
||||
|
||||
util_safe_free( base );
|
||||
util_safe_free( path );
|
||||
util_safe_free( ext );
|
||||
@@ -151,7 +151,7 @@ void ecl_sum_set_case( ecl_sum_type * ecl_sum , const char * ecl_case) {
|
||||
static ecl_sum_type * ecl_sum_alloc__( const char * input_arg , const char * key_join_string) {
|
||||
ecl_sum_type * ecl_sum = util_malloc( sizeof * ecl_sum );
|
||||
UTIL_TYPE_ID_INIT( ecl_sum , ECL_SUM_ID );
|
||||
|
||||
|
||||
ecl_sum->ecl_case = NULL;
|
||||
ecl_sum->path = NULL;
|
||||
ecl_sum->base = NULL;
|
||||
@@ -159,7 +159,7 @@ static ecl_sum_type * ecl_sum_alloc__( const char * input_arg , const char * key
|
||||
ecl_sum->abs_path = NULL;
|
||||
ecl_sum_set_case( ecl_sum , input_arg );
|
||||
ecl_sum->key_join_string = util_alloc_string_copy( key_join_string );
|
||||
|
||||
|
||||
ecl_sum->smspec = NULL;
|
||||
ecl_sum->data = NULL;
|
||||
|
||||
@@ -167,69 +167,72 @@ static ecl_sum_type * ecl_sum_alloc__( const char * input_arg , const char * key
|
||||
}
|
||||
|
||||
|
||||
static void ecl_sum_fread_data( ecl_sum_type * ecl_sum , const stringlist_type * data_files , bool include_restart) {
|
||||
static bool ecl_sum_fread_data( ecl_sum_type * ecl_sum , const stringlist_type * data_files , bool include_restart) {
|
||||
if (ecl_sum->data != NULL)
|
||||
ecl_sum_free_data( ecl_sum );
|
||||
ecl_sum->data = ecl_sum_data_alloc( ecl_sum->smspec );
|
||||
ecl_sum_data_fread( ecl_sum->data , data_files );
|
||||
|
||||
if (include_restart) {
|
||||
const char * path = ecl_sum->path;
|
||||
const stringlist_type * restart_cases = ecl_smspec_get_restart_list( ecl_sum->smspec );
|
||||
stringlist_type * restart_files = stringlist_alloc_new();
|
||||
|
||||
int restart_nr;
|
||||
for (restart_nr = 0; restart_nr < stringlist_get_size( restart_cases ); restart_nr++) {
|
||||
ecl_util_alloc_summary_data_files(path , stringlist_iget( restart_cases , restart_nr ) , ecl_sum->fmt_case , restart_files );
|
||||
ecl_sum_data_fread_restart( ecl_sum->data , restart_files );
|
||||
}
|
||||
stringlist_free( restart_files );
|
||||
}
|
||||
|
||||
ecl_sum->data = ecl_sum_data_alloc( ecl_sum->smspec );
|
||||
if (ecl_sum_data_fread( ecl_sum->data , data_files )) {
|
||||
if (include_restart) {
|
||||
const char * path = ecl_sum->path;
|
||||
const stringlist_type * restart_cases = ecl_smspec_get_restart_list( ecl_sum->smspec );
|
||||
stringlist_type * restart_files = stringlist_alloc_new();
|
||||
|
||||
int restart_nr;
|
||||
for (restart_nr = 0; restart_nr < stringlist_get_size( restart_cases ); restart_nr++) {
|
||||
ecl_util_alloc_summary_data_files(path , stringlist_iget( restart_cases , restart_nr ) , ecl_sum->fmt_case , restart_files );
|
||||
ecl_sum_data_fread_restart( ecl_sum->data , restart_files );
|
||||
}
|
||||
stringlist_free( restart_files );
|
||||
}
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void ecl_sum_fread(ecl_sum_type * ecl_sum , const char *header_file , const stringlist_type *data_files , bool include_restart) {
|
||||
|
||||
static bool ecl_sum_fread(ecl_sum_type * ecl_sum , const char *header_file , const stringlist_type *data_files , bool include_restart) {
|
||||
ecl_sum->smspec = ecl_smspec_fread_alloc( header_file , ecl_sum->key_join_string , include_restart);
|
||||
{
|
||||
if (ecl_sum->smspec) {
|
||||
bool fmt_file;
|
||||
ecl_util_get_file_type( header_file , &fmt_file , NULL);
|
||||
ecl_sum_set_fmt_case( ecl_sum , fmt_file );
|
||||
}
|
||||
ecl_sum_fread_data( ecl_sum , data_files , include_restart );
|
||||
} else
|
||||
return false;
|
||||
|
||||
{
|
||||
if (ecl_sum_fread_data( ecl_sum , data_files , include_restart )) {
|
||||
ecl_file_enum file_type = ecl_util_get_file_type( stringlist_iget( data_files , 0 ) , NULL , NULL);
|
||||
|
||||
|
||||
if (file_type == ECL_SUMMARY_FILE)
|
||||
ecl_sum_set_unified( ecl_sum , false );
|
||||
else if (file_type == ECL_UNIFIED_SUMMARY_FILE)
|
||||
ecl_sum_set_unified( ecl_sum , true);
|
||||
else
|
||||
util_abort("%s: what the fuck? \n",__func__);
|
||||
}
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool ecl_sum_fread_case( ecl_sum_type * ecl_sum , bool include_restart) {
|
||||
char * header_file;
|
||||
stringlist_type * summary_file_list = stringlist_alloc_new();
|
||||
|
||||
|
||||
bool caseOK = false;
|
||||
|
||||
|
||||
ecl_util_alloc_summary_files( ecl_sum->path , ecl_sum->base , ecl_sum->ext , &header_file , summary_file_list );
|
||||
if ((header_file != NULL) && (stringlist_get_size( summary_file_list ) > 0)) {
|
||||
ecl_sum_fread( ecl_sum , header_file , summary_file_list , include_restart );
|
||||
caseOK = true;
|
||||
caseOK = ecl_sum_fread( ecl_sum , header_file , summary_file_list , include_restart );
|
||||
}
|
||||
util_safe_free( header_file );
|
||||
stringlist_free( summary_file_list );
|
||||
|
||||
|
||||
return caseOK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
This will explicitly load the summary specified by @header_file and
|
||||
@@ -240,8 +243,8 @@ static bool ecl_sum_fread_case( ecl_sum_type * ecl_sum , bool include_restart) {
|
||||
initializing the data_files list with files from the restarted
|
||||
case.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
ecl_sum_type * ecl_sum_fread_alloc(const char *header_file , const stringlist_type *data_files , const char * key_join_string) {
|
||||
ecl_sum_type * ecl_sum = ecl_sum_alloc__( header_file , key_join_string );
|
||||
ecl_sum_fread( ecl_sum , header_file , data_files , false );
|
||||
@@ -293,7 +296,7 @@ ecl_sum_type * ecl_sum_alloc_writer( const char * ecl_case , bool fmt_output , b
|
||||
|
||||
ecl_sum->smspec = ecl_smspec_alloc_writer( key_join_string , sim_start , nx , ny , nz );
|
||||
ecl_sum->data = ecl_sum_data_alloc_writer( ecl_sum->smspec );
|
||||
|
||||
|
||||
return ecl_sum;
|
||||
}
|
||||
|
||||
@@ -330,14 +333,14 @@ void ecl_sum_free( ecl_sum_type * ecl_sum ) {
|
||||
|
||||
if (ecl_sum->smspec != NULL)
|
||||
ecl_smspec_free( ecl_sum->smspec );
|
||||
|
||||
|
||||
util_safe_free( ecl_sum->path );
|
||||
util_safe_free( ecl_sum->ext );
|
||||
util_safe_free( ecl_sum->abs_path );
|
||||
|
||||
free( ecl_sum->base );
|
||||
free( ecl_sum->ecl_case );
|
||||
|
||||
|
||||
free( ecl_sum->key_join_string );
|
||||
free( ecl_sum );
|
||||
}
|
||||
@@ -410,7 +413,7 @@ bool ecl_sum_case_exists( const char * input_file ) {
|
||||
util_safe_free( extension );
|
||||
util_safe_free( smspec_file );
|
||||
stringlist_free( data_files );
|
||||
|
||||
|
||||
return case_exists;
|
||||
}
|
||||
|
||||
@@ -450,8 +453,8 @@ double ecl_sum_time2days( const ecl_sum_type * ecl_sum , time_t sim_time) {
|
||||
/*****************************************************************/
|
||||
/* Well variables */
|
||||
|
||||
bool ecl_sum_has_well_var(const ecl_sum_type * ecl_sum , const char * well , const char *var) {
|
||||
return ecl_smspec_has_well_var(ecl_sum->smspec , well , var);
|
||||
bool ecl_sum_has_well_var(const ecl_sum_type * ecl_sum , const char * well , const char *var) {
|
||||
return ecl_smspec_has_well_var(ecl_sum->smspec , well , var);
|
||||
}
|
||||
|
||||
double ecl_sum_get_well_var(const ecl_sum_type * ecl_sum , int time_index , const char * well , const char *var) {
|
||||
@@ -473,8 +476,8 @@ double ecl_sum_get_well_var_from_sim_days( const ecl_sum_type * ecl_sum , double
|
||||
/*****************************************************************/
|
||||
/* Group variables */
|
||||
|
||||
bool ecl_sum_has_group_var(const ecl_sum_type * ecl_sum , const char * group , const char *var) {
|
||||
return ecl_smspec_has_group_var( ecl_sum->smspec , group , var);
|
||||
bool ecl_sum_has_group_var(const ecl_sum_type * ecl_sum , const char * group , const char *var) {
|
||||
return ecl_smspec_has_group_var( ecl_sum->smspec , group , var);
|
||||
}
|
||||
|
||||
double ecl_sum_get_group_var(const ecl_sum_type * ecl_sum , int time_index , const char * group , const char *var) {
|
||||
@@ -496,8 +499,8 @@ double ecl_sum_get_group_var_from_sim_days( const ecl_sum_type * ecl_sum , doubl
|
||||
|
||||
/*****************************************************************/
|
||||
/* Field variables */
|
||||
bool ecl_sum_has_field_var(const ecl_sum_type * ecl_sum , const char *var) {
|
||||
return ecl_smspec_has_field_var( ecl_sum->smspec , var);
|
||||
bool ecl_sum_has_field_var(const ecl_sum_type * ecl_sum , const char *var) {
|
||||
return ecl_smspec_has_field_var( ecl_sum->smspec , var);
|
||||
}
|
||||
|
||||
double ecl_sum_get_field_var(const ecl_sum_type * ecl_sum , int time_index , const char * var) {
|
||||
@@ -519,8 +522,8 @@ double ecl_sum_get_field_var_from_sim_days( const ecl_sum_type * ecl_sum , doubl
|
||||
/*****************************************************************/
|
||||
/* Block variables */
|
||||
|
||||
bool ecl_sum_has_block_var(const ecl_sum_type * ecl_sum , const char * block_var , int block_nr) {
|
||||
return ecl_smspec_has_block_var( ecl_sum->smspec , block_var , block_nr );
|
||||
bool ecl_sum_has_block_var(const ecl_sum_type * ecl_sum , const char * block_var , int block_nr) {
|
||||
return ecl_smspec_has_block_var( ecl_sum->smspec , block_var , block_nr );
|
||||
}
|
||||
|
||||
double ecl_sum_get_block_var(const ecl_sum_type * ecl_sum , int time_index , const char * block_var , int block_nr) {
|
||||
@@ -559,8 +562,8 @@ double ecl_sum_get_block_var_ijk_from_sim_days( const ecl_sum_type * ecl_sum , d
|
||||
region_nr: [1...num_regions] (NOT C-based indexing)
|
||||
*/
|
||||
|
||||
bool ecl_sum_has_region_var(const ecl_sum_type * ecl_sum , const char *var , int region_nr ) {
|
||||
return ecl_smspec_has_region_var( ecl_sum->smspec , var , region_nr);
|
||||
bool ecl_sum_has_region_var(const ecl_sum_type * ecl_sum , const char *var , int region_nr ) {
|
||||
return ecl_smspec_has_region_var( ecl_sum->smspec , var , region_nr);
|
||||
}
|
||||
|
||||
double ecl_sum_get_region_var(const ecl_sum_type * ecl_sum , int time_index , const char *var , int region_nr) {
|
||||
@@ -583,12 +586,12 @@ double ecl_sum_get_region_var_from_sim_days( const ecl_sum_type * ecl_sum , doub
|
||||
/*****************************************************************/
|
||||
/* Misc variables */
|
||||
|
||||
int ecl_sum_get_misc_var_index(const ecl_sum_type * ecl_sum , const char *var) {
|
||||
return ecl_smspec_get_misc_var_params_index( ecl_sum->smspec , var );
|
||||
int ecl_sum_get_misc_var_index(const ecl_sum_type * ecl_sum , const char *var) {
|
||||
return ecl_smspec_get_misc_var_params_index( ecl_sum->smspec , var );
|
||||
}
|
||||
|
||||
bool ecl_sum_has_misc_var(const ecl_sum_type * ecl_sum , const char *var) {
|
||||
return ecl_smspec_has_misc_var( ecl_sum->smspec , var );
|
||||
bool ecl_sum_has_misc_var(const ecl_sum_type * ecl_sum , const char *var) {
|
||||
return ecl_smspec_has_misc_var( ecl_sum->smspec , var );
|
||||
}
|
||||
|
||||
double ecl_sum_get_misc_var(const ecl_sum_type * ecl_sum , int time_index , const char *var) {
|
||||
@@ -631,11 +634,11 @@ int ecl_sum_get_general_var_params_index(const ecl_sum_type * ecl_sum , const ch
|
||||
}
|
||||
|
||||
|
||||
bool ecl_sum_has_general_var(const ecl_sum_type * ecl_sum , const char * lookup_kw) {
|
||||
return ecl_smspec_has_general_var( ecl_sum->smspec , lookup_kw);
|
||||
bool ecl_sum_has_general_var(const ecl_sum_type * ecl_sum , const char * lookup_kw) {
|
||||
return ecl_smspec_has_general_var( ecl_sum->smspec , lookup_kw);
|
||||
}
|
||||
|
||||
bool ecl_sum_has_key(const ecl_sum_type * ecl_sum , const char * lookup_kw) {
|
||||
bool ecl_sum_has_key(const ecl_sum_type * ecl_sum , const char * lookup_kw) {
|
||||
return ecl_sum_has_general_var( ecl_sum , lookup_kw );
|
||||
}
|
||||
|
||||
@@ -646,6 +649,11 @@ double ecl_sum_get_general_var(const ecl_sum_type * ecl_sum , int time_index , c
|
||||
}
|
||||
|
||||
|
||||
void ecl_sum_dump_line_to_csv_file(const ecl_sum_type * ecl_sum, time_t sim_time, const ecl_sum_vector_type * key_words, FILE *fp){
|
||||
ecl_sum_data_write_csv_file(ecl_sum->data, sim_time, key_words, fp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
double ecl_sum_get_general_var_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const char * var) {
|
||||
const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum , var );
|
||||
@@ -836,7 +844,7 @@ time_t ecl_sum_iget_sim_time( const ecl_sum_type * ecl_sum , int index ) {
|
||||
return ecl_sum_data_iget_sim_time( ecl_sum->data , index );
|
||||
}
|
||||
|
||||
const time_interval_type * ecl_sum_get_sim_time( const ecl_sum_type * ecl_sum) {
|
||||
const time_interval_type * ecl_sum_get_sim_time( const ecl_sum_type * ecl_sum) {
|
||||
return ecl_sum_data_get_sim_time( ecl_sum->data );
|
||||
}
|
||||
|
||||
@@ -905,52 +913,52 @@ void ecl_sum_fmt_init_summary_x( ecl_sum_fmt_type * fmt ) {
|
||||
|
||||
static void __ecl_sum_fprintf_line( const ecl_sum_type * ecl_sum , FILE * stream , int internal_index , const bool_vector_type * has_var , const int_vector_type * var_index , char * date_string , const ecl_sum_fmt_type * fmt) {
|
||||
fprintf(stream , fmt->days_fmt , ecl_sum_iget_sim_days(ecl_sum , internal_index));
|
||||
fprintf(stream , fmt->sep );
|
||||
fprintf(stream , "%s", fmt->sep );
|
||||
|
||||
{
|
||||
{
|
||||
struct tm ts;
|
||||
time_t sim_time = ecl_sum_iget_sim_time(ecl_sum , internal_index );
|
||||
util_localtime( &sim_time , &ts);
|
||||
strftime( date_string , DATE_STRING_LENGTH - 1 , fmt->date_fmt , &ts);
|
||||
fprintf(stream , date_string );
|
||||
}
|
||||
fprintf(stream , "%s", date_string );
|
||||
}
|
||||
|
||||
{
|
||||
int ivar;
|
||||
for (ivar = 0; ivar < int_vector_size( var_index ); ivar++) {
|
||||
for (ivar = 0; ivar < int_vector_size( var_index ); ivar++) {
|
||||
if (bool_vector_iget( has_var , ivar )) {
|
||||
fprintf(stream , fmt->sep);
|
||||
fprintf(stream , "%s", fmt->sep);
|
||||
fprintf(stream , fmt->value_fmt , ecl_sum_iget(ecl_sum , internal_index, int_vector_iget( var_index , ivar )));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stream , fmt->newline);
|
||||
|
||||
fprintf(stream , "%s", fmt->newline);
|
||||
}
|
||||
|
||||
|
||||
static void ecl_sum_fprintf_header( const ecl_sum_type * ecl_sum , const stringlist_type * key_list , const bool_vector_type * has_var , FILE * stream, const ecl_sum_fmt_type * fmt) {
|
||||
fprintf(stream , fmt->date_header);
|
||||
{
|
||||
fprintf(stream , "%s", fmt->date_header);
|
||||
{
|
||||
int i;
|
||||
for (i=0; i < stringlist_get_size( key_list ); i++)
|
||||
if (bool_vector_iget( has_var , i )) {
|
||||
fprintf(stream , fmt->sep);
|
||||
if (bool_vector_iget( has_var , i )) {
|
||||
fprintf(stream , "%s", fmt->sep);
|
||||
fprintf(stream , fmt->header_fmt , stringlist_iget( key_list , i ));
|
||||
}
|
||||
}
|
||||
|
||||
fprintf( stream , fmt->newline);
|
||||
fprintf( stream , "%s", fmt->newline);
|
||||
if (fmt->print_dash) {
|
||||
fprintf(stream , fmt->date_dash);
|
||||
|
||||
fprintf(stream , "%s", fmt->date_dash);
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i=0; i < stringlist_get_size( key_list ); i++)
|
||||
if (bool_vector_iget( has_var , i ))
|
||||
fprintf(stream , fmt->value_dash);
|
||||
fprintf(stream , "%s", fmt->value_dash);
|
||||
}
|
||||
fprintf( stream , fmt->newline);
|
||||
fprintf( stream , "%s", fmt->newline);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -964,7 +972,7 @@ void ecl_sum_fprintf(const ecl_sum_type * ecl_sum , FILE * stream , const string
|
||||
char * current_locale = NULL;
|
||||
if (fmt->locale != NULL)
|
||||
current_locale = setlocale(LC_NUMERIC , fmt->locale);
|
||||
|
||||
|
||||
{
|
||||
int ivar;
|
||||
for (ivar = 0; ivar < stringlist_get_size( var_list ); ivar++) {
|
||||
@@ -977,7 +985,7 @@ void ecl_sum_fprintf(const ecl_sum_type * ecl_sum , FILE * stream , const string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (fmt->print_header)
|
||||
ecl_sum_fprintf_header( ecl_sum , var_list , has_var , stream , fmt);
|
||||
|
||||
@@ -1175,10 +1183,10 @@ void ecl_sum_update_wgname( ecl_sum_type * ecl_sum , smspec_node_type * node , c
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
/*
|
||||
/*
|
||||
The functions below are extremly simple functions which only serve
|
||||
as an easy access to the smspec_alloc_xxx_key() functions which
|
||||
know how to create the various composite keys.
|
||||
know how to create the various composite keys.
|
||||
*/
|
||||
|
||||
char * ecl_sum_alloc_well_key( const ecl_sum_type * ecl_sum , const char * keyword , const char * wgname) {
|
||||
@@ -1198,7 +1206,7 @@ bool ecl_sum_is_oil_producer( const ecl_sum_type * ecl_sum , const char * well)
|
||||
if (wopt > 0)
|
||||
oil_producer = true;
|
||||
}
|
||||
|
||||
|
||||
return oil_producer;
|
||||
}
|
||||
|
||||
@@ -1206,7 +1214,7 @@ bool ecl_sum_is_oil_producer( const ecl_sum_type * ecl_sum , const char * well)
|
||||
|
||||
bool ecl_sum_report_step_equal( const ecl_sum_type * ecl_sum1 , const ecl_sum_type * ecl_sum2) {
|
||||
if (ecl_sum1 == ecl_sum2)
|
||||
return true;
|
||||
return true;
|
||||
else
|
||||
return ecl_sum_data_report_step_equal( ecl_sum1->data , ecl_sum2->data );
|
||||
}
|
||||
@@ -1214,7 +1222,7 @@ bool ecl_sum_report_step_equal( const ecl_sum_type * ecl_sum1 , const ecl_sum_ty
|
||||
|
||||
bool ecl_sum_report_step_compatible( const ecl_sum_type * ecl_sum1 , const ecl_sum_type * ecl_sum2) {
|
||||
if (ecl_sum1 == ecl_sum2)
|
||||
return true;
|
||||
return true;
|
||||
else
|
||||
return ecl_sum_data_report_step_compatible( ecl_sum1->data , ecl_sum2->data );
|
||||
}
|
||||
|
||||
+230
-188
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_sum_data.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_sum_data.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@@ -34,14 +34,15 @@
|
||||
#include <ert/ecl/ecl_file.h>
|
||||
#include <ert/ecl/ecl_endian_flip.h>
|
||||
#include <ert/ecl/ecl_kw_magic.h>
|
||||
#include <ert/ecl/ecl_sum_vector.h>
|
||||
|
||||
|
||||
|
||||
/*
|
||||
This file implements the type ecl_sum_data_type. The data structure
|
||||
This file implements the type ecl_sum_data_type. The data structure
|
||||
is involved with holding all the actual summary data (i.e. the
|
||||
PARAMS vectors in ECLIPSE speak), in addition the time-information
|
||||
with MINISTEPS / REPORT_STEPS and so on is implemented here.
|
||||
with MINISTEPS / REPORT_STEPS and so on is implemented here.
|
||||
|
||||
This file has no information about how to index into the PARAMS
|
||||
vector, i.e. at which location can the WWCT for well P6 be found,
|
||||
@@ -62,7 +63,7 @@
|
||||
|
||||
------------------
|
||||
SEQHDR \
|
||||
MINISTEP 0 |
|
||||
MINISTEP 0 |
|
||||
PARAMS ..... |
|
||||
MINISTEP 1 |==> This is REPORT STEP 1, in file BASE.S00001
|
||||
PARAMS ..... |
|
||||
@@ -92,7 +93,7 @@
|
||||
* When using multiple files we can read off the report number
|
||||
from the filename, for unified files this is IMPOSSIBLE, and we
|
||||
just have to assume that the first block corresponds to
|
||||
report_step 1 and then count afterwards.
|
||||
report_step 1 and then count afterwards.
|
||||
|
||||
* When asking for a summary variable at a particular REPORT STEP
|
||||
(as we do in enkf) it is ambigous as to which ministep within
|
||||
@@ -101,7 +102,7 @@
|
||||
use the last ministep in the block.
|
||||
|
||||
* There is no BASE.SOOOO file
|
||||
|
||||
|
||||
* The report steps are halfopen intervals in the "wrong way":
|
||||
(....]
|
||||
|
||||
@@ -116,7 +117,7 @@
|
||||
underlying partial differential equation, i.e. the length of the
|
||||
timesteps is controlled by the simulator itself - there is no finer
|
||||
temporal resolution.
|
||||
|
||||
|
||||
The user has told the simulator to store (i.e. save to file
|
||||
results) the results at reportsteps. A reportstep will typically
|
||||
consist of several ministeps. The timeline below shows a simulation
|
||||
@@ -125,8 +126,8 @@
|
||||
|
||||
S0001 S0002
|
||||
||------|------|------------|------------------||----------------------|----------------------||
|
||||
M1 M2 M3 M4 M5 M6
|
||||
|
||||
M1 M2 M3 M4 M5 M6
|
||||
|
||||
The first reportstep consist of four ministeps, the second
|
||||
reportstep consits of only two ministeps. As a user you have no
|
||||
control over the length/number of ministeps apart from:
|
||||
@@ -163,7 +164,7 @@
|
||||
S0000 S0001
|
||||
||--------------|---------------|------------X-------------||
|
||||
M1 M2 /|\ M3
|
||||
|
|
||||
|
|
||||
|
|
||||
|
||||
We have enteeed the sim_days/sim_time cooresponding to the location
|
||||
@@ -179,9 +180,9 @@
|
||||
ecl_smspec_set_rate_var() function in ecl_smspec.c.
|
||||
|
||||
|
||||
|
||||
|
||||
Indexing and _get() versus _iget()
|
||||
----------------------------------
|
||||
----------------------------------
|
||||
As already mentionded the set of ministeps is not necessarrily a
|
||||
continous series, we can easily have a series of ministeps with
|
||||
"holes" in it, and the series can also start on a non-zero
|
||||
@@ -196,11 +197,11 @@
|
||||
data by giving an internal (not that internal ...) index. In
|
||||
ecl_sum_data.c the latter functions have _iget():
|
||||
|
||||
|
||||
|
||||
ecl_sum_data_get_xxx : Expects the time direction given as a ministep_nr.
|
||||
ecl_sum_data_iget_xxx: Expects the time direction given as an internal index.
|
||||
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -211,14 +212,14 @@ struct ecl_sum_data_struct {
|
||||
ecl_smspec_type * smspec; /* A shared reference - only used for providing good error messages. */
|
||||
vector_type * data; /* Vector of ecl_sum_tstep_type instances. */
|
||||
int first_ministep;
|
||||
int last_ministep;
|
||||
int last_ministep;
|
||||
double days_start;
|
||||
double sim_length;
|
||||
int_vector_type * report_first_index ; /* Indexed by report_step - giving first internal_index in report_step. */
|
||||
int_vector_type * report_last_index; /* Indexed by report_step - giving last internal_index in report_step. */
|
||||
int_vector_type * report_last_index; /* Indexed by report_step - giving last internal_index in report_step. */
|
||||
int first_report_step;
|
||||
int last_report_step;
|
||||
time_t __min_time; /* An internal member used during the load of
|
||||
time_t __min_time; /* An internal member used during the load of
|
||||
restarted cases; see doc in ecl_sum_data_append_tstep. */
|
||||
bool index_valid;
|
||||
time_interval_type * sim_time; /* The time interval sim_time goes from the first time value where we have
|
||||
@@ -250,13 +251,13 @@ struct ecl_sum_data_struct {
|
||||
static void ecl_sum_data_clear_index( ecl_sum_data_type * data ) {
|
||||
int_vector_reset( data->report_first_index);
|
||||
int_vector_reset( data->report_last_index);
|
||||
|
||||
|
||||
data->first_report_step = 1024 * 1024;
|
||||
data->last_report_step = -1024 * 1024;
|
||||
data->days_start = 0;
|
||||
data->sim_length = -1;
|
||||
data->first_ministep = INVALID_MINISTEP_NR;
|
||||
data->last_ministep = INVALID_MINISTEP_NR;
|
||||
data->last_ministep = INVALID_MINISTEP_NR;
|
||||
data->index_valid = false;
|
||||
time_interval_reopen( data->sim_time );
|
||||
}
|
||||
@@ -267,8 +268,8 @@ ecl_sum_data_type * ecl_sum_data_alloc(ecl_smspec_type * smspec) {
|
||||
data->data = vector_alloc_new();
|
||||
data->smspec = smspec;
|
||||
data->__min_time = 0;
|
||||
|
||||
data->report_first_index = int_vector_alloc( 0 , INVALID_MINISTEP_NR );
|
||||
|
||||
data->report_first_index = int_vector_alloc( 0 , INVALID_MINISTEP_NR );
|
||||
data->report_last_index = int_vector_alloc( 0 , INVALID_MINISTEP_NR );
|
||||
data->sim_time = time_interval_alloc_open();
|
||||
|
||||
@@ -280,17 +281,17 @@ ecl_sum_data_type * ecl_sum_data_alloc(ecl_smspec_type * smspec) {
|
||||
/**
|
||||
This function will take a report as input , and update the two
|
||||
pointers ministep1 and ministep2 with the range of the report step
|
||||
(in terms of ministeps).
|
||||
(in terms of ministeps).
|
||||
|
||||
Calling this function with report_step == 2 for the example
|
||||
documented at the top of the file will yield: *ministep1 = 3 and
|
||||
*ministep2 = 7. If you are only interested in one of the limits you
|
||||
can pass in NULL for the other limit, i.e.
|
||||
can pass in NULL for the other limit, i.e.
|
||||
|
||||
xxx(data , report_step , NULL , &ministep2);
|
||||
xxx(data , report_step , NULL , &ministep2);
|
||||
|
||||
to get the last step.
|
||||
|
||||
|
||||
If the supplied report_step is invalid the function will set both
|
||||
return values to -1 (the return value from safe_iget). In that case
|
||||
it is the responsability of the calling scope to check the return
|
||||
@@ -308,9 +309,9 @@ static const ecl_sum_tstep_type * ecl_sum_data_iget_ministep( const ecl_sum_data
|
||||
void ecl_sum_data_report2internal_range(const ecl_sum_data_type * data , int report_step , int * index1 , int * index2 ){
|
||||
if (index1 != NULL)
|
||||
*index1 = int_vector_safe_iget( data->report_first_index , report_step );
|
||||
|
||||
|
||||
if (index2 != NULL)
|
||||
*index2 = int_vector_safe_iget( data->report_last_index , report_step );
|
||||
*index2 = int_vector_safe_iget( data->report_last_index , report_step );
|
||||
}
|
||||
|
||||
|
||||
@@ -331,7 +332,7 @@ static void ecl_sum_data_fwrite_report__( const ecl_sum_data_type * data , int r
|
||||
|
||||
{
|
||||
int index , index1 , index2;
|
||||
|
||||
|
||||
ecl_sum_data_report2internal_range( data , report_step , &index1 , &index2);
|
||||
for (index = index1; index <= index2; index++) {
|
||||
const ecl_sum_tstep_type * tstep = ecl_sum_data_iget_ministep( data , index );
|
||||
@@ -345,9 +346,9 @@ static void ecl_sum_data_fwrite_report__( const ecl_sum_data_type * data , int r
|
||||
static void ecl_sum_data_fwrite_multiple_step( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case , int report_step) {
|
||||
char * filename = ecl_util_alloc_filename( NULL , ecl_case , ECL_UNIFIED_SUMMARY_FILE , fmt_case , 0 );
|
||||
fortio_type * fortio = fortio_open_readwrite( filename , fmt_case , ECL_ENDIAN_FLIP );
|
||||
|
||||
|
||||
ecl_sum_data_fwrite_report__( data , report_step , fortio );
|
||||
|
||||
|
||||
fortio_fclose( fortio );
|
||||
free(filename);
|
||||
}
|
||||
@@ -356,7 +357,7 @@ static void ecl_sum_data_fwrite_multiple_step( const ecl_sum_data_type * data ,
|
||||
static void ecl_sum_data_fwrite_unified_step( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case , int report_step) {
|
||||
char * filename = ecl_util_alloc_filename( NULL , ecl_case , ECL_UNIFIED_SUMMARY_FILE , fmt_case , 0 );
|
||||
fortio_type * fortio = fortio_open_readwrite( filename , fmt_case , ECL_ENDIAN_FLIP );
|
||||
|
||||
|
||||
int current_step = 1;
|
||||
if (report_step > 1) {
|
||||
while (true) {
|
||||
@@ -370,15 +371,15 @@ static void ecl_sum_data_fwrite_unified_step( const ecl_sum_data_type * data , c
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (current_step == report_step) { // We found the position:
|
||||
long size = fortio_ftell( fortio );
|
||||
|
||||
|
||||
util_ftruncate( fortio_get_FILE( fortio ) , size );
|
||||
ecl_sum_data_fwrite_report__( data , report_step , fortio );
|
||||
} else
|
||||
util_abort("%s: hmm could not locate the position for report step:%d in summary file:%s \n",__func__ , report_step , filename);
|
||||
|
||||
|
||||
fortio_fclose( fortio );
|
||||
free( filename );
|
||||
}
|
||||
@@ -389,12 +390,12 @@ static void ecl_sum_data_fwrite_unified( const ecl_sum_data_type * data , const
|
||||
char * filename = ecl_util_alloc_filename( NULL , ecl_case , ECL_UNIFIED_SUMMARY_FILE , fmt_case , 0 );
|
||||
fortio_type * fortio = fortio_open_writer( filename , fmt_case , ECL_ENDIAN_FLIP );
|
||||
int report_step;
|
||||
|
||||
|
||||
for (report_step = data->first_report_step; report_step <= data->last_report_step; report_step++) {
|
||||
if (ecl_sum_data_has_report_step( data , report_step ))
|
||||
ecl_sum_data_fwrite_report__( data , report_step , fortio );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fortio_fclose( fortio );
|
||||
free( filename );
|
||||
}
|
||||
@@ -407,14 +408,14 @@ static void ecl_sum_data_fwrite_multiple( const ecl_sum_data_type * data , const
|
||||
if (ecl_sum_data_has_report_step( data , report_step )) {
|
||||
char * filename = ecl_util_alloc_filename( NULL , ecl_case , ECL_SUMMARY_FILE , fmt_case , report_step );
|
||||
fortio_type * fortio = fortio_open_writer( filename , fmt_case , ECL_ENDIAN_FLIP );
|
||||
|
||||
|
||||
ecl_sum_data_fwrite_report__( data , report_step , fortio );
|
||||
|
||||
|
||||
fortio_fclose( fortio );
|
||||
free( filename );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -451,8 +452,8 @@ double ecl_sum_data_get_first_day( const ecl_sum_data_type * data) { return data
|
||||
actually been loaded) to the last loaded simulation step.
|
||||
*/
|
||||
|
||||
double ecl_sum_data_get_sim_length( const ecl_sum_data_type * data ) {
|
||||
return data->sim_length;
|
||||
double ecl_sum_data_get_sim_length( const ecl_sum_data_type * data ) {
|
||||
return data->sim_length;
|
||||
}
|
||||
|
||||
|
||||
@@ -466,7 +467,7 @@ double ecl_sum_data_get_sim_length( const ecl_sum_data_type * data ) {
|
||||
have summary data for the requested date/days value. In the case of
|
||||
a restarted case, where the original case is missing - this will
|
||||
return false if the input values are in the region after simulation
|
||||
start with no data.
|
||||
start with no data.
|
||||
*/
|
||||
|
||||
bool ecl_sum_data_check_sim_time( const ecl_sum_data_type * data , time_t sim_time) {
|
||||
@@ -527,7 +528,7 @@ bool ecl_sum_data_check_sim_days( const ecl_sum_data_type * data , double sim_da
|
||||
static int ecl_sum_data_get_index_from_sim_time( const ecl_sum_data_type * data , time_t sim_time) {
|
||||
time_t data_start_time = time_interval_get_start( data->sim_time );
|
||||
time_t sim_end = time_interval_get_end( data->sim_time );
|
||||
|
||||
|
||||
if (!ecl_sum_data_check_sim_time( data , sim_time )) {
|
||||
fprintf(stderr , "Simulation start: "); util_fprintf_date( ecl_smspec_get_start_time( data->smspec ) , stderr );
|
||||
fprintf(stderr , "Data start......: "); util_fprintf_date( data_start_time , stderr );
|
||||
@@ -535,8 +536,8 @@ static int ecl_sum_data_get_index_from_sim_time( const ecl_sum_data_type * data
|
||||
fprintf(stderr , "Requested date .: "); util_fprintf_date( sim_time , stderr );
|
||||
util_abort("%s: invalid time_t instance:%d interval: [%d,%d]\n",__func__, sim_time , data_start_time , sim_end);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
The moment we have passed the intial test we MUST find a valid
|
||||
ministep index, however care should be taken that there can
|
||||
perfectly well be 'holes' in the time domain, because of e.g. the
|
||||
@@ -546,7 +547,7 @@ static int ecl_sum_data_get_index_from_sim_time( const ecl_sum_data_type * data
|
||||
int low_index = 0;
|
||||
int high_index = vector_get_size( data->data );
|
||||
int internal_index = INVALID_MINISTEP_NR;
|
||||
|
||||
|
||||
|
||||
while (internal_index < 0) {
|
||||
if (low_index == high_index)
|
||||
@@ -554,7 +555,7 @@ static int ecl_sum_data_get_index_from_sim_time( const ecl_sum_data_type * data
|
||||
else {
|
||||
int center_index = 0.5*( low_index + high_index );
|
||||
const ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep( data , center_index );
|
||||
|
||||
|
||||
if ((high_index - low_index) == 1) {
|
||||
/* Degenerate special case. */
|
||||
if (sim_time < ecl_sum_tstep_get_sim_time( ministep ))
|
||||
@@ -570,7 +571,7 @@ static int ecl_sum_data_get_index_from_sim_time( const ecl_sum_data_type * data
|
||||
const ecl_sum_tstep_type * prev_step = ecl_sum_data_iget_ministep( data , center_index - 1 );
|
||||
prev_time = ecl_sum_tstep_get_sim_time( prev_step );
|
||||
}
|
||||
|
||||
|
||||
if (prev_time < sim_time)
|
||||
internal_index = center_index; /* Found it */
|
||||
else
|
||||
@@ -594,7 +595,7 @@ int ecl_sum_data_get_index_from_sim_days( const ecl_sum_data_type * data , doubl
|
||||
/**
|
||||
This function will take a true time 'sim_time' as input. The
|
||||
ministep indices bracketing this sim_time is identified, and the
|
||||
corresponding weights are calculated.
|
||||
corresponding weights are calculated.
|
||||
|
||||
The actual value we are interested in can then be computed with the
|
||||
ecl_sum_data_interp_get() function:
|
||||
@@ -609,8 +610,8 @@ int ecl_sum_data_get_index_from_sim_days( const ecl_sum_data_type * data , doubl
|
||||
ecl_sum_data_init_interp_from_sim_time( data , sim_time , &ministep1 , &ministep2 , &weight1 , &weight2);
|
||||
return ecl_sum_data_interp_get( data , ministep1 , ministep2 , weight1 , weight2 , param_index );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
For further explanation (in particular for which keywords the
|
||||
function should be used), consult documentation at the top of this
|
||||
file.
|
||||
@@ -624,8 +625,8 @@ void ecl_sum_data_init_interp_from_sim_time( const ecl_sum_data_type * data , ti
|
||||
const ecl_sum_tstep_type * ministep2 = ecl_sum_data_iget_ministep( data , index2 );
|
||||
const ecl_sum_tstep_type * ministep1;
|
||||
time_t sim_time2 = ecl_sum_tstep_get_sim_time( ministep2 );
|
||||
|
||||
|
||||
|
||||
|
||||
index1 = index2;
|
||||
while (true) {
|
||||
index1--;
|
||||
@@ -638,12 +639,12 @@ void ecl_sum_data_init_interp_from_sim_time( const ecl_sum_data_type * data , ti
|
||||
if (index1 == 0)
|
||||
util_abort("%s: Hmm internal error?? \n",__func__);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
double weight2 = (sim_time - ecl_sum_tstep_get_sim_time( ministep1 ));
|
||||
double weight1 = -(sim_time - ecl_sum_tstep_get_sim_time( ministep2 ));
|
||||
|
||||
|
||||
|
||||
|
||||
*_index1 = index1;
|
||||
*_index2 = index2;
|
||||
*_weight1 = weight1 / ( weight1 + weight2 );
|
||||
@@ -664,7 +665,7 @@ void ecl_sum_data_init_interp_from_sim_days( const ecl_sum_data_type * data , do
|
||||
|
||||
|
||||
static void ecl_sum_data_append_tstep__( ecl_sum_data_type * data , int ministep_nr , ecl_sum_tstep_type * tstep) {
|
||||
/*
|
||||
/*
|
||||
Here the tstep is just appended naively, the vector will be
|
||||
sorted by ministep_nr before the data instance is returned.
|
||||
*/
|
||||
@@ -681,8 +682,8 @@ static void ecl_sum_data_append_tstep__( ecl_sum_data_type * data , int ministep
|
||||
the initial simulation:
|
||||
|
||||
Simulation 1: T1-------------TR------------T2
|
||||
|
|
||||
Simulation 2: \-----------------------T3
|
||||
|
|
||||
Simulation 2: \-----------------------T3
|
||||
|
||||
|
||||
In the time interval [TR,T2] we have data from two simulations, we
|
||||
@@ -691,14 +692,14 @@ static void ecl_sum_data_append_tstep__( ecl_sum_data_type * data , int ministep
|
||||
have been performed by the scope calling this function; when a
|
||||
ministep has arrived here it will be added.
|
||||
*/
|
||||
|
||||
|
||||
if (data->__min_time == 0)
|
||||
data->__min_time = ecl_sum_tstep_get_sim_time( tstep );
|
||||
else {
|
||||
if (ecl_sum_tstep_get_sim_time( tstep ) < data->__min_time)
|
||||
data->__min_time = ecl_sum_tstep_get_sim_time( tstep );
|
||||
}
|
||||
|
||||
|
||||
vector_append_owned_ref( data->data , tstep , ecl_sum_tstep_free__);
|
||||
data->index_valid = false;
|
||||
}
|
||||
@@ -706,15 +707,15 @@ static void ecl_sum_data_append_tstep__( ecl_sum_data_type * data , int ministep
|
||||
|
||||
static void ecl_sum_data_update_end_info( ecl_sum_data_type * sum_data ) {
|
||||
const ecl_sum_tstep_type * last_ministep = vector_get_last_const( sum_data->data );
|
||||
|
||||
|
||||
sum_data->last_ministep = ecl_sum_tstep_get_ministep( last_ministep );
|
||||
sum_data->sim_length = ecl_sum_tstep_get_sim_days( last_ministep );
|
||||
time_interval_update_end( sum_data->sim_time , ecl_sum_tstep_get_sim_time( last_ministep ));
|
||||
}
|
||||
|
||||
|
||||
static int cmp_ministep( const void * arg1 , const void * arg2) {
|
||||
const ecl_sum_tstep_type * ministep1 = ecl_sum_tstep_safe_cast_const( arg1 );
|
||||
const ecl_sum_tstep_type * ministep2 = ecl_sum_tstep_safe_cast_const( arg2 );
|
||||
const ecl_sum_tstep_type * ministep2 = ecl_sum_tstep_safe_cast_const( arg2 );
|
||||
|
||||
time_t time1 = ecl_sum_tstep_get_sim_time( ministep1 );
|
||||
time_t time2 = ecl_sum_tstep_get_sim_time( ministep2 );
|
||||
@@ -731,19 +732,19 @@ static int cmp_ministep( const void * arg1 , const void * arg2) {
|
||||
static void ecl_sum_data_build_index( ecl_sum_data_type * sum_data ) {
|
||||
/* Clear the existing index (if any): */
|
||||
ecl_sum_data_clear_index( sum_data );
|
||||
|
||||
|
||||
/*
|
||||
Sort the internal storage vector after sim_time.
|
||||
Sort the internal storage vector after sim_time.
|
||||
*/
|
||||
vector_sort( sum_data->data , cmp_ministep );
|
||||
|
||||
|
||||
|
||||
/* Identify various global first and last values. */
|
||||
{
|
||||
const ecl_sum_tstep_type * first_ministep = ecl_sum_data_iget_ministep( sum_data , 0 );
|
||||
sum_data->first_ministep = ecl_sum_tstep_get_ministep( first_ministep );
|
||||
|
||||
/*
|
||||
/*
|
||||
In most cases the days_start and data_start_time will agree
|
||||
with the global simulation start; however in the case where we
|
||||
have loaded a summary case from a restarted simulation where
|
||||
@@ -754,14 +755,14 @@ static void ecl_sum_data_build_index( ecl_sum_data_type * sum_data ) {
|
||||
time_interval_update_start( sum_data->sim_time , ecl_sum_tstep_get_sim_time( first_ministep ));
|
||||
}
|
||||
ecl_sum_data_update_end_info( sum_data );
|
||||
|
||||
|
||||
/* Build up the report -> ministep mapping. */
|
||||
{
|
||||
int internal_index;
|
||||
for (internal_index = 0; internal_index < vector_get_size( sum_data->data ); internal_index++) {
|
||||
const ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep( sum_data , internal_index );
|
||||
int report_step = ecl_sum_tstep_get_report(ministep);
|
||||
|
||||
|
||||
/* Indexing internal_index - report_step */
|
||||
{
|
||||
int current_first_index = int_vector_safe_iget( sum_data->report_first_index , report_step );
|
||||
@@ -771,7 +772,7 @@ static void ecl_sum_data_build_index( ecl_sum_data_type * sum_data ) {
|
||||
if (internal_index < current_first_index)
|
||||
int_vector_iset( sum_data->report_first_index , report_step , internal_index);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
int current_last_index = int_vector_safe_iget( sum_data->report_last_index , report_step );
|
||||
if (current_last_index < 0)
|
||||
@@ -780,7 +781,7 @@ static void ecl_sum_data_build_index( ecl_sum_data_type * sum_data ) {
|
||||
if (internal_index > current_last_index)
|
||||
int_vector_iset( sum_data->report_last_index , report_step , internal_index);
|
||||
}
|
||||
|
||||
|
||||
sum_data->first_report_step = util_int_min( sum_data->first_report_step , report_step );
|
||||
sum_data->last_report_step = util_int_max( sum_data->last_report_step , report_step );
|
||||
}
|
||||
@@ -796,7 +797,7 @@ static void ecl_sum_data_build_index( ecl_sum_data_type * sum_data ) {
|
||||
will also be returned, so the calling scope can call
|
||||
ecl_sum_tstep_iset() to set elements in the tstep.
|
||||
*/
|
||||
|
||||
|
||||
ecl_sum_tstep_type * ecl_sum_data_add_new_tstep( ecl_sum_data_type * data , int report_step , double sim_days) {
|
||||
int ministep_nr = vector_get_size( data->data );
|
||||
ecl_sum_tstep_type * tstep = ecl_sum_tstep_alloc_new( report_step , ministep_nr , sim_days , data->smspec );
|
||||
@@ -804,7 +805,7 @@ ecl_sum_tstep_type * ecl_sum_data_add_new_tstep( ecl_sum_data_type * data , int
|
||||
|
||||
if (vector_get_size( data->data ) > 0)
|
||||
prev_tstep = vector_get_last( data->data );
|
||||
|
||||
|
||||
ecl_sum_data_append_tstep__( data , ministep_nr , tstep );
|
||||
{
|
||||
bool rebuild_index = true;
|
||||
@@ -815,12 +816,12 @@ ecl_sum_tstep_type * ecl_sum_data_add_new_tstep( ecl_sum_data_type * data , int
|
||||
index, otherwise we call ecl_sum_data_build_index() to get a
|
||||
full recalculation of the index.
|
||||
*/
|
||||
|
||||
|
||||
if (prev_tstep != NULL) {
|
||||
if (ecl_sum_tstep_get_report( prev_tstep ) == ecl_sum_tstep_get_report( tstep )) { // Same report step
|
||||
if (ecl_sum_tstep_get_sim_days( prev_tstep ) < ecl_sum_tstep_get_sim_days( tstep )) { // This tstep will become the new latest tstep
|
||||
int internal_index = vector_get_size( data->data ) - 1;
|
||||
|
||||
|
||||
ecl_sum_data_update_end_info( data );
|
||||
int_vector_iset( data->report_last_index , report_step , internal_index );
|
||||
rebuild_index = false;
|
||||
@@ -831,7 +832,7 @@ ecl_sum_tstep_type * ecl_sum_data_add_new_tstep( ecl_sum_data_type * data , int
|
||||
ecl_sum_data_build_index( data );
|
||||
}
|
||||
ecl_smspec_lock( data->smspec );
|
||||
|
||||
|
||||
return tstep;
|
||||
}
|
||||
|
||||
@@ -863,13 +864,13 @@ ecl_sum_tstep_type * ecl_sum_data_add_new_tstep( ecl_sum_data_type * data , int
|
||||
calling routine will read the unified summary file partly.
|
||||
*/
|
||||
|
||||
static void ecl_sum_data_add_ecl_file(ecl_sum_data_type * data ,
|
||||
time_t load_end ,
|
||||
int report_step ,
|
||||
const ecl_file_type * ecl_file ,
|
||||
static void ecl_sum_data_add_ecl_file(ecl_sum_data_type * data ,
|
||||
time_t load_end ,
|
||||
int report_step ,
|
||||
const ecl_file_type * ecl_file ,
|
||||
const ecl_smspec_type * smspec) {
|
||||
|
||||
|
||||
|
||||
|
||||
int num_ministep = ecl_file_get_num_named_kw( ecl_file , PARAMS_KW);
|
||||
if (num_ministep > 0) {
|
||||
int ikw;
|
||||
@@ -881,16 +882,16 @@ static void ecl_sum_data_add_ecl_file(ecl_sum_data_type * data ,
|
||||
{
|
||||
ecl_sum_tstep_type * tstep;
|
||||
int ministep_nr = ecl_kw_iget_int( ministep_kw , 0 );
|
||||
tstep = ecl_sum_tstep_alloc_from_file( report_step ,
|
||||
tstep = ecl_sum_tstep_alloc_from_file( report_step ,
|
||||
ministep_nr ,
|
||||
params_kw ,
|
||||
params_kw ,
|
||||
ecl_file_get_src_file( ecl_file ),
|
||||
smspec );
|
||||
|
||||
|
||||
if (tstep != NULL) {
|
||||
if (load_end == 0 || (ecl_sum_tstep_get_sim_time( tstep ) < load_end))
|
||||
ecl_sum_data_append_tstep__( data , ministep_nr , tstep );
|
||||
else
|
||||
else
|
||||
/* This tstep is in a time-period overlapping with data we
|
||||
already have; discard this. */
|
||||
ecl_sum_tstep_free( tstep );
|
||||
@@ -901,76 +902,87 @@ static void ecl_sum_data_add_ecl_file(ecl_sum_data_type * data ,
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool ecl_sum_data_check_file( ecl_file_type * ecl_file ) {
|
||||
if (ecl_file_has_kw( ecl_file , PARAMS_KW ) &&
|
||||
(ecl_file_get_num_named_kw( ecl_file , PARAMS_KW ) == ecl_file_get_num_named_kw( ecl_file , MINISTEP_KW)))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Observe that this can be called several times (but not with the same
|
||||
data - that will die).
|
||||
data - that will die).
|
||||
|
||||
Warning: The index information of the ecl_sum_data instance has
|
||||
__NOT__ been updated when leaving this function. That is done with a
|
||||
call to ecl_sum_data_build_index().
|
||||
*/
|
||||
|
||||
static void ecl_sum_data_fread__( ecl_sum_data_type * data , time_t load_end , const stringlist_type * filelist) {
|
||||
ecl_file_enum file_type;
|
||||
|
||||
static bool ecl_sum_data_fread__( ecl_sum_data_type * data , time_t load_end , const stringlist_type * filelist) {
|
||||
if (stringlist_get_size( filelist ) == 0)
|
||||
util_abort("%s: internal error - function called with empty list of data files.\n",__func__);
|
||||
|
||||
file_type = ecl_util_get_file_type( stringlist_iget( filelist , 0 ) , NULL , NULL);
|
||||
if ((stringlist_get_size( filelist ) > 1) && (file_type != ECL_SUMMARY_FILE))
|
||||
util_abort("%s: internal error - when calling with more than one file - you can not supply a unified file - come on?! \n",__func__);
|
||||
return false;
|
||||
|
||||
{
|
||||
int filenr;
|
||||
if (file_type == ECL_SUMMARY_FILE) {
|
||||
|
||||
/* Not unified. */
|
||||
for (filenr = 0; filenr < stringlist_get_size( filelist ); filenr++) {
|
||||
const char * data_file = stringlist_iget( filelist , filenr);
|
||||
ecl_file_enum file_type;
|
||||
int report_step;
|
||||
file_type = ecl_util_get_file_type( data_file , NULL , &report_step);
|
||||
/**
|
||||
ECLIPSE starts a report step by writing an empty summary
|
||||
file, therefor we must verify that the ecl_file instance
|
||||
returned by ecl_file_fread_alloc() is different from NULL
|
||||
before adding it to the ecl_sum_data instance.
|
||||
*/
|
||||
if (file_type != ECL_SUMMARY_FILE)
|
||||
util_abort("%s: file:%s has wrong type \n",__func__ , data_file);
|
||||
{
|
||||
ecl_file_type * ecl_file = ecl_file_open( data_file , 0);
|
||||
ecl_sum_data_add_ecl_file( data , load_end , report_step , ecl_file , data->smspec);
|
||||
ecl_file_enum file_type = ecl_util_get_file_type( stringlist_iget( filelist , 0 ) , NULL , NULL);
|
||||
if ((stringlist_get_size( filelist ) > 1) && (file_type != ECL_SUMMARY_FILE))
|
||||
util_abort("%s: internal error - when calling with more than one file - you can not supply a unified file - come on?! \n",__func__);
|
||||
|
||||
{
|
||||
int filenr;
|
||||
if (file_type == ECL_SUMMARY_FILE) {
|
||||
|
||||
/* Not unified. */
|
||||
for (filenr = 0; filenr < stringlist_get_size( filelist ); filenr++) {
|
||||
const char * data_file = stringlist_iget( filelist , filenr);
|
||||
ecl_file_enum file_type;
|
||||
int report_step;
|
||||
file_type = ecl_util_get_file_type( data_file , NULL , &report_step);
|
||||
if (file_type != ECL_SUMMARY_FILE)
|
||||
util_abort("%s: file:%s has wrong type \n",__func__ , data_file);
|
||||
{
|
||||
ecl_file_type * ecl_file = ecl_file_open( data_file , 0);
|
||||
if (ecl_file && ecl_sum_data_check_file( ecl_file )) {
|
||||
ecl_sum_data_add_ecl_file( data , load_end , report_step , ecl_file , data->smspec);
|
||||
ecl_file_close( ecl_file );
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (file_type == ECL_UNIFIED_SUMMARY_FILE) {
|
||||
ecl_file_type * ecl_file = ecl_file_open( stringlist_iget(filelist ,0 ) , 0);
|
||||
if (ecl_file && ecl_sum_data_check_file( ecl_file )) {
|
||||
int report_step = 1; /* <- ECLIPSE numbering - starting at 1. */
|
||||
while (true) {
|
||||
/*
|
||||
Observe that there is a number discrepancy between ECLIPSE
|
||||
and the ecl_file_select_smryblock() function. ECLIPSE
|
||||
starts counting report steps at 1; whereas the first
|
||||
SEQHDR block in the unified summary file is block zero (in
|
||||
ert counting).
|
||||
*/
|
||||
if (ecl_file_select_smryblock( ecl_file , report_step - 1)) {
|
||||
ecl_sum_data_add_ecl_file( data , load_end , report_step , ecl_file , data->smspec);
|
||||
report_step++;
|
||||
} else break;
|
||||
}
|
||||
ecl_file_close( ecl_file );
|
||||
}
|
||||
}
|
||||
} else if (file_type == ECL_UNIFIED_SUMMARY_FILE) {
|
||||
ecl_file_type * ecl_file = ecl_file_open( stringlist_iget(filelist ,0 ) , 0);
|
||||
int report_step = 1; /* <- ECLIPSE numbering - starting at 1. */
|
||||
while (true) {
|
||||
/*
|
||||
Observe that there is a number discrepancy between ECLIPSE
|
||||
and the ecl_file_select_smryblock() function. ECLIPSE
|
||||
starts counting report steps at 1; whereas the first
|
||||
SEQHDR block in the unified summary file is block zero (in
|
||||
ert counting).
|
||||
*/
|
||||
if (ecl_file_select_smryblock( ecl_file , report_step - 1)) {
|
||||
ecl_sum_data_add_ecl_file( data , load_end , report_step , ecl_file , data->smspec);
|
||||
report_step++;
|
||||
} else break;
|
||||
}
|
||||
ecl_file_close( ecl_file );
|
||||
} else
|
||||
util_abort("%s: invalid file type:%s \n",__func__ , ecl_util_file_type_name(file_type ));
|
||||
}
|
||||
ecl_sum_data_build_index( data );
|
||||
} else
|
||||
util_abort("%s: invalid file type:%s \n",__func__ , ecl_util_file_type_name(file_type ));
|
||||
}
|
||||
|
||||
if (ecl_sum_data_get_length( data ) > 0) {
|
||||
ecl_sum_data_build_index( data );
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ecl_sum_data_fread( ecl_sum_data_type * data , const stringlist_type * filelist) {
|
||||
ecl_sum_data_fread__( data , 0 , filelist );
|
||||
bool ecl_sum_data_fread( ecl_sum_data_type * data , const stringlist_type * filelist) {
|
||||
return ecl_sum_data_fread__( data , 0 , filelist );
|
||||
}
|
||||
|
||||
|
||||
@@ -1012,7 +1024,7 @@ ecl_sum_data_type * ecl_sum_data_fread_alloc( ecl_smspec_type * smspec , const s
|
||||
}
|
||||
|
||||
|
||||
void ecl_sum_data_summarize(const ecl_sum_data_type * data , FILE * stream) {
|
||||
void ecl_sum_data_summarize(const ecl_sum_data_type * data , FILE * stream) {
|
||||
fprintf(stream , "REPORT INDEX DATE DAYS\n");
|
||||
fprintf(stream , "---------------------------------------------------------------\n");
|
||||
{
|
||||
@@ -1048,7 +1060,7 @@ bool ecl_sum_data_has_report_step(const ecl_sum_data_type * data , int report_st
|
||||
*/
|
||||
|
||||
int ecl_sum_data_iget_report_end( const ecl_sum_data_type * data , int report_step ) {
|
||||
return int_vector_safe_iget( data->report_last_index , report_step );
|
||||
return int_vector_safe_iget( data->report_last_index , report_step );
|
||||
}
|
||||
|
||||
|
||||
@@ -1062,7 +1074,7 @@ int ecl_sum_data_iget_report_end( const ecl_sum_data_type * data , int report_st
|
||||
|
||||
|
||||
int ecl_sum_data_iget_report_start( const ecl_sum_data_type * data , int report_step ) {
|
||||
return int_vector_safe_iget( data->report_first_index , report_step );
|
||||
return int_vector_safe_iget( data->report_first_index , report_step );
|
||||
}
|
||||
|
||||
|
||||
@@ -1086,7 +1098,7 @@ int ecl_sum_data_iget_mini_step(const ecl_sum_data_type * data , int internal_in
|
||||
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
This will look up a value based on an internal index. The internal
|
||||
index will ALWAYS run in the interval [0,num_ministep), without
|
||||
any holes.
|
||||
@@ -1095,16 +1107,16 @@ int ecl_sum_data_iget_mini_step(const ecl_sum_data_type * data , int internal_in
|
||||
|
||||
double ecl_sum_data_iget( const ecl_sum_data_type * data , int time_index , int params_index ) {
|
||||
const ecl_sum_tstep_type * ministep_data = ecl_sum_data_iget_ministep( data , time_index );
|
||||
return ecl_sum_tstep_iget( ministep_data , params_index);
|
||||
return ecl_sum_tstep_iget( ministep_data , params_index);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function will form a weight average of the two ministeps
|
||||
@ministep1 and @ministep2. The weights and the ministep indices
|
||||
should (typically) be determined by the
|
||||
should (typically) be determined by the
|
||||
|
||||
ecl_sum_data_init_interp_from_sim_xxx()
|
||||
ecl_sum_data_init_interp_from_sim_xxx()
|
||||
|
||||
functions. The function will typically the last function called
|
||||
when we seek a reservoir state variable at an intermediate time
|
||||
@@ -1112,13 +1124,43 @@ double ecl_sum_data_iget( const ecl_sum_data_type * data , int time_index , int
|
||||
*/
|
||||
|
||||
double ecl_sum_data_interp_get(const ecl_sum_data_type * data , int time_index1 , int time_index2 , double weight1 , double weight2 , int params_index) {
|
||||
const ecl_sum_tstep_type * ministep_data1 = ecl_sum_data_iget_ministep( data , time_index1 );
|
||||
const ecl_sum_tstep_type * ministep_data2 = ecl_sum_data_iget_ministep( data , time_index2 );
|
||||
|
||||
const ecl_sum_tstep_type * ministep_data1 = ecl_sum_data_iget_ministep( data , time_index1 );
|
||||
const ecl_sum_tstep_type * ministep_data2 = ecl_sum_data_iget_ministep( data , time_index2 );
|
||||
|
||||
return ecl_sum_tstep_iget( ministep_data1 , params_index ) * weight1 + ecl_sum_tstep_iget( ministep_data2 , params_index ) * weight2;
|
||||
}
|
||||
|
||||
|
||||
void ecl_sum_data_write_csv_file(const ecl_sum_data_type * data , time_t sim_time, const ecl_sum_vector_type * keylist, FILE *fp){
|
||||
int num_keywords = ecl_sum_vector_get_size(keylist);
|
||||
double weight1 , weight2;
|
||||
int time_index1 , time_index2;
|
||||
double value = 0.0;
|
||||
int i;
|
||||
|
||||
ecl_sum_data_init_interp_from_sim_time( data , sim_time , &time_index1 , &time_index2 , &weight1 , &weight2);
|
||||
for(i = 0; i< num_keywords; i++ ){
|
||||
bool is_rate = ecl_sum_vector_iget_is_rate(keylist, i);
|
||||
int params_index = ecl_sum_vector_iget_param_index(keylist , i);
|
||||
if(is_rate){
|
||||
int time_index;
|
||||
if (sim_time == time_interval_get_start( data->sim_time ))
|
||||
time_index = 0;
|
||||
else
|
||||
time_index = ecl_sum_data_get_index_from_sim_time( data , sim_time );
|
||||
|
||||
value = ecl_sum_data_iget( data , time_index , params_index);
|
||||
} else {
|
||||
value = ecl_sum_data_interp_get( data , time_index1 , time_index2 , weight1 , weight2 , params_index);
|
||||
|
||||
}
|
||||
if(i == 0){
|
||||
fprintf(fp , "%f",value);
|
||||
}else{
|
||||
fprintf(fp , ",%f",value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1133,14 +1175,14 @@ double ecl_sum_data_get_from_sim_time( const ecl_sum_data_type * data , time_t s
|
||||
|
||||
[]<------------]<--------------]<-----------]
|
||||
t0 t1 t2 t3
|
||||
|
||||
|
||||
However - as indicated on the figure above there is a zero
|
||||
measure point right at the start which corresponds to
|
||||
time_index == 0; this is to ensure that there is correspondance
|
||||
with the ECLIPSE results if you ask for a value interpolated to
|
||||
the starting time.
|
||||
*/
|
||||
if (sim_time == time_interval_get_start( data->sim_time ))
|
||||
if (sim_time == time_interval_get_start( data->sim_time ))
|
||||
time_index = 0;
|
||||
else
|
||||
time_index = ecl_sum_data_get_index_from_sim_time( data , sim_time );
|
||||
@@ -1150,7 +1192,7 @@ double ecl_sum_data_get_from_sim_time( const ecl_sum_data_type * data , time_t s
|
||||
/* Interpolated lookup based on two (hopefully) consecutive ministeps. */
|
||||
double weight1 , weight2;
|
||||
int time_index1 , time_index2;
|
||||
|
||||
|
||||
|
||||
ecl_sum_data_init_interp_from_sim_time( data , sim_time , &time_index1 , &time_index2 , &weight1 , &weight2);
|
||||
return ecl_sum_data_interp_get( data , time_index1 , time_index2 , weight1 , weight2 , params_index);
|
||||
@@ -1171,19 +1213,19 @@ int ecl_sum_data_get_report_step_from_days(const ecl_sum_data_type * data , doub
|
||||
for (i=1; i < int_vector_size( data->report_last_index ); i++) {
|
||||
int ministep_index = int_vector_iget( data->report_last_index , i );
|
||||
const ecl_sum_tstep_type * ministep = vector_iget_const( data->data , ministep_index );
|
||||
|
||||
|
||||
double_vector_iset( days_map , i , ecl_sum_tstep_get_sim_days( ministep ));
|
||||
int_vector_iset( report_map , i , ecl_sum_tstep_get_report( ministep ));
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
/** Hmmmm - double == comparison ... */
|
||||
int index = double_vector_index_sorted( days_map , sim_days );
|
||||
|
||||
|
||||
if (index >= 0)
|
||||
report_step = int_vector_iget( report_map , index );
|
||||
}
|
||||
|
||||
|
||||
int_vector_free( report_map );
|
||||
double_vector_free( days_map );
|
||||
return report_step;
|
||||
@@ -1193,14 +1235,14 @@ int ecl_sum_data_get_report_step_from_days(const ecl_sum_data_type * data , doub
|
||||
/**
|
||||
Will go through the data and find the report step which EXACTLY
|
||||
matches the input sim_time. If no report step matches exactly the
|
||||
function will return -1.
|
||||
function will return -1.
|
||||
|
||||
Observe that by default the report steps consist of half-open time
|
||||
intervals like this: (t1, t2]. However the first report step
|
||||
(i.e. report step 1, is a fully inclusive interval: [t0 , t1] where
|
||||
t0 is the simulation start time. That is not implemented here;
|
||||
meaning that if you supply the start time as @sim_time argument you
|
||||
will get -1 and not 0 as you might expect.
|
||||
will get -1 and not 0 as you might expect.
|
||||
|
||||
It would certainly be possible to detect the start_time input
|
||||
argument and special case the return, but the opposite would be
|
||||
@@ -1211,7 +1253,7 @@ int ecl_sum_data_get_report_step_from_days(const ecl_sum_data_type * data , doub
|
||||
|
||||
|
||||
int ecl_sum_data_get_report_step_from_time(const ecl_sum_data_type * data , time_t sim_time) {
|
||||
|
||||
|
||||
if (!ecl_sum_data_check_sim_time(data , sim_time))
|
||||
return -1;
|
||||
|
||||
@@ -1225,19 +1267,19 @@ int ecl_sum_data_get_report_step_from_time(const ecl_sum_data_type * data , time
|
||||
for (i=1; i < int_vector_size( data->report_last_index ); i++) {
|
||||
int ministep_index = int_vector_iget( data->report_last_index , i );
|
||||
const ecl_sum_tstep_type * ministep = vector_iget_const( data->data , ministep_index );
|
||||
|
||||
|
||||
time_t_vector_iset( time_map , i , ecl_sum_tstep_get_sim_time( ministep ));
|
||||
int_vector_iset( report_map , i , ecl_sum_tstep_get_report( ministep ));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
int index = time_t_vector_index_sorted( time_map , sim_time );
|
||||
|
||||
|
||||
if (index >= 0)
|
||||
report_step = int_vector_iget( report_map , index );
|
||||
}
|
||||
|
||||
|
||||
int_vector_free( report_map );
|
||||
time_t_vector_free( time_map );
|
||||
return report_step;
|
||||
@@ -1371,7 +1413,7 @@ int ecl_sum_data_get_length( const ecl_sum_data_type * data ) {
|
||||
bool ecl_sum_data_report_step_equal( const ecl_sum_data_type * data1 , const ecl_sum_data_type * data2) {
|
||||
bool equal = true;
|
||||
if (int_vector_size( data1->report_last_index ) == int_vector_size(data2->report_last_index)) {
|
||||
int i;
|
||||
int i;
|
||||
for (i = 0; i < int_vector_size( data1->report_last_index ); i++) {
|
||||
int time_index1 = int_vector_iget( data1->report_last_index , i );
|
||||
int time_index2 = int_vector_iget( data2->report_last_index , i );
|
||||
@@ -1379,7 +1421,7 @@ bool ecl_sum_data_report_step_equal( const ecl_sum_data_type * data1 , const ecl
|
||||
if ((time_index1 != INVALID_MINISTEP_NR) && (time_index2 != INVALID_MINISTEP_NR)) {
|
||||
const ecl_sum_tstep_type * ministep1 = ecl_sum_data_iget_ministep( data1 , time_index1 );
|
||||
const ecl_sum_tstep_type * ministep2 = ecl_sum_data_iget_ministep( data2 , time_index2 );
|
||||
|
||||
|
||||
if (!ecl_sum_tstep_sim_time_equal( ministep1 , ministep2)) {
|
||||
equal = false;
|
||||
break;
|
||||
@@ -1399,7 +1441,7 @@ bool ecl_sum_data_report_step_equal( const ecl_sum_data_type * data1 , const ecl
|
||||
bool ecl_sum_data_report_step_compatible( const ecl_sum_data_type * data1 , const ecl_sum_data_type * data2) {
|
||||
bool compatible = true;
|
||||
int min_size = util_int_min( int_vector_size( data1->report_last_index ) , int_vector_size( data2->report_last_index));
|
||||
int i;
|
||||
int i;
|
||||
for (i = 0; i < min_size; i++) {
|
||||
int time_index1 = int_vector_iget( data1->report_last_index , i );
|
||||
int time_index2 = int_vector_iget( data2->report_last_index , i );
|
||||
@@ -1407,12 +1449,12 @@ bool ecl_sum_data_report_step_compatible( const ecl_sum_data_type * data1 , cons
|
||||
if ((time_index1 != INVALID_MINISTEP_NR) && (time_index2 != INVALID_MINISTEP_NR)) {
|
||||
const ecl_sum_tstep_type * ministep1 = ecl_sum_data_iget_ministep( data1 , time_index1 );
|
||||
const ecl_sum_tstep_type * ministep2 = ecl_sum_data_iget_ministep( data2 , time_index2 );
|
||||
|
||||
|
||||
if (!ecl_sum_tstep_sim_time_equal( ministep1 , ministep2)) {
|
||||
compatible = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return compatible;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
Copyright (C) 2014 Statoil ASA, Norway.
|
||||
|
||||
The file 'ecl_sum_vector.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <ert/ecl/ecl_sum_vector.h>
|
||||
#include <ert/ecl/ecl_sum.h>
|
||||
#include <ert/ecl/ecl_smspec.h>
|
||||
|
||||
#include <ert/util/util.h>
|
||||
#include <ert/util/vector.h>
|
||||
#include <ert/util/type_macros.h>
|
||||
#include <ert/util/int_vector.h>
|
||||
#include <ert/util/bool_vector.h>
|
||||
|
||||
|
||||
#define ECL_SUM_VECTOR_TYPE_ID 8756667078
|
||||
|
||||
struct ecl_sum_vector_struct {
|
||||
int_vector_type * node_index_list;
|
||||
bool_vector_type * is_rate_list;
|
||||
const ecl_sum_type * ecl_sum;
|
||||
};
|
||||
|
||||
void ecl_sum_vector_free( ecl_sum_vector_type * ecl_sum_vector ){
|
||||
int_vector_free(ecl_sum_vector->node_index_list);
|
||||
bool_vector_free(ecl_sum_vector->is_rate_list);
|
||||
}
|
||||
|
||||
ecl_sum_vector_type * ecl_sum_vector_alloc(const ecl_sum_type * ecl_sum){
|
||||
ecl_sum_vector_type * ecl_sum_vector = util_malloc( sizeof * ecl_sum_vector );
|
||||
ecl_sum_vector->ecl_sum = ecl_sum;
|
||||
ecl_sum_vector->node_index_list = int_vector_alloc(0,0);
|
||||
ecl_sum_vector->is_rate_list = bool_vector_alloc(0,false);
|
||||
return ecl_sum_vector;
|
||||
}
|
||||
|
||||
|
||||
bool ecl_sum_vector_add_key( ecl_sum_vector_type * ecl_sum_vector, const char * key){
|
||||
if (ecl_sum_has_general_var( ecl_sum_vector->ecl_sum , key)) {
|
||||
const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum_vector->ecl_sum , key );
|
||||
int params_index = smspec_node_get_params_index( node );
|
||||
bool is_rate_key = smspec_node_is_rate( node);
|
||||
|
||||
int_vector_append(ecl_sum_vector->node_index_list, params_index);
|
||||
bool_vector_append(ecl_sum_vector->is_rate_list, is_rate_key);
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ecl_sum_vector_add_keys( ecl_sum_vector_type * ecl_sum_vector, const char * pattern){
|
||||
stringlist_type * keylist = ecl_sum_alloc_matching_general_var_list(ecl_sum_vector->ecl_sum , pattern);
|
||||
|
||||
int num_keywords = stringlist_get_size(keylist);
|
||||
int i;
|
||||
for(i = 0; i < num_keywords ;i++){
|
||||
const char * key = stringlist_iget(keylist, i);
|
||||
const smspec_node_type * node = ecl_sum_get_general_var_node( ecl_sum_vector->ecl_sum , key );
|
||||
int params_index = smspec_node_get_params_index( node );
|
||||
bool is_rate_key = smspec_node_is_rate( node);
|
||||
|
||||
int_vector_append(ecl_sum_vector->node_index_list, params_index);
|
||||
bool_vector_append(ecl_sum_vector->is_rate_list, is_rate_key);
|
||||
}
|
||||
stringlist_free(keylist);
|
||||
}
|
||||
|
||||
int ecl_sum_vector_get_size(const ecl_sum_vector_type * ecl_sum_vector){
|
||||
return int_vector_size(ecl_sum_vector->node_index_list);
|
||||
}
|
||||
|
||||
bool ecl_sum_vector_iget_is_rate(const ecl_sum_vector_type * ecl_sum_vector, int index){
|
||||
return bool_vector_iget(ecl_sum_vector->is_rate_list, index);
|
||||
}
|
||||
|
||||
int ecl_sum_vector_iget_param_index(const ecl_sum_vector_type * ecl_sum_vector, int index){
|
||||
return int_vector_iget(ecl_sum_vector->node_index_list, index);
|
||||
}
|
||||
+29
-23
@@ -1206,12 +1206,12 @@ int ecl_util_get_month_nr(const char * month_name) {
|
||||
|
||||
|
||||
time_t ecl_util_get_start_date(const char * data_file) {
|
||||
parser_type * parser = parser_alloc(" \t\r\n" , "\"\'" , NULL , NULL , "--" , "\n");
|
||||
basic_parser_type * parser = basic_parser_alloc(" \t\r\n" , "\"\'" , NULL , NULL , "--" , "\n");
|
||||
time_t start_date = -1;
|
||||
FILE * stream = util_fopen(data_file , "r");
|
||||
char * buffer;
|
||||
|
||||
if (!parser_fseek_string( parser , stream , "START" , true , true)) /* Seeks case insensitive. */
|
||||
if (!basic_parser_fseek_string( parser , stream , "START" , true , true)) /* Seeks case insensitive. */
|
||||
util_abort("%s: sorry - could not find START in DATA file %s \n",__func__ , data_file);
|
||||
|
||||
{
|
||||
@@ -1219,7 +1219,7 @@ time_t ecl_util_get_start_date(const char * data_file) {
|
||||
int buffer_size;
|
||||
|
||||
/* Look for terminating '/' */
|
||||
if (!parser_fseek_string( parser , stream , "/" , false , true))
|
||||
if (!basic_parser_fseek_string( parser , stream , "/" , false , true))
|
||||
util_abort("%s: sorry - could not find \"/\" termination of START keyword in data_file: \n",__func__ , data_file);
|
||||
|
||||
buffer_size = (util_ftell(stream) - start_pos) ;
|
||||
@@ -1231,7 +1231,7 @@ time_t ecl_util_get_start_date(const char * data_file) {
|
||||
|
||||
|
||||
{
|
||||
stringlist_type * tokens = parser_tokenize_buffer( parser , buffer , true );
|
||||
stringlist_type * tokens = basic_parser_tokenize_buffer( parser , buffer , true );
|
||||
int day, year, month_nr;
|
||||
if ( util_sscanf_int( stringlist_iget( tokens , 0 ) , &day) && util_sscanf_int( stringlist_iget(tokens , 2) , &year)) {
|
||||
month_nr = ecl_util_get_month_nr(stringlist_iget( tokens , 1));
|
||||
@@ -1242,21 +1242,21 @@ time_t ecl_util_get_start_date(const char * data_file) {
|
||||
}
|
||||
|
||||
free( buffer );
|
||||
parser_free( parser );
|
||||
basic_parser_free( parser );
|
||||
fclose(stream);
|
||||
|
||||
return start_date;
|
||||
}
|
||||
|
||||
|
||||
static int ecl_util_get_num_parallel_cpu__(parser_type* parser, FILE* stream, const char * data_file) {
|
||||
static int ecl_util_get_num_parallel_cpu__(basic_parser_type* parser, FILE* stream, const char * data_file) {
|
||||
int num_cpu = 1;
|
||||
char * buffer;
|
||||
long int start_pos = util_ftell( stream );
|
||||
int buffer_size;
|
||||
|
||||
/* Look for terminating '/' */
|
||||
if (!parser_fseek_string( parser , stream , "/" , false , true))
|
||||
if (!basic_parser_fseek_string( parser , stream , "/" , false , true))
|
||||
util_abort("%s: sorry - could not find \"/\" termination of PARALLEL keyword in data_file: \n",__func__ , data_file);
|
||||
|
||||
buffer_size = (util_ftell(stream) - start_pos) ;
|
||||
@@ -1266,7 +1266,7 @@ static int ecl_util_get_num_parallel_cpu__(parser_type* parser, FILE* stream, co
|
||||
buffer[buffer_size] = '\0';
|
||||
|
||||
{
|
||||
stringlist_type * tokens = parser_tokenize_buffer( parser , buffer , true );
|
||||
stringlist_type * tokens = basic_parser_tokenize_buffer( parser , buffer , true );
|
||||
|
||||
if (stringlist_get_size( tokens ) > 0) {
|
||||
const char * num_cpu_string = stringlist_iget( tokens , 0 );
|
||||
@@ -1283,11 +1283,11 @@ static int ecl_util_get_num_parallel_cpu__(parser_type* parser, FILE* stream, co
|
||||
|
||||
|
||||
|
||||
static int ecl_util_get_num_slave_cpu__(parser_type* parser, FILE* stream, const char * data_file) {
|
||||
static int ecl_util_get_num_slave_cpu__(basic_parser_type* parser, FILE* stream, const char * data_file) {
|
||||
int num_cpu = 0;
|
||||
int linecount = 0;
|
||||
|
||||
parser_fseek_string( parser , stream , "\n" , true , true); /* Go to next line after the SLAVES keyword*/
|
||||
basic_parser_fseek_string( parser , stream , "\n" , true , true); /* Go to next line after the SLAVES keyword*/
|
||||
|
||||
while (true) {
|
||||
char * buffer = util_fscanf_alloc_line( stream , NULL);
|
||||
@@ -1296,7 +1296,7 @@ static int ecl_util_get_num_slave_cpu__(parser_type* parser, FILE* stream, const
|
||||
util_abort("%s: Did not find ending \"/\" character after SLAVES keyword, aborting \n", __func__);
|
||||
|
||||
{
|
||||
stringlist_type * tokens = parser_tokenize_buffer( parser , buffer , true );
|
||||
stringlist_type * tokens = basic_parser_tokenize_buffer( parser , buffer , true );
|
||||
if (stringlist_get_size(tokens) > 0 ) {
|
||||
|
||||
const char * first_item = stringlist_iget(tokens, 0);
|
||||
@@ -1322,34 +1322,34 @@ static int ecl_util_get_num_slave_cpu__(parser_type* parser, FILE* stream, const
|
||||
|
||||
int ecl_util_get_num_cpu(const char * data_file) {
|
||||
int num_cpu = 1;
|
||||
parser_type * parser = parser_alloc(" \t\r\n" , "\"\'" , NULL , NULL , "--" , "\n");
|
||||
basic_parser_type * parser = basic_parser_alloc(" \t\r\n" , "\"\'" , NULL , NULL , "--" , "\n");
|
||||
FILE * stream = util_fopen(data_file , "r");
|
||||
|
||||
if (parser_fseek_string( parser , stream , "PARALLEL" , true , true)) { /* Seeks case insensitive. */
|
||||
if (basic_parser_fseek_string( parser , stream , "PARALLEL" , true , true)) { /* Seeks case insensitive. */
|
||||
num_cpu = ecl_util_get_num_parallel_cpu__(parser, stream, data_file);
|
||||
} else if (parser_fseek_string( parser , stream , "SLAVES" , true , true)) { /* Seeks case insensitive. */
|
||||
} else if (basic_parser_fseek_string( parser , stream , "SLAVES" , true , true)) { /* Seeks case insensitive. */
|
||||
num_cpu = ecl_util_get_num_slave_cpu__(parser, stream, data_file) + 1;
|
||||
fprintf(stderr, "Information: \"SLAVES\" option found, returning %d number of CPUs", num_cpu);
|
||||
}
|
||||
|
||||
parser_free( parser );
|
||||
basic_parser_free( parser );
|
||||
fclose(stream);
|
||||
return num_cpu;
|
||||
}
|
||||
|
||||
|
||||
ecl_unit_enum ecl_util_get_unit_set(const char * data_file) {
|
||||
ecl_unit_enum units = ECL_METRIC_UNITS;
|
||||
parser_type * parser = parser_alloc(" \t\r\n" , "\"\'" , NULL , NULL , "--" , "\n");
|
||||
ert_ecl_unit_enum ecl_util_get_unit_set(const char * data_file) {
|
||||
ert_ecl_unit_enum units = ERT_ECL_METRIC_UNITS;
|
||||
basic_parser_type * parser = basic_parser_alloc(" \t\r\n" , "\"\'" , NULL , NULL , "--" , "\n");
|
||||
FILE * stream = util_fopen(data_file , "r");
|
||||
|
||||
if (parser_fseek_string( parser , stream , "FIELD" , true , true)) { /* Seeks case insensitive. */
|
||||
units = ECL_FIELD_UNITS;
|
||||
} else if (parser_fseek_string( parser , stream , "LAB" , true , true)) { /* Seeks case insensitive. */
|
||||
units = ECL_LAB_UNITS;
|
||||
if (basic_parser_fseek_string( parser , stream , "FIELD" , true , true)) { /* Seeks case insensitive. */
|
||||
units = ERT_ECL_FIELD_UNITS;
|
||||
} else if (basic_parser_fseek_string( parser , stream , "LAB" , true , true)) { /* Seeks case insensitive. */
|
||||
units = ERT_ECL_LAB_UNITS;
|
||||
}
|
||||
|
||||
parser_free( parser );
|
||||
basic_parser_free( parser );
|
||||
fclose(stream);
|
||||
return units;
|
||||
}
|
||||
@@ -1534,4 +1534,10 @@ const char * ecl_util_type_enum_iget( int index, int * value) {
|
||||
return util_enum_iget( index , ECL_TYPE_ENUM_SIZE , (const util_enum_element_type []) { ECL_TYPE_ENUM_DEFS }, value);
|
||||
}
|
||||
|
||||
void ecl_util_set_date_values(time_t t , int * mday , int * month , int * year) {
|
||||
return util_set_date_values(t,mday,month,year);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+205
-145
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'fortio.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
Copyright (C) 2011 Statoil ASA, Norway.
|
||||
|
||||
The file 'fortio.c' is part of ERT - Ensemble based Reservoir Tool.
|
||||
|
||||
ERT is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
for more details.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
@@ -51,7 +51,7 @@ Where the "400" head and tail is the number of bytes in the following
|
||||
record. Fortran IO handles this transparently, but when mixing with
|
||||
other programming languages care must be taken. This file implements
|
||||
functionality to read and write these fortran generated files
|
||||
transparently. The three functions:
|
||||
transparently. The three functions:
|
||||
|
||||
1. fortio_fopen()
|
||||
2. fortio_fread_record()
|
||||
@@ -65,47 +65,54 @@ fwrite() from the standard library.
|
||||
#define READ_MODE_TXT "r"
|
||||
#define READ_MODE_BINARY "rb"
|
||||
#define WRITE_MODE_TXT "w"
|
||||
#define WRITE_MODE_BINARY "wb"
|
||||
#define WRITE_MODE_BINARY "wb"
|
||||
#define READ_WRITE_MODE_TXT "r+"
|
||||
#define READ_WRITE_MODE_BINARY "r+b"
|
||||
#define APPEND_MODE_TXT "a"
|
||||
#define APPEND_MODE_BINARY "ab"
|
||||
#define APPEND_MODE_BINARY "ab"
|
||||
|
||||
|
||||
struct fortio_struct {
|
||||
UTIL_TYPE_ID_DECLARATION;
|
||||
FILE * stream;
|
||||
char * filename;
|
||||
bool endian_flip_header;
|
||||
bool endian_flip_header;
|
||||
bool fmt_file; /* This is not really used by the fortio instance - but it is very convenient to store it here. */
|
||||
const char * fopen_mode;
|
||||
bool stream_owner;
|
||||
|
||||
/* Internal variables used during partial read.*/
|
||||
int active_header;
|
||||
int rec_nr;
|
||||
|
||||
/*
|
||||
The internal variable read_size is used in the functions
|
||||
fortio_fseek() and fortio_read_at_eof() - if-and-only-if - the
|
||||
file is opened in read only mode.
|
||||
|
||||
Observe that the semantics of the fortio_fseek() function depends
|
||||
on whether the file is writable.
|
||||
*/
|
||||
bool readable;
|
||||
offset_type read_size;
|
||||
};
|
||||
|
||||
|
||||
UTIL_IS_INSTANCE_FUNCTION( fortio , FORTIO_ID );
|
||||
UTIL_SAFE_CAST_FUNCTION( fortio, FORTIO_ID );
|
||||
|
||||
static fortio_type * fortio_alloc__(const char *filename , bool fmt_file , bool endian_flip_header , bool stream_owner) {
|
||||
static fortio_type * fortio_alloc__(const char *filename , bool fmt_file , bool endian_flip_header , bool stream_owner , bool readable) {
|
||||
fortio_type * fortio = util_malloc(sizeof * fortio );
|
||||
UTIL_TYPE_ID_INIT( fortio, FORTIO_ID );
|
||||
fortio->filename = util_alloc_string_copy(filename);
|
||||
fortio->endian_flip_header = endian_flip_header;
|
||||
fortio->active_header = 0;
|
||||
fortio->rec_nr = 0;
|
||||
fortio->fmt_file = fmt_file;
|
||||
fortio->stream_owner = stream_owner;
|
||||
fortio->read_size = 0;
|
||||
fortio->readable = readable;
|
||||
return fortio;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Helper function for fortio_is_fortran_stream__().
|
||||
Helper function for fortio_is_fortran_stream__().
|
||||
*/
|
||||
|
||||
static bool __read_int(FILE * stream , int * value, bool endian_flip) {
|
||||
@@ -139,7 +146,7 @@ static bool fortio_is_fortran_stream__(FILE * stream , bool endian_flip) {
|
||||
if (util_fseek(stream , (offset_type) header , SEEK_CUR) == 0) {
|
||||
if (__read_int(stream , &tail , endian_flip)) {
|
||||
cont = true;
|
||||
/*
|
||||
/*
|
||||
OK - now we have read a header and a tail - it might be
|
||||
a fortran file.
|
||||
*/
|
||||
@@ -148,7 +155,7 @@ static bool fortio_is_fortran_stream__(FILE * stream , bool endian_flip) {
|
||||
/* This is (most probably) a fortran file */
|
||||
is_fortran_stream = true;
|
||||
if (strict_checking)
|
||||
cont = true;
|
||||
cont = true;
|
||||
else
|
||||
cont = false;
|
||||
}
|
||||
@@ -160,7 +167,7 @@ static bool fortio_is_fortran_stream__(FILE * stream , bool endian_flip) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (cont);
|
||||
util_fseek(stream , init_pos , SEEK_SET);
|
||||
@@ -170,68 +177,41 @@ static bool fortio_is_fortran_stream__(FILE * stream , bool endian_flip) {
|
||||
|
||||
/**
|
||||
This function tries (using some heuristic) to guess whether a
|
||||
particular file is a Fortran file. To complicate the matters
|
||||
further we make no assumptions regarding endian ness, if it is
|
||||
indeed determined that this is fortran file, the endian ness is
|
||||
returned by reference (if it is not recognized as a fortran file,
|
||||
the returned endian ness will be garbage).
|
||||
particular file is a Fortran file.
|
||||
|
||||
The heuristic algorithm which is used is as follows:
|
||||
|
||||
|
||||
1. Read four bytes as an integer (header)
|
||||
2. Skip that number of bytes forward.
|
||||
3. Read four bytes again (tail).
|
||||
|
||||
Now, when this is done we do the following tests:
|
||||
Now, when this is done we do the following test:
|
||||
|
||||
1. If header == tail. This is (probably) a fortran file, however
|
||||
if header == 0, we might have a normal file with two
|
||||
consequitive zeroes. In that case it is difficult to determine,
|
||||
and we continue.
|
||||
If header == tail. This is (probably) a fortran file, however if
|
||||
header == 0, we might have a normal file with two consequitive
|
||||
zeroes. In that case it is difficult to determine, and we continue.
|
||||
|
||||
2. If header != tail we try to reinterpret header with an endian
|
||||
swap and read a new tail. If they are now equal we repeat test1, or
|
||||
return false (i.e. *not* a fortran file).
|
||||
*/
|
||||
|
||||
bool fortio_is_fortran_file(const char * filename, bool * _endian_flip) {
|
||||
bool fortio_looks_like_fortran_file(const char * filename, bool endian_flip) {
|
||||
FILE * stream = util_fopen(filename , "rb");
|
||||
bool endian_flip = false;
|
||||
bool is_fortran_stream = fortio_is_fortran_stream__(stream , endian_flip);
|
||||
if (!is_fortran_stream) {
|
||||
endian_flip = !endian_flip;
|
||||
is_fortran_stream = fortio_is_fortran_stream__(stream , endian_flip);
|
||||
}
|
||||
|
||||
*_endian_flip = endian_flip;
|
||||
fclose(stream);
|
||||
return is_fortran_stream;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function tries to determine automatically whether a certain
|
||||
file has endian flip or not.
|
||||
|
||||
Observe that the return value is whether we managed to determine the
|
||||
endian-ness or not, whereas the endian_flip flag is returned by
|
||||
reference.
|
||||
|
||||
To be able to determine endianness the file *must* be a binary
|
||||
fortran file - this is essentially the return value.
|
||||
*/
|
||||
|
||||
bool fortio_guess_endian_flip(const char * filename , bool * _endian_flip) {
|
||||
return fortio_is_fortran_file(filename , _endian_flip);
|
||||
static void fortio_init_size(fortio_type * fortio) {
|
||||
fortio->read_size = util_fd_size( fortio_fileno( fortio ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
fortio_type * fortio_alloc_FILE_wrapper(const char *filename , bool endian_flip_header , bool fmt_file , FILE * stream) {
|
||||
fortio_type * fortio = fortio_alloc__(filename , fmt_file , endian_flip_header , false);
|
||||
fortio_type * fortio_alloc_FILE_wrapper(const char *filename , bool endian_flip_header , bool fmt_file , bool readable , FILE * stream) {
|
||||
fortio_type * fortio = fortio_alloc__(filename , fmt_file , endian_flip_header , false , readable);
|
||||
fortio->stream = stream;
|
||||
fortio_init_size( fortio );
|
||||
return fortio;
|
||||
}
|
||||
|
||||
@@ -312,9 +292,10 @@ static FILE * fortio_fopen_append( const char * filename , bool fmt_file ) {
|
||||
fortio_type * fortio_open_reader(const char *filename , bool fmt_file , bool endian_flip_header) {
|
||||
FILE * stream = fortio_fopen_read( filename , fmt_file );
|
||||
if (stream) {
|
||||
fortio_type *fortio = fortio_alloc__(filename , fmt_file , endian_flip_header , true);
|
||||
fortio_type *fortio = fortio_alloc__(filename , fmt_file , endian_flip_header , true , true);
|
||||
fortio->stream = stream;
|
||||
fortio->fopen_mode = fortio_fopen_read_mode( fmt_file );
|
||||
fortio_init_size( fortio );
|
||||
return fortio;
|
||||
} else
|
||||
return NULL;
|
||||
@@ -326,9 +307,10 @@ fortio_type * fortio_open_reader(const char *filename , bool fmt_file , bool end
|
||||
fortio_type * fortio_open_writer(const char *filename , bool fmt_file , bool endian_flip_header ) {
|
||||
FILE * stream = fortio_fopen_write( filename , fmt_file );
|
||||
if (stream) {
|
||||
fortio_type *fortio = fortio_alloc__(filename , fmt_file , endian_flip_header, true);
|
||||
fortio_type *fortio = fortio_alloc__(filename , fmt_file , endian_flip_header, true , false);
|
||||
fortio->stream = stream;
|
||||
fortio->fopen_mode = fortio_fopen_write_mode( fmt_file );
|
||||
fortio_init_size( fortio );
|
||||
return fortio;
|
||||
} else
|
||||
return NULL;
|
||||
@@ -339,9 +321,10 @@ fortio_type * fortio_open_writer(const char *filename , bool fmt_file , bool end
|
||||
fortio_type * fortio_open_readwrite(const char *filename , bool fmt_file , bool endian_flip_header) {
|
||||
FILE * stream = fortio_fopen_readwrite( filename , fmt_file );
|
||||
if (stream) {
|
||||
fortio_type *fortio = fortio_alloc__(filename , fmt_file , endian_flip_header , true);
|
||||
fortio_type *fortio = fortio_alloc__(filename , fmt_file , endian_flip_header , true , true);
|
||||
fortio->stream = stream;
|
||||
fortio->fopen_mode = fortio_fopen_readwrite_mode( fmt_file );
|
||||
fortio_init_size( fortio );
|
||||
return fortio;
|
||||
} else
|
||||
return NULL;
|
||||
@@ -351,9 +334,12 @@ fortio_type * fortio_open_readwrite(const char *filename , bool fmt_file , bool
|
||||
fortio_type * fortio_open_append(const char *filename , bool fmt_file , bool endian_flip_header) {
|
||||
FILE * stream = fortio_fopen_append( filename , fmt_file );
|
||||
if (stream) {
|
||||
fortio_type *fortio = fortio_alloc__(filename , fmt_file , endian_flip_header , true);
|
||||
fortio_type *fortio = fortio_alloc__(filename , fmt_file , endian_flip_header , true , false);
|
||||
|
||||
fortio->stream = stream;
|
||||
fortio->fopen_mode = fortio_fopen_append_mode( fmt_file );
|
||||
fortio_init_size( fortio );
|
||||
|
||||
return fortio;
|
||||
} else
|
||||
return NULL;
|
||||
@@ -433,22 +419,23 @@ bool fortio_is_fortio_file(fortio_type * fortio) {
|
||||
offset_type init_pos = fortio_ftell(fortio);
|
||||
int elm_read;
|
||||
bool is_fortio_file = false;
|
||||
elm_read = fread(&fortio->active_header , sizeof(fortio->active_header) , 1 , fortio->stream);
|
||||
int record_size;
|
||||
elm_read = fread(&record_size , sizeof(record_size) , 1 , fortio->stream);
|
||||
if (elm_read == 1) {
|
||||
int trailer;
|
||||
|
||||
if (fortio->endian_flip_header)
|
||||
util_endian_flip_vector(&fortio->active_header , sizeof fortio->active_header , 1);
|
||||
util_endian_flip_vector(&record_size , sizeof record_size , 1);
|
||||
|
||||
if (fortio_fseek(fortio , (offset_type) fortio->active_header , SEEK_CUR) == 0) {
|
||||
if (fread(&trailer , sizeof(fortio->active_header) , 1 , fortio->stream) == 1) {
|
||||
if (fortio_fseek(fortio , (offset_type) record_size , SEEK_CUR) == 0) {
|
||||
if (fread(&trailer , sizeof(record_size) , 1 , fortio->stream) == 1) {
|
||||
if (fortio->endian_flip_header)
|
||||
util_endian_flip_vector(&trailer , sizeof trailer , 1);
|
||||
|
||||
if (trailer == fortio->active_header)
|
||||
|
||||
if (trailer == record_size)
|
||||
is_fortio_file = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fortio_fseek(fortio , init_pos , SEEK_SET);
|
||||
@@ -465,24 +452,25 @@ bool fortio_is_fortio_file(fortio_type * fortio) {
|
||||
|
||||
int fortio_init_read(fortio_type *fortio) {
|
||||
int elm_read;
|
||||
elm_read = fread(&fortio->active_header , sizeof(fortio->active_header) , 1 , fortio->stream);
|
||||
int record_size;
|
||||
|
||||
elm_read = fread(&record_size , sizeof(record_size) , 1 , fortio->stream);
|
||||
if (elm_read == 1) {
|
||||
if (fortio->endian_flip_header)
|
||||
util_endian_flip_vector(&fortio->active_header , sizeof fortio->active_header , 1);
|
||||
util_endian_flip_vector(&record_size , sizeof record_size , 1);
|
||||
|
||||
fortio->rec_nr++;
|
||||
return fortio->active_header;
|
||||
} else
|
||||
return record_size;
|
||||
} else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void fortio_data_fskip(fortio_type* fortio, const int element_size, const int element_count, const int block_count) {
|
||||
int headers = block_count * 4;
|
||||
int trailers = block_count * 4;
|
||||
int bytes_to_skip = headers + trailers + (element_size * element_count);
|
||||
bool fortio_data_fskip(fortio_type* fortio, const int element_size, const int element_count, const int block_count) {
|
||||
int headers = block_count * 4;
|
||||
int trailers = block_count * 4;
|
||||
int bytes_to_skip = headers + trailers + (element_size * element_count);
|
||||
|
||||
fortio_fseek(fortio, bytes_to_skip, SEEK_CUR);
|
||||
return fortio_fseek(fortio, bytes_to_skip, SEEK_CUR);
|
||||
}
|
||||
|
||||
|
||||
@@ -501,34 +489,40 @@ void fortio_data_fseek(fortio_type* fortio, offset_type data_offset, size_t data
|
||||
}
|
||||
|
||||
|
||||
void fortio_complete_read(fortio_type *fortio) {
|
||||
bool fortio_complete_read(fortio_type *fortio , int record_size) {
|
||||
int trailer;
|
||||
trailer = util_fread_int( fortio->stream );
|
||||
|
||||
if (fortio->endian_flip_header)
|
||||
util_endian_flip_vector(&trailer , sizeof trailer , 1);
|
||||
|
||||
if (trailer != fortio->active_header) {
|
||||
fprintf(stderr,"%s: fatal error reading record:%d in file: %s - aborting \n",__func__ , fortio->rec_nr , fortio->filename);
|
||||
util_abort("%s: Header: %d Trailer: %d \n",__func__ , fortio->active_header , trailer);
|
||||
size_t read_count = fread(&trailer , sizeof trailer , 1 , fortio->stream );
|
||||
|
||||
if (read_count == 1) {
|
||||
if (fortio->endian_flip_header)
|
||||
util_endian_flip_vector(&trailer , sizeof trailer , 1);
|
||||
|
||||
if (record_size == trailer)
|
||||
return true;
|
||||
}
|
||||
fortio->active_header = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function reads one record from the fortio stream, and fills
|
||||
the buffer with the content. The return value is the number of bytes read.
|
||||
the buffer with the content. The return value is the number of
|
||||
bytes read; the function will return -1 on failure.
|
||||
*/
|
||||
|
||||
int fortio_fread_record(fortio_type *fortio, char *buffer) {
|
||||
fortio_init_read(fortio);
|
||||
{
|
||||
int record_size = fortio->active_header; /* This is reset in fortio_complete_read - must store it for the return. */
|
||||
util_fread(buffer , 1 , fortio->active_header , fortio->stream , __func__);
|
||||
fortio_complete_read(fortio);
|
||||
return record_size;
|
||||
static int fortio_fread_record(fortio_type *fortio , char *buffer) {
|
||||
int record_size = fortio_init_read(fortio);
|
||||
if (record_size >= 0) {
|
||||
size_t items_read = fread(buffer , 1 , record_size , fortio->stream);
|
||||
if (items_read == record_size) {
|
||||
bool complete_ok = fortio_complete_read(fortio , record_size);
|
||||
if (!complete_ok)
|
||||
record_size = -1;
|
||||
} else
|
||||
record_size = -1; /* Failure */
|
||||
}
|
||||
return record_size;
|
||||
}
|
||||
|
||||
|
||||
@@ -541,38 +535,53 @@ int fortio_fread_record(fortio_type *fortio, char *buffer) {
|
||||
transparent, low-level way.
|
||||
*/
|
||||
|
||||
void fortio_fread_buffer(fortio_type * fortio, char * buffer , int buffer_size) {
|
||||
int bytes_read = 0;
|
||||
while (bytes_read < buffer_size) {
|
||||
char * buffer_ptr = &buffer[bytes_read];
|
||||
bytes_read += fortio_fread_record(fortio , buffer_ptr);
|
||||
bool fortio_fread_buffer(fortio_type * fortio, char * buffer , int buffer_size) {
|
||||
int total_bytes_read = 0;
|
||||
|
||||
while (true) {
|
||||
char * buffer_ptr = &buffer[total_bytes_read];
|
||||
int bytes_read = fortio_fread_record(fortio , buffer_ptr);
|
||||
|
||||
if (bytes_read < 0)
|
||||
break;
|
||||
else {
|
||||
total_bytes_read += bytes_read;
|
||||
if (total_bytes_read >= buffer_size)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bytes_read > buffer_size)
|
||||
util_abort("%s: hmmmm - something is broken. The individual records in %s did not sum up to the expected buffer size \n",__func__ , fortio->filename);
|
||||
if (total_bytes_read == buffer_size)
|
||||
return true;
|
||||
|
||||
if (total_bytes_read < buffer_size)
|
||||
return false;
|
||||
|
||||
util_abort("%s: internal inconsistency: buffer_size:%d read %d bytes \n",__func__ , buffer_size , total_bytes_read);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int fortio_fskip_record(fortio_type *fortio) {
|
||||
int record_size = fortio_init_read(fortio);
|
||||
fortio_fseek(fortio , (offset_type) record_size , SEEK_CUR);
|
||||
fortio_complete_read(fortio);
|
||||
fortio_complete_read(fortio , record_size);
|
||||
return record_size;
|
||||
}
|
||||
|
||||
void fortio_fskip_buffer(fortio_type * fortio, int buffer_size) {
|
||||
int bytes_skipped = 0;
|
||||
while (bytes_skipped < buffer_size)
|
||||
while (bytes_skipped < buffer_size)
|
||||
bytes_skipped += fortio_fskip_record(fortio);
|
||||
|
||||
if (bytes_skipped > buffer_size)
|
||||
if (bytes_skipped > buffer_size)
|
||||
util_abort("%s: hmmmm - something is broken. The individual records in %s did not sum up to the expected buffer size \n",__func__ , fortio->filename);
|
||||
}
|
||||
|
||||
|
||||
void fortio_copy_record(fortio_type * src_stream , fortio_type * target_stream , int buffer_size , void * buffer , bool *at_eof) {
|
||||
int bytes_read;
|
||||
int record_size = fortio_init_read(src_stream);
|
||||
int record_size = fortio_init_read(src_stream);
|
||||
fortio_init_write(target_stream , record_size);
|
||||
|
||||
bytes_read = 0;
|
||||
@@ -585,12 +594,12 @@ void fortio_copy_record(fortio_type * src_stream , fortio_type * target_stream ,
|
||||
|
||||
util_fread(buffer , 1 , bytes , src_stream->stream , __func__);
|
||||
util_fwrite(buffer , 1 , bytes , target_stream->stream , __func__);
|
||||
|
||||
|
||||
bytes_read += bytes;
|
||||
}
|
||||
|
||||
fortio_complete_read(src_stream);
|
||||
fortio_complete_write(target_stream);
|
||||
fortio_complete_read(src_stream , record_size);
|
||||
fortio_complete_write(target_stream , record_size);
|
||||
|
||||
if (feof(src_stream->stream))
|
||||
*at_eof = true;
|
||||
@@ -603,38 +612,35 @@ void fortio_copy_record(fortio_type * src_stream , fortio_type * target_stream ,
|
||||
|
||||
void fortio_init_write(fortio_type *fortio , int record_size) {
|
||||
int file_header;
|
||||
fortio->active_header = record_size;
|
||||
file_header = fortio->active_header;
|
||||
file_header = record_size;
|
||||
if (fortio->endian_flip_header)
|
||||
util_endian_flip_vector(&file_header , sizeof file_header , 1);
|
||||
|
||||
util_fwrite_int( file_header , fortio->stream );
|
||||
fortio->rec_nr++;
|
||||
}
|
||||
|
||||
void fortio_complete_write(fortio_type *fortio) {
|
||||
int file_header = fortio->active_header;
|
||||
void fortio_complete_write(fortio_type *fortio , int record_size) {
|
||||
int file_header = record_size;
|
||||
if (fortio->endian_flip_header)
|
||||
util_endian_flip_vector(&file_header , sizeof file_header , 1);
|
||||
|
||||
util_fwrite_int( file_header , fortio->stream );
|
||||
fortio->active_header = 0;
|
||||
}
|
||||
|
||||
|
||||
void fortio_fwrite_record(fortio_type *fortio, const char *buffer , int record_size) {
|
||||
fortio_init_write(fortio , record_size);
|
||||
util_fwrite( buffer , 1 , record_size , fortio->stream , __func__);
|
||||
fortio_complete_write(fortio);
|
||||
fortio_complete_write(fortio , record_size);
|
||||
}
|
||||
|
||||
|
||||
void * fortio_fread_alloc_record(fortio_type * fortio) {
|
||||
void * buffer;
|
||||
fortio_init_read(fortio);
|
||||
buffer = util_malloc(fortio->active_header );
|
||||
util_fread(buffer , 1 , fortio->active_header , fortio->stream , __func__);
|
||||
fortio_complete_read(fortio);
|
||||
int record_size = fortio_init_read(fortio);
|
||||
buffer = util_malloc( record_size );
|
||||
util_fread(buffer , 1 , record_size , fortio->stream , __func__);
|
||||
fortio_complete_read(fortio , record_size);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -651,8 +657,8 @@ static fortio_status_type fortio_check_record( FILE * stream , bool endian_flip
|
||||
else {
|
||||
if (endian_flip)
|
||||
util_endian_flip_vector(&header , sizeof header , 1);
|
||||
|
||||
if (util_fseek( stream , (offset_type) header , SEEK_CUR ) != 0)
|
||||
|
||||
if (util_fseek( stream , (offset_type) header , SEEK_CUR ) != 0)
|
||||
/* The fseek() failed - i.e. the data section was not sufficiently long. */
|
||||
status = FORTIO_MISSING_DATA;
|
||||
else {
|
||||
@@ -660,14 +666,14 @@ static fortio_status_type fortio_check_record( FILE * stream , bool endian_flip
|
||||
if (read_count == 1) {
|
||||
if (endian_flip)
|
||||
util_endian_flip_vector(&tail , sizeof tail , 1);
|
||||
|
||||
|
||||
if (tail == header)
|
||||
/* All OK */
|
||||
status = FORTIO_OK;
|
||||
else if ( tail != header )
|
||||
else if ( tail != header )
|
||||
/* The numerical value of the tail did not agree with the header. */
|
||||
status = FORTIO_HEADER_MISMATCH;
|
||||
} else
|
||||
} else
|
||||
/* The file ended before we could read the tail mark. */
|
||||
status = FORTIO_MISSING_TAIL;
|
||||
}
|
||||
@@ -698,7 +704,7 @@ fortio_status_type fortio_check_buffer( FILE * stream , bool endian_flip , size_
|
||||
return record_status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
fortio_status_type fortio_check_file( const char * filename , bool endian_flip) {
|
||||
if (util_file_exists( filename )) {
|
||||
@@ -730,12 +736,52 @@ offset_type fortio_ftell( const fortio_type * fortio ) {
|
||||
}
|
||||
|
||||
|
||||
int fortio_fseek( fortio_type * fortio , offset_type offset , int whence) {
|
||||
static bool fortio_fseek__(fortio_type * fortio , offset_type offset , int whence) {
|
||||
int fseek_return = util_fseek( fortio->stream , offset , whence );
|
||||
/*
|
||||
if fseek_return != 0 -> util_abort().
|
||||
*/
|
||||
return fseek_return;
|
||||
if (fseek_return == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
The semantics of this function depends on the readbale flag of the
|
||||
fortio structure:
|
||||
|
||||
readable == false: Ordinary fseek() semantics.
|
||||
|
||||
readable == true: The function will only seek within the range of
|
||||
the file, and fail if you try to seek beyond the EOF marker.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
bool fortio_fseek( fortio_type * fortio , offset_type offset , int whence) {
|
||||
if (!fortio->readable)
|
||||
return fortio_fseek__( fortio , offset , whence );
|
||||
else {
|
||||
offset_type new_offset = 0;
|
||||
|
||||
switch (whence) {
|
||||
case( SEEK_CUR ):
|
||||
new_offset = fortio_ftell( fortio ) + offset;
|
||||
break;
|
||||
case (SEEK_END):
|
||||
new_offset = fortio->read_size + offset;
|
||||
break;
|
||||
case (SEEK_SET):
|
||||
new_offset = offset;
|
||||
break;
|
||||
default:
|
||||
util_abort("%s: invalid seek flag \n",__func__);
|
||||
}
|
||||
|
||||
if (new_offset <= fortio->read_size)
|
||||
return fortio_fseek__( fortio , new_offset , SEEK_SET );
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -744,11 +790,25 @@ int fortio_fileno( fortio_type * fortio ) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
It is massively undefined behaviour to call this function for a file
|
||||
which has been updated; in that case the util_fd_size() function
|
||||
will return the size of the file *when it was opened*.
|
||||
*/
|
||||
|
||||
bool fortio_read_at_eof( fortio_type * fortio ) {
|
||||
|
||||
if (fortio_ftell(fortio) == fortio->read_size)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************/
|
||||
void fortio_fflush(fortio_type * fortio) { fflush( fortio->stream); }
|
||||
FILE * fortio_get_FILE(const fortio_type *fortio) { return fortio->stream; }
|
||||
int fortio_get_record_size(const fortio_type *fortio) { return fortio->active_header; }
|
||||
//bool fortio_endian_flip(const fortio_type *fortio) { return fortio->endian_flip_header; }
|
||||
bool fortio_fmt_file(const fortio_type *fortio) { return fortio->fmt_file; }
|
||||
void fortio_rewind(const fortio_type *fortio) { util_rewind(fortio->stream); }
|
||||
|
||||
+7
-7
@@ -447,8 +447,8 @@ static void smspec_node_set_gen_keys( smspec_node_type * smspec_node , const cha
|
||||
switch( smspec_node->var_type) {
|
||||
case(ECL_SMSPEC_COMPLETION_VAR):
|
||||
// KEYWORD:WGNAME:NUM
|
||||
smspec_node->gen_key1 = smspec_alloc_completion_num_key( key_join_string , smspec_node->keyword , smspec_node->wgname , smspec_node->num);
|
||||
smspec_node->gen_key2 = smspec_alloc_completion_ijk_key( key_join_string , smspec_node->keyword , smspec_node->wgname , smspec_node->ijk[0], smspec_node->ijk[1], smspec_node->ijk[2]);
|
||||
smspec_node->gen_key1 = smspec_alloc_completion_ijk_key( key_join_string , smspec_node->keyword , smspec_node->wgname , smspec_node->ijk[0], smspec_node->ijk[1], smspec_node->ijk[2]);
|
||||
smspec_node->gen_key2 = smspec_alloc_completion_num_key( key_join_string , smspec_node->keyword , smspec_node->wgname , smspec_node->num);
|
||||
break;
|
||||
case(ECL_SMSPEC_FIELD_VAR):
|
||||
// KEYWORD
|
||||
@@ -472,12 +472,12 @@ static void smspec_node_set_gen_keys( smspec_node_type * smspec_node , const cha
|
||||
break;
|
||||
case(ECL_SMSPEC_REGION_2_REGION_VAR):
|
||||
// KEYWORDS:RXF:NUM and RXF:R1-R2
|
||||
smspec_node->gen_key1 = smspec_alloc_region_2_region_num_key( key_join_string , smspec_node->keyword , smspec_node->num);
|
||||
{
|
||||
int r1 = smspec_node->num % 32768;
|
||||
int r2 = ((smspec_node->num-r1) / 32768)-10;
|
||||
smspec_node->gen_key2 = smspec_alloc_region_2_region_r1r2_key( key_join_string , smspec_node->keyword , r1, r2);
|
||||
smspec_node->gen_key1 = smspec_alloc_region_2_region_r1r2_key( key_join_string , smspec_node->keyword , r1, r2);
|
||||
}
|
||||
smspec_node->gen_key2 = smspec_alloc_region_2_region_num_key( key_join_string , smspec_node->keyword , smspec_node->num);
|
||||
break;
|
||||
case(ECL_SMSPEC_MISC_VAR):
|
||||
// KEYWORD
|
||||
@@ -486,8 +486,8 @@ static void smspec_node_set_gen_keys( smspec_node_type * smspec_node , const cha
|
||||
break;
|
||||
case(ECL_SMSPEC_BLOCK_VAR):
|
||||
// KEYWORD:NUM
|
||||
smspec_node->gen_key1 = smspec_alloc_block_num_key( key_join_string , smspec_node->keyword , smspec_node->num);
|
||||
smspec_node->gen_key2 = smspec_alloc_block_ijk_key( key_join_string , smspec_node->keyword , smspec_node->ijk[0], smspec_node->ijk[1], smspec_node->ijk[2]);
|
||||
smspec_node->gen_key1 = smspec_alloc_block_ijk_key( key_join_string , smspec_node->keyword , smspec_node->ijk[0], smspec_node->ijk[1], smspec_node->ijk[2]);
|
||||
smspec_node->gen_key2 = smspec_alloc_block_num_key( key_join_string , smspec_node->keyword , smspec_node->num);
|
||||
break;
|
||||
case(ECL_SMSPEC_LOCAL_WELL_VAR):
|
||||
/** KEYWORD:LGR:WGNAME */
|
||||
@@ -733,7 +733,7 @@ smspec_node_type * smspec_node_alloc_lgr( ecl_smspec_var_type var_type ,
|
||||
int param_index , float default_value) {
|
||||
|
||||
smspec_node_type * smspec_node = smspec_node_alloc_new( param_index , default_value );
|
||||
if (smspec_node_init_lgr( smspec_node , var_type , wgname , keyword , lgr , unit , key_join_string , lgr_i, lgr_j , lgr_k))
|
||||
if (smspec_node_init_lgr( smspec_node , var_type , wgname , keyword , unit , lgr , key_join_string , lgr_i, lgr_j , lgr_k))
|
||||
return smspec_node;
|
||||
else {
|
||||
smspec_node_free( smspec_node );
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user