Many changes. I cannot remember them all.

This commit is contained in:
Jostein R. Natvig
2009-06-12 12:40:38 +00:00
parent 0b9709cf27
commit 201a31a9bc
9 changed files with 320 additions and 137 deletions

View File

@@ -2,6 +2,7 @@
#include <math.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include "sparsetable.h"
#include "facetopology.h"

1
make.m Normal file
View File

@@ -0,0 +1 @@
mex processgrid.c uniquepoints.c facetopology.c sparsetable.c mxgrdecl.c CFLAGS='$CFLAGS -Wall -fPIC'

View File

@@ -13,15 +13,15 @@
/*-------------------------------------------------------*/
void mxInitGrdecl(struct Grdecl *g, const mxArray *prhs[])
{
int i,j,k;
int i,j,k,n;
g->coord = mxGetPr(mxGetField(prhs[0], 0, "COORD"));
double *tmp = mxGetPr(mxGetField(prhs[0], 0, "cartDims"));
g->n = 1;
n = 1;
for (i=0; i<3; ++i){
g->dims[i] = tmp[i];
g->n *= tmp[i];
n *= tmp[i];
}
mexPrintf("dimensions: %d %d %d\n",
g->dims[0],
@@ -32,21 +32,22 @@ void mxInitGrdecl(struct Grdecl *g, const mxArray *prhs[])
/* grdecl.actnum = permute(actnum, [3,1,2]); */
int *actnum = mxGetData(mxGetField(prhs[0], 0, "ACTNUM"));
g->actnum = malloc(g->n* sizeof(*g->actnum));
int *iptr = g->actnum;
int *a = malloc(n* sizeof(*g->actnum));
int *iptr = a;
for (j=0; j<g->dims[1]; ++j){
for (i=0; i<g->dims[0]; ++i){
for (k=0; k<g->dims[2]; ++k){
*iptr++ = actnum[i+g->dims[0]*(j+g->dims[1]*k)];
}
}
}
g->actnum = a;
/* grdecl.zcorn = permute(zcorn, [3,1,2]); */
double *zcorn = mxGetPr(mxGetField(prhs[0], 0, "ZCORN"));
g->zcorn = malloc(g->n*8*sizeof(*g->zcorn));
double *dptr = g->zcorn;
double *z = malloc(n*8*sizeof(*g->zcorn));
double *dptr = z;
for (j=0; j<2*g->dims[1]; ++j){
for (i=0; i<2*g->dims[0]; ++i){
for (k=0; k<2*g->dims[2]; ++k){
@@ -54,6 +55,7 @@ void mxInitGrdecl(struct Grdecl *g, const mxArray *prhs[])
}
}
}
g->zcorn = z;
}
@@ -62,7 +64,7 @@ void mxInitGrdecl(struct Grdecl *g, const mxArray *prhs[])
/*-------------------------------------------------------*/
void freeGrdecl(struct Grdecl *g)
{
free(g->zcorn); g->zcorn = NULL;
free(g->actnum); g->actnum = NULL;
free((double*)g->zcorn); g->zcorn = NULL;
free((double*)g->actnum); g->actnum = NULL;
}

View File

@@ -8,7 +8,6 @@
#include "grdecl.h"
#include "uniquepoints.h"
#include "mxgrdecl.h"
#include "matalloc.h"
#include "facetopology.h"
/* No checking of input arguments in this code! */
@@ -41,134 +40,297 @@ static void igetvectors(int dims[3], int i, int j, int *field, int *v[])
}
struct processed_grid{
int numfaces;
int *facenodes;
int *faceptr;
int *neighbors;
double *nodes;
int *cellindex;
};
void free_processed_grid(struct processed_grid *g)
{
if( g ){
free((g)->facenodes);
free((g)->faceptr);
free((g)->neighbors);
/* if (*g->nodes) free(*g->nodes); */
/* if (*g->cellindex) free(*g->cellindex); */
}
}
void processGrdecl(const struct Grdecl *g, double tol, struct processed_grid *out);
/* Gateway routine for Matlab mex function. */
/*-------------------------------------------------------*/
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
int i,j;
/* Set up data passed from Matlab */
struct Grdecl g;
mxInitGrdecl(&g, prhs);
struct processed_grid out;
mxInitGrdecl(&g, prhs);
processGrdecl(&g, 0.0, &out);
/* Free whatever was allocated in initGrdecl. */
freeGrdecl(&g);
free_processed_grid(&out);
}
/*-------------------------------------------------------*/
void compute_cell_index(const int dims[3], int i, int j, int *neighbors, int len)
{
int k;
if (i<0 || i>=dims[0] || j<0 || j >= dims[1]){
for(k=0; k<len; k+=2){
neighbors[k] = -1;
}
}else{
for(k=0; k<len; k+=2){
if (neighbors[k] != -1){
neighbors[k] = i + dims[0]*(j + dims[1]*neighbors[k]);
}
}
}
}
/* Ensure there's sufficient memory */
int checkmemeory(int nz, sparse_table_t *ftab, int **neighbors, int **intersections)
{
/* Ensure there is enough space */
int r = (2*nz+2)*(2*nz+2);
int m = ftab->m;
int n = ftab->n;
if(ftab->position + r> m){
m += max(m*0.5, 2*r);
}
if (ftab->ptr[ftab->position] + 6*r > n){
n += max(n*0.5, 12*r);
}
if (m != ftab->m){
fprintf(stderr, "m= %d, n = %d\n", m, n);
void *p1 = realloc(*neighbors, 2*m * sizeof(**neighbors));
void *p2 = realloc(*intersections, 4*m * sizeof(**neighbors));
if (p1 && p2){
*neighbors = p1;
*intersections = p2;
}else{
return 0;
}
}
if (m != ftab->m || n != ftab->n){
fprintf(stderr, "m= %d, n = %d\n", m, n);
void *p = realloc_sparse_table(ftab, m, n, sizeof(int));
if (p){
ftab = p;
}else{
return 0;
}
}
return 1;
}
void process_vertical_faces(const int dims[3], int direction, sparse_table_t *ftab,
int **neighbors, int **intersections, int *npoints,
int npillarpoints, int *plist, int *work)
{
/* direction == 0 : constant i-faces
direction == 1 : constant j-faces */
int i,j;
int *cornerpts[4];
/* constant i-faces */
for (j=0; j<dims[1]+direction; ++j) {
for (i=0; i<dims[0]+1-direction; ++i){
if (!checkmemeory(dims[2], ftab, neighbors, intersections)){
fprintf(stderr, "Could not allocat enough space\n");
exit(1);
}
int startface = ftab->position;
int num_intersections = *npoints - npillarpoints;
/* Vectors of point numbers */
int d[] = {2*dims[0], 2*dims[1], 2+2*dims[2]};
igetvectors(d, 2*i+direction, 2*j+1-direction, plist, cornerpts);
if(direction==1){
/* swap */
int *tmp = cornerpts[2];
cornerpts[2] = cornerpts[1];
cornerpts[1] = tmp;
}
findconnections(2*dims[2]+2, cornerpts, npoints,
*intersections+4*num_intersections,
*neighbors, work, ftab);
int *ptr = *neighbors + 2*startface;
int len = 2*ftab->position - 2*startface;
compute_cell_index(dims, i-1+direction, j-direction, ptr, len);
compute_cell_index(dims, i, j, ptr+1, len);
}
}
}
/* Gateway routine. */
/*-------------------------------*/
void processGrdecl(const struct Grdecl *g, double tol, struct processed_grid *out)
{
int i,k;
/* Code below assumes k index runs fastests, ie. that dimensions of
table is permuted to (dims[2], dims[0], dims[1]) */
/* ---------------------------------------------------------------*/
int nx = g->dims[0];
int ny = g->dims[1];
int nz = g->dims[2];
/* Set up space for return values */
/* Unstructured storage of unique zcorn values for each pillar. */
/* ztab->data may need extra space temporarily due to simple boundary treatement */
int sz = 8*(g.dims[0]+1)*(g.dims[1]+1)*g.dims[2]; /* Big for convenient bc */
int numpillars = (g.dims[0]+1)*(g.dims[1]+1);
sparse_table_t *ztab = malloc_sparse_table(numpillars, sz, sizeof(double));
int *plist = malloc( 2*g.dims[0]*2*g.dims[1]*(2*g.dims[2]+2)*sizeof(int));
int npillarpoints = 8*(nx+1)*(ny+1)*nz;
int npillars = (nx+1)*(ny+1);
sparse_table_t *ztab = malloc_sparse_table(npillars,
npillarpoints,
sizeof(double));
/* Allocate space for cornerpoint numbers plus INT_MIN (INT_MAX) padding */
int *plist = malloc( 4*nx*ny*(2*nz+2) * sizeof(int));
finduniquepoints(&g, plist, ztab);
/* Fill plist of cornerpoint numbers and ztab of unique zcorn values. */
finduniquepoints(g, plist, ztab);
npillarpoints = ztab->ptr[npillars];
ztab = realloc_sparse_table (ztab, npillars, npillarpoints, sizeof(double));
/*======================================================*/
fprintf(stderr, "process face geomtery\n");
/* Process face geometry and cell-face topology */
/* internal constant i pillar pairs */
int n = 2 + 2*g.dims[2];
int k;
/* Process face geometry and cell-face topology on constant-i pillar pairs */
const int BIGNUM = 100;
const int BIGNUM = 1024;
/* Unstructured storage of face nodes */
sparse_table_t *ftab = malloc_sparse_table(BIGNUM*sz*sizeof(int),
BIGNUM*sz*sizeof(int),
sparse_table_t *ftab = malloc_sparse_table(BIGNUM/3,
BIGNUM,
sizeof(int));
int *pts[4];
int *neighbors = malloc(2* n*n* sizeof(*neighbors));
int *intersections = malloc(4* n*n* sizeof(*intersections));
int *neighbors = malloc(BIGNUM* sizeof(*neighbors));
int *intersections = malloc(BIGNUM* sizeof(*intersections));
int *work = calloc(2* n, sizeof(*work));
int d[3] = {2*g.dims[0], 2*g.dims[1], 2+2*g.dims[2]};
int *work = calloc(2* (2*nz+2), sizeof(*work));
int npoints = npillarpoints;
ftab->position = 0;
ftab->ptr[0] = 0;
int startface;
int numpts = ztab->ptr[numpillars];
int startpts = numpts;
int isodd;
ftab->ptr[0]=0;
process_vertical_faces(g->dims, 0, ftab,
&neighbors, &intersections, &npoints,
npillarpoints, plist, work);
process_vertical_faces(g->dims, 1, ftab,
&neighbors, &intersections, &npoints,
npillarpoints, plist, work);
for (j=0; j<g.dims[1]; ++j) {
/* ------------------ */
/* Add boundary faces */
/* ------------------ */
igetvectors(d, 0, 2*j+1, plist, pts);
startface = ftab->position;
findconnections(n, pts, &numpts, intersections, neighbors, work, ftab);
#if 0
int di = 0;
int dj = 1;
int *cornerpts[4];
/* constant i-faces */
for (j=0; j<g->dims[1]; ++j) {
for (i=0; i<g->dims[0]+1; ++i){
/* odd */
for(k=2*startface+1; k<2*ftab->position; k+=2){
if (neighbors[k] != -1){
neighbors[k] = g.dims[0]*(j + g.dims[1]*neighbors[k]);
if (!checkmemeory(nz, ftab, &neighbors, &intersections)){
fprintf(stderr, "Could not allocat enough space\n");
exit(1);
}
}
/* even */
for(k=2*startface; k<2*ftab->position; k+=2){
neighbors[k] = -1;
}
/* -------------- */
/* internal faces */
/* -------------- */
for (i=1; i<g.dims[0]; ++i){
int startface = ftab->position;
int num_intersections = npoints - npillarpoints;
/* Vectors of point numbers */
igetvectors(d, 2*i, 2*j+1, plist, pts);
startface = ftab->position;
findconnections(n, pts, &numpts, intersections, neighbors, work, ftab);
int d[] = {2*nx, 2*ny, 2+2*nz};
igetvectors(d, 2*i+di, 2*j+dj, plist, cornerpts);
findconnections(2*nz+2, cornerpts,
&npoints, intersections+4*num_intersections,
neighbors, work, ftab);
/* Compute cell numbers from cell k-index (stored in neighbors) */
/* For even k, neighbors[k] refers to stack (i-1,j),
for odd k, neighbors[k] refers to stack (i,j) of cells */
isodd = 1;
for(k=2*startface; k<2*ftab->position; ++k){
isodd = !isodd;
if (neighbors[k] != -1){
neighbors[k] = i-1+isodd + g.dims[0]*(j + g.dims[1]*neighbors[k]);
}
if(di==1){
/* swap */
int *tmp = cornerpts[2];
cornerpts[2] = cornerpts[1];
cornerpts[1] = tmp;
}
/* compute intersections */
int *ptr = neighbors + 2*startface;
int len = 2*ftab->position - 2*startface;
compute_cell_index(g->dims, i-1+di, j-1+dj, ptr, len);
compute_cell_index(g->dims, i, j, ptr+1, len);
}
/* ------------------ */
/* Add boundary face */
/* ------------------ */
startface = ftab->position;
igetvectors(d, 2*g.dims[0], 2*j+1, plist, pts);
findconnections(n, pts, &numpts, intersections, neighbors, work, ftab);
/* even indices */
for(k=2*startface; k<2*ftab->position; k+=2){
if (neighbors[k] != -1){
neighbors[k] = g.dims[0]-1 + g.dims[0]*(j + g.dims[1]*neighbors[k]);
}
}
/* odd indices */
for(k=2*startface+1; k<2*ftab->position; k+=2){
neighbors[k] = -1;
}
}
/* constant j-faces */
for (i=0; i<g->dims[0]; ++i){
for (j=0; j<g->dims[1]+1; ++j) {
if (!checkmemeory(nz, ftab, &neighbors, &intersections)){
fprintf(stderr, "Could not allocat enough space\n");
exit(1);
}
int startface = ftab->position;
int num_intersections = npoints - npillarpoints;
/* Vectors of point numbers */
int d[] = {2*nx, 2*ny, 2+2*nz};
igetvectors(d, 2*i+1, 2*j, plist, cornerpts);
int *tmp[4] = {cornerpts[0],
cornerpts[2],
cornerpts[1],
cornerpts[3]};
findconnections(2*nz+2, tmp,
&npoints, intersections+4*num_intersections,
neighbors, work, ftab);
int *ptr = neighbors + 2*startface;
int len = 2*ftab->position - 2*startface;
compute_cell_index(g->dims, i, j-1, ptr, len);
compute_cell_index(g->dims, i, j, ptr+1, len);
}
}
#endif
free(work);
/* */
@@ -199,7 +361,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
fprintf(stderr, "\nline intersections:\n");
iptr = intersections;
int numintersections = numpts - startpts;
int numintersections = npoints - npillarpoints;
for(k=0; k<numintersections; ++k){
fprintf(stderr, " (%d %d %d %d)\n", iptr[0], iptr[1], iptr[2], iptr[3]);
iptr+=4;
@@ -207,30 +369,40 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
#endif
out->numfaces = ftab->position;
out->facenodes = ftab->data;
out->faceptr = ftab->ptr;
out->neighbors = neighbors;
/* compute constant-j faces*/
#if 0
int xstride = 2*g.dims[2];
int ystride = 4*g.dims[2]*g.dims[0];
int zstride = 1;
/* internal constant j pillar pairs */
for (i=0; i<g.dims[0]; ++i){
for (j=0; j<g.dims[1]-1; ++j){
int p1 = 2*i + ystride* (2*j+1);
int p2 = p1 + xstride;
process_pair(p1, p2, g.dims, g.zcorn, ystride, zstride);
}
}
#endif
/* compute constant-k faces */
/* compute node coordinates */
free_sparse_table(ztab);
free_sparse_table(ftab);
/* compute intersections */
free (intersections);
free (neighbors);
free (plist);
/* Free whatever was allocated in initGrdecl. */
freeGrdecl(&g);
/* compute local cell numbering */
free (plist);
/* free_sparse_table(ftab); */
/* free (neighbors); */
}
/* (*out)->facenodes = realloc(ftab->data, (*out)->numfaces * sizeof(int)); */
/* (*out)->faceptr = realloc(ftab->ptr, ((*out)->numfaces + 1) * sizeof(int)); */
/* (*out)->neighbors = realloc(neighbors, 2*ftab->position * sizeof(int)); */
/* (*out)->nodes = NULL;/\* realloc(nodes, 3*npoints * sizeof(double)); *\/ */
/* (*out)->cellindex = NULL; */

View File

@@ -20,7 +20,6 @@ sparse_table_t *malloc_sparse_table(int m, int n, int datasz)
tab->m = m;
tab->n = n;
tab->position = 0;
/* fprintf(stderr, "sizeof tab = %ld\n", sizeof (*tab->ptr)); */
if (!(tab->ptr = malloc((m+1) * sizeof (*tab->ptr)))){
fprintf(stderr, "Could not allocate space for sparse ptr\n");
free_sparse_table(tab);
@@ -41,18 +40,25 @@ sparse_table_t *realloc_sparse_table(sparse_table_t *tab, int m, int n, int data
{
tab->m = m;
tab->n = n;
if (!(tab->ptr = realloc(tab->ptr, (m+1) * sizeof (*tab->ptr)))){
void *p = realloc(tab->ptr, (m+1) * sizeof (*tab->ptr));
if (p){
tab->ptr = p;
}else{
fprintf(stderr, "Could not reallocate space for sparse ptr\n");
free_sparse_table(tab);
return NULL;
}
if(!(tab->data = realloc(tab->data, n * datasz))){
p = realloc(tab->data, n * datasz);
if(p){
tab->data = p;
}else{
fprintf(stderr, "Could not reallocate space for sparse data\n");
free_sparse_table(tab);
return NULL;
}
return tab;
}

View File

@@ -7,10 +7,10 @@
typedef struct{
int m; /* number of rows */
int *ptr; /* row pointer of size m+1 */
int position; /* position in ptr that is not filled. */
int position; /* first position in ptr that is not filled. */
int n; /* size of data */
void *data; /* sparse table data */
void *data; /* sparse table data */
} sparse_table_t;

2
test.m
View File

@@ -1,5 +1,5 @@
g=simpleGrdecl([2, 1, 4], @(x) -0.05+0.1*x+0.01 );
g=simpleGrdecl([4, 2, 4], @(x) -0.055+0.11*x+0.011 );
G=processGRDECL(g);
%clf,plotGrid(G);view(3);

View File

@@ -26,7 +26,7 @@ static int compare(const void *a, const void *b)
/* Creat sorted list of z-values in zcorn with actnum==1 */
/*-------------------------------------------------------*/
static int createSortedList(double *list, int n, int m,
double *z[], int *a[])
const double *z[], const int *a[])
{
fprintf(stderr, "\n");
int i,j;
@@ -70,10 +70,10 @@ static int uniquify(int n, double *list, double tolerance)
/* Along single pillar: */
static int* assignPointNumbers(int begin,
int end,
double *zlist,
const double *zlist,
int n,
double *zcorn,
int *actnum,
const double *zcorn,
const int *actnum,
int *plist,
double tolerance)
{
@@ -85,8 +85,8 @@ static int* assignPointNumbers(int begin,
/* All points should now be within tolerance of a listed point. */
double *z = zcorn;
int *a = actnum;
const double *z = zcorn;
const int *a = actnum;
int *p = plist;
k = begin;
@@ -118,7 +118,8 @@ static int* assignPointNumbers(int begin,
/*-------------------------------------------------------*/
static void igetvectors(int dims[3], int i, int j, int *field, int *v[])
static void igetvectors(const int dims[3], int i, int j,
const int *field, const int *v[])
{
int im = max(1, i ) - 1;
@@ -133,7 +134,7 @@ static void igetvectors(int dims[3], int i, int j, int *field, int *v[])
}
/*-------------------------------------------------------*/
static void dgetvectors(int dims[3], int i, int j, double *field, double *v[])
static void dgetvectors(const int dims[3], int i, int j, const double *field, const double *v[])
{
int im = max(1, i ) - 1;
@@ -151,7 +152,7 @@ static void dgetvectors(int dims[3], int i, int j, double *field, double *v[])
/* Assume that coordinate number is arranged in a */
/* sequence such that the natural index is (k,i,j) */
/*-------------------------------------------------------*/
void finduniquepoints(struct Grdecl *g,
void finduniquepoints(const struct Grdecl *g,
/* return values: */
int *plist, /* list of point numbers on each pillar*/
sparse_table_t *ztab)
@@ -175,8 +176,8 @@ void finduniquepoints(struct Grdecl *g,
for (j=0; j < g->dims[1]+1; ++j){
for (i=0; i < g->dims[0]+1; ++i){
int *a[4];
double *z[4];
const int *a[4];
const double *z[4];
/* Get positioned pointers for actnum and zcorn data */
igetvectors(g->dims, i, j, g->actnum, a);
@@ -207,8 +208,8 @@ void finduniquepoints(struct Grdecl *g,
/* zcorn column position */
int zix = 2*g->dims[2]*(i+2*g->dims[0]*j);
int *a = g->actnum + cix;
double *z = g->zcorn + zix;
const int *a = g->actnum + cix;
const double *z = g->zcorn + zix;
assignPointNumbers(zptr[pix], zptr[pix+1], zlist,
2*g->dims[2], z, a, p, 0.0);

View File

@@ -1,6 +1,6 @@
#ifndef UNIQUEPOINTS_H
#define UNIQUEPOINTS_H
void finduniquepoints(struct Grdecl *g,
void finduniquepoints(const struct Grdecl *g,
int *plist,
sparse_table_t *ztab);