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
<opm/core/newwells.h>, 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.
This commit is contained in:
Bård Skaflestad 2012-03-06 20:07:35 +01:00
parent 0d5431aaba
commit 0a99364c27
2 changed files with 185 additions and 37 deletions

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <stdlib.h>
#include "flow_bc.h"
#include <opm/core/pressure/flow_bc.h>
/* 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;
}

View File

@ -22,26 +22,56 @@
#include <stddef.h>
#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