Updated ERT to 946e512ac17c1e2469892072a925428c0a012fa1

This commit is contained in:
Magne Sjaastad 2014-10-09 20:13:04 +02:00
parent a8ce90e404
commit b93053b089
1188 changed files with 49680 additions and 11622 deletions

View File

@ -152,7 +152,7 @@ bool transferGridCellData(RigMainGrid* mainGrid, RigActiveCellInfo* activeCellIn
for (cIdx = 0; cIdx < 8; ++cIdx)
{
double * point = mainGrid->nodes()[nodeStartIndex + gridLocalCellIndex * 8 + cellMappingECLRi[cIdx]].ptr();
ecl_grid_get_corner_xyz1(localEclGrid, gridLocalCellIndex, cIdx, &(point[0]), &(point[1]), &(point[2]));
ecl_grid_get_cell_corner_xyz1(localEclGrid, gridLocalCellIndex, cIdx, &(point[0]), &(point[1]), &(point[2]));
point[2] = -point[2]; // Flipping Z making depth become negative z values
cell.cornerIndices()[cIdx] = nodeStartIndex + gridLocalCellIndex*8 + cIdx;
}

View File

@ -1,8 +1,14 @@
cmake_minimum_required( VERSION 2.8 )
project( ERT C CXX )
if(POLICY CMP0042)
cmake_policy(SET CMP0042 OLD)
endif()
set( ERT_VERSION_MAJOR 1 )
set( ERT_VERSION_MINOR 0 )
set( ERT_VERSION_MINOR 7 )
set( ERT_VERSION_MICRO X )
option( BUILD_ERT "Build the full ERT application - Linux only" OFF)
option( BUILD_ENS_PLOT "Build small Eclipse plotting program - no" OFF)
@ -14,6 +20,8 @@ option( BUILD_SHARED_LIBS "Build shared libraries" ON )
option( INSTALL_ERT "Should anything be installed when issuing make install?" ON)
option( ERT_BUILD_GUI "Should the pyQt based gui be compiled and installed" OFF )
option( ERT_USE_OPENMP "Use OpenMP - currently only in EclGrid" OFF)
option( ERT_DOC "Build ERT documantation" OFF)
include( CheckFunctionExists )
include( CheckTypeSize )
@ -22,6 +30,10 @@ ENABLE_TESTING()
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(ERT_LINUX TRUE )
add_definitions( -DERT_LINUX )
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(ERT_LINUX TRUE )
set(ERT_MAC TRUE)
add_definitions( -DERT_LINUX )
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
set(ERT_WINDOWS TRUE)
add_definitions( -DERT_WINDOWS )
@ -29,16 +41,29 @@ elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
add_definitions( -DWINDOWS_LFS )
endif()
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.")
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"MinSizeRel" "RelWithDebInfo")
endif()
# Treat warnings as errors if not on Windows
if (ERT_WINDOWS)
set( CMAKE_C_FLAGS "-O2" )
set( CMAKE_CXX_FLAGS "-O2" )
else()
set( CMAKE_C_FLAGS "-std=gnu99 -g -O2 -Wall -Wno-unknown-pragmas " )
set( CMAKE_CXX_FLAGS "-g -Wall -O2 ")
if (NOT ERT_WINDOWS)
set( CMAKE_C_FLAGS "-std=gnu99 -Wall -Wno-unknown-pragmas ")
set( CMAKE_CXX_FLAGS "-Wall " )
endif()
if (MSVC)
add_definitions( "/W3 /D_CRT_SECURE_NO_WARNINGS /wd4996" )
add_definitions( -DCOMPILER_MSVC )
elseif (CMAKE_COMPILER_IS_GNUCC)
add_definitions( -DCOMPILER_GCC )
endif()
if (ERT_USE_OPENMP)
find_package(OpenMP)
if (OPENMP_FOUND)
@ -118,6 +143,8 @@ add_subdirectory( libecl_well )
#-----------------------------------------------------------------
if (BUILD_ERT)
#-----------------------------------------------------------------
include(cmake/ert_module_name.cmake)
include_directories( ${PROJECT_SOURCE_DIR}/libconfig/include )
add_subdirectory( libconfig )
@ -143,5 +170,8 @@ endif()
if (BUILD_PYTHON)
include(cmake/python.cmake2)
add_subdirectory( python )
if(ERT_DOC)
add_subdirectory( docs )
endif()
endif()

View File

@ -1,6 +1,8 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <time.h>
#include <stdlib.h>
int main(int argc, char ** argv) {
struct tm ts;

View File

@ -13,6 +13,12 @@ if (HAVE_REALPATH)
add_definitions( -DHAVE_REALPATH )
endif()
check_function_exists( chmod HAVE_CHMOD )
check_type_size( mode_t SIZE_MODE_T )
if (HAVE_CHMOD AND HAVE_SIZE_MODE_T)
add_definitions( -DHAVE_CHMOD_AND_MODE_T )
endif()
check_function_exists( fork HAVE_FORK )
if (HAVE_FORK)
add_definitions( -DHAVE_FORK )
@ -143,8 +149,10 @@ 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 )
if (RUN_RESULT)
add_defintions( -DTIME_T_64BIT_ACCEPT_PRE1970 )
if (${COMPILE_RESULT})
if (${RUN_RESULT} EQUAL 0)
add_definitions( -DTIME_T_64BIT_ACCEPT_PRE1970 )
endif()
endif()
endif()

View File

@ -1,5 +1,5 @@
if (CMAKE_COMPILER_IS_GNUCC)
option (USE_RUNPATH "Embed original dependency paths in installed library" OFF)
option (USE_RUNPATH "Embed original dependency paths in installed library" ON)
if (USE_RUNPATH)
set (CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
set (CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
@ -10,5 +10,7 @@ endif()
macro( add_runpath target )
set_target_properties( ${target} PROPERTIES LINK_FLAGS -Wl,--enable-new-dtags)
if(NOT ERT_MAC)
set_target_properties( ${target} PROPERTIES LINK_FLAGS -Wl,--enable-new-dtags)
endif()
endmacro()

View File

@ -0,0 +1,17 @@
function( ert_module_name module module_name lib_path )
set( osx_file ${lib_path}/${module_name}.dylib )
set( linux_file ${lib_path}/${module_name}.so )
set( win_file ${lib_path}/${module_name}.dll )
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set( ${module} ${linux_file} PARENT_SCOPE)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set( ${module} ${osx_file} PARENT_SCOPE)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
set( ${module} ${win_file} PARENT_SCOPE)
else()
message( FATAL_ERROR "Hmmm - which platform is this ??")
endif()
endfunction()

View File

@ -0,0 +1,11 @@
set( ERT_DOC_INSTALL_PATH "" CACHE PATH "Absolute path to install documentation *in addition* to $PREFIX/documentation")
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 )
INSTALL( DIRECTORY ${PROJECT_BINARY_DIR}/tmp_doc/_build/ DESTINATION ${CMAKE_INSTALL_PREFIX}/documentation )
if (ERT_DOC_INSTALL_PATH)
INSTALL( DIRECTORY ${PROJECT_BINARY_DIR}/tmp_doc/_build/ DESTINATION ${ERT_DOC_INSTALL_PATH} )
endif()

View File

@ -0,0 +1,6 @@
First page in the static ert's documentation!
===============================
Contents:
This is where we need to write the "manual" documentation

View File

@ -0,0 +1,6 @@
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/)
execute_process(COMMAND sphinx-build -b html -d _build/doctrees . _build WORKING_DIRECTORY ${pbd}/tmp_doc/)

332
ThirdParty/Ert/devel/docs/conf.py vendored Normal file
View File

@ -0,0 +1,332 @@
# -*- coding: utf-8 -*-
#
# ert documentation build configuration file, created by
# sphinx-quickstart on Mon Aug 11 13:14:00 2014.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys
import os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
sys.path.insert(0, os.path.abspath('../python/python'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.viewcode',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'ert'
copyright = u'2014, Statoil ASA'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '1.1'
# The full version, including alpha/beta/rc tags.
release = '1.7'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'ertdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'ert.tex', u'ert Documentation',
u'Statoil ASA', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'ert', u'ert Documentation',
[u'Statoil ASA'], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'ert', u'ert Documentation',
u'Statoil ASA', 'ert', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
# -- Options for Epub output ----------------------------------------------
# Bibliographic Dublin Core info.
epub_title = u'ert'
epub_author = u'Statoil ASA'
epub_publisher = u'Statoil ASA'
epub_copyright = u'2014, Statoil ASA'
# The basename for the epub file. It defaults to the project name.
#epub_basename = u'ert'
# The HTML theme for the epub output. Since the default themes are not optimized
# for small screen space, using the same theme for HTML and epub output is
# usually not wise. This defaults to 'epub', a theme designed to save visual
# space.
#epub_theme = 'epub'
# The language of the text. It defaults to the language option
# or en if the language is not set.
#epub_language = ''
# The scheme of the identifier. Typical schemes are ISBN or URL.
#epub_scheme = ''
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#epub_identifier = ''
# A unique identification for the text.
#epub_uid = ''
# A tuple containing the cover image and cover page html template filenames.
#epub_cover = ()
# A sequence of (type, uri, title) tuples for the guide element of content.opf.
#epub_guide = ()
# HTML files that should be inserted before the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_pre_files = []
# HTML files shat should be inserted after the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_post_files = []
# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']
# The depth of the table of contents in toc.ncx.
#epub_tocdepth = 3
# Allow duplicate toc entries.
#epub_tocdup = True
# Choose between 'default' and 'includehidden'.
#epub_tocscope = 'default'
# Fix unsupported image types using the PIL.
#epub_fix_images = False
# Scale large images.
#epub_max_image_width = 0
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#epub_show_urls = 'inline'
# If false, no index is generated.
#epub_use_index = True

26
ThirdParty/Ert/devel/docs/index.rst vendored Normal file
View File

@ -0,0 +1,26 @@
.. ert documentation master file, created by
sphinx-quickstart on Mon Aug 11 13:14:00 2014.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to ert's documentation!
===============================
Contents:
.. toctree::
:maxdepth: 2
Static/index
python/ert
python/ert_gui
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -4,11 +4,11 @@ add_subdirectory( script )
add_subdirectory( src )
add_subdirectory( modules )
if (BUILD_TESTS)
add_subdirectory( tests )
endif()
if (BUILD_APPLICATIONS)
add_subdirectory( applications )
endif()
if (BUILD_TESTS)
add_subdirectory( tests )
endif()

View File

@ -5,4 +5,16 @@ if (USE_RUNPATH)
add_runpath( ert_module_test )
endif()
install(TARGETS ert_module_test DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
set (destination ${CMAKE_INSTALL_PREFIX}/bin)
install(TARGETS ert_module_test DESTINATION ${destination})
if (INSTALL_GROUP)
install(CODE "EXECUTE_PROCESS(COMMAND chgrp ${INSTALL_GROUP} ${destination}/ert_module_test)")
install(CODE "EXECUTE_PROCESS(COMMAND chmod g+w ${destination}/ert_module_test)")
endif()
if (BUILD_TESTS)
ert_module_name( VAR_RML rml_enkf ${LIBRARY_OUTPUT_PATH} )
add_test( analysis_module_test_RML ${EXECUTABLE_OUTPUT_PATH}/ert_module_test ${VAR_RML})
endif()

View File

@ -24,6 +24,7 @@ extern "C" {
#include <ert/util/type_macros.h>
#include <ert/util/matrix.h>
#include <ert/util/bool_vector.h>
/*
@ -94,13 +95,15 @@ typedef enum {
matrix_type * dObs ,
matrix_type * E ,
matrix_type * D );
void analysis_module_init_update( analysis_module_type * module ,
matrix_type * S ,
matrix_type * R ,
matrix_type * dObs ,
matrix_type * E ,
matrix_type * D );
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);
@ -114,6 +117,7 @@ typedef enum {
bool analysis_module_has_var( const analysis_module_type * module , const char * var );
double analysis_module_get_double( const analysis_module_type * module , const char * var);
int analysis_module_get_int( const analysis_module_type * module , const char * var);
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);

View File

@ -8,7 +8,7 @@ extern "C" {
#include <ert/util/matrix.h>
#include <ert/util/rng.h>
#include <ert/util/bool_vector.h>
typedef void (analysis_updateA_ftype) (void * module_data ,
matrix_type * A ,
@ -38,6 +38,7 @@ extern "C" {
typedef void (analysis_init_update_ftype) (void * module_data,
const bool_vector_type * ens_mask ,
const matrix_type * S ,
const matrix_type * R ,
const matrix_type * dObs ,
@ -51,6 +52,7 @@ extern "C" {
typedef bool (analysis_has_var_ftype) (const void * module_data , const char * var_name);
typedef int (analysis_get_int_ftype) (const void * module_data , const char * var_name );
typedef double (analysis_get_double_ftype) (const void * module_data , const char * var_name );
typedef bool (analysis_get_bool_ftype) (const void * module_data , const char * var_name );
typedef void * (analysis_get_ptr_ftype) (const void * module_data , const char * var_name );
/*****************************************************************/
@ -77,6 +79,7 @@ typedef struct {
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;
} analysis_table_type;

View File

@ -18,6 +18,7 @@
#include <ert/util/rng.h>
#include <ert/util/matrix.h>
#include <ert/util/bool_vector.h>
typedef struct cv_enkf_data_struct cv_enkf_data_type;
@ -25,6 +26,7 @@ void * cv_enkf_data_alloc( rng_type * rng );
void cv_enkf_data_free( void * arg );
void cv_enkf_init_update( void * arg ,
const bool_vector_type * ens_mask ,
const matrix_type * S ,
const matrix_type * R ,
const matrix_type * dObs ,

View File

@ -3,6 +3,7 @@
#include <ert/util/matrix_lapack.h>
#include <ert/util/matrix.h>
#include <ert/util/double_vector.h>
void enkf_linalg_get_PC( const matrix_type * S0,
@ -10,7 +11,8 @@ void enkf_linalg_get_PC( const matrix_type * S0,
double truncation,
int ncomp,
matrix_type * PC,
matrix_type * PC_obs );
matrix_type * PC_obs ,
double_vector_type * singular_values);
void enkf_linalg_init_stdX( matrix_type * X ,
@ -96,16 +98,11 @@ void enkf_linalg_checkX(const matrix_type * X , bool bootstrap);
void enkf_linalg_rml_enkfX1(matrix_type *X1, matrix_type * Udr ,matrix_type * S ,matrix_type *R);
void enkf_linalg_rml_enkfX2(matrix_type *X2, double *Wdr, matrix_type * X1 ,double a , int nsign);
void enkf_linalg_rml_enkfX3(matrix_type *X3, matrix_type *VdTr, double *Wdr,matrix_type *X2, int nsign);
void enkf_linalg_rml_enkfdA(matrix_type *dA1,matrix_type *Dm,matrix_type *X3);
double enkf_linalg_data_mismatch(matrix_type *D , matrix_type *R , matrix_type *Sk);
void enkf_linalg_Covariance(matrix_type *Cd, const matrix_type *E, double nsc ,int nrobs);
void enkf_linalg_rml_enkfAm(matrix_type * Um, double * Wm,int nsign1);
void enkf_linalg_rml_enkfAm(matrix_type * Um, const double * Wm,int nsign1);
void enkf_linalg_rml_enkfX4 (matrix_type *X4,matrix_type *Am, matrix_type *A);
void enkf_linalg_rml_enkfX5(matrix_type * X5,matrix_type * Am, matrix_type * X4);
void enkf_linalg_rml_enkfX6(matrix_type * X6, matrix_type * Dk, matrix_type * X5);
void enkf_linalg_rml_enkfX7(matrix_type * X7, matrix_type * VdT, double * Wdr, double a,matrix_type * X6);
void enkf_linalg_rml_enkfXdA2(matrix_type * dA2,matrix_type * Dk,matrix_type * X7);
#endif

View File

@ -13,8 +13,6 @@ extern "C" {
#define DEFAULT_ENKF_TRUNCATION_ 0.98
#define ENKF_TRUNCATION_KEY_ "ENKF_TRUNCATION"
#define ENKF_NCOMP_KEY_ "ENKF_NCOMP"
#define ENKF_LAMBDA0_KEY_ "LAMBDA0"
#define ENKF_ITER_KEY_ "ITER"
typedef struct std_enkf_data_struct std_enkf_data_type;
@ -27,7 +25,9 @@ extern "C" {
void std_enkf_set_truncation( std_enkf_data_type * data , double truncation );
void std_enkf_set_subspace_dimension( std_enkf_data_type * data , int subspace_dimension);
void std_enkf_set_lambda0( std_enkf_data_type * data , double lambda0 );
bool std_enkf_has_var( const void * arg, const char * var_name);
int std_enkf_get_int( const void * arg, const char * var_name);
double std_enkf_get_double( const void * arg, const char * var_name);
double std_enkf_get_truncation( std_enkf_data_type * data );
void * std_enkf_data_alloc( rng_type * rng);

View File

@ -1,12 +1,43 @@
set( args "--silent --exclude-ert -I${PROJECT_SOURCE_DIR}/libanalysis/include -I${PROJECT_SOURCE_DIR}/libert_util/include -I${CMAKE_CURRENT_SOURCE_DIR} -I${PROJECT_BINARY_DIR}/libert_util/include")
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
set( RML_SOURCE_FILES
rml_enkf.c
set( RML_SOURCE_FILES
rml_enkf.c
rml_enkf_common.c )
set( RMLI_SOURCE_FILES
rml_enkf_imodel.c
rml_enkf_common.c )
set( header_files analysis_module.h enkf_linalg.h analysis_table.h std_enkf.h rml_enkf_common.h)
add_library( rml_enkf SHARED ${RML_SOURCE_FILES} )
set_target_properties( rml_enkf PROPERTIES VERSION 1.0 SOVERSION 1.0 PREFIX "")
target_link_libraries( rml_enkf analysis )
target_link_libraries( rml_enkf dl )
if (USE_RUNPATH)
add_runpath( rml_enkf )
endif()
if (BUILD_TESTS)
add_subdirectory( tests )
endif()
if (INSTALL_ERT)
install(TARGETS rml_enkf DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
#-----------------------------------------------------------------
# Alternative script based build:
#if (BUILD_TESTS)
# if (BUILD_APPLICATIONS)
#set( args "--silent --exclude-ert -I${PROJECT_SOURCE_DIR}/libanalysis/include -I${PROJECT_SOURCE_DIR}/libert_util/include -I${CMAKE_CURRENT_SOURCE_DIR} -I${PROJECT_BINARY_DIR}/libert_util/include")
#set( RML_SOURCE_FILES
# rml_enkf.c
# rml_enkf_common.c )
#ert_module( ${LIBRARY_OUTPUT_PATH}/rml_enkf ${args} "${RML_SOURCE_FILES}")
ert_module( ${LIBRARY_OUTPUT_PATH}/rml_enkf ${args} "${RML_SOURCE_FILES}")
ert_module( ${LIBRARY_OUTPUT_PATH}/rmli_enkf ${args} "${RMLI_SOURCE_FILES}")

View File

@ -0,0 +1,427 @@
/*
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>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <ert/util/type_macros.h>
#include <ert/util/util.h>
#include <ert/util/rng.h>
#include <ert/util/matrix.h>
#include <ert/util/matrix_blas.h>
#include <ert/util/bool_vector.h>
#include <ert/analysis/analysis_module.h>
#include <ert/analysis/analysis_table.h>
#include <ert/analysis/enkf_linalg.h>
#include <ert/analysis/std_enkf.h>
#include <rml_enkf_common.h>
/*
A random 'magic' integer id which is used for run-time type checking
of the input data.
*/
#define RML_ENKF_TYPE_ID 261123
/*
Observe that only one of the settings subspace_dimension and
truncation can be valid at a time; otherwise the svd routine will
fail. This implies that the set_truncation() and
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.
*/
#define INVALID_SUBSPACE_DIMENSION -1
#define INVALID_TRUNCATION -1
#define DEFAULT_SUBSPACE_DIMENSION INVALID_SUBSPACE_DIMENSION
/*
The configuration data used by the rml_enkf module is contained in a
rml_enkf_data_struct instance. The data type used for the rml_enkf
module is quite simple; with only a few scalar variables, but there
are essentially no limits to what you can pack into such a datatype.
All the functions in the module have a void pointer as the first
argument, this will immediately be casted to a rml_enkf_data_type
instance, to get some type safety the UTIL_TYPE_ID system should be
used (see documentation in util.h)
The data structure holding the data for your analysis module should
be created and initialized by a constructor, which should be
registered with the '.alloc' element of the analysis table; in the
same manner the desctruction of this data should be handled by a
destructor or free() function registered with the .freef field of
the analysis table.
*/
typedef struct rml_enkf_data_struct rml_enkf_data_type;
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 lambda; // parameter to control the search direction in Marquardt levenberg optimization
double lambda0; // Initial lambda value
double Sk; // Objective function value
double Std; // Standard Deviation of the Objective function
matrix_type *state;
bool_vector_type * ens_mask;
};
/*
This is a macro which will expand to generate a function:
rml_enkf_data_type * rml_enkf_data_safe_cast( void * arg ) {}
which is used for runtime type checking of all the functions which
accept a void pointer as first argument.
*/
static UTIL_SAFE_CAST_FUNCTION( rml_enkf_data , RML_ENKF_TYPE_ID )
static UTIL_SAFE_CAST_FUNCTION_CONST( rml_enkf_data , RML_ENKF_TYPE_ID )
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;
}
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_number( rml_enkf_data_type *data , int iteration_number ) {
data->iteration_nr = iteration_number;
}
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 );
rml_enkf_set_truncation( data , DEFAULT_ENKF_TRUNCATION_ );
rml_enkf_set_subspace_dimension( data , DEFAULT_SUBSPACE_DIMENSION );
data->option_flags = ANALYSIS_NEED_ED + ANALYSIS_UPDATE_A + ANALYSIS_ITERABLE + ANALYSIS_SCALE_DATA;
data->iteration_nr = 0;
data->Std = 0;
data->state = matrix_alloc(1,1); // This will be resized under use; but we need a valid instance
data->lambda0 = -1.0;
data->ens_mask = bool_vector_alloc(0,false);
return data;
}
void rml_enkf_data_free( void * module_data ) {
rml_enkf_data_type * data = rml_enkf_data_safe_cast( module_data );
matrix_free( data->state );
bool_vector_free(data->ens_mask);
free( data );
}
/*
About the matrix Cd: The matrix Cd is calculated based on the content
of the E input matrix. In the original implementation this matrix was
only calculated in the first iteration, and then reused between subsequent
iterations.
Due to deactivating outliers the number of active observations can change
from one iteration to the next, if the matrix Cd is then reused between
iterations we will get a matrix size mismatch in the linear algebra. In the
current implementation the Cd matrix is recalculated based on the E input
for each iteration.
*/
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) {
rml_enkf_data_type * data = rml_enkf_data_safe_cast( module_data );
double truncation = data->truncation;
double Sk_new;
double Std_new;
int ens_size = matrix_get_columns( S );
int nrobs = matrix_get_rows( S );
matrix_type * Cd = matrix_alloc( nrobs , nrobs);
double nsc = 1/sqrt(ens_size-1);
matrix_type * Skm = matrix_alloc(matrix_get_columns(D),matrix_get_columns(D));
FILE *fp = util_fopen("rml_enkf_output","a");
int nrmin = util_int_min( ens_size , nrobs);
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 );
Cd = matrix_alloc( nrobs, nrobs );
enkf_linalg_Covariance(Cd ,E ,nsc, nrobs);
matrix_inv(Cd);
if (data->iteration_nr == 0) {
Sk_new = enkf_linalg_data_mismatch(D,Cd,Skm); //Calculate the intitial data mismatch term
Std_new = matrix_diag_std(Skm,Sk_new);
rml_enkf_common_store_state( data->state , A , data->ens_mask );
if (data->lambda0 < 0)
data->lambda = pow(10,floor(log10(Sk_new/(2*nrobs))));
else
data->lambda = data->lambda0;
rml_enkf_common_initA__(A,S,Cd,E,D,truncation,data->lambda,Ud,Wd,VdT);
data->Sk = Sk_new;
data->Std = Std_new;
printf("Prior Objective function value is %5.3f \n", data->Sk);
fprintf(fp,"Iteration number\t Lamda Value \t Current Mean (OB FN) \t Old Mean\t Current Stddev\n");
fprintf(fp, "\n\n");
fprintf(fp,"%d \t\t NA \t %5.5f \t \t %5.5f \n",data->iteration_nr, Sk_new, Std_new);
} else {
Sk_new = enkf_linalg_data_mismatch(D , Cd , Skm); //Calculate the intitial data mismatch term
Std_new= matrix_diag_std(Skm,Sk_new);
printf(" Current Objective function value is %5.3f \n\n",Sk_new);
printf("The old Objective function value is %5.3f \n", data->Sk);
if ((Sk_new< (data->Sk)) && (Std_new< (data->Std)))
{
if ( (1- (Sk_new/data->Sk)) < .0001) // check convergence ** model change norm has to be added in this!!
data-> iteration_nr = 16;
fprintf(fp,"%d \t\t %5.5f \t %5.5f \t %5.5f \t %5.5f \n",data->iteration_nr,data->lambda, Sk_new,data->Sk, Std_new);
data->lambda = data->lambda / 10 ;
data->Std = Std_new;
rml_enkf_common_store_state( data->state , A , data->ens_mask );
data->Sk = Sk_new;
rml_enkf_common_initA__(A,S,Cd,E,D,truncation,data->lambda,Ud,Wd,VdT);
}
else if((Sk_new< (data->Sk)) && (Std_new > (data->Std)))
{
if ( (1- (Sk_new/data->Sk)) < .0001) // check convergence ** model change norm has to be added in this!!
data-> iteration_nr = 16;
fprintf(fp,"%d \t\t %5.5f \t %5.5f \t %5.5f \t %5.5f \n",data->iteration_nr,data->lambda, Sk_new,data->Sk, Std_new);
data->Std=Std_new;
rml_enkf_common_store_state( data->state , A , data->ens_mask );
data->Sk = Sk_new;
rml_enkf_common_initA__(A,S,Cd,E,D,truncation,data->lambda,Ud,Wd,VdT);
}
else {
fprintf(fp,"%d \t\t %5.5f \t %5.5f \t %5.5f \t %5.5f \n",data->iteration_nr,data->lambda, Sk_new,data->Sk, Std_new);
printf("The previous step is rejected !!\n");
data->lambda = data ->lambda * 4;
rml_enkf_common_recover_state( data->state , A , data->ens_mask );
rml_enkf_common_initA__(A,S,Cd,E,D,truncation,data->lambda,Ud,Wd,VdT);
data->iteration_nr--;
}
}
data->iteration_nr++;
// setting the lower bound for lambda
if (data->lambda <.01)
data->lambda= .01;
printf ("The current iteration number is %d \n ", data->iteration_nr);
matrix_free(Cd);
matrix_free(Ud);
matrix_free(VdT);
matrix_free(Skm);
free(Wd);
fclose(fp);
}
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 );
}
bool rml_enkf_set_double( void * arg , const char * var_name , double value) {
rml_enkf_data_type * module_data = rml_enkf_data_safe_cast( arg );
{
bool name_recognized = true;
if (strcmp( var_name , ENKF_TRUNCATION_KEY_) == 0)
rml_enkf_set_truncation( module_data , value );
else if (strcmp( var_name , ENKF_LAMBDA0_KEY_) == 0)
rml_enkf_set_lambda0( module_data , value );
else
name_recognized = false;
return name_recognized;
}
}
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 );
else if(strcmp( var_name , ENKF_ITER_KEY_) == 0)
rml_enkf_set_iteration_number( module_data , value );
else
name_recognized = false;
return name_recognized;
}
}
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;
}
}
bool rml_enkf_has_var( const void * arg, const char * var_name) {
bool ret = false;
if ((strcmp(var_name , ENKF_ITER_KEY_) == 0) ||
(strcmp(var_name , ENKF_TRUNCATION_KEY_) == 0) ||
(strcmp(var_name , ENKF_LAMBDA0_KEY_) == 0)) {
ret = true;
}
return ret;
}
int rml_enkf_get_int( 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 , ENKF_ITER_KEY_) == 0)
return module_data->iteration_nr;
else
return -1;
}
}
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 , ENKF_TRUNCATION_KEY_) == 0)
return module_data->truncation;
else if (strcmp(var_name , ENKF_LAMBDA0_KEY_) == 0)
return module_data->lambda0;
else
return -1.0;
}
}
/**
gcc -fpic -c <object_file> -I?? <src_file>
gcc -shared -o <lib_file> <object_files>
*/
#ifdef INTERNAL_LINK
#define SYMBOL_TABLE rml_enkf_symbol_table
#else
#define SYMBOL_TABLE EXTERNAL_MODULE_SYMBOL
#endif
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 = NULL ,
.set_string = NULL ,
.get_options = rml_enkf_get_options ,
.initX = NULL,
.updateA = rml_enkf_updateA ,
.init_update = rml_enkf_init_update ,
.complete_update = NULL,
.has_var = rml_enkf_has_var,
.get_int = rml_enkf_get_int,
.get_double = rml_enkf_get_double,
.get_ptr = NULL,
};

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,3 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
@ -34,69 +32,60 @@
#include <rml_enkf_common.h>
/* This program contains common functions to both rml_enkf & rml_enkf_imodel*/
void rml_enkf_common_initA__( matrix_type * A ,
matrix_type * S ,
matrix_type * Cd ,
matrix_type * E ,
matrix_type * D ,
double truncation,
double lamda,
matrix_type * Udr,
double * Wdr,
matrix_type * VdTr) {
int nrobs = matrix_get_rows( S );
int ens_size = matrix_get_columns( S );
double a = lamda + 1;
matrix_type *tmp = matrix_alloc (nrobs, ens_size);
double nsc = 1/sqrt(ens_size-1);
printf("The lamda Value is %5.5f\n",lamda);
printf("The Value of Truncation is %4.2f \n",truncation);
matrix_subtract_row_mean( S ); /* Shift away the mean in the ensemble predictions*/
matrix_inplace_diag_sqrt(Cd);
matrix_dgemm(tmp, Cd, S,false, false, 1.0, 0.0);
matrix_scale(tmp, nsc);
printf("The Scaling of data matrix completed !\n ");
// Explanation
// zzz_enkf_common_store_state( state , A ,ens_mask) assigns A to state. RESIZES state to rows(A)-by-LEN(ens_mask)
// zzz_enkf_common_recover_state(state , A ,ens_mask) assigns state to A. RESIZES A to rows(state)-by-SUM(ens_mask)
// SVD(S) = Ud * Wd * Vd(T)
int nsign = enkf_linalg_svd_truncation(tmp , truncation , -1 , DGESVD_MIN_RETURN , Wdr , Udr , VdTr);
/* After this we only work with the reduced dimension matrices */
printf("The number of siginificant ensembles are %d \n ",nsign);
matrix_type * X1 = matrix_alloc( nsign, ens_size);
matrix_type * X2 = matrix_alloc (nsign, ens_size );
matrix_type * X3 = matrix_alloc (ens_size, ens_size );
// Compute the matrices X1,X2,X3 and dA
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 ,a, nsign); //X2 = ((a*Ipd)+Wd^2)^-1 * X1
matrix_free(X1);
enkf_linalg_rml_enkfX3(X3, VdTr ,Wdr,X2, nsign); //X3 = Vd *Wd*X2
printf("The X3 matrix is computed !\n ");
matrix_type *dA1= matrix_alloc (matrix_get_rows(A), 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);
enkf_linalg_rml_enkfdA(dA1, Dm, X3); //dA = Dm * X3
matrix_inplace_add(A,dA1); //dA
matrix_free(X3);
matrix_free(Dm);
matrix_free(dA1);
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 );
int active_index = 0;
for (int iens = 0; iens < ens_size; iens++) {
if (bool_vector_iget( ens_mask , iens )) {
matrix_copy_column( state , A , iens , active_index );
active_index++;
} else
matrix_set_const_column( state , iens , 0);
}
}
}
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;
for (int iens = 0; iens < ens_size; iens++) {
if (bool_vector_iget( ens_mask , iens )) {
matrix_copy_column( A , state , active_index , iens );
active_index++;
}
}
}
}
// Scale rows by the entries in the vector Csc
void rml_enkf_common_scaleA(matrix_type *A , const double * Csc, bool invert ){
int nrows = matrix_get_rows(A);
if (invert) {
for (int i=0; i< nrows ; i++) {
double sc= 1/Csc[i];
matrix_scale_row(A, i, sc);
}
} else {
for (int i=0; i< nrows ; i++) {
double sc= Csc[i];
matrix_scale_row(A, i, sc);
}
}
}

