Actual source code: iterativ.c

  1: /*
  2:    This file contains some simple default routines.
  3:    These routines should be SHORT, since they will be included in every
  4:    executable image that uses the iterative routines (note that, through
  5:    the registry system, we provide a way to load only the truly necessary
  6:    files)
  7:  */
  8: #include <petsc/private/kspimpl.h>
  9: #include <petscdmshell.h>
 10: #include <petscdraw.h>

 12: /*@
 13:    KSPGetResidualNorm - Gets the last (possibly approximate and/or preconditioned) residual norm that has been computed.

 15:    Not Collective

 17:    Input Parameter:
 18: .  ksp - the iterative context

 20:    Output Parameter:
 21: .  rnorm - residual norm

 23:    Level: intermediate

 25:    Note:
 26:    For some methods, such as `KSPGMRES`, the norm is not computed directly from the residual.

 28:    The type of norm used by the method can be controlled with `KSPSetNormType()`

 30: .seealso: [](ch_ksp), `KSP`, `KSPSetNormType()`, `KSPBuildResidual()`, `KSPNormType`
 31: @*/
 32: PetscErrorCode KSPGetResidualNorm(KSP ksp, PetscReal *rnorm)
 33: {
 34:   PetscFunctionBegin;
 37:   *rnorm = ksp->rnorm;
 38:   PetscFunctionReturn(PETSC_SUCCESS);
 39: }

 41: /*@
 42:    KSPGetIterationNumber - Gets the current iteration number; if the `KSPSolve()` is complete, returns the number of iterations used.

 44:    Not Collective

 46:    Input Parameter:
 47: .  ksp - the iterative context

 49:    Output Parameter:
 50: .  its - number of iterations

 52:    Level: intermediate

 54:    Note:
 55:    During the ith iteration this returns i-1

 57: .seealso: [](ch_ksp), `KSP`, `KSPGetResidualNorm()`, `KSPBuildResidual()`, `KSPGetResidualNorm()`, `KSPGetTotalIterations()`
 58: @*/
 59: PetscErrorCode KSPGetIterationNumber(KSP ksp, PetscInt *its)
 60: {
 61:   PetscFunctionBegin;
 64:   *its = ksp->its;
 65:   PetscFunctionReturn(PETSC_SUCCESS);
 66: }

 68: /*@
 69:    KSPGetTotalIterations - Gets the total number of iterations this `KSP` object has performed since was created, counted over all linear solves

 71:    Not Collective

 73:    Input Parameter:
 74: .  ksp - the iterative context

 76:    Output Parameter:
 77: .  its - total number of iterations

 79:    Level: intermediate

 81:    Note:
 82:     Use `KSPGetIterationNumber()` to get the count for the most recent solve only
 83:    If this is called within a `KSPSolve()` (such as in a `KSPMonitor` routine) then it does not include iterations within that current solve

 85: .seealso: [](ch_ksp), `KSP`, `KSPBuildResidual()`, `KSPGetResidualNorm()`, `KSPGetIterationNumber()`
 86: @*/
 87: PetscErrorCode KSPGetTotalIterations(KSP ksp, PetscInt *its)
 88: {
 89:   PetscFunctionBegin;
 92:   *its = ksp->totalits;
 93:   PetscFunctionReturn(PETSC_SUCCESS);
 94: }

 96: /*@C
 97:   KSPMonitorResidual - Print the (possibly preconditioned) residual norm at each iteration of an iterative solver.

 99:   Collective

101:   Input Parameters:
102: + ksp   - iterative context
103: . n     - iteration number
104: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
105: - vf    - The viewer context

107:   Options Database Key:
108: . -ksp_monitor - Activates `KSPMonitorResidual()`

110:   Level: intermediate

112:   Note:
113:   For some methods, such as `KSPGMRES`, the norm is not computed directly from the residual.

115:   The type of norm used by the method can be controlled with `KSPSetNormType()`

117:   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
118:   to be used during the KSP solve.

120: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorResidualDraw()`, `KSPMonitorResidualDrawLG()`,
121:           `KSPMonitorResidualRange()`, `KSPMonitorTrueResidualDraw()`, `KSPMonitorTrueResidualDrawLG()`, `KSPMonitorTrueResidualMax()`,
122:           `KSPMonitorSingularValue()`, `KSPMonitorSolutionDrawLG()`, `KSPMonitorSolutionDraw()`, `KSPMonitorSolution()`,
123:           `KSPMonitorErrorDrawLG()`, `KSPMonitorErrorDraw()`, KSPMonitorError()`
124: @*/
125: PetscErrorCode KSPMonitorResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
126: {
127:   PetscViewer       viewer = vf->viewer;
128:   PetscViewerFormat format = vf->format;
129:   PetscInt          tablevel;
130:   const char       *prefix;

132:   PetscFunctionBegin;
134:   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
135:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
136:   PetscCall(PetscViewerPushFormat(viewer, format));
137:   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
138:   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
139:   PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Residual norm %14.12e \n", n, (double)rnorm));
140:   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
141:   PetscCall(PetscViewerPopFormat(viewer));
142:   PetscFunctionReturn(PETSC_SUCCESS);
143: }

145: /*@C
146:   KSPMonitorResidualDraw - Plots the (possibly preconditioned) residual at each iteration of an iterative solver.

148:   Collective

150:   Input Parameters:
151: + ksp   - iterative context
152: . n     - iteration number
153: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
154: - vf    - The viewer context

156:   Options Database Key:
157: . -ksp_monitor draw - Activates `KSPMonitorResidualDraw()`

159:   Level: intermediate

161:   Note:
162:   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
163:   to be used during the `KSP` solve.

165: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorResidual()`, `KSPMonitorResidualDrawLG()`
166: @*/
167: PetscErrorCode KSPMonitorResidualDraw(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
168: {
169:   PetscViewer       viewer = vf->viewer;
170:   PetscViewerFormat format = vf->format;
171:   Vec               r;

173:   PetscFunctionBegin;
175:   PetscCall(PetscViewerPushFormat(viewer, format));
176:   PetscCall(KSPBuildResidual(ksp, NULL, NULL, &r));
177:   PetscCall(PetscObjectSetName((PetscObject)r, "Residual"));
178:   PetscCall(PetscObjectCompose((PetscObject)r, "__Vec_bc_zero__", (PetscObject)ksp));
179:   PetscCall(VecView(r, viewer));
180:   PetscCall(PetscObjectCompose((PetscObject)r, "__Vec_bc_zero__", NULL));
181:   PetscCall(VecDestroy(&r));
182:   PetscCall(PetscViewerPopFormat(viewer));
183:   PetscFunctionReturn(PETSC_SUCCESS);
184: }

186: /*@C
187:   KSPMonitorResidualDrawLG - Plots the (possibly preconditioned) residual norm at each iteration of an iterative solver.

189:   Collective

191:   Input Parameters:
192: + ksp   - iterative context
193: . n     - iteration number
194: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
195: - vf    - The viewer context

197:   Options Database Key:
198: . -ksp_monitor draw::draw_lg - Activates `KSPMonitorResidualDrawLG()`

200:   Level: intermediate

202:   Notes:
203:   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
204:   to be used during the `KSP` solve.

206:   Use `KSPMonitorResidualDrawLGCreate()` to create the context used with this monitor

208: .seealso: [](ch_ksp), `KSP`, `PETSCVIEWERDRAW`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorResidualDraw()`, `KSPMonitorResidual()`
209: @*/
210: PetscErrorCode KSPMonitorResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
211: {
212:   PetscViewer        viewer = vf->viewer;
213:   PetscViewerFormat  format = vf->format;
214:   PetscDrawLG        lg     = vf->lg;
215:   KSPConvergedReason reason;
216:   PetscReal          x, y;

218:   PetscFunctionBegin;
221:   PetscCall(PetscViewerPushFormat(viewer, format));
222:   if (!n) PetscCall(PetscDrawLGReset(lg));
223:   x = (PetscReal)n;
224:   if (rnorm > 0.0) y = PetscLog10Real(rnorm);
225:   else y = -15.0;
226:   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
227:   PetscCall(KSPGetConvergedReason(ksp, &reason));
228:   if (n <= 20 || !(n % 5) || reason) {
229:     PetscCall(PetscDrawLGDraw(lg));
230:     PetscCall(PetscDrawLGSave(lg));
231:   }
232:   PetscCall(PetscViewerPopFormat(viewer));
233:   PetscFunctionReturn(PETSC_SUCCESS);
234: }

236: /*@C
237:   KSPMonitorResidualDrawLGCreate - Creates the context for the (possibly preconditioned) residual norm monitor `KSPMonitorResidualDrawLG()`

239:   Collective

241:   Input Parameters:
242: + viewer - The `PetscViewer` of type `PETSCVIEWERDRAW`
243: . format - The viewer format
244: - ctx    - An optional user context

246:   Output Parameter:
247: . vf    - The viewer context

249:   Level: intermediate

251: .seealso: [](ch_ksp), `KSP`, `PETSCVIEWERDRAW`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorResidualDrawLG()`,
252:           `PetscViewerFormat`, `PetscViewer`, `PetscViewerAndFormat`
253: @*/
254: PetscErrorCode KSPMonitorResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
255: {
256:   PetscFunctionBegin;
257:   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
258:   (*vf)->data = ctx;
259:   PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Residual Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg));
260:   PetscFunctionReturn(PETSC_SUCCESS);
261: }

263: /*
264:   This is the same as KSPMonitorResidual() except it prints fewer digits of the residual as the residual gets smaller.
265:   This is because the later digits are meaningless and are often different on different machines; by using this routine different
266:   machines will usually generate the same output.

268:   Deprecated: Intentionally has no manual page
269: */
270: PetscErrorCode KSPMonitorResidualShort(KSP ksp, PetscInt its, PetscReal fnorm, PetscViewerAndFormat *vf)
271: {
272:   PetscViewer       viewer = vf->viewer;
273:   PetscViewerFormat format = vf->format;
274:   PetscInt          tablevel;
275:   const char       *prefix;

277:   PetscFunctionBegin;
279:   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
280:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
281:   PetscCall(PetscViewerPushFormat(viewer, format));
282:   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
283:   if (its == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
284:   if (fnorm > 1.e-9) PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Residual norm %g \n", its, (double)fnorm));
285:   else if (fnorm > 1.e-11) PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Residual norm %5.3e \n", its, (double)fnorm));
286:   else PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Residual norm < 1.e-11\n", its));
287:   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
288:   PetscCall(PetscViewerPopFormat(viewer));
289:   PetscFunctionReturn(PETSC_SUCCESS);
290: }

292: PetscErrorCode KSPMonitorRange_Private(KSP ksp, PetscInt it, PetscReal *per)
293: {
294:   Vec                resid;
295:   const PetscScalar *r;
296:   PetscReal          rmax, pwork;
297:   PetscInt           i, n, N;

299:   PetscFunctionBegin;
300:   PetscCall(KSPBuildResidual(ksp, NULL, NULL, &resid));
301:   PetscCall(VecNorm(resid, NORM_INFINITY, &rmax));
302:   PetscCall(VecGetLocalSize(resid, &n));
303:   PetscCall(VecGetSize(resid, &N));
304:   PetscCall(VecGetArrayRead(resid, &r));
305:   pwork = 0.0;
306:   for (i = 0; i < n; ++i) pwork += (PetscAbsScalar(r[i]) > .20 * rmax);
307:   PetscCall(VecRestoreArrayRead(resid, &r));
308:   PetscCall(VecDestroy(&resid));
309:   PetscCall(MPIU_Allreduce(&pwork, per, 1, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)ksp)));
310:   *per = *per / N;
311:   PetscFunctionReturn(PETSC_SUCCESS);
312: }

