commit
b2ce32b329
398
opm/core/grid.c
398
opm/core/grid.c
@ -18,7 +18,12 @@
|
||||
*/
|
||||
|
||||
#include <opm/core/grid.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
void
|
||||
@ -135,3 +140,396 @@ allocate_grid(size_t ndims ,
|
||||
|
||||
return G;
|
||||
}
|
||||
|
||||
|
||||
#define GRID_NMETA 6
|
||||
#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[GRID_NMETA], i;
|
||||
|
||||
save_errno = errno;
|
||||
|
||||
i = 0;
|
||||
while ((i < GRID_NMETA) && (fscanf(fp, " %lu", &tmp) == 1)) {
|
||||
dimens[i] = tmp;
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if (i == GRID_NMETA) {
|
||||
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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -19,6 +19,7 @@ sparsevector_test \
|
||||
test_cartgrid \
|
||||
test_column_extract \
|
||||
test_lapack \
|
||||
test_read_grid \
|
||||
test_read_vag \
|
||||
test_readpolymer \
|
||||
test_sf2p \
|
||||
|
25
tests/test_read_grid.c
Normal file
25
tests/test_read_grid.c
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* test_read_grid.c
|
||||
*
|
||||
* Created on: Aug 28, 2012
|
||||
* Author: bska
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <opm/core/grid.h>
|
||||
#include <opm/core/grid/cart_grid.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
struct UnstructuredGrid *G1, *G2;
|
||||
|
||||
G1 = read_grid("cart_grid_2d.txt");
|
||||
G2 = create_grid_cart2d(2, 2);
|
||||
|
||||
destroy_grid(G2);
|
||||
destroy_grid(G1);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user