View File

@ -1,4 +1,3 @@
#ifndef __RML_ENKF_COMMON_H__
#define __RML_ENKF_COMMON_H__
@ -6,18 +5,11 @@
#include <ert/util/matrix.h>
#include <ert/util/rng.h>
#include <ert/util/bool_vector.h>
void rml_enkf_common_initA__( matrix_type * A ,
matrix_type * S ,
matrix_type * Cd ,
matrix_type * E ,
matrix_type * D ,
double truncation,
double lamda,
matrix_type * Ud,
double * Wd,
matrix_type * VdT);
void rml_enkf_common_store_state( matrix_type * state , const 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 );
void rml_enkf_common_scaleA(matrix_type *A , const double * Csc, bool invert );
#endif

View File

@ -1,532 +0,0 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'rml_enkf_imodel.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>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ert/util/util.h>
#include <ert/util/type_macros.h>
#include <ert/util/rng.h>
#include <ert/util/matrix.h>
#include <ert/util/matrix_blas.h>
#include <ert/analysis/analysis_module.h>
#include <ert/analysis/analysis_table.h>
#include <ert/analysis/enkf_linalg.h>
#include <ert/analysis/std_enkf.h>
#include <rml_enkf_common.h>
/*
A random 'magic' integer id which is used for run-time type checking
of the input data.
*/
#define RML_ENKF_IMODEL_TYPE_ID 261123
typedef struct rml_enkf_imodel_data_struct rml_enkf_imodel_data_type;
/*
Observe that only one of the settings subspace_dimension and
truncation can be valid at a time; otherwise the svd routine will
fail. This implies that the set_truncation() and
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.
*/
#define INVALID_SUBSPACE_DIMENSION -1
#define INVALID_TRUNCATION -1
#define DEFAULT_SUBSPACE_DIMENSION INVALID_SUBSPACE_DIMENSION
/*
The configuration data used by the rml_enkf_imodel module is contained in a
rml_enkf_imodel_data_struct instance. The data type used for the rml_enkf_imodel
module is quite simple; with only a few scalar variables, but there
are essentially no limits to what you can pack into such a datatype.
All the functions in the module have a void pointer as the first
argument, this will immediately be casted to a rml_enkf_imodel_data_type
instance, to get some type safety the UTIL_TYPE_ID system should be
used (see documentation in util.h)
The data structure holding the data for your analysis module should
be created and initialized by a constructor, which should be
registered with the '.alloc' element of the analysis table; in the
same manner the desctruction of this data should be handled by a
destructor or free() function registered with the .freef field of
the analysis table.
*/
struct rml_enkf_imodel_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 lamda; // parameter to control the search direction in Marquardt levenberg optimization
double Sk; // Objective function value
double Std; // Standard Deviation of the Objective function
double * Csc;
matrix_type * Am;
matrix_type *prior;
matrix_type *state;
};
/*
This is a macro which will expand to generate a function:
rml_enkf_imodel_data_type * rml_enkf_imodel_data_safe_cast( void * arg ) {}
which is used for runtime type checking of all the functions which
accept a void pointer as first argument.
*/
static UTIL_SAFE_CAST_FUNCTION( rml_enkf_imodel_data , RML_ENKF_IMODEL_TYPE_ID )
static UTIL_SAFE_CAST_FUNCTION_CONST( rml_enkf_imodel_data , RML_ENKF_IMODEL_TYPE_ID )
double rml_enkf_imodel_get_truncation( rml_enkf_imodel_data_type * data ) {
return data->truncation;
}
int rml_enkf_imodel_get_subspace_dimension( rml_enkf_imodel_data_type * data ) {
return data->subspace_dimension;
}
void rml_enkf_imodel_set_truncation( rml_enkf_imodel_data_type * data , double truncation ) {
data->truncation = truncation;
if (truncation > 0.0)
data->subspace_dimension = INVALID_SUBSPACE_DIMENSION;
}
void rml_enkf_imodel_set_subspace_dimension( rml_enkf_imodel_data_type * data , int subspace_dimension) {
data->subspace_dimension = subspace_dimension;
if (subspace_dimension > 0)
data->truncation = INVALID_TRUNCATION;
}
void * rml_enkf_imodel_data_alloc( rng_type * rng) {
rml_enkf_imodel_data_type * data = util_malloc( sizeof * data);
UTIL_TYPE_ID_INIT( data , RML_ENKF_IMODEL_TYPE_ID );
rml_enkf_imodel_set_truncation( data , DEFAULT_ENKF_TRUNCATION_ );
rml_enkf_imodel_set_subspace_dimension( data , DEFAULT_SUBSPACE_DIMENSION );
data->option_flags = ANALYSIS_NEED_ED + ANALYSIS_UPDATE_A + ANALYSIS_ITERABLE + ANALYSIS_SCALE_DATA;
data->iteration_nr = 0;
data->Std = 0;
return data;
}
void rml_enkf_imodel_data_free( void * data ) {
free( data );
}
void rml_enkf_imodel_init1__( matrix_type * A,
rml_enkf_imodel_data_type * data,
double truncation,
double nsc) {
int nstate = matrix_get_rows( A );
int ens_size = matrix_get_columns( A );
int nrmin = util_int_min( ens_size , nstate);
matrix_type * Dm = matrix_alloc_copy( A );
matrix_type * Um = matrix_alloc( nstate , nrmin ); /* Left singular vectors. */
matrix_type * VmT = matrix_alloc( nrmin , ens_size ); /* Right singular vectors. */
double * Wm = util_calloc( nrmin , sizeof * Wm );
matrix_subtract_row_mean(Dm);
//This routine only computes the SVD of Ensemble State matrix
for (int i=0; i<nstate; i++){
double sc = nsc/ (data->Csc[i]);
matrix_scale_row (Dm,i, sc);
}
int nsign1 = enkf_linalg_svd_truncation(Dm , truncation , -1 , DGESVD_MIN_RETURN , Wm , Um , VmT);
printf("The significant Eigen values are %d\n",nsign1);
enkf_linalg_rml_enkfAm(Um, Wm, nsign1);
data->Am=matrix_alloc_copy(Um);
printf("\n Init1 completed\n");
matrix_free(Um);
matrix_free(VmT);
matrix_free(Dm);
free(Wm);
}
void rml_enkf_imodel_Create_Csc(rml_enkf_imodel_data_type * data){
// Create the scaling matrix based on the state vector
int nstate = matrix_get_rows( data->prior );
int ens_size = matrix_get_columns( data->prior );
for (int i=0; i < nstate; i++) {
double sumrow = matrix_get_row_sum(data->prior , i);
double tmp = sumrow / ens_size;
if (abs(tmp)< 1)
data->Csc[i]=0.05;
else
data->Csc[i]= 1;
}
}
void rml_enkf_imodel_scalingA(matrix_type *A, double * Csc, bool invert ){
int nrows = matrix_get_rows(A);
if (invert)
for (int i=0; i< nrows ; i++)
{
double sc= 1/Csc[i];
matrix_scale_row(A, i, sc);
}
else
for (int i=0; i< nrows ; i++)
{
double sc= Csc[i];
matrix_scale_row(A, i, sc);
}
}
void rml_enkf_imodel_init2__( rml_enkf_imodel_data_type * data,
matrix_type *A,
matrix_type *Acopy,
double * Wdr,
double nsc,
matrix_type * VdTr) {
int nstate = matrix_get_rows( Acopy );
int ens_size = matrix_get_columns( Acopy );
matrix_type * Dk = matrix_alloc_copy( Acopy );
double a = data->lamda + 1;
matrix_type *Am= matrix_alloc_copy(data->Am);
matrix_type *Apr= matrix_alloc_copy(data->prior);
double *Csc = util_calloc(nstate , sizeof * Csc );
for (int i=0; i< nstate ; i++)
{
Csc[i]= data->Csc[i];
}
int nsign1= matrix_get_columns(data->Am);
matrix_type * X4 = matrix_alloc(nsign1,ens_size);
matrix_type * X5 = matrix_alloc(nstate,ens_size);
matrix_type * X6 = matrix_alloc(ens_size,ens_size);
matrix_type * X7 = matrix_alloc(ens_size,ens_size);
matrix_type * dA2 = matrix_alloc(nstate, ens_size);
//Compute dA2
printf("\n Starting init 2 \n");
matrix_inplace_sub(Dk, Apr);
rml_enkf_imodel_scalingA(Dk,Csc,true);
enkf_linalg_rml_enkfX4(X4, Am, Dk);
matrix_free(Dk);
enkf_linalg_rml_enkfX5(X5, Am, X4);
printf("\nMatrix X5 computed\n");
matrix_type * Dk1 = matrix_alloc_copy( Acopy );
matrix_subtract_row_mean(Dk1);
rml_enkf_imodel_scalingA(Dk1,Csc,true);
matrix_scale(Dk1,nsc);
enkf_linalg_rml_enkfX6(X6, Dk1,X5);
printf("Matrix X6 computed!\n");
enkf_linalg_rml_enkfX7(X7, VdTr ,Wdr, a, X6);
printf("Matrix X7 computed!\n");
rml_enkf_imodel_scalingA(Dk1,Csc,false);
printf("Matrix Dk1 Scaling done!\n");
enkf_linalg_rml_enkfXdA2(dA2,Dk1,X7);
printf("Matrix dA2 computed!\n");
matrix_inplace_sub(A, dA2);
free(Csc);
matrix_free(Am);
matrix_free(Apr);
matrix_free(X4);
matrix_free(X5);
matrix_free(X6);
matrix_free(X7);
matrix_free(dA2);
matrix_free(Dk1);
}
void rml_enkf_imodel_updateA(void * module_data ,
matrix_type * A ,
matrix_type * S ,
matrix_type * R ,
matrix_type * dObs ,
matrix_type * E ,
matrix_type * D) {
rml_enkf_imodel_data_type * data = rml_enkf_imodel_data_safe_cast( module_data );
double truncation = data->truncation;
double Sk_new;
double Std_new;
matrix_type * Skm = matrix_alloc(matrix_get_columns(D),matrix_get_columns(D));
FILE *fp = util_fopen("rml_enkf_imodel_output","a");
int nstate = matrix_get_rows(A);
int ens_size = matrix_get_columns( S );
int nrobs = matrix_get_rows( S );
matrix_type * Cd = matrix_alloc( nrobs, nrobs );
double nsc = 1/sqrt(ens_size-1);
int nrmin = util_int_min( ens_size , nrobs);
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 );
enkf_linalg_Covariance(Cd ,E ,nsc, nrobs);
matrix_inv(Cd);
if (data->iteration_nr == 0) {
Sk_new = enkf_linalg_data_mismatch(D,Cd,Skm); //Calculate the intitial data mismatch term
Std_new= matrix_diag_std(Skm,Sk_new);
data->lamda =pow(10,floor(log10(Sk_new/(2*nrobs))));
data->prior = matrix_alloc_copy(A);
data->state = matrix_alloc_copy(A);
data->Csc = util_calloc(nstate , sizeof * data->Csc);
rml_enkf_imodel_Create_Csc(data);
rml_enkf_common_initA__(A,S,Cd,E,D,truncation,data->lamda,Ud,Wd,VdT);
printf("\n model scaling matrix computed\n");
rml_enkf_imodel_init1__(data->prior, data, truncation, nsc);
data->Sk = Sk_new;
data->Std= Std_new;
printf("Prior Objective function value is %5.3f \n", data->Sk);
fprintf(fp,"Iteration number\t Lamda Value \t Current Mean (OB FN) \t Old Mean\t Current Stddev\n");
fprintf(fp, "\n\n");
fprintf(fp,"%d \t\t NA \t %5.5f \t \t %5.5f \n",data->iteration_nr, Sk_new, Std_new);
}
else
{
matrix_type *Acopy = matrix_alloc_copy (A);
Sk_new = enkf_linalg_data_mismatch(D,Cd,Skm); //Calculate the intitial data mismatch term
Std_new= matrix_diag_std(Skm,Sk_new);
printf(" Current Objective function value is %5.3f \n\n",Sk_new);
printf("The old Objective function value is %5.3f \n", data->Sk);
if ((Sk_new< (data->Sk)) && (Std_new<= (data->Std)))
{
if ( (1- (Sk_new/data->Sk)) < .0001) // check convergence ** model change norm has to be added in this!!
data-> iteration_nr = 16;
fprintf(fp,"%d \t\t %5.5f \t %5.5f \t %5.5f \t %5.5f \n",data->iteration_nr,data->lamda, Sk_new,data->Sk, Std_new);
data->lamda = data->lamda / 10 ;
data->Std = Std_new;
data->state = matrix_alloc_copy(A);
data->Sk = Sk_new;
rml_enkf_common_initA__(A,S,Cd,E,D,truncation,data->lamda,Ud,Wd,VdT);
rml_enkf_imodel_init2__(data,A,Acopy,Wd,nsc,VdT);
}
else if((Sk_new< (data->Sk)) && (Std_new > (data->Std)))
{
if ( (1- (Sk_new/data->Sk)) < .0001) // check convergence ** model change norm has to be added in this!!
data-> iteration_nr = 16;
fprintf(fp,"%d \t\t %5.5f \t %5.5f \t %5.5f \t %5.5f \n",data->iteration_nr,data->lamda, Sk_new,data->Sk, Std_new);
data->lamda = data->lamda;
data->Std=Std_new;
data->state = matrix_alloc_copy(A);
data->Sk = Sk_new;
rml_enkf_common_initA__(A,S,Cd,E,D,truncation,data->lamda,Ud,Wd,VdT);
rml_enkf_imodel_init2__(data,A,Acopy,Wd,nsc,VdT);
}
else {
fprintf(fp,"%d \t\t %5.5f \t %5.5f \t %5.5f \t %5.5f \n",data->iteration_nr,data->lamda, Sk_new,data->Sk, Std_new);
printf("The previous step is rejected !!\n");
data->lamda = data ->lamda * 4;
matrix_assign( A , data->state );
printf("matrix copied \n");
rml_enkf_common_initA__(A,S,Cd,E,D,truncation,data->lamda,Ud,Wd,VdT);
rml_enkf_imodel_init2__(data,A,Acopy,Wd,nsc,VdT);
data->iteration_nr--;
}
matrix_free(Acopy);
}
data->iteration_nr++;
//setting the lower bound for lamda
if (data->lamda <.01)
data->lamda= .01;
printf ("The current iteration number is %d \n ", data->iteration_nr);
// free(data->Csc);
matrix_free(Ud);
matrix_free(VdT);
free(Wd);
matrix_free(Skm);
matrix_free(Cd);
fclose(fp);
}
bool rml_enkf_imodel_set_double( void * arg , const char * var_name , double value) {
rml_enkf_imodel_data_type * module_data = rml_enkf_imodel_data_safe_cast( arg );
{
bool name_recognized = true;
if (strcmp( var_name , ENKF_TRUNCATION_KEY_) == 0)
rml_enkf_imodel_set_truncation( module_data , value );
else
name_recognized = false;
return name_recognized;
}
}
bool rml_enkf_imodel_set_int( void * arg , const char * var_name , int value) {
rml_enkf_imodel_data_type * module_data = rml_enkf_imodel_data_safe_cast( arg );
{
bool name_recognized = true;
if (strcmp( var_name , ENKF_NCOMP_KEY_) == 0)
rml_enkf_imodel_set_subspace_dimension( module_data , value );
else
name_recognized = false;
return name_recognized;
}
}
long rml_enkf_imodel_get_options( void * arg , long flag ) {
rml_enkf_imodel_data_type * module_data = rml_enkf_imodel_data_safe_cast( arg );
{
return module_data->option_flags;
}
}
bool rml_enkf_imodel_has_var( const void * arg, const char * var_name) {
{
if (strcmp(var_name , ENKF_ITER_KEY_) == 0)
return true;
else
return false;
}
}
int rml_enkf_imodel_get_int( const void * arg, const char * var_name) {
const rml_enkf_imodel_data_type * module_data = rml_enkf_imodel_data_safe_cast_const( arg );
{
if (strcmp(var_name , ENKF_ITER_KEY_) == 0)
return module_data->iteration_nr;
else
return -1;
}
}
/**
gcc -fpic -c <object_file> -I?? <src_file>
gcc -shared -o <lib_file> <object_files>
*/
#ifdef INTERNAL_LINK
#define SYMBOL_TABLE rml_enkf_imodel_symbol_table
#else
#define SYMBOL_TABLE EXTERNAL_MODULE_SYMBOL
#endif
analysis_table_type SYMBOL_TABLE = {
.alloc = rml_enkf_imodel_data_alloc,
.freef = rml_enkf_imodel_data_free,
.set_int = rml_enkf_imodel_set_int ,
.set_double = rml_enkf_imodel_set_double ,
.set_bool = NULL ,
.set_string = NULL ,
.get_options = rml_enkf_imodel_get_options ,
.initX = NULL,
.updateA = rml_enkf_imodel_updateA ,
.init_update = NULL,
.complete_update = NULL,
.has_var = rml_enkf_imodel_has_var,
.get_int = rml_enkf_imodel_get_int,
.get_double = NULL,
.get_ptr = NULL,
};

View File

@ -0,0 +1,5 @@
add_executable(analysis_rml_enkf_common analysis_rml_enkf_common.c ../rml_enkf_common.c)
target_link_libraries( analysis_rml_enkf_common analysis util test_util )
add_test( analysis_rml_enkf_common ${EXECUTABLE_OUTPUT_PATH}/analysis_rml_enkf_common )

View File

@ -0,0 +1,133 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'analysis_rml_common.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/util/rng.h>
#include <ert/util/mzran.h>
#include <ert/util/matrix.h>
#include <ert/util/bool_vector.h>
#include <rml_enkf_common.h>
void test_store_recover_state() {
rng_type * rng = rng_alloc( MZRAN , INIT_DEFAULT );
int ens_size = 10;
int active_size = 8;
int rows = 100;
matrix_type * state = matrix_alloc(1,1);
bool_vector_type * ens_mask = bool_vector_alloc(ens_size , false);
matrix_type * A = matrix_alloc( rows , active_size);
matrix_type * A2 = matrix_alloc( rows, active_size );
matrix_type * A3 = matrix_alloc( 1,1 );
for (int i=0; i < active_size; i++)
bool_vector_iset( ens_mask , i + 1 , true );
matrix_random_init(A , rng);
rml_enkf_common_store_state( state , A , ens_mask );
test_assert_int_equal( matrix_get_rows( state ) , rows );
test_assert_int_equal( matrix_get_columns( state ) , ens_size );
{
int g;
int a = 0;
for (g=0; g < ens_size; g++) {
if (bool_vector_iget( ens_mask , g )) {
test_assert_true( matrix_columns_equal( state , g , A , a ));
a++;
}
}
}
rml_enkf_common_recover_state( state , A2 , ens_mask);
rml_enkf_common_recover_state( state , A3 , ens_mask);
test_assert_true( matrix_equal( A , A2 ));
test_assert_true( matrix_equal( A , A3 ));
bool_vector_free( ens_mask );
matrix_free( state );
matrix_free( A );
}
void test_scaleA() {
const int N = 10;
matrix_type * m1 = matrix_alloc(N , N);
matrix_type * m2 = matrix_alloc(N , N);
double * csc = util_calloc( N , sizeof * csc );
rng_type * rng = rng_alloc( MZRAN , INIT_DEFAULT );
matrix_random_init( m1 , rng );
matrix_assign(m2 , m1);
test_assert_true( matrix_equal(m1 , m2));
{
for (int i=0; i < N; i++)
csc[i] = (i + 2);
}
rml_enkf_common_scaleA( m1 , csc , false );
{
int row,col;
for (row = 0; row < N; row++) {
for (col=0; col < N; col++) {
double v1 = matrix_iget(m1 , row , col);
double v2 = matrix_iget(m2 , row , col);
test_assert_double_equal( v1 , v2 * csc[row] );
}
}
}
rml_enkf_common_scaleA( m2 , csc , false );
test_assert_true( matrix_equal(m1 , m2));
rml_enkf_common_scaleA( m2 , csc , true );
{
int row,col;
for (row = 0; row < N; row++) {
for (col=0; col < N; col++) {
double v1 = matrix_iget(m1 , row , col);
double v2 = matrix_iget(m2 , row , col);
test_assert_double_equal( v1 , v2 * csc[row] );
}
}
}
rml_enkf_common_scaleA( m1 , csc , true );
test_assert_true( matrix_equal(m1 , m2));
rng_free( rng );
matrix_free(m1);
matrix_free(m2);
free( csc );
}
int main(int argc , char ** argv) {
test_store_recover_state();
test_scaleA();
exit(0);
}

View File