314: /*@C
315:   KSPMonitorResidualRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.

317:   Collective

319:   Input Parameters:
320: + ksp   - iterative context
321: . it    - iteration number
322: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
323: - vf    - The viewer context

325:   Options Database Key:
326: . -ksp_monitor_range - Activates `KSPMonitorResidualRange()`

328:   Level: intermediate

330:   Note:
331:   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
332:   to be used during the `KSP` solve.

334: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorResidual()`
335: @*/
336: PetscErrorCode KSPMonitorResidualRange(KSP ksp, PetscInt it, PetscReal rnorm, PetscViewerAndFormat *vf)
337: {
338:   static PetscReal  prev;
339:   PetscViewer       viewer = vf->viewer;
340:   PetscViewerFormat format = vf->format;
341:   PetscInt          tablevel;
342:   const char       *prefix;
343:   PetscReal         perc, rel;

345:   PetscFunctionBegin;
347:   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
348:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
349:   PetscCall(PetscViewerPushFormat(viewer, format));
350:   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
351:   if (!it) prev = rnorm;
352:   if (it == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
353:   PetscCall(KSPMonitorRange_Private(ksp, it, &perc));
354:   rel  = (prev - rnorm) / prev;
355:   prev = rnorm;
356:   PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP preconditioned resid norm %14.12e Percent values above 20 percent of maximum %5.2f relative decrease %5.2e ratio %5.2e \n", it, (double)rnorm, (double)(100.0 * perc), (double)rel, (double)(rel / perc)));
357:   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
358:   PetscCall(PetscViewerPopFormat(viewer));
359:   PetscFunctionReturn(PETSC_SUCCESS);
360: }

362: /*@C
363:   KSPMonitorTrueResidual - Prints the true residual norm, as well as the (possibly preconditioned) approximate residual norm, at each iteration of an iterative solver.

365:   Collective

367:   Input Parameters:
368: + ksp   - iterative context
369: . n     - iteration number
370: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
371: - vf    - The viewer context

373:   Options Database Key:
374: . -ksp_monitor_true_residual - Activates `KSPMonitorTrueResidual()`

376:   Level: intermediate

378:   Notes:
379:   When using right preconditioning, these values are equivalent.

381:   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
382:   to be used during the `KSP` solve.

384: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`, `PetscViewerAndFormat`
385: @*/
386: PetscErrorCode KSPMonitorTrueResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
387: {
388:   PetscViewer       viewer = vf->viewer;
389:   PetscViewerFormat format = vf->format;
390:   Vec               r;
391:   PetscReal         truenorm, bnorm;
392:   char              normtype[256];
393:   PetscInt          tablevel;
394:   const char       *prefix;

396:   PetscFunctionBegin;
398:   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
399:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
400:   PetscCall(PetscStrncpy(normtype, KSPNormTypes[ksp->normtype], sizeof(normtype)));
401:   PetscCall(PetscStrtolower(normtype));
402:   PetscCall(KSPBuildResidual(ksp, NULL, NULL, &r));
403:   PetscCall(VecNorm(r, NORM_2, &truenorm));
404:   PetscCall(VecNorm(ksp->vec_rhs, NORM_2, &bnorm));
405:   PetscCall(VecDestroy(&r));

407:   PetscCall(PetscViewerPushFormat(viewer, format));
408:   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
409:   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
410:   if (bnorm == 0) {
411:     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP %s resid norm %14.12e true resid norm %14.12e ||r(i)||/||b|| inf\n", n, normtype, (double)rnorm, (double)truenorm));
412:   } else {
413:     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP %s resid norm %14.12e true resid norm %14.12e ||r(i)||/||b|| %14.12e\n", n, normtype, (double)rnorm, (double)truenorm, (double)(truenorm / bnorm)));
414:   }
415:   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
416:   PetscCall(PetscViewerPopFormat(viewer));
417:   PetscFunctionReturn(PETSC_SUCCESS);
418: }

420: /*@C
421:   KSPMonitorTrueResidualDraw - Plots the true residual at each iteration of an iterative solver.

423:   Collective

425:   Input Parameters:
426: + ksp   - iterative context
427: . n     - iteration number
428: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
429: - vf    - The viewer context of type `PETSCVIEWERDRAW`

431:   Options Database Key:
432: . -ksp_monitor_true_residual draw - Activates `KSPMonitorResidualDraw()`

434:   Level: intermediate

436:   Note:
437:   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
438:   to be used during the `KSP` solve.

440: .seealso: [](ch_ksp), `PETSCVIEWERDRAW`, `KSP`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorResidual()`,
441:           `KSPMonitorTrueResidualDrawLG()`, `PetscViewerAndFormat`
442: @*/
443: PetscErrorCode KSPMonitorTrueResidualDraw(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
444: {
445:   PetscViewer       viewer = vf->viewer;
446:   PetscViewerFormat format = vf->format;
447:   Vec               r;

449:   PetscFunctionBegin;
451:   PetscCall(PetscViewerPushFormat(viewer, format));
452:   PetscCall(KSPBuildResidual(ksp, NULL, NULL, &r));
453:   PetscCall(PetscObjectSetName((PetscObject)r, "Residual"));
454:   PetscCall(PetscObjectCompose((PetscObject)r, "__Vec_bc_zero__", (PetscObject)ksp));
455:   PetscCall(VecView(r, viewer));
456:   PetscCall(PetscObjectCompose((PetscObject)r, "__Vec_bc_zero__", NULL));
457:   PetscCall(VecDestroy(&r));
458:   PetscCall(PetscViewerPopFormat(viewer));
459:   PetscFunctionReturn(PETSC_SUCCESS);
460: }

462: /*@C
463:   KSPMonitorTrueResidualDrawLG - Plots the true residual norm at each iteration of an iterative solver.

465:   Collective

467:   Input Parameters:
468: + ksp   - iterative context
469: . n     - iteration number
470: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
471: - vf    - The viewer context

473:   Options Database Key:
474: . -ksp_monitor_true_residual draw::draw_lg - Activates `KSPMonitorTrueResidualDrawLG()`

476:   Level: intermediate

478:   Notes:
479:   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
480:   to be used during the `KSP` solve.

482:   Call `KSPMonitorTrueResidualDrawLGCreate()` to create the context needed for this monitor

484: .seealso: [](ch_ksp), `PETSCVIEWERDRAW`, `KSP`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorTrueResidualDraw()`, `KSPMonitorResidual`,
485:           `KSPMonitorTrueResidualDrawLGCreate()`
486: @*/
487: PetscErrorCode KSPMonitorTrueResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
488: {
489:   PetscViewer        viewer = vf->viewer;
490:   PetscViewerFormat  format = vf->format;
491:   PetscDrawLG        lg     = vf->lg;
492:   Vec                r;
493:   KSPConvergedReason reason;
494:   PetscReal          truenorm, x[2], y[2];

496:   PetscFunctionBegin;
499:   PetscCall(KSPBuildResidual(ksp, NULL, NULL, &r));
500:   PetscCall(VecNorm(r, NORM_2, &truenorm));
501:   PetscCall(VecDestroy(&r));
502:   PetscCall(PetscViewerPushFormat(viewer, format));
503:   if (!n) PetscCall(PetscDrawLGReset(lg));
504:   x[0] = (PetscReal)n;
505:   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
506:   else y[0] = -15.0;
507:   x[1] = (PetscReal)n;
508:   if (truenorm > 0.0) y[1] = PetscLog10Real(truenorm);
509:   else y[1] = -15.0;
510:   PetscCall(PetscDrawLGAddPoint(lg, x, y));
511:   PetscCall(KSPGetConvergedReason(ksp, &reason));
512:   if (n <= 20 || !(n % 5) || reason) {
513:     PetscCall(PetscDrawLGDraw(lg));
514:     PetscCall(PetscDrawLGSave(lg));
515:   }
516:   PetscCall(PetscViewerPopFormat(viewer));
517:   PetscFunctionReturn(PETSC_SUCCESS);
518: }

520: /*@C
521:   KSPMonitorTrueResidualDrawLGCreate - Creates the context for the true residual monitor `KSPMonitorTrueResidualDrawLG()`

523:   Collective

525:   Input Parameters:
526: + viewer - The `PetscViewer` of type `PETSCVIEWERDRAW`
527: . format - The viewer format
528: - ctx    - An optional user context

530:   Output Parameter:
531: . vf    - The viewer context

533:   Level: intermediate

535: .seealso: [](ch_ksp), `PETSCVIEWERDRAW`, `KSP`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `PetscViewerAndFormat`
536: @*/
537: PetscErrorCode KSPMonitorTrueResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
538: {
539:   const char *names[] = {"preconditioned", "true"};

541:   PetscFunctionBegin;
542:   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
543:   (*vf)->data = ctx;
544:   PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Residual Norm", 2, names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg));
545:   PetscFunctionReturn(PETSC_SUCCESS);
546: }

548: /*@C
549:   KSPMonitorTrueResidualMax - Prints the true residual max norm at each iteration of an iterative solver.

551:   Collective

553:   Input Parameters:
554: + ksp   - iterative context
555: . n     - iteration number
556: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
557: - vf    - The viewer context

559:   Options Database Key:
560: . -ksp_monitor_true_residual_max - Activates `KSPMonitorTrueResidualMax()`

562:   Level: intermediate

564:   Note:
565:   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
566:   to be used during the `KSP` solve.

568: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`
569: @*/
570: PetscErrorCode KSPMonitorTrueResidualMax(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
571: {
572:   PetscViewer       viewer = vf->viewer;
573:   PetscViewerFormat format = vf->format;
574:   Vec               r;
575:   PetscReal         truenorm, bnorm;
576:   char              normtype[256];
577:   PetscInt          tablevel;
578:   const char       *prefix;

580:   PetscFunctionBegin;
582:   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
583:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
584:   PetscCall(PetscStrncpy(normtype, KSPNormTypes[ksp->normtype], sizeof(normtype)));
585:   PetscCall(PetscStrtolower(normtype));
586:   PetscCall(KSPBuildResidual(ksp, NULL, NULL, &r));
587:   PetscCall(VecNorm(r, NORM_INFINITY, &truenorm));
588:   PetscCall(VecNorm(ksp->vec_rhs, NORM_INFINITY, &bnorm));
589:   PetscCall(VecDestroy(&r));

591:   PetscCall(PetscViewerPushFormat(viewer, format));
592:   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
593:   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
594:   PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP %s true resid max norm %14.12e ||r(i)||/||b|| %14.12e\n", n, normtype, (double)truenorm, (double)(truenorm / bnorm)));
595:   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
596:   PetscCall(PetscViewerPopFormat(viewer));
597:   PetscFunctionReturn(PETSC_SUCCESS);
598: }

600: /*@C
601:   KSPMonitorError - Prints the error norm, as well as the (possibly preconditioned) residual norm, at each iteration of an iterative solver.

603:   Collective

605:   Input Parameters:
606: + ksp   - iterative context
607: . n     - iteration number
608: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
609: - vf    - The viewer context

611:   Options Database Key:
612: . -ksp_monitor_error - Activates `KSPMonitorError()`

614:   Level: intermediate

616:   Note:
617:   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
618:   to be used during the `KSP` solve.

620: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`
621: @*/
622: PetscErrorCode KSPMonitorError(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
623: {
624:   PetscViewer       viewer = vf->viewer;
625:   PetscViewerFormat format = vf->format;
626:   DM                dm;
627:   Vec               sol;
628:   PetscReal        *errors;
629:   PetscInt          Nf, f;
630:   PetscInt          tablevel;
631:   const char       *prefix;

633:   PetscFunctionBegin;
635:   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
636:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
637:   PetscCall(KSPGetDM(ksp, &dm));
638:   PetscCall(DMGetNumFields(dm, &Nf));
639:   PetscCall(DMGetGlobalVector(dm, &sol));
640:   PetscCall(KSPBuildSolution(ksp, sol, NULL));
641:   /* TODO: Make a different monitor that flips sign for SNES, Newton system is A dx = -b, so we need to negate the solution */
642:   PetscCall(VecScale(sol, -1.0));
643:   PetscCall(PetscCalloc1(Nf, &errors));
644:   PetscCall(DMComputeError(dm, sol, errors, NULL));

646:   PetscCall(PetscViewerPushFormat(viewer, format));
647:   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
648:   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Error norms for %s solve.\n", prefix));
649:   PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Error norm %s", n, Nf > 1 ? "[" : ""));
650:   PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
651:   for (f = 0; f < Nf; ++f) {
652:     if (f > 0) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
653:     PetscCall(PetscViewerASCIIPrintf(viewer, "%14.12e", (double)errors[f]));
654:   }
655:   PetscCall(PetscViewerASCIIPrintf(viewer, "%s resid norm %14.12e\n", Nf > 1 ? "]" : "", (double)rnorm));
656:   PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
657:   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
658:   PetscCall(PetscViewerPopFormat(viewer));
659:   PetscCall(DMRestoreGlobalVector(dm, &sol));
660:   PetscFunctionReturn(PETSC_SUCCESS);
661: }

663: /*@C
664:   KSPMonitorErrorDraw - Plots the error at each iteration of an iterative solver.

666:   Collective

668:   Input Parameters:
669: + ksp   - iterative context
670: . n     - iteration number
671: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
672: - vf    - The viewer context

674:   Options Database Key:
675: . -ksp_monitor_error draw - Activates `KSPMonitorErrorDraw()`

677:   Level: intermediate

679:   Note:
680:   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
681:   to be used during the `KSP` solve.

683: .seealso: [](ch_ksp), `PETSCVIEWERDRAW`, `KSP`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorErrorDrawLG()`
684: @*/
685: PetscErrorCode KSPMonitorErrorDraw(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
686: {
687:   PetscViewer       viewer = vf->viewer;
688:   PetscViewerFormat format = vf->format;
689:   DM                dm;
690:   Vec               sol, e;

692:   PetscFunctionBegin;
694:   PetscCall(PetscViewerPushFormat(viewer, format));
695:   PetscCall(KSPGetDM(ksp, &dm));
696:   PetscCall(DMGetGlobalVector(dm, &sol));
697:   PetscCall(KSPBuildSolution(ksp, sol, NULL));
698:   PetscCall(DMComputeError(dm, sol, NULL, &e));
699:   PetscCall(PetscObjectSetName((PetscObject)e, "Error"));
700:   PetscCall(PetscObjectCompose((PetscObject)e, "__Vec_bc_zero__", (PetscObject)ksp));
701:   PetscCall(VecView(e, viewer));
702:   PetscCall(PetscObjectCompose((PetscObject)e, "__Vec_bc_zero__", NULL));
703:   PetscCall(VecDestroy(&e));
704:   PetscCall(DMRestoreGlobalVector(dm, &sol));
705:   PetscCall(PetscViewerPopFormat(viewer));
706:   PetscFunctionReturn(PETSC_SUCCESS);
707: }

709: /*@C
710:   KSPMonitorErrorDrawLG - Plots the error and residual norm at each iteration of an iterative solver.

712:   Collective

714:   Input Parameters:
715: + ksp   - iterative context
716: . n     - iteration number
717: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
718: - vf    - The viewer context

720:   Options Database Key:
721: . -ksp_monitor_error draw::draw_lg - Activates `KSPMonitorTrueResidualDrawLG()`

723:   Level: intermediate

725:   Notes:
726:   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
727:   to be used during the `KSP` solve.

729:   Call `KSPMonitorErrorDrawLGCreate()` to create the context used with this monitor

731: .seealso: [](ch_ksp), `PETSCVIEWERDRAW`, `KSP`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorErrorDraw()`
732: @*/
733: PetscErrorCode KSPMonitorErrorDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
734: {
735:   PetscViewer        viewer = vf->viewer;
736:   PetscViewerFormat  format = vf->format;
737:   PetscDrawLG        lg     = vf->lg;
738:   DM                 dm;
739:   Vec                sol;
740:   KSPConvergedReason reason;
741:   PetscReal         *x, *errors;
742:   PetscInt           Nf, f;

744:   PetscFunctionBegin;
747:   PetscCall(KSPGetDM(ksp, &dm));
748:   PetscCall(DMGetNumFields(dm, &Nf));
749:   PetscCall(DMGetGlobalVector(dm, &sol));
750:   PetscCall(KSPBuildSolution(ksp, sol, NULL));
751:   /* TODO: Make a different monitor that flips sign for SNES, Newton system is A dx = -b, so we need to negate the solution */
752:   PetscCall(VecScale(sol, -1.0));
753:   PetscCall(PetscCalloc2(Nf + 1, &x, Nf + 1, &errors));
754:   PetscCall(DMComputeError(dm, sol, errors, NULL));

756:   PetscCall(PetscViewerPushFormat(viewer, format));
757:   if (!n) PetscCall(PetscDrawLGReset(lg));
758:   for (f = 0; f < Nf; ++f) {
759:     x[f]      = (PetscReal)n;
760:     errors[f] = errors[f] > 0.0 ? PetscLog10Real(errors[f]) : -15.;
761:   }
762:   x[Nf]      = (PetscReal)n;
763:   errors[Nf] = rnorm > 0.0 ? PetscLog10Real(rnorm) : -15.;
764:   PetscCall(PetscDrawLGAddPoint(lg, x, errors));
765:   PetscCall(KSPGetConvergedReason(ksp, &reason));
766:   if (n <= 20 || !(n % 5) || reason) {
767:     PetscCall(PetscDrawLGDraw(lg));
768:     PetscCall(PetscDrawLGSave(lg));
769:   }
770:   PetscCall(PetscViewerPopFormat(viewer));
771:   PetscFunctionReturn(PETSC_SUCCESS);
772: }

774: /*@C
775:   KSPMonitorErrorDrawLGCreate - Creates the context for the error and preconditioned residual plotter `KSPMonitorErrorDrawLG()`

777:   Collective

779:   Input Parameters:
780: + viewer - The `PetscViewer`
781: . format - The viewer format
782: - ctx    - An optional user context

784:   Output Parameter:
785: . vf    - The viewer context

787:   Level: intermediate

789: .seealso: [](ch_ksp), `PETSCVIEWERDRAW`, `KSP`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorErrorDrawLG()`, `KSPMonitorErrorDrawLG()`
790: @*/
791: PetscErrorCode KSPMonitorErrorDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
792: {
793:   KSP      ksp = (KSP)ctx;
794:   DM       dm;
795:   char   **names;
796:   PetscInt Nf, f;

798:   PetscFunctionBegin;
799:   PetscCall(KSPGetDM(ksp, &dm));
800:   PetscCall(DMGetNumFields(dm, &Nf));
801:   PetscCall(PetscMalloc1(Nf + 1, &names));
802:   for (f = 0; f < Nf; ++f) {
803:     PetscObject disc;
804:     const char *fname;
805:     char        lname[PETSC_MAX_PATH_LEN];

807:     PetscCall(DMGetField(dm, f, NULL, &disc));
808:     PetscCall(PetscObjectGetName(disc, &fname));
809:     PetscCall(PetscStrncpy(lname, fname, PETSC_MAX_PATH_LEN));
810:     PetscCall(PetscStrlcat(lname, " Error", PETSC_MAX_PATH_LEN));
811:     PetscCall(PetscStrallocpy(lname, &names[f]));
812:   }
813:   PetscCall(PetscStrallocpy("residual", &names[Nf]));
814:   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
815:   (*vf)->data = ctx;
816:   PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Error Norm", Nf + 1, (const char **)names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg));
817:   for (f = 0; f <= Nf; ++f) PetscCall(PetscFree(names[f]));
818:   PetscCall(PetscFree(names));
819:   PetscFunctionReturn(PETSC_SUCCESS);
820: }

822: /*@C
823:   KSPMonitorSolution - Print the solution norm at each iteration of an iterative solver.

825:   Collective

827:   Input Parameters:
828: + ksp   - iterative context
829: . n     - iteration number
830: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
831: - vf    - The viewer context

833:   Options Database Key:
834: . -ksp_monitor_solution - Activates `KSPMonitorSolution()`

836:   Level: intermediate

838:   Note:
839:   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
840:   to be used during the `KSP` solve.

842: .seealso: [](ch_ksp), `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
843: @*/
844: PetscErrorCode KSPMonitorSolution(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
845: {
846:   PetscViewer       viewer = vf->viewer;
847:   PetscViewerFormat format = vf->format;
848:   Vec               x;
849:   PetscReal         snorm;
850:   PetscInt          tablevel;
851:   const char       *prefix;

853:   PetscFunctionBegin;
855:   PetscCall(KSPBuildSolution(ksp, NULL, &x));
856:   PetscCall(VecNorm(x, NORM_2, &snorm));
857:   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
858:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
859:   PetscCall(PetscViewerPushFormat(viewer, format));
860:   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
861:   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Solution norms for %s solve.\n", prefix));
862:   PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Solution norm %14.12e \n", n, (double)snorm));
863:   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
864:   PetscCall(PetscViewerPopFormat(viewer));
865:   PetscFunctionReturn(PETSC_SUCCESS);
866: }

868: /*@C
869:   KSPMonitorSolutionDraw - Plots the solution at each iteration of an iterative solver.

871:   Collective

873:   Input Parameters:
874: + ksp   - iterative context
875: . n     - iteration number
876: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
877: - vf    - The viewer context

879:   Options Database Key:
880: . -ksp_monitor_solution draw - Activates `KSPMonitorSolutionDraw()`

882:   Level: intermediate

884:   Note:
885:   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
886:   to be used during the `KSP` solve.

888: .seealso: [](ch_ksp), `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
889: @*/
890: PetscErrorCode KSPMonitorSolutionDraw(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
891: {
892:   PetscViewer       viewer = vf->viewer;
893:   PetscViewerFormat format = vf->format;
894:   Vec               x;

896:   PetscFunctionBegin;
898:   PetscCall(KSPBuildSolution(ksp, NULL, &x));
899:   PetscCall(PetscViewerPushFormat(viewer, format));
900:   PetscCall(PetscObjectSetName((PetscObject)x, "Solution"));
901:   PetscCall(PetscObjectCompose((PetscObject)x, "__Vec_bc_zero__", (PetscObject)ksp));
902:   PetscCall(VecView(x, viewer));
903:   PetscCall(PetscObjectCompose((PetscObject)x, "__Vec_bc_zero__", NULL));
904:   PetscCall(PetscViewerPopFormat(viewer));
905:   PetscFunctionReturn(PETSC_SUCCESS);
906: }

908: /*@C
909:   KSPMonitorSolutionDrawLG - Plots the solution norm at each iteration of an iterative solver.

911:   Collective

913:   Input Parameters:
914: + ksp   - iterative context
915: . n     - iteration number
916: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
917: - vf    - The viewer context

919:   Options Database Key:
920: . -ksp_monitor_solution draw::draw_lg - Activates `KSPMonitorSolutionDrawLG()`

922:   Level: intermediate

924:   Notes:
925:   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
926:   to be used during the `KSP` solve.

928:    Call `KSPMonitorSolutionDrawLGCreate()` to create the context needed with this monitor

930: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorSolutionDrawLGCreate()`
931: @*/
932: PetscErrorCode KSPMonitorSolutionDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
933: {
934:   PetscViewer        viewer = vf->viewer;
935:   PetscViewerFormat  format = vf->format;
936:   PetscDrawLG        lg     = vf->lg;
937:   Vec                u;
938:   KSPConvergedReason reason;
939:   PetscReal          snorm, x, y;

941:   PetscFunctionBegin;
944:   PetscCall(KSPBuildSolution(ksp, NULL, &u));
945:   PetscCall(VecNorm(u, NORM_2, &snorm));
946:   PetscCall(PetscViewerPushFormat(viewer, format));
947:   if (!n) PetscCall(PetscDrawLGReset(lg));
948:   x = (PetscReal)n;
949:   if (snorm > 0.0) y = PetscLog10Real(snorm);
950:   else y = -15.0;
951:   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
952:   PetscCall(KSPGetConvergedReason(ksp, &reason));
953:   if (n <= 20 || !(n % 5) || reason) {
954:     PetscCall(PetscDrawLGDraw(lg));
955:     PetscCall(PetscDrawLGSave(lg));
956:   }
957:   PetscCall(PetscViewerPopFormat(viewer));
958:   PetscFunctionReturn(PETSC_SUCCESS);
959: }

961: /*@C
962:   KSPMonitorSolutionDrawLGCreate - Creates the context for the `KSP` monitor `KSPMonitorSolutionDrawLG()`

964:   Collective

966:   Input Parameters:
967: + viewer - The `PetscViewer`
968: . format - The viewer format
969: - ctx    - An optional user context

971:   Output Parameter:
972: . vf    - The viewer context

974:   Level: intermediate

976:   Note:
977:   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
978:   to be used during the `KSP` solve.

980: .seealso: [](ch_ksp), `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
981: @*/
982: PetscErrorCode KSPMonitorSolutionDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
983: {
984:   PetscFunctionBegin;
985:   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
986:   (*vf)->data = ctx;
987:   PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Solution Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg));
988:   PetscFunctionReturn(PETSC_SUCCESS);
989: }

991: /*@C
992:   KSPMonitorSingularValue - Prints the two norm of the true residual and estimation of the extreme singular values of the preconditioned problem at each iteration.

994:   Logically Collective

996:   Input Parameters:
997: + ksp   - the iterative context
998: . n     - the iteration
999: . rnorm - the two norm of the residual
1000: - vf    - The viewer context

1002:   Options Database Key:
1003: . -ksp_monitor_singular_value - Activates `KSPMonitorSingularValue()`

1005:   Level: intermediate

1007:   Notes:
1008:   The `KSPCG` solver uses the Lanczos technique for eigenvalue computation,
1009:   while `KSPGMRES` uses the Arnoldi technique; other iterative methods do
1010:   not currently compute singular values.

1012:   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
1013:   to be used during the `KSP` solve.

1015:   Call `KSPMonitorSingularValueCreate()` to create the context needed by this monitor

1017: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPComputeExtremeSingularValues()`, `KSPMonitorSingularValueCreate()`
1018: @*/
1019: PetscErrorCode KSPMonitorSingularValue(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
1020: {
1021:   PetscViewer       viewer = vf->viewer;
1022:   PetscViewerFormat format = vf->format;
1023:   PetscReal         emin, emax;
1024:   PetscInt          tablevel;
1025:   const char       *prefix;

1027:   PetscFunctionBegin;
1030:   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
1031:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
1032:   PetscCall(PetscViewerPushFormat(viewer, format));
1033:   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
1034:   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
1035:   if (!ksp->calc_sings) {
1036:     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Residual norm %14.12e \n", n, (double)rnorm));
1037:   } else {
1038:     PetscCall(KSPComputeExtremeSingularValues(ksp, &emax, &emin));
1039:     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Residual norm %14.12e %% max %14.12e min %14.12e max/min %14.12e\n", n, (double)rnorm, (double)emax, (double)emin, (double)(emax / emin)));
1040:   }
1041:   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
1042:   PetscCall(PetscViewerPopFormat(viewer));
1043:   PetscFunctionReturn(PETSC_SUCCESS);
1044: }

1046: /*@C
1047:   KSPMonitorSingularValueCreate - Creates the singular value monitor context needed by `KSPMonitorSingularValue()`

1049:   Collective

1051:   Input Parameters:
1052: + viewer - The PetscViewer
1053: . format - The viewer format
1054: - ctx    - An optional user context

1056:   Output Parameter:
1057: . vf    - The viewer context

1059:   Level: intermediate

1061: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorSingularValue()`, `PetscViewer`
1062: @*/
1063: PetscErrorCode KSPMonitorSingularValueCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
1064: {
1065:   KSP ksp = (KSP)ctx;

1067:   PetscFunctionBegin;
1068:   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
1069:   (*vf)->data = ctx;
1070:   PetscCall(KSPSetComputeSingularValues(ksp, PETSC_TRUE));
1071:   PetscFunctionReturn(PETSC_SUCCESS);
1072: }

1074: /*@C
1075:    KSPMonitorDynamicToleranceCreate - Creates the context used by `KSPMonitorDynamicTolerance()`

1077:    Logically Collective

1079:    Output Parameter:
1080: .  ctx - a void pointer

1082:    Options Database Key:
1083: .   -sub_ksp_dynamic_tolerance <coef> - coefficient of dynamic tolerance for inner solver, default is 1.0

1085:    Level: advanced

1087:    Note:
1088:    Use before calling `KSPMonitorSet()` with `KSPMonitorDynamicTolerance()`

1090:    The default coefficient for the tolerance can be changed with `KSPMonitorDynamicToleranceSetCoefficient()`

1092: .seealso: [](sec_flexibleksp), `KSP`, `KSPMonitorDynamicTolerance()`, `KSPMonitorDynamicToleranceDestroy()`, `KSPMonitorDynamicToleranceSetCoefficient()`
1093: @*/
1094: PetscErrorCode KSPMonitorDynamicToleranceCreate(void *ctx)
1095: {
1096:   KSPDynTolCtx *scale;

1098:   PetscFunctionBegin;
1099:   PetscCall(PetscMalloc1(1, &scale));
1100:   scale->bnrm   = -1.0;
1101:   scale->coef   = 1.0;
1102:   *(void **)ctx = scale;
1103:   PetscFunctionReturn(PETSC_SUCCESS);
1104: }

1106: /*@C
1107:    KSPMonitorDynamicToleranceSetCoefficient - Sets the coefficient in the context used by `KSPMonitorDynamicTolerance()`

1109:    Logically Collective

1111:    Output Parameters:
1112: +  ctx - the context for `KSPMonitorDynamicTolerance()`
1113: -  coeff - the coefficient, default is 1.0

1115:    Options Database Key:
1116: .   -sub_ksp_dynamic_tolerance <coef> - coefficient of dynamic tolerance for inner solver, default is 1.0

1118:    Level: advanced

1120:    Note:
1121:    Use before calling `KSPMonitorSet()` and after `KSPMonitorDynamicToleranceCreate()`

1123: .seealso: [](sec_flexibleksp), `KSP`, `KSPMonitorDynamicTolerance()`, `KSPMonitorDynamicToleranceDestroy()`, `KSPMonitorDynamicToleranceCreate()`
1124: @*/
1125: PetscErrorCode KSPMonitorDynamicToleranceSetCoefficient(void *ctx, PetscReal coeff)
1126: {
1127:   KSPDynTolCtx *scale = (KSPDynTolCtx *)ctx;

1129:   PetscFunctionBegin;
1130:   scale->coef = coeff;
1131:   PetscFunctionReturn(PETSC_SUCCESS);
1132: }

1134: /*@C
1135:    KSPMonitorDynamicTolerance - A monitor that changes the inner tolerance of nested preconditioners in every outer iteration in an adaptive way.

1137:    Collective

1139:    Input Parameters:
1140: +  ksp   - iterative context
1141: .  n     - iteration number (not used)
1142: .  fnorm - the current residual norm
1143: -  ctx   - context used by monitor

1145:    Options Database Key:
1146: .   -sub_ksp_dynamic_tolerance <coef> - coefficient of dynamic tolerance for inner solver, default is 1.0

1148:    Level: advanced

1150:    Notes:
1151:    Applies for `PCKSP`, `PCBJACOBI`, and `PCDEFLATION` preconditioners

1153:    This may be useful for a flexible preconditioned Krylov method, such as `KSPFGMRES`, [](sec_flexibleksp) to
1154:    control the accuracy of the inner solves needed to guarantee convergence of the outer iterations.

1156:    This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
1157:    to be used during the `KSP` solve.

1159:    Use `KSPMonitorDynamicToleranceCreate()` and `KSPMonitorDynamicToleranceSetCoefficient()` to create the context needed by this
1160:    monitor function.

1162:    Pass the context and `KSPMonitorDynamicToleranceDestroy()` to `KSPMonitorSet()`

1164: .seealso: [](sec_flexibleksp), `KSP`, `KSPMonitorDynamicToleranceCreate()`, `KSPMonitorDynamicToleranceDestroy()`, `KSPMonitorDynamicToleranceSetCoefficient()`
1165: @*/
1166: PetscErrorCode KSPMonitorDynamicTolerance(KSP ksp, PetscInt its, PetscReal fnorm, void *dummy)
1167: {
1168:   PC            pc;
1169:   PetscReal     outer_rtol, outer_abstol, outer_dtol, inner_rtol;
1170:   PetscInt      outer_maxits, nksp, first, i;
1171:   KSPDynTolCtx *scale  = (KSPDynTolCtx *)dummy;
1172:   KSP          *subksp = NULL;
1173:   KSP           kspinner;
1174:   PetscBool     flg;

1176:   PetscFunctionBegin;
1177:   PetscCall(KSPGetPC(ksp, &pc));

1179:   /* compute inner_rtol */
1180:   if (scale->bnrm < 0.0) {
1181:     Vec b;
1182:     PetscCall(KSPGetRhs(ksp, &b));
1183:     PetscCall(VecNorm(b, NORM_2, &(scale->bnrm)));
1184:   }
1185:   PetscCall(KSPGetTolerances(ksp, &outer_rtol, &outer_abstol, &outer_dtol, &outer_maxits));
1186:   inner_rtol = PetscMin(scale->coef * scale->bnrm * outer_rtol / fnorm, 0.999);

1188:   /* if pc is ksp */
1189:   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCKSP, &flg));
1190:   if (flg) {
1191:     PetscCall(PCKSPGetKSP(pc, &kspinner));
1192:     PetscCall(KSPSetTolerances(kspinner, inner_rtol, outer_abstol, outer_dtol, outer_maxits));
1193:     PetscFunctionReturn(PETSC_SUCCESS);
1194:   }

1196:   /* if pc is bjacobi */
1197:   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCBJACOBI, &flg));
1198:   if (flg) {
1199:     PetscCall(PCBJacobiGetSubKSP(pc, &nksp, &first, &subksp));
1200:     if (subksp) {
1201:       for (i = 0; i < nksp; i++) PetscCall(KSPSetTolerances(subksp[i], inner_rtol, outer_abstol, outer_dtol, outer_maxits));
1202:       PetscFunctionReturn(PETSC_SUCCESS);
1203:     }
1204:   }

1206:   /* if pc is deflation*/
1207:   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCDEFLATION, &flg));
1208:   if (flg) {
1209:     PetscCall(PCDeflationGetCoarseKSP(pc, &kspinner));
1210:     PetscCall(KSPSetTolerances(kspinner, inner_rtol, outer_abstol, outer_dtol, PETSC_DEFAULT));
1211:     PetscFunctionReturn(PETSC_SUCCESS);
1212:   }

1214:   /* todo: dynamic tolerance may apply to other types of pc */
1215:   PetscFunctionReturn(PETSC_SUCCESS);
1216: }

1218: /*@C
1219:      KSPMonitorDynamicToleranceDestroy - Destroy the monitor context used in `KSPMonitorDynamicTolerance()`

1221:    Input Parameter:
1222: .   ctx - the monitor context

1224:    Level: advanced

1226:    Note:
1227:    This is not called directly but is passed to `KSPMonitorSet()` along with `KSPMonitorDynamicTolerance()`

1229: .seealso: `KSP`, `KSPMonitorDynamicTolerance()`, `KSPMonitorSet()`, `KSPMonitorDynamicToleranceCreate()`
1230: @*/
1231: PetscErrorCode KSPMonitorDynamicToleranceDestroy(void **ctx)
1232: {
1233:   PetscFunctionBegin;
1234:   PetscCall(PetscFree(*ctx));
1235:   PetscFunctionReturn(PETSC_SUCCESS);
1236: }

1238: /*@C
1239:    KSPConvergedSkip - Convergence test that do not return as converged
1240:    until the maximum number of iterations is reached.

1242:    Collective

1244:    Input Parameters:
1245: +  ksp   - iterative context
1246: .  n     - iteration number
1247: .  rnorm - 2-norm residual value (may be estimated)
1248: -  dummy - unused convergence context

1250:    Output Parameter:
1251: .  reason - `KSP_CONVERGED_ITERATING`, `KSP_CONVERGED_ITS`

1253:    Level: advanced

1255:    Notes:
1256:    This should be used as the convergence test with the option
1257:    `KSPSetNormType`(ksp,`KSP_NORM_NONE`), since norms of the residual are
1258:    not computed. Convergence is then declared after the maximum number
1259:    of iterations have been reached. Useful when one is using `KSPCG` or
1260:    `KSPBCGS`. [](sec_flexibleksp)

1262: .seealso: [](ch_ksp), `KSP`, `KSPCG`, `KSPBCGS`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPSetNormType()`, [](sec_flexibleksp),
1263:           `KSPConvergedReason`
1264: @*/
1265: PetscErrorCode KSPConvergedSkip(KSP ksp, PetscInt n, PetscReal rnorm, KSPConvergedReason *reason, void *dummy)
1266: {
1267:   PetscFunctionBegin;
1270:   *reason = KSP_CONVERGED_ITERATING;
1271:   if (n >= ksp->max_it) *reason = KSP_CONVERGED_ITS;
1272:   PetscFunctionReturn(PETSC_SUCCESS);
1273: }

1275: /*@
1276:    KSPSetConvergedNegativeCurvature - Allows to declare convergence and return `KSP_CONVERGED_NEG_CURVE` when negative curvature is detected

1278:    Collective

1280:    Input Parameters:
1281: +  ksp   - iterative context
1282: -  flg   - the Boolean value

1284:    Options Database Key:
1285: .   -ksp_converged_neg_curve <bool> - Declare convergence if negative curvature is detected

1287:    Level: advanced

1289:    Notes:
1290:    This is currently used only by a subset of the Krylov solvers, namely `KSPCG`, `KSPSTCG`, `KSPQCG`, `KSPGLTR`, `KSPNASH`, and `KSPMINRES`.

1292: .seealso: [](ch_ksp), `KSP`, `KSPConvergedReason`, `KSPGetConvergedNegativeCurvature()`
1293: @*/
1294: PetscErrorCode KSPSetConvergedNegativeCurvature(KSP ksp, PetscBool flg)
1295: {
1296:   PetscFunctionBegin;
1299:   ksp->converged_neg_curve = flg;
1300:   PetscFunctionReturn(PETSC_SUCCESS);
1301: }

1303: /*@
1304:    KSPGetConvergedNegativeCurvature - Get the flag to declare convergence if negative curvature is detected

1306:    Collective

1308:    Input Parameter:
1309: .  ksp   - iterative context

1311:    Output Parameter:
1312: .  flg   - the Boolean value

1314:    Level: advanced

1316: .seealso: [](ch_ksp), `KSP`, `KSPConvergedReason`, `KSPSetConvergedNegativeCurvature()`
1317: @*/
1318: PetscErrorCode KSPGetConvergedNegativeCurvature(KSP ksp, PetscBool *flg)
1319: {
1320:   PetscFunctionBegin;
1323:   *flg = ksp->converged_neg_curve;
1324:   PetscFunctionReturn(PETSC_SUCCESS);
1325: }

1327: /*@C
1328:    KSPConvergedDefaultCreate - Creates and initializes the context used by the `KSPConvergedDefault()` function

1330:    Not Collective

1332:    Output Parameter:
1333: .  ctx - convergence context

1335:    Level: intermediate

1337: .seealso: [](ch_ksp), `KSP`, `KSPConvergedDefault()`, `KSPConvergedDefaultDestroy()`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`,
1338:           `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetUMIRNorm()`,
1339:           `KSPConvergedDefaultSetConvergedMaxits()`
1340: @*/
1341: PetscErrorCode KSPConvergedDefaultCreate(void **ctx)
1342: {
1343:   KSPConvergedDefaultCtx *cctx;

1345:   PetscFunctionBegin;
1346:   PetscCall(PetscNew(&cctx));
1347:   *ctx = cctx;
1348:   PetscFunctionReturn(PETSC_SUCCESS);
1349: }

1351: /*@
1352:    KSPConvergedDefaultSetUIRNorm - makes the default convergence test use || B*(b - A*(initial guess))||
1353:       instead of || B*b ||. In the case of right preconditioner or if `KSPSetNormType`(ksp,`KSP_NORM_UNPRECONDITIONED`)
1354:       is used there is no B in the above formula. UIRNorm is short for Use Initial Residual Norm.

1356:    Collective

1358:    Input Parameters:
1359: .  ksp   - iterative context

1361:    Options Database Key:
1362: .   -ksp_converged_use_initial_residual_norm <bool> - Use initial residual norm for computing relative convergence

1364:    Level: intermediate

1366:    Notes:
1367:    Use `KSPSetTolerances()` to alter the defaults for rtol, abstol, dtol.

1369:    The precise values of reason are macros such as `KSP_CONVERGED_RTOL`, which
1370:    are defined in petscksp.h.

1372:    If the convergence test is not `KSPConvergedDefault()` then this is ignored.

1374:    If right preconditioning is being used then B does not appear in the above formula.

1376: .seealso: [](ch_ksp), `KSP`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUMIRNorm()`, `KSPConvergedDefaultSetConvergedMaxits()`
1377: @*/
1378: PetscErrorCode KSPConvergedDefaultSetUIRNorm(KSP ksp)
1379: {
1380:   KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx *)ksp->cnvP;

1382:   PetscFunctionBegin;
1384:   if (ksp->converged != KSPConvergedDefault) PetscFunctionReturn(PETSC_SUCCESS);
1385:   PetscCheck(!ctx->mininitialrtol, PetscObjectComm((PetscObject)ksp), PETSC_ERR_ARG_WRONGSTATE, "Cannot use KSPConvergedDefaultSetUIRNorm() and KSPConvergedDefaultSetUMIRNorm() together");
1386:   ctx->initialrtol = PETSC_TRUE;
1387:   PetscFunctionReturn(PETSC_SUCCESS);
1388: }

