From 0d5431aaba224dc49b097dba23ca7f6a356a43c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Tue, 6 Mar 2012 14:00:34 +0100 Subject: [PATCH 1/2] Start encapsulating ifs_tpfa driving forces into a managing structure. --- opm/core/pressure/IncompTpfa.cpp | 5 ++++- opm/core/pressure/tpfa/ifs_tpfa.c | 6 ++++-- opm/core/pressure/tpfa/ifs_tpfa.h | 7 ++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/opm/core/pressure/IncompTpfa.cpp b/opm/core/pressure/IncompTpfa.cpp index ac9552495..74d0472a2 100644 --- a/opm/core/pressure/IncompTpfa.cpp +++ b/opm/core/pressure/IncompTpfa.cpp @@ -105,7 +105,10 @@ namespace Opm } } - ifs_tpfa_assemble(gg, &trans_[0], &src[0], &gpress_omegaweighted_[0], h_); + ifs_tpfa_forces F; + F.src = &src[0]; + + ifs_tpfa_assemble(gg, &F, &trans_[0], &gpress_omegaweighted_[0], h_); linsolver_.solve(h_->A, h_->b, h_->x); diff --git a/opm/core/pressure/tpfa/ifs_tpfa.c b/opm/core/pressure/tpfa/ifs_tpfa.c index 43c5d1fc7..efe81245e 100644 --- a/opm/core/pressure/tpfa/ifs_tpfa.c +++ b/opm/core/pressure/tpfa/ifs_tpfa.c @@ -186,8 +186,8 @@ ifs_tpfa_construct(struct UnstructuredGrid *G) /* ---------------------------------------------------------------------- */ void ifs_tpfa_assemble(struct UnstructuredGrid *G, + const struct ifs_tpfa_forces *F, const double *trans, - const double *src, const double *gpress, struct ifs_tpfa_data *h) /* ---------------------------------------------------------------------- */ @@ -223,7 +223,9 @@ ifs_tpfa_assemble(struct UnstructuredGrid *G, } } - h->b[c] += src[c]; + if ((F != NULL) && (F->src != NULL)) { + h->b[c] += F->src[c]; + } } h->A->sa[0] *= 2; diff --git a/opm/core/pressure/tpfa/ifs_tpfa.h b/opm/core/pressure/tpfa/ifs_tpfa.h index 5f9a6fab7..4635ca8c8 100644 --- a/opm/core/pressure/tpfa/ifs_tpfa.h +++ b/opm/core/pressure/tpfa/ifs_tpfa.h @@ -38,13 +38,18 @@ struct ifs_tpfa_data { }; +struct ifs_tpfa_forces { + const double *src; +}; + + struct ifs_tpfa_data * ifs_tpfa_construct(struct UnstructuredGrid *G); void ifs_tpfa_assemble(struct UnstructuredGrid *G, + const struct ifs_tpfa_forces *F, const double *trans, - const double *src, const double *gpress, struct ifs_tpfa_data *h); From 0a99364c2735c915bbbe93415199461d92ad5260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Tue, 6 Mar 2012 20:07:35 +0100 Subject: [PATCH 2/2] Switch to a sparse/compressed boundary condition representation. Specifically, replace the existing flowbc_t (that was densely represented on each interface, including internal interface and external no-flow interfaces) with a new structure given by struct FlowBoundaryConditions The semantics of this structure mirror those of "struct Wells" from , but is currently mostly intended for simple, incompressible flow purposes. Update pressure solvers supporting boundary conditions to accommodate the new boundary condition representation in the process. --- opm/core/pressure/flow_bc.c | 174 ++++++++++++++++++++++++++++++------ opm/core/pressure/flow_bc.h | 48 ++++++++-- 2 files changed, 185 insertions(+), 37 deletions(-) diff --git a/opm/core/pressure/flow_bc.c b/opm/core/pressure/flow_bc.c index d61afbcc1..dba5701ff 100644 --- a/opm/core/pressure/flow_bc.c +++ b/opm/core/pressure/flow_bc.c @@ -1,5 +1,5 @@ /* - Copyright 2010 SINTEF ICT, Applied Mathematics. + Copyright 2010, 2012 SINTEF ICT, Applied Mathematics. This file is part of the Open Porous Media project (OPM). @@ -17,54 +17,172 @@ along with OPM. If not, see . */ +#include #include -#include "flow_bc.h" +#include -/* Create structure to hold flow boundary conditions for 'nf' faces. - * - * Return fully allocated structure or NULL in case of allocation - * failure. */ /* ---------------------------------------------------------------------- */ -flowbc_t * -allocate_flowbc(size_t nf) +/* Compute an appropriate array dimension to minimise total number of + * (re-)allocations. */ +/* ---------------------------------------------------------------------- */ +static size_t +alloc_size(size_t n, size_t c) /* ---------------------------------------------------------------------- */ { - size_t i; - flowbc_t *new; + if (c < n) { + c *= 2; /* log_2(n) allocations */ - new = malloc(1 * sizeof *new); - if (new != NULL) { - new->type = malloc(nf * sizeof *new->type); - new->bcval = malloc(nf * sizeof *new->bcval); - - if ((new->type == NULL) || (new->bcval == NULL)) { - deallocate_flowbc(new); - new = NULL; - } else { - for (i = 0; i < nf; i++) { - new->type [i] = UNSET; - new->bcval[i] = 0.0; - } + if (c < n) { + c = n; /* Typically for the first few allocs */ } } - return new; + return c; } -/* Release memory resources for dynamically allocated flow boundary - * condition structure. */ +/* ---------------------------------------------------------------------- */ +/* Put structure in a well-defined, initial state */ +/* ---------------------------------------------------------------------- */ +static void +initialise_structure(struct FlowBoundaryConditions *fbc) +/* ---------------------------------------------------------------------- */ +{ + fbc->nbc = 0; + fbc->cpty = 0; + + fbc->type = NULL; + fbc->value = NULL; + fbc->face = NULL; +} + + +/* ---------------------------------------------------------------------- */ +static int +expand_tables(size_t nbc, + struct FlowBoundaryConditions *fbc) +/* ---------------------------------------------------------------------- */ +{ + int ok; + size_t alloc_sz; + void *p1, *p2, *p3; + + ok = nbc <= fbc->cpty; + + if (! ok) { + alloc_sz = alloc_size(nbc, fbc->cpty); + + p1 = realloc(fbc->type , alloc_sz * sizeof *fbc->type ); + p2 = realloc(fbc->value, alloc_sz * sizeof *fbc->value); + p3 = realloc(fbc->face , alloc_sz * sizeof *fbc->face ); + + ok = (p1 != NULL) && (p2 != NULL) && (p3 != NULL); + + if (ok) { + fbc->type = p1; + fbc->value = p2; + fbc->face = p3; + + fbc->cpty = alloc_sz; + } else { + free(p3); free(p2); free(p1); + } + } + + return ok; +} + + +/* ====================================================================== + * Public interface below separator + * ====================================================================== */ + + +/* ---------------------------------------------------------------------- */ +/* Allocate a 'FlowBoundaryConditions' structure, initially capable of + * managing 'nbc' individual boundary conditions. */ +/* ---------------------------------------------------------------------- */ +struct FlowBoundaryConditions * +flow_conditions_construct(size_t nbc) +/* ---------------------------------------------------------------------- */ +{ + int ok; + struct FlowBoundaryConditions *fbc; + + fbc = malloc(1 * sizeof *fbc); + + if (fbc != NULL) { + initialise_structure(fbc); + + ok = expand_tables(nbc, fbc); + + if (! ok) { + flow_conditions_destroy(fbc); + + fbc = NULL; + } + } + + return fbc; +} + + +/* ---------------------------------------------------------------------- */ +/* Release memory resources managed by 'fbc', including the containing + * 'struct' pointer, 'fbc'. */ /* ---------------------------------------------------------------------- */ void -deallocate_flowbc(flowbc_t *fbc) +flow_conditions_destroy(struct FlowBoundaryConditions *fbc) /* ---------------------------------------------------------------------- */ { if (fbc != NULL) { - free(fbc->bcval); + free(fbc->face ); + free(fbc->value); free(fbc->type ); } free(fbc); } + + +/* ---------------------------------------------------------------------- */ +/* Append a new boundary condition to existing set. + * + * Return one (1) if successful, and zero (0) otherwise. */ +/* ---------------------------------------------------------------------- */ +int +flow_conditions_append(enum FlowBCType type , + int face , + double value, + struct FlowBoundaryConditions *fbc ) +/* ---------------------------------------------------------------------- */ +{ + int ok; + + ok = expand_tables(fbc->nbc + 1, fbc); + + if (ok) { + fbc->type [ fbc->nbc ] = type ; + fbc->value[ fbc->nbc ] = value; + fbc->face [ fbc->nbc ] = face ; + + fbc->nbc += 1; + } + + return ok; +} + + +/* ---------------------------------------------------------------------- */ +/* Clear existing set of boundary conditions */ +/* ---------------------------------------------------------------------- */ +void +flow_conditions_clear(struct FlowBoundaryConditions *fbc) +/* ---------------------------------------------------------------------- */ +{ + assert (fbc != NULL); + + fbc->nbc = 0; +} diff --git a/opm/core/pressure/flow_bc.h b/opm/core/pressure/flow_bc.h index 6da3e81c0..7d209db81 100644 --- a/opm/core/pressure/flow_bc.h +++ b/opm/core/pressure/flow_bc.h @@ -22,26 +22,56 @@ #include - #ifdef __cplusplus extern "C" { #endif -enum flowbc_type { UNSET, PRESSURE, FLUX }; +enum FlowBCType { BC_NOFLOW , + BC_PRESSURE , + BC_FLUX_TOTVOL }; -typedef struct { - enum flowbc_type *type; - double *bcval; -} flowbc_t; +/* Boundary condition structure. + * + * Condition i (in [0 .. nbc-1]) affects (outer) interface face[i], is + * of type type[i], and specifies a target value of value[i]. + * + * The field 'cpty' is for internal use by the implementation. */ +struct FlowBoundaryConditions { + size_t nbc; /* Current number of bdry. conditions */ + size_t cpty; /* Internal management. Do not touch */ + + enum FlowBCType *type; /* Condition type */ + double *value; /* Condition value (target) */ + int *face; /* Outer faces affected by ind. target */ +}; -flowbc_t * -allocate_flowbc(size_t nf); +/* Allocate a 'FlowBoundaryConditions' structure, initially capable of + * managing 'nbc' individual boundary conditions. */ +struct FlowBoundaryConditions * +flow_conditions_construct(size_t nbc); + +/* Release memory resources managed by 'fbc', including the containing + * 'struct' pointer, 'fbc'. */ void -deallocate_flowbc(flowbc_t *fbc); +flow_conditions_destroy(struct FlowBoundaryConditions *fbc); +/* Append a new boundary condition to existing set. + * + * Return one (1) if successful, and zero (0) otherwise. */ +int +flow_conditions_append(enum FlowBCType type , + int face , + double value, + struct FlowBoundaryConditions *fbc ); + + +/* Clear existing set of boundary conditions */ +void +flow_conditions_clear(struct FlowBoundaryConditions *fbc); + #ifdef __cplusplus } #endif