/* Copyright 2011 (c) Jostein R. Natvig */ #include #include #include #include #include #include #include #include #include #include #include struct Rock { double *perm; double *poro; }; static void destroy_rock(struct Rock *rock) { if (rock!=NULL) { free(rock->perm); free(rock->poro); } free(rock); } static struct Rock* init_rock(int nc, int d) { int i,j; struct Rock *rock = (struct Rock*) malloc(sizeof *rock); if (rock!=NULL) { rock->perm = (double*) malloc(nc*d*d*sizeof *rock->perm); rock->poro = (double*) malloc(nc * sizeof *rock->poro); if ((rock->perm==NULL) || (rock->poro==NULL)) { destroy_rock(rock); rock = NULL; } else { vector_zero(nc*d*d, rock->perm); for (i=0; iporo[i] = 1.0; for (j=0; jperm[j*(d+1)+i*d*d] = 1.0; } } } } return rock; } static void qfs(grid_t *g, struct Rock *rock, double *src, double *pressure, double *faceflux) { size_t alloc_sz, totconn; double *htrans, *trans, *gpress; struct ifs_tpfa_data *h; fprintf(stderr, "QFS: Allocate space\n"); totconn = g->cell_facepos[ g->number_of_cells ]; alloc_sz = totconn; /* htrans */ alloc_sz += g->number_of_faces; /* trans */ alloc_sz += totconn; /* gpress */ htrans = (double*) malloc(alloc_sz * sizeof *htrans); trans = htrans + totconn; gpress = trans + g->number_of_faces; h = ifs_tpfa_construct(g); fprintf(stderr, "QFS: Compute transmissibilities\n"); tpfa_htrans_compute(g, rock->perm, htrans); tpfa_trans_compute (g, htrans , trans ); vector_zero(totconn, gpress); assert (g->number_of_cells > 1); fprintf(stderr, "QFS: Assemble pressure system\n"); ifs_tpfa_assemble(g, trans, src, gpress, h); fprintf(stderr, "QFS: Solve pressure system\n"); call_UMFPACK(h->A, h->b, h->x); fprintf(stderr, "QFS: Recover pressure and flux\n"); ifs_tpfa_press_flux(g, trans, h, pressure, faceflux); fprintf(stderr, "QFS: Release memory resources\n"); ifs_tpfa_destroy(h); free(htrans); fprintf(stderr, "QFS: Done\n"); } static void compute_porevolume(struct UnstructuredGrid *g, double *poro, double *pv) { int i; for (i=0; inumber_of_cells; ++i) { pv[i] = g->cell_volumes[i]*poro[i]; } } int main(void) { struct UnstructuredGrid *g = create_cart_grid_2d(10,10); struct Rock *rock = init_rock(g->number_of_cells, g->dimensions); double *sat = (double*) malloc(g->number_of_cells *sizeof *sat); double *press = (double*) malloc(g->number_of_cells *sizeof *press); double *flux = (double*) malloc(g->number_of_faces *sizeof *flux); double *pv = (double*) malloc(g->number_of_cells *sizeof *pv); double *src = (double*) malloc(g->number_of_cells *sizeof *src); vector_zero(g->number_of_cells, sat); vector_zero(g->number_of_cells, src); src[0]=1;src[g->number_of_cells-1]=-1; qfs(g, rock, src, press, flux); compute_porevolume(g, rock->poro, pv); twophasetransport(pv, src, 10, g, flux, NULL, sat); vector_write(g->number_of_cells, sat, "saturation.txt"); free(pv); free(src); free(sat); free(press); free(flux); destroy_rock(rock); return 0; }