1390: /*@
1391:    KSPConvergedDefaultSetUMIRNorm - makes the default convergence test use min(|| B*(b - A*(initial guess))||,|| B*b ||)
1392:       In the case of right preconditioner or if `KSPSetNormType`(ksp,`KSP_NORM_UNPRECONDITIONED`)
1393:       is used there is no B in the above formula. UMIRNorm is short for Use Minimum Initial Residual Norm.

1395:    Collective

1397:    Input Parameters:
1398: .  ksp   - iterative context

1400:    Options Database Key:
1401: .   -ksp_converged_use_min_initial_residual_norm <bool> - Use minimum of initial residual norm and b for computing relative convergence

1403:    Level: intermediate

1405:    Use `KSPSetTolerances()` to alter the defaults for rtol, abstol, dtol.

1407:    The precise values of reason are macros such as `KSP_CONVERGED_RTOL`, which
1408:    are defined in petscksp.h.

1410: .seealso: [](ch_ksp), `KSP`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetConvergedMaxits()`
1411: @*/
1412: PetscErrorCode KSPConvergedDefaultSetUMIRNorm(KSP ksp)
1413: {
1414:   KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx *)ksp->cnvP;

1416:   PetscFunctionBegin;
1418:   if (ksp->converged != KSPConvergedDefault) PetscFunctionReturn(PETSC_SUCCESS);
1419:   PetscCheck(!ctx->initialrtol, PetscObjectComm((PetscObject)ksp), PETSC_ERR_ARG_WRONGSTATE, "Cannot use KSPConvergedDefaultSetUIRNorm() and KSPConvergedDefaultSetUMIRNorm() together");
1420:   ctx->mininitialrtol = PETSC_TRUE;
1421:   PetscFunctionReturn(PETSC_SUCCESS);
1422: }

