mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
* Rename to resdata * Remove development feature for storing grid import type in project file * Clean up comments
810 lines
23 KiB
C++
810 lines
23 KiB
C++
/*
|
|
Copyright (C) 2014 Equinor 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 <math.h>
|
|
|
|
#include <vector>
|
|
|
|
#include <ert/util/type_macros.hpp>
|
|
#include <ert/util/int_vector.hpp>
|
|
|
|
#include <ert/ecl/layer.hpp>
|
|
|
|
#define LAYER_TYPE_ID 55185409
|
|
|
|
|
|
|
|
typedef struct {
|
|
int cell_value;
|
|
int edges[4];
|
|
bool bottom_barrier;
|
|
bool left_barrier;
|
|
bool active;
|
|
} 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 = (layer_type*)util_malloc( sizeof * layer );
|
|
UTIL_TYPE_ID_INIT( layer , LAYER_TYPE_ID );
|
|
layer->nx = nx;
|
|
layer->ny = ny;
|
|
layer->cell_sum = 0;
|
|
{
|
|
int data_size = (layer->nx + 1)* (layer->ny + 1);
|
|
layer->data = (cell_type*)util_malloc( data_size * sizeof * layer->data );
|
|
{
|
|
int g;
|
|
for (g=0; g < data_size; 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;
|
|
|
|
cell->active = true;
|
|
cell->bottom_barrier = false;
|
|
cell->left_barrier = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
static cell_type* layer_iget_cell( const layer_type * layer , int i , int j) {
|
|
int g = layer_get_global_cell_index( layer , i , j );
|
|
return &layer->data[g];
|
|
}
|
|
|
|
/*
|
|
To be able to update barriers on the edge we need access to the i =
|
|
nx and j = ny cells.
|
|
*/
|
|
static cell_type* layer_iget_cell__( const layer_type * layer , int i , int j) {
|
|
int g = layer_get_global_cell_index__( layer , i , j );
|
|
return &layer->data[g];
|
|
}
|
|
|
|
|
|
bool layer_iget_left_barrier( const layer_type * layer, int i , int j) {
|
|
cell_type * cell = layer_iget_cell(layer , i,j);
|
|
return cell->left_barrier;
|
|
}
|
|
|
|
|
|
bool layer_iget_bottom_barrier( const layer_type * layer, int i , int j) {
|
|
cell_type * cell = layer_iget_cell(layer,i,j);
|
|
return cell->bottom_barrier;
|
|
}
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
bool layer_iget_active( const layer_type * layer, int i , int j) {
|
|
int g = layer_get_global_cell_index( layer , i , j );
|
|
return layer->data[g].active;
|
|
}
|
|
|
|
|
|
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 ,
|
|
std::vector<int_point2d_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( ¤t_point , 1 , 0 );
|
|
point_shift( &next_point , 1 , 1 );
|
|
} else if (dir == TOP_EDGE) {
|
|
point_shift( ¤t_point , 1 , 1 );
|
|
point_shift( &next_point , 0 , 1 );
|
|
} else if (dir == LEFT_EDGE)
|
|
point_shift( ¤t_point , 0 , 1 );
|
|
|
|
corner_list.push_back(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 , std::vector<int_point2d_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;
|
|
corner_list.clear();
|
|
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: 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 = (bool*)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;
|
|
}
|
|
|
|
|
|
static void layer_assert_cell_index( const layer_type * layer , int i , int j ) {
|
|
if ((i < 0) || (j < 0))
|
|
util_abort("%s: invalid value for i,j i:%d [0,%d) j:%d [0,%d) \n",__func__ , i , layer->nx , j , layer->ny);
|
|
|
|
if ((i >= layer->nx) || (j >= layer->ny))
|
|
util_abort("%s: invalid value for i,j i:%d [0,%d) j:%d [0,%d) \n",__func__ , i , layer->nx , j , layer->ny);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool layer_cell_contact( const layer_type * layer , int i1 , int j1 , int i2 , int j2) {
|
|
layer_assert_cell_index( layer , i1 , j1 );
|
|
layer_assert_cell_index( layer , i2 , j2 );
|
|
{
|
|
|
|
if ((abs(i1 - i2) == 1) && (j1 == j2)) {
|
|
int i = util_int_max( i1,i2 );
|
|
const cell_type * cell = layer_iget_cell( layer , i , j1 );
|
|
return !cell->left_barrier;
|
|
}
|
|
|
|
if ((i1 == i2) && (abs(j1 - j2) == 1)) {
|
|
int j = util_int_max( j1 , j2 );
|
|
const cell_type * cell = layer_iget_cell( layer , i1 , j );
|
|
return !cell->bottom_barrier;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
void layer_add_ijbarrier( layer_type * layer , int i1 , int j1 , int i2 , int j2 ) {
|
|
if ((j1 == j2) || (i1 == i2)) {
|
|
if (i1 == i2) {
|
|
int j;
|
|
int jmin = util_int_min(j1,j2);
|
|
int jmax = util_int_max(j1,j2);
|
|
|
|
for (j=jmin; j < jmax; j++) {
|
|
cell_type * cell = layer_iget_cell__( layer , i1 , j );
|
|
cell->left_barrier = true;
|
|
}
|
|
} else {
|
|
int i;
|
|
int imin = util_int_min(i1,i2);
|
|
int imax = util_int_max(i1,i2);
|
|
|
|
for (i=imin; i < imax; i++) {
|
|
cell_type * cell = layer_iget_cell__( layer , i , j1 );
|
|
cell->bottom_barrier = true;
|
|
}
|
|
}
|
|
} else
|
|
util_abort("%s: fatal error must have i1 == i2 || j1 == j2 \n",__func__);
|
|
|
|
}
|
|
|
|
|
|
|
|
void layer_add_barrier( layer_type * layer , int c1 , int c2) {
|
|
int dimx = layer->nx + 1;
|
|
int j1 = c1 / dimx;
|
|
int i1 = c1 % dimx;
|
|
|
|
int j2 = c2 / dimx;
|
|
int i2 = c2 % dimx;
|
|
|
|
layer_add_ijbarrier( layer , i1 , j1 , i2 , j2 );
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
Line is parameterized as: ax + by + c = 0
|
|
*/
|
|
static double distance_to_line(double a , double b , double c , int i , int j) {
|
|
double x0 = 1.0 * i;
|
|
double y0 = 1.0 * j;
|
|
|
|
|
|
return fabs(a*x0 + b*y0 + c) / sqrt(a*a + b*b);
|
|
}
|
|
|
|
|
|
|
|
|
|
void layer_add_interp_barrier( layer_type * layer , int c1 , int c2) {
|
|
int dimx = layer->nx + 1;
|
|
int j1 = c1 / dimx;
|
|
int i1 = c1 % dimx;
|
|
|
|
int j2 = c2 / dimx;
|
|
int i2 = c2 % dimx;
|
|
|
|
if ((j1 == j2) || (i1 == i2))
|
|
layer_add_barrier( layer , c1 , c2 );
|
|
else {
|
|
int di = abs(i2 - i1) / (i2 - i1);
|
|
int dj = abs(j2 - j1) / (j2 - j1);
|
|
double a = 1.0 * (j2 - j1) / (i2 - i1);
|
|
double b = 1.0 * (j1 - a*i1);
|
|
|
|
int i = i1;
|
|
int j = j1;
|
|
int c = c1;
|
|
|
|
while (c != c2) {
|
|
double dx = distance_to_line( a , -1 , b , i + di , j );
|
|
double dy = distance_to_line( a , -1 , b , i , j + dj);
|
|
|
|
if (dx <= dy)
|
|
i += di;
|
|
else
|
|
j += dj;
|
|
|
|
layer_add_barrier( layer , c , i + j*dimx);
|
|
c = i + j*dimx;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void layer_memcpy(layer_type * target_layer , const layer_type * src_layer) {
|
|
if ((target_layer->nx == src_layer->nx) && (target_layer->ny == src_layer->ny)) {
|
|
size_t data_size = target_layer->nx * target_layer->ny * sizeof(cell_type);
|
|
memcpy(target_layer->data , src_layer->data , data_size );
|
|
target_layer->cell_sum = src_layer->cell_sum;
|
|
} else
|
|
util_abort("%s: fatal error - tried to copy elements between layers of different size\n",__func__);
|
|
}
|
|
|
|
|
|
static void layer_assign__( layer_type * layer, int value) {
|
|
int i,j;
|
|
for (j=0; j < layer->ny; j++) {
|
|
for (i=0; i < layer->nx; i++) {
|
|
cell_type * cell = layer_iget_cell( layer , i , j );
|
|
cell->cell_value = value;
|
|
{
|
|
int e;
|
|
for (e=0; e < 4; e++)
|
|
cell->edges[e] = 0;
|
|
}
|
|
}
|
|
}
|
|
layer->cell_sum = value * layer->nx*layer->ny;
|
|
}
|
|
|
|
void layer_clear_cells( layer_type * layer) {
|
|
layer_assign__(layer , 0 );
|
|
}
|
|
|
|
void layer_assign( layer_type * layer, int value) {
|
|
layer_assign__( layer , value );
|
|
}
|
|
|
|
|
|
|
|
void layer_update_connected_cells( layer_type * layer , int i , int j , int org_value , int new_value) {
|
|
if (org_value != new_value) {
|
|
if (layer_iget_cell_value( layer , i , j ) == org_value) {
|
|
layer_iset_cell_value( layer , i , j , new_value);
|
|
|
|
if (i < (layer->nx - 1) && layer_cell_contact( layer , i,j,i+1,j))
|
|
layer_update_connected_cells( layer , i + 1 , j , org_value , new_value);
|
|
|
|
if (i > 0 && layer_cell_contact( layer , i,j,i-1,j))
|
|
layer_update_connected_cells( layer , i - 1 , j , org_value , new_value);
|
|
|
|
if (j < (layer->ny - 1) && layer_cell_contact( layer , i,j,i,j+1))
|
|
layer_update_connected_cells( layer , i , j + 1, org_value , new_value);
|
|
|
|
if (j > 0 && layer_cell_contact( layer , i,j,i,j-1))
|
|
layer_update_connected_cells( layer , i , j - 1, org_value , new_value);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void layer_cells_equal( const layer_type * layer , int value , int_vector_type * i_list , int_vector_type * j_list) {
|
|
int i,j;
|
|
for (j=0; j < layer->ny; j++) {
|
|
for (i=0; i < layer->nx; i++) {
|
|
cell_type * cell = layer_iget_cell( layer , i , j );
|
|
if (cell->cell_value == value) {
|
|
int_vector_append( i_list , i );
|
|
int_vector_append( j_list , j );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
int layer_count_equal( const layer_type * layer , int value ) {
|
|
int num_equal = 0;
|
|
int i,j;
|
|
for (j=0; j < layer->ny; j++) {
|
|
for (i=0; i < layer->nx; i++) {
|
|
cell_type * cell = layer_iget_cell( layer , i , j );
|
|
if (cell->cell_value == value)
|
|
num_equal++;
|
|
}
|
|
}
|
|
return num_equal;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void layer_update_active( layer_type * layer , const ecl_grid_type * grid , int k) {
|
|
int i,j;
|
|
for (j=0; j< ecl_grid_get_ny( grid ); j++) {
|
|
for (i=0; i < ecl_grid_get_nx( grid ); i++) {
|
|
cell_type * cell = layer_iget_cell( layer , i , j );
|
|
cell->active = ecl_grid_cell_active3( grid , i , j , k );
|
|
}
|
|
}
|
|
}
|