Skip to main content
`Ctrl`+`K`

# PCFIELDSPLIT

Preconditioner created by combining separate preconditioners for individual collections of variables (that may overlap) called fields or splits. Each field often represents a different continuum variable represented on a grid, such as velocity, pressure, or temperature. In the literature these are sometimes called block preconditioners; but should not be confused with `PCBJACOBI`. See the users manual section on “Solving Block Matrices” for more details.

## Options Database Keys

- -pc_fieldsplit_%d_fields a,b,… - indicates the fields to be used in the `%d`’th split

- -pc_fieldsplit_default - automatically add any fields to additional splits that have not been supplied explicitly by `-pc_fieldsplit_%d_fields`

- -pc_fieldsplit_block_size bs - size of block that defines fields (i.e. there are bs fields) when the matrix is not of `MatType` `MATNEST`

- -pc_fieldsplit_type (additive|multiplicative|symmetric_multiplicative|schur|gkb) - type of relaxation or factorization splitting

- -pc_fieldsplit_schur_precondition (self|selfp|user|a11|full) - default is `a11`; see `PCFieldSplitSetSchurPre()`

- -pc_fieldsplit_schur_fact_type (diag|lower|upper|full) - set factorization type when using `-pc_fieldsplit_type schur`; see `PCFieldSplitSetSchurFactType()`

- -pc_fieldsplit_dm_splits (true|false) (default is true) - Whether to use `DMCreateFieldDecomposition()` for splits

- -pc_fieldsplit_detect_saddle_point (true|false) - automatically finds rows with zero diagonal and uses Schur complement with no preconditioner as the solver

Options prefixes for inner solvers when using the Schur complement preconditioner are `-fieldsplit_0_` and `-fieldsplit_1_` . The options prefix for the inner solver when using the Golub-Kahan biadiagonalization preconditioner is `-fieldsplit_0_` For all other solvers they are `-fieldsplit_%d_` for the `%d`’th field; use `-fieldsplit_` for all fields.

To set options on the solvers for all blocks, prepend `-fieldsplit_` to all the `PC` options database keys. For example, `-fieldsplit_pc_type ilu` `-fieldsplit_pc_factor_levels 1`.

To set the options on the solvers separate for each block call `PCFieldSplitGetSubKSP()` and set the options directly on the resulting `KSP` object

## Notes

Use `PCFieldSplitSetFields()` to set splits defined by “strided” entries or with a `MATNEST` and `PCFieldSplitSetIS()` to define a split by an arbitrary collection of entries.

If no splits are set, the default is used. If a `DM` is associated with the `PC` and it supports `DMCreateFieldDecomposition()`, then that is used for the default. Otherwise if the matrix is not `MATNEST`, the splits are defined by entries strided by bs, beginning at 0 then 1, etc to bs-1. The block size can be set with `PCFieldSplitSetBlockSize()`, if this is not called the block size defaults to the blocksize of the second matrix passed to `KSPSetOperators()`/`PCSetOperators()`.

For the Schur complement preconditioner if

\[J = \left[\begin{array}{cc} A_{00} & A_{01} \\ A_{10} & A_{11} \end{array}\right]\]

the preconditioner using `full` factorization is logically

\[\left[\begin{array}{cc} I & -\text{ksp}(A_{00}) A_{01} \\ 0 & I \end{array}\right] \left[\begin{array}{cc} \text{ksp}(A_{00}) & 0 \\ 0 & \text{ksp}(S) \end{array}\right] \left[\begin{array}{cc} I & 0 \\ -A_{10} \text{ksp}(A_{00}) & I \end{array}\right]\]

where the action of \(\text{ksp}(A_{00})\) is applied using the `KSP` solver with prefix `-fieldsplit_0_`. \(S\) is the Schur complement

\[S = A_{11} - A_{10} \text{ksp}(A_{00}) A_{01}\]

which is usually dense and not stored explicitly. The action of \(\text{ksp}(S)\) is computed using the `KSP` solver with prefix `-fieldsplit_splitname_` (where `splitname` was given in providing the SECOND split or 1 if not given). Accordingly, if using `PCFieldSplitGetSubKSP()`, the array of sub-`KSP` contexts will hold two `KSP`s: at its 0th index, the `KSP` associated with `-fieldsplit_0_`, and at its 1st index, the `KSP` corresponding to `-fieldsplit_1_`. By default, \(A_{11}\) is used to construct a preconditioner for \(S\), use `PCFieldSplitSetSchurPre()` for all the possible ways to construct the preconditioner for \(S\).

The factorization type is set using `-pc_fieldsplit_schur_fact_type <diag, lower, upper, full>`. `full` is shown above, `diag` gives

\[\left[\begin{array}{cc} \text{ksp}(A_{00}) & 0 \\ 0 & -\text{ksp}(S) \end{array}\right]\]

