mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
349 lines
12 KiB
C++
349 lines
12 KiB
C++
/*
|
|
Copyright (c) 2012 equinor asa, norway.
|
|
|
|
The file 'ecl_coarse_cell.c' is part of ert - ensemble based reservoir tool.
|
|
|
|
ERT is free software: you can redistribute it and/or modify
|
|
it under the terms of the gnu general public license as published by
|
|
the free software foundation, either version 3 of the license, or
|
|
(at your option) any later version.
|
|
|
|
ERT is distributed in the hope that it will be useful, but without any
|
|
warranty; without even the implied warranty of merchantability or
|
|
fitness for a particular purpose.
|
|
|
|
See the gnu general public license at <http://www.gnu.org/licenses/gpl.html>
|
|
for more details.
|
|
*/
|
|
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <ert/util/util.h>
|
|
#include <ert/util/type_macros.hpp>
|
|
#include <ert/util/int_vector.hpp>
|
|
|
|
#include <ert/ecl/ecl_kw_magic.hpp>
|
|
#include <ert/ecl/ecl_coarse_cell.hpp>
|
|
|
|
/******************************************************************/
|
|
/*
|
|
|
|
+---------+---------+---------+---------+---------+---------+
|
|
| 24 | 25 | 26 | 27 | 28 | 29 |
|
|
| [X] | [X] | [X] | [X] | | |
|
|
| | | | | | |
|
|
+---------+=========+=========+=========+=========+---------+
|
|
| 18 | 19 . 20 . 21 . 22 | 23 |
|
|
| [X] | . . [C] . | | j
|
|
| | . . . | | /|\
|
|
+---------+. . . . ... . . . ... . . . ... . . . .+---------+ |
|
|
| 12 | 13 . 14 . 15 . 16 | 17 | |
|
|
| [X] | [A] . . [B] . | [X] | |
|
|
| | . . . | | |
|
|
+---------+. . . . ... . . . ... . . . ... . . . .+---------+ +---------> i
|
|
| 6 | 7 . 8 . 9 . 10 | 11 |
|
|
| | . . . | |
|
|
| | . . . | |
|
|
+---------+=========+=========+=========+=========+---------+
|
|
| 0 | 1 | 2 | 3 | 4 | 5 |
|
|
| | [X] | [X] | [X] | | |
|
|
| | | | | | |
|
|
+---------+---------+---------+---------+---------+---------+
|
|
|
|
|
|
- A global grid of nx = 6, ny = 5 cells. The running number inside
|
|
the cells represents the cells global index.
|
|
|
|
- The grid contains a coarse cell of dimensions 4 x 3, the coarse
|
|
cell is in the global region: i \in [1,4] and j \in [1,3].
|
|
|
|
- When solving the dynamical equations the properties of the coarse
|
|
cell will enter as one entity, but when defining the grid initially
|
|
one can in prinsiple have more than one active cell. The example
|
|
above shows that the coarse region has three active cells, marked
|
|
with [A], [B] and [C] respectively.
|
|
|
|
- In the global grid the cells marked with [X] are active, i.e. when
|
|
counting from zero the coarse cell will be the fourth active
|
|
cell. This particular grid has a total of ten normal active cells
|
|
(i.e. 10 x [X]) and one coarse cell which is active.
|
|
|
|
|
|
- The dynamic variables like PRESSURE and SWAT are only represented
|
|
with one element for the entire coarse cell. Static properties like
|
|
PERMX and PORO are typically defined for all the cells in the
|
|
entire grid, the different active cells in the coarse cell are
|
|
stored in the active_cells vector, and when we just want one
|
|
representative property from the the coarse cell the first (often
|
|
only ...) element in this vector is used.
|
|
|
|
----
|
|
|
|
|
|
- When we introduce coarse cells the mapping between global cell
|
|
indices and active cell indices is not unique any longer. In the
|
|
current grid active_index == 3 will point to the coarse cell, and
|
|
all the cells in the coarse region will:
|
|
|
|
- ecl_grid_cell_active1( grid , global_index) => True
|
|
- ecl_grid_get_active_index1( grid , global_index) => 3
|
|
|
|
|
|
|
|
For the example above the ecl_coarse_cell datastructure would have the
|
|
following content:
|
|
|
|
ijk = {0 , 5 , 0 , 4 , k1 , k2 }
|
|
active_index = 3
|
|
cell_list = {7,8,9,10,13,14,15,16,19,20,21,22}
|
|
active_cells = {13,15,21}
|
|
active_values = {1,1,1} <= This can 2/3 for dual porosity.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define ECL_COARSE_CELL_TYPE_ID 91554106
|
|
|
|
struct ecl_coarse_cell_struct {
|
|
UTIL_TYPE_ID_DECLARATION;
|
|
int ijk[6]; // {i1, i2 , j1 , j2 , k1 , k2}
|
|
int active_index;
|
|
int active_fracture_index;
|
|
|
|
bool __cell_list_sorted;
|
|
int_vector_type * cell_list;
|
|
int_vector_type * active_cells;
|
|
int_vector_type * active_values;
|
|
};
|
|
|
|
|
|
|
|
|
|
static UTIL_SAFE_CAST_FUNCTION( ecl_coarse_cell , ECL_COARSE_CELL_TYPE_ID )
|
|
|
|
void ecl_coarse_cell_assert( ecl_coarse_cell_type * coarse_cell ) {
|
|
int box_size =
|
|
(1 + coarse_cell->ijk[1] - coarse_cell->ijk[0]) *
|
|
(1 + coarse_cell->ijk[2] - coarse_cell->ijk[3]) *
|
|
(1 + coarse_cell->ijk[4] - coarse_cell->ijk[5]);
|
|
|
|
if (box_size != int_vector_size( coarse_cell->cell_list ))
|
|
util_abort("%s: using invalid coarse cell. Box size:%d cells. cell_list:%d cells \n",__func__ , box_size , int_vector_size( coarse_cell->cell_list ));
|
|
}
|
|
|
|
|
|
|
|
|
|
ecl_coarse_cell_type * ecl_coarse_cell_alloc() {
|
|
const int LARGE = 1 << 30;
|
|
ecl_coarse_cell_type * coarse_cell = (ecl_coarse_cell_type *) util_malloc( sizeof * coarse_cell );
|
|
UTIL_TYPE_ID_INIT( coarse_cell , ECL_COARSE_CELL_TYPE_ID );
|
|
|
|
coarse_cell->ijk[0] = LARGE;
|
|
coarse_cell->ijk[2] = LARGE;
|
|
coarse_cell->ijk[4] = LARGE;
|
|
|
|
coarse_cell->ijk[1] = -LARGE;
|
|
coarse_cell->ijk[3] = -LARGE;
|
|
coarse_cell->ijk[5] = -LARGE;
|
|
|
|
coarse_cell->active_index = -1;
|
|
coarse_cell->active_fracture_index = -1;
|
|
coarse_cell->__cell_list_sorted = false;
|
|
coarse_cell->cell_list = int_vector_alloc(0,0);
|
|
coarse_cell->active_cells = int_vector_alloc(0,0);
|
|
coarse_cell->active_values = int_vector_alloc(0,0);
|
|
return coarse_cell;
|
|
}
|
|
|
|
|
|
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.
|
|
*/
|
|
|
|
void ecl_coarse_cell_update( ecl_coarse_cell_type * coarse_cell , int i , int j , int k , int global_index ) {
|
|
coarse_cell->ijk[0] = util_int_min( coarse_cell->ijk[0] , i );
|
|
coarse_cell->ijk[2] = util_int_min( coarse_cell->ijk[2] , j );
|
|
coarse_cell->ijk[4] = util_int_min( coarse_cell->ijk[4] , k );
|
|
|
|
coarse_cell->ijk[1] = util_int_max( coarse_cell->ijk[1] , i );
|
|
coarse_cell->ijk[3] = util_int_max( coarse_cell->ijk[3] , j );
|
|
coarse_cell->ijk[5] = util_int_max( coarse_cell->ijk[5] , k );
|
|
|
|
int_vector_append( coarse_cell->cell_list , global_index );
|
|
}
|
|
|
|
|
|
void ecl_coarse_cell_free( ecl_coarse_cell_type * coarse_cell ) {
|
|
int_vector_free( coarse_cell->cell_list );
|
|
int_vector_free( coarse_cell->active_cells );
|
|
int_vector_free( coarse_cell->active_values );
|
|
free( coarse_cell );
|
|
}
|
|
|
|
|
|
void ecl_coarse_cell_free__( void * arg ) {
|
|
ecl_coarse_cell_type * coarse_cell = ecl_coarse_cell_safe_cast( arg );
|
|
ecl_coarse_cell_free( coarse_cell );
|
|
}
|
|
|
|
|
|
/*****************************************************************/
|
|
|
|
static void ecl_coarse_cell_sort( ecl_coarse_cell_type * coarse_cell ) {
|
|
if (!coarse_cell->__cell_list_sorted) {
|
|
int_vector_sort( coarse_cell->cell_list );
|
|
coarse_cell->__cell_list_sorted = true;
|
|
}
|
|
}
|
|
|
|
int ecl_coarse_cell_get_size( const ecl_coarse_cell_type * coarse_cell) {
|
|
return int_vector_size( coarse_cell->cell_list );
|
|
}
|
|
|
|
|
|
int ecl_coarse_cell_iget_cell_index( ecl_coarse_cell_type * coarse_cell , int group_index) {
|
|
ecl_coarse_cell_sort( coarse_cell );
|
|
return int_vector_iget( coarse_cell->cell_list , group_index );
|
|
}
|
|
|
|
const int * ecl_coarse_cell_get_index_ptr( ecl_coarse_cell_type * coarse_cell ) {
|
|
ecl_coarse_cell_sort( coarse_cell );
|
|
return int_vector_get_const_ptr( coarse_cell->cell_list );
|
|
}
|
|
|
|
|
|
const int_vector_type * ecl_coarse_cell_get_index_vector( ecl_coarse_cell_type * coarse_cell ) {
|
|
ecl_coarse_cell_sort( coarse_cell );
|
|
return coarse_cell->cell_list;
|
|
}
|
|
|
|
/*****************************************************************/
|
|
|
|
|
|
int ecl_coarse_cell_get_i1( const ecl_coarse_cell_type * coarse_cell ) {
|
|
return coarse_cell->ijk[0];
|
|
}
|
|
|
|
int ecl_coarse_cell_get_i2( const ecl_coarse_cell_type * coarse_cell ) {
|
|
return coarse_cell->ijk[1];
|
|
}
|
|
|
|
int ecl_coarse_cell_get_j1( const ecl_coarse_cell_type * coarse_cell ) {
|
|
return coarse_cell->ijk[2];
|
|
}
|
|
|
|
int ecl_coarse_cell_get_j2( const ecl_coarse_cell_type * coarse_cell ) {
|
|
return coarse_cell->ijk[3];
|
|
}
|
|
|
|
int ecl_coarse_cell_get_k1( const ecl_coarse_cell_type * coarse_cell ) {
|
|
return coarse_cell->ijk[4];
|
|
}
|
|
|
|
int ecl_coarse_cell_get_k2( const ecl_coarse_cell_type * coarse_cell ) {
|
|
return coarse_cell->ijk[5];
|
|
}
|
|
|
|
const int * ecl_coarse_cell_get_box_ptr( const ecl_coarse_cell_type * coarse_cell ) {
|
|
return coarse_cell->ijk;
|
|
}
|
|
|
|
|
|
/*****************************************************************/
|
|
|
|
void ecl_coarse_cell_update_index( ecl_coarse_cell_type * coarse_cell , int global_index , int * active_index , int * active_fracture_index , int active_value) {
|
|
if (active_value & CELL_ACTIVE_MATRIX) {
|
|
coarse_cell->active_index = *active_index;
|
|
(*active_index) += 1;
|
|
}
|
|
|
|
if (active_value & CELL_ACTIVE_FRACTURE) {
|
|
coarse_cell->active_fracture_index = *active_fracture_index;
|
|
(*active_fracture_index) += 1;
|
|
}
|
|
|
|
int_vector_append( coarse_cell->active_cells , global_index );
|
|
int_vector_append( coarse_cell->active_values , active_value );
|
|
|
|
if (int_vector_size( coarse_cell->active_values ) > 1) {
|
|
if (int_vector_reverse_iget( coarse_cell->active_values , -2 ) != active_value)
|
|
util_abort("%s: Sorry - current coarse cell implementation requires that all active cells have the same active value\n",__func__);
|
|
}
|
|
}
|
|
|
|
|
|
int ecl_coarse_cell_get_active_index( const ecl_coarse_cell_type * coarse_cell ) {
|
|
return coarse_cell->active_index;
|
|
}
|
|
|
|
int ecl_coarse_cell_get_active_fracture_index( const ecl_coarse_cell_type * coarse_cell ) {
|
|
return coarse_cell->active_fracture_index;
|
|
}
|
|
|
|
|
|
/**
|
|
Will return the global index of the 'ith active cell in the coarse
|
|
cell.
|
|
*/
|
|
int ecl_coarse_cell_iget_active_cell_index( const ecl_coarse_cell_type * coarse_cell , int index) {
|
|
return int_vector_iget( coarse_cell->active_cells , index );
|
|
}
|
|
|
|
int ecl_coarse_cell_iget_active_value( const ecl_coarse_cell_type * coarse_cell , int index) {
|
|
return int_vector_iget( coarse_cell->active_values , index );
|
|
}
|
|
|
|
int ecl_coarse_cell_get_num_active( const ecl_coarse_cell_type * coarse_cell) {
|
|
return int_vector_size( coarse_cell->active_cells );
|
|
}
|
|
|
|
|
|
/*****************************************************************/
|
|
|
|
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 ");
|
|
}
|