1aa9a5b67SBarry Smith--- 2aa9a5b67SBarry Smithorphan: true 3aa9a5b67SBarry Smith--- 4aa9a5b67SBarry Smith 5aa9a5b67SBarry Smith(tut_stokes)= 6aa9a5b67SBarry Smith 7aa9a5b67SBarry Smith# Guide to the Stokes Equations using Finite Elements 8aa9a5b67SBarry Smith 9aa9a5b67SBarry SmithThe Stokes equations 10aa9a5b67SBarry Smith 11aa9a5b67SBarry Smith$$ 12aa9a5b67SBarry Smith\begin{aligned} 13aa9a5b67SBarry Smith-\nabla \cdot \left(\mu \left(\nabla u + \nabla u^T \right)\right) + \nabla p + f &= 0 \\ 14aa9a5b67SBarry Smith\nabla\cdot u &= 0 \end{aligned} 15aa9a5b67SBarry Smith$$ 16aa9a5b67SBarry Smith 17aa9a5b67SBarry Smithdescribe slow flow of an incompressible fluid with velocity $u$, pressure $p$, and body force $f$. 18aa9a5b67SBarry Smith 19aa9a5b67SBarry SmithThis guide accompanies <a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tutorials/ex62.c.html">SNES Example 62></a> and <a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tutorials/ex69.c.html">SNES Example 69><\a>. 20aa9a5b67SBarry Smith 21aa9a5b67SBarry SmithThe Stokes equations for a fluid, a steady-state form of the Navier-Stokes equations, start with the balance of momentum, just as in elastostatics, 22aa9a5b67SBarry Smith 23aa9a5b67SBarry Smith$$ 24aa9a5b67SBarry Smith\nabla \cdot \sigma + f = 0, 25aa9a5b67SBarry Smith$$ 26aa9a5b67SBarry Smith 27aa9a5b67SBarry Smithwhere $\sigma$ is the stress tensor and $f$ is the body force, combined with the conservation of mass 28aa9a5b67SBarry Smith 29aa9a5b67SBarry Smith$$ 30aa9a5b67SBarry Smith\nabla \cdot (\rho u) = 0, 31aa9a5b67SBarry Smith$$ 32aa9a5b67SBarry Smith 33aa9a5b67SBarry Smithwhere $\rho$ is the density and $u$ is the fluid velocity. If we assume that the density is constant, making the fluid incompressible, and that the rheology is Newtonian, meaning that the viscous stress is linearly proportional to the local strain rate, then we have 34aa9a5b67SBarry Smith 35aa9a5b67SBarry Smith$$ 36aa9a5b67SBarry Smith\begin{aligned} 37aa9a5b67SBarry Smith \nabla \cdot \mu \left( \nabla u + \nabla u^T \right) - \nabla p + f &= 0 \\ 38aa9a5b67SBarry Smith \nabla \cdot u &= 0 39aa9a5b67SBarry Smith\end{aligned} 40aa9a5b67SBarry Smith$$ 41aa9a5b67SBarry Smith 42aa9a5b67SBarry Smithwhere $p$ is the pressure, $\mu$ is the dynamic shear viscosity, with units $N\cdot s/m^2$ or $Pa\cdot s$. If we divide by the constant density, we would have the kinematic viscosity $\nu$ and a force per unit mass. The second equation demands that the velocity field be divergence-free, indicating that the flow is incompressible. The pressure in this case can be thought of as the Lagrange multiplier enforcing the incompressibility constraint. In the compressible case, we would need an equation of state to relate the pressure to the density, and perhaps temperature. 43aa9a5b67SBarry Smith 44aa9a5b67SBarry SmithWe will discretize our Stokes equations with finite elements, so the first step is to write a variational weak form of the equations. We choose to use a Ritz-Galerkin setup, so let our velocity $u \in V$ and pressure $p \in Q$, so that 45aa9a5b67SBarry Smith 46aa9a5b67SBarry Smith$$ 47aa9a5b67SBarry Smith\begin{aligned} 48aa9a5b67SBarry Smith \left< \nabla v, \mu \left( \nabla u + \nabla u^T \right) \right> + \left< v, \frac{\partial\sigma}{\partial n} \right>_\Gamma - \left< \nabla\cdot v, p \right> - \left< v, f \right> &= 0 & \text{for all} \ v \in V\\ 49aa9a5b67SBarry Smith \left< q, -\nabla \cdot u \right> &= 0 & \text{for all} \ q \in Q 50aa9a5b67SBarry Smith\end{aligned} 51aa9a5b67SBarry Smith$$ 52aa9a5b67SBarry Smith 53aa9a5b67SBarry Smithwhere integration by parts has added a boundary integral over the normal derivative of the stress (traction), and natural boundary conditions correspond to stress-free boundaries. We have multiplied the continuity equation by minus one in order to preserve symmetry. 54aa9a5b67SBarry Smith 55aa9a5b67SBarry Smith## Equation Definition 56aa9a5b67SBarry Smith 57aa9a5b67SBarry SmithThe test functions $v, q$ and their derivatives are determined by the discretization, whereas the form of the integrand is determined by the physics. Given a quadrature rule to evaluate the form integral, we would only need the evaluation of the physics integrand at the quadrature points, given the values of the fields and their derivatives. The entire scheme is detailed in {cite}`knepleybrownruppsmith13`. The kernels paired with test functions we will call $f_0$ and those paired with gradients of test functions will be called $f_1$. 58aa9a5b67SBarry Smith 59aa9a5b67SBarry SmithFor example, the kernel for the continuity equation, paired with the pressure test function, is called `f0_p` and can be seen here 60aa9a5b67SBarry Smith 61aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 62aa9a5b67SBarry Smith:end-at: '}' 63aa9a5b67SBarry Smith:start-at: static void f0_p( 64aa9a5b67SBarry Smith``` 65aa9a5b67SBarry Smith 66aa9a5b67SBarry SmithWe use the components of the Jacobian of $u$ to build up its divergence. For the balance of momentum excluding body force, we test against the gradient of the test function, as seen in `f1_u`, 67aa9a5b67SBarry Smith 68aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 69aa9a5b67SBarry Smith:end-at: '}' 70aa9a5b67SBarry Smith:start-at: static void f1_u( 71aa9a5b67SBarry Smith``` 72aa9a5b67SBarry Smith 73aa9a5b67SBarry SmithNotice how the pressure $p$ is referred to using `u[uOff[1]]` so that we can have many fields with different numbers of components. `DMPlex` uses these point functions to construct the residual. A similar set of point functions is also used to build the Jacobian. The last piece of our physics specification is the construction of exact solutions using the Method of Manufactured Solutions (MMS). 74aa9a5b67SBarry Smith 75aa9a5b67SBarry Smith## MMS Solutions 76aa9a5b67SBarry Smith 77aa9a5b67SBarry SmithAn MMS solution is chosen to elucidate some property of the problem, and to check that it is being solved accurately, since the error can be calculated explicitly. For our Stokes problem, we first choose a solution with quadratic velocity and linear pressure, 78aa9a5b67SBarry Smith 79aa9a5b67SBarry Smith$$ 80aa9a5b67SBarry Smithu = \begin{pmatrix} x^2 + y^2 \\ 2 x^2 - 2 x y \end{pmatrix} \quad \mathrm{or} \quad \begin{pmatrix} 2 x^2 + y^2 + z^2 \\ 2 x^2 - 2xy \\ 2 x^2 - 2xz \end{pmatrix} 81aa9a5b67SBarry Smith$$ 82aa9a5b67SBarry Smith 83aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 84aa9a5b67SBarry Smith:append: '}' 85aa9a5b67SBarry Smith:end-at: return 0; 86aa9a5b67SBarry Smith:start-at: static PetscErrorCode quadratic_u 87aa9a5b67SBarry Smith``` 88aa9a5b67SBarry Smith 89aa9a5b67SBarry Smith$$ 90aa9a5b67SBarry Smithp = x + y - 1 \quad \mathrm{or} \quad x + y + z - \frac{3}{2} 91aa9a5b67SBarry Smith$$ 92aa9a5b67SBarry Smith 93aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 94aa9a5b67SBarry Smith:append: '}' 95aa9a5b67SBarry Smith:end-at: return 0; 96aa9a5b67SBarry Smith:start-at: static PetscErrorCode quadratic_p 97aa9a5b67SBarry Smith``` 98aa9a5b67SBarry Smith 99aa9a5b67SBarry SmithBy plugging these solutions into our equations, assuming that the velocity we choose is divergence-free, we can determine the body force necessary to make them satisfy the Stokes equations. For the quadratic solution above, we find 100aa9a5b67SBarry Smith 101aa9a5b67SBarry Smith$$ 102aa9a5b67SBarry Smithf = \begin{pmatrix} 1 - 4\mu \\ 1 - 4\mu \end{pmatrix} \quad \mathrm{or} \quad \begin{pmatrix} 1 - 8\mu \\ 1 - 4\mu \\ 1 - 4\mu \end{pmatrix} 103aa9a5b67SBarry Smith$$ 104aa9a5b67SBarry Smith 105aa9a5b67SBarry Smithwhich is implemented in our `f0_quadratic_u` pointwise function 106aa9a5b67SBarry Smith 107aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 108aa9a5b67SBarry Smith:end-at: '}' 109aa9a5b67SBarry Smith:start-at: static void f0_quadratic_u 110aa9a5b67SBarry Smith``` 111aa9a5b67SBarry Smith 112aa9a5b67SBarry SmithWe let PETSc know about these solutions 113aa9a5b67SBarry Smith 114aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 115aa9a5b67SBarry Smith:end-at: PetscCall(PetscDSSetExactSolution(ds, 1 116aa9a5b67SBarry Smith:start-at: PetscCall(PetscDSSetExactSolution(ds, 0 117aa9a5b67SBarry Smith``` 118aa9a5b67SBarry Smith 119aa9a5b67SBarry SmithThese solutions will be captured exactly by the $P_2-P_1$ finite element space. We can use the `-dmsnes_check` option to activate function space checks. It gives the $L_2$ error, or *discretization* error, of the exact solution, the residual computed using the interpolation of the exact solution into our finite element space, and uses a Taylor test to check that our Jacobian matches the residual. It should converge at order 2, or be exact in the case of linear equations like Stokes. Our $P_2-P_1$ runs in the PETSc test section at the bottom of the source file 120aa9a5b67SBarry Smith 121aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 122aa9a5b67SBarry Smith:lines: 1-3 123aa9a5b67SBarry Smith:start-at: 'suffix: 2d_p2_p1_check' 124aa9a5b67SBarry Smith``` 125aa9a5b67SBarry Smith 126aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 127aa9a5b67SBarry Smith:lines: 1-3 128aa9a5b67SBarry Smith:start-at: 'suffix: 3d_p2_p1_check' 129aa9a5b67SBarry Smith``` 130aa9a5b67SBarry Smith 131aa9a5b67SBarry Smithverify these claims, as we can see from the output files 132aa9a5b67SBarry Smith 133aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/output/ex62_2d_p2_p1_check.out 134aa9a5b67SBarry Smith:language: none 135aa9a5b67SBarry Smith``` 136aa9a5b67SBarry Smith 137aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/output/ex62_3d_p2_p1_check.out 138aa9a5b67SBarry Smith:language: none 139aa9a5b67SBarry Smith``` 140aa9a5b67SBarry Smith 141aa9a5b67SBarry SmithWe can carry out the same tests for the $Q_2-Q_1$ element, 142aa9a5b67SBarry Smith 143aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 144aa9a5b67SBarry Smith:lines: 1-2 145aa9a5b67SBarry Smith:start-at: 'suffix: 2d_q2_q1_check' 146aa9a5b67SBarry Smith``` 147aa9a5b67SBarry Smith 148aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 149aa9a5b67SBarry Smith:lines: 1-2 150aa9a5b67SBarry Smith:start-at: 'suffix: 3d_q2_q1_check' 151aa9a5b67SBarry Smith``` 152aa9a5b67SBarry Smith 153aa9a5b67SBarry SmithThe quadratic solution, however, cannot tell us whether our discretization is attaining the correct order of convergence, especially for higher order elements. Thus, we will define another solution based on trigonometric functions. 154aa9a5b67SBarry Smith 155aa9a5b67SBarry Smith$$ 156aa9a5b67SBarry Smithu = \begin{pmatrix} \sin(\pi x) + \sin(\pi y) \\ -\pi \cos(\pi x) y \end{pmatrix} \quad \mathrm{or} \quad 157aa9a5b67SBarry Smith \begin{pmatrix} 2 \sin(\pi x) + \sin(\pi y) + \sin(\pi z) \\ -\pi \cos(\pi x) y \\ -\pi \cos(\pi x) z \end{pmatrix} 158aa9a5b67SBarry Smith$$ 159aa9a5b67SBarry Smith 160aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 161aa9a5b67SBarry Smith:append: '}' 162aa9a5b67SBarry Smith:end-at: return 0; 163aa9a5b67SBarry Smith:start-at: static PetscErrorCode trig_u 164aa9a5b67SBarry Smith``` 165aa9a5b67SBarry Smith 166aa9a5b67SBarry Smith$$ 167aa9a5b67SBarry Smithp = \sin(2 \pi x) + \sin(2 \pi y) \quad \mathrm{or} \quad \sin(2 \pi x) + \sin(2 \pi y) + \sin(2 \pi z) 168aa9a5b67SBarry Smith$$ 169aa9a5b67SBarry Smith 170aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 171aa9a5b67SBarry Smith:append: '}' 172aa9a5b67SBarry Smith:end-at: return 0; 173aa9a5b67SBarry Smith:start-at: static PetscErrorCode trig_p 174aa9a5b67SBarry Smith``` 175aa9a5b67SBarry Smith 176aa9a5b67SBarry Smith$$ 177aa9a5b67SBarry Smithf = \begin{pmatrix} 2 \pi \cos(2 \pi x) + \mu \pi^2 \sin(\pi x) + \mu \pi^2 \sin(\pi y) \\ 2 \pi \cos(2 \pi y) - \mu \pi^3 \cos(\pi x) y \end{pmatrix} \quad \mathrm{or} \quad 178aa9a5b67SBarry Smith\begin{pmatrix} 2 \pi \cos(2 \pi x) + 2\mu \pi^2 \sin(\pi x) + \mu \pi^2 \sin(\pi y) + \mu \pi^2 \sin(\pi z) \\ 2 \pi \cos(2 \pi y) - \mu \pi^3 cos(\pi x) y \\ 2 \pi \cos(2 \pi z) - \mu \pi^3 \cos(\pi x) z \end{pmatrix} 179aa9a5b67SBarry Smith$$ 180aa9a5b67SBarry Smith 181aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 182aa9a5b67SBarry Smith:append: '}' 183aa9a5b67SBarry Smith:end-at: '}' 184aa9a5b67SBarry Smith:start-at: static void f0_quadratic_u 185aa9a5b67SBarry Smith``` 186aa9a5b67SBarry Smith 187aa9a5b67SBarry SmithWe can now use `-snes_convergence_estimate` to determine the convergence exponent for the discretization. This options solves the problem on a series of refined meshes, calculates the error on each mesh, and determines the slope on a logarithmic scale. For example, we do this in two dimensions, refining our mesh twice using `-convest_num_refine 2` in the following test. 188aa9a5b67SBarry Smith 189aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 190aa9a5b67SBarry Smith:end-before: 'test:' 191aa9a5b67SBarry Smith:start-at: 'suffix: 2d_p2_p1_conv' 192aa9a5b67SBarry Smith``` 193aa9a5b67SBarry Smith 1947addb90fSBarry SmithHowever, the test needs an accurate linear solver. Sparse LU factorizations do not, in general, do full pivoting. Thus we must deal with the zero pressure block explicitly. We use the `PCFIELDSPLIT` preconditioner and the full Schur complement factorization, but we still need a preconditioner for the Schur complement $B^T A^{-1} B$. We can have PETSc construct that matrix automatically, but the cost rises steeply as the problem size increases. Instead, we use the fact that the Schur complement is spectrally equivalent to the pressure mass matrix $M_p$. We can make a matrix from which the preconditioner is constructed, which has the diagonal blocks we will use to build the preconditioners, letting PETSc know that we get the off-diagonal blocks from the original system with `-pc_fieldsplit_off_diag_use_amat` and to build the Schur complement from the original matrix using `-pc_use_amat`, 195aa9a5b67SBarry Smith 196aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 197aa9a5b67SBarry Smith:end-at: PetscCall(PetscDSSetJacobianPreconditioner(ds, 1 198aa9a5b67SBarry Smith:start-at: PetscCall(PetscDSSetJacobianPreconditioner(ds, 0 199aa9a5b67SBarry Smith``` 200aa9a5b67SBarry Smith 201aa9a5b67SBarry SmithPutting this all together, and using exact solvers on the subblocks, we have 202aa9a5b67SBarry Smith 203aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 204aa9a5b67SBarry Smith:end-before: 'test:' 205aa9a5b67SBarry Smith:start-at: 'suffix: 2d_p2_p1_conv' 206aa9a5b67SBarry Smith``` 207aa9a5b67SBarry Smith 208aa9a5b67SBarry Smithand we see it converges, however it is superconverging in the pressure, 209aa9a5b67SBarry Smith 210aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/output/ex62_2d_p2_p1_conv.out 211aa9a5b67SBarry Smith``` 212aa9a5b67SBarry Smith 213aa9a5b67SBarry SmithIf we refine the mesh using `-dm_refine 3`, the convergence rates become `[3.0, 2.1]`. 214aa9a5b67SBarry Smith 215aa9a5b67SBarry Smith## Dealing with Parameters 216aa9a5b67SBarry Smith 217aa9a5b67SBarry SmithLike most physical problems, the Stokes problem has a parameter, the dynamic shear viscosity, which determines what solution regime we are in. To handle these parameters in PETSc, we first define a C struct to hold them, 218aa9a5b67SBarry Smith 219aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 220aa9a5b67SBarry Smith:end-at: '} Parameter;' 221aa9a5b67SBarry Smith:start-at: typedef struct 222aa9a5b67SBarry Smith``` 223aa9a5b67SBarry Smith 224aa9a5b67SBarry Smithand then add a `PetscBag` object to our application context. We then setup the parameter object, 225aa9a5b67SBarry Smith 226aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 227aa9a5b67SBarry Smith:append: '}' 228aa9a5b67SBarry Smith:end-at: PetscFunctionReturn(PETSC_SUCCESS); 229aa9a5b67SBarry Smith:start-at: static PetscErrorCode SetupParameters 230aa9a5b67SBarry Smith``` 231aa9a5b67SBarry Smith 232aa9a5b67SBarry Smithwhich will allow us to set the value from the command line using `-mu`. The `PetscBag` can also be persisted to disk with `PetscBagLoad/View()`. We can make these values available as constant to our pointwise functions through the `PetscDS` object. 233aa9a5b67SBarry Smith 234aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex62.c 235aa9a5b67SBarry Smith:end-at: '}' 236aa9a5b67SBarry Smith:start-after: /* Make constant values 237aa9a5b67SBarry Smith``` 238aa9a5b67SBarry Smith 239aa9a5b67SBarry Smith## Investigating convergence 240aa9a5b67SBarry Smith 241aa9a5b67SBarry SmithIn order to look at the convergence of some harder problems, we will examine `SNES ex69`. This example provides an exact solution to the variable viscosity Stokes equation. The sharp viscosity variation will allow us to investigate convergence of the solver and discretization. Briefly, a sharp viscosity variation is created across the unit square, imposed on a background pressure with given fundamental frequency. For example, we can create examples with period one half and viscosity $e^{2 B x}$ (solKx) 242aa9a5b67SBarry Smith 243aa9a5b67SBarry Smith```console 24430266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-dm_refine 5 -dm_view hdf5:$PETSC_DIR/sol.h5 -snes_view_solution hdf5:$PETSC_DIR/sol.h5::append -exact_vec_view hdf5:$PETSC_DIR/sol.h5::append -m 2 -n 2 -B 1" 24530266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-dm_refine 5 -dm_view hdf5:$PETSC_DIR/sol.h5 -snes_view_solution hdf5:$PETSC_DIR/sol.h5::append -exact_vec_view hdf5:$PETSC_DIR/sol.h5::append -m 2 -n 2 -B 3.75" 246aa9a5b67SBarry Smith``` 247aa9a5b67SBarry Smith 248aa9a5b67SBarry Smithwhich are show in the figure below. 249aa9a5b67SBarry Smith 250aa9a5b67SBarry Smith```{eval-rst} 251aa9a5b67SBarry Smith.. list-table:: 252aa9a5b67SBarry Smith 253aa9a5b67SBarry Smith * - .. figure:: /images/tutorials/physics/ex69_sol_m_2_n_2_B_1.png 254aa9a5b67SBarry Smith 255aa9a5b67SBarry Smith Solution for :math:`m=2`, :math:`n=2`, :math:`B=1` 256aa9a5b67SBarry Smith 257aa9a5b67SBarry Smith - .. figure:: /images/tutorials/physics/ex69_sol_m_2_n_2_B_375.png 258aa9a5b67SBarry Smith 259aa9a5b67SBarry Smith Solution for :math:`m=2`, :math:`n=2`, :math:`B=3.75` 260aa9a5b67SBarry Smith``` 261aa9a5b67SBarry Smith 262aa9a5b67SBarry Smith### Debugging 263aa9a5b67SBarry Smith 264aa9a5b67SBarry SmithIf we can provide the `PetscDS` object in our problem with the exact solution function, PETSc has good support for debugging our discretization and solver. We can use the `PetscConvEst` object to check the convergence behavior of our element automatically. For example, if we use the `-snes_convergence_estimate` option, PETSc will solve our nonlinear equations on a series of refined meshes, use our exact solution to calculate the error, and then fit this line on a log-log scale to get the convergence rate, 265aa9a5b67SBarry Smith 266aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex69.c 267aa9a5b67SBarry Smith:end-before: 'test:' 268aa9a5b67SBarry Smith:start-at: 'suffix: p2p1_conv' 269aa9a5b67SBarry Smith``` 270aa9a5b67SBarry Smith 271aa9a5b67SBarry SmithIf we initially refine the mesh twice, `-dm_refine 2`, we get 272aa9a5b67SBarry Smith 273aa9a5b67SBarry Smith> L_2 convergence rate: [3.0, 2.2] 274aa9a5b67SBarry Smith 275aa9a5b67SBarry Smithwhich are the convergence rates we expect for the velocity and pressure using a $P_2-P_1$ discretization. For $Q_1-P_0$ 276aa9a5b67SBarry Smith 277aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex69.c 278aa9a5b67SBarry Smith:end-before: 'test:' 279aa9a5b67SBarry Smith:start-at: 'suffix: q1p0_conv' 280aa9a5b67SBarry Smith``` 281aa9a5b67SBarry Smith 282aa9a5b67SBarry Smithwe get 283aa9a5b67SBarry Smith 284aa9a5b67SBarry Smith> L_2 convergence rate: [2.0, 1.0] 285aa9a5b67SBarry Smith 286aa9a5b67SBarry SmithThis is a sensitive check that everything is working correctly. However, if this is wrong, where can I start? More fine-grained checks are available using the `-dmsnes_check` option. Using this for our $P_2-P_1$ example (the `p2p1` test), we have 287aa9a5b67SBarry Smith 288aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/output/ex69_p2p1.out 289aa9a5b67SBarry Smith``` 290aa9a5b67SBarry Smith 291aa9a5b67SBarry SmithThe first line records the discretization error for our exact solution. This means that we project our solution function into the finite element space and then calculate the $L_2$ norm of the difference between the exact solution and its projection. The norm is computed for each field separately. Next, PETSc calculates the residual using the projected exact solution as input. This should be small, and as the mesh is refined it should approach zero. Last, PETSc uses a Taylor test to try and determine how the error in the linear model scales as a function of the perturbation $h$. Thus, in a nonlinear situation we would expect 292aa9a5b67SBarry Smith 293aa9a5b67SBarry Smith> Taylor approximation converging at order 2.0 294aa9a5b67SBarry Smith 295aa9a5b67SBarry SmithIn this case, since the viscosity does not depend on the velocity or pressure fields, we detect that the linear model is exact 296aa9a5b67SBarry Smith 297aa9a5b67SBarry Smith> Function appears to be linear 298aa9a5b67SBarry Smith 299aa9a5b67SBarry SmithSuppose that we have made an error in the Jacobian. For instance, let us accidentally flip the sign of the pressure term in the momentum Jacobian. 300aa9a5b67SBarry Smith 301aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex69.c 302aa9a5b67SBarry Smith:end-at: '}' 303aa9a5b67SBarry Smith:start-at: static void stokes_momentum_pres_J 304aa9a5b67SBarry Smith``` 305aa9a5b67SBarry Smith 306aa9a5b67SBarry SmithWhen we run, we get a failure of the nonlinear solver. Our checking reveals that the Jacobian is wrong because it is converging at order 1 instead of 2, meaning the linear term is not correct in our model. 307aa9a5b67SBarry Smith 308aa9a5b67SBarry Smith```console 30930266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-snes_monitor -ksp_monitor_true_residual -ksp_converged_reason" 310aa9a5b67SBarry SmithL_2 Error: [0.000439127, 0.0376629] 311aa9a5b67SBarry SmithL_2 Residual: 0.0453958 312aa9a5b67SBarry SmithTaylor approximation converging at order 1.00 313aa9a5b67SBarry Smith 0 SNES Function norm 1.170604545948e-01 314aa9a5b67SBarry Smith 0 KSP preconditioned resid norm 4.965098891419e-01 true resid norm 1.170604545948e-01 ||r(i)||/||b|| 1.000000000000e+00 315aa9a5b67SBarry Smith 1 KSP preconditioned resid norm 9.236805404733e-11 true resid norm 1.460082233654e-12 ||r(i)||/||b|| 1.247289051378e-11 316aa9a5b67SBarry Smith Linear solve converged due to CONVERGED_ATOL iterations 1 317aa9a5b67SBarry Smith[0]PETSC ERROR: --------------------- Error Message -------------------------------------------------------------- 318aa9a5b67SBarry Smith[0]PETSC ERROR: 319aa9a5b67SBarry Smith[0]PETSC ERROR: SNESSolve has not converged 320aa9a5b67SBarry Smith``` 321aa9a5b67SBarry Smith 322aa9a5b67SBarry SmithIn order to track down the error, we can use `-snes_test_jacobian` which computes a finite difference approximation to the Jacobian and compares that to the analytic Jacobian. We ignore the first test, which occurs during our testing of the Jacobian, and look at the test that happens during the first Newton iterate. We see that the relative error in the Frobenius norm is about one percent, which indicates we have a real problem. 323aa9a5b67SBarry Smith 324aa9a5b67SBarry Smith```console 32530266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-snes_monitor -ksp_monitor_true_residual -ksp_converged_reason -snes_test_jacobian" 326aa9a5b67SBarry SmithL_2 Error: [0.000439127, 0.0376629] 327aa9a5b67SBarry SmithL_2 Residual: 0.0453958 328aa9a5b67SBarry Smith ---------- Testing Jacobian ------------- 329aa9a5b67SBarry Smith Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference 330aa9a5b67SBarry Smith of hand-coded and finite difference Jacobian entries greater than <threshold>. 331aa9a5b67SBarry Smith Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is 332aa9a5b67SBarry Smith O(1.e-8), the hand-coded Jacobian is probably correct. 333aa9a5b67SBarry Smith ||J - Jfd||_F/||J||_F = 136.793, ||J - Jfd||_F = 136.793 334aa9a5b67SBarry Smith ---------- Testing Jacobian for preconditioner ------------- 335aa9a5b67SBarry Smith ||J - Jfd||_F/||J||_F = 136.793, ||J - Jfd||_F = 136.793 336aa9a5b67SBarry SmithTaylor approximation converging at order 1.00 337aa9a5b67SBarry Smith 0 SNES Function norm 1.170604545948e-01 338aa9a5b67SBarry Smith ---------- Testing Jacobian ------------- 339aa9a5b67SBarry Smith ||J - Jfd||_F/||J||_F = 0.0119377, ||J - Jfd||_F = 1.63299 340aa9a5b67SBarry Smith ---------- Testing Jacobian for preconditioner ------------- 341aa9a5b67SBarry Smith ||J - Jfd||_F/||J||_F = 0.008471, ||J - Jfd||_F = 1.15873 342aa9a5b67SBarry Smith 0 KSP preconditioned resid norm 4.965098891419e-01 true resid norm 1.170604545948e-01 ||r(i)||/||b|| 1.000000000000e+00 343aa9a5b67SBarry Smith 1 KSP preconditioned resid norm 9.236804064319e-11 true resid norm 1.460031196842e-12 ||r(i)||/||b|| 1.247245452699e-11 344aa9a5b67SBarry Smith Linear solve converged due to CONVERGED_ATOL iterations 1 345aa9a5b67SBarry Smith[0]PETSC ERROR: --------------------- Error Message -------------------------------------------------------------- 346aa9a5b67SBarry Smith[0]PETSC ERROR: 347aa9a5b67SBarry Smith[0]PETSC ERROR: SNESSolve has not converged 348aa9a5b67SBarry Smith``` 349aa9a5b67SBarry Smith 3507addb90fSBarry SmithAt this point, we could just go back and check the code. However, PETSc will also print out the differences between the analytic and approximate Jacobians. When we give the `-snes_test_jacobian_view` option, the code will print both Jacobians (which we omit) and then their difference, and will also do this for the matrix used to construct the preconditioner (which we omit). It is clear from the output that the $u-p$ block of the Jacobian is wrong, and thus we know right where to look for our error. Moreover, if we look at the values in row 15, we see that the values just differ by a sign. 351aa9a5b67SBarry Smith 352aa9a5b67SBarry Smith```console 35330266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-snes_monitor -ksp_monitor_true_residual -ksp_converged_reason -snes_test_jacobian" 354aa9a5b67SBarry Smith Hand-coded minus finite-difference Jacobian with tolerance 1e-05 ---------- 355aa9a5b67SBarry SmithMat Object: 1 MPI process 356aa9a5b67SBarry Smith type: seqaij 357aa9a5b67SBarry Smithrow 0: 358aa9a5b67SBarry Smithrow 1: 359aa9a5b67SBarry Smithrow 2: 360aa9a5b67SBarry Smithrow 3: 361aa9a5b67SBarry Smithrow 4: 362aa9a5b67SBarry Smithrow 5: 363aa9a5b67SBarry Smithrow 6: 364aa9a5b67SBarry Smithrow 7: 365aa9a5b67SBarry Smithrow 8: 366aa9a5b67SBarry Smithrow 9: 367aa9a5b67SBarry Smithrow 10: 368aa9a5b67SBarry Smithrow 11: 369aa9a5b67SBarry Smithrow 12: 370aa9a5b67SBarry Smithrow 13: 371aa9a5b67SBarry Smithrow 14: 372aa9a5b67SBarry Smithrow 15: (0, 0.166667) (2, -0.166667) 373aa9a5b67SBarry Smithrow 16: (0, 0.166667) (2, -0.166667) (5, 0.166667) (8, -0.166667) 374aa9a5b67SBarry Smithrow 17: (0, 0.166667) (2, 0.166667) (5, -0.166667) (8, -0.166667) 375aa9a5b67SBarry Smithrow 18: (0, 0.166667) (5, -0.166667) 376aa9a5b67SBarry Smithrow 19: (5, 0.166667) (8, -0.166667) (11, 0.166667) (13, -0.166667) 377aa9a5b67SBarry Smithrow 20: (5, 0.166667) (8, 0.166667) (11, -0.166667) (13, -0.166667) 378aa9a5b67SBarry Smithrow 21: (5, 0.166667) (11, -0.166667) 379aa9a5b67SBarry Smithrow 22: (5, 0.333333) (8, -0.333333) 380aa9a5b67SBarry Smithrow 23: (2, 0.166667) (5, 0.166667) (8, -0.166667) (11, -0.166667) 381aa9a5b67SBarry Smithrow 24: (2, 0.166667) (3, -0.166667) (5, 0.166667) (8, -0.166667) 382aa9a5b67SBarry Smithrow 25: (2, 0.333333) (8, -0.333333) 383aa9a5b67SBarry Smithrow 26: (2, 0.166667) (3, -0.166667) (8, 0.166667) (10, -0.166667) 384aa9a5b67SBarry Smithrow 27: (2, 0.166667) (3, 0.166667) (8, -0.166667) (10, -0.166667) 385aa9a5b67SBarry Smithrow 28: (3, 0.166667) (10, -0.166667) 386aa9a5b67SBarry Smithrow 29: (8, 0.333333) (10, -0.333333) 387aa9a5b67SBarry Smithrow 30: (3, 0.166667) (8, 0.166667) (10, -0.166667) (13, -0.166667) 388aa9a5b67SBarry Smithrow 31: (2, 0.166667) (3, -0.166667) 389aa9a5b67SBarry Smithrow 32: (8, 0.166667) (10, -0.166667) (13, 0.166667) (14, -0.166667) 390aa9a5b67SBarry Smithrow 33: (8, 0.166667) (10, 0.166667) (13, -0.166667) (14, -0.166667) 391aa9a5b67SBarry Smithrow 34: (10, 0.166667) (14, -0.166667) 392aa9a5b67SBarry Smithrow 35: (13, 0.166667) (14, -0.166667) 393aa9a5b67SBarry Smithrow 36: (8, 0.166667) (10, -0.166667) (11, 0.166667) (13, -0.166667) 394aa9a5b67SBarry Smithrow 37: (8, 0.333333) (13, -0.333333) 395aa9a5b67SBarry Smithrow 38: (11, 0.166667) (13, -0.166667) 396aa9a5b67SBarry Smith 0 KSP preconditioned resid norm 4.965098891419e-01 true resid norm 1.170604545948e-01 ||r(i)||/||b|| 1.000000000000e+00 397aa9a5b67SBarry Smith 1 KSP preconditioned resid norm 9.236804067326e-11 true resid norm 1.460031196842e-12 ||r(i)||/||b|| 1.247245452699e-11 398aa9a5b67SBarry Smith Linear solve converged due to CONVERGED_ATOL iterations 1 399aa9a5b67SBarry Smith [0]PETSC ERROR: --------------------- Error Message -------------------------------------------------------------- 400aa9a5b67SBarry Smith [0]PETSC ERROR: 401aa9a5b67SBarry Smith [0]PETSC ERROR: SNESSolve has not converged 402aa9a5b67SBarry Smith``` 403aa9a5b67SBarry Smith 404aa9a5b67SBarry SmithCan we see that the Schur complement of Q1-P0 is ill-conditioned? 405aa9a5b67SBarry Smith 406aa9a5b67SBarry Smith### Optimizing the Solver 407aa9a5b67SBarry Smith 408aa9a5b67SBarry SmithIn order to see exactly what solver we have employed, we can use the `-snes_view` option. When checking $P_2-P_1$ convergence, we use an exact solver, but it must have several parts in order to deal with the saddle-point in the Jacobian. Using the test system to provide our extra option, we get 409aa9a5b67SBarry Smith 410aa9a5b67SBarry Smith```console 41130266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-snes_view" 412aa9a5b67SBarry SmithSNES Object: 1 MPI process 413aa9a5b67SBarry Smith type: newtonls 414aa9a5b67SBarry Smith maximum iterations=50, maximum function evaluations=10000 415aa9a5b67SBarry Smith tolerances: relative=1e-08, absolute=1e-50, solution=1e-08 416aa9a5b67SBarry Smith total number of linear solver iterations=1 417aa9a5b67SBarry Smith total number of function evaluations=2 418aa9a5b67SBarry Smith norm schedule ALWAYS 419aa9a5b67SBarry Smith SNESLineSearch Object: 1 MPI process 420aa9a5b67SBarry Smith type: bt 421aa9a5b67SBarry Smith interpolation: cubic 422aa9a5b67SBarry Smith alpha=1.000000e-04 423aa9a5b67SBarry Smith maxstep=1.000000e+08, minlambda=1.000000e-12 424aa9a5b67SBarry Smith tolerances: relative=1.000000e-08, absolute=1.000000e-15, lambda=1.000000e-08 425aa9a5b67SBarry Smith maximum iterations=40 426aa9a5b67SBarry Smith KSP Object: 1 MPI process 427aa9a5b67SBarry Smith type: gmres 428f971d498SPierre Jolivet restart=30, using classical (unmodified) Gram-Schmidt orthogonalization with no iterative refinement 429*143f2514SPierre Jolivet happy breakdown tolerance=1e-30 430aa9a5b67SBarry Smith maximum iterations=10000, initial guess is zero 431aa9a5b67SBarry Smith tolerances: relative=1e-09, absolute=1e-10, divergence=10000. 432aa9a5b67SBarry Smith left preconditioning 433aa9a5b67SBarry Smith using PRECONDITIONED norm type for convergence test 434aa9a5b67SBarry Smith PC Object: 1 MPI process 435aa9a5b67SBarry Smith type: fieldsplit 436aa9a5b67SBarry Smith FieldSplit with Schur preconditioner, factorization FULL 437aa9a5b67SBarry Smith Preconditioner for the Schur complement formed from A11 438aa9a5b67SBarry Smith Split info: 439aa9a5b67SBarry Smith Split number 0 Defined by IS 440aa9a5b67SBarry Smith Split number 1 Defined by IS 441aa9a5b67SBarry Smith KSP solver for A00 block 442aa9a5b67SBarry Smith KSP Object: (fieldsplit_velocity_) 1 MPI process 443aa9a5b67SBarry Smith type: gmres 444f971d498SPierre Jolivet restart=30, using classical (unmodified) Gram-Schmidt orthogonalization with no iterative refinement 445*143f2514SPierre Jolivet happy breakdown tolerance=1e-30 446aa9a5b67SBarry Smith maximum iterations=10000, initial guess is zero 447aa9a5b67SBarry Smith tolerances: relative=1e-05, absolute=1e-50, divergence=10000. 448aa9a5b67SBarry Smith left preconditioning 449aa9a5b67SBarry Smith using PRECONDITIONED norm type for convergence test 450aa9a5b67SBarry Smith PC Object: (fieldsplit_velocity_) 1 MPI process 451aa9a5b67SBarry Smith type: lu 452aa9a5b67SBarry Smith out-of-place factorization 453aa9a5b67SBarry Smith tolerance for zero pivot 2.22045e-14 454aa9a5b67SBarry Smith matrix ordering: nd 455aa9a5b67SBarry Smith factor fill ratio given 5., needed 1.15761 456ecf3d421SBarry Smith Factored matrix: 457aa9a5b67SBarry Smith Mat Object: 1 MPI process 458aa9a5b67SBarry Smith type: seqaij 459aa9a5b67SBarry Smith rows=30, cols=30 460aa9a5b67SBarry Smith package used to perform factorization: petsc 461aa9a5b67SBarry Smith total: nonzeros=426, allocated nonzeros=426 462aa9a5b67SBarry Smith using I-node routines: found 17 nodes, limit used is 5 463aa9a5b67SBarry Smith linear system matrix followed by preconditioner matrix: 464aa9a5b67SBarry Smith Mat Object: 1 MPI process 465aa9a5b67SBarry Smith type: seqaij 466aa9a5b67SBarry Smith rows=30, cols=30 467aa9a5b67SBarry Smith total: nonzeros=368, allocated nonzeros=368 468aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 469aa9a5b67SBarry Smith using I-node routines: found 20 nodes, limit used is 5 470aa9a5b67SBarry Smith Mat Object: (fieldsplit_velocity_) 1 MPI process 471aa9a5b67SBarry Smith type: seqaij 472aa9a5b67SBarry Smith rows=30, cols=30 473aa9a5b67SBarry Smith total: nonzeros=368, allocated nonzeros=368 474aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 475aa9a5b67SBarry Smith using I-node routines: found 20 nodes, limit used is 5 476aa9a5b67SBarry Smith KSP solver for S = A11 - A10 inv(A00) A01 477aa9a5b67SBarry Smith KSP Object: (fieldsplit_pressure_) 1 MPI process 478aa9a5b67SBarry Smith type: gmres 479f971d498SPierre Jolivet restart=30, using classical (unmodified) Gram-Schmidt orthogonalization with no iterative refinement 480*143f2514SPierre Jolivet happy breakdown tolerance=1e-30 481aa9a5b67SBarry Smith maximum iterations=10000, initial guess is zero 482aa9a5b67SBarry Smith tolerances: relative=1e-09, absolute=1e-50, divergence=10000. 483aa9a5b67SBarry Smith left preconditioning 484aa9a5b67SBarry Smith using PRECONDITIONED norm type for convergence test 485aa9a5b67SBarry Smith PC Object: (fieldsplit_pressure_) 1 MPI process 486aa9a5b67SBarry Smith type: lu 487aa9a5b67SBarry Smith out-of-place factorization 488aa9a5b67SBarry Smith tolerance for zero pivot 2.22045e-14 489aa9a5b67SBarry Smith matrix ordering: nd 490aa9a5b67SBarry Smith factor fill ratio given 5., needed 1.2439 491ecf3d421SBarry Smith Factored matrix: 492aa9a5b67SBarry Smith Mat Object: 1 MPI process 493aa9a5b67SBarry Smith type: seqaij 494aa9a5b67SBarry Smith rows=9, cols=9 495aa9a5b67SBarry Smith package used to perform factorization: petsc 496aa9a5b67SBarry Smith total: nonzeros=51, allocated nonzeros=51 497aa9a5b67SBarry Smith not using I-node routines 498aa9a5b67SBarry Smith linear system matrix followed by preconditioner matrix: 499aa9a5b67SBarry Smith Mat Object: (fieldsplit_pressure_) 1 MPI process 500aa9a5b67SBarry Smith type: schurcomplement 501aa9a5b67SBarry Smith rows=9, cols=9 502aa9a5b67SBarry Smith has attached null space 503aa9a5b67SBarry Smith Schur complement A11 - A10 inv(A00) A01 504aa9a5b67SBarry Smith A11 505aa9a5b67SBarry Smith Mat Object: 1 MPI process 506aa9a5b67SBarry Smith type: seqaij 507aa9a5b67SBarry Smith rows=9, cols=9 508aa9a5b67SBarry Smith total: nonzeros=41, allocated nonzeros=41 509aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 510aa9a5b67SBarry Smith has attached null space 511aa9a5b67SBarry Smith not using I-node routines 512aa9a5b67SBarry Smith A10 513aa9a5b67SBarry Smith Mat Object: 1 MPI process 514aa9a5b67SBarry Smith type: seqaij 515aa9a5b67SBarry Smith rows=9, cols=30 516aa9a5b67SBarry Smith total: nonzeros=122, allocated nonzeros=122 517aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 518aa9a5b67SBarry Smith not using I-node routines 519aa9a5b67SBarry Smith KSP solver for A00 block viewable with the additional option -fc_fieldsplit_velocity_ksp_view 520aa9a5b67SBarry Smith A01 521aa9a5b67SBarry Smith Mat Object: 1 MPI process 522aa9a5b67SBarry Smith type: seqaij 523aa9a5b67SBarry Smith rows=30, cols=9 524aa9a5b67SBarry Smith total: nonzeros=122, allocated nonzeros=122 525aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 526aa9a5b67SBarry Smith using I-node routines: found 20 nodes, limit used is 5 527aa9a5b67SBarry Smith Mat Object: (fieldsplit_pressure_) 1 MPI process 528aa9a5b67SBarry Smith type: seqaij 529aa9a5b67SBarry Smith rows=9, cols=9 530aa9a5b67SBarry Smith total: nonzeros=41, allocated nonzeros=41 531aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 532aa9a5b67SBarry Smith not using I-node routines 533aa9a5b67SBarry Smith linear system matrix followed by preconditioner matrix: 534aa9a5b67SBarry Smith Mat Object: 1 MPI process 535aa9a5b67SBarry Smith type: seqaij 536aa9a5b67SBarry Smith rows=39, cols=39 537aa9a5b67SBarry Smith total: nonzeros=653, allocated nonzeros=653 538aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 539aa9a5b67SBarry Smith has attached null space 540aa9a5b67SBarry Smith using I-node routines: found 24 nodes, limit used is 5 541aa9a5b67SBarry Smith Mat Object: (prec_) 1 MPI process 542aa9a5b67SBarry Smith type: seqaij 543aa9a5b67SBarry Smith rows=39, cols=39 544aa9a5b67SBarry Smith total: nonzeros=653, allocated nonzeros=653 545aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 546aa9a5b67SBarry Smith using I-node routines: found 24 nodes, limit used is 5 547aa9a5b67SBarry Smith``` 548aa9a5b67SBarry Smith 549aa9a5b67SBarry SmithGoing through this piece-by-piece, we can see all the parts of our solver. At the top level, we have a `SNES` using Newton's method 550aa9a5b67SBarry Smith 551aa9a5b67SBarry Smith```console 55230266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-snes_view" 553aa9a5b67SBarry SmithSNES Object: 1 MPI process 554aa9a5b67SBarry Smith type: newtonls 555aa9a5b67SBarry Smith maximum iterations=50, maximum function evaluations=10000 556aa9a5b67SBarry Smith tolerances: relative=1e-08, absolute=1e-50, solution=1e-08 557aa9a5b67SBarry Smith total number of linear solver iterations=1 558aa9a5b67SBarry Smith total number of function evaluations=2 559aa9a5b67SBarry Smith norm schedule ALWAYS 560aa9a5b67SBarry Smith SNESLineSearch Object: 1 MPI process 561aa9a5b67SBarry Smith type: bt 562aa9a5b67SBarry Smith interpolation: cubic 563aa9a5b67SBarry Smith alpha=1.000000e-04 564aa9a5b67SBarry Smith maxstep=1.000000e+08, minlambda=1.000000e-12 565aa9a5b67SBarry Smith tolerances: relative=1.000000e-08, absolute=1.000000e-15, lambda=1.000000e-08 566aa9a5b67SBarry Smith maximum iterations=40 567aa9a5b67SBarry Smith``` 568aa9a5b67SBarry Smith 569aa9a5b67SBarry SmithFor each nonlinear step, we use `KSPGMRES` to solve the Newton equation, preconditioned by `PCFIELDSPLIT`. We split the problem into two blocks, with the split determined by our `DM`, and combine those blocks using a Schur complement. The Schur complement is faithful since we use the `FULL` factorization type. 570aa9a5b67SBarry Smith 571aa9a5b67SBarry Smith```console 57230266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-snes_view" 573aa9a5b67SBarry Smith KSP Object: 1 MPI process 574aa9a5b67SBarry Smith type: gmres 575f971d498SPierre Jolivet restart=30, using classical (unmodified) Gram-Schmidt orthogonalization with no iterative refinement 576*143f2514SPierre Jolivet happy breakdown tolerance=1e-30 577aa9a5b67SBarry Smith maximum iterations=10000, initial guess is zero 578aa9a5b67SBarry Smith tolerances: relative=1e-09, absolute=1e-10, divergence=10000. 579aa9a5b67SBarry Smith left preconditioning 580aa9a5b67SBarry Smith using PRECONDITIONED norm type for convergence test 581aa9a5b67SBarry Smith PC Object: 1 MPI process 582aa9a5b67SBarry Smith type: fieldsplit 583aa9a5b67SBarry Smith FieldSplit with Schur preconditioner, factorization FULL 584aa9a5b67SBarry Smith Preconditioner for the Schur complement formed from A11 585aa9a5b67SBarry Smith Split info: 586aa9a5b67SBarry Smith Split number 0 Defined by IS 587aa9a5b67SBarry Smith Split number 1 Defined by IS 588aa9a5b67SBarry Smith``` 589aa9a5b67SBarry Smith 5907addb90fSBarry SmithWe form the preconditioner for the Schur complement from the (1,1) block of our matrix used to construct the preconditioner, which we have set to be the viscosity-weighted mass matrix 591aa9a5b67SBarry Smith 592aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex69.c 593aa9a5b67SBarry Smith:end-before: /* 594aa9a5b67SBarry Smith:start-at: static void stokes_identity_J_kx 595aa9a5b67SBarry Smith``` 596aa9a5b67SBarry Smith 5977addb90fSBarry SmithThe solver for the first block, representing the velocity, is GMRES/LU. Note that the prefix is `fieldsplit_velocity_`, constructed automatically from the name of the field in our DM. Also note that there are two matrices, one from our original matrix, and one from our matrix used to construct the preconditioner, but they are identical. In an optimized, scalable solver, this block would likely be solved by multigrid, but here we use LU for verification purposes. 598aa9a5b67SBarry Smith 599aa9a5b67SBarry Smith```console 60030266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-snes_view" 601aa9a5b67SBarry Smith KSP solver for A00 block 602aa9a5b67SBarry Smith KSP Object: (fieldsplit_velocity_) 1 MPI process 603aa9a5b67SBarry Smith type: gmres 604f971d498SPierre Jolivet restart=30, using classical (unmodified) Gram-Schmidt orthogonalization with no iterative refinement 605*143f2514SPierre Jolivet happy breakdown tolerance=1e-30 606aa9a5b67SBarry Smith maximum iterations=10000, initial guess is zero 607aa9a5b67SBarry Smith tolerances: relative=1e-05, absolute=1e-50, divergence=10000. 608aa9a5b67SBarry Smith left preconditioning 609aa9a5b67SBarry Smith using PRECONDITIONED norm type for convergence test 610aa9a5b67SBarry Smith PC Object: (fieldsplit_velocity_) 1 MPI process 611aa9a5b67SBarry Smith type: lu 612aa9a5b67SBarry Smith out-of-place factorization 613aa9a5b67SBarry Smith tolerance for zero pivot 2.22045e-14 614aa9a5b67SBarry Smith matrix ordering: nd 615aa9a5b67SBarry Smith factor fill ratio given 5., needed 1.15761 616ecf3d421SBarry Smith Factored matrix: 617aa9a5b67SBarry Smith Mat Object: 1 MPI process 618aa9a5b67SBarry Smith type: seqaij 619aa9a5b67SBarry Smith rows=30, cols=30 620aa9a5b67SBarry Smith package used to perform factorization: petsc 621aa9a5b67SBarry Smith total: nonzeros=426, allocated nonzeros=426 622aa9a5b67SBarry Smith using I-node routines: found 17 nodes, limit used is 5 623aa9a5b67SBarry Smith linear system matrix followed by preconditioner matrix: 624aa9a5b67SBarry Smith Mat Object: 1 MPI process 625aa9a5b67SBarry Smith type: seqaij 626aa9a5b67SBarry Smith rows=30, cols=30 627aa9a5b67SBarry Smith total: nonzeros=368, allocated nonzeros=368 628aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 629aa9a5b67SBarry Smith using I-node routines: found 20 nodes, limit used is 5 630aa9a5b67SBarry Smith Mat Object: (fieldsplit_velocity_) 1 MPI process 631aa9a5b67SBarry Smith type: seqaij 632aa9a5b67SBarry Smith rows=30, cols=30 633aa9a5b67SBarry Smith total: nonzeros=368, allocated nonzeros=368 634aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 635aa9a5b67SBarry Smith using I-node routines: found 20 nodes, limit used is 5 636aa9a5b67SBarry Smith``` 637aa9a5b67SBarry Smith 638aa9a5b67SBarry SmithThe solver for the second block, with prefix `fieldsplit_pressure_`, is also GMRES/LU, however we cannot factor the Schur complement operator since we never explicitly assemble it. Thus we assemble the viscosity-weighted mass matrix on the pressure space as an approximation. Notice that the Schur complement has the velocity solver embedded in it. 639aa9a5b67SBarry Smith 640aa9a5b67SBarry Smith```console 64130266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-snes_view" 642aa9a5b67SBarry Smith KSP solver for S = A11 - A10 inv(A00) A01 643aa9a5b67SBarry Smith KSP Object: (fieldsplit_pressure_) 1 MPI process 644aa9a5b67SBarry Smith type: gmres 645f971d498SPierre Jolivet restart=30, using classical (unmodified) Gram-Schmidt orthogonalization with no iterative refinement 646*143f2514SPierre Jolivet happy breakdown tolerance=1e-30 647aa9a5b67SBarry Smith maximum iterations=10000, initial guess is zero 648aa9a5b67SBarry Smith tolerances: relative=1e-09, absolute=1e-50, divergence=10000. 649aa9a5b67SBarry Smith left preconditioning 650aa9a5b67SBarry Smith using PRECONDITIONED norm type for convergence test 651aa9a5b67SBarry Smith PC Object: (fieldsplit_pressure_) 1 MPI process 652aa9a5b67SBarry Smith type: lu 653aa9a5b67SBarry Smith out-of-place factorization 654aa9a5b67SBarry Smith tolerance for zero pivot 2.22045e-14 655aa9a5b67SBarry Smith matrix ordering: nd 656aa9a5b67SBarry Smith factor fill ratio given 5., needed 1.2439 657ecf3d421SBarry Smith Factored matrix: 658aa9a5b67SBarry Smith Mat Object: 1 MPI process 659aa9a5b67SBarry Smith type: seqaij 660aa9a5b67SBarry Smith rows=9, cols=9 661aa9a5b67SBarry Smith package used to perform factorization: petsc 662aa9a5b67SBarry Smith total: nonzeros=51, allocated nonzeros=51 663aa9a5b67SBarry Smith not using I-node routines 664aa9a5b67SBarry Smith linear system matrix followed by preconditioner matrix: 665aa9a5b67SBarry Smith Mat Object: (fieldsplit_pressure_) 1 MPI process 666aa9a5b67SBarry Smith type: schurcomplement 667aa9a5b67SBarry Smith rows=9, cols=9 668aa9a5b67SBarry Smith has attached null space 669aa9a5b67SBarry Smith Schur complement A11 - A10 inv(A00) A01 670aa9a5b67SBarry Smith A11 671aa9a5b67SBarry Smith Mat Object: 1 MPI process 672aa9a5b67SBarry Smith type: seqaij 673aa9a5b67SBarry Smith rows=9, cols=9 674aa9a5b67SBarry Smith total: nonzeros=41, allocated nonzeros=41 675aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 676aa9a5b67SBarry Smith has attached null space 677aa9a5b67SBarry Smith not using I-node routines 678aa9a5b67SBarry Smith A10 679aa9a5b67SBarry Smith Mat Object: 1 MPI process 680aa9a5b67SBarry Smith type: seqaij 681aa9a5b67SBarry Smith rows=9, cols=30 682aa9a5b67SBarry Smith total: nonzeros=122, allocated nonzeros=122 683aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 684aa9a5b67SBarry Smith not using I-node routines 685aa9a5b67SBarry Smith KSP of A00 686aa9a5b67SBarry Smith KSP Object: (fieldsplit_velocity_) 1 MPI process 687aa9a5b67SBarry Smith type: gmres 688f971d498SPierre Jolivet restart=30, using classical (unmodified) Gram-Schmidt orthogonalization with no iterative refinement 689*143f2514SPierre Jolivet happy breakdown tolerance=1e-30 690aa9a5b67SBarry Smith maximum iterations=10000, initial guess is zero 691aa9a5b67SBarry Smith tolerances: relative=1e-05, absolute=1e-50, divergence=10000. 692aa9a5b67SBarry Smith left preconditioning 693aa9a5b67SBarry Smith using PRECONDITIONED norm type for convergence test 694aa9a5b67SBarry Smith PC Object: (fieldsplit_velocity_) 1 MPI process 695aa9a5b67SBarry Smith type: lu 696aa9a5b67SBarry Smith out-of-place factorization 697aa9a5b67SBarry Smith tolerance for zero pivot 2.22045e-14 698aa9a5b67SBarry Smith matrix ordering: nd 699aa9a5b67SBarry Smith factor fill ratio given 5., needed 1.15761 700ecf3d421SBarry Smith Factored matrix: 701aa9a5b67SBarry Smith Mat Object: 1 MPI process 702aa9a5b67SBarry Smith type: seqaij 703aa9a5b67SBarry Smith rows=30, cols=30 704aa9a5b67SBarry Smith package used to perform factorization: petsc 705aa9a5b67SBarry Smith total: nonzeros=426, allocated nonzeros=426 706aa9a5b67SBarry Smith using I-node routines: found 17 nodes, limit used is 5 707aa9a5b67SBarry Smith linear system matrix followed by preconditioner matrix: 708aa9a5b67SBarry Smith Mat Object: 1 MPI process 709aa9a5b67SBarry Smith type: seqaij 710aa9a5b67SBarry Smith rows=30, cols=30 711aa9a5b67SBarry Smith total: nonzeros=368, allocated nonzeros=368 712aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 713aa9a5b67SBarry Smith using I-node routines: found 20 nodes, limit used is 5 714aa9a5b67SBarry Smith Mat Object: (fieldsplit_velocity_) 1 MPI process 715aa9a5b67SBarry Smith type: seqaij 716aa9a5b67SBarry Smith rows=30, cols=30 717aa9a5b67SBarry Smith total: nonzeros=368, allocated nonzeros=368 718aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 719aa9a5b67SBarry Smith using I-node routines: found 20 nodes, limit used is 5 720aa9a5b67SBarry Smith A01 721aa9a5b67SBarry Smith Mat Object: 1 MPI process 722aa9a5b67SBarry Smith type: seqaij 723aa9a5b67SBarry Smith rows=30, cols=9 724aa9a5b67SBarry Smith total: nonzeros=122, allocated nonzeros=122 725aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 726aa9a5b67SBarry Smith using I-node routines: found 20 nodes, limit used is 5 727aa9a5b67SBarry Smith Mat Object: (fieldsplit_pressure_) 1 MPI process 728aa9a5b67SBarry Smith type: seqaij 729aa9a5b67SBarry Smith rows=9, cols=9 730aa9a5b67SBarry Smith total: nonzeros=41, allocated nonzeros=41 731aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 732aa9a5b67SBarry Smith not using I-node routines 733aa9a5b67SBarry Smith``` 734aa9a5b67SBarry Smith 7357addb90fSBarry SmithFinally, the SNES viewer reports the system matrix and matrix from which the preconditioner is constructed 736aa9a5b67SBarry Smith 737aa9a5b67SBarry Smith```console 73830266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-snes_view" 739aa9a5b67SBarry Smith linear system matrix followed by preconditioner matrix: 740aa9a5b67SBarry Smith Mat Object: 1 MPI process 741aa9a5b67SBarry Smith type: seqaij 742aa9a5b67SBarry Smith rows=39, cols=39 743aa9a5b67SBarry Smith total: nonzeros=653, allocated nonzeros=653 744aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 745aa9a5b67SBarry Smith has attached null space 746aa9a5b67SBarry Smith using I-node routines: found 24 nodes, limit used is 5 747aa9a5b67SBarry Smith Mat Object: (prec_) 1 MPI process 748aa9a5b67SBarry Smith type: seqaij 749aa9a5b67SBarry Smith rows=39, cols=39 750aa9a5b67SBarry Smith total: nonzeros=653, allocated nonzeros=653 751aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 752aa9a5b67SBarry Smith using I-node routines: found 24 nodes, limit used is 5 753aa9a5b67SBarry Smith``` 754aa9a5b67SBarry Smith 7557addb90fSBarry SmithWe see that they have the same nonzero pattern, even though the matrix used to construct the preconditioner only contains the diagonal blocks. This is because zeros were inserted to define the nonzero structure. We can remove these nonzeros by telling the DM not to insert zero at preallocation time, and also telling the matrix itself to ignore the zeros from the assembly process. 756aa9a5b67SBarry Smith 757aa9a5b67SBarry Smith```console 75830266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-snes_view -dm_preallocate_only -prec_mat_ignore_zero_entries" 759aa9a5b67SBarry Smith linear system matrix followed by preconditioner matrix: 760aa9a5b67SBarry Smith Mat Object: 1 MPI process 761aa9a5b67SBarry Smith type: seqaij 762aa9a5b67SBarry Smith rows=39, cols=39 763aa9a5b67SBarry Smith total: nonzeros=653, allocated nonzeros=653 764aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 765aa9a5b67SBarry Smith has attached null space 766aa9a5b67SBarry Smith using I-node routines: found 24 nodes, limit used is 5 767aa9a5b67SBarry Smith Mat Object: (prec_) 1 MPI process 768aa9a5b67SBarry Smith type: seqaij 769aa9a5b67SBarry Smith rows=39, cols=39 770aa9a5b67SBarry Smith total: nonzeros=409, allocated nonzeros=653 771aa9a5b67SBarry Smith total number of mallocs used during MatSetValues calls=0 772aa9a5b67SBarry Smith using I-node routines: found 29 nodes, limit used is 5 773aa9a5b67SBarry Smith``` 774aa9a5b67SBarry Smith 775aa9a5b67SBarry SmithWe can see a sparsity portrait of the system and preconditioning matrices if the installation supports X-windows visualization 776aa9a5b67SBarry Smith 777aa9a5b67SBarry Smith```console 77830266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-ksp_view_mat draw -prec_mat_view draw -draw_pause -1" 77930266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-ksp_view_mat draw -prec_mat_view draw -draw_save $PETSC_DIR/mat.png" 78030266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-dm_preallocate_only -mat_ignore_zero_entries -prec_mat_ignore_zero_entries -ksp_view_mat draw -prec_mat_view draw -draw_save $PETSC_DIR/mat_sparse.png" 781aa9a5b67SBarry Smith``` 782aa9a5b67SBarry Smith 783aa9a5b67SBarry Smith```{eval-rst} 784aa9a5b67SBarry Smith.. list-table:: 785aa9a5b67SBarry Smith 786aa9a5b67SBarry Smith * - .. figure:: /images/tutorials/physics/stokes_p2p1_sys_mat.png 787aa9a5b67SBarry Smith 788aa9a5b67SBarry Smith System matrix 789aa9a5b67SBarry Smith 790aa9a5b67SBarry Smith - .. figure:: /images/tutorials/physics/stokes_p2p1_sys_mat_sparse.png 791aa9a5b67SBarry Smith 792aa9a5b67SBarry Smith System matrix with sparse stencil 793aa9a5b67SBarry Smith 794aa9a5b67SBarry Smith * - .. figure:: /images/tutorials/physics/stokes_p2p1_prec_mat.png 795aa9a5b67SBarry Smith 7967addb90fSBarry Smith Matrix used to construct the preconditioner 797aa9a5b67SBarry Smith 798aa9a5b67SBarry Smith - .. figure:: /images/tutorials/physics/stokes_p2p1_prec_mat_sparse.png 799aa9a5b67SBarry Smith 8007addb90fSBarry Smith Matrix used to construct the preconditioner with sparse stencil 801aa9a5b67SBarry Smith``` 802aa9a5b67SBarry Smith 803aa9a5b67SBarry SmithIf we want to check the convergence of the solver, we can also do that using options. Both the linear and nonlinear solvers converge in a single iteration, which is exactly what we want. In order to have this happen, we must have the tolerance on both the outer KSP solver and the inner Schur complement solver be low enough. Notice that the sure complement solver is used twice, and converges in seven iterates each time. 804aa9a5b67SBarry Smith 805aa9a5b67SBarry Smith```console 80630266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-snes_monitor -ksp_monitor_true_residual -ksp_converged_reason -fieldsplit_pressure_ksp_converged_reason" 807aa9a5b67SBarry Smith0 SNES Function norm 1.170604545948e-01 808aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 7 809aa9a5b67SBarry Smith 0 KSP preconditioned resid norm 4.965098891419e-01 true resid norm 1.170604545948e-01 ||r(i)||/||b|| 1.000000000000e+00 810aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 7 811aa9a5b67SBarry Smith 1 KSP preconditioned resid norm 9.236813926190e-11 true resid norm 1.460072673561e-12 ||r(i)||/||b|| 1.247280884579e-11 812aa9a5b67SBarry SmithLinear solve converged due to CONVERGED_ATOL iterations 1 813aa9a5b67SBarry Smith1 SNES Function norm 1.460070661322e-12 814aa9a5b67SBarry Smith``` 815aa9a5b67SBarry Smith 816aa9a5b67SBarry SmithWe can look at the scalability of the solve by refining the mesh. We see that the Schur complement solve looks robust to grid refinement. 817aa9a5b67SBarry Smith 818aa9a5b67SBarry Smith```console 81930266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-dm_refine 2 -snes_monitor -ksp_monitor_true_residual -ksp_converged_reason -fieldsplit_pressure_ksp_converged_reason" 820aa9a5b67SBarry Smith0 SNES Function norm 3.503062983054e-02 821aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 8 822aa9a5b67SBarry Smith 0 KSP preconditioned resid norm 9.943095979973e-01 true resid norm 3.503062983054e-02 ||r(i)||/||b|| 1.000000000000e+00 823aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 8 824aa9a5b67SBarry Smith 1 KSP preconditioned resid norm 1.148772629230e-10 true resid norm 2.693482255004e-13 ||r(i)||/||b|| 7.688934706664e-12 825aa9a5b67SBarry SmithLinear solve converged due to CONVERGED_RTOL iterations 1 826aa9a5b67SBarry Smith1 SNES Function norm 2.693649920420e-13 82730266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-dm_refine 4 -snes_monitor -ksp_monitor_true_residual -ksp_converged_reason -fieldsplit_pressure_ksp_converged_reason" 828aa9a5b67SBarry Smith0 SNES Function norm 8.969202737759e-03 829aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 6 830aa9a5b67SBarry Smith 0 KSP preconditioned resid norm 3.322375727167e+00 true resid norm 8.969202737759e-03 ||r(i)||/||b|| 1.000000000000e+00 831aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 6 832aa9a5b67SBarry Smith 1 KSP preconditioned resid norm 6.112282404006e-10 true resid norm 8.543800889926e-14 ||r(i)||/||b|| 9.525708292843e-12 833aa9a5b67SBarry SmithLinear solve converged due to CONVERGED_RTOL iterations 1 834aa9a5b67SBarry Smith1 SNES Function norm 8.543893996362e-14 835aa9a5b67SBarry Smith``` 836aa9a5b67SBarry Smith 837aa9a5b67SBarry SmithStarting off with an exact solver allows us to check that the discretization, equations, and boundary conditions are correct. Moreover, choosing the Schur complement formulation, rather than a sparse direct solve, gives us a path to incremental boost the scalability. Our first step will be to replace the direct solve of the momentum operator, which has cost superlinear in $N$, with a more scalable alternative. Since the operator is still elliptic, despite the viscosity variation, we should be able to use some form of multigrid. We will start with algebraic multigrid because it handles coefficient variation well, even if the setup time is larger than the geometric variant. 838aa9a5b67SBarry Smith 839aa9a5b67SBarry Smith```console 84030266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1" EXTRA_OPTIONS="-dm_refine 2 -snes_monitor -ksp_monitor_true_residual -ksp_converged_reason -fieldsplit_pressure_ksp_converged_reason -fieldsplit_velocity_pc_type gamg -fieldsplit_velocity_ksp_converged_reason" 841aa9a5b67SBarry Smith0 SNES Function norm 3.503062983054e-02 842aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 8 843aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 844aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 845aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 846aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 10 847aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 848aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 849aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 8 850aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 8 851aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 8 852aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 853aa9a5b67SBarry Smith 0 KSP preconditioned resid norm 9.943097452179e-01 true resid norm 3.503062983054e-02 ||r(i)||/||b|| 1.000000000000e+00 854aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 8 855aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 856aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 857aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 858aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 10 859aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 860aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 861aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 8 862aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 8 863aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 8 864aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 865aa9a5b67SBarry Smith 1 KSP preconditioned resid norm 1.503326145261e-05 true resid norm 1.089276827085e-06 ||r(i)||/||b|| 3.109498265814e-05 866aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 10 867aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 868aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 869aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 870aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 871aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 872aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 873aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 874aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 875aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 9 876aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 9 877aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 10 878aa9a5b67SBarry Smith 2 KSP preconditioned resid norm 1.353007845554e-10 true resid norm 6.056095141823e-11 ||r(i)||/||b|| 1.728799959098e-09 879aa9a5b67SBarry SmithLinear solve converged due to CONVERGED_RTOL iterations 2 880aa9a5b67SBarry Smith1 SNES Function norm 6.056096909907e-11 881aa9a5b67SBarry Smith``` 882aa9a5b67SBarry Smith 883aa9a5b67SBarry SmithThis looks alright, but the number of iterates grows with refinement. At 3 refinements, it is 16, 30 at 4 refinements, and 70 at 5 refinements. Increasing the number of smoother iterates to four, `-fieldsplit_velocity_mg_levels_ksp_max_it 4`, brings down the number of iterates, but not the growth. Using w-cycles and full multigrid does not help either. It is likely that the coarse grids made by MIS are inaccurate for the $P_2$ discretization. 884aa9a5b67SBarry Smith 885aa9a5b67SBarry SmithWe can instead use geometric multigrid, and we would hope get more accurate coarse bases. The `-dm_refine_hierarchy` allows us to make a hierarchy of refined meshes and sets the number of multigrid levels automatically. Then all we need to specify is `-fieldsplit_velocity_pc_type mg`, as we see in the test 886aa9a5b67SBarry Smith 887aa9a5b67SBarry Smith```{literalinclude} /../src/snes/tutorials/ex69.c 888aa9a5b67SBarry Smith:end-before: 'test:' 889aa9a5b67SBarry Smith:start-at: 'suffix: p2p1_gmg' 890aa9a5b67SBarry Smith``` 891aa9a5b67SBarry Smith 892aa9a5b67SBarry SmithThis behaves well for the initial mesh, 893aa9a5b67SBarry Smith 894aa9a5b67SBarry Smith```console 89530266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1_gmg" EXTRA_OPTIONS="-dm_refine_hierarchy 2 -snes_monitor -ksp_monitor_true_residual -ksp_converged_reason -fieldsplit_pressure_ksp_converged_reason -fieldsplit_velocity_ksp_converged_reason" 896aa9a5b67SBarry Smith0 SNES Function norm 3.503062983054e-02 897aa9a5b67SBarry Smith 0 KSP unpreconditioned resid norm 3.503062983054e-02 true resid norm 3.503062983054e-02 ||r(i)||/||b|| 1.000000000000e+00 898aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 899aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 900aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 901aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 902aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 903aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 5 904aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 5 905aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 906aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 907aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 8 908aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 909aa9a5b67SBarry Smith 1 KSP unpreconditioned resid norm 4.643855168829e-06 true resid norm 4.643855168807e-06 ||r(i)||/||b|| 1.325655630878e-04 910aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 5 911aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 5 912aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 913aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 914aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 915aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 916aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 917aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 918aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 919aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 5 920aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 9 921aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 5 922aa9a5b67SBarry Smith 2 KSP unpreconditioned resid norm 1.520240889941e-11 true resid norm 1.520239396618e-11 ||r(i)||/||b|| 4.339743258890e-10 923aa9a5b67SBarry SmithLinear solve converged due to CONVERGED_ATOL iterations 2 924aa9a5b67SBarry Smith1 SNES Function norm 1.520237877998e-11 925aa9a5b67SBarry Smith``` 926aa9a5b67SBarry Smith 927aa9a5b67SBarry Smithand is also stable under refinement 928aa9a5b67SBarry Smith 929aa9a5b67SBarry Smith```console 93030266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1_gmg" EXTRA_OPTIONS="-dm_refine_hierarchy 4 -snes_monitor -ksp_monitor_true_residual -ksp_converged_reason -fieldsplit_pressure_ksp_converged_reason -fieldsplit_velocity_ksp_converged_reason" 931aa9a5b67SBarry Smith0 SNES Function norm 3.503062983054e-02 932aa9a5b67SBarry Smith 0 KSP unpreconditioned resid norm 3.503062983054e-02 true resid norm 3.503062983054e-02 ||r(i)||/||b|| 1.000000000000e+00 933aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 934aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 935aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 936aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 937aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 938aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 5 939aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 5 940aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 941aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 942aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 8 943aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 944aa9a5b67SBarry Smith 1 KSP unpreconditioned resid norm 4.643855168829e-06 true resid norm 4.643855168807e-06 ||r(i)||/||b|| 1.325655630878e-04 945aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 5 946aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 5 947aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 948aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 949aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 950aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 951aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 952aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 953aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 4 954aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 5 955aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 9 956aa9a5b67SBarry Smith Linear fieldsplit_velocity_ solve converged due to CONVERGED_RTOL iterations 5 957aa9a5b67SBarry Smith 2 KSP unpreconditioned resid norm 1.520240889941e-11 true resid norm 1.520239396618e-11 ||r(i)||/||b|| 4.339743258890e-10 958aa9a5b67SBarry SmithLinear solve converged due to CONVERGED_ATOL iterations 2 959aa9a5b67SBarry Smith1 SNES Function norm 1.520237877998e-11 960aa9a5b67SBarry Smith``` 961aa9a5b67SBarry Smith 962aa9a5b67SBarry SmithFinally, we can back off the pressure solve. `ILU(0)` is good enough to maintain a constant number of iterates as we refine the grid. We could continue to refine our preconditioner by playing with the tolerance of the inner multigrid and Schur complement solves, trading fewer inner iterates for more outer iterates. 963aa9a5b67SBarry Smith 964aa9a5b67SBarry Smith```console 96530266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1_gmg" EXTRA_OPTIONS="-dm_refine_hierarchy 2 -snes_monitor -ksp_monitor_true_residual -ksp_converged_reason -fieldsplit_pressure_ksp_converged_reason -fieldsplit_pressure_pc_type ilu" 966aa9a5b67SBarry Smith0 SNES Function norm 3.503062983054e-02 967aa9a5b67SBarry Smith 0 KSP unpreconditioned resid norm 3.503062983054e-02 true resid norm 3.503062983054e-02 ||r(i)||/||b|| 1.000000000000e+00 968aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 10 969aa9a5b67SBarry Smith 1 KSP unpreconditioned resid norm 4.643855785779e-06 true resid norm 4.643855785812e-06 ||r(i)||/||b|| 1.325655807011e-04 970aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 10 971aa9a5b67SBarry Smith 2 KSP unpreconditioned resid norm 1.521944777036e-11 true resid norm 1.521942998859e-11 ||r(i)||/||b|| 4.344606437913e-10 972aa9a5b67SBarry SmithLinear solve converged due to CONVERGED_ATOL iterations 2 973aa9a5b67SBarry Smith1 SNES Function norm 1.521943449163e-11 97430266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1_gmg" EXTRA_OPTIONS="-dm_refine_hierarchy 4 -snes_monitor -ksp_monitor_true_residual -ksp_converged_reason -fieldsplit_pressure_ksp_converged_reason -fieldsplit_pressure_pc_type ilu" 975aa9a5b67SBarry Smith0 SNES Function norm 8.969202737759e-03 976aa9a5b67SBarry Smith 0 KSP unpreconditioned resid norm 8.969202737759e-03 true resid norm 8.969202737759e-03 ||r(i)||/||b|| 1.000000000000e+00 977aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 10 978aa9a5b67SBarry Smith 1 KSP unpreconditioned resid norm 2.234849111673e-05 true resid norm 2.234849111674e-05 ||r(i)||/||b|| 2.491692045566e-03 979aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 10 980aa9a5b67SBarry Smith 2 KSP unpreconditioned resid norm 1.205594722917e-10 true resid norm 1.205594316079e-10 ||r(i)||/||b|| 1.344148807121e-08 981aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 10 982aa9a5b67SBarry Smith 3 KSP unpreconditioned resid norm 1.461086575333e-15 true resid norm 2.284323415523e-15 ||r(i)||/||b|| 2.546852247977e-13 983aa9a5b67SBarry SmithLinear solve converged due to CONVERGED_ATOL iterations 3 984aa9a5b67SBarry Smith1 SNES Function norm 2.317901194143e-15 98530266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1_gmg" EXTRA_OPTIONS="-dm_refine_hierarchy 6 -snes_monitor -ksp_monitor_true_residual -ksp_converged_reason -fieldsplit_pressure_ksp_converged_reason -fieldsplit_pressure_pc_type ilu" 986aa9a5b67SBarry Smith0 SNES Function norm 2.252260693635e-03 987aa9a5b67SBarry Smith 0 KSP unpreconditioned resid norm 2.252260693635e-03 true resid norm 2.252260693635e-03 ||r(i)||/||b|| 1.000000000000e+00 988aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 9 989aa9a5b67SBarry Smith 1 KSP unpreconditioned resid norm 1.220195757583e-05 true resid norm 1.220195757579e-05 ||r(i)||/||b|| 5.417648858445e-03 990aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 10 991aa9a5b67SBarry Smith 2 KSP unpreconditioned resid norm 2.683367607036e-09 true resid norm 2.683367591382e-09 ||r(i)||/||b|| 1.191410745197e-06 992aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 10 993aa9a5b67SBarry Smith 3 KSP unpreconditioned resid norm 5.510932827474e-13 true resid norm 5.511665167379e-13 ||r(i)||/||b|| 2.447170162386e-10 994aa9a5b67SBarry SmithLinear solve converged due to CONVERGED_ATOL iterations 3 995aa9a5b67SBarry Smith1 SNES Function norm 5.511916500930e-13 996aa9a5b67SBarry Smith``` 997aa9a5b67SBarry Smith 998aa9a5b67SBarry SmithWe can make the problem harder by increasing the wave number and size of the viscosity perturbation. If we set the $B$ parameter to 6.9, we have a factor of one million increase in viscosity across the cell. At this scale, we see that we lose enough accuracy in our Jacobian calculation to defeat our Taylor test, but we are still able to solve the problem efficiently. 999aa9a5b67SBarry Smith 1000aa9a5b67SBarry Smith```console 100130266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1_gmg" EXTRA_OPTIONS="-dm_refine_hierarchy 2 -snes_monitor -ksp_monitor_true_residual -ksp_converged_reason -fieldsplit_pressure_ksp_converged_reason -fieldsplit_pressure_pc_type ilu -m 2 -n 2 -B 6.9" 1002aa9a5b67SBarry SmithL_2 Error: [4.07817e-06, 0.0104694] 1003aa9a5b67SBarry SmithL_2 Residual: 0.0145403 1004aa9a5b67SBarry SmithTaylor approximation converging at order 1.00 1005aa9a5b67SBarry Smith0 SNES Function norm 3.421266970274e-02 1006aa9a5b67SBarry Smith 0 KSP unpreconditioned resid norm 3.421266970274e-02 true resid norm 3.421266970274e-02 ||r(i)||/||b|| 1.000000000000e+00 1007aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 21 1008aa9a5b67SBarry Smith 1 KSP unpreconditioned resid norm 2.066264276201e-05 true resid norm 2.066264276201e-05 ||r(i)||/||b|| 6.039471032675e-04 1009aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 20 1010aa9a5b67SBarry Smith 2 KSP unpreconditioned resid norm 1.295461366009e-10 true resid norm 1.295461419342e-10 ||r(i)||/||b|| 3.786496144842e-09 1011aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 20 1012aa9a5b67SBarry Smith 3 KSP unpreconditioned resid norm 1.954355290546e-15 true resid norm 1.954135246291e-15 ||r(i)||/||b|| 5.711729786858e-14 1013aa9a5b67SBarry SmithLinear solve converged due to CONVERGED_ATOL iterations 3 1014aa9a5b67SBarry Smith1 SNES Function norm 1.946196473520e-15 101530266083SMatthew G. Knepley$ make -f ./gmakefile test search="snes_tutorials-ex69_p2p1_gmg" EXTRA_OPTIONS="-dm_refine_hierarchy 6 -snes_monitor -ksp_monitor_true_residual -ksp_converged_reason -fieldsplit_pressure_ksp_converged_reason -fieldsplit_pressure_pc_type ilu -m 2 -n 2 -B 6.9" 1016aa9a5b67SBarry SmithL_2 Error: [1.52905e-09, 4.72606e-05] 1017aa9a5b67SBarry SmithL_2 Residual: 7.18836e-06 1018aa9a5b67SBarry SmithTaylor approximation converging at order 1.00 1019aa9a5b67SBarry Smith0 SNES Function norm 2.252034794902e-03 1020aa9a5b67SBarry Smith 0 KSP unpreconditioned resid norm 2.252034794902e-03 true resid norm 2.252034794902e-03 ||r(i)||/||b|| 1.000000000000e+00 1021aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 19 1022aa9a5b67SBarry Smith 1 KSP unpreconditioned resid norm 1.843225742581e-05 true resid norm 1.843225742582e-05 ||r(i)||/||b|| 8.184712539768e-03 1023aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 19 1024aa9a5b67SBarry Smith 2 KSP unpreconditioned resid norm 1.410472862037e-09 true resid norm 1.410472860342e-09 ||r(i)||/||b|| 6.263104209294e-07 1025aa9a5b67SBarry Smith Linear fieldsplit_pressure_ solve converged due to CONVERGED_RTOL iterations 19 1026aa9a5b67SBarry Smith 3 KSP unpreconditioned resid norm 1.051996270409e-14 true resid norm 1.064465321443e-14 ||r(i)||/||b|| 4.726682393419e-12 1027aa9a5b67SBarry SmithLinear solve converged due to CONVERGED_ATOL iterations 3 1028aa9a5b67SBarry Smith1 SNES Function norm 1.063917948054e-14 1029aa9a5b67SBarry Smith``` 1030aa9a5b67SBarry Smith 1031aa9a5b67SBarry Smith## Bibliography 1032aa9a5b67SBarry Smith 1033aa9a5b67SBarry Smith```{eval-rst} 1034aa9a5b67SBarry Smith.. bibliography:: /petsc.bib 1035aa9a5b67SBarry Smith :filter: docname in docnames 1036aa9a5b67SBarry Smith``` 1037