mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Use commit 0e1e780fd6f18ce93119061e36a4fca9711bc020 Excluded multibuild folder, as this caused git issues
205 lines
8.8 KiB
C++
205 lines
8.8 KiB
C++
/*
|
|
Copyright (C) 2012 Equinor ASA, Norway.
|
|
|
|
The file 'ecl_init_file.c' is part of ERT - Ensemble based Reservoir Tool.
|
|
|
|
ERT is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
ERT is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
|
for more details.
|
|
*/
|
|
|
|
/*
|
|
This file contains functionality to write an ECLIPSE INIT file. The
|
|
file does (currently) not contain any datastructures, only
|
|
functions. Essentially this file is only a codifying of the ECLIPSE
|
|
documentation of INIT files.
|
|
|
|
The functionality is mainly targeted at saving grid properties like
|
|
PORO, PERMX and FIPNUM. The thermodynamic/relperm properties are
|
|
mainly hardcoded to FALSE (in particular in the
|
|
ecl_init_file_alloc_LOGIHEAD() function); this implies that the INIT
|
|
files produced in this way are probably not 100% valid, and can
|
|
certainly not be used to query for e.g. relperm properties.
|
|
*/
|
|
|
|
|
|
#include <ert/util/util.h>
|
|
|
|
#include <ert/ecl/fortio.h>
|
|
#include <ert/ecl/ecl_kw_magic.hpp>
|
|
#include <ert/ecl/ecl_kw.hpp>
|
|
#include <ert/ecl/ecl_grid.hpp>
|
|
#include <ert/ecl/ecl_util.hpp>
|
|
#include <ert/ecl/ecl_type.hpp>
|
|
#include <ert/ecl/ecl_init_file.hpp>
|
|
|
|
static ecl_kw_type * ecl_init_file_alloc_INTEHEAD( const ecl_grid_type * ecl_grid , ert_ecl_unit_enum unit_system, int phases, time_t start_date , int simulator) {
|
|
ecl_kw_type * intehead_kw = ecl_kw_alloc( INTEHEAD_KW , INTEHEAD_INIT_SIZE , ECL_INT );
|
|
ecl_kw_scalar_set_int( intehead_kw , 0 );
|
|
|
|
ecl_kw_iset_int( intehead_kw , INTEHEAD_UNIT_INDEX , unit_system );
|
|
ecl_kw_iset_int( intehead_kw , INTEHEAD_NX_INDEX , ecl_grid_get_nx( ecl_grid ));
|
|
ecl_kw_iset_int( intehead_kw , INTEHEAD_NY_INDEX , ecl_grid_get_ny( ecl_grid ));
|
|
ecl_kw_iset_int( intehead_kw , INTEHEAD_NZ_INDEX , ecl_grid_get_nz( ecl_grid ));
|
|
ecl_kw_iset_int( intehead_kw , INTEHEAD_NACTIVE_INDEX , ecl_grid_get_active_size( ecl_grid ));
|
|
ecl_kw_iset_int( intehead_kw , INTEHEAD_PHASE_INDEX , phases );
|
|
{
|
|
int mday,month,year;
|
|
ecl_util_set_date_values( start_date , &mday , &month , &year );
|
|
ecl_kw_iset_int( intehead_kw , INTEHEAD_DAY_INDEX , mday );
|
|
ecl_kw_iset_int( intehead_kw , INTEHEAD_MONTH_INDEX , month );
|
|
ecl_kw_iset_int( intehead_kw , INTEHEAD_YEAR_INDEX , year );
|
|
}
|
|
ecl_kw_iset_int( intehead_kw , INTEHEAD_IPROG_INDEX , simulator);
|
|
|
|
return intehead_kw;
|
|
}
|
|
|
|
|
|
static ecl_kw_type * ecl_init_file_alloc_LOGIHEAD( int simulator ) {
|
|
/*
|
|
This function includes lots of hardcoded options; the main
|
|
intention of writing the INIT file is to store the grid properties
|
|
like e.g. PORO and SATNUM. The relperm/thermodynamics properties
|
|
are just all defaulted to False.
|
|
|
|
The documentation
|
|
*/
|
|
bool with_RS = false;
|
|
bool with_RV = false;
|
|
bool with_directional_relperm = false;
|
|
bool with_reversible_relperm_ECLIPSE100 = false;
|
|
bool radial_grid_ECLIPSE100 = false;
|
|
bool radial_grid_ECLIPSE300 = false;
|
|
bool with_reversible_relperm_ECLIPSE300 = false;
|
|
bool with_hysterisis = false;
|
|
bool dual_porosity = false;
|
|
bool endpoint_scaling = false;
|
|
bool directional_endpoint_scaling = false;
|
|
bool reversible_endpoint_scaling = false;
|
|
bool alternative_endpoint_scaling = false;
|
|
bool miscible_displacement = false;
|
|
bool scale_water_PC_at_max_sat = false;
|
|
bool scale_gas_PC_at_max_sat = false;
|
|
|
|
|
|
ecl_kw_type * logihead_kw = ecl_kw_alloc( LOGIHEAD_KW , LOGIHEAD_INIT_SIZE , ECL_BOOL );
|
|
|
|
ecl_kw_scalar_set_bool( logihead_kw , false );
|
|
|
|
ecl_kw_iset_bool( logihead_kw , LOGIHEAD_RS_INDEX , with_RS);
|
|
ecl_kw_iset_bool( logihead_kw , LOGIHEAD_RV_INDEX , with_RV);
|
|
ecl_kw_iset_bool( logihead_kw , LOGIHEAD_DIR_RELPERM_INDEX , with_directional_relperm);
|
|
|
|
if (simulator == INTEHEAD_ECLIPSE100_VALUE) {
|
|
ecl_kw_iset_bool( logihead_kw , LOGIHEAD_REV_RELPERM100_INDEX , with_reversible_relperm_ECLIPSE100);
|
|
ecl_kw_iset_bool( logihead_kw , LOGIHEAD_RADIAL100_INDEX , radial_grid_ECLIPSE100);
|
|
} else {
|
|
ecl_kw_iset_bool( logihead_kw , LOGIHEAD_REV_RELPERM300_INDEX , with_reversible_relperm_ECLIPSE300 );
|
|
ecl_kw_iset_bool( logihead_kw , LOGIHEAD_RADIAL300_INDEX , radial_grid_ECLIPSE300);
|
|
}
|
|
|
|
ecl_kw_iset_bool( logihead_kw , LOGIHEAD_HYSTERISIS_INDEX , with_hysterisis);
|
|
ecl_kw_iset_bool( logihead_kw , LOGIHEAD_DUALP_INDEX , dual_porosity);
|
|
ecl_kw_iset_bool( logihead_kw , LOGIHEAD_ENDPOINT_SCALING_INDEX , endpoint_scaling);
|
|
ecl_kw_iset_bool( logihead_kw , LOGIHEAD_DIR_ENDPOINT_SCALING_INDEX , directional_endpoint_scaling);
|
|
ecl_kw_iset_bool( logihead_kw , LOGIHEAD_REV_ENDPOINT_SCALING_INDEX , reversible_endpoint_scaling);
|
|
ecl_kw_iset_bool( logihead_kw , LOGIHEAD_ALT_ENDPOINT_SCALING_INDEX , alternative_endpoint_scaling);
|
|
ecl_kw_iset_bool( logihead_kw , LOGIHEAD_MISC_DISPLACEMENT_INDEX , miscible_displacement);
|
|
ecl_kw_iset_bool( logihead_kw , LOGIHEAD_SCALE_WATER_PC_AT_MAX_SAT_INDEX , scale_water_PC_at_max_sat);
|
|
ecl_kw_iset_bool( logihead_kw , LOGIHEAD_SCALE_GAS_PC_AT_MAX_SAT_INDEX , scale_gas_PC_at_max_sat);
|
|
|
|
return logihead_kw;
|
|
}
|
|
|
|
|
|
static ecl_kw_type * ecl_init_file_alloc_DOUBHEAD( ) {
|
|
ecl_kw_type * doubhead_kw = ecl_kw_alloc( DOUBHEAD_KW , DOUBHEAD_INIT_SIZE , ECL_DOUBLE );
|
|
|
|
ecl_kw_scalar_set_double( doubhead_kw , 0);
|
|
|
|
return doubhead_kw;
|
|
}
|
|
|
|
|
|
/**
|
|
The writing of the PORO field is somewhat special cased; the INIT
|
|
file should contain the PORV keyword with nx*ny*nz elements. The
|
|
cells which are inactive have the PORV volume explicitly set to
|
|
zero; this way the active/inactive status can be inferred from PORV
|
|
field in the INIT file.
|
|
|
|
In this code the PORO field is considered to be the fundamental
|
|
quantity, and the PORV field is calculated from PORO and the volume
|
|
of the grid cells. Apart from PORV all the remaining fields in the
|
|
INIT file should have nactive elements.
|
|
|
|
If you do not wish this function to be used for the PORV special
|
|
casing you can just pass NULL as the poro_kw in the
|
|
ecl_init_file_fwrite_header() function.
|
|
*/
|
|
|
|
static void ecl_init_file_fwrite_poro( fortio_type * fortio , const ecl_grid_type * ecl_grid , const ecl_kw_type * poro ) {
|
|
{
|
|
ecl_kw_type * porv = ecl_kw_alloc( PORV_KW , ecl_grid_get_global_size( ecl_grid ) , ECL_FLOAT);
|
|
int global_index;
|
|
bool global_poro = (ecl_kw_get_size( poro ) == ecl_grid_get_global_size( ecl_grid )) ? true : false;
|
|
for ( global_index = 0; global_index < ecl_grid_get_global_size( ecl_grid ); global_index++) {
|
|
int active_index = ecl_grid_get_active_index1( ecl_grid , global_index );
|
|
if (active_index >= 0) {
|
|
int poro_index = global_poro ? global_index : active_index;
|
|
ecl_kw_iset_float( porv , global_index , ecl_kw_iget_float( poro , poro_index ) * ecl_grid_get_cell_volume1( ecl_grid , global_index ));
|
|
} else
|
|
ecl_kw_iset_float( porv , global_index , 0 );
|
|
}
|
|
ecl_kw_fwrite( porv , fortio );
|
|
ecl_kw_free( porv );
|
|
}
|
|
|
|
ecl_kw_fwrite( poro , fortio );
|
|
}
|
|
|
|
|
|
/*
|
|
If the poro keyword is non NULL this function will write both the
|
|
PORO keyword itself and also calculate the PORV keyword and write
|
|
that.
|
|
*/
|
|
|
|
void ecl_init_file_fwrite_header( fortio_type * fortio , const ecl_grid_type * ecl_grid , const ecl_kw_type * poro , ert_ecl_unit_enum unit_system, int phases , time_t start_date) {
|
|
int simulator = INTEHEAD_ECLIPSE100_VALUE;
|
|
{
|
|
ecl_kw_type * intehead_kw = ecl_init_file_alloc_INTEHEAD( ecl_grid , unit_system , phases , start_date , simulator );
|
|
ecl_kw_fwrite( intehead_kw , fortio );
|
|
ecl_kw_free( intehead_kw );
|
|
}
|
|
|
|
{
|
|
ecl_kw_type * logihead_kw = ecl_init_file_alloc_LOGIHEAD( simulator );
|
|
ecl_kw_fwrite( logihead_kw , fortio );
|
|
ecl_kw_free( logihead_kw );
|
|
}
|
|
|
|
{
|
|
ecl_kw_type * doubhead_kw = ecl_init_file_alloc_DOUBHEAD( );
|
|
ecl_kw_fwrite( doubhead_kw , fortio );
|
|
ecl_kw_free( doubhead_kw );
|
|
}
|
|
|
|
if (poro) {
|
|
int poro_size = ecl_kw_get_size( poro );
|
|
if ((poro_size == ecl_grid_get_nactive( ecl_grid )) || (poro_size == ecl_grid_get_global_size(ecl_grid)))
|
|
ecl_init_file_fwrite_poro( fortio , ecl_grid , poro );
|
|
else
|
|
util_abort("%s: keyword PORO has wrong size:%d Grid: %d/%d \n",__func__ , ecl_kw_get_size( poro ) , ecl_grid_get_nactive( ecl_grid ) , ecl_grid_get_global_size( ecl_grid ));
|
|
}
|
|
}
|