1424: /*@
1425:    KSPConvergedDefaultSetConvergedMaxits - allows the default convergence test to declare convergence and return `KSP_CONVERGED_ITS` if the maximum number of iterations is reached

1427:    Collective

1429:    Input Parameters:
1430: +  ksp - iterative context
1431: -  flg - boolean flag

1433:    Options Database Key:
1434: .   -ksp_converged_maxits <bool> - Declare convergence if the maximum number of iterations is reached

1436:    Level: intermediate

1438:    Note:
1439:    The precise values of reason available in `KSPConvergedReason`

1441: .seealso: [](ch_ksp), `KSP`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUMIRNorm()`, `KSPConvergedDefaultSetUIRNorm()`
1442: @*/
1443: PetscErrorCode KSPConvergedDefaultSetConvergedMaxits(KSP ksp, PetscBool flg)
1444: {
1445:   KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx *)ksp->cnvP;

1447:   PetscFunctionBegin;
1450:   if (ksp->converged != KSPConvergedDefault) PetscFunctionReturn(PETSC_SUCCESS);
1451:   ctx->convmaxits = flg;
1452:   PetscFunctionReturn(PETSC_SUCCESS);
1453: }

1455: /*@C
1456:    KSPConvergedDefault - Default code to determine convergence of the linear iterative solvers

1458:    Collective

1460:    Input Parameters:
1461: +  ksp   - iterative context
1462: .  n     - iteration number
1463: .  rnorm - residual norm (may be estimated, depending on the method may be the preconditioned residual norm)
1464: -  ctx - convergence context which must be created by `KSPConvergedDefaultCreate()`

1466:    Output Parameter:
1467: .  reason - the convergence reason; it is positive if the iteration has converged,
1468:             negative if the iteration has diverged, and `KSP_CONVERGED_ITERATING` otherwise

1470:    Options Database Keys:
1471: +   -ksp_max_it - maximum number of linear iterations
1472: .   -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e. if residual norm decreases by this factor than convergence is declared
1473: .   -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual norm is less than this then convergence is declared
1474: .   -ksp_divtol tol - if residual norm increases by this factor than divergence is declared
1475: .   -ksp_converged_use_initial_residual_norm - see `KSPConvergedDefaultSetUIRNorm()`
1476: .   -ksp_converged_use_min_initial_residual_norm - see `KSPConvergedDefaultSetUMIRNorm()`
1477: -   -ksp_converged_maxits - see `KSPConvergedDefaultSetConvergedMaxits()`

1479:    Level: advanced

1481:    Notes:
1482:    `KSPConvergedDefault()` reaches convergence when   rnorm < MAX (rtol * rnorm_0, abstol);
1483:    Divergence is detected if rnorm > dtol * rnorm_0, or when failures are detected throughout the iteration.
1484:    By default, reaching the maximum number of iterations is considered divergence (i.e. KSP_DIVERGED_ITS).
1485:    In order to have PETSc declaring convergence in such a case (i.e. `KSP_CONVERGED_ITS`), users can use `KSPConvergedDefaultSetConvergedMaxits()`

1487:    where:
1488: +     rtol - relative tolerance,
1489: .     abstol - absolute tolerance.
1490: .     dtol - divergence tolerance,
1491: -     rnorm_0 - the two norm of the right hand side (or the preconditioned norm, depending on what was set with
1492:           `KSPSetNormType()`. When initial guess is non-zero you
1493:           can call `KSPConvergedDefaultSetUIRNorm()` to use the norm of (b - A*(initial guess))
1494:           as the starting point for relative norm convergence testing, that is as rnorm_0.
1495:           Call `KSPConvergedDefaultSetUMIRNorm()` to use the minimum of the norm of (b - A*(initial guess)) and the norm of b as the starting point.

1497:    Use `KSPSetTolerances()` to alter the defaults for rtol, abstol, dtol.

1499:    Use `KSPSetNormType()` (or -ksp_norm_type <none,preconditioned,unpreconditioned,natural>) to change the norm used for computing rnorm

1501:    The precise values of reason are available in `KSPConvergedReason`

1503:    This routine is used by `KSP` by default so the user generally never needs call it directly.

1505:    Use `KSPSetConvergenceTest()` to provide your own test instead of using this one.

1507:    Call `KSPSetConvergenceTest()` with the ctx, as created above and the destruction function `KSPConvergedDefaultDestroy()`

1509: .seealso: [](ch_ksp), `KSP`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`,
1510:           `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetUMIRNorm()`, `KSPConvergedDefaultSetConvergedMaxits()`, `KSPConvergedDefaultCreate()`, `KSPConvergedDefaultDestroy()`
1511: @*/
1512: PetscErrorCode KSPConvergedDefault(KSP ksp, PetscInt n, PetscReal rnorm, KSPConvergedReason *reason, void *ctx)
1513: {
1514:   KSPConvergedDefaultCtx *cctx = (KSPConvergedDefaultCtx *)ctx;
1515:   KSPNormType             normtype;

1517:   PetscFunctionBegin;
1521:   PetscCheck(cctx, PetscObjectComm((PetscObject)ksp), PETSC_ERR_ARG_NULL, "Convergence context must have been created with KSPConvergedDefaultCreate()");
1522:   *reason = KSP_CONVERGED_ITERATING;

1524:   if (cctx->convmaxits && n >= ksp->max_it) {
1525:     *reason = KSP_CONVERGED_ITS;
1526:     PetscCall(PetscInfo(ksp, "Linear solver has converged. Maximum number of iterations reached %" PetscInt_FMT "\n", n));
1527:     PetscFunctionReturn(PETSC_SUCCESS);
1528:   }
1529:   PetscCall(KSPGetNormType(ksp, &normtype));
1530:   if (normtype == KSP_NORM_NONE) PetscFunctionReturn(PETSC_SUCCESS);

1532:   if (!n) {
1533:     /* if user gives initial guess need to compute norm of b */
1534:     if (!ksp->guess_zero && !cctx->initialrtol) {
1535:       PetscReal snorm = 0.0;
1536:       if (ksp->normtype == KSP_NORM_UNPRECONDITIONED || ksp->pc_side == PC_RIGHT) {
1537:         PetscCall(PetscInfo(ksp, "user has provided nonzero initial guess, computing 2-norm of RHS\n"));
1538:         PetscCall(VecNorm(ksp->vec_rhs, NORM_2, &snorm)); /*     <- b'*b */
1539:       } else {
1540:         Vec z;
1541:         /* Should avoid allocating the z vector each time but cannot stash it in cctx because if KSPReset() is called the vector size might change */
1542:         PetscCall(VecDuplicate(ksp->vec_rhs, &z));
1543:         PetscCall(KSP_PCApply(ksp, ksp->vec_rhs, z));
1544:         if (ksp->normtype == KSP_NORM_PRECONDITIONED) {
1545:           PetscCall(PetscInfo(ksp, "user has provided nonzero initial guess, computing 2-norm of preconditioned RHS\n"));
1546:           PetscCall(VecNorm(z, NORM_2, &snorm)); /*    dp <- b'*B'*B*b */
1547:         } else if (ksp->normtype == KSP_NORM_NATURAL) {
1548:           PetscScalar norm;
1549:           PetscCall(PetscInfo(ksp, "user has provided nonzero initial guess, computing natural norm of RHS\n"));
1550:           PetscCall(VecDot(ksp->vec_rhs, z, &norm));
1551:           snorm = PetscSqrtReal(PetscAbsScalar(norm)); /*    dp <- b'*B*b */
1552:         }
1553:         PetscCall(VecDestroy(&z));
1554:       }
1555:       /* handle special case of zero RHS and nonzero guess */
1556:       if (!snorm) {
1557:         PetscCall(PetscInfo(ksp, "Special case, user has provided nonzero initial guess and zero RHS\n"));
1558:         snorm = rnorm;
1559:       }
1560:       if (cctx->mininitialrtol) ksp->rnorm0 = PetscMin(snorm, rnorm);
1561:       else ksp->rnorm0 = snorm;
1562:     } else {
1563:       ksp->rnorm0 = rnorm;
1564:     }
1565:     ksp->ttol = PetscMax(ksp->rtol * ksp->rnorm0, ksp->abstol);
1566:   }

1568:   if (n <= ksp->chknorm) PetscFunctionReturn(PETSC_SUCCESS);

1570:   if (PetscIsInfOrNanReal(rnorm)) {
1571:     PCFailedReason pcreason;
1572:     PetscInt       sendbuf, recvbuf;
1573:     PetscCall(PCGetFailedReasonRank(ksp->pc, &pcreason));
1574:     sendbuf = (PetscInt)pcreason;
1575:     PetscCall(MPIU_Allreduce(&sendbuf, &recvbuf, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)ksp)));
1576:     if (recvbuf) {
1577:       *reason = KSP_DIVERGED_PC_FAILED;
1578:       PetscCall(PCSetFailedReason(ksp->pc, (PCFailedReason)recvbuf));
1579:       PetscCall(PetscInfo(ksp, "Linear solver pcsetup fails, declaring divergence \n"));
1580:     } else {
1581:       *reason = KSP_DIVERGED_NANORINF;
1582:       PetscCall(PetscInfo(ksp, "Linear solver has created a not a number (NaN) as the residual norm, declaring divergence \n"));
1583:     }
1584:   } else if (rnorm <= ksp->ttol) {
1585:     if (rnorm < ksp->abstol) {
1586:       PetscCall(PetscInfo(ksp, "Linear solver has converged. Residual norm %14.12e is less than absolute tolerance %14.12e at iteration %" PetscInt_FMT "\n", (double)rnorm, (double)ksp->abstol, n));
1587:       *reason = KSP_CONVERGED_ATOL;
1588:     } else {
1589:       if (cctx->initialrtol) {
1590:         PetscCall(PetscInfo(ksp, "Linear solver has converged. Residual norm %14.12e is less than relative tolerance %14.12e times initial residual norm %14.12e at iteration %" PetscInt_FMT "\n", (double)rnorm, (double)ksp->rtol, (double)ksp->rnorm0, n));
1591:       } else {
1592:         PetscCall(PetscInfo(ksp, "Linear solver has converged. Residual norm %14.12e is less than relative tolerance %14.12e times initial right hand side norm %14.12e at iteration %" PetscInt_FMT "\n", (double)rnorm, (double)ksp->rtol, (double)ksp->rnorm0, n));
1593:       }
1594:       *reason = KSP_CONVERGED_RTOL;
1595:     }
1596:   } else if (rnorm >= ksp->divtol * ksp->rnorm0) {
1597:     PetscCall(PetscInfo(ksp, "Linear solver is diverging. Initial right hand size norm %14.12e, current residual norm %14.12e at iteration %" PetscInt_FMT "\n", (double)ksp->rnorm0, (double)rnorm, n));
1598:     *reason = KSP_DIVERGED_DTOL;
1599:   }
1600:   PetscFunctionReturn(PETSC_SUCCESS);
1601: }

