pmgbergen / porepy

Python Simulation Tool for Fractured and Deformable Porous Media

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Improve conditioning of MpXA local problems

keileg opened this issue · comments

A core part of the Mpfa and Mpsa discretizations is the construction of basis functions on subcells see (review paper) for details. This is implemented as inversion of a block diagonal matrix, which contains local problems on the form

$$\begin{bmatrix} n^T K & 0 \\\ \pm dist & \pm I \\\ 0 & I \end{bmatrix} \begin{bmatrix} g \\ p_{cc} \end{bmatrix} \begin{bmatrix} 0 \\ 0 \\ I \end{bmatrix}$$

The unknowns are the pressure gradient $g$ and the cell center pressures $p_{cc}$. The first row of equations represent flux continuity (hence the block corresponding to the cell center pressure contribution is zero), the second continuity of pressures over grid faces (the face pressure is computed from the cell center values + the pressure gradient multiplied with the distance from cell to face; the $\pm$ reflects that the expression for one of the cells has been moved to the other side). The third equation enforces unit pressures in the cell centers, one cell at a time (that is, we solve for multiple right hand side, each has one non-zero cell-center pressure).

The goal of the MpXa discretization is to solve the equation for $g$ in terms of $p_{cc}$. To that end, we need to invert the matrix

$$\begin{bmatrix} n^T K \\\ \pm dist \end{bmatrix}$$

Note the scaling of these equations: The first scales with face area $h^{n-1}$, and also with the permeability, while the second scales with $h$. For general values, this may lead to poor conditioning of the system, hence loss of accuracy in the computation of the basis functions.

The suggested remedy is to scale the linear system before inversion, so that the equations become more balanced. This should be done on the level of interaction regions, e.g., separate scaling for each local linear system. The suggested approach is to define a local typical grid size $h$ and permeability $k$ - the latter possibly as a harmonic mean of the permeabilities in the nearby cells.

For this to work, it is paramount that the gradients are scaled back after computations so that the computed fluxes are correct. This should not be difficult, but the right way to do so is not immediately clear.

It seems the trick is not to scale back, but rather to scale the right hand side (the $p$ term which is moved to the rhs to facilitate the computation of a basis function). So, right before inversion (and, thinking of the implementation, right before the permutation of the linear system to a block diagonal form), we need to scale with a diagonal matrix. Except for juggling with indices of subcells (which is technically complex), this should be straightforward.

We also need to scale the various right hand sides. Two questions arise:

  1. Do we need to pass the scaling matrix around to various subfunctions that compute various right hand sides? This is relevant in particular for poro-elasticity.
  2. Do boundary conditions need special care? My intuition says no, but I have learned not to trust myself.

A final question:
3.: How do we do permeability scaling, and stiffness for the elasticity? Likely, we want eigenvalues of the tensors, I'll need to think of that.

Test cases must also be defined. Right now, my thinking is we need not introduce extra formal tests, but I may leave some functionality that enables monitoring of condition numbers for the local systems, should we ever be interested in that.