@ -1 +1,8 @@
install(PROGRAMS ert_module DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
set (destination ${CMAKE_INSTALL_PREFIX}/bin)
install(PROGRAMS ert_module DESTINATION ${destination})
if (INSTALL_GROUP)
install(CODE "EXECUTE_PROCESS(COMMAND chgrp ${INSTALL_GROUP} ${destination}/ert_module)")
install(CODE "EXECUTE_PROCESS(COMMAND chmod g+w ${destination}/ert_module)")
endif()

View File

@ -9,7 +9,7 @@ ert_root = os.path.realpath( os.path.join(os.path.dirname( os.path.realpath( os.
#-----------------------------------------------------------------
default_lib_list = ["analysis" , "ert_util"]
default_define_list = ["HAVE_PTHREAD"]
default_define_list = ["HAVE_PTHREAD" , "COMPILER_GCC"]
CFLAGS = "-std=gnu99 -O2 -Wall -fpic -g"
@ -169,10 +169,10 @@ Link: %s %s %s
parser = OptionParser( usage )
parser.add_option("--ert-root" , dest="ert_root" , action="store")
parser.add_option("-I" , dest = "include_path_list", action = "append")
parser.add_option("-D" , dest = "define_list" , action = "append")
parser.add_option("-L" , dest = "lib_path_list" , action = "append")
parser.add_option("-l" , dest = "lib_list" , action = "append")
parser.add_option("-I" , dest = "include_path_list", action = "append" , default = [])
parser.add_option("-D" , dest = "define_list" , action = "append" , default = [])
parser.add_option("-L" , dest = "lib_path_list" , action = "append" , default = [])
parser.add_option("-l" , dest = "lib_list" , action = "append" , default = [])
parser.add_option("--exclude-ert" , dest = "exclude_ert" , action="store_true" , default = False)
parser.add_option("--use-rpath" , dest="use_rpath" , action="store_true" , default = False)
parser.add_option("--silent" , dest="silent" , action="store_true" , default = False)
@ -185,28 +185,21 @@ if options.ert_root:
ert_root = options.ert_root
if options.exclude_ert:
include_path_list = ["./"]
lib_path_list = []
define_list = []
lib_list = []
default_include_path_list = ["./"]
default_lib_path_list = []
default_lib_list = []
else:
include_path_list = ["./" , "%s/include" % ert_root]
lib_path_list = ["%s/lib64" % ert_root]
define_list = default_define_list
lib_list = default_lib_list
default_include_path_list = ["./" , "%s/include" % ert_root]
default_lib_path_list = ["%s/lib64" % ert_root]
default_lib_list = default_lib_list
if options.include_path_list:
include_path_list += options.include_path_list
if options.define_list:
define_list += options.define_list
if options.lib_list:
lib_list += options.lib_list
if options.lib_path_list:
lib_path_list += options.lib_path_list
# What is supplied as commandline options should take presedence, this
# implies that it should be first OR last on the commandline.
include_path_list = options.include_path_list + default_include_path_list
define_list = default_define_list + options.define_list
lib_list = options.lib_list + default_lib_list
lib_path_list = options.lib_path_list + default_lib_path_list
verbose = not options.silent

View File

@ -1,6 +1,6 @@
# Common libanalysis library
set( source_files analysis_module.c enkf_linalg.c std_enkf.c sqrt_enkf.c cv_enkf.c bootstrap_enkf.c null_enkf.c fwd_step_enkf.c )
set( header_files analysis_module.h enkf_linalg.h analysis_table.h std_enkf.h)
set( header_files analysis_module.h enkf_linalg.h analysis_table.h std_enkf.h fwd_step_enkf.h)
add_library( analysis SHARED ${source_files} )
set_target_properties( analysis PROPERTIES COMPILE_DEFINITIONS INTERNAL_LINK)
set_target_properties( analysis PROPERTIES VERSION 1.0 SOVERSION 1.0 )

View File

@ -55,6 +55,7 @@ struct analysis_module_struct {
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;
@ -81,6 +82,7 @@ static analysis_module_type * analysis_module_alloc_empty( const char * user_nam
module->has_var = NULL;
module->get_int = NULL;
module->get_double = NULL;
module->get_bool = NULL;
module->get_ptr = NULL;
module->alloc = NULL;
@ -121,6 +123,7 @@ static analysis_module_type * analysis_module_alloc__( rng_type * rng ,
module->has_var = table->has_var;
module->get_int = table->get_int;
module->get_double = table->get_double;
module->get_bool = table->get_bool;
module->get_ptr = table->get_ptr;
if (module->alloc)
@ -270,13 +273,14 @@ void analysis_module_updateA(analysis_module_type * module ,
void analysis_module_init_update( analysis_module_type * module ,
matrix_type * S ,
matrix_type * R ,
matrix_type * dObs ,
matrix_type * E ,
matrix_type * D ) {
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 , S , R , dObs , E , D);
module->init_update( module->module_data , ens_mask , S , R , dObs , E , D);
}
@ -407,6 +411,19 @@ int analysis_module_get_int( const analysis_module_type * module , const char *
}
bool analysis_module_get_bool( const analysis_module_type * module , const char * var) {
if (analysis_module_has_var( module , var )) {
if (module->get_bool != NULL)
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
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;
}
double analysis_module_get_double( const analysis_module_type * module , const char * var) {
if (analysis_module_has_var( module , var )) {
if (module->get_double != NULL)

View File

@ -56,281 +56,7 @@ typedef struct {
static UTIL_SAFE_CAST_FUNCTION( bootstrap_enkf_data , BOOTSTRAP_ENKF_TYPE_ID )
/*****************************************************************/
//CV: static void lowrankCinv_pre_cv(const matrix_type * S ,
//CV: const matrix_type * R ,
//CV: matrix_type * V0T ,
//CV: matrix_type * Z ,
//CV: double * eig ,
//CV: matrix_type * U0,
//CV: double truncation ,
//CV: int ncomp) {
//CV:
//CV: const int nrobs = matrix_get_rows( S );
//CV: const int nrens = matrix_get_columns( S );
//CV: const int nrmin = util_int_min( nrobs , nrens );
//CV:
//CV: double * inv_sig0 = util_malloc( nrmin * sizeof * inv_sig0 , __func__);
//CV:
//CV: enkf_linalg_svdS( S , truncation , ncomp , DGESVD_MIN_RETURN , inv_sig0 , U0 , V0T);
//CV:
//CV: {
//CV: matrix_type * B = matrix_alloc( nrmin , nrmin );
//CV: enkf_linalg_Cee( B , nrens , R , U0 , inv_sig0); /* B = Xo = (N-1) * Sigma0^(+) * U0'* Cee * U0 * Sigma0^(+') (14.26)*/
//CV: /*USE SVD INSTEAD*/
//CV: matrix_dgesvd(DGESVD_MIN_RETURN , DGESVD_NONE, B , eig, Z , NULL);
//CV: matrix_free( B );
//CV: }
//CV:
//CV: {
//CV: int i,j;
//CV: /* Lambda1 = (I + Lambda)^(-1) */
//CV:
//CV: for (i=0; i < nrmin; i++)
//CV: eig[i] = 1.0 / (1 + eig[i]);
//CV:
//CV: for (j=0; j < nrmin; j++)
//CV: for (i=0; i < nrmin; i++)
//CV: matrix_imul(Z , i , j , inv_sig0[i]); /* Z2 = Sigma0^(+) * Z; */
//CV: }
//CV: }
//CV:
//CV:
//CV:
//CV: void enkf_analysis_invertS_pre_cv(double truncation,
//CV: int ncomp ,
//CV: const matrix_type * S ,
//CV: const matrix_type * R ,
//CV: matrix_type * V0T ,
//CV: matrix_type * Z ,
//CV: double * eig ,
//CV: matrix_type * U0 ) {
//CV:
//CV: lowrankCinv_pre_cv( S , R , V0T , Z , eig , U0 , truncation , ncomp );
//CV: }
//CV:
//CV:
//CV:
//CV: static void getW_pre_cv(matrix_type * W ,
//CV: const matrix_type * V0T,
//CV: const matrix_type * Z ,
//CV: double * eig ,
//CV: const matrix_type * U0 ,
//CV: int nfolds_CV,
//CV: const matrix_type * A,
//CV: int unique_bootstrap_components ,
//CV: rng_type * rng,
//CV: bool pen_press) {
//CV:
//CV: const int nrobs = matrix_get_rows( U0 );
//CV: const int nrens = matrix_get_columns( V0T );
//CV: const int nrmin = util_int_min( nrobs , nrens );
//CV:
//CV: int i,j;
//CV:
//CV:
//CV: /* Vector with random permutations of the itegers 1,...,nrens */
//CV: int * randperms = util_malloc( sizeof * randperms * nrens, __func__);
//CV: int * indexTest = util_malloc( sizeof * indexTest * nrens, __func__);
//CV: int * indexTrain = util_malloc( sizeof * indexTrain * nrens, __func__);
//CV:
//CV: if(nrens != unique_bootstrap_components)
//CV: nfolds_CV = util_int_min( nfolds_CV , unique_bootstrap_components-1);
//CV:
//CV:
//CV: matrix_type * cvError = matrix_alloc( nrmin,nfolds_CV );
//CV:
//CV: /*Copy Z */
//CV: matrix_type * workZ = matrix_alloc_copy( Z );
//CV:
//CV: int optP;
//CV:
//CV:
//CV: /* start cross-validation: */
//CV:
//CV: const int maxp = matrix_get_rows(V0T);
//CV:
//CV: /* draw random permutations of the integers 0,...,nrens-1 */
//CV: for (i=0; i < nrens; i++)
//CV: randperms[i] = i;
//CV: rng_shuffle_int( rng , randperms , nrens );
//CV:
//CV:
//CV:
//CV: /*need to init cvError to all zeros (?) */
//CV: for (i = 0; i < nrmin; i++){
//CV: for( j = 0; j> nfolds_CV; j++){
//CV: matrix_iset( cvError , i , j , 0.0 );
//CV: }
//CV: }
//CV:
//CV: int ntest, ntrain, k;
//CV: printf("\nStarting cross-validation\n");
//CV: for (i = 0; i < nfolds_CV; i++) {
//CV: printf(".");
//CV:
//CV: ntest = 0;
//CV: ntrain = 0;
//CV: k = i;
//CV: /*extract members for the training and test ensembles */
//CV: for (j = 0; j < nrens; j++) {
//CV: if (j == k) {
//CV: indexTest[ntest] = randperms[j];
//CV: k += nfolds_CV;
//CV: ntest++;
//CV: } else {
//CV: indexTrain[ntrain] = randperms[j];
//CV: ntrain++;
//CV: }
//CV: }
//CV:
//CV: //This one instaed: ?? enkf_analysis_get_cv_error_prin_comp( cv_data , cvError , A , indexTest , indexTrain, ntest, ntrain , i , maxP);
//CV: enkf_analysis_get_cv_error( cvError , A , V0T , workZ , eig , indexTest , indexTrain, ntest, ntrain , i );
//CV: }
//CV: printf("\n");
//CV: /* find optimal truncation value for the cv-scheme */
//CV: optP = enkf_analysis_get_optimal_numb_comp( cvError , maxp, nfolds_CV, pen_press);
//CV:
//CV: printf("Optimal number of components found: %d \n",optP);
//CV: printf("\n");
//CV: FILE * compSel_log = util_fopen("compSel_log_local_cv" , "a");
//CV: fprintf( compSel_log , " %d ",optP);
//CV: fclose( compSel_log);
//CV:
//CV:
//CV: /*free cvError vector and randperm */
//CV: matrix_free( cvError );
//CV: free( randperms );
//CV: free( indexTest );
//CV: free( indexTrain );
//CV:
//CV: /* need to update matrices so that we only use components 1,...,optP */
//CV: /* remove non-zero entries of the z matrix (we do not want to recompute sigma0^(+') * z */
//CV: /* this can surely be done much more efficiently, but for now we want to minimize the
//CV: number of potential bugs in the code for now */
//CV: for (i = optP; i < nrmin; i++) {
//CV: for (j = 0; j < nrmin; j++) {
//CV: matrix_iset(workZ , i , j, 0.0);
//CV: }
//CV: }
//CV:
//CV:
//CV: /*fix the eig vector as well: */
//CV: {
//CV: int i;
//CV: /* lambda1 = (i + lambda)^(-1) */
//CV: for (i=optP; i < nrmin; i++)
//CV: eig[i] = 1.0;
//CV: }
//CV:
//CV: matrix_matmul(W , U0 , workZ); /* x1 = w = u0 * z2 = u0 * sigma0^(+') * z */
//CV:
//CV:
//CV:
//CV:
//CV: /*end cross-validation */
//CV: }
// CV: void enkf_analysis_initX_pre_cv(matrix_type * X ,
// CV: int nfolds_CV,
// CV: enkf_mode_type enkf_mode,
// CV: bool bootstrap ,
// CV: matrix_type * S ,
// CV: matrix_type * R ,
// CV: matrix_type * E ,
// CV: matrix_type * D ,
// CV: rng_type * rng ,
// CV: meas_data_type * meas_data ,
// CV: obs_data_type * obs_data ,
// CV: const matrix_type * randrot ,
// CV: const matrix_type * A ,
// CV: const matrix_type * V0T ,
// CV: const matrix_type * Z ,
// CV: const double * eig ,
// CV: const matrix_type * U0 ,
// CV: meas_data_type * fasit ,
// CV: int unique_bootstrap_components) {
// CV:
// CV: int ens_size = meas_data_get_ens_size( meas_data );
// CV: {
// CV: int nrobs = obs_data_get_active_size(obs_data);
// CV: int nrmin = util_int_min( ens_size , nrobs);
// CV:
// CV:
// CV: /*
// CV: 1: Allocating all matrices
// CV: */
// CV: /*Need a copy of A, because we need it later */
// CV: matrix_type * workA = matrix_alloc_copy( A ); /* <- This is a massive memory requirement. */
// CV: matrix_type * innov = enkf_linalg_alloc_innov( dObs , S );
// CV:
// CV: matrix_type * W = matrix_alloc(nrobs , nrmin);
// CV: double * workeig = util_malloc( sizeof * workeig * nrmin , __func__);
// CV:
// CV:
// CV: // Really unclear whether the row mean should have been shifted from S????
// CV:
// CV: /*copy entries in eig:*/
// CV: {
// CV: int i;
// CV: for (i = 0 ; i < nrmin ; i++)
// CV: workeig[i] = eig[i];
// CV: }
// CV:
// CV: /* Subtracting the ensemble mean of the state vector ensemble */
// CV: matrix_subtract_row_mean( workA );
// CV:
// CV: /*
// CV: 2: Diagonalize the S matrix; singular vectors are stored in W
// CV: and singular values (after some massage) are stored in eig.
// CV: W = X1, eig = inv(I+Lambda1),(Eq.14.30, and 14.29, Evensen, 2007, respectively)
// CV: */
// CV:
// CV: getW_pre_cv(W , V0T , Z , workeig , U0 , nfolds_CV , workA , unique_bootstrap_components , rng);
// CV:
// CV: /*
// CV: 3: actually calculating the X matrix.
// CV: */
// CV: switch (enkf_mode) {
// CV: case(ENKF_STANDARD):
// CV: enkf_linalg_init_stdX( X , S , D , W , workeig , bootstrap);
// CV: break;
// CV: case(ENKF_SQRT):
// CV: enkf_linalg_init_sqrtX(X , S , randrot , dObs , W , workeig , bootstrap );
// CV: break;
// CV: default:
// CV: util_abort("%s: INTERNAL ERROR \n",__func__);
// CV: }
// CV:
// CV: matrix_free( W );
// CV: matrix_free( R );
// CV: matrix_free( S );
// CV: matrix_free( workA );
// CV: matrix_free( innov );
// CV: free( workeig );
// CV:
// CV: if (enkf_mode == ENKF_STANDARD) {
// CV: matrix_free( E );
// CV: matrix_free( D );
// CV: }
// CV:
// CV: enkf_analysis_checkX(X , bootstrap);
// CV: }
// CV: }
/*****************************************************************/
static UTIL_SAFE_CAST_FUNCTION_CONST( bootstrap_enkf_data , BOOTSTRAP_ENKF_TYPE_ID )
void bootstrap_enkf_set_doCV( bootstrap_enkf_data_type * data , bool doCV) {
@ -376,6 +102,7 @@ void bootstrap_enkf_data_free( void * arg ) {
std_enkf_data_free( boot_data->std_enkf_data );
cv_enkf_data_free( boot_data->cv_enkf_data );
}
free( boot_data );
}
@ -443,7 +170,8 @@ void bootstrap_enkf_updateA(void * module_data ,
}
if (bootstrap_data->doCV) {
cv_enkf_init_update( bootstrap_data->cv_enkf_data , S_resampled , R , dObs , E , D);
const bool_vector_type * ens_mask = NULL;
cv_enkf_init_update( bootstrap_data->cv_enkf_data , ens_mask , S_resampled , R , dObs , E , D);
cv_enkf_initX( bootstrap_data->cv_enkf_data , X , A_resampled , S_resampled , R , dObs , E , D);
} else
std_enkf_initX(bootstrap_data->std_enkf_data , X , NULL , S_resampled,R, dObs, E,D );
@ -518,6 +246,26 @@ bool bootstrap_enkf_set_bool( void * arg , const char * var_name , bool value) {
}
bool bootstrap_enkf_has_var( const void * arg, const char * var_name) {
const bootstrap_enkf_data_type * module_data = bootstrap_enkf_data_safe_cast_const( arg );
{
return std_enkf_has_var(module_data->std_enkf_data, var_name);
}
}
double bootstrap_enkf_get_double( const void * arg, const char * var_name) {
const bootstrap_enkf_data_type * module_data = bootstrap_enkf_data_safe_cast_const( arg );
{
return std_enkf_get_double( module_data->std_enkf_data , var_name);
}
}
int bootstrap_enkf_get_int( const void * arg, const char * var_name) {
const bootstrap_enkf_data_type * module_data = bootstrap_enkf_data_safe_cast_const( arg );
{
return std_enkf_get_int( module_data->std_enkf_data , var_name);
}
}
@ -543,8 +291,9 @@ analysis_table_type SYMBOL_TABLE = {
.updateA = bootstrap_enkf_updateA,
.init_update = NULL,
.complete_update = NULL,
.has_var = NULL,
.get_int = NULL,
.get_double = NULL,
.has_var = bootstrap_enkf_has_var,
.get_int = bootstrap_enkf_get_int,
.get_double = bootstrap_enkf_get_double,
.get_bool = NULL,
.get_ptr = NULL,
};

View File

@ -63,6 +63,7 @@ struct cv_enkf_data_struct {
static UTIL_SAFE_CAST_FUNCTION( cv_enkf_data , CV_ENKF_TYPE_ID )
static UTIL_SAFE_CAST_FUNCTION_CONST( cv_enkf_data , CV_ENKF_TYPE_ID )
void cv_enkf_set_truncation( cv_enkf_data_type * data , double truncation ) {
@ -114,6 +115,7 @@ void cv_enkf_data_free( void * arg ) {
matrix_safe_free( cv_data->Rp );
matrix_safe_free( cv_data->Dp );
}
free( cv_data );
}
@ -122,6 +124,7 @@ void cv_enkf_data_free( void * arg ) {
void cv_enkf_init_update( void * arg ,
const bool_vector_type * ens_mask ,
const matrix_type * S ,
const matrix_type * R ,
const matrix_type * dObs ,
@ -643,6 +646,53 @@ long cv_enkf_get_options( void * arg , long flag) {
}
}
bool cv_enkf_has_var( const void * arg, const char * var_name) {
{
if (strcmp(var_name , ENKF_NCOMP_KEY_) == 0)
return true;
else if (strcmp(var_name , ENKF_TRUNCATION_KEY_) == 0)
return true;
else if (strcmp(var_name , NFOLDS_KEY) == 0)
return true;
else if (strcmp(var_name , CV_PEN_PRESS_KEY) == 0)
return true;
else
return false;
}
}
double cv_enkf_get_double( const void * arg, const char * var_name) {
const cv_enkf_data_type * module_data = cv_enkf_data_safe_cast_const( arg );
{
if (strcmp(var_name , ENKF_TRUNCATION_KEY_) == 0)
return module_data->truncation;
else
return -1;
}
}
int cv_enkf_get_int( const void * arg, const char * var_name) {
const cv_enkf_data_type * module_data = cv_enkf_data_safe_cast_const( arg );
{
if (strcmp(var_name , ENKF_NCOMP_KEY_) == 0)
return module_data->subspace_dimension;
else if (strcmp(var_name , NFOLDS_KEY) == 0)
return module_data->nfolds;
else
return -1;
}
}
bool cv_enkf_get_bool( const void * arg, const char * var_name) {
const cv_enkf_data_type * module_data = cv_enkf_data_safe_cast_const( arg );
{
if (strcmp(var_name , CV_PEN_PRESS_KEY) == 0)
return module_data->penalised_press;
else
return false;
}
}
@ -665,8 +715,9 @@ analysis_table_type SYMBOL_TABLE = {
.updateA = NULL,
.init_update = cv_enkf_init_update ,
.complete_update = cv_enkf_complete_update ,
.has_var = NULL,
.get_int = NULL,
.get_double = NULL,
.has_var = cv_enkf_has_var,
.get_int = cv_enkf_get_int,
.get_double = cv_enkf_get_double,
.get_bool = cv_enkf_get_bool,
.get_ptr = NULL,
};

View File

@ -73,19 +73,19 @@ 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 ncomp ,
dgesvd_vector_enum store_V0T ,
double * sig0,
matrix_type * U0 ,
matrix_type * V0T) {
double truncation ,
int ncomp ,
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);
if (((truncation > 0) && (ncomp < 0)) ||
((truncation < 0) && (ncomp > 0))) {
@ -95,7 +95,6 @@ int enkf_linalg_svd_truncation(const matrix_type * S ,
matrix_dgesvd(DGESVD_MIN_RETURN , store_V0T , workS , sig0 , U0 , V0T);
matrix_free( workS );
}
int i;
if (ncomp > 0)
@ -125,7 +124,7 @@ int enkf_linalg_svd_truncation(const matrix_type * S ,
matrix_resize(U0 , nrows , num_significant , true);
matrix_resize(V0T , num_significant , ncolumns , true);
}
else
else
util_abort("%s: truncation:%g ncomp:%d - invalid ambigous input.\n",__func__ , truncation , ncomp );
return num_significant;
}
@ -590,7 +589,8 @@ void enkf_linalg_get_PC( const matrix_type * S0,
double truncation,
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 );
@ -598,10 +598,12 @@ void enkf_linalg_get_PC( const matrix_type * S0,
matrix_type * U0 = matrix_alloc( nrobs , nrens );
matrix_type * S = matrix_alloc_copy( S0 );
double * inv_sig0 = util_calloc( nrmin , sizeof * inv_sig0 );
double * inv_sig0;
double_vector_iset( singular_values , nrmin - 1 , 0 );
matrix_subtract_row_mean( S );
ncomp = util_int_min( ncomp , nrmin );
inv_sig0 = double_vector_get_ptr( singular_values );
{
matrix_type * S_mean = matrix_alloc( nrobs , 1 );
int num_PC = enkf_linalg_svdS(S , truncation , ncomp, DGESVD_NONE , inv_sig0 , U0 , NULL);
@ -629,10 +631,11 @@ void enkf_linalg_get_PC( const matrix_type * S0,
matrix_dgemm( PC_obs , U0 , S_mean , true , false , 1.0 , 0.0 );
}
for (int i=0; i < double_vector_size( singular_values ); i++)
inv_sig0[i] = 1.0 / inv_sig0[i];
matrix_free( S_mean );
}
free( inv_sig0 );
matrix_free( S );
matrix_free( U0 );
}
@ -641,147 +644,114 @@ void enkf_linalg_get_PC( const matrix_type * S0,
void enkf_linalg_rml_enkfX1(matrix_type *X1, matrix_type *Udr, matrix_type *D, matrix_type *R)
{
/*This routine computes X1 for RML_EnKF module as X1 = Ud(T)*Cd(-1/2)*D -- D= (dk-do)
here the negative sign cancels with one needed in X3 matrix computation*/
/*
This routine computes X1 for RML_EnKF module as X1 = Ud(T)*Cd(-1/2)*D -- D= (dk-do)
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_dgemm( tmp, Udr, R, true, false, 1.0, 0.0);
printf("tmp matrix is computed");
matrix_dgemm( X1 , tmp, D,false,false, 1.0, 0.0);
printf("X1 is computed");
matrix_free(tmp);
matrix_matmul_with_transpose( tmp, Udr, R, true, false);
matrix_matmul( X1 , tmp, D);
matrix_free(tmp);
}
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 */
/* Since a+Ipd & Wd are diagonal in nature the computation is reduced to array operations*/
double * tmp = util_calloc(nsign , sizeof * tmp );
for (int i=0; i< nsign ; i++)
{
tmp[i] = 1/ (a+ (Wdr[i]*Wdr[i]));
matrix_scale_row(X1,i,tmp[i]);
}
matrix_assign(X2,X1);
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
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 */
matrix_type *tmp = matrix_alloc_copy(VdTr);
matrix_matlab_dump(tmp, "matrixVdTrcopy.dat");
printf("matrix X3 started");
for (int i=0; i< nsign ; i++)
{
printf("The value of Wd(%d) is = %5.2f \n",i, Wdr[i]);
matrix_scale_row(tmp, i, Wdr[i]);
}
/*
This routine computes X3 for RML_EnKF module as X3 = Vd *Wd*X2
*/
matrix_dgemm( X3 , tmp , X2 , true, false, 1.0, 0.0);
printf("\nWd: ");
matrix_type *tmp = matrix_alloc_copy(VdTr);
for (int i=0; i< nsign ; i++) {
printf("%5.2f ", Wdr[i]);
matrix_scale_row(tmp, i, Wdr[i]);
}
printf("\n\n");
matrix_matmul_with_transpose( X3 , tmp , X2 , true, false);
matrix_free(tmp);
}
void enkf_linalg_rml_enkfdA(matrix_type * dA1, matrix_type * Dm, matrix_type * X3) //dA = Dm * X3
{
matrix_dgemm (dA1, Dm, X3,false, false, 1.0, 0.0 );
}
double enkf_linalg_data_mismatch(matrix_type *D , matrix_type *R , matrix_type *Sk)
{
matrix_type * tmp = matrix_alloc (matrix_get_columns(D), matrix_get_columns(R));
double mean;
printf("-----------------------------------------------------------------\n");
printf("%s:%d Calling matrix_dgemm() \n",__func__ , __LINE__);
// C A B
matrix_dgemm(tmp, D, R,true, false, 1.0, 0.0);
printf("-----------------------------------------------------------------\n");
printf("%s:%d Calling matrix_dgemm() \n",__func__ , __LINE__);
matrix_dgemm(Sk, tmp, D, false, false, 1.0, 0.0);
printf("-----------------------------------------------------------------\n");
printf("The data mismatch computed");
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
mean = matrix_trace(Sk)/(matrix_get_columns(D));
return mean;
mismatch = matrix_trace(Sk)/(matrix_get_columns(D));
return mismatch;
}
// Cd = SampCov(E) (including (N-1) normalization)
void enkf_linalg_Covariance(matrix_type *Cd, const matrix_type *E, double nsc ,int nrobs)
{
matrix_matlab_dump( E, "matrixE.dat");
printf("Starting Dgemm for EE(T)\n");
matrix_dgemm(Cd, E, E,false,true, 1.0, 0.0);
for (int i=0; i< nrobs; i++)
{
for (int j=0;j< nrobs; j++)
{
if (i!=j)
matrix_iset(Cd, i, j, 0.0);
}
matrix_matmul_with_transpose(Cd, E, E,false,true);
for (int i=0; i< nrobs; i++) {
for (int j=0;j< nrobs; j++) {
if (i!=j)
matrix_iset(Cd, i, j, 0.0);
}
nsc= nsc*nsc;
printf("nsc = %5.3f\n",nsc);
}
nsc = nsc*nsc;
matrix_scale(Cd,nsc);
}
void enkf_linalg_rml_enkfAm(matrix_type * Um, double * Wm,int nsign1){
for (int i=0; i< nsign1 ; i++)
{
double sc = 1/ Wm[i];
matrix_scale_column(Um, i, sc);
}
// Scale columns (not rows!) of Um by entries in diagonal Wm
void enkf_linalg_rml_enkfAm(matrix_type * Um, const double * Wm,int nsign1){
for (int i=0; i< nsign1 ; i++) {
double sc = 1 / Wm[i];
matrix_scale_column(Um, i, sc);
}
}
void enkf_linalg_rml_enkfX4 (matrix_type *X4,matrix_type *Am, matrix_type *A){
matrix_dgemm(X4, Am, A, true, false, 1.0, 0.0);
}
void enkf_linalg_rml_enkfX5(matrix_type * X5,matrix_type * Am, matrix_type * X4){
matrix_dgemm (X5, Am, X4, false,false,1.0,0.0);
}
void enkf_linalg_rml_enkfX6(matrix_type * X6, matrix_type * Dk, matrix_type * X5){
matrix_dgemm(X6, Dk, X5, true, false, 1.0, 0.0);
}
void enkf_linalg_rml_enkfX7(matrix_type * X7, matrix_type * VdT, double * Wdr, double a, matrix_type * X6){
int nsign = matrix_get_rows(VdT);
int ens_size= matrix_get_columns(VdT);
matrix_type *tmp1= matrix_alloc_copy(VdT);
matrix_type *tmp2= matrix_alloc(ens_size,ens_size);
int ens_size = matrix_get_columns(VdT);
matrix_type *tmp1 = matrix_alloc_copy(VdT);
matrix_type *tmp2 = matrix_alloc(ens_size,ens_size);
for (int i=0; i< nsign ; i++)
{
double tmp = 1/ ( a + (Wdr[i]*Wdr[i]));
matrix_scale_row(tmp1, i ,tmp);
}
matrix_dgemm(tmp2, tmp1, VdT, true, false, 1.0, 0.0);
for (int i=0; i < nsign ; i++) {
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);
matrix_free(tmp1);
matrix_dgemm(X7, tmp2, X6, false,false, 1.0, 0.0);
matrix_free(tmp2);
}
void enkf_linalg_rml_enkfXdA2(matrix_type * dA2, matrix_type * Dk,matrix_type * X7){
matrix_dgemm(dA2, Dk, X7, false, false, 1.0, 0.0);
}

View File

@ -20,7 +20,8 @@
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <ert/util/type_macros.h>
#include <ert/util/util.h>
#include <ert/util/rng.h>
#include <ert/util/matrix.h>
@ -50,7 +51,7 @@ struct fwd_step_enkf_data_struct {
};
static UTIL_SAFE_CAST_FUNCTION_CONST( fwd_step_enkf_data , FWD_STEP_ENKF_TYPE_ID )
static UTIL_SAFE_CAST_FUNCTION( fwd_step_enkf_data , FWD_STEP_ENKF_TYPE_ID )
@ -177,6 +178,7 @@ void fwd_step_enkf_data_free( void * arg ) {
}
}
}
free( fwd_step_data );
}
@ -217,6 +219,37 @@ long fwd_step_enkf_get_options( void * arg , long flag) {
}
}
bool fwd_step_enkf_has_var( const void * arg, const char * var_name) {
{
if (strcmp(var_name , NFOLDS_KEY) == 0)
return true;
else if (strcmp(var_name , R2_LIMIT_KEY ) == 0)
return true;
else
return false;
}
}
double fwd_step_enkf_get_double( const void * arg, const char * var_name) {
const fwd_step_enkf_data_type * module_data = fwd_step_enkf_data_safe_cast_const( arg );
{
if (strcmp(var_name , R2_LIMIT_KEY ) == 0)
return module_data->r2_limit;
else
return -1;
}
}
int fwd_step_enkf_get_int( const void * arg, const char * var_name) {
const fwd_step_enkf_data_type * module_data = fwd_step_enkf_data_safe_cast_const( arg );
{
if (strcmp(var_name , NFOLDS_KEY) == 0)
return module_data->nfolds;
else
return -1;
}
}
@ -239,9 +272,10 @@ analysis_table_type SYMBOL_TABLE = {
.updateA = fwd_step_enkf_updateA,
.init_update = NULL ,
.complete_update = NULL ,
.has_var = NULL ,
.get_int = NULL ,
.get_double = NULL ,
.has_var = fwd_step_enkf_has_var,
.get_int = fwd_step_enkf_get_int ,
.get_double = fwd_step_enkf_get_double ,
.get_bool = NULL ,
.get_ptr = NULL
};

View File

@ -48,6 +48,7 @@ typedef struct {
static UTIL_SAFE_CAST_FUNCTION( sqrt_enkf_data , SQRT_ENKF_TYPE_ID )
static UTIL_SAFE_CAST_FUNCTION_CONST( sqrt_enkf_data , SQRT_ENKF_TYPE_ID )
void * sqrt_enkf_data_alloc( rng_type * rng ) {
@ -164,6 +165,27 @@ void sqrt_enkf_complete_update( void * arg ) {
}
}
bool sqrt_enkf_has_var( const void * arg, const char * var_name) {
const sqrt_enkf_data_type * module_data = sqrt_enkf_data_safe_cast_const( arg );
{
return std_enkf_has_var(module_data->std_data, var_name);
}
}
double sqrt_enkf_get_double( const void * arg, const char * var_name) {
const sqrt_enkf_data_type * module_data = sqrt_enkf_data_safe_cast_const( arg );
{
return std_enkf_get_double( module_data->std_data , var_name);
}
}
int sqrt_enkf_get_int( const void * arg, const char * var_name) {
const sqrt_enkf_data_type * module_data = sqrt_enkf_data_safe_cast_const( arg );
{
return std_enkf_get_int( module_data->std_data , var_name);
}
}
/*****************************************************************/
@ -189,9 +211,10 @@ analysis_table_type SYMBOL_TABLE = {
.init_update = sqrt_enkf_init_update,
.complete_update = sqrt_enkf_complete_update,
.get_options = sqrt_enkf_get_options,
.has_var = NULL,
.get_int = NULL,
.get_double = NULL,
.has_var = sqrt_enkf_has_var,
.get_int = sqrt_enkf_get_int,
.get_double = sqrt_enkf_get_double,
.get_bool = NULL,
.get_ptr = NULL
};

View File

@ -86,6 +86,8 @@ struct std_enkf_data_struct {
long option_flags;
};
static UTIL_SAFE_CAST_FUNCTION_CONST( std_enkf_data , STD_ENKF_TYPE_ID )
/*
This is a macro which will expand to generate a function:
@ -229,6 +231,36 @@ long std_enkf_get_options( void * arg , long flag ) {
}
}
bool std_enkf_has_var( const void * arg, const char * var_name) {
{
if (strcmp(var_name , ENKF_NCOMP_KEY_) == 0)
return true;
else if (strcmp(var_name , ENKF_TRUNCATION_KEY_) == 0)
return true;
else
return false;
}
}
double std_enkf_get_double( const void * arg, const char * var_name) {
const std_enkf_data_type * module_data = std_enkf_data_safe_cast_const( arg );
{
if (strcmp(var_name , ENKF_TRUNCATION_KEY_) == 0)
return module_data->truncation;
else
return -1;
}
}
int std_enkf_get_int( const void * arg, const char * var_name) {
const std_enkf_data_type * module_data = std_enkf_data_safe_cast_const( arg );
{
if (strcmp(var_name , ENKF_NCOMP_KEY_) == 0)
return module_data->subspace_dimension;
else
return -1;
}
}
/**
@ -257,9 +289,10 @@ analysis_table_type SYMBOL_TABLE = {
.updateA = NULL,
.init_update = NULL,
.complete_update = NULL,
.has_var = NULL,
.get_int = NULL,
.get_double = NULL,
.has_var = std_enkf_has_var,
.get_int = std_enkf_get_int,
.get_double = std_enkf_get_double,
.get_bool = NULL,
.get_ptr = NULL,
};

View File

@ -1,10 +1,19 @@
if (BUILD_APPLICATIONS)
add_test( analysis_module_test_RML ${EXECUTABLE_OUTPUT_PATH}/ert_module_test ${LIBRARY_OUTPUT_PATH}/rml_enkf.so )
add_test( analysis_module_test_RMLI ${EXECUTABLE_OUTPUT_PATH}/ert_module_test ${LIBRARY_OUTPUT_PATH}/rmli_enkf.so )
endif()
ert_module_name( VAR_RML rml_enkf ${LIBRARY_OUTPUT_PATH} )
add_executable(analysis_test_external_module analysis_test_external_module.c )
target_link_libraries( analysis_test_external_module analysis util test_util )
add_test( analysis_module_rml ${EXECUTABLE_OUTPUT_PATH}/analysis_test_external_module "RML_ENKF" ${LIBRARY_OUTPUT_PATH}/rml_enkf.so 41 ITER LAMBDA0)
add_test( analysis_module_rmli ${EXECUTABLE_OUTPUT_PATH}/analysis_test_external_module "RMLI_ENKF" ${LIBRARY_OUTPUT_PATH}/rmli_enkf.so 41 ITER)
add_test( analysis_module_rml ${EXECUTABLE_OUTPUT_PATH}/analysis_test_external_module "RML_ENKF" ${VAR_RML} 41
ITER:45
USE_PRIOR:False
LAMBDA_REDUCE:0.10
LAMBDA_INCREASE:2.5
ENKF_TRUNCATION:0.77
LAMBDA0:0.25
LAMBDA_MIN:0.01
LOG_FILE:LogFile.txt
CLEAR_LOG:True
LAMBDA_RECALCULATE:True )

View File

@ -26,6 +26,49 @@
void test_set_get(analysis_module_type * module , const char * var_value) {
char * var , *string_value;
util_binary_split_string( var_value , ":" , false , &var , &string_value);
if (var && string_value) {
printf("Testing variable:%s \n",var);
while (true) {
int int_value;
double double_value;
bool bool_value;
test_assert_true(analysis_module_has_var( module , var ));
if (util_sscanf_int( string_value , &int_value)) {
test_assert_true(analysis_module_set_var( module , var , string_value ));
test_assert_int_equal( int_value , analysis_module_get_int( module , var ));
break;
}
if (util_sscanf_double( string_value , &double_value)) {
test_assert_true(analysis_module_set_var( module , var , string_value ));
test_assert_double_equal( double_value , analysis_module_get_double( module , var ));
break;
}
if (util_sscanf_bool( string_value , &bool_value)) {
test_assert_true(analysis_module_set_var( module , var , string_value ));
test_assert_bool_equal( bool_value , analysis_module_get_bool( module , var ));
break;
}
test_assert_true(analysis_module_set_var( module , var , string_value ));
test_assert_string_equal( string_value , (const char *) analysis_module_get_ptr( module , var ));
break;
}
} else {
fprintf(stderr,"Invalid test input data: %s -> could not split in var:value\n" , var_value);
exit(1);
}
}
void load_module( rng_type * rng , const char * user_name , const char * lib_name, const char * options_str , int nvar , const char ** var_list) {
long flags = strtol(options_str , NULL , 10);
analysis_module_type * analysis_module = analysis_module_alloc_external(rng , user_name , lib_name);
@ -36,9 +79,9 @@ void load_module( rng_type * rng , const char * user_name , const char * lib_nam
test_assert_string_equal( lib_name , analysis_module_get_lib_name(analysis_module));
test_assert_true( analysis_module_is_instance( analysis_module));
for (int i=0; i < nvar; i++) {
printf("has_var(%s) \n" , var_list[i]);
test_assert_true( analysis_module_has_var(analysis_module , var_list[i]));
{
for (int i=0; i < nvar; i++)
test_set_get( analysis_module , var_list[i] );
}
test_assert_false( analysis_module_has_var(analysis_module , "DoesNotHaveThisVariable"));

View File

@ -28,6 +28,7 @@ extern "C" {
#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>
@ -104,6 +105,7 @@ typedef struct config_struct config_type;
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 );

View File

@ -261,6 +261,10 @@ config_type * config_alloc() {
const subst_list_type * config_get_define_list( const config_type * config) {
return config->define_list;
}
static void config_clear_content_items( config_type * config ) {
hash_free( config->content_items );
@ -302,6 +306,11 @@ void config_free(config_type * config) {
hash_free(config->content_items);
hash_free(config->messages);
util_safe_free( config->config_file );
util_safe_free( config->abs_path );
if (config->invoke_path != NULL)
config_root_path_free( config->invoke_path );
free(config);
}

View File

@ -92,9 +92,11 @@ char * config_content_item_alloc_joined_string(const config_content_item_type *
char * joined_string = NULL;
for (int i =0; i < occurences ; i++) {
joined_string = util_strcat_realloc( joined_string , config_content_item_ialloc_joined_string(item , sep , i));
char * element = config_content_item_ialloc_joined_string(item , sep , i);
joined_string = util_strcat_realloc( joined_string , element);
if (i < (occurences - 1))
joined_string = util_strcat_realloc( joined_string , sep );
free( element );
}
return joined_string;

View File

@ -28,6 +28,9 @@ target_link_libraries( config_content_item config test_util )
add_executable( config_argc config_argc.c)
target_link_libraries( config_argc config test_util )
add_executable( config_define config_define.c)
target_link_libraries( config_define config test_util )
add_executable( config_error config_error.c)
target_link_libraries( config_error config test_util )
add_test( config_error ${EXECUTABLE_OUTPUT_PATH}/config_error )
@ -45,6 +48,7 @@ add_test( config_typeOK ${EXECUTABLE_OUTPUT_PATH}/config_typeOK ${C
add_test( config_typeFail ${EXECUTABLE_OUTPUT_PATH}/config_typeFail ${CMAKE_CURRENT_SOURCE_DIR}/data/type_testFail )
add_test( config_append_test ${EXECUTABLE_OUTPUT_PATH}/config_append_test ${CMAKE_CURRENT_SOURCE_DIR}/data/append_test )
add_test( config_node_test ${EXECUTABLE_OUTPUT_PATH}/config_node_test ${CMAKE_CURRENT_SOURCE_DIR}/data/append_test )
add_test( config_define ${EXECUTABLE_OUTPUT_PATH}/config_define ${CMAKE_CURRENT_SOURCE_DIR}/data/define_test )
add_test( config_path_elm ${EXECUTABLE_OUTPUT_PATH}/config_path_elm )
add_test( config_content_node ${EXECUTABLE_OUTPUT_PATH}/config_content_node )
add_test( config_content_item ${EXECUTABLE_OUTPUT_PATH}/config_content_item ${CMAKE_CURRENT_SOURCE_DIR}/data/content_item_test)

View File

@ -0,0 +1,69 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'config_define.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 <stdio.h>
#include <ert/util/test_util.h>
#include <ert/util/util.h>
#include <ert/util/subst_list.h>
#include <ert/config/config.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 ));
{
const subst_list_type * define_list = config_get_define_list( config );
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"));
test_assert_false( subst_list_has_key( define_list , "VARY"));
test_assert_string_equal( subst_list_get_value( define_list , "VAR1") , "100");
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_type * config_create_schema() {
config_type * config = config_alloc();
config_add_schema_item( config , "SET" , true );
config_add_schema_item( config , "NOTSET" , false );
return config;
}
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);
}

View File

@ -0,0 +1,5 @@
DEFINE VAR1 100
DEFINE VAR2 10
DEFINE VARX 1
SET VAR1 100

View File

@ -52,7 +52,7 @@ int main(int argc , char ** argv) {
if (argc < 3) usage();
{
ecl_sum_type * first_ecl_sum; /* This governs the timing */
ecl_sum_type * first_ecl_sum = NULL; /* This governs the timing */
vector_type * ecl_sum_list = vector_alloc_new();
time_interval_type * time_union = NULL;
time_interval_type * time_intersect = NULL;
@ -74,30 +74,32 @@ int main(int argc , char ** argv) {
util_alloc_file_components( argv[iarg] , &path , &basename , NULL);
fprintf(stderr,"Loading case: %s/%s" , path , basename); fflush(stderr);
ecl_sum = ecl_sum_fread_alloc_case( argv[iarg] , ":");
if (iarg == 1) {
first_ecl_sum = ecl_sum; /* Keep track of this - might sort the vector */
time_union = time_interval_alloc_copy( ecl_sum_get_sim_time( ecl_sum ));
time_intersect = time_interval_alloc_copy( ecl_sum_get_sim_time( ecl_sum ));
if (use_time_union)
time = time_union;
else
time = time_intersect;
vector_append_owned_ref( ecl_sum_list , ecl_sum , ecl_sum_free__ );
} else {
const time_interval_type * ti = ecl_sum_get_sim_time( ecl_sum );
if (time_interval_has_overlap(time , ti)) {
time_interval_intersect( time_intersect , ti );
time_interval_extend( time_union , ti );
if (ecl_sum) {
if (first_ecl_sum == NULL) {
first_ecl_sum = ecl_sum; /* Keep track of this - might sort the vector */
time_union = time_interval_alloc_copy( ecl_sum_get_sim_time( ecl_sum ));
time_intersect = time_interval_alloc_copy( ecl_sum_get_sim_time( ecl_sum ));
vector_append_owned_ref( ecl_sum_list , ecl_sum , ecl_sum_free__ );
load_count++;
if (use_time_union)
time = time_union;
else
time = time_intersect;
vector_append_owned_ref( ecl_sum_list , ecl_sum , ecl_sum_free__ );
} else {
fprintf(stderr,"** Warning case:%s has no time overlap - discarded \n",ecl_sum_get_case( ecl_sum ));
ecl_sum_free( ecl_sum );
const time_interval_type * ti = ecl_sum_get_sim_time( ecl_sum );
if (time_interval_has_overlap(time , ti)) {
time_interval_intersect( time_intersect , ti );
time_interval_extend( time_union , ti );
vector_append_owned_ref( ecl_sum_list , ecl_sum , ecl_sum_free__ );
load_count++;
} else {
fprintf(stderr,"** Warning case:%s has no time overlap - discarded \n",ecl_sum_get_case( ecl_sum ));
ecl_sum_free( ecl_sum );
}
}
}
} else
fprintf(stderr," --- no data found?!");
iarg++;
fprintf(stderr,"\n");

View File

@ -44,7 +44,7 @@ int main(int argc, char ** argv) {
stream = stdout;
ecl_grid = ecl_grid_alloc(grid_file);
ecl_grid_dump_ascii( ecl_grid , false , stream );
ecl_grid_dump_ascii( ecl_grid , true , stream );
if (output_file != NULL)
fclose( stream );

View File

@ -42,7 +42,7 @@ int main(int argc, char ** argv) {
if (argc >= 3) {
ecl_grid_type * grid2 = ecl_grid_alloc( argv[2] );
if (ecl_grid_compare( ecl_grid , grid2 , true , false))
if (ecl_grid_compare( ecl_grid , grid2 , true , false , false))
printf("\nThe grids %s %s are IDENTICAL.\n" , argv[1] , argv[2]);
else {
printf("\n");

View File

@ -20,65 +20,87 @@
#include <stdio.h>
#include <stdbool.h>
#include <ert/util/timer.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl/ecl_file.h>
void test_case( const char * base , bool load_all) {
timer_type * ti = timer_alloc(false);
timer_type * tr = timer_alloc(false);
timer_type * tg = timer_alloc(false);
timer_type * ti = timer_alloc(false);
timer_type * tr = timer_alloc(false);
timer_type * tg = timer_alloc(false);
char * grid_file = ecl_util_alloc_filename( NULL , base , ECL_EGRID_FILE , false , 0 );
char * init_file = ecl_util_alloc_filename( NULL , base , ECL_INIT_FILE , false , 0 );
char * restart_file = ecl_util_alloc_filename( NULL , base , ECL_UNIFIED_RESTART_FILE , false , 0 );
char * grid_file = NULL;
char * init_file = NULL;
char * restart_file = NULL;
ecl_grid_type * grid;
ecl_file_type * restart;
ecl_file_type * init;
// grid_file = ecl_util_alloc_filename( NULL , base , ECL_EGRID_FILE , false , 0 );
// init_file = ecl_util_alloc_filename( NULL , base , ECL_INIT_FILE , false , 0 );
restart_file = ecl_util_alloc_filename( NULL , base , ECL_UNIFIED_RESTART_FILE , false , 0 );
timer_start( tg );
grid = ecl_grid_alloc(grid_file );
timer_stop( tg );
timer_start( tg );
if (grid_file)
{
ecl_grid_type * grid = NULL;
grid = ecl_grid_alloc(grid_file );
ecl_grid_free( grid );
}
timer_stop( tg );
timer_start( ti );
init = ecl_file_open( init_file , 0);
if (load_all)
ecl_file_load_all( init );
timer_stop( ti );
timer_start( ti );
if (init_file)
{
ecl_file_type * init = NULL;
init = ecl_file_open( init_file , 0);
if (load_all)
{
ecl_file_load_all( init );
}
ecl_file_close( init );
}
timer_stop( ti );
timer_start( tr );
restart = ecl_file_open( restart_file , 0);
if (load_all)
ecl_file_load_all( restart );
timer_stop( tr );
timer_start( tr );
if (restart_file)
{
ecl_file_type * restart = NULL;
restart = ecl_file_open( restart_file , 0);
if (load_all)
{
ecl_file_load_all( restart );
}
ecl_file_close( restart );
}
timer_stop( tr );
printf("%-64s Restart:%8.4f Grid:%8.4f Init:%8.4f \n",
base,
timer_get_total_time( tr ),
timer_get_total_time( tg ),
timer_get_total_time( ti ));
printf("%-64s Restart:%8.4f Grid:%8.4f Init:%8.4f \n",
base,
timer_get_total_time( tr ),
timer_get_total_time( tg ),
timer_get_total_time( ti ));
timer_free( tr );
timer_free( ti );
timer_free( tg );
ecl_file_close( init );
ecl_file_close( restart );
ecl_grid_free( grid );
free( grid_file );
free( init_file );
free( restart_file );
timer_free( tr );
timer_free( ti );
timer_free( tg );
free( grid_file );
free( init_file );
free( restart_file );
}
int main(int argc, char ** argv) {
bool load_all = true;
bool load_all = false;
int i;
// system("pause");
for (i=1; i < argc; i++)
test_case( argv[i] , load_all);
system("pause");
}

View File

@ -26,6 +26,7 @@ extern "C" {
typedef struct ecl_coarse_cell_struct ecl_coarse_cell_type;
bool ecl_coarse_cell_equal( const ecl_coarse_cell_type * coarse_cell1 , const ecl_coarse_cell_type * coarse_cell2);
ecl_coarse_cell_type * ecl_coarse_cell_alloc( );
void ecl_coarse_cell_update( ecl_coarse_cell_type * coarse_cell , int i , int j , int k , int global_index );
void ecl_coarse_cell_free( ecl_coarse_cell_type * coarse_cell );
@ -49,7 +50,7 @@ extern "C" {
int ecl_coarse_cell_iget_active_cell_index( const ecl_coarse_cell_type * coarse_cell , int index);
int ecl_coarse_cell_iget_active_value( const ecl_coarse_cell_type * coarse_cell , int index);
int ecl_coarse_cell_get_num_active( const ecl_coarse_cell_type * coarse_cell);
void ecl_coarse_cell_fprintf( ecl_coarse_cell_type * coarse_cell , FILE * stream );
void ecl_coarse_cell_fprintf( const ecl_coarse_cell_type * coarse_cell , FILE * stream );
#ifdef __cplusplus
}

View File

@ -36,8 +36,6 @@ extern "C" {
*/
#define ECLIPSE_BYTE_ORDER __BIG_ENDIAN // Alternatively: __LITTLE_ENDIAN
#define WIN32 1
#ifdef BYTE_ORDER
#if BYTE_ORDER == ECLIPSE_BYTE_ORDER

View File

@ -83,6 +83,7 @@ extern "C" {
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);
@ -96,7 +97,8 @@ extern "C" {
ecl_kw_type * ecl_file_iget_named_kw( const ecl_file_type * file , const char * kw, int ith);
ecl_type_enum ecl_file_iget_named_type( const ecl_file_type * file , const char * kw , int ith);
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);
@ -118,7 +120,9 @@ extern "C" {
bool ecl_file_select_rstblock_sim_time( ecl_file_type * ecl_file , time_t sim_time);
bool ecl_file_select_rstblock_report_step( ecl_file_type * ecl_file , int report_step);
bool ecl_file_iselect_rstblock( ecl_file_type * ecl_file , int seqnum_index );
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_iopen_rstblock( const char * filename , int seqnum_index , int flags);

View File

@ -46,6 +46,7 @@ typedef struct inv_map_struct inv_map_type;
const char * ecl_file_kw_get_header( const ecl_file_kw_type * file_kw );
int ecl_file_kw_get_size( const ecl_file_kw_type * file_kw );
ecl_type_enum ecl_file_kw_get_type( const ecl_file_kw_type * file_kw);
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);

View File

@ -50,9 +50,11 @@ extern "C" {
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);
int ecl_grid_get_global_index_from_xy_bottom( const ecl_grid_type * ecl_grid , double x , double y);
void ecl_grid_get_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_corner_xyz1(const ecl_grid_type * grid , int global_index , int corner_nr , double * xpos , double * ypos , double * zpos );
ecl_grid_type * ecl_grid_alloc_dx_dy_dz_tops( int nx, int ny , int nz , const double * dx , const double * dy , const double * dz , const double * tops , const int * actnum);
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 );
@ -63,6 +65,7 @@ extern "C" {
bool ecl_grid_cell_contains_xyz1( const ecl_grid_type * ecl_grid , int global_index , double x , double y , double z);
bool ecl_grid_cell_contains_xyz3( const ecl_grid_type * ecl_grid , int i , int j , int k, double x , double y , double z );
double ecl_grid_get_cell_volume1( const ecl_grid_type * ecl_grid, int global_index );
double ecl_grid_get_cell_volume1_tskille( const ecl_grid_type * ecl_grid, int global_index );
double ecl_grid_get_cell_volume3( const ecl_grid_type * ecl_grid, int i , int j , int k);
bool ecl_grid_cell_contains1(const ecl_grid_type * grid , int global_index , double x , double y , double z);
bool ecl_grid_cell_contains3(const ecl_grid_type * grid , int i , int j ,int k , double x , double y , double z);
@ -90,6 +93,7 @@ extern "C" {
ecl_grid_type * ecl_grid_alloc_rectangular( int nx , int ny , int nz , double dx , double dy , double dz , const int * actnum);
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 );
@ -112,7 +116,7 @@ extern "C" {
void ecl_grid_get_xyz1(const ecl_grid_type * grid , int global_index , double *xpos , double *ypos , double *zpos);
void ecl_grid_get_xyz1A(const ecl_grid_type * grid , int active_index , double *xpos , double *ypos , double *zpos);
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 verbose);
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);
@ -136,8 +140,10 @@ extern "C" {
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(const ecl_grid_type * grid , bool active_only , 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);
void ecl_grid_dump_ascii_cell3(ecl_grid_type * grid , int i , int j , int k , FILE * stream , const double * offset);
/* lgr related functions */
const ecl_grid_type * ecl_grid_get_cell_lgr3(const ecl_grid_type * grid , int i, int j , int k);
const ecl_grid_type * ecl_grid_get_cell_lgr1A(const ecl_grid_type * grid , int active_index);
@ -177,14 +183,32 @@ extern "C" {
ecl_kw_type * ecl_grid_alloc_actnum_kw( const ecl_grid_type * grid );
ecl_kw_type * ecl_grid_alloc_hostnum_kw( const ecl_grid_type * grid );
ecl_kw_type * ecl_grid_alloc_gridhead_kw( int nx, int ny , int nz , int grid_nr);
ecl_grid_type * ecl_grid_alloc_copy( const ecl_grid_type * src_grid );
void ecl_grid_ri_export( const ecl_grid_type * ecl_grid , double * ri_points);
void ecl_grid_cell_ri_export( const ecl_grid_type * ecl_grid , int global_index , double * ri_points);
bool ecl_grid_dual_grid( const ecl_grid_type * ecl_grid );
int ecl_grid_get_num_nnc( const ecl_grid_type * grid );
bool ecl_grid_cell_regular3( const ecl_grid_type * ecl_grid, int i,int j,int k);
bool ecl_grid_cell_regular1( const ecl_grid_type * ecl_grid, int global_index);
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);
void ecl_grid_init_actnum_data( const ecl_grid_type * grid , int * actnum );
bool ecl_grid_use_mapaxes( const ecl_grid_type * grid );
void ecl_grid_init_mapaxes_data_double( const ecl_grid_type * grid , double * mapaxes);
void ecl_grid_reset_actnum( ecl_grid_type * grid , const int * actnum );
UTIL_IS_INSTANCE_HEADER( ecl_grid );
UTIL_SAFE_CAST_HEADER( ecl_grid );
#ifdef __cplusplus
}

View File

@ -26,6 +26,7 @@ extern "C" {
#include <stdio.h>
#include <ert/util/buffer.h>
#include <ert/util/type_macros.h>
#include <ert/ecl/fortio.h>
#include <ert/ecl/ecl_util.h>
@ -34,6 +35,8 @@ 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);
@ -59,6 +62,7 @@ extern "C" {
void ecl_kw_fread(ecl_kw_type * , fortio_type * );
ecl_kw_type * ecl_kw_fread_alloc(fortio_type *);
void ecl_kw_free_data(ecl_kw_type *);
void ecl_kw_fread_indexed_data(fortio_type * fortio, offset_type data_offset, ecl_type_enum ecl_type, int element_count, const int_vector_type* index_map, char* buffer);
void ecl_kw_free(ecl_kw_type *);
void ecl_kw_free__(void *);
ecl_kw_type * ecl_kw_alloc_copy (const ecl_kw_type *);
@ -109,6 +113,7 @@ extern "C" {
bool ecl_kw_is_grdecl_file(FILE * );
bool ecl_kw_is_kw_file(FILE * , bool );
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 * );

View File

@ -163,6 +163,7 @@ typedef struct ecl_region_struct ecl_region_type;
void ecl_region_kw_imul( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , const ecl_kw_type * mul_kw , bool force_active);
void ecl_region_kw_isub( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , const ecl_kw_type * delta_kw , bool force_active);
bool ecl_region_equal( const ecl_region_type * region1 , const ecl_region_type * region2);
/*****************************************************************/
/* set/get the name */

View File

@ -86,7 +86,6 @@ typedef struct ecl_sum_struct ecl_sum_type;
void ecl_sum_summarize( const ecl_sum_type * ecl_sum , FILE * stream );
bool ecl_sum_general_is_total(const ecl_sum_type * ecl_sum , const char * gen_key);
bool ecl_sum_var_is_total(const ecl_sum_type * ecl_sum , const char * gen_key);
void ecl_sum_free_data(ecl_sum_type * );
void ecl_sum_free__(void * );
void ecl_sum_free(ecl_sum_type * );

View File

@ -141,6 +141,14 @@ typedef enum {
#define ECL_PHASE_ENUM_SIZE 3
typedef enum {
ECL_METRIC_UNITS = 0,
ECL_FIELD_UNITS = 1,
ECL_LAB_UNITS = 2
} 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
// For unformatted files:
@ -177,6 +185,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);
bool ecl_util_valid_basename_fmt( const char * basename_fmt );
bool ecl_util_valid_basename( const char * basename );

View File

@ -0,0 +1,59 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'fault_block.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 __FAULT_BLOCK_H__
#define __FAULT_BLOCK_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <ert/util/int_vector.h>
#include <ert/util/double_vector.h>
#include <ert/util/type_macros.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl/ecl_kw.h>
typedef struct fault_block_struct fault_block_type;
void fault_block_free__( void * arg);
int fault_block_get_size( const fault_block_type * block );
double fault_block_get_xc( fault_block_type * fault_block );
double fault_block_get_yc( fault_block_type * fault_block );
int fault_block_get_id( const fault_block_type * block );
int fault_block_get_size( const fault_block_type * fault_block );
void fault_block_export_cell(const fault_block_type * fault_block , int index , int * i , int * j , int * k , double * x, double * y, double * z);
void fault_block_assign_to_region( fault_block_type * fault_block , int region_id );
const int_vector_type * fault_block_get_region_list( const fault_block_type * fault_block );
int fault_block_iget_j(const fault_block_type * fault_block , int index);
int fault_block_iget_i(const fault_block_type * fault_block , int index);
void fault_block_add_cell( fault_block_type * fault_block , int i , int j);
bool fault_block_trace_edge( const fault_block_type * block , double_vector_type * x_list , double_vector_type * y_list, int_vector_type * cell_list);
const int_vector_type * fault_block_get_global_index_list( const fault_block_type * fault_block);
void fault_block_copy_content(fault_block_type * target_block , const fault_block_type * src_block );
void fault_block_list_neighbours( const fault_block_type * block, int_vector_type * neighbour_list);
UTIL_IS_INSTANCE_HEADER(fault_block);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,61 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'fault_block_layer.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 __FAULT_BLOCK_LAYER_H__
#define __FAULT_BLOCK_LAYER_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <ert/util/type_macros.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/fault_block.h>
#include <ert/ecl/layer.h>
UTIL_IS_INSTANCE_HEADER(fault_block_layer);
typedef struct fault_block_layer_struct fault_block_layer_type;
fault_block_layer_type * fault_block_layer_alloc( const ecl_grid_type * grid , int k);
void fault_block_layer_free( fault_block_layer_type * layer );
void fault_block_layer_free__( void * arg );
bool fault_block_layer_has_block( const fault_block_layer_type * layer , int block_id);
void fault_block_layer_del_block( fault_block_layer_type * layer , int block_id);
fault_block_type * fault_block_layer_add_block( fault_block_layer_type * layer , int block_id);
fault_block_type * fault_block_layer_get_block( const fault_block_layer_type * layer , int block_id);
fault_block_type * fault_block_layer_iget_block( const fault_block_layer_type * layer , int storage_index);
fault_block_type * fault_block_layer_safe_get_block( fault_block_layer_type * layer , int block_id);
int fault_block_layer_get_max_id( const fault_block_layer_type * layer );
int fault_block_layer_get_next_id( const fault_block_layer_type * layer );
int fault_block_layer_get_size( const fault_block_layer_type * layer);
bool fault_block_layer_scan_kw( fault_block_layer_type * layer , const ecl_kw_type * fault_block_kw);
bool fault_block_layer_load_kw( fault_block_layer_type * layer , const ecl_kw_type * fault_block_kw);
int fault_block_layer_get_k( const fault_block_layer_type * layer );
void fault_block_layer_scan_layer( fault_block_layer_type * fault_layer , layer_type * layer);
void fault_block_layer_insert_block_content( fault_block_layer_type * layer , const fault_block_type * src_block);
bool fault_block_layer_export( const fault_block_layer_type * layer , ecl_kw_type * faultblock_kw);
const ecl_grid_type * fault_block_layer_get_grid( const fault_block_layer_type * layer );
layer_type * fault_block_layer_get_layer( const fault_block_layer_type * layer );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -27,6 +27,7 @@ extern "C" {
#include <stdbool.h>
#include <ert/util/util.h>
#include <ert/util/type_macros.h>
typedef enum {
FORTIO_NOENTRY = 0, /* File does not exists at all - application error. */
@ -68,8 +69,10 @@ typedef struct fortio_struct 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 );
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);
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 );
bool fortio_fclose_stream( fortio_type * fortio );
@ -77,6 +80,10 @@ typedef struct fortio_struct fortio_type;
bool fortio_stream_is_open( const fortio_type * fortio );
bool fortio_assert_stream_open( fortio_type * fortio );
UTIL_IS_INSTANCE_HEADER( fortio );
UTIL_SAFE_CAST_HEADER( fortio );
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,78 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'layer.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 __LAYER_H__
#define __LAYER_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <ert/util/int_vector.h>
#include <ert/util/struct_vector.h>
#include <ert/util/type_macros.h>
/*
The elements in this enum are (ab)used as indexes into a int[] vector;
i.e. the must span the values 0..3.
*/
typedef enum {
RIGHT_EDGE = 0,
LEFT_EDGE = 1,
TOP_EDGE = 2,
BOTTOM_EDGE = 3
} edge_dir_enum;
typedef struct {
int i;
int j;
} int_point2d_type;
typedef struct layer_struct layer_type;
int layer_get_nx( const layer_type * layer );
int layer_get_ny( const layer_type * layer );
void layer_fprintf_cell( const layer_type * layer , int i , int j , FILE * stream);
void layer_fprintf( const layer_type * layer , FILE * stream);
void layer_fprintf_box( const layer_type * layer , FILE * stream , int i1 , int i2 , int j1 , int j2);
layer_type * layer_alloc(int nx , int ny);
void layer_free( layer_type * layer );
int layer_replace_cell_values( layer_type * layer , int old_value , int new_value);
int layer_iget_cell_value( const layer_type * layer, int i , int j);
void layer_iset_cell_value( layer_type * layer , int i , int j , int value);
int layer_iget_edge_value( const layer_type * layer , int i , int j , edge_dir_enum dir);
bool layer_cell_on_edge( const layer_type * layer , int i , int j);
int layer_get_ny( const layer_type * layer);
int layer_get_nx( const layer_type * layer);
int layer_get_cell_sum( const layer_type * layer );
bool layer_trace_block_content( layer_type * layer , bool erase , int start_i , int start_j , int value , int_vector_type * i_list , int_vector_type * j_list);
bool layer_trace_block_edge( const layer_type * layer , int i , int j , int value , struct_vector_type * corner_list , int_vector_type * cell_list);
UTIL_IS_INSTANCE_HEADER( layer );
UTIL_SAFE_CAST_HEADER( layer );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -50,6 +50,9 @@ extern "C" {
int nnc_info_get_total_size( const nnc_info_type * nnc_info );
void nnc_info_fprintf(const nnc_info_type * nnc_info , FILE * stream);
bool nnc_info_equal( const nnc_info_type * nnc_info1 , const nnc_info_type * nnc_info2 );
nnc_info_type * nnc_info_alloc_copy( const nnc_info_type * src_info );
#ifdef __cplusplus
}
#endif

View File

@ -31,6 +31,7 @@ extern "C" {
UTIL_IS_INSTANCE_HEADER(nnc_vector);
nnc_vector_type * nnc_vector_alloc(int lgr_nr);
nnc_vector_type * nnc_vector_alloc_copy(const nnc_vector_type * src_vector);
void nnc_vector_free( nnc_vector_type * nnc_vector );
void nnc_vector_add_nnc(nnc_vector_type * nnc_vector, int global_cell_number, int nnc_index);
const int_vector_type * nnc_vector_get_grid_index_list(const nnc_vector_type * nnc_vector);
@ -38,7 +39,8 @@ extern "C" {
int nnc_vector_get_lgr_nr(const nnc_vector_type * nnc_vector );
void nnc_vector_free__(void * arg);
int nnc_vector_get_size( const nnc_vector_type * nnc_vector );
bool nnc_vector_equal( const nnc_vector_type * nnc_vector1 , const nnc_vector_type * nnc_vector2);
#ifdef __cplusplus
}
#endif

View File

@ -39,9 +39,10 @@ extern "C" {
void point_inplace_sub(point_type * point , const point_type * sub);
void point_inplace_add(point_type * point , const point_type * add);
void point_inplace_scale(point_type * point , double scale_factor);
bool point_equal( const point_type *p1 , const point_type * p2);
void point_compare( const point_type *p1 , const point_type * p2, bool * equal);
void point_dump( const point_type * p , FILE * stream);
void point_dump_ascii( const point_type * p , FILE * stream);
void point_dump_ascii( const point_type * p , FILE * stream , const double * offset);
void point_fprintf( const point_type * p , FILE * stream );
void point_free( point_type * p);
void point_set( point_type *p , double x , double y , double z);
@ -53,6 +54,7 @@ extern "C" {
double point_dot_product( const point_type * v1 , const point_type * v2);
void point_normal_vector(point_type * n, const point_type * p0, const point_type * p1 , const point_type * p2);
double point_plane_distance(const point_type * p , const point_type * n , const point_type * plane_point);
double point3_plane_distance(const point_type * p0 , const point_type * p1 , const point_type * p2 , const point_type * x);
#ifdef __cplusplus
}

View File

@ -34,6 +34,7 @@ struct tetrahedron_struct {
void tetrahedron_init( tetrahedron_type * tet , const point_type * p0 , const point_type * p1 , const point_type * p2 , const point_type * p3);
double tetrahedron_volume( const tetrahedron_type * tet );
bool tetrahedron_contains( const tetrahedron_type * tet , const point_type * p);
void tetrahedron_fprintf( const tetrahedron_type * tet , FILE * stream , const double * offset);
#endif

View File

@ -2,9 +2,84 @@ include_directories( ext )
file(GLOB ext_source "ext/*.c" )
file(GLOB ext_header "ext/*.h" )
set( source_files ecl_rsthead.c ecl_sum_tstep.c ecl_rst_file.c ecl_init_file.c ecl_grid_cache.c smspec_node.c ecl_kw_grdecl.c ecl_file_kw.c ecl_grav.c ecl_grav_calc.c ecl_smspec.c ecl_sum_data.c ecl_util.c ecl_kw.c ecl_sum.c fortio.c ecl_rft_file.c ecl_rft_node.c ecl_rft_cell.c ecl_grid.c ecl_coarse_cell.c ecl_box.c ecl_io_config.c ecl_file.c ecl_region.c point.c tetrahedron.c ecl_subsidence.c ecl_grid_dims.c grid_dims.c nnc_info.c ecl_grav_common.c nnc_vector.c ecl_nnc_export.c${ext_source})
set( source_files
ecl_rsthead.c
ecl_sum_tstep.c
ecl_rst_file.c
ecl_init_file.c
ecl_grid_cache.c
smspec_node.c
ecl_kw_grdecl.c
ecl_file_kw.c
ecl_grav.c
ecl_grav_calc.c
ecl_smspec.c
ecl_sum_data.c
ecl_util.c
ecl_kw.c
ecl_sum.c
fortio.c
ecl_rft_file.c
ecl_rft_node.c
ecl_rft_cell.c
ecl_grid.c
ecl_coarse_cell.c
ecl_box.c
ecl_io_config.c
ecl_file.c
ecl_region.c
point.c
tetrahedron.c
ecl_subsidence.c
ecl_grid_dims.c
grid_dims.c
nnc_info.c
ecl_grav_common.c
nnc_vector.c
ecl_nnc_export.c
layer.c
fault_block_layer.c
${ext_source})
set( header_files ecl_rsthead.h ecl_sum_tstep.h ecl_rst_file.h ecl_init_file.h smspec_node.h ecl_grid_cache.h ecl_kw_grdecl.h ecl_file_kw.h ecl_grav.h ecl_grav_calc.h ecl_endian_flip.h ecl_smspec.h ecl_sum_data.h ecl_util.h ecl_kw.h ecl_sum.h fortio.h ecl_rft_file.h ecl_rft_node.h ecl_rft_cell.h ecl_box.h ecl_coarse_cell.h ecl_grid.h ecl_io_config.h ecl_file.h ecl_region.h ecl_kw_magic.h ecl_subsidence.h ecl_grid_dims.h grid_dims.h nnc_info.h nnc_vector.h ${ext_header} ecl_grav_common.h ecl_nnc_export.h)
set( header_files
ecl_rsthead.h
ecl_sum_tstep.h
ecl_rst_file.h
ecl_init_file.h
smspec_node.h
ecl_grid_cache.h
ecl_kw_grdecl.h
ecl_file_kw.h
ecl_grav.h
ecl_grav_calc.h
ecl_endian_flip.h
ecl_smspec.h
ecl_sum_data.h
ecl_util.h
ecl_kw.h
ecl_sum.h
fortio.h
ecl_rft_file.h
ecl_rft_node.h
ecl_rft_cell.h
ecl_box.h
ecl_coarse_cell.h
ecl_grid.h
ecl_io_config.h
ecl_file.h
ecl_region.h
ecl_kw_magic.h
ecl_subsidence.h
ecl_grid_dims.h
grid_dims.h
nnc_info.h
nnc_vector.h
ecl_grav_common.h
ecl_nnc_export.h
layer.h
fault_block.h
fault_block_layer.h
${ext_header})
if (ERT_USE_OPENMP)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")

View File

@ -119,6 +119,8 @@ struct ecl_coarse_cell_struct {
};
static UTIL_SAFE_CAST_FUNCTION( ecl_coarse_cell , ECL_COARSE_CELL_TYPE_ID )
void ecl_coarse_cell_assert( ecl_coarse_cell_type * coarse_cell ) {
@ -157,6 +159,37 @@ ecl_coarse_cell_type * ecl_coarse_cell_alloc() {
}
bool ecl_coarse_cell_equal( const ecl_coarse_cell_type * coarse_cell1 , const ecl_coarse_cell_type * coarse_cell2) {
bool equal = true;
if (coarse_cell1->active_index != coarse_cell2->active_index)
equal = false;
if (coarse_cell1->active_fracture_index != coarse_cell2->active_fracture_index)
equal = false;
if (equal) {
if (memcmp( coarse_cell1->ijk , coarse_cell2->ijk , 6 * sizeof * coarse_cell1->ijk) != 0)
equal = false;
}
if (equal)
equal = int_vector_equal(coarse_cell1->active_cells , coarse_cell2->active_cells);
if (equal)
equal = int_vector_equal(coarse_cell1->active_values , coarse_cell2->active_values);
if (equal)
equal = int_vector_equal(coarse_cell1->cell_list , coarse_cell2->cell_list);
if (!equal) {
ecl_coarse_cell_fprintf( coarse_cell1 , stdout );
ecl_coarse_cell_fprintf( coarse_cell2 , stdout );
}
return equal;
}
/*
Should not be called more than once with the same arguments; that is
not checked.
@ -306,12 +339,12 @@ int ecl_coarse_cell_get_num_active( const ecl_coarse_cell_type * coarse_cell) {
/*****************************************************************/
void ecl_coarse_cell_fprintf( ecl_coarse_cell_type * coarse_cell , FILE * stream ) {
void ecl_coarse_cell_fprintf( const ecl_coarse_cell_type * coarse_cell , FILE * stream ) {
fprintf(stream,"Coarse box: \n");
fprintf(stream," i : %3d - %3d\n",coarse_cell->ijk[0] , coarse_cell->ijk[1]);
fprintf(stream," j : %3d - %3d\n",coarse_cell->ijk[2] , coarse_cell->ijk[3]);
fprintf(stream," k : %3d - %3d\n",coarse_cell->ijk[4] , coarse_cell->ijk[5]);
fprintf(stream," active_cells : " ); int_vector_fprintf( coarse_cell->active_cells , stream , "" , "%5d ");
fprintf(stream," active_values : " ); int_vector_fprintf( coarse_cell->active_values , stream , "" , "%5d ");
fprintf(stream," Cells : " ); int_vector_fprintf( coarse_cell->cell_list , stream , "" , "%5d ");
//fprintf(stream," Cells : " ); int_vector_fprintf( coarse_cell->cell_list , stream , "" , "%5d ");
}

View File

@ -132,7 +132,7 @@ struct file_map_struct {
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. */
int flags;
int * flags;
};
@ -191,7 +191,7 @@ static bool FILE_FLAGS_SET( int state_flags , int query_flags) {
static file_map_type * file_map_alloc( fortio_type * fortio , int flags , inv_map_type * inv_map , bool owner ) {
static file_map_type * file_map_alloc( fortio_type * fortio , int * flags , inv_map_type * inv_map , bool owner ) {
file_map_type * file_map = util_malloc( sizeof * file_map );
file_map->kw_list = vector_alloc_new();
file_map->kw_index = hash_alloc();
@ -199,7 +199,7 @@ static file_map_type * file_map_alloc( fortio_type * fortio , int flags , inv_ma
file_map->owner = owner;
file_map->fortio = fortio;
file_map->inv_map = inv_map;
file_map->flags = flags;
file_map->flags = flags;
return file_map;
}
@ -268,13 +268,25 @@ static ecl_kw_type * file_map_iget_kw( const file_map_type * file_map , int inde
ecl_kw = ecl_file_kw_get_kw( file_kw , file_map->fortio , file_map->inv_map);
if (FILE_FLAGS_SET( file_map->flags , ECL_FILE_CLOSE_STREAM))
if (FILE_FLAGS_SET( file_map->flags[0] , ECL_FILE_CLOSE_STREAM))
fortio_fclose_stream( file_map->fortio );
}
}
return ecl_kw;
}
static void file_map_index_fload_kw(const file_map_type * file_map, const char* kw, int index, const int_vector_type * index_map, char* buffer) {
ecl_file_kw_type * file_kw = file_map_iget_named_file_kw( file_map , kw , index);
if (fortio_assert_stream_open( file_map->fortio )) {
offset_type offset = ecl_file_kw_get_offset(file_kw);
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);
}
}
static int file_map_find_kw_value( const file_map_type * file_map , const char * kw , const void * value) {
int global_index = -1;
@ -330,7 +342,7 @@ static ecl_kw_type * file_map_iget_named_kw( const file_map_type * file_map , co
ecl_kw = ecl_file_kw_get_kw( file_kw , file_map->fortio , file_map->inv_map);
if (FILE_FLAGS_SET( file_map->flags , ECL_FILE_CLOSE_STREAM))
if (FILE_FLAGS_SET( file_map->flags[0] , ECL_FILE_CLOSE_STREAM))
fortio_fclose_stream( file_map->fortio );
}
}
@ -384,7 +396,7 @@ static bool file_map_load_all( file_map_type * file_map ) {
loadOK = true;
}
if (FILE_FLAGS_SET( file_map->flags , ECL_FILE_CLOSE_STREAM))
if (FILE_FLAGS_SET( file_map->flags[0] , ECL_FILE_CLOSE_STREAM))
fortio_fclose_stream( file_map->fortio );
return loadOK;
@ -776,6 +788,10 @@ ecl_kw_type * ecl_file_iget_named_kw( const ecl_file_type * file , const char *
return file_map_iget_named_kw( file->active_map , kw , ith);
}
void ecl_file_indexed_read(const ecl_file_type * file , const char * kw, int index, const int_vector_type * index_map, char* buffer) {
file_map_index_fload_kw(file->active_map, kw, index, index_map, buffer);
}
ecl_type_enum ecl_file_iget_named_type( const ecl_file_type * file , const char * kw , int ith) {
return file_map_iget_named_type( file->active_map , kw , ith );
}
@ -871,7 +887,7 @@ static ecl_file_type * ecl_file_open__( const char * filename , int flags) {
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->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 );
@ -907,6 +923,9 @@ int ecl_file_get_flags( const ecl_file_type * ecl_file ) {
return ecl_file->flags;
}
void ecl_file_set_flags( ecl_file_type * ecl_file, int flags ) {
ecl_file->flags = flags;
}
bool ecl_file_flags_set( const ecl_file_type * ecl_file , int flags) {
return FILE_FLAGS_SET( ecl_file->flags , flags );
@ -963,6 +982,13 @@ void ecl_file_close(ecl_file_type * ecl_file) {
}
void ecl_file_close_fortio_stream(ecl_file_type * ecl_file) {
if (ecl_file->fortio != NULL) {
fortio_fclose_stream(ecl_file->fortio);
}
}
/**
This function will detach the current ecl_file instance from the
underlying fortio instance. The ecl_file instance can be used

View File

@ -293,6 +293,9 @@ ecl_type_enum ecl_file_kw_get_type( const ecl_file_kw_type * file_kw) {
return file_kw->ecl_type;
}
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 );

File diff suppressed because it is too large Load Diff

View File

@ -174,7 +174,7 @@ void ecl_init_file_fwrite_header( fortio_type * fortio , const ecl_grid_type * e
}
{
ecl_kw_type * doubhead_kw = ecl_init_file_alloc_DOUBHEAD( ecl_grid , phases , start_date );
ecl_kw_type * doubhead_kw = ecl_init_file_alloc_DOUBHEAD( );
ecl_kw_fwrite( doubhead_kw , fortio );
ecl_kw_free( doubhead_kw );
}

View File

@ -80,8 +80,6 @@ UTIL_IS_INSTANCE_FUNCTION(ecl_kw , ECL_KW_TYPE_ID )
#define COLUMNS_INT 6
#define COLUMNS_MESSAGE 1
#define COLUMNS_BOOL 25
#define ECL_KW_FORTIO_HEADER_SIZE 4 + ECL_STRING_LENGTH + 4 + ECL_TYPE_LENGTH + 4
/*****************************************************************/
@ -751,11 +749,11 @@ double ecl_kw_iget_as_double(const ecl_kw_type * ecl_kw , int index) {
float ecl_kw_iget_as_float(const ecl_kw_type * ecl_kw , int i) {
if (ecl_kw->ecl_type == ECL_FLOAT_TYPE)
return ecl_kw_iget_float( ecl_kw , i); /* Here the compiler will silently insert a float -> double conversion. */
return ecl_kw_iget_float( ecl_kw , i);
else if (ecl_kw->ecl_type == ECL_DOUBLE_TYPE)
return ecl_kw_iget_double( ecl_kw, i);
return (float) ecl_kw_iget_double( ecl_kw, i);
else {
util_abort("%s: can not be converted to double - no data for you! \n",__func__);
util_abort("%s: can not be converted to float - no data for you! \n",__func__);
return -1;
}
}
@ -1159,34 +1157,65 @@ void ecl_kw_fread_data(ecl_kw_type *ecl_kw, fortio_type *fortio) {
}
}
void ecl_kw_fread_indexed_data(fortio_type * fortio, offset_type data_offset, ecl_type_enum ecl_type, int element_count, const int_vector_type* index_map, char* buffer) {
const int block_size = get_blocksize( ecl_type );
FILE *stream = fortio_get_FILE( fortio );
int index;
int element_size = ecl_util_get_sizeof_ctype(ecl_type);
if(ecl_type == ECL_CHAR_TYPE || ecl_type == ECL_MESS_TYPE) {
element_size = ECL_STRING_LENGTH;
}
for(index = 0; index < int_vector_size(index_map); index++) {
int element_index = int_vector_iget(index_map, index);
if(element_index < 0 || element_index >= element_count) {
util_abort("%s: Element index is out of range 0 <= %d < %d\n", __func__, element_index, element_count);
}
fortio_data_fseek(fortio, data_offset, element_index, element_size, element_count, block_size);
util_fread(&buffer[index * element_size], element_size, 1, stream, __func__);
}
if (ECL_ENDIAN_FLIP) {
util_endian_flip_vector(buffer, element_size, int_vector_size(index_map));
}
}
/**
Allocates storage and reads data.
*/
void ecl_kw_fread_realloc_data(ecl_kw_type *ecl_kw, fortio_type *fortio) {
ecl_kw_alloc_data(ecl_kw);
return ecl_kw_fread_data(ecl_kw , fortio);
ecl_kw_fread_data(ecl_kw , fortio);
}
/**
Static method without a class instance.
*/
void ecl_kw_fskip_data__( ecl_type_enum ecl_type , int size , fortio_type * fortio) {
void ecl_kw_fskip_data__( ecl_type_enum ecl_type , const int element_count , fortio_type * fortio) {
bool fmt_file = fortio_fmt_file(fortio);
if (size > 0) {
if (element_count > 0) {
if (fmt_file) {
/* Formatted skipping actually involves reading the data - nice ??? */
ecl_kw_type * tmp_kw = ecl_kw_alloc_empty( );
ecl_kw_initialize( tmp_kw , "WORK" , size , ecl_type );
ecl_kw_initialize( tmp_kw , "WORK" , element_count , ecl_type );
ecl_kw_alloc_data(tmp_kw);
ecl_kw_fread_data(tmp_kw , fortio);
ecl_kw_free( tmp_kw );
} else {
const int blocksize = get_blocksize( ecl_type );
const int blocks = size / blocksize + (size % blocksize == 0 ? 0 : 1);
int ib;
for (ib = 0; ib < blocks; ib++)
fortio_fskip_record(fortio);
const int block_count = element_count / blocksize + (element_count % blocksize == 0 ? 0 : 1);
int element_size = ecl_util_get_sizeof_ctype(ecl_type );
if(ecl_type == ECL_CHAR_TYPE || ecl_type == ECL_MESS_TYPE) {
element_size = ECL_STRING_LENGTH;
}
fortio_data_fskip(fortio, element_size, element_count, block_count);
}
}
}
@ -1362,8 +1391,12 @@ void ecl_kw_set_data_ptr(ecl_kw_type * ecl_kw , void * data) {
void ecl_kw_alloc_data(ecl_kw_type *ecl_kw) {
if (ecl_kw->shared_data)
util_abort("%s: trying to allocate data for ecl_kw object which has been declared with shared storage - aborting \n",__func__);
ecl_kw->data = util_realloc(ecl_kw->data , ecl_kw->size * ecl_kw->sizeof_ctype );
{
size_t byte_size = ecl_kw->size * ecl_kw->sizeof_ctype;
ecl_kw->data = util_realloc(ecl_kw->data , byte_size );
memset(ecl_kw->data , 0 , byte_size);
}
}
@ -1720,7 +1753,7 @@ void ecl_kw_get_data_as_float(const ecl_kw_type * ecl_kw , float * float_data) {
const int * int_data = (const int *) ecl_kw->data;
int i;
for (i=0; i < ecl_kw->size; i++)
float_data[i] = int_data[i];
float_data[i] = (float) int_data[i];
} else {
fprintf(stderr,"%s: type can not be converted to float - aborting \n",__func__);
ecl_kw_summarize(ecl_kw);
@ -2349,7 +2382,7 @@ void ecl_kw_inplace_inv(ecl_kw_type * my_kw) {
{
float *my_float = (float *) my_data;
for (i=0; i < size; i++)
my_float[i] = 1.0 / my_float[i];
my_float[i] = 1.0f / my_float[i];
break;
}
default:
@ -2577,6 +2610,14 @@ double ecl_kw_element_sum_float( const ecl_kw_type * ecl_kw ) {
return 0;
}
int ecl_kw_element_sum_int( const ecl_kw_type * ecl_kw ) {
int int_sum;
ecl_kw_element_sum( ecl_kw , &int_sum);
return int_sum;
}
/*****************************************************************/
#define ECL_KW_FPRINTF_DATA(ctype) \

View File

@ -173,7 +173,8 @@ static bool ecl_kw_grdecl_fseek_kw__(const char * kw , FILE * stream) {
char next_kw[256];
fscanf( stream , "%s" , next_kw);
if (strcmp( kw , next_kw ) == 0) {
util_fseek( stream , -strlen(next_kw) , SEEK_CUR);
offset_type offset = (offset_type) strlen(next_kw);
util_fseek( stream , -offset , SEEK_CUR);
return true;
}
} else {

View File

@ -1403,3 +1403,14 @@ void ecl_region_set_name( ecl_region_type * region , const char * name ) {
const char * ecl_region_get_name( const ecl_region_type * region ) {
return region->name;
}
bool ecl_region_equal( const ecl_region_type * region1 , const ecl_region_type * region2) {
if (region1->parent_grid == region2->parent_grid) { // Must be exactly the same grid instance to compare as equal.
if (memcmp(region1->active_mask , region2->active_mask , region1->grid_vol * sizeof * region1->active_mask ) == 0)
return true;
else
return false;
} else
return false;
}

View File

@ -515,7 +515,14 @@ ecl_smspec_var_type ecl_smspec_identify_var_type(const char * var) {
var_type = ECL_SMSPEC_LOCAL_WELL_VAR;
break;
default:
util_abort("%s: not recognized: %s \n",__func__ , var);
/*
The documentation explicitly mentions keywords starting with
LB, LC and LW as special types, but keywords starting with
L[^BCW] are also valid. These come in the misceallaneous
category; at least the LLINEAR keyword is an example of such
a keyword.
*/
var_type = ECL_SMSPEC_MISC_VAR;
}
break;
case('N'):

View File

@ -624,7 +624,7 @@ 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) {
@ -642,8 +642,8 @@ void ecl_sum_data_init_interp_from_sim_time( const ecl_sum_data_type * data , ti
{
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 );
@ -1126,7 +1126,25 @@ double ecl_sum_data_interp_get(const ecl_sum_data_type * data , int time_index1
double ecl_sum_data_get_from_sim_time( const ecl_sum_data_type * data , time_t sim_time , const smspec_node_type * smspec_node) {
int params_index = smspec_node_get_params_index( smspec_node );
if (smspec_node_is_rate( smspec_node )) {
int time_index = ecl_sum_data_get_index_from_sim_time( data , sim_time );
int time_index;
/*
In general the mapping from sim_time to index is based on half
open intervals, which are closed in the upper end:
[]<------------]<--------------]<-----------]
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 ))
time_index = 0;
else
time_index = ecl_sum_data_get_index_from_sim_time( data , sim_time );
return ecl_sum_data_iget( data , time_index , params_index);
} else {
/* Interpolated lookup based on two (hopefully) consecutive ministeps. */

View File

@ -1267,18 +1267,14 @@ static int ecl_util_get_num_parallel_cpu__(parser_type* parser, FILE* stream, co
{
stringlist_type * tokens = parser_tokenize_buffer( parser , buffer , true );
int i;
char * item = NULL;
for (i=0; i < stringlist_get_size( tokens ); i++) {
item = util_realloc_string_copy( item , stringlist_iget( tokens , i ));
util_strupr( item );
if (( util_string_equal( item , "DISTRIBUTED" )) ||
( util_string_equal( item , "DIST" ))) {
num_cpu = atoi( stringlist_iget( tokens , i - 1));
break;
}
}
free( item );
if (stringlist_get_size( tokens ) > 0) {
const char * num_cpu_string = stringlist_iget( tokens , 0 );
if (!util_sscanf_int( num_cpu_string , &num_cpu))
fprintf(stderr,"** Warning: failed to interpret:%s as integer - assuming one CPU\n",num_cpu_string);
} else
fprintf(stderr,"** Warning: failed to load data for PARALLEL keyword - assuming one CPU\n");
stringlist_free( tokens );
}
free( buffer );
@ -1342,6 +1338,23 @@ int ecl_util_get_num_cpu(const char * data_file) {
}
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");
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;
}
parser_free( parser );
fclose(stream);
return units;
}
/**
This function checks that all the characters in the input @basename
are either lowercase, or uppercase. If presented with a mixed-case
@ -1351,12 +1364,15 @@ int ecl_util_get_num_cpu(const char * data_file) {
bool ecl_util_valid_basename( const char * basename ) {
char * eclbasename = util_split_alloc_filename(basename);
int upper_count = 0;
int lower_count = 0;
int index;
for (index = 0; index < strlen( basename ); index++) {
int c = basename[index];
for (index = 0; index < strlen( eclbasename ); index++) {
int c = eclbasename[index];
if (isalpha(c)) {
if (isupper(c))
upper_count++;
@ -1365,6 +1381,8 @@ bool ecl_util_valid_basename( const char * basename ) {
}
}
free(eclbasename);
if ((lower_count * upper_count) != 0)
return false;
else
@ -1375,14 +1393,17 @@ bool ecl_util_valid_basename( const char * basename ) {
bool ecl_util_valid_basename_fmt(const char * basename_fmt)
{
bool valid;
const char * percent_ptr = strchr(basename_fmt, '%');
char * eclbasename_fmt = util_split_alloc_filename(basename_fmt);
const char * percent_ptr = strchr(eclbasename_fmt, '%');
if (percent_ptr) {
percent_ptr++;
while (true)
{
if (*percent_ptr == 'd')
{
char * basename_instance = util_alloc_sprintf(basename_fmt, 0);
char * basename_instance = util_alloc_sprintf(eclbasename_fmt, 0);
valid = ecl_util_valid_basename(basename_instance);
free(basename_instance);
break;
@ -1393,7 +1414,9 @@ bool ecl_util_valid_basename_fmt(const char * basename_fmt)
percent_ptr++;
}
} else
valid = ecl_util_valid_basename(basename_fmt);
valid = ecl_util_valid_basename(eclbasename_fmt);
free(eclbasename_fmt);
return valid;
}

View File

@ -0,0 +1,267 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'fault_block.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/type_macros.h>
#include <ert/util/int_vector.h>
#include <ert/geometry/geo_util.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/fault_block.h>
#include <ert/ecl/layer.h>
#define FAULT_BLOCK_ID 3297376
struct fault_block_struct {
UTIL_TYPE_ID_DECLARATION;
const ecl_grid_type * grid;
const fault_block_layer_type * parent_layer;
int_vector_type * i_list;
int_vector_type * j_list;
int_vector_type * global_index_list;
int_vector_type * region_list;
int block_id;
int k;
double xc,yc;
bool valid_center;
};
UTIL_IS_INSTANCE_FUNCTION( fault_block , FAULT_BLOCK_ID )
static UTIL_SAFE_CAST_FUNCTION( fault_block , FAULT_BLOCK_ID )
static fault_block_type * fault_block_alloc( const fault_block_layer_type * parent_layer , int block_id ) {
fault_block_type * block = util_malloc( sizeof * block );
UTIL_TYPE_ID_INIT( block , FAULT_BLOCK_ID );
block->parent_layer = parent_layer;
block->grid = fault_block_layer_get_grid( parent_layer );
block->k = fault_block_layer_get_k( parent_layer );
block->block_id = block_id;
block->i_list = int_vector_alloc(0,0);
block->j_list = int_vector_alloc(0,0);
block->global_index_list = int_vector_alloc(0,0);
block->region_list = int_vector_alloc(0,0);
block->valid_center = false;
return block;
}
int fault_block_get_size( const fault_block_type * block ) {
return int_vector_size( block->i_list );
}
int fault_block_get_id( const fault_block_type * block ) {
return block->block_id;
}
static void fault_block_free( fault_block_type * block ) {
int_vector_free( block->i_list );
int_vector_free( block->j_list );
int_vector_free( block->region_list );
int_vector_free( block->global_index_list );
free( block );
}
void fault_block_free__( void * arg) {
fault_block_type * block = fault_block_safe_cast( arg );
fault_block_free( block );
}
void fault_block_add_cell( fault_block_type * fault_block , int i , int j) {
int_vector_append( fault_block->i_list , i);
int_vector_append( fault_block->j_list , j);
int_vector_append( fault_block->global_index_list , ecl_grid_get_global_index3( fault_block->grid , i , j , fault_block->k));
fault_block->valid_center = false;
layer_iset_cell_value( fault_block_layer_get_layer( fault_block->parent_layer ) , i , j , fault_block->block_id );
}
void fault_block_assign_to_region( fault_block_type * fault_block , int region_id ) {
if (int_vector_size( fault_block->region_list ) == 0)
int_vector_append( fault_block->region_list , region_id );
else {
if (int_vector_index_sorted( fault_block->region_list , region_id ) == -1)
int_vector_append( fault_block->region_list , region_id );
}
int_vector_sort( fault_block->region_list );
}
const int_vector_type * fault_block_get_region_list( const fault_block_type * fault_block ) {
return fault_block->region_list;
}
static void fault_block_assert_center( fault_block_type * fault_block ) {
if (!fault_block->valid_center) {
int index;
double xc = 0;
double yc = 0;
for (index = 0; index < int_vector_size( fault_block->i_list ); index++) {
int i = int_vector_iget( fault_block->i_list , index);
int j = int_vector_iget( fault_block->j_list , index);
int g = ecl_grid_get_global_index3( fault_block->grid , i , j , fault_block->k );
double x , y , z;
ecl_grid_get_xyz1( fault_block->grid , g , &x , &y , &z);
xc += x;
yc += y;
}
fault_block->xc = xc / int_vector_size( fault_block->i_list );
fault_block->yc = yc / int_vector_size( fault_block->i_list );
}
fault_block->valid_center = true;
}
double fault_block_get_xc( fault_block_type * fault_block ) {
fault_block_assert_center( fault_block );
return fault_block->xc;
}
double fault_block_get_yc( fault_block_type * fault_block ) {
fault_block_assert_center( fault_block );
return fault_block->yc;
}
void fault_block_export_cell(const fault_block_type * fault_block , int index , int * i , int * j , int * k , double * x, double * y, double * z) {
*i = int_vector_iget( fault_block->i_list , index );
*j = int_vector_iget( fault_block->j_list , index );
*k = fault_block->k;
ecl_grid_get_xyz3( fault_block->grid , *i , *j , *k , x , y , z);
}
int fault_block_iget_i(const fault_block_type * fault_block , int index) {
return int_vector_iget( fault_block->i_list , index );
}
int fault_block_iget_j(const fault_block_type * fault_block , int index) {
return int_vector_iget( fault_block->j_list , index );
}
const int_vector_type * fault_block_get_global_index_list( const fault_block_type * fault_block) {
return fault_block->global_index_list;
}
bool fault_block_trace_edge( const fault_block_type * block , double_vector_type * x_list , double_vector_type * y_list, int_vector_type * cell_list) {
if (fault_block_get_size( block ) > 0) {
struct_vector_type * corner_list = struct_vector_alloc( sizeof(int_point2d_type) );
int c;
{
int start_i = fault_block_iget_i( block , 0 );
int start_j = fault_block_iget_j( block , 0 );
layer_trace_block_edge(fault_block_layer_get_layer( block->parent_layer ) , start_i , start_j , block->block_id , corner_list , cell_list);
}
double_vector_reset( x_list );
double_vector_reset( y_list );
for (c=0; c < struct_vector_get_size( corner_list ); c++) {
double x,y,z;
int_point2d_type ij;
struct_vector_iget( corner_list , c , &ij );
ecl_grid_get_corner_xyz( block->grid , ij.i , ij.j , block->k , &x , &y , &z);
double_vector_append( x_list , x);
double_vector_append( y_list , y);
}
struct_vector_free( corner_list );
return true;
} else
return false;
}
void fault_block_list_neighbours( const fault_block_type * block, int_vector_type * neighbour_list) {
int_vector_reset( neighbour_list );
{
int_vector_type * cell_list = int_vector_alloc(0,0);
double_vector_type * x_list = double_vector_alloc(0,0);
double_vector_type * y_list = double_vector_alloc(0,0);
fault_block_trace_edge( block , x_list , y_list , cell_list );
{
int c;
layer_type * layer = fault_block_layer_get_layer( block->parent_layer );
for (c = 0; c < int_vector_size( cell_list ); c++) {
int j = int_vector_iget( cell_list , c) / layer_get_nx(layer);
int i = int_vector_iget( cell_list , c) % layer_get_nx(layer);
if (i > 0) {
int neighbour_id = layer_iget_cell_value(layer , i - 1, j);
int_vector_append( neighbour_list , neighbour_id );
}
if (i < (layer_get_nx( layer) - 1)) {
int neighbour_id = layer_iget_cell_value(layer , i + 1, j);
int_vector_append( neighbour_list , neighbour_id );
}
if (j > 0) {
int neighbour_id = layer_iget_cell_value(layer , i, j - 1);
int_vector_append( neighbour_list , neighbour_id );
}
if (j < (layer_get_ny( layer) - 1)) {
int neighbour_id = layer_iget_cell_value(layer , i, j + 1);
int_vector_append( neighbour_list , neighbour_id );
}
}
}
double_vector_free( x_list );
double_vector_free( y_list );
int_vector_free( cell_list );
}
int_vector_select_unique( neighbour_list );
int_vector_del_value( neighbour_list , 0 );
int_vector_del_value( neighbour_list , block->block_id );
}
void fault_block_copy_content(fault_block_type * target_block , const fault_block_type * src_block ) {
int b;
for (b = 0; b < int_vector_size( src_block->i_list ); b++)
fault_block_add_cell( target_block , int_vector_iget( src_block->i_list , b) , int_vector_iget( src_block->j_list , b));
}

View File

@ -0,0 +1,342 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'fault_block_layer.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/type_macros.h>
#include <ert/util/int_vector.h>
#include <ert/util/double_vector.h>
#include <ert/util/vector.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/fault_block_layer.h>
#include <ert/ecl/layer.h>
#define FAULT_BLOCK_LAYER_ID 2297476
/*
The fault_block object is implemented as a separate object type in
the fault_block.c file; however the fault blocks should be closely
linked to the layer object in the fault_block_layer structure - it
is therefor not possible/legal to create a fault block instance by
itself. To support that encapsulation the fault_block.c file is
included here, and the functions:
fault_block_alloc();
fault_block_free();
Which must be called through the fault_block_layer class are made
static.
*/
static fault_block_type * fault_block_alloc( const fault_block_layer_type * parent_layer , int block_id );
static void fault_block_free( fault_block_type * block );
#include "fault_block.c"
struct fault_block_layer_struct {
UTIL_TYPE_ID_DECLARATION;
const ecl_grid_type * grid;
int_vector_type * block_map;
layer_type * layer;
int k;
vector_type * blocks;
};
UTIL_IS_INSTANCE_FUNCTION(fault_block_layer , FAULT_BLOCK_LAYER_ID);
static UTIL_SAFE_CAST_FUNCTION(fault_block_layer , FAULT_BLOCK_LAYER_ID);
fault_block_type * fault_block_layer_add_block( fault_block_layer_type * layer , int block_id) {
if (int_vector_safe_iget( layer->block_map , block_id) < 0) {
fault_block_type * block = fault_block_alloc( layer , block_id );
int storage_index = vector_get_size( layer->blocks );
int_vector_iset( layer->block_map , block_id , storage_index );
vector_append_owned_ref( layer->blocks , block , fault_block_free__ );
return block;
} else
return NULL;
}
void fault_block_layer_scan_layer( fault_block_layer_type * fault_layer , layer_type * layer) {
int i,j;
int_vector_type * i_list = int_vector_alloc(0,0);
int_vector_type * j_list = int_vector_alloc(0,0);
for (j = 0; j < layer_get_ny( layer ); j++) {
for (i = 0; i < layer_get_nx( layer); i++) {
int cell_value = layer_iget_cell_value( layer , i , j );
if (cell_value != 0) {
layer_trace_block_content( layer , true , i , j , cell_value , i_list , j_list );
{
int c;
int block_id = fault_block_layer_get_next_id( fault_layer );
fault_block_type * fault_block = fault_block_layer_add_block( fault_layer , block_id );
for (c=0; c < int_vector_size( i_list ); c++)
fault_block_add_cell( fault_block , int_vector_iget( i_list , c ), int_vector_iget( j_list , c ));
}
}
}
}
int_vector_free( i_list );
int_vector_free( j_list );
}
/*
Observe that the id values from the ecl_kw instance are not
retained; the fault_block_layer instance gets new block id numbers,
including a nonzero value for the cells which have value zero in the
keyword.
- The blocks in the fault_block_layer instance are guaranteed to be
singly connected.
- Observe that the numbering of the blocks is implicitly given by
the spatial distribution of the values, and hence *completely
random* with respect to the original values in the keyword.
*/
bool fault_block_layer_scan_kw( fault_block_layer_type * layer , const ecl_kw_type * fault_block_kw) {
bool assign_zero = true;
if (ecl_kw_get_size( fault_block_kw) != ecl_grid_get_global_size(layer->grid))
return false;
else if (ecl_kw_get_type( fault_block_kw ) != ECL_INT_TYPE)
return false;
else {
int i,j;
int max_block_id = 0;
layer_type * work_layer = layer_alloc( ecl_grid_get_nx( layer->grid ) , ecl_grid_get_ny( layer->grid ));
for (j=0; j < ecl_grid_get_ny( layer->grid ); j++) {
for (i=0; i < ecl_grid_get_nx( layer->grid ); i++) {
int g = ecl_grid_get_global_index3( layer->grid , i , j , layer->k );
int block_id = ecl_kw_iget_int( fault_block_kw , g );
if (block_id > 0) {
layer_iset_cell_value( work_layer , i , j , block_id );
max_block_id = util_int_max( block_id , max_block_id );
}
}
}
if (assign_zero)
layer_replace_cell_values( work_layer , 0 , max_block_id + 1);
fault_block_layer_scan_layer( layer , work_layer );
layer_free( work_layer );
return true;
}
}
/**
This function will just load the fault block distribution from
fault_block_kw; it will not do any reordering or assign block ids
to the regions with ID == 0.
*/
bool fault_block_layer_load_kw( fault_block_layer_type * layer , const ecl_kw_type * fault_block_kw) {
if (ecl_kw_get_size( fault_block_kw) != ecl_grid_get_global_size(layer->grid))
return false;
else if (ecl_kw_get_type( fault_block_kw ) != ECL_INT_TYPE)
return false;
else {
int i,j;
for (j=0; j < ecl_grid_get_ny( layer->grid ); j++) {
for (i=0; i < ecl_grid_get_nx( layer->grid ); i++) {
int g = ecl_grid_get_global_index3( layer->grid , i , j , layer->k );
int block_id = ecl_kw_iget_int( fault_block_kw , g );
if (block_id > 0) {
fault_block_layer_add_block( layer , block_id );
{
fault_block_type * fault_block = fault_block_layer_get_block( layer , block_id );
fault_block_add_cell( fault_block , i,j );
}
}
}
}
return true;
}
}
fault_block_layer_type * fault_block_layer_alloc( const ecl_grid_type * grid , int k) {
if ((k < 0) || (k >= ecl_grid_get_nz( grid )))
return NULL;
else {
fault_block_layer_type * layer = util_malloc( sizeof * layer );
UTIL_TYPE_ID_INIT( layer , FAULT_BLOCK_LAYER_ID);
layer->grid = grid;
layer->k = k;
layer->block_map = int_vector_alloc( 0 , -1);
layer->blocks = vector_alloc_new();
layer->layer = layer_alloc(ecl_grid_get_nx(grid) , ecl_grid_get_ny(grid));
return layer;
}
}
fault_block_type * fault_block_layer_iget_block( const fault_block_layer_type * layer , int storage_index) {
return vector_iget( layer->blocks , storage_index );
}
fault_block_type * fault_block_layer_get_block( const fault_block_layer_type * layer , int block_id) {
int storage_index = int_vector_safe_iget( layer->block_map , block_id);
if (storage_index < 0)
return NULL;
else
return vector_iget( layer->blocks , storage_index );
}
fault_block_type * fault_block_layer_safe_get_block( fault_block_layer_type * layer , int block_id) {
int storage_index = int_vector_safe_iget( layer->block_map , block_id);
if (storage_index < 0)
return fault_block_layer_add_block( layer , block_id );
else
return vector_iget( layer->blocks , storage_index );
}
void fault_block_layer_del_block( fault_block_layer_type * layer , int block_id) {
int storage_index = int_vector_safe_iget( layer->block_map , block_id);
if (storage_index >= 0) {
int_vector_iset( layer->block_map , block_id , -1 );
vector_idel( layer->blocks , storage_index );
{
int index;
for (index = 0; index < int_vector_size( layer->block_map ); index++) {
int current_storage_index = int_vector_iget( layer->block_map , index );
if (current_storage_index > storage_index)
int_vector_iset( layer->block_map ,index , current_storage_index - 1);
}
}
}
}
bool fault_block_layer_has_block( const fault_block_layer_type * layer , int block_id) {
if (int_vector_safe_iget( layer->block_map , block_id) >= 0)
return true;
else
return false;
}
int fault_block_layer_get_max_id( const fault_block_layer_type * layer ) {
return int_vector_size( layer->block_map ) - 1;
}
int fault_block_layer_get_next_id( const fault_block_layer_type * layer ) {
if (int_vector_size( layer->block_map ) == 0)
return 1;
else
return int_vector_size( layer->block_map );
}
int fault_block_layer_get_size( const fault_block_layer_type * layer ) {
return vector_get_size( layer->blocks );
}
int fault_block_layer_get_k( const fault_block_layer_type * layer ) {
return layer->k;
}
void fault_block_layer_free( fault_block_layer_type * layer ) {
int_vector_free( layer->block_map );
vector_free( layer->blocks );
layer_free( layer->layer );
free(layer);
}
void fault_block_layer_free__( void * arg ) {
fault_block_layer_type * layer = fault_block_layer_safe_cast( arg );
fault_block_layer_free( layer );
}
void fault_block_layer_insert_block_content( fault_block_layer_type * layer , const fault_block_type * src_block) {
int next_block_id = fault_block_layer_get_next_id( layer );
fault_block_type * target_block = fault_block_layer_add_block( layer , next_block_id );
fault_block_copy_content( target_block , src_block );
}
bool fault_block_layer_export( const fault_block_layer_type * layer , ecl_kw_type * faultblock_kw) {
if ((ecl_kw_get_type( faultblock_kw ) == ECL_INT_TYPE) && (ecl_kw_get_size( faultblock_kw ) == ecl_grid_get_global_size( layer->grid ))) {
int i,j;
for (j=0; j < ecl_grid_get_ny( layer->grid ); j++) {
for (i=0; i < ecl_grid_get_nx( layer->grid ); i++) {
int g = ecl_grid_get_global_index3( layer->grid , i, j , layer->k );
int cell_value = layer_iget_cell_value( layer->layer , i , j );
ecl_kw_iset_int( faultblock_kw , g , cell_value);
}
}
return true;
} else
return false;
}
const ecl_grid_type * fault_block_layer_get_grid( const fault_block_layer_type * layer ) {
return layer->grid;
}
layer_type * fault_block_layer_get_layer( const fault_block_layer_type * layer ) {
return layer->layer;
}

View File

@ -23,9 +23,13 @@
#include <errno.h>
#include <ert/util/util.h>
#include <ert/util/type_macros.h>
#include <ert/ecl/fortio.h>
#define FORTIO_ID 345116
extern int errno;
/**
@ -69,6 +73,7 @@ fwrite() from the standard library.
struct fortio_struct {
UTIL_TYPE_ID_DECLARATION;
FILE * stream;
char * filename;
bool endian_flip_header;
@ -82,9 +87,12 @@ struct fortio_struct {
};
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) {
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;
@ -469,7 +477,28 @@ int fortio_init_read(fortio_type *fortio) {
}
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);
fortio_fseek(fortio, bytes_to_skip, SEEK_CUR);
}
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) {
if(data_element < 0 || data_element >= element_count) {
util_abort("%s: Element index is out of range: 0 <= %d < %d \n", __func__, data_element, element_count);
}
{
int block_index = data_element / block_size;
int headers = (block_index + 1) * 4;
int trailers = block_index * 4;
int bytes_to_skip = data_offset + headers + trailers + (data_element * element_size);
fortio_fseek(fortio, bytes_to_skip, SEEK_SET);
}
}
void fortio_complete_read(fortio_type *fortio) {
@ -578,7 +607,7 @@ void fortio_init_write(fortio_type *fortio , int record_size) {
file_header = fortio->active_header;
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++;
}

521
ThirdParty/Ert/devel/libecl/src/layer.c vendored Normal file
View File

@ -0,0 +1,521 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'layer.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/int_vector.h>
#include <ert/ecl/layer.h>
#define LAYER_TYPE_ID 55185409
typedef struct {
int cell_value;
int edges[4];
} cell_type;
struct layer_struct {
UTIL_TYPE_ID_DECLARATION;
int nx, ny;
cell_type * data;
int cell_sum;
};
UTIL_IS_INSTANCE_FUNCTION( layer , LAYER_TYPE_ID )
UTIL_SAFE_CAST_FUNCTION( layer , LAYER_TYPE_ID )
layer_type * layer_alloc(int nx , int ny) {
layer_type * layer = util_malloc( sizeof * layer );
UTIL_TYPE_ID_INIT( layer , LAYER_TYPE_ID );
layer->nx = nx;
layer->ny = ny;
layer->cell_sum = 0;
layer->data = util_malloc( (layer->nx + 1)* (layer->ny + 1) * sizeof * layer->data );
{
int g;
for (g=0; g < (layer->nx + 1)*(layer->ny + 1); g++) {
cell_type * cell = &layer->data[g];
cell->cell_value = 0;
cell->edges[RIGHT_EDGE] = 0;
cell->edges[LEFT_EDGE] = 0;
cell->edges[TOP_EDGE] = 0;
cell->edges[BOTTOM_EDGE] = 0;
}
}
return layer;
}
void layer_free( layer_type * layer ) {
free( layer->data );
free(layer);
}
static int layer_get_global_cell_index( const layer_type * layer , int i , int j) {
if ((i < 0) || (i >= layer->nx))
util_abort("%s: invalid i value:%d Valid range: [0,%d) \n",__func__ , i , layer->nx);
if ((j < 0) || (j >= layer->ny))
util_abort("%s: invalid j value:%d Valid range: [0,%d) \n",__func__ , j , layer->ny);
return i + j*(layer->nx + 1);
}
int layer_iget_cell_value( const layer_type * layer, int i , int j) {
int g = layer_get_global_cell_index( layer , i , j );
return layer->data[g].cell_value;
}
int layer_get_cell_sum( const layer_type * layer ) {
return layer->cell_sum;
}
static void layer_cancel_edge( layer_type * layer , int i , int j , edge_dir_enum dir) {
int g = layer_get_global_cell_index( layer , i , j );
cell_type * cell = &layer->data[g];
cell->edges[dir] = 0;
}
int layer_get_nx( const layer_type * layer ) {
return layer->nx;
}
int layer_get_ny( const layer_type * layer ) {
return layer->ny;
}
void layer_iset_cell_value( layer_type * layer , int i , int j , int value) {
int g = layer_get_global_cell_index( layer , i , j );
cell_type * cell = &layer->data[g];
layer->cell_sum += (value - cell->cell_value);
cell->cell_value = value;
if (i > 0) {
int neighbour_value = layer_iget_cell_value( layer , i - 1 , j);
if (value == neighbour_value) {
cell->edges[LEFT_EDGE] = 0;
layer_cancel_edge( layer , i - 1, j , RIGHT_EDGE);
} else
cell->edges[LEFT_EDGE] = -value;
} else
cell->edges[LEFT_EDGE] = -value;
if (i < (layer->nx - 1)) {
int neighbour_value = layer_iget_cell_value( layer , i + 1 , j);
if (value == neighbour_value) {
cell->edges[RIGHT_EDGE] = 0;
layer_cancel_edge( layer , i + 1, j , LEFT_EDGE);
} else
cell->edges[RIGHT_EDGE] = value;
} else
cell->edges[RIGHT_EDGE] = value;
if (j < (layer->ny - 1)) {
int neighbour_value = layer_iget_cell_value( layer , i , j + 1);
if (value == neighbour_value) {
cell->edges[TOP_EDGE] = 0;
layer_cancel_edge( layer , i , j + 1, BOTTOM_EDGE);
} else
cell->edges[TOP_EDGE] = -value;
} else
cell->edges[TOP_EDGE] = -value;
if (j > 0) {
int neighbour_value = layer_iget_cell_value( layer , i , j - 1);
if (value == neighbour_value) {
cell->edges[BOTTOM_EDGE] = 0;
layer_cancel_edge( layer , i , j - 1, TOP_EDGE);
} else
cell->edges[BOTTOM_EDGE] = value;
} else
cell->edges[BOTTOM_EDGE] = value;
}
static int layer_get_global_edge_index( const layer_type * layer , int i , int j , edge_dir_enum dir) {
if ((i < 0) || (j < 0))
util_abort("%s: invalid value for i,j \n",__func__);
if ((i > layer->nx) || (j > layer->ny))
util_abort("%s: invalid value for i,j \n",__func__);
if (i == layer->nx) {
if (j == layer->ny)
util_abort("%s: invalid value for i,j \n",__func__);
if (dir != LEFT_EDGE)
util_abort("%s: invalid value for i,j \n",__func__);
}
if (j == layer->ny) {
if (i == layer->nx)
util_abort("%s: invalid value for i,j \n",__func__);
if (dir != BOTTOM_EDGE)
util_abort("%s: invalid value for i,j \n",__func__);
}
return i + j*(layer->nx + 1);
}
int layer_iget_edge_value( const layer_type * layer , int i , int j , edge_dir_enum dir) {
int g = layer_get_global_edge_index( layer , i , j , dir);
cell_type * cell = &layer->data[g];
return cell->edges[dir];
}
bool layer_cell_on_edge( const layer_type * layer , int i , int j) {
int g = layer_get_global_cell_index( layer , i , j);
cell_type * cell = &layer->data[g];
if (cell->cell_value == cell->edges[LEFT_EDGE])
return true;
if (cell->cell_value == cell->edges[RIGHT_EDGE])
return true;
if (cell->cell_value == cell->edges[BOTTOM_EDGE])
return true;
if (cell->cell_value == cell->edges[TOP_EDGE])
return true;
return false;
}
static void point_shift(int_point2d_type * point , int di , int dj) {
point->i += di;
point->j += dj;
}
static bool point_equal(int_point2d_type * p1 , int_point2d_type *p2) {
if ((p1->i == p2->i) && (p1->j == p2->j))
return true;
else
return false;
}
/*
Possible edge transitions:
BOTTOM_EDGE -> BOTTOM_EDGE{ i + 1, j } , RIGHT_EDGE{i,j} , LEFT_EDGE{i +1,j -1}
RIGHT_EDGE -> TOP_EDGE{i,j} , RIGHT_EDGE{i,j+1} , BOTTOM_EDGE{i+1 , j+1}
TOP_EDGE -> LEFT_EDGE{i,j} , TOP_EDGE{i-1,j} , RIGHT_EDGE{i-1,j+1}
LEFT_EDGE -> BOTTOM_EDGE{i,j} , LEFT_EDGE{i,j-1} , TOP_EDGE{i-1 , j-1}
*/
static void layer_trace_block_edge__( const layer_type * layer , int_point2d_type start_point , int i , int j , int value , edge_dir_enum dir , struct_vector_type * corner_list, int_vector_type * cell_list) {
int_point2d_type current_point;
int_point2d_type next_point;
current_point.i = i;
current_point.j = j;
next_point = current_point;
if (dir == BOTTOM_EDGE)
point_shift( &next_point , 1 , 0 );
else if (dir == RIGHT_EDGE) {
point_shift( &current_point , 1 , 0 );
point_shift( &next_point , 1 , 1 );
} else if (dir == TOP_EDGE) {
point_shift( &current_point , 1 , 1 );
point_shift( &next_point , 0 , 1 );
} else if (dir == LEFT_EDGE)
point_shift( &current_point , 0 , 1 );
struct_vector_append( corner_list , &current_point );
{
int cell_index = i + j*layer->nx;
int_vector_append( cell_list , cell_index );
}
if ( !point_equal(&start_point , &next_point) ) {
if (dir == BOTTOM_EDGE) {
if (layer_iget_edge_value( layer , i,j,RIGHT_EDGE) == value)
layer_trace_block_edge__( layer , start_point , i , j , value , RIGHT_EDGE , corner_list , cell_list);
else if (layer_iget_edge_value( layer , i + 1 , j ,BOTTOM_EDGE) == value)
layer_trace_block_edge__( layer , start_point , i + 1 , j , value , BOTTOM_EDGE , corner_list , cell_list);
else if (layer_iget_edge_value( layer , i + 1 , j - 1 , LEFT_EDGE) == -value)
layer_trace_block_edge__( layer , start_point , i + 1 , j -1 , value , LEFT_EDGE , corner_list , cell_list);
else
util_abort("%s: dir == BOTTOM_EDGE \n",__func__);
}
if (dir == RIGHT_EDGE) {
if (layer_iget_edge_value( layer , i,j,TOP_EDGE) == -value)
layer_trace_block_edge__( layer , start_point , i , j , value , TOP_EDGE , corner_list , cell_list);
else if (layer_iget_edge_value( layer , i , j + 1 ,RIGHT_EDGE) == value)
layer_trace_block_edge__( layer , start_point , i , j + 1, value , RIGHT_EDGE , corner_list , cell_list);
else if (layer_iget_edge_value( layer , i + 1 , j + 1 ,BOTTOM_EDGE) == value)
layer_trace_block_edge__( layer , start_point , i + 1 , j + 1, value , BOTTOM_EDGE , corner_list , cell_list);
else
util_abort("%s: dir == RIGHT_EDGE \n",__func__);
}
if (dir == TOP_EDGE) {
if (layer_iget_edge_value( layer , i , j , LEFT_EDGE) == -value)
layer_trace_block_edge__( layer , start_point , i , j , value , LEFT_EDGE , corner_list , cell_list);
else if (layer_iget_edge_value( layer , i - 1 , j ,TOP_EDGE) == -value)
layer_trace_block_edge__( layer , start_point , i - 1 , j , value , TOP_EDGE , corner_list , cell_list);
else if (layer_iget_edge_value( layer , i - 1 , j + 1 ,RIGHT_EDGE) == value)
layer_trace_block_edge__( layer , start_point , i - 1 , j + 1, value , RIGHT_EDGE , corner_list , cell_list);
else
util_abort("%s: dir == TOP_EDGE \n",__func__);
}
if (dir == LEFT_EDGE) {
if (layer_iget_edge_value( layer , i , j , BOTTOM_EDGE) == value)
layer_trace_block_edge__( layer , start_point , i , j , value , BOTTOM_EDGE , corner_list , cell_list);
else if (layer_iget_edge_value( layer , i , j - 1 , LEFT_EDGE) == -value)
layer_trace_block_edge__( layer , start_point , i , j - 1, value , LEFT_EDGE , corner_list , cell_list);
else if (layer_iget_edge_value( layer , i -1 , j - 1 , TOP_EDGE) == -value)
layer_trace_block_edge__( layer , start_point , i-1 , j - 1, value , TOP_EDGE , corner_list , cell_list);
else
util_abort("%s: dir == LEFT_EDGE \n",__func__);
}
}
}
static void layer_fprintf_dash( const layer_type * layer , FILE * stream, int i1 , int i2) {
int i;
fprintf(stream," --");
for (i=i1; i <= i2; i++)
fprintf(stream , "----");
fprintf(stream , "----\n");
}
static void layer_fprintf_header( const layer_type * layer , FILE * stream, int i1 , int i2) {
int i;
fprintf(stream," ");
for (i=i1; i <= i2; i++)
fprintf(stream , " %3d" , i);
fprintf(stream , "\n");
}
void layer_fprintf_box( const layer_type * layer , FILE * stream , int i1 , int i2 , int j1 , int j2) {
int i,j;
layer_fprintf_header( layer , stream , i1 , i2);
layer_fprintf_dash( layer , stream , i1 , i2);
for (j=j2; j >= j1; j--) {
fprintf(stream , " %3d | " , j);
for (i=i1; i <= i2; i++) {
int g = layer_get_global_cell_index( layer , i , j);
cell_type * cell = &layer->data[g];
fprintf(stream , " %3d" , cell->cell_value);
}
fprintf(stream , " | %3d \n" , j);
}
layer_fprintf_dash( layer , stream , i1 , i2);
layer_fprintf_header( layer , stream , i1 , i2);
}
void layer_fprintf( const layer_type * layer , FILE * stream) {
layer_fprintf_box( layer , stream , 0 , layer->nx - 1 , 0 , layer->ny - 1);
}
void layer_fprintf_cell( const layer_type * layer , int i , int j , FILE * stream) {
int g = layer_get_global_cell_index( layer , i , j);
cell_type * cell = &layer->data[g];
fprintf(stream , " i:%d j:%d \n",i,j);
fprintf(stream , " *--- %4d ---* \n",cell->edges[TOP_EDGE]);
fprintf(stream , " | | \n");
fprintf(stream , " %4d %4d %4d\n" , cell->edges[LEFT_EDGE] , cell->cell_value , cell->edges[RIGHT_EDGE]);
fprintf(stream , " | | \n");
fprintf(stream , " *--- %4d ---* \n",cell->edges[BOTTOM_EDGE]);
}
static bool layer_find_edge( const layer_type * layer , int *i , int *j , int value) {
int g = layer_get_global_cell_index( layer , *i , *j);
cell_type * cell = &layer->data[g];
if (cell->cell_value == value) {
while (!layer_cell_on_edge( layer , *i , *j))
(*i) += 1;
return true;
} else
return false;
}
bool layer_trace_block_edge( const layer_type * layer , int start_i , int start_j , int value , struct_vector_type * corner_list , int_vector_type * cell_list) {
int g = layer_get_global_cell_index( layer , start_i , start_j);
cell_type * cell = &layer->data[g];
if ((cell->cell_value == value)) {
int i = start_i;
int j = start_j;
if (layer_find_edge( layer , &i , &j , value)) {
int_point2d_type start_corner;
g = layer_get_global_cell_index( layer , i , j);
cell = &layer->data[g];
start_corner.i = i;
start_corner.j = j;
struct_vector_reset( corner_list );
int_vector_reset( cell_list );
if (cell->edges[BOTTOM_EDGE] == value) {
point_shift( &start_corner , 0 , 0 );
layer_trace_block_edge__(layer , start_corner , i , j , value , BOTTOM_EDGE , corner_list , cell_list);
} else if (cell->edges[RIGHT_EDGE] == value) {
point_shift( &start_corner , 1 , 0 );
layer_trace_block_edge__(layer , start_corner , i , j , value , RIGHT_EDGE , corner_list , cell_list);
} else if (cell->edges[TOP_EDGE] == -value) {
point_shift( &start_corner , 1 , 1 );
layer_trace_block_edge__(layer , start_corner , i , j , value , TOP_EDGE , corner_list , cell_list);
} else if (cell->edges[LEFT_EDGE] == -value) {
point_shift( &start_corner , 0 , 1 );
layer_trace_block_edge__(layer , start_corner , i , j , value , LEFT_EDGE , corner_list , cell_list);
} else
util_abort("%s: what the fuck - internal error \n",__func__);
int_vector_select_unique( cell_list );
return true;
}
}
return false;
}
static void layer_trace_block_content__( layer_type * layer , bool erase , int i , int j , int value , bool * visited , int_vector_type * i_list , int_vector_type * j_list) {
int g = layer_get_global_cell_index( layer , i , j);
cell_type * cell = &layer->data[g];
if (cell->cell_value != value || visited[g])
return;
{
visited[g] = true;
if (erase)
layer_iset_cell_value( layer , i , j , 0);
int_vector_append( i_list , i );
int_vector_append( j_list , j );
if (i > 0)
layer_trace_block_content__( layer , erase , i - 1 , j , value , visited , i_list , j_list);
if (i < (layer->nx - 1))
layer_trace_block_content__( layer , erase , i + 1 , j , value , visited , i_list , j_list);
if (j > 0)
layer_trace_block_content__( layer , erase , i , j - 1, value , visited , i_list , j_list);
if (j < (layer->ny - 1))
layer_trace_block_content__( layer , erase , i , j + 1, value , visited , i_list , j_list);
}
}
static bool * layer_alloc_visited_mask( const layer_type * layer ) {
int total_size = (layer->nx + 1)* (layer->ny + 1);
bool * visited = util_malloc( total_size * sizeof * visited );
int g;
for (g = 0; g < total_size; g++)
visited[g] = false;
return visited;
}
bool layer_trace_block_content( layer_type * layer , bool erase , int start_i , int start_j , int value , int_vector_type * i_list, int_vector_type * j_list) {
bool start_tracing = false;
int g = layer_get_global_cell_index( layer , start_i , start_j);
cell_type * cell = &layer->data[g];
if ((value == 0) && (cell->cell_value != 0))
start_tracing = true;
else if ((cell->cell_value == value) && (cell->cell_value != 0))
start_tracing = true;
if (start_tracing) {
bool * visited = layer_alloc_visited_mask( layer );
value = cell->cell_value;
int_vector_reset( i_list );
int_vector_reset( j_list );
layer_trace_block_content__(layer , erase , start_i , start_j , value , visited , i_list , j_list );
free( visited );
return true;
} else
return false;
}
int layer_replace_cell_values( layer_type * layer , int old_value , int new_value) {
int i,j;
int replace_count = 0;
for (j=0; j < layer->ny; j++) {
for (i=0; i < layer->nx; i++) {
if (layer_iget_cell_value( layer , i , j ) == old_value) {
layer_iset_cell_value( layer , i , j , new_value);
replace_count++;
}
}
}
return replace_count;
}

View File

@ -36,7 +36,7 @@ struct nnc_info_struct {
int lgr_nr; /* The lgr_nr of the cell holding this nnc_info structure. */
};
static void nnc_info_add_vector( nnc_info_type * nnc_info , nnc_vector_type * nnc_vector);
UTIL_IS_INSTANCE_FUNCTION( nnc_info , NNC_INFO_TYPE_ID )
@ -49,6 +49,58 @@ nnc_info_type * nnc_info_alloc(int lgr_nr) {
return nnc_info;
}
nnc_info_type * nnc_info_alloc_copy( const nnc_info_type * src_info ) {
nnc_info_type * copy_info = nnc_info_alloc( src_info->lgr_nr );
int ivec;
for (ivec = 0; ivec < vector_get_size( src_info->lgr_list ); ivec++) {
nnc_vector_type * copy_vector = nnc_vector_alloc_copy( vector_iget_const( src_info->lgr_list , ivec));
nnc_info_add_vector( copy_info , copy_vector );
}
return copy_info;
}
bool nnc_info_equal( const nnc_info_type * nnc_info1 , const nnc_info_type * nnc_info2 ) {
if (nnc_info1 == nnc_info2)
return true;
if ((nnc_info1 == NULL) || (nnc_info2 == NULL))
return false;
{
if (nnc_info1->lgr_nr != nnc_info2->lgr_nr)
return false;
if ((int_vector_size( nnc_info1->lgr_index_map ) > 0) && (int_vector_size( nnc_info2->lgr_index_map ) > 0)) {
int max_lgr_nr = util_int_max( int_vector_size( nnc_info1->lgr_index_map ),
int_vector_size( nnc_info2->lgr_index_map ) );
int lgr_nr = 0;
while (true) {
nnc_vector_type * vector1 = nnc_info_get_vector( nnc_info1 , lgr_nr );
nnc_vector_type * vector2 = nnc_info_get_vector( nnc_info2 , lgr_nr );
if (!nnc_vector_equal(vector1 , vector2))
return false;
lgr_nr++;
if (lgr_nr > max_lgr_nr)
return true;
}
} else {
if (int_vector_size( nnc_info1->lgr_index_map ) == int_vector_size( nnc_info2->lgr_index_map ))
return true;
else
return false;
}
}
}
void nnc_info_free( nnc_info_type * nnc_info ) {
vector_free(nnc_info->lgr_list);
int_vector_free(nnc_info->lgr_index_map);
@ -73,13 +125,17 @@ nnc_vector_type * nnc_info_get_self_vector( const nnc_info_type * nnc_info ) {
return nnc_info_get_vector( nnc_info , nnc_info->lgr_nr );
}
static void nnc_info_add_vector( nnc_info_type * nnc_info , nnc_vector_type * nnc_vector) {
vector_append_owned_ref( nnc_info->lgr_list , nnc_vector , nnc_vector_free__ );
int_vector_iset( nnc_info->lgr_index_map , nnc_vector_get_lgr_nr( nnc_vector ) , vector_get_size( nnc_info->lgr_list ) - 1 );
}
static void nnc_info_assert_vector( nnc_info_type * nnc_info , int lgr_nr ) {
nnc_vector_type * nnc_vector = nnc_info_get_vector( nnc_info , lgr_nr);
if (!nnc_vector) {
nnc_vector = nnc_vector_alloc( lgr_nr );
vector_append_owned_ref( nnc_info->lgr_list , nnc_vector , nnc_vector_free__ );
int_vector_iset( nnc_info->lgr_index_map , lgr_nr , vector_get_size( nnc_info->lgr_list ) - 1 );
nnc_info_add_vector( nnc_info , nnc_vector );
}
}

View File

@ -53,6 +53,39 @@ nnc_vector_type * nnc_vector_alloc(int lgr_nr) {
return nnc_vector;
}
nnc_vector_type * nnc_vector_alloc_copy(const nnc_vector_type * src_vector) {
nnc_vector_type * copy_vector = util_malloc( sizeof * src_vector );
UTIL_TYPE_ID_INIT(copy_vector , NNC_VECTOR_TYPE_ID);
copy_vector->lgr_nr = src_vector->lgr_nr;
copy_vector->grid_index_list = int_vector_alloc_copy( src_vector->grid_index_list );
copy_vector->nnc_index_list = int_vector_alloc_copy( src_vector->nnc_index_list );
return copy_vector;
}
bool nnc_vector_equal( const nnc_vector_type * nnc_vector1 , const nnc_vector_type * nnc_vector2) {
if (nnc_vector1 == nnc_vector2)
return true;
if ((nnc_vector1 == NULL) || (nnc_vector2 == NULL))
return false;
{
if (nnc_vector1->lgr_nr != nnc_vector2->lgr_nr)
return false;
if (!int_vector_equal( nnc_vector1->grid_index_list , nnc_vector2->grid_index_list))
return false;
if (!int_vector_equal( nnc_vector1->nnc_index_list , nnc_vector2->nnc_index_list))
return false;
return true;
}
}
void nnc_vector_free( nnc_vector_type * nnc_vector ) {
int_vector_free( nnc_vector->grid_index_list );
int_vector_free( nnc_vector->nnc_index_list );

View File

@ -16,8 +16,10 @@
for more details.
*/
#include <math.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <ert/util/util.h>
@ -39,7 +41,7 @@ void point_mapaxes_invtransform( point_type * p , const double origo[2], const d
double dy = p->y - origo[1];
double org_x = (dx*unit_y[1] - dy*unit_y[0]) * norm;
double org_x = ( dx*unit_y[1] - dy*unit_y[0]) * norm;
double org_y = (-dx*unit_x[1] + dy*unit_x[0]) * norm;
p->x = org_x;
@ -48,12 +50,19 @@ void point_mapaxes_invtransform( point_type * p , const double origo[2], const d
void point_compare( const point_type *p1 , const point_type * p2, bool * equal) {
const double tolerance = 0.0001;
if ((abs(p1->x - p2->x) + abs(p1->y - p2->y) + abs(p1->z - p2->z)) > tolerance)
const double tolerance = 0.001;
double diff_x = (abs(p1->x - p2->x) / abs(p1->x + p2->x + 1));
double diff_y = (abs(p1->y - p2->y) / abs(p1->y + p2->y + 1));
double diff_z = (abs(p1->z - p2->z) / abs(p1->z + p2->z + 1));
if (diff_x + diff_y + diff_z > tolerance)
*equal = false;
}
bool point_equal( const point_type *p1 , const point_type * p2) {
return (memcmp( p1 , p2 , sizeof * p1 ) == 0);
}
@ -64,8 +73,12 @@ void point_dump( const point_type * p , FILE * stream) {
}
void point_dump_ascii( const point_type * p , FILE * stream) {
fprintf(stream , "(%7.2f, %7.2f, %7.2f) " , p->x , p->y , p->z);
void point_dump_ascii( const point_type * p , FILE * stream , const double * offset) {
if (offset)
fprintf(stream , "(%7.2f, %7.2f, %7.2f) " , p->x - offset[0], p->y - offset[1] , p->z - offset[2]);
else
fprintf(stream , "(%7.2f, %7.2f, %7.2f) " , p->x , p->y , p->z);
}
@ -184,21 +197,21 @@ void point_normal_vector(point_type * n, const point_type * p0, const point_type
/**
This function calculates the (signed) distance from point 'p' to
the plane specifed by the plane vector 'n' andthe point
the plane specifed by the plane vector 'n' and the point
'plane_point' which is part of the plane.
*/
double point_plane_distance(const point_type * p , const point_type * n , const point_type * plane_point) {
point_type * diff = point_alloc_diff( p , plane_point );
double d = point_dot_product( n , diff );
printf("plane_point: "); point_fprintf( plane_point , stdout ); printf("\n");
printf("p: "); point_fprintf( p , stdout ); printf("\n");
printf("diff: "); point_fprintf( diff , stdout ); printf("\n");
free( diff );
return d;
}
double point3_plane_distance(const point_type * p0 , const point_type * p1 , const point_type * p2 , const point_type * x) {
point_type n;
point_normal_vector( &n , p0 , p1 , p2 );
return point_plane_distance( x , &n , p0 ) / sqrt( n.x*n.x + n.y*n.y + n.z*n.z);
}

View File

@ -64,17 +64,19 @@ double tetrahedron_volume( const tetrahedron_type * tet ) {
point_vector_cross( &b_x_c , &b , &c);
return fabs( point_dot_product( &a , &b_x_c) ) / 6.0;
return point_dot_product( &a , &b_x_c) / 6.0;
}
/**
The __sign() function will return 0 for x ==== 0 - it is not
exactly zero measure....
*/
static int __sign( double x) {
const double zero_tol = 1e-10;
const double zero_tol = 1e-8;
if (fabs(x) < zero_tol)
return 0;
else if (x > 0)
@ -170,8 +172,12 @@ bool tetrahedron_contains__( const tetrahedron_type * tet , const point_type * p
const point_type * p3 = tet->p2;
const point_type * p4 = tet->p3;
double D0 , D1 , D2 , D3 , D4;
int current_sign , sign;
/*
Special casing around the vertex points should be handled prior to
calling this function.
*/
/*****************************************************************/
matrix_iset( D , 0 , 0 , p1->x);
@ -193,10 +199,13 @@ bool tetrahedron_contains__( const tetrahedron_type * tet , const point_type * p
matrix_iset( D , 3 , 1 , p4->y);
matrix_iset( D , 3 , 2 , p4->z);
matrix_iset( D , 3 , 3 , 1);
D0 = matrix_det4( D );
current_sign = __sign( D0 );
if (current_sign == 0)
return false; /* A zero volume cell. */
{
double D0 = matrix_det4( D );
current_sign = __sign( D0 );
if (current_sign == 0)
return false; /* A zero volume cell. */
}
/*****************************************************************/
matrix_iset( D , 0 , 0 , p->x);
@ -218,10 +227,14 @@ bool tetrahedron_contains__( const tetrahedron_type * tet , const point_type * p
matrix_iset( D , 3 , 1 , p4->y);
matrix_iset( D , 3 , 2 , p4->z);
matrix_iset( D , 3 , 3 , 1);
D1 = matrix_det4( D );
sign = __sign( D1 );
if ((sign != 0) && (sign != current_sign)) return false;
{
double D1 = matrix_det4( D );
sign = __sign( D1 );
if ((sign != 0) && (sign != current_sign))
return false;
}
/*****************************************************************/
matrix_iset( D , 0 , 0 , p1->x);
matrix_iset( D , 0 , 1 , p1->y);
@ -242,10 +255,15 @@ bool tetrahedron_contains__( const tetrahedron_type * tet , const point_type * p
matrix_iset( D , 3 , 1 , p4->y);
matrix_iset( D , 3 , 2 , p4->z);
matrix_iset( D , 3 , 3 , 1);
D2 = matrix_det4( D );
sign = __sign( D2 );
if ((sign != 0) && (sign != current_sign)) return false;
{
double D2 = matrix_det4( D );
sign = __sign( D2 );
if ((sign != 0) && (sign != current_sign))
return false;
}
/*****************************************************************/
matrix_iset( D , 0 , 0 , p1->x);
matrix_iset( D , 0 , 1 , p1->y);
matrix_iset( D , 0 , 2 , p1->z);
@ -265,10 +283,15 @@ bool tetrahedron_contains__( const tetrahedron_type * tet , const point_type * p
matrix_iset( D , 3 , 1 , p4->y);
matrix_iset( D , 3 , 2 , p4->z);
matrix_iset( D , 3 , 3 , 1);
D3 = matrix_det4( D );
sign = __sign( D3 );
if ((sign != 0) && (sign != current_sign)) return false;
{
double D3 = matrix_det4( D );
sign = __sign( D3 );
if ((sign != 0) && (sign != current_sign))
return false;
}
/*****************************************************************/
matrix_iset( D , 0 , 0 , p1->x);
matrix_iset( D , 0 , 1 , p1->y);
matrix_iset( D , 0 , 2 , p1->z);
@ -288,11 +311,13 @@ bool tetrahedron_contains__( const tetrahedron_type * tet , const point_type * p
matrix_iset( D , 3 , 1 , p->y);
matrix_iset( D , 3 , 2 , p->z);
matrix_iset( D , 3 , 3 , 1);
D4 = matrix_det4( D );
sign = __sign( D4 );
if ((sign != 0) && (sign != current_sign)) return false;
/*****************************************************************/
{
double D4 = matrix_det4( D );
sign = __sign( D4 );
if ((sign != 0) && (sign != current_sign))
return false;
}
return true;
}
@ -303,3 +328,11 @@ bool tetrahedron_contains( const tetrahedron_type * tet , const point_type * p)
matrix_free( D );
return contains;
}
void tetrahedron_fprintf( const tetrahedron_type * tet , FILE * stream , const double* offset) {
fprintf(stream , "P0: "); point_dump_ascii( tet->p0 , stream , offset); fprintf(stream , "\n");
fprintf(stream , "P1: "); point_dump_ascii( tet->p1 , stream , offset); fprintf(stream , "\n");
fprintf(stream , "P2: "); point_dump_ascii( tet->p2 , stream , offset); fprintf(stream , "\n");
fprintf(stream , "P3: "); point_dump_ascii( tet->p3 , stream , offset); fprintf(stream , "\n");
}

View File

@ -0,0 +1,3 @@
PARALLEL
4 /

View File

@ -0,0 +1,78 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'ecl_fault_block_collection_statoil.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 <unistd.h>
#include <ert/util/test_util.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/fault_block_collection.h>
void test_create( const ecl_grid_type * grid , const ecl_kw_type * fault_block_kw) {
fault_block_collection_type * fault_blocks = fault_block_collection_alloc( grid );
test_assert_true( fault_block_collection_is_instance( fault_blocks ));
test_assert_int_equal( ecl_grid_get_nz( grid ) , fault_block_collection_num_layers( fault_blocks ));
fault_block_collection_free( fault_blocks );
}
void test_get_layer( const ecl_grid_type * grid , const ecl_kw_type * fault_block_kw) {
fault_block_collection_type * fault_blocks = fault_block_collection_alloc( grid );
test_assert_NULL( fault_block_collection_get_layer( fault_blocks , -1 ));
test_assert_NULL( fault_block_collection_get_layer( fault_blocks , ecl_grid_get_nz( grid ) ));
{
int k;
for (k = 0; k < ecl_grid_get_nz( grid ); k++) {
fault_block_layer_type * layer = fault_block_collection_get_layer( fault_blocks , k );
test_assert_true( fault_block_layer_is_instance( layer ));
}
}
fault_block_collection_free( fault_blocks );
}
int main(int argc , char ** argv) {
const char * grid_file = argv[1];
const char * fault_blk_file = argv[2];
ecl_grid_type * ecl_grid = ecl_grid_alloc( grid_file );
ecl_kw_type * fault_blk_kw;
{
FILE * stream = util_fopen( fault_blk_file , "r");
fault_blk_kw = ecl_kw_fscanf_alloc_grdecl( stream , "FAULTBLK" , ecl_grid_get_global_size( ecl_grid ) , ECL_INT_TYPE);
fclose( stream );
}
test_create( ecl_grid , fault_blk_kw );
test_get_layer( ecl_grid , fault_blk_kw );
ecl_grid_free( ecl_grid );
ecl_kw_free( fault_blk_kw );
exit(0);
}

View File

@ -0,0 +1,194 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'ecl_fault_block_layer.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 <unistd.h>
#include <ert/util/test_util.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/fault_block_layer.h>
void test_create( const ecl_grid_type * grid , ecl_kw_type * fault_block_kw) {
int k = 0;
int i,j;
for (j=0; j < ecl_grid_get_ny( grid ); j++) {
for (i = 0; i < ecl_grid_get_nx( grid ); i++) {
int g = ecl_grid_get_global_index3( grid , i,j,k);
ecl_kw_iset_int( fault_block_kw , g , 9 );
}
}
{
fault_block_layer_type * layer = fault_block_layer_alloc( grid , k );
test_assert_int_equal( 1 , fault_block_layer_get_next_id( layer ));
fault_block_layer_scan_kw( layer , fault_block_kw);
{
fault_block_type * block = fault_block_layer_iget_block( layer , 0 );
double x,y,z;
ecl_grid_get_xyz3( grid , 4,4,k , &x, &y , &z );
test_assert_double_equal( x , fault_block_get_xc( block ));
test_assert_double_equal( y , fault_block_get_yc( block ));
}
fault_block_layer_free( layer );
}
}
void test_create_invalid( const ecl_grid_type * grid ) {
ecl_kw_type * fault_blk_kw = ecl_kw_alloc("FAULTBLK" , ecl_grid_get_global_size( grid ) - 1, ECL_INT_TYPE );
test_assert_NULL( fault_block_layer_alloc( grid , 7 ));
ecl_kw_free( fault_blk_kw );
}
void test_trace_edge( const ecl_grid_type * grid) {
const int k = 1;
fault_block_layer_type * layer = fault_block_layer_alloc( grid , k );
double_vector_type * x_list = double_vector_alloc( 0,0);
double_vector_type * y_list = double_vector_alloc( 0,0);
fault_block_type * block = fault_block_layer_safe_get_block( layer , 99);
int_vector_type * cell_list = int_vector_alloc(0,0);
test_assert_false( fault_block_trace_edge( block , x_list , y_list , cell_list));
fault_block_add_cell( block , 0,0);
test_assert_true( fault_block_trace_edge( block , x_list , y_list , cell_list));
test_assert_int_equal( 4 , double_vector_size( x_list ));
test_assert_int_equal( 4 , double_vector_size( y_list ));
test_assert_double_equal( 0 , double_vector_iget( x_list , 0 ));
test_assert_double_equal( 1 , double_vector_iget( x_list , 1 ));
test_assert_double_equal( 1 , double_vector_iget( x_list , 2 ));
test_assert_double_equal( 0 , double_vector_iget( x_list , 3 ));
test_assert_double_equal( 0 , double_vector_iget( y_list , 0 ));
test_assert_double_equal( 0 , double_vector_iget( y_list , 1 ));
test_assert_double_equal( 1 , double_vector_iget( y_list , 2 ));
test_assert_double_equal( 1 , double_vector_iget( y_list , 3 ));
test_assert_int_equal( 1 , int_vector_size( cell_list ));
test_assert_int_equal( 0 , int_vector_iget( cell_list , 0));
int_vector_free( cell_list );
double_vector_free( x_list );
double_vector_free( y_list );
}
void test_export( const ecl_grid_type * grid) {
fault_block_layer_type * layer = fault_block_layer_alloc( grid , 0 );
ecl_kw_type * ecl_kw1 = ecl_kw_alloc("FAULTBLK" , ecl_grid_get_global_size( grid ) , ECL_INT_TYPE );
ecl_kw_type * ecl_kw2 = ecl_kw_alloc("FAULTBLK" , ecl_grid_get_global_size( grid ) + 1 , ECL_INT_TYPE );
ecl_kw_type * ecl_kw3 = ecl_kw_alloc("FAULTBLK" , ecl_grid_get_global_size( grid ) , ECL_FLOAT_TYPE );
fault_block_type * block = fault_block_layer_add_block( layer , 10 );
fault_block_add_cell( block , 0 , 0 );
fault_block_add_cell( block , 1 , 0 );
fault_block_add_cell( block , 1 , 1 );
fault_block_add_cell( block , 0 , 1 );
test_assert_true( fault_block_layer_export( layer , ecl_kw1 ));
test_assert_false( fault_block_layer_export( layer , ecl_kw2 ));
test_assert_false( fault_block_layer_export( layer , ecl_kw3 ));
{
int nx = ecl_grid_get_nx( grid );
test_assert_int_equal( ecl_kw_iget_int( ecl_kw1 , 0 ) , 10 );
test_assert_int_equal( ecl_kw_iget_int( ecl_kw1 , 1 ) , 10 );
test_assert_int_equal( ecl_kw_iget_int( ecl_kw1 , nx ) , 10 );
test_assert_int_equal( ecl_kw_iget_int( ecl_kw1 , nx + 1 ) , 10 );
}
test_assert_int_equal( 40 , ecl_kw_element_sum_int( ecl_kw1 ));
fault_block_layer_free( layer );
ecl_kw_free( ecl_kw1 );
ecl_kw_free( ecl_kw2 );
ecl_kw_free( ecl_kw3 );
}
void test_neighbours( const ecl_grid_type * grid) {
const int k = 0;
fault_block_layer_type * layer = fault_block_layer_alloc( grid , k );
ecl_kw_type * ecl_kw = ecl_kw_alloc("FAULTBLK" , ecl_grid_get_global_size( grid ) , ECL_INT_TYPE );
ecl_kw_iset_int( ecl_kw , 0 , 1);
ecl_kw_iset_int( ecl_kw , ecl_grid_get_global_index3( grid , 3,3,k) , 2);
ecl_kw_iset_int( ecl_kw , ecl_grid_get_global_index3( grid , 4,3,k) , 3);
ecl_kw_iset_int( ecl_kw , ecl_grid_get_global_index3( grid , 5,3,k) , 4);
ecl_kw_iset_int( ecl_kw , ecl_grid_get_global_index3( grid , 4,2,k) , 5);
fault_block_layer_load_kw( layer , ecl_kw);
{
int_vector_type * neighbours = int_vector_alloc( 0,0);
{
fault_block_type * block = fault_block_layer_get_block( layer , 1 );
test_assert_int_equal( 0 , int_vector_size( neighbours ));
fault_block_list_neighbours( block , neighbours );
test_assert_int_equal( 0 , int_vector_size( neighbours ));
}
{
fault_block_type * block = fault_block_layer_get_block( layer , 2 );
fault_block_list_neighbours( block , neighbours );
test_assert_int_equal( 1 , int_vector_size( neighbours ));
test_assert_true( int_vector_contains( neighbours , 3 ));
}
int_vector_free( neighbours );
}
fault_block_layer_free( layer );
ecl_kw_free( ecl_kw );
}
int main(int argc , char ** argv) {
ecl_grid_type * ecl_grid = ecl_grid_alloc_rectangular( 9 , 9 , 2 , 1 , 1 , 1 , NULL );
ecl_kw_type * fault_blk_kw = ecl_kw_alloc("FAULTBLK" , ecl_grid_get_global_size( ecl_grid ) , ECL_INT_TYPE );
test_create( ecl_grid , fault_blk_kw );
test_create_invalid( ecl_grid );
test_trace_edge( ecl_grid );
test_export(ecl_grid);
test_neighbours( ecl_grid );
ecl_grid_free( ecl_grid );
ecl_kw_free( fault_blk_kw );
exit(0);
}

View File

@ -0,0 +1,89 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'ecl_fault_block_layer_statoil.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 <unistd.h>
#include <ert/util/test_util.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/fault_block_layer.h>
void test_create( const ecl_grid_type * grid , const ecl_kw_type * fault_block_kw) {
test_assert_NULL( fault_block_layer_alloc( grid , -1 ));
test_assert_NULL( fault_block_layer_alloc( grid , ecl_grid_get_nz( grid )));
{
int k;
for (k = 0; k < ecl_grid_get_nz( grid ); k++) {
fault_block_layer_type * layer = fault_block_layer_alloc( grid , k);
test_assert_true( fault_block_layer_is_instance( layer ));
fault_block_layer_scan_kw( layer , fault_block_kw);
{
int max_block_id = fault_block_layer_get_max_id( layer );
int block_id;
for (block_id = 0; block_id <= max_block_id; block_id++) {
if (fault_block_layer_has_block( layer , block_id)) {
fault_block_type * block = fault_block_layer_get_block( layer , block_id );
fault_block_get_xc( block );
fault_block_get_yc( block );
}
}
}
{
int index;
for (index = 0; index < fault_block_layer_get_size( layer ); index++) {
fault_block_type * block = fault_block_layer_iget_block( layer , index );
fault_block_get_xc( block );
fault_block_get_yc( block );
}
}
fault_block_layer_free( layer );
}
}
}
int main(int argc , char ** argv) {
const char * grid_file = argv[1];
const char * fault_blk_file = argv[2];
ecl_grid_type * ecl_grid = ecl_grid_alloc( grid_file );
ecl_kw_type * fault_blk_kw;
{
FILE * stream = util_fopen( fault_blk_file , "r");
fault_blk_kw = ecl_kw_fscanf_alloc_grdecl( stream , "FAULTBLK" , ecl_grid_get_global_size( ecl_grid ) , ECL_INT_TYPE);
fclose( stream );
}
test_create( ecl_grid , fault_blk_kw );
ecl_grid_free( ecl_grid );
ecl_kw_free( fault_blk_kw );
exit(0);
}

View File

@ -20,6 +20,7 @@
#include <ert/util/test_util.h>
#include <ert/util/util.h>
#include <ert/util/vector.h>
#include <ert/util/test_work_area.h>
#include <ert/ecl/fortio.h>
@ -32,6 +33,38 @@ void test_existing_read(const char * filename) {
}
void test_fortio_is_instance(const char * filename ) {
{
fortio_type * fortio = fortio_open_reader( filename , false , ECL_ENDIAN_FLIP);
test_assert_not_NULL( fortio );
test_assert_true(fortio_is_instance(fortio));
fortio_fclose( fortio );
}
{
vector_type * dummy_vector = vector_alloc_new();
test_assert_false(fortio_is_instance(dummy_vector));
vector_free(dummy_vector);
}
}
void test_fortio_safe_cast(const char * filename ) {
void * i_am_a_fortio = fortio_open_reader( filename , false , ECL_ENDIAN_FLIP);
test_assert_not_NULL( i_am_a_fortio );
fortio_type * fortio = fortio_safe_cast(i_am_a_fortio);
test_assert_true(fortio_is_instance(fortio));
fortio_fclose( fortio );
}
void test_fortio_unsafe_cast(void * arg) {
void * i_am_not_a_fortio = vector_alloc_new();
test_assert_not_NULL( i_am_not_a_fortio );
fortio_safe_cast(i_am_not_a_fortio);
}
void test_not_existing_read() {
fortio_type * fortio = fortio_open_reader( "/does/not/exist" , false , ECL_ENDIAN_FLIP);
test_assert_NULL( fortio );
@ -78,6 +111,9 @@ void test_open_close_read( const char * filename ) {
int main( int argc , char ** argv) {
const char * file = argv[1];
test_fortio_is_instance( file );
test_fortio_safe_cast( file );
test_assert_util_abort("fortio_safe_cast", test_fortio_unsafe_cast, NULL);
test_existing_read( file );
test_not_existing_read( );
test_open_close_read( file );

View File

@ -26,10 +26,14 @@ int main(int argc , char ** argv) {
const char * filename1 = argv[1];
const char * filename2 = argv[2];
const char * filename3 = argv[3];
const char * filename4 = argv[4];
int num_cpu = 4;
test_assert_int_equal(ecl_util_get_num_cpu(filename1), num_cpu);
test_assert_int_equal(ecl_util_get_num_cpu(filename2), num_cpu);
test_assert_int_equal(ecl_util_get_num_cpu(filename3), num_cpu);
test_assert_int_equal(ecl_util_get_num_cpu(filename4), num_cpu);
exit(0);
}

View File

@ -0,0 +1,188 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'ecl_grid_DEPTHZ.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 <math.h>
#include <ert/util/test_util.h>
#include <ert/ecl/ecl_grid.h>
double zfunc(double x , double y) {
return cos(3*x)*sin(2*y)*sqrt(x*y);
}
double center_sum(const double * DV, int index) {
double sum = DV[index] * 0.5;
for (int i=0; i < index; i++)
sum += DV[i];
return sum;
}
void test_create() {
ecl_grid_type * ecl_grid;
int nx = 100;
int ny = 100;
int nz = 10;
double * DXV = util_malloc( nx * sizeof * DXV );
double * DYV = util_malloc( ny * sizeof * DYV );
double * DZV = util_malloc( nz * sizeof * DZV );
double * DEPTHZ = util_malloc( (nx + 1) * (ny + 1) * sizeof * DEPTHZ);
for (int i=0; i < nx; i++)
DXV[i] = 1.0 / nx;
for (int j=0; j < ny; j++)
DYV[j] = 1.0 / ny;
for (int k=0; k < nz; k++)
DZV[k] = 3.0 / nz;
for (int j=0; j <= ny; j++) {
double y = center_sum(DYV , j);
for (int i=0; i <= nx; i++) {
double x = center_sum(DXV , i);
DEPTHZ[i + j*(nx + 1)] = zfunc( x,y );
}
}
ecl_grid = ecl_grid_alloc_dxv_dyv_dzv_depthz( nx,ny,nz,DXV , DYV , DZV , DEPTHZ , NULL);
for (int k=0; k < nz; k++) {
double z0 = center_sum(DZV , k ) - 0.5*DZV[0];
for (int j=0; j < ny; j++) {
double y0 = center_sum(DYV , j );
for (int i=0; i < nx; i++) {
double x0 = center_sum(DXV , i );
double xc,yc,zc;
int g = ecl_grid_get_global_index3( ecl_grid , i , j , k );
ecl_grid_get_xyz1( ecl_grid , g , &xc , &yc , &zc);
test_assert_double_equal( x0 , xc );
test_assert_double_equal( y0 , yc );
ecl_grid_get_cell_corner_xyz1( ecl_grid , g , 0 , &xc , &yc , &zc);
test_assert_double_equal( z0 + zfunc(x0 , y0) , zc );
ecl_grid_get_cell_corner_xyz1( ecl_grid , g , 4, &xc , &yc , &zc);
test_assert_double_equal( z0 + zfunc(x0 , y0) + DZV[k] , zc );
}
}
}
free( DXV );
free( DYV );
free( DZV );
free( DEPTHZ );
ecl_grid_free( ecl_grid );
}
void test_compare() {
int nx = 10;
int ny = 15;
int nz = 5;
int V = nx*ny*nz;
double dx = 10;
double dy = 15;
double dz = 10;
double z0 = 0;
ecl_grid_type * grid1;
ecl_grid_type * grid2;
{
double * DX = util_malloc( V * sizeof * DX );
double * DY = util_malloc( V * sizeof * DY );
double * DZ = util_malloc( V * sizeof * DZ );
double * TOPS = util_malloc( V * sizeof * TOPS );
for (int i = 0; i < V; i++) {
DX[i] = dx;
DY[i] = dy;
DZ[i] = dz;
}
for (int i = 0; i < nx*ny; i++) {
TOPS[i] = z0;
}
for (int k=1; k < nz; k++) {
for (int i = 0; i < nx*ny; i++) {
int g2 = k*nx*ny + i;
int g1 = (k- 1)*nx*ny + i;
TOPS[g2] = TOPS[g1];
}
}
grid1 = ecl_grid_alloc_dx_dy_dz_tops( nx , ny , nz , DX , DY , DZ , TOPS , NULL );
free( DX );
free( DY );
free( DZ );
free( TOPS );
}
{
double * DXV = util_malloc( nx * sizeof * DXV );
double * DYV = util_malloc( ny * sizeof * DYV );
double * DZV = util_malloc( nz * sizeof * DZV );
double * DEPTHZ = util_malloc( (nx + 1)*(ny + 1) * sizeof * DEPTHZ);
for (int i = 0; i < nx; i++)
DXV[i] = dx;
for (int i = 0; i < ny; i++)
DYV[i] = dy;
for (int i = 0; i < nz; i++)
DZV[i] = dz;
for (int i = 0; i < (nx + 1)*(ny+ 1); i++)
DEPTHZ[i] = z0;
grid2 = ecl_grid_alloc_dxv_dyv_dzv_depthz( nx , ny , nz , DXV , DYV , DZV , DEPTHZ , NULL );
free( DXV );
free( DYV );
free( DZV );
free( DEPTHZ );
}
test_assert_true( ecl_grid_compare( grid1 , grid2 , true , true , true));
ecl_grid_free( grid1 );
ecl_grid_free( grid2 );
}
int main(int argc , char ** argv) {
test_create();
test_compare();
exit(0);
}

View File

@ -0,0 +1,288 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'ecl_grid_cell_contains.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/ecl/ecl_grid.h>
#include <ert/ecl/point.h>
void test_grid_covering( const ecl_grid_type * grid) {
const int nx = ecl_grid_get_nx( grid );
const int ny = ecl_grid_get_ny( grid );
const int nz = ecl_grid_get_nz( grid );
for (int k=0; k < nz - 1; k++) {
for (int j=0; j < ny; j++) {
for (int i=0; i < nx; i++) {
int g1 = ecl_grid_get_global_index3(grid, i,j,k);
int g2 = ecl_grid_get_global_index3(grid, i,j,k + 1);
point_type p1;
point_type p2;
for (int l=0; l < 4; l++) {
ecl_grid_get_cell_corner_xyz1( grid , g1 , l + 4 , &p1.x , &p1.y , &p1.z);
ecl_grid_get_cell_corner_xyz1( grid , g2 , l , &p2.x , &p2.y , &p2.z);
test_assert_true( point_equal( &p1 , &p2 ));
}
for (int l=0; l < 4; l++) {
ecl_grid_get_cell_corner_xyz1( grid , g1 , l , &p1.x , &p1.y , &p1.z);
ecl_grid_get_cell_corner_xyz1( grid , g1 , l + 4 , &p2.x , &p2.y , &p2.z);
test_assert_true( p2.z >= p1.z );
}
}
}
}
}
void test_contains_count( const ecl_grid_type * grid ) {
int error_count = 0;
const int nx = ecl_grid_get_nx( grid );
const int ny = ecl_grid_get_ny( grid );
const int nz = ecl_grid_get_nz( grid );
for (int k=0; k < nz; k++) {
printf("k: %d/%d \n", k , nz - 1);
for (int j=0; j < ny; j++) {
for (int i=0; i < nx; i++) {
double x,y,z;
ecl_grid_get_xyz3( grid , i,j,k , &x,&y,&z);
{
int i2,j2,k2;
int contains_count = 0;
int kmin = util_int_max( 0 , k - 1 );
int kmax = util_int_min( nz , k + 1 );
int jmin = util_int_max( 0 , j - 1 );
int jmax = util_int_min( ny , j + 1 );
int imin = util_int_max( 0 , i - 1 );
int imax = util_int_min( nx , i + 1 );
for (k2 = kmin; k2 < kmax; k2++) {
for (j2 = jmin; j2 < jmax; j2++) {
for (i2 = imin; i2 < imax; i2++) {
if (ecl_grid_cell_contains_xyz3( grid , i2,j2,k2 , x,y, z )) {
contains_count++;
}
}
}
}
if (contains_count != 1) {
if (contains_count > 1)
error_count += 1;
else
if (ecl_grid_cell_regular3( grid , i,j,k))
error_count += 1;
}
}
}
}
}
test_assert_int_equal( error_count , 0 );
}
void test_find( ecl_grid_type * grid ) {
int init_index;
int find_count = 100;
int delta = util_int_max(1 , ecl_grid_get_global_size( grid ) / find_count);
for (init_index = 0; init_index < ecl_grid_get_global_size( grid ); init_index += delta) {
printf("find index:%d \n",init_index / delta);
if (!ecl_grid_cell_invalid1(grid , init_index) && ecl_grid_cell_regular1( grid , init_index) ) {
double x,y,z;
int find_index;
int start_index = 0;
ecl_grid_get_xyz1( grid , init_index , &x,&y,&z);
find_index = ecl_grid_get_global_index_from_xyz(grid , x, y , z , start_index );
test_assert_int_equal(init_index , find_index );
}
}
}
// /*
// Will indeed answer yes when asked if it contains it's own center.
// */
// test_assert_true( ecl_grid_cell_contains_xyz1( grid , init_index , x,y,z) );
//
// if (1)
// {
// int start_index = 0;
//
// if (find_index != init_index) {
// int init_ijk[3];
// int find_ijk[3];
//
// ecl_grid_get_ijk1( grid , find_index , &find_ijk[0] , &find_ijk[1] , &find_ijk[2]);
// ecl_grid_get_ijk1( grid , init_index , &init_ijk[0] , &init_ijk[1] , &init_ijk[2]);
//
// printf("ijk: %d:(%2d,%2d,%2d) -> %d:(%2d,%2d,%2d) \n",init_index , init_ijk[0] , init_ijk[1] , init_ijk[2] , find_index , find_ijk[0] , find_ijk[1], find_ijk[2]);
// global_error += 1;
// }
//
// if (0) {
// //if (find_index != init_index) {
// int init_ijk[3];
// int find_ijk[3];
//
// ecl_grid_get_ijk1( grid , find_index , &find_ijk[0] , &find_ijk[1] , &find_ijk[2]);
// ecl_grid_get_ijk1( grid , init_index , &init_ijk[0] , &init_ijk[1] , &init_ijk[2]);
//
// {
// printf("ijk: (%2d,%2d,%2d) -> (%2d,%2d,%2d) \n",init_ijk[0] , init_ijk[1] , init_ijk[2] , find_ijk[0] , find_ijk[1], find_ijk[2]);
//
// if (0) {
// printf(" ecl_grid_cell_contains_xyz3(%d,%d,%d) : %d Volume:%g \n",init_ijk[0] , init_ijk[1], init_ijk[2] ,
// ecl_grid_cell_contains_xyz3( grid , init_ijk[0] , init_ijk[1], init_ijk[2] , x , y , z ),
// ecl_grid_get_cell_volume1( grid , init_index));
//
// printf(" ecl_grid_cell_contains_xyz3(%d,%d,%d) : %d Volume:%g \n",find_ijk[0] , find_ijk[1], find_ijk[2] ,
// ecl_grid_cell_contains_xyz3( grid , find_ijk[0] , find_ijk[1], find_ijk[2] , x , y , z ),
// ecl_grid_get_cell_volume1( grid , find_index));
// }
//
// {
// int find_index2 = ecl_grid_get_global_index_from_xyz(grid , x, y , z , init_index );
// printf("find_index2:%d \n",find_index2);
// }
//
// printf("init_index:%d find_index:%d \n",init_index , find_index);
// if (find_index >= 0)
// printf("Vrengte: %d\n",ecl_grid_cell_inside_out1( grid , find_index));
// printf("Vrengte: %d\n",ecl_grid_cell_inside_out1( grid , init_index));
//
// {
// bool init_cell_inside_out = ecl_grid_cell_inside_out1( grid , init_index);
// bool find_cell_inside_out = false;
//
// if (find_index >= 0)
// find_cell_inside_out = ecl_grid_cell_inside_out1( grid , find_index );
// else
// test_assert_int_not_equal( -1 , find_index );
//
// if (find_cell_inside_out == init_cell_inside_out) {
// if (init_cell_inside_out == false)
// test_assert_int_equal( init_index , find_index );
// }
// }
// }
// }
// }
// }
// }
//}
void test_corners() {
ecl_grid_type * grid = ecl_grid_alloc_rectangular(3,3,3,1,1,1,NULL);
test_assert_int_equal( -1 , ecl_grid_get_global_index_from_xyz( grid , -1,-1,-1 , 0));
test_assert_int_equal( -1 , ecl_grid_get_global_index_from_xyz( grid , -1, 1, 1 , 0));
test_assert_int_equal( -1 , ecl_grid_get_global_index_from_xyz( grid , 1,-1, 1 , 0));
test_assert_int_equal( -1 , ecl_grid_get_global_index_from_xyz( grid , 1, 1,-1 , 0));
test_assert_int_equal( -1 , ecl_grid_get_global_index_from_xyz( grid , 3.5 , 3.5 , 3.5 , 0));
test_assert_int_equal( -1 , ecl_grid_get_global_index_from_xyz( grid , 3.5 , 1 , 1 , 0));
test_assert_int_equal( -1 , ecl_grid_get_global_index_from_xyz( grid , 1 , 3.5 , 1 , 0));
test_assert_int_equal( -1 , ecl_grid_get_global_index_from_xyz( grid , 1 , 1 , 3.5 , 0));
{
double x,y,z;
int i;
ecl_grid_get_cell_corner_xyz3( grid , 0, 0, 0 , 0 , &x , &y , &z);
test_assert_int_equal( 0 , ecl_grid_get_global_index_from_xyz( grid , x,y,z,0));
for (i=1; i < 8; i++) {
ecl_grid_get_cell_corner_xyz3( grid , 0, 0, 0 , i , &x , &y , &z);
test_assert_int_not_equal( 0 , ecl_grid_get_global_index_from_xyz( grid , x,y,z,0));
}
// Corner 1
ecl_grid_get_cell_corner_xyz3(grid , 2,0,0,1 , &x,&y,&z);
test_assert_int_equal( ecl_grid_get_global_index3( grid , 2,0,0 ) , ecl_grid_get_global_index_from_xyz( grid , x,y,z,0));
// Corner 2
ecl_grid_get_cell_corner_xyz3(grid , 0,2,0,2 , &x,&y,&z);
test_assert_int_equal( ecl_grid_get_global_index3( grid , 0,2,0 ) , ecl_grid_get_global_index_from_xyz( grid , x,y,z,0));
// Corner 3
ecl_grid_get_cell_corner_xyz3(grid , 2,2,0,3 , &x,&y,&z);
test_assert_int_equal( ecl_grid_get_global_index3( grid , 2,2,0 ) , ecl_grid_get_global_index_from_xyz( grid , x,y,z,0));
// Corner 4
ecl_grid_get_cell_corner_xyz3(grid , 0,0,2,4 , &x,&y,&z);
test_assert_int_equal( ecl_grid_get_global_index3( grid , 0,0,2 ) , ecl_grid_get_global_index_from_xyz( grid , x,y,z,0));
// Corner 5
ecl_grid_get_cell_corner_xyz3(grid , 2,0,2,5 , &x,&y,&z);
test_assert_int_equal( ecl_grid_get_global_index3( grid , 2,0,2 ) , ecl_grid_get_global_index_from_xyz( grid , x,y,z,0));
// Corner 6
ecl_grid_get_cell_corner_xyz3(grid , 0,2,2,6 , &x,&y,&z);
test_assert_int_equal( ecl_grid_get_global_index3( grid , 0,2,2 ) , ecl_grid_get_global_index_from_xyz( grid , x,y,z,0));
// Corner 7
ecl_grid_get_cell_corner_xyz3(grid , 2,2,2,7 , &x,&y,&z);
test_assert_int_equal( ecl_grid_get_global_index3( grid , 2,2,2 ) , ecl_grid_get_global_index_from_xyz( grid , x,y,z,0));
}
ecl_grid_free( grid );
}
int main(int argc , char ** argv) {
ecl_grid_type * grid;
int case_nr;
util_install_signals();
util_sscanf_int( argv[1] , &case_nr );
if (argc == 2) {
grid = ecl_grid_alloc_rectangular(6,6,6,1,2,3,NULL);
} else
grid = ecl_grid_alloc( argv[2] );
test_grid_covering( grid );
test_contains_count( grid );
test_find(grid);
test_corners();
ecl_grid_free( grid );
exit(0);
}

View File

@ -0,0 +1,57 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'ecl_grid_cell_contains.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/ecl/ecl_grid.h>
void test_cells( const ecl_grid_type * grid ) {
int error_count = 0;
int global_index;
for (global_index = 0; global_index < ecl_grid_get_global_size( grid ); global_index++) {
if ((abs(ecl_grid_get_cell_volume1( grid , global_index)) + abs(ecl_grid_get_cell_volume1_tskille( grid , global_index))) > 1e-9) {
if (!test_check_double_equal( ecl_grid_get_cell_volume1( grid , global_index) , ecl_grid_get_cell_volume1_tskille( grid , global_index))) {
fprintf(stderr," Global index:%d \n",global_index);
error_count += 1;
}
}
}
test_assert_int_equal(0 , error_count);
}
int main(int argc , char ** argv) {
ecl_grid_type * grid;
if (argc == 1)
grid = ecl_grid_alloc_rectangular(6,6,6,1,2,3,NULL);
else
grid = ecl_grid_alloc( argv[1] );
test_cells( grid );
ecl_grid_free( grid );
exit(0);
}

View File

@ -0,0 +1,48 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'ecl_grid_copy.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/util/time_t_vector.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_grid.h>
void test_copy_grid( const ecl_grid_type * grid ) {
ecl_grid_type * grid_copy = ecl_grid_alloc_copy( grid );
test_assert_true( ecl_grid_compare( grid , grid_copy , true , true , true ));
ecl_grid_free( grid_copy );
}
int main( int argc , char ** argv) {
ecl_grid_type * grid = ecl_grid_alloc_rectangular( 10,11,12,1,2,3 , NULL);
test_copy_grid( grid );
ecl_grid_free( grid );
exit(0);
}

View File

@ -0,0 +1,52 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'ecl_grid_copy_statoil.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/util/time_t_vector.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_grid.h>
void test_copy_grid( const char * filename ) {
{
ecl_grid_type * src_grid = ecl_grid_alloc( filename );
ecl_grid_type * copy_grid = ecl_grid_alloc_copy( src_grid );
test_assert_true( ecl_grid_compare( src_grid , copy_grid , true , true , true ));
ecl_grid_free( copy_grid );
ecl_grid_free( src_grid );
}
}
int main( int argc , char ** argv) {
int iarg;
for (iarg = 1; iarg < argc; iarg++)
test_copy_grid( argv[iarg] );
exit(0);
}

View File

@ -0,0 +1,72 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'ecl_grid_corner.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/ecl/ecl_grid.h>
void invalid_call1( void * arg ) {
ecl_grid_type * grid = ecl_grid_safe_cast( arg );
double x,y,z;
ecl_grid_get_corner_xyz( grid , 10,10,11 , &x,&y,&z);
}
void test_invalid( ecl_grid_type * grid) {
test_assert_util_abort( "ecl_grid_get_corner_xyz" , invalid_call1 , grid );
}
void test_OK( const ecl_grid_type * grid) {
double x,y,z;
ecl_grid_get_corner_xyz( grid , 0,0,0,&x,&y,&z);
test_assert_double_equal( x,0 );
test_assert_double_equal( y,0 );
test_assert_double_equal( z,0 );
ecl_grid_get_corner_xyz( grid , 4,5,6,&x,&y,&z);
test_assert_double_equal( x,4 );
test_assert_double_equal( y,5 );
test_assert_double_equal( z,6 );
ecl_grid_get_corner_xyz( grid , 10,10,10,&x,&y,&z);
test_assert_double_equal( x,10 );
test_assert_double_equal( y,10 );
test_assert_double_equal( z,10 );
}
int main( int argc , char ** argv) {
ecl_grid_type * grid = ecl_grid_alloc_rectangular(10,10,10,1,1,1, NULL);
test_invalid( grid );
test_OK(grid);
ecl_grid_free( grid );
exit(0);
}

View File

@ -0,0 +1,145 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'ecl_grid_create.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 <signal.h>
#include <ert/util/test_util.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_grid.h>
void test_create2() {
int nx = 10;
int ny = 8;
int nz = 5;
double * dx = util_calloc( nx*ny*nz , sizeof * dx );
double * dy = util_calloc( nx*ny*nz , sizeof * dy );
double * dz = util_calloc( nx*ny*nz , sizeof * dz );
double * tops = util_calloc( nx*ny*nz , sizeof * dz );
for (int k=0; k< nz; k++) {
for (int j=0; j < ny; j++) {
for (int i=0; i < nx; i++) {
int g = k*nx*ny + j*nx + i;
dx[g] = (i+1);
dy[g] = (j+1);
dz[g] = (k+1);
if (k == 0)
tops[g] = 77;
else
tops[g] = tops[g - nx*ny] + dz[g];
}
}
}
{
ecl_grid_type * grid = ecl_grid_alloc_dx_dy_dz_tops( nx , ny , nz , dx , dy , dz , tops , NULL );
test_assert_int_equal( nx*ny*nz , ecl_grid_get_global_size( grid ));
test_assert_int_equal( nx*ny*nz , ecl_grid_get_active_size( grid ));
for (int k=0; k< nz; k++) {
for (int j=0; j < ny; j++) {
for (int i=0; i < nx; i++) {
int g = k*nx*ny + j*nx + i;
test_assert_double_equal( ecl_grid_get_cell_volume1( grid , g ) , dx[g] * dy[g] * dz[g]);
}
}
}
{
double x,y,z;
ecl_grid_get_xyz1(grid , 0 , &x , &y , &z);
test_assert_double_equal( x , dx[0] * 0.5 );
test_assert_double_equal( y , dy[0] * 0.5 );
test_assert_double_equal( z , dz[0] * 0.5 + tops[0]);
}
ecl_grid_free( grid );
}
free( tops );
free( dx );
free( dy );
free( dz );
}
void test_create1() {
int nx = 10;
int ny = 10;
int nz = 10;
double * dx = util_calloc( nx*ny*nz , sizeof * dx );
double * dy = util_calloc( nx*ny*nz , sizeof * dy );
double * dz = util_calloc( nx*ny*nz , sizeof * dz );
double * tops = util_calloc( nx*ny*nz , sizeof * tops );
for (int k=0; k< nz; k++) {
for (int j=0; j < ny; j++) {
for (int i=0; i < nx; i++) {
int g = k*nx*ny + j*nx + i;
dx[g] = 1;
dy[g] = 1;
dz[g] = 1;
if (k == 0)
tops[g] = 0;
else
tops[g] = tops[g - nx*ny] + dz[g];
}
}
}
{
ecl_grid_type * grid = ecl_grid_alloc_dx_dy_dz_tops( nx , ny , nz , dx , dy , dz , tops , NULL );
test_assert_int_equal( nx*ny*nz , ecl_grid_get_global_size( grid ));
test_assert_int_equal( nx*ny*nz , ecl_grid_get_active_size( grid ));
for (int k=0; k< nz; k++) {
for (int j=0; j < ny; j++) {
for (int i=0; i < nx; i++) {
int g = k*nx*ny + j*nx + i;
test_assert_double_equal( ecl_grid_get_cell_volume1( grid , g ) , dx[g] * dy[g] * dz[g]);
{
double x,y,z;
ecl_grid_get_xyz1(grid , g , &x , &y , &z);
test_assert_double_equal( x , i + 0.5);
test_assert_double_equal( y , j + 0.5);
test_assert_double_equal( z , k + 0.5);
}
}
}
}
ecl_grid_free( grid );
}
free( tops );
free( dx );
free( dy );
free( dz );
}
int main(int argc , char ** argv) {
test_create1();
test_create2();
}

View File

@ -0,0 +1,107 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'ecl_grid_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 details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/ecl_file.h>
void export_actnum( const ecl_grid_type * ecl_grid , ecl_file_type * ecl_file ) {
ecl_kw_type * actnum_kw = ecl_file_iget_named_kw( ecl_file , "ACTNUM" , 0 );
int * actnum = util_malloc( ecl_kw_get_size( actnum_kw ) * sizeof * actnum );
ecl_grid_init_actnum_data( ecl_grid , actnum );
for (int i=0; i < ecl_kw_get_size( actnum_kw); i++)
test_assert_int_equal( actnum[i] , ecl_kw_iget_int( actnum_kw , i ));
free( actnum );
}
void export_coord( const ecl_grid_type * grid , ecl_file_type * ecl_file ) {
ecl_kw_type * coord_kw = ecl_file_iget_named_kw( ecl_file , "COORD" , 0);
test_assert_int_equal( ecl_kw_get_size( coord_kw ) , ecl_grid_get_coord_size( grid ));
{
float * coord_float = util_malloc( ecl_grid_get_coord_size( grid ) * sizeof * coord_float );
double * coord_double = util_malloc( ecl_grid_get_coord_size( grid ) * sizeof * coord_double );
ecl_grid_init_coord_data( grid , coord_float );
ecl_grid_init_coord_data_double( grid , coord_double );
for (int i=0; i < ecl_grid_get_coord_size( grid ); i++)
test_assert_double_equal( coord_double[i] , coord_float[i]);
free( coord_float );
free( coord_double );
}
}
void export_zcorn( const ecl_grid_type * grid , ecl_file_type * ecl_file ) {
ecl_kw_type * zcorn_kw = ecl_file_iget_named_kw( ecl_file , "ZCORN" , 0);
test_assert_int_equal( ecl_kw_get_size( zcorn_kw ) , ecl_grid_get_zcorn_size( grid ));
{
float * zcorn_float = util_malloc( ecl_grid_get_zcorn_size( grid ) * sizeof * zcorn_float );
double * zcorn_double = util_malloc( ecl_grid_get_zcorn_size( grid ) * sizeof * zcorn_double );
ecl_grid_init_zcorn_data( grid , zcorn_float );
ecl_grid_init_zcorn_data_double( grid , zcorn_double );
for (int i=0; i < ecl_grid_get_zcorn_size( grid ); i++) {
test_assert_double_equal( zcorn_double[i] , zcorn_float[i]);
test_assert_float_equal( zcorn_float[i] , ecl_kw_iget_float( zcorn_kw , i ));
}
free( zcorn_float );
free( zcorn_double );
}
}
void export_mapaxes( const ecl_grid_type * grid , ecl_file_type * ecl_file ) {
ecl_kw_type * mapaxes_kw = ecl_file_iget_named_kw( ecl_file , "MAPAXES" , 0);
double mapaxes[6];
int i;
test_assert_true( ecl_grid_use_mapaxes( grid ));
ecl_grid_init_mapaxes_data_double( grid , mapaxes );
for (i= 0; i < 6; i++)
test_assert_double_equal( ecl_kw_iget_float( mapaxes_kw , i) , mapaxes[i]);
}
int main(int argc , char ** argv) {
const char * grid_file = argv[1];
ecl_grid_type * ecl_grid = ecl_grid_alloc( grid_file );
ecl_file_type * ecl_file = ecl_file_open( grid_file , 0) ;
export_actnum( ecl_grid , ecl_file );
export_coord( ecl_grid , ecl_file );
export_zcorn( ecl_grid , ecl_file );
export_mapaxes( ecl_grid , ecl_file );
ecl_file_close( ecl_file );
ecl_grid_free( ecl_grid );
}

View File

@ -0,0 +1,48 @@
/*
Copyright (C) 2014 Statoil ASA, Norway.
The file 'ecl_kw_fwrite.c' is part of ERT - Ensemble based Reservoir Tool.
ERT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/util/util.h>
#include <ert/util/test_work_area.h>
#include <ert/ecl/ecl_grid.h>
void test_fwrite_EGRID(ecl_grid_type * grid ) {
test_work_area_type * work_area = test_work_area_alloc("grid-has-mapaxes");
ecl_grid_fwrite_EGRID( grid , "TEST.EGRID");
{
ecl_grid_type * copy = ecl_grid_alloc( "TEST.EGRID" );
test_assert_true( ecl_grid_compare( grid , copy , false , false , true ));
ecl_grid_free( copy );
}
test_work_area_free( work_area );
}
int main( int argc , char **argv) {
const char * src_file = argv[1];
ecl_grid_type * grid = ecl_grid_alloc( src_file );
test_fwrite_EGRID( grid );
ecl_grid_free( grid );
}

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