1603: /*@C
1604:    KSPConvergedDefaultDestroy - Frees the space used by the `KSPConvergedDefault()` function context

1606:    Not Collective

1608:    Input Parameter:
1609: .  ctx - convergence context

1611:    Level: intermediate

1613:    Note:
1614:    Pass this function name into `KSPSetConvergenceTest()` along with the context obtained with `KSPConvergedDefaultCreate()` and `KSPConvergedDefault()`

1616: .seealso: [](ch_ksp), `KSP`, `KSPConvergedDefault()`, `KSPConvergedDefaultCreate()`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`,
1617:           `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetUMIRNorm()`
1618: @*/
1619: PetscErrorCode KSPConvergedDefaultDestroy(void *ctx)
1620: {
1621:   KSPConvergedDefaultCtx *cctx = (KSPConvergedDefaultCtx *)ctx;

1623:   PetscFunctionBegin;
1624:   PetscCall(VecDestroy(&cctx->work));
1625:   PetscCall(PetscFree(ctx));
1626:   PetscFunctionReturn(PETSC_SUCCESS);
1627: }

1629: /*
1630:    KSPBuildSolutionDefault - Default code to create/move the solution.

1632:    Collective

1634:    Input Parameters:
1635: +  ksp - iterative context
1636: -  v   - pointer to the user's vector

1638:    Output Parameter:
1639: .  V - pointer to a vector containing the solution

1641:    Level: advanced

1643:    Developers Note:
1644:    This is PETSC_EXTERN because it may be used by user written plugin `KSPType` implementations

1646: .seealso: [](ch_ksp), `KSP`, `KSPGetSolution()`, `KSPBuildResidualDefault()`
1647: */
1648: PetscErrorCode KSPBuildSolutionDefault(KSP ksp, Vec v, Vec *V)
1649: {
1650:   PetscFunctionBegin;
1651:   if (ksp->pc_side == PC_RIGHT) {
1652:     if (ksp->pc) {
1653:       PetscCheck(v, PetscObjectComm((PetscObject)ksp), PETSC_ERR_SUP, "Not working with right preconditioner");
1654:       PetscCall(KSP_PCApply(ksp, ksp->vec_sol, v));
1655:       *V = v;
1656:     } else {
1657:       if (v) {
1658:         PetscCall(VecCopy(ksp->vec_sol, v));
1659:         *V = v;
1660:       } else *V = ksp->vec_sol;
1661:     }
1662:   } else if (ksp->pc_side == PC_SYMMETRIC) {
1663:     if (ksp->pc) {
1664:       PetscCheck(!ksp->transpose_solve, PetscObjectComm((PetscObject)ksp), PETSC_ERR_SUP, "Not working with symmetric preconditioner and transpose solve");
1665:       PetscCheck(v, PetscObjectComm((PetscObject)ksp), PETSC_ERR_SUP, "Not working with symmetric preconditioner");
1666:       PetscCall(PCApplySymmetricRight(ksp->pc, ksp->vec_sol, v));
1667:       *V = v;
1668:     } else {
1669:       if (v) {
1670:         PetscCall(VecCopy(ksp->vec_sol, v));
1671:         *V = v;
1672:       } else *V = ksp->vec_sol;
1673:     }
1674:   } else {
1675:     if (v) {
1676:       PetscCall(VecCopy(ksp->vec_sol, v));
1677:       *V = v;
1678:     } else *V = ksp->vec_sol;
1679:   }
1680:   PetscFunctionReturn(PETSC_SUCCESS);
1681: }

