From bfdd9917a8c3ffbd31ffcebbe82e05957dfa3451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Tue, 28 Aug 2012 16:03:26 +0200 Subject: [PATCH] Add a utility for creating a grid from textual representation. There is little to no error checking, and the importer assumes that the grid is serialised more or less directly from the grid structure. Intended use: Testing on non-uniform grids created in MRST. --- opm/core/grid.c | 397 ++++++++++++++++++++++++++++++++++++++++++++++++ opm/core/grid.h | 11 ++ 2 files changed, 408 insertions(+) diff --git a/opm/core/grid.c b/opm/core/grid.c index 9fa4cd67..bb7de1bc 100644 --- a/opm/core/grid.c +++ b/opm/core/grid.c @@ -18,7 +18,12 @@ */ #include + +#include +#include +#include #include +#include void @@ -135,3 +140,395 @@ allocate_grid(size_t ndims , return G; } + + +#define GRID_NDIMS 0 +#define GRID_NCELLS 1 +#define GRID_NFACES 2 +#define GRID_NNODES 3 +#define GRID_NFACENODES 4 +#define GRID_NCELLFACES 5 + + +static void +input_error(FILE *fp, const char * const err) +{ + int save_errno = errno; + + if (ferror(fp)) { + fprintf(stderr, "%s: %s\n", err, strerror(save_errno)); + clearerr(fp); + } + else if (feof(fp)) { + fprintf(stderr, "%s: End-of-file\n", err); + } + + errno = save_errno; +} + + +static struct UnstructuredGrid * +allocate_grid_from_file(FILE *fp, int *has_tag, int *has_indexmap) +{ + struct UnstructuredGrid *G; + + int save_errno; + unsigned long tmp; + size_t dimens[6], i; + + save_errno = errno; + + i = 0; + while ((i < 6) && (fscanf(fp, " %lu", &tmp) == 1)) { + dimens[i] = tmp; + + i += 1; + } + + if (i == 6) { + if (fscanf(fp, "%d %d", has_tag, has_indexmap) == 2) { + G = allocate_grid(dimens[GRID_NDIMS] , + dimens[GRID_NCELLS] , + dimens[GRID_NFACES] , + dimens[GRID_NFACENODES], + dimens[GRID_NCELLFACES], + dimens[GRID_NNODES] ); + + if (G != NULL) { + if (! *has_tag) { + free(G->cell_facetag); + G->cell_facetag = NULL; + } + + if (*has_indexmap) { + G->global_cell = + malloc(dimens[GRID_NCELLS] * sizeof *G->global_cell); + + /* Allocation failure checked elsewhere. */ + } + + G->number_of_cells = (int) dimens[GRID_NCELLS]; + G->number_of_faces = (int) dimens[GRID_NFACES]; + G->number_of_nodes = (int) dimens[GRID_NNODES]; + G->dimensions = (int) dimens[GRID_NDIMS]; + + i = 0; + while ((i < dimens[GRID_NDIMS]) && + (fscanf(fp, "%d", & G->cartdims[ i ]) == 1)) { + i += 1; + } + + if (i < dimens[GRID_NDIMS]) { + input_error(fp, "Unable to read Cartesian dimensions"); + + destroy_grid(G); + G = NULL; + } + else { + /* Account for dimens[GRID_DIMS] < 3 */ + size_t n = (sizeof G->cartdims) / (sizeof G->cartdims[0]); + for (; i < n; i++) { G->cartdims[ i ] = 1; } + } + } + } + else { + input_error(fp, "Unable to read grid predicates"); + + G = NULL; + } + } + else { + input_error(fp, "Unable to read grid dimensions"); + + G = NULL; + } + + errno = save_errno; + + return G; +} + + +static int +read_grid_nodes(FILE *fp, struct UnstructuredGrid *G) +{ + int save_errno; + size_t i, n; + + save_errno = errno; + + n = G->dimensions; + n *= G->number_of_nodes; + + i = 0; + while ((i < n) && + (fscanf(fp, " %lf", & G->node_coordinates[ i ]) == 1)) { + i += 1; + } + + if (i < n) { + input_error(fp, "Unable to read node coordinates"); + } + + errno = save_errno; + + return i == n; +} + + +static int +read_grid_faces(FILE *fp, struct UnstructuredGrid *G) +{ + int save_errno, ok; + size_t nf, nfn, i; + + save_errno = errno; + + nf = G->number_of_faces; + + /* G->face_nodepos */ + i = 0; + while ((i < nf + 1) && + (fscanf(fp, " %d", & G->face_nodepos[ i ]) == 1)) { + i += 1; + } + ok = i == nf + 1; + + if (! ok) { + input_error(fp, "Unable to read node indirection array"); + } + else { + /* G->face_nodes */ + nfn = G->face_nodepos[ nf ]; + + i = 0; + while ((i < nfn) && (fscanf(fp, " %d", & G->face_nodes[ i ]) == 1)) { + i += 1; + } + + ok = i == nfn; + if (! ok) { + input_error(fp, "Unable to read face-nodes"); + } + } + + if (ok) { + /* G->face_cells */ + i = 0; + while ((i < 2 * nf) && (fscanf(fp, " %d", & G->face_cells[ i ]) == 1)) { + i += 1; + } + + ok = i == 2 * nf; + if (! ok) { + input_error(fp, "Unable to read neighbourship"); + } + } + + if (ok) { + /* G->face_areas */ + i = 0; + while ((i < nf) && (fscanf(fp, " %lf", & G->face_areas[ i ]) == 1)) { + i += 1; + } + + ok = i == nf; + if (! ok) { + input_error(fp, "Unable to read face areas"); + } + } + + if (ok) { + /* G->face_centroids */ + size_t n; + + n = G->dimensions; + n *= nf; + + i = 0; + while ((i < n) && (fscanf(fp, " %lf", & G->face_centroids[ i ]) == 1)) { + i += 1; + } + + ok = i == n; + if (! ok) { + input_error(fp, "Unable to read face centroids"); + } + } + + if (ok) { + /* G->face_normals */ + size_t n; + + n = G->dimensions; + n *= nf; + + i = 0; + while ((i < n) && (fscanf(fp, " %lf", & G->face_normals[ i ]) == 1)) { + i += 1; + } + + ok = i == n; + if (! ok) { + input_error(fp, "Unable to read face normals"); + } + } + + errno = save_errno; + + return ok; +} + + +static int +read_grid_cells(FILE *fp, int has_tag, int has_indexmap, + struct UnstructuredGrid *G) +{ + int save_errno, ok; + size_t nc, ncf, i; + + save_errno = errno; + + nc = G->number_of_cells; + + /* G->cell_facepos */ + i = 0; + while ((i < nc + 1) && (fscanf(fp, " %d", & G->cell_facepos[ i ]) == 1)) { + i += 1; + } + ok = i == nc + 1; + + if (! ok) { + input_error(fp, "Unable to read face indirection array"); + } + else { + /* G->cell_faces (and G->cell_facetag if applicable) */ + ncf = G->cell_facepos[ nc ]; + i = 0; + + if (has_tag) { + assert (G->cell_facetag != NULL); + + while ((i < ncf) && + (fscanf(fp, " %d %d", + & G->cell_faces [ i ], + & G->cell_facetag[ i ]) == 2)) { + i += 1; + } + } + else { + while ((i < ncf) && + (fscanf(fp, " %d", & G->cell_faces[ i ]) == 1)) { + i += 1; + } + } + + ok = i == ncf; + if (! ok) { + input_error(fp, "Unable to read cell-faces"); + } + } + + if (ok) { + /* G->global_cell if applicable */ + if (has_indexmap) { + i = 0; + + if (G->global_cell != NULL) { + while ((i < nc) && + (fscanf(fp, " %d", & G->global_cell[ i ]) == 1)) { + i += 1; + } + } + else { + int discard; + + while ((i < nc) && (fscanf(fp, " %d", & discard) == 1)) { + i += 1; + } + } + } + else { + assert (G->global_cell == NULL); + i = nc; + } + + ok = i == nc; + if (! ok) { + input_error(fp, "Unable to read global cellmap"); + } + } + + if (ok) { + /* G->cell_volumes */ + i = 0; + while ((i < nc) && (fscanf(fp, " %lf", & G->cell_volumes[ i ]) == 1)) { + i += 1; + } + + ok = i == nc; + if (! ok) { + input_error(fp, "Unable to read cell volumes"); + } + } + + if (ok) { + /* G->cell_centroids */ + size_t n; + + n = G->dimensions; + n *= nc; + + i = 0; + while ((i < n) && (fscanf(fp, " %lf", & G->cell_centroids[ i ]) == 1)) { + i += 1; + } + + ok = i == n; + if (! ok) { + input_error(fp, "Unable to read cell centroids"); + } + } + + errno = save_errno; + + return ok; +} + + +struct UnstructuredGrid * +read_grid(const char *fname) +{ + struct UnstructuredGrid *G; + FILE *fp; + + int save_errno; + int has_tag, has_indexmap, ok; + + save_errno = errno; + + fp = fopen(fname, "rt"); + if (fp != NULL) { + G = allocate_grid_from_file(fp, & has_tag, & has_indexmap); + + ok = G != NULL; + + if (ok) { ok = read_grid_nodes(fp, G); } + if (ok) { ok = read_grid_faces(fp, G); } + if (ok) { ok = read_grid_cells(fp, has_tag, has_indexmap, G); } + + if (! ok) { + destroy_grid(G); + G = NULL; + } + + fclose(fp); + } + else { + G = NULL; + } + + errno = save_errno; + + return G; +} diff --git a/opm/core/grid.h b/opm/core/grid.h index 841ea8e2..37b074d4 100644 --- a/opm/core/grid.h +++ b/opm/core/grid.h @@ -273,6 +273,17 @@ allocate_grid(size_t ndims , size_t ncellfaces, size_t nnodes ); + +/** + * Import a grid from a character representation stored in file. + * + * @param[in] fname File name. + * @return Fully formed UnstructuredGrid with all fields allocated and filled. + * Returns @c NULL in case of allocation failure. + */ +struct UnstructuredGrid * +read_grid(const char *fname); + #ifdef __cplusplus } #endif