diff --git a/opm/core/pressure/mimetic/hybsys.h b/opm/core/pressure/mimetic/hybsys.h
index 7e0da807..2fd77a96 100644
--- a/opm/core/pressure/mimetic/hybsys.h
+++ b/opm/core/pressure/mimetic/hybsys.h
@@ -20,87 +20,338 @@
#ifndef OPM_HYBSYS_HEADER_INCLUDED
#define OPM_HYBSYS_HEADER_INCLUDED
+/**
+ * \file
+ * Routines and data structures to manage local contributions to a
+ * global system of simultaneous linear equations arising from a
+ * Schur complement reduction of an original block system.
+ *
+ * Specifically, these data structures and related routines compute
+ * and store the elemental (cell-based) contributions of the Schur
+ * complement reduction of the block system of simultaneous linear
+ * equations
+ * \f[
+ * \begin{pmatrix}
+ * B & C_1 & D \\
+ * C_2^\mathsf{T} & P & 0 \\
+ * D^\mathsf{T} & 0 & 0
+ * \end{pmatrix}
+ * \begin{pmatrix}
+ * v \\ -p \\ \pi
+ * \end{pmatrix} = \begin{pmatrix}
+ * G \\ g \\ h
+ * \end{pmatrix}
+ * \f]
+ * in which \f$G\f$ accounts for effects of gravity. The traditional
+ * Schurcomplement reduction (block Gaussian elimination) then produces
+ * the equivalent system of simultaneous linear equations
+ * \f[
+ * \begin{pmatrix}
+ * B & C_1 & D \\
+ * 0 & -L & -F_2 \\
+ * 0 & 0 & A
+ * \end{pmatrix}
+ * \begin{pmatrix}
+ * v \\ -p \\ \pi
+ * \end{pmatrix} = \begin{pmatrix}
+ * G \\ g - C_2^\mathsf{T}B^{-1}G \\ b
+ * \end{pmatrix}.
+ * \f]
+ * Here, the matrix \f$A\f$ and the right hand side vector \f$b\f$ are given
+ * by
+ * \f[
+ * \begin{aligned}
+ * A &= D^\mathsf{T}B^{-1}D - F_1^\mathsf{T}L^{-1}F_2 \\
+ * b &= D^\mathsf{T}B^{-1}G +
+ * F_1^\mathsf{T}L^{-1}(g - C_2^\mathsf{T}B^{-1}G) - h,
+ * \end{aligned}
+ * \f]
+ * and the component matrices \f$F_1\f$, \f$F_2\f$, and \f$L\f$ are given
+ * by
+ * \f[
+ * F_1 = C_1^\mathsf{T}B^{-1}D, \quad
+ * F_2 = C_2^\mathsf{T}B^{-1}D, \quad
+ * L = C_2^\mathsf{T}B^{-1}C_1 - P.
+ * \f]
+ * In the case of incompressible flow, the matrix \f$C_2\f$ is the same
+ * as \f$C_1\f$ and \f$P=0\f$ whence the coefficient matrix \f$A\f$ of
+ * the Schur complement system \f$A\pi=b\f$ is symmetric.
+ *
+ * A great deal of simplification arises from the simple characterisation
+ * of the \f$C_1\f$ and \f$D\f$ matrices. Specifically,
+ * \f[
+ * (C_1)_{ij} = \begin{cases}
+ * 1, &\quad i\in\{\mathit{pconn}_j, \dots, \mathit{pconn}_{j+1}-1\}, \\
+ * 0, &\quad \text{otherwise},
+ * \end{cases}
+ * \f]
+ * and
+ * \f[
+ * (D)_{ij} = \begin{cases}
+ * 1, &\quad \mathit{conn}_i = j, \\
+ * 0, &\quad \text{otherwise}.
+ * \end{cases}
+ * \f]
+ * When viewed in the context of a single cell, then the \f$D\f$ matrix
+ * is, effectively, the identity with the \f$\mathit{conn}\f$ array
+ * simply affecting a finite-element style redistribution (assembly)
+ * of the local contributions. This module leverages that property
+ * extensively.
+ */
+
#ifdef __cplusplus
extern "C" {
#endif
+/**
+ * Elemental contributions (from cells) to block system of simultaneous
+ * linear equations. Mixes quantities of single cells (@c r,
+ * @c S and @c one) with those that cater to all cells (@c L,
+ * @c q, @c F1, and--possibly--@c F2).
+ */
struct hybsys {
- double *L; /* C2' * inv(B) * C1 - P */
- double *q; /* g - F2*G */
- double *F1; /* C1' * inv(B) */
- double *F2; /* C2' * inv(B) */
- double *r; /* system rhs in single cell */
- double *S; /* system matrix in single cell */
- double *one; /* ones(max_nconn, 1) */
+ double *L; /**< \f$C_2^\mathsf{T}B^{-1}C - P\f$, all cells */
+ double *q; /**< \f$g - F_2 G\f$, all cells */
+ double *F1; /**< \f$C_1^\mathsf{T}B^{-1}\f$, all cells */
+ double *F2; /**< \f$C_2^\mathsf{T}B^{-1}\f$, all cells*/
+ double *r; /**< Data buffer for system right-hand side, single cell */
+ double *S; /**< Data buffer system matrix, single cell */
+ double *one; /**< \f$(1,1,\dots,1)^\mathsf{T}\f$, single cell */
};
+/**
+ * Elemental contributions (from wells) to block system of simultaneous
+ * linear equations. Mixes quantities of single cell connections (@c r,
+ * @c w2r, @c r2w, and @c w2w) and those that pertain to all well
+ * connections (perforations) in concert (@c F1 and @c F2).
+ */
struct hybsys_well {
- double *F1;
- double *F2;
- double *r;
+ double *F1; /**< \f$C_1^\mathsf{T}B^{-1}\f$, all connections. */
+ double *F2; /**< \f$C_2^\mathsf{T}B^{-1}\f$, all connections. */
+ double *r; /**< Data buffer for system right-hand side, single cell. */
- double *w2r;
- double *r2w;
- double *w2w;
+ double *w2r; /**< Well-to-reservoir connection strength, single cell. */
+ double *r2w; /**< Reservoir-to-well connection strength, single cell. */
+ double *w2w; /**< Aggregate well-to-well connection strength. */
- double *data;
+ double *data; /**< Linear storage array. Structure undisclosed. */
};
+/**
+ * Allocate a hybrid system management structure suitable for discretising
+ * a symmetric (i.e., incompressible) flow problem on a grid model of
+ * given size.
+ *
+ * @param[in] max_nconn Maximum number of single cell faces.
+ * @param[in] nc Total number of grid cells.
+ * @param[in] nconn_tot Aggregate number of cell faces for all cells.
+ * @return Fully formed hybrid system management structure if successful or
+ * @c NULL in case of allocation failure.
+ */
struct hybsys *
hybsys_allocate_symm(int max_nconn, int nc, int nconn_tot);
+
+/**
+ * Allocate a hybrid system management structure suitable for discretising
+ * an unsymmetric (i.e., compressible) flow problem on a grid model of
+ * given size.
+ *
+ * @param[in] max_nconn Maximum number of single cell faces.
+ * @param[in] nc Total number of grid cells.
+ * @param[in] nconn_tot Aggregate number of cell faces for all cells.
+ * @return Fully formed hybrid system management structure if successful or
+ * @c NULL in case of allocation failure.
+ */
struct hybsys *
hybsys_allocate_unsymm(int max_nconn, int nc, int nconn_tot);
+
+/**
+ * Allocate a hybrid system management structure suitable for discretising
+ * an incompressible (i.e., symmetric) well flow problem on a grid model
+ * of given size.
+ *
+ * @param[in] max_nconn Maximum number of single cell faces.
+ * @param[in] nc Total number of grid cells.
+ * @param[in] cwpos Indirection array that defines each cell's
+ * connecting wells. Values typically computed
+ * using function derive_cell_wells().
+ * @return Fully formed hybrid system management structure if successful or
+ * @c NULL in case of allocation failure.
+ */
struct hybsys_well *
hybsys_well_allocate_symm(int max_nconn, int nc, int *cwpos);
+
+/**
+ * Allocate a hybrid system management structure suitable for discretising
+ * a compressible (i.e., unsymmetric) well flow problem on a grid model
+ * of given size.
+ *
+ * @param[in] max_nconn Maximum number of single cell faces.
+ * @param[in] nc Total number of grid cells.
+ * @param[in] cwpos Indirection array that defines each cell's
+ * connecting wells. Values typically computed
+ * using function derive_cell_wells().
+ * @return Fully formed hybrid system management structure if successful
+ * or @c NULL in case of allocation failure.
+ */
struct hybsys_well *
hybsys_well_allocate_unsymm(int max_nconn, int nc, int *cwpos);
+
+/**
+ * Dispose of memory resources previously obtained through one of the
+ * allocation functions, hybsys_allocate_symm() or
+ * hybsys_allocate_unsymm().
+ *
+ * Following a call to hybsys_free(), the input pointer is no longer
+ * valid. hybsys_free(NULL)
does nothing.
+ *
+ * @param[in,out] sys Previously allocated hybrid system management
+ * structure (or @c NULL).
+ */
void
hybsys_free(struct hybsys *sys);
+/**
+ * Dispose of memory resources previously obtained through one of the
+ * allocation functions, hybsys_well_allocate_symm() or
+ * hybsys_well_allocate_unsymm().
+ *
+ * Following a call to hybsys_well_free(), the input pointer is
+ * no longer valid. hybsys_well_free(NULL)
does nothing.
+ *
+ * @param[in,out] wsys Previously allocated hybrid system management
+ * structure (or @c NULL).
+ */
void
hybsys_well_free(struct hybsys_well *wsys);
+
+/**
+ * Perform post-construction dynamic initialisation of system
+ * structure obtained from function hybsys_allocate_symm() or
+ * hybsys_allocate_unsymm().
+ *
+ * @param[in] max_nconn Maximum number of single cell faces.
+ * Must coincide with the equally named
+ * parameter of functions hybsys_allocate_symm()
+ * or hybsys_allocate_unsymm().
+ * @param[in,out] sys Previously allocated hybrid system management
+ * structure.
+ */
void
hybsys_init(int max_nconn, struct hybsys *sys);
-/*
- * Schur complement reduction (per grid cell) of block matrix
+/**
+ * Compute elemental (per-cell) contributions to symmetric Schur
+ * system of simultaneous linear equations.
*
- * [ B C D ]
- * [ C' 0 0 ]
- * [ D' 0 0 ]
+ * This function assumes that the coefficient matrix of the hybrid
+ * system of linear equations is that of the introduction with the
+ * additional provision that \f$C_1=C_2=C\f$ and that \f$P=0\f$.
+ * In other words, this function assumes that the coefficient matrix
+ * is of the form
+ * \f[
+ * \begin{pmatrix}
+ * B & C & D \\
+ * C^\mathsf{T} & 0 & 0 \\
+ * D^\mathsf{T} & 0 & 0
+ * \end{pmatrix}.
+ * \f]
+ * This function fills the @c F1 and @c L fields of the management
+ * structure.
*
+ * @param[in] nc Total number of grid cells.
+ * @param[in] pconn Cell-to-face start pointers.
+ * @param[in] Binv Inverse inner product results, usually
+ * computed using mim_ip_simple_all() and
+ * mim_ip_mobility_update().
+ * @param[in,out] sys Hybrid system management structure allocated
+ * using hybsys_allocate_symm() and initialised
+ * using hybsys_init().
*/
void
hybsys_schur_comp_symm(int nc, const int *pconn,
const double *Binv, struct hybsys *sys);
-/*
- * Schur complement reduction (per grid cell) of block matrix
+
+/**
+ * Compute elemental (per-cell) contributions to unsymmetric Schur
+ * system of simultaneous linear equations.
*
- * [ B C D ]
- * [ (C-V)' P 0 ]
- * [ D' 0 0 ]
+ * This function assumes that the coefficient matrix of the hybrid
+ * system of linear equations is that of the introduction with the
+ * additional provision that \f$C_2=C_1-V\f$. In other words, this
+ * function assumes that the coefficient matrix is of the form
+ * \f[
+ * \begin{pmatrix}
+ * B & C & D \\
+ * (C-V)^\mathsf{T} & P & 0 \\
+ * D^\mathsf{T} & 0 & 0
+ * \end{pmatrix}.
+ * \f]
+ * This matrix arises in the ``\f$v^2\f$'' phase compressibility
+ * formulation of the compressible black-oil model. This function
+ * fills the @c F1, @c F2 and @c L fields of the management structure.
*
+ * @param[in] nc Total number of grid cells.
+ * @param[in] pconn Cell-to-face start pointers.
+ * @param[in] Binv Inverse inner product results, usually
+ * computed using mim_ip_simple_all() and
+ * mim_ip_mobility_update().
+ * @param[in] BIV \f$B^{-1}v\f$ in which \f$v\f$ is the flux
+ * field of a previous time step or non-linear
+ * iteration.
+ * @param[in] P Per cell compressible accumulation term. One
+ * scalar per cell.
+ * @param[in,out] sys Hybrid system management structure allocated
+ * using hybsys_allocate_symm() and initialised
+ * using hybsys_init().
*/
void
hybsys_schur_comp_unsymm(int nc, const int *pconn,
const double *Binv, const double *BIV,
const double *P, struct hybsys *sys);
-/*
- * Schur complement reduction (per grid cell) of block matrix
+
+/**
+ * Compute elemental (per-cell) contributions to unsymmetric Schur
+ * system of simultaneous linear equations.
*
- * [ B C D ]
- * [ C2' P 0 ]
- * [ D' 0 0 ]
+ * This function assumes that the coefficient matrix of the hybrid
+ * system of linear equations is that of the introduction with no
+ * additional provisions. In other words, this
+ * function assumes that the coefficient matrix is of the form
+ * \f[
+ * \begin{pmatrix}
+ * B & C_1 & D \\
+ * C_2^\mathsf{T} & P & 0 \\
+ * D^\mathsf{T} & 0 & 0
+ * \end{pmatrix}.
+ * \f]
+ * This function fills the @c F1, @c F2 and @c L fields of
+ * the management structure.
*
+ * @param[in] nc Total number of grid cells.
+ * @param[in] pconn Cell-to-face start pointers.
+ * @param[in] Binv Inverse inner product results, usually
+ * computed using mim_ip_simple_all() and
+ * mim_ip_mobility_update().
+ * @param[in] C2 Explicit representation of the \f$C_2\f$
+ * matrix as a linear array. Assumed to only
+ * contain the (structurally) non-zero matrix
+ * elements (that correspond to the non-zero
+ * structure of \f$C_1\f$).
+ * @param[in] P Per cell compressible accumulation term. One
+ * scalar per cell.
+ * @param[in,out] sys Hybrid system management structure allocated
+ * using hybsys_allocate_symm() and initialised
+ * using hybsys_init().
*/
void
hybsys_schur_comp_gen(int nc, const int *pconn,