1683: /*
1684:    KSPBuildResidualDefault - Default code to compute the residual.

1686:    Collecive on ksp

1688:    Input Parameters:
1689: .  ksp - iterative context
1690: .  t   - pointer to temporary vector
1691: .  v   - pointer to user vector

1693:    Output Parameter:
1694: .  V - pointer to a vector containing the residual

1696:    Level: advanced

1698:    Developers Note:
1699:    This is PETSC_EXTERN because it may be used by user written plugin `KSPType` implementations

1701: .seealso: [](ch_ksp), `KSP`, `KSPBuildSolutionDefault()`
1702: */
1703: PetscErrorCode KSPBuildResidualDefault(KSP ksp, Vec t, Vec v, Vec *V)
1704: {
1705:   Mat Amat, Pmat;

1707:   PetscFunctionBegin;
1708:   if (!ksp->pc) PetscCall(KSPGetPC(ksp, &ksp->pc));
1709:   PetscCall(PCGetOperators(ksp->pc, &Amat, &Pmat));
1710:   PetscCall(KSPBuildSolution(ksp, t, NULL));
1711:   PetscCall(KSP_MatMult(ksp, Amat, t, v));
1712:   PetscCall(VecAYPX(v, -1.0, ksp->vec_rhs));
1713:   *V = v;
1714:   PetscFunctionReturn(PETSC_SUCCESS);
1715: }