Note that, slightly counter intuitively, there is a negative in front of the \(\text{ksp}(S)\) so that the preconditioner is positive definite. For SPD matrices \(J\), the sign flip can be turned off with `PCFieldSplitSetSchurScale()` or by command line `-pc_fieldsplit_schur_scale 1.0`. The `lower` factorization is the inverse of

\[\left[\begin{array}{cc} A_{00} & 0 \\ A_{10} & S \end{array}\right]\]

where the inverses of \(A_{00}\) and \(S\) are applied using `KSP`s. The upper factorization is the inverse of

\[\left[\begin{array}{cc} A_{00} & A_{01} \\ 0 & S \end{array}\right]\]

where again the inverses of \(A_{00}\) and \(S\) are applied using `KSP`s.

If only one set of indices (one `IS`) is provided with `PCFieldSplitSetIS()` then the complement of that `IS` is used automatically for a second submatrix.

The fieldsplit preconditioner cannot currently be used with the `MATBAIJ` or `MATSBAIJ` data formats if the blocksize is larger than 1. Generally it should be used with the `MATAIJ` or `MATNEST` `MatType`

The forms of these preconditioners are closely related, if not identical, to forms derived as “Distributive Iterations”, see, for example, page 294 in “Principles of Computational Fluid Dynamics” by Pieter Wesseling [Wes09]. One can also use `PCFIELDSPLIT` inside a smoother resulting in “Distributive Smoothers”.

See “A taxonomy and comparison of parallel block multi-level preconditioners for the incompressible Navier-Stokes equations” [EHS+08].

The Constrained Pressure Preconditioner (CPR) can be implemented using `PCCOMPOSITE` with `PCGALERKIN`. CPR first solves an \(R A P\) subsystem, updates the residual on all variables (`PCCompositeSetType(pc,PC_COMPOSITE_MULTIPLICATIVE)`), and then applies a simple ILU like preconditioner on all the variables.

The generalized Golub-Kahan bidiagonalization preconditioner (GKB) can be applied to symmetric \(2 \times 2\) block matrices of the shape

\[\left[\begin{array}{cc} A_{00} & A_{01} \\ A_{01}' & 0 \end{array}\right]\]

with \(A_{00}\) positive semi-definite. The implementation follows [Ari13]. Therein, we choose \(N := 1/\nu * I\) and the \((1,1)\)-block of the matrix is modified to \(H = _{A00} + \nu*A_{01}*A_{01}'\). A linear system \(Hx = b\) has to be solved in each iteration of the GKB algorithm. This solver is chosen with the option prefix `-fieldsplit_0_`.

Some `PCFIELDSPLIT` variants are called physics-based preconditioners, since the preconditioner takes into account the underlying physics of the problem. But this nomenclature is not well-defined.

## Developer Note

The Schur complement functionality of `PCFIELDSPLIT` should likely be factored into its own `PC` thus simplifying the implementation of the preconditioners and their user API.

## References

[Ari13]

Mario Arioli. Generalized Golub–Kahan bidiagonalization and stopping criteria. SIAM Journal on Matrix Analysis and Applications, 34(2):571–592, 2013.

[EHS+08]

H.C. Elman, V.E. Howle, J. Shadid, R. Shuttleworth, and R. Tuminaro. A taxonomy and comparison of parallel block multi-level preconditioners for the incompressible Navier-Stokes equations. Journal of Computational Physics, 227(1):1790–1808, 2008. URL: https://www.osti.gov/biblio/920807/.

[Wes09]

Pieter Wesseling. Principles of computational fluid dynamics. Volume 29. Springer Science & Business Media, 2009.

## See Also

Solving Block Matrices with PCFIELDSPLIT, `PC`, `PCCreate()`, `PCSetType()`, `PCType`, `PCLSC`, `PCFieldSplitGetSubKSP()`, `PCFieldSplitSchurGetSubKSP()`, `PCFieldSplitSetFields()`, `PCFieldSplitSetType()`, `PCFieldSplitSetIS()`, `PCFieldSplitSetSchurPre()`, `PCFieldSplitSetSchurFactType()`, `MatSchurComplementSetAinvType()`, `PCFieldSplitSetSchurScale()`, `PCFieldSplitSetDetectSaddlePoint()`

## Level

intermediate

## Location

src/ksp/pc/impls/fieldsplit/fieldsplit.c

## Examples

src/ksp/ksp/tutorials/ex81.c
src/dm/impls/stag/tutorials/ex4.c
src/ksp/ksp/tutorials/ex27.c
src/ksp/ksp/tutorials/ex84.c
src/dm/impls/stag/tutorials/ex2.c
src/dm/impls/stag/tutorials/ex3.c
src/ksp/ksp/tutorials/ex81a.c
src/ksp/ksp/tutorials/ex70.c
src/ksp/ksp/tutorials/ex43.c

Index of all PC routines
Table of Contents for all manual pages
Index of all manual pages