1717: /*@C
1718:   KSPCreateVecs - Gets a number of work vectors suitably sized for the operator in the `KSP`

1720:   Collective

1722:   Input Parameters:
1723: + ksp  - iterative context
1724: . rightn  - number of right work vectors
1725: - leftn   - number of left work vectors to allocate

1727:   Output Parameters:
1728: +  right - the array of vectors created
1729: -  left - the array of left vectors

1731:    Level: advanced

1733:    Notes:
1734:    The right vector has as many elements as the matrix has columns. The left
1735:      vector has as many elements as the matrix has rows.

1737:    The vectors are new vectors that are not owned by the `KSP`, they should be destroyed with calls to `VecDestroyVecs()` when no longer needed.

1739:    Developers Note:
1740:    First tries to duplicate the rhs and solution vectors of the `KSP`, if they do not exist tries to get them from the matrix, if
1741:    that does not exist tries to get them from the `DM` (if it is provided).

1743: .seealso: [](ch_ksp), `MatCreateVecs()`, `VecDestroyVecs()`, `KSPSetWorkVecs()`
1744: @*/
1745: PetscErrorCode KSPCreateVecs(KSP ksp, PetscInt rightn, Vec **right, PetscInt leftn, Vec **left)
1746: {
1747:   Vec       vecr = NULL, vecl = NULL;
1748:   PetscBool matset, pmatset, isshell, preferdm = PETSC_FALSE;
1749:   Mat       mat = NULL;

1751:   PetscFunctionBegin;
1752:   if (ksp->dm) {
1753:     PetscCall(PetscObjectTypeCompare((PetscObject)ksp->dm, DMSHELL, &isshell));
1754:     preferdm = isshell ? PETSC_FALSE : PETSC_TRUE;
1755:   }
1756:   if (rightn) {
1757:     PetscCheck(right, PetscObjectComm((PetscObject)ksp), PETSC_ERR_ARG_INCOMP, "You asked for right vectors but did not pass a pointer to hold them");
1758:     if (ksp->vec_sol) vecr = ksp->vec_sol;
1759:     else {
1760:       if (preferdm) {
1761:         PetscCall(DMGetGlobalVector(ksp->dm, &vecr));
1762:       } else if (ksp->pc) {
1763:         PetscCall(PCGetOperatorsSet(ksp->pc, &matset, &pmatset));
1764:         /* check for mat before pmat because for KSPLSQR pmat may be a different size than mat since pmat maybe mat'*mat */
1765:         if (matset) {
1766:           PetscCall(PCGetOperators(ksp->pc, &mat, NULL));
1767:           PetscCall(MatCreateVecs(mat, &vecr, NULL));
1768:         } else if (pmatset) {
1769:           PetscCall(PCGetOperators(ksp->pc, NULL, &mat));
1770:           PetscCall(MatCreateVecs(mat, &vecr, NULL));
1771:         }
1772:       }
1773:       if (!vecr && ksp->dm) PetscCall(DMGetGlobalVector(ksp->dm, &vecr));
1774:       PetscCheck(vecr, PetscObjectComm((PetscObject)ksp), PETSC_ERR_ARG_WRONGSTATE, "You requested a vector from a KSP that cannot provide one");
1775:     }
1776:     PetscCall(VecDuplicateVecs(vecr, rightn, right));
1777:     if (!ksp->vec_sol) {
1778:       if (preferdm) {
1779:         PetscCall(DMRestoreGlobalVector(ksp->dm, &vecr));
1780:       } else if (mat) {
1781:         PetscCall(VecDestroy(&vecr));
1782:       } else if (ksp->dm) {
1783:         PetscCall(DMRestoreGlobalVector(ksp->dm, &vecr));
1784:       }
1785:     }
1786:   }
1787:   if (leftn) {
1788:     PetscCheck(left, PetscObjectComm((PetscObject)ksp), PETSC_ERR_ARG_INCOMP, "You asked for left vectors but did not pass a pointer to hold them");
1789:     if (ksp->vec_rhs) vecl = ksp->vec_rhs;
1790:     else {
1791:       if (preferdm) {
1792:         PetscCall(DMGetGlobalVector(ksp->dm, &vecl));
1793:       } else if (ksp->pc) {
1794:         PetscCall(PCGetOperatorsSet(ksp->pc, &matset, &pmatset));
1795:         /* check for mat before pmat because for KSPLSQR pmat may be a different size than mat since pmat maybe mat'*mat */
1796:         if (matset) {
1797:           PetscCall(PCGetOperators(ksp->pc, &mat, NULL));
1798:           PetscCall(MatCreateVecs(mat, NULL, &vecl));
1799:         } else if (pmatset) {
1800:           PetscCall(PCGetOperators(ksp->pc, NULL, &mat));
1801:           PetscCall(MatCreateVecs(mat, NULL, &vecl));
1802:         }
1803:       }
1804:       if (!vecl && ksp->dm) PetscCall(DMGetGlobalVector(ksp->dm, &vecl));
1805:       PetscCheck(vecl, PetscObjectComm((PetscObject)ksp), PETSC_ERR_ARG_WRONGSTATE, "You requested a vector from a KSP that cannot provide one");
1806:     }
1807:     PetscCall(VecDuplicateVecs(vecl, leftn, left));
1808:     if (!ksp->vec_rhs) {
1809:       if (preferdm) {
1810:         PetscCall(DMRestoreGlobalVector(ksp->dm, &vecl));
1811:       } else if (mat) {
1812:         PetscCall(VecDestroy(&vecl));
1813:       } else if (ksp->dm) {
1814:         PetscCall(DMRestoreGlobalVector(ksp->dm, &vecl));
1815:       }
1816:     }
1817:   }
1818:   PetscFunctionReturn(PETSC_SUCCESS);
1819: }

1821: /*@C
1822:   KSPSetWorkVecs - Sets a number of work vectors into a `KSP` object

1824:   Collective

1826:   Input Parameters:
1827: + ksp  - iterative context
1828: - nw   - number of work vectors to allocate

1830:   Level: developer

1832:   Developers Note:
1833:   This is PETSC_EXTERN because it may be used by user written plugin `KSPType` implementations

1835: .seealso: [](ch_ksp), `KSP`, `KSPCreateVecs()`
1836: @*/
1837: PetscErrorCode KSPSetWorkVecs(KSP ksp, PetscInt nw)
1838: {
1839:   PetscFunctionBegin;
1840:   PetscCall(VecDestroyVecs(ksp->nwork, &ksp->work));
1841:   ksp->nwork = nw;
1842:   PetscCall(KSPCreateVecs(ksp, nw, &ksp->work, 0, NULL));
1843:   PetscFunctionReturn(PETSC_SUCCESS);
1844: }

1846: /*
1847:   KSPDestroyDefault - Destroys a iterative context variable for methods with no separate context.  Preferred calling sequence `KSPDestroy()`.

1849:   Input Parameter:
1850: . ksp - the iterative context

1852:    Developers Note:
1853:    This is PETSC_EXTERN because it may be used by user written plugin `KSPType` implementations

1855: */
1856: PetscErrorCode KSPDestroyDefault(KSP ksp)
1857: {
1858:   PetscFunctionBegin;
1860:   PetscCall(PetscFree(ksp->data));
1861:   PetscFunctionReturn(PETSC_SUCCESS);
1862: }

1864: /*@
1865:    KSPGetConvergedReason - Gets the reason the `KSP` iteration was stopped.

1867:    Not Collective

1869:    Input Parameter:
1870: .  ksp - the `KSP` context

1872:    Output Parameter:
1873: .  reason - negative value indicates diverged, positive value converged, see `KSPConvergedReason` for the possible values

1875:    Options Database Key:
1876: .   -ksp_converged_reason - prints the reason to standard out

1878:    Level: intermediate

1880:    Notes:
1881:     If this routine is called before or doing the `KSPSolve()` the value of `KSP_CONVERGED_ITERATING` is returned

1883: .seealso: [](ch_ksp), `KSPConvergedReason`, `KSP`, `KSPSetConvergenceTest()`, `KSPConvergedDefault()`, `KSPSetTolerances()`, `KSPConvergedReason`,
1884:           `KSPConvergedReasonView()`
1885: @*/
1886: PetscErrorCode KSPGetConvergedReason(KSP ksp, KSPConvergedReason *reason)
1887: {
1888:   PetscFunctionBegin;
1891:   *reason = ksp->reason;
1892:   PetscFunctionReturn(PETSC_SUCCESS);
1893: }

1895: /*@C
1896:    KSPGetConvergedReasonString - Return a human readable string for a `KSPConvergedReason`

1898:    Not Collective

1900:    Input Parameter:
1901: .  ksp - the `KSP` context

1903:    Output Parameter:
1904: .  strreason - a human readable string that describes ksp converged reason

1906:    Level: beginner

1908: .seealso: [](ch_ksp), `KSP`, `KSPGetConvergedReason()`
1909: @*/
1910: PetscErrorCode KSPGetConvergedReasonString(KSP ksp, const char **strreason)
1911: {
1912:   PetscFunctionBegin;
1915:   *strreason = KSPConvergedReasons[ksp->reason];
1916:   PetscFunctionReturn(PETSC_SUCCESS);
1917: }

1919: #include <petsc/private/dmimpl.h>
1920: /*@
1921:    KSPSetDM - Sets the `DM` that may be used by some preconditioners

1923:    Logically Collective

1925:    Input Parameters:
1926: +  ksp - the `KSP`
1927: -  dm - the `DM`, cannot be `NULL` to remove a previously set `DM`

1929:    Level: intermediate

1931:    Notes:
1932:    If this is used then the `KSP` will attempt to use the `DM` to create the matrix and use the routine set with
1933:    `DMKSPSetComputeOperators()`. Use `KSPSetDMActive`(ksp,`PETSC_FALSE`) to instead use the matrix you've provided with
1934:    `KSPSetOperators()`.

1936:    A `DM` can only be used for solving one problem at a time because information about the problem is stored on the `DM`,
1937:    even when not using interfaces like `DMKSPSetComputeOperators()`.  Use `DMClone()` to get a distinct `DM` when solving
1938:    different problems using the same function space.

1940: .seealso: [](ch_ksp), `KSP`, `DM`, `KSPGetDM()`, `KSPSetDMActive()`, `KSPSetComputeOperators()`, `KSPSetComputeRHS()`, `KSPSetComputeInitialGuess()`, `DMKSPSetComputeOperators()`, `DMKSPSetComputeRHS()`, `DMKSPSetComputeInitialGuess()`
1941: @*/
1942: PetscErrorCode KSPSetDM(KSP ksp, DM dm)
1943: {
1944:   PC pc;

1946:   PetscFunctionBegin;
1949:   PetscCall(PetscObjectReference((PetscObject)dm));
1950:   if (ksp->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */
1951:     if (ksp->dm->dmksp && !dm->dmksp) {
1952:       DMKSP kdm;
1953:       PetscCall(DMCopyDMKSP(ksp->dm, dm));
1954:       PetscCall(DMGetDMKSP(ksp->dm, &kdm));
1955:       if (kdm->originaldm == ksp->dm) kdm->originaldm = dm; /* Grant write privileges to the replacement DM */
1956:     }
1957:     PetscCall(DMDestroy(&ksp->dm));
1958:   }
1959:   ksp->dm     = dm;
1960:   ksp->dmAuto = PETSC_FALSE;
1961:   PetscCall(KSPGetPC(ksp, &pc));
1962:   PetscCall(PCSetDM(pc, dm));
1963:   ksp->dmActive = PETSC_TRUE;
1964:   PetscFunctionReturn(PETSC_SUCCESS);
1965: }

1967: /*@
1968:    KSPSetDMActive - Indicates the `DM` should be used to generate the linear system matrix and right hand side vector

1970:    Logically Collective

1972:    Input Parameters:
1973: +  ksp - the `KSP`
1974: -  flg - use the `DM`

1976:    Level: intermediate

1978:    Note:
1979:    By default `KSPSetDM()` sets the `DM` as active, call `KSPSetDMActive`(ksp,`PETSC_FALSE`); after `KSPSetDM`(ksp,dm) to not have the `KSP` object use the `DM` to generate the matrices.

1981: .seealso: [](ch_ksp), `KSP`, `DM`, `KSPGetDM()`, `KSPSetDM()`, `SNESSetDM()`, `KSPSetComputeOperators()`, `KSPSetComputeRHS()`, `KSPSetComputeInitialGuess()`
1982: @*/
1983: PetscErrorCode KSPSetDMActive(KSP ksp, PetscBool flg)
1984: {
1985:   PetscFunctionBegin;
1988:   ksp->dmActive = flg;
1989:   PetscFunctionReturn(PETSC_SUCCESS);
1990: }

1992: /*@
1993:    KSPGetDM - Gets the `DM` that may be used by some preconditioners

1995:    Not Collective

1997:    Input Parameter:
1998: . ksp - the `KSP`

2000:    Output Parameter:
2001: .  dm - the `DM`

2003:    Level: intermediate

2005: .seealso: [](ch_ksp), `KSP`, `DM`, `KSPSetDM()`, `KSPSetDMActive()`
2006: @*/
2007: PetscErrorCode KSPGetDM(KSP ksp, DM *dm)
2008: {
2009:   PetscFunctionBegin;
2011:   if (!ksp->dm) {
2012:     PetscCall(DMShellCreate(PetscObjectComm((PetscObject)ksp), &ksp->dm));
2013:     ksp->dmAuto = PETSC_TRUE;
2014:   }
2015:   *dm = ksp->dm;
2016:   PetscFunctionReturn(PETSC_SUCCESS);
2017: }

2019: /*@
2020:    KSPSetApplicationContext - Sets the optional user-defined context for the linear solver.

2022:    Logically Collective

2024:    Input Parameters:
2025: +  ksp - the `KSP` context
2026: -  usrP - optional user context

2028:    Level: intermediate

2030:    Notes:
2031:    The user context is a way for users to attach any information to the `KSP` that they may need later when interacting with the `KSP`

2033:    Use `KSPGetApplicationContext()` to get access to the context at a later time.

2035:    Fortran Note:
2036:    To use this from Fortran you must write a Fortran interface definition for this
2037:    function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.

2039: .seealso: [](ch_ksp), `KSP`, `KSPGetApplicationContext()`
2040: @*/
2041: PetscErrorCode KSPSetApplicationContext(KSP ksp, void *usrP)
2042: {
2043:   PC pc;

2045:   PetscFunctionBegin;
2047:   ksp->user = usrP;
2048:   PetscCall(KSPGetPC(ksp, &pc));
2049:   PetscCall(PCSetApplicationContext(pc, usrP));
2050:   PetscFunctionReturn(PETSC_SUCCESS);
2051: }

2053: /*@
2054:    KSPGetApplicationContext - Gets the user-defined context for the linear solver set with `KSPSetApplicationContext()`

2056:    Not Collective

2058:    Input Parameter:
2059: .  ksp - `KSP` context

2061:    Output Parameter:
2062: .  usrP - user context

2064:    Level: intermediate

2066:    Fortran Notes:
2067:    To use this from Fortran you must write a Fortran interface definition for this
2068:    function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.

2070: .seealso: [](ch_ksp), `KSP`, `KSPSetApplicationContext()`
2071: @*/
2072: PetscErrorCode KSPGetApplicationContext(KSP ksp, void *usrP)
2073: {
2074:   PetscFunctionBegin;
2076:   *(void **)usrP = ksp->user;
2077:   PetscFunctionReturn(PETSC_SUCCESS);
2078: }

2080: #include <petsc/private/pcimpl.h>

2082: /*@
2083:    KSPCheckSolve - Checks if the `PCSetUp()` or `KSPSolve()` failed and set the error flag for the outer `PC`. A `KSP_DIVERGED_ITS` is
2084:          not considered a failure in this context

2086:    Collective

2088:    Input Parameters:
2089: +  ksp - the linear solver `KSP` context.
2090: .  pc - the preconditioner context
2091: -  vec - a vector that will be initialized with Inf to indicate lack of convergence

2093:    Level: developer

2095:    Note:
2096:    This is called within `KSPSolve()` and `PCApply()` to check if an error has been detected on any particular MPI ranks. By initializing the vector
2097:    with Inf the next call to `KSPCheckNorm()` or `KSPCheckDot()` will provide the same information to all the MPI ranks that an error occurred on
2098:    at least one of the ranks.

2100:    This may be called by a subset of the processes in the `PC`.

2102:    Developer Note:
2103:    This is used to manage returning with appropriate information from preconditioners whose inner `KSP` solvers have failed in some way

2105: .seealso: [](ch_ksp), `KSP`, `KSPCreate()`, `KSPSetType()`, `KSP`, `KSPCheckNorm()`, `KSPCheckDot()`
2106: @*/
2107: PetscErrorCode KSPCheckSolve(KSP ksp, PC pc, Vec vec)
2108: {
2109:   PCFailedReason pcreason;
2110:   PC             subpc;

2112:   PetscFunctionBegin;
2113:   PetscCall(KSPGetPC(ksp, &subpc));
2114:   PetscCall(PCGetFailedReason(subpc, &pcreason));
2115:   if (pcreason || (ksp->reason < 0 && ksp->reason != KSP_DIVERGED_ITS)) {
2116:     PetscCheck(!pc->erroriffailure, PETSC_COMM_SELF, PETSC_ERR_NOT_CONVERGED, "Detected not converged in KSP inner solve: KSP reason %s PC reason %s", KSPConvergedReasons[ksp->reason], PCFailedReasons[pcreason]);
2117:     PetscCall(PetscInfo(ksp, "Detected not converged in KSP inner solve: KSP reason %s PC reason %s\n", KSPConvergedReasons[ksp->reason], PCFailedReasons[pcreason]));
2118:     pc->failedreason = PC_SUBPC_ERROR;
2119:     if (vec) PetscCall(VecSetInf(vec));
2120:   }
2121:   PetscFunctionReturn(PETSC_SUCCESS);
2122: }