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:   Notes:
 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:   Certain solvers, under certain conditions, may not compute the final residual norm in an iteration, in that case the previous norm is returned.

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

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

 46:   Not Collective

 48:   Input Parameter:
 49: . ksp - the iterative context

 51:   Output Parameter:
 52: . its - number of iterations

 54:   Level: intermediate

 56:   Note:
 57:   During the ith iteration this returns i-1

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

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

 73:   Not Collective

 75:   Input Parameter:
 76: . ksp - the iterative context

 78:   Output Parameter:
 79: . its - total number of iterations

 81:   Level: intermediate

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

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

 98: /*@
 99:   KSPMonitorResidual - Print the (possibly preconditioned, possibly approximate) residual norm at each iteration of an iterative solver.

101:   Collective

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

109:   Options Database Key:
110: . -ksp_monitor - Activates `KSPMonitorResidual()` to print the norm value at each iteration

112:   Level: intermediate

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

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

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

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

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

147: /*@
148:   KSPMonitorResidualView - Plots the (possibly preconditioned) residual at each iteration of an iterative solver.

150:   Collective

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

158:   Options Database Key:
159: . -ksp_monitor viewertype - Activates `KSPMonitorResidualView()`

161:   Level: intermediate

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

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

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

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

191:   Collective

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

199:   Options Database Key:
200: . -ksp_monitor draw::draw_lg - Activates `KSPMonitorResidualDrawLG()`

202:   Level: intermediate

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

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

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

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

238: /*@
239:   KSPMonitorResidualDrawLGCreate - Creates the context for the (possibly preconditioned) residual norm monitor `KSPMonitorResidualDrawLG()`

241:   Collective

243:   Input Parameters:
244: + viewer - The `PetscViewer` of type `PETSCVIEWERDRAW`
245: . format - The viewer format
246: - ctx    - An optional application context

248:   Output Parameter:
249: . vf - The viewer context

251:   Level: intermediate

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

265: PetscErrorCode KSPMonitorRange_Private(KSP ksp, PetscInt it, PetscReal *per)
266: {
267:   Vec                resid;
268:   const PetscScalar *r;
269:   PetscReal          rmax;
270:   PetscInt           i, n, N;

272:   PetscFunctionBegin;
273:   PetscCall(KSPBuildResidual(ksp, NULL, NULL, &resid));
274:   PetscCall(VecNorm(resid, NORM_INFINITY, &rmax));
275:   PetscCall(VecGetLocalSize(resid, &n));
276:   PetscCall(VecGetSize(resid, &N));
277:   PetscCall(VecGetArrayRead(resid, &r));
278:   *per = 0.0;
279:   for (i = 0; i < n; ++i) *per += (PetscAbsScalar(r[i]) > .20 * rmax);
280:   PetscCall(VecRestoreArrayRead(resid, &r));
281:   PetscCall(VecDestroy(&resid));
282:   PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, per, 1, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)ksp)));
283:   *per = *per / N;
284:   PetscFunctionReturn(PETSC_SUCCESS);
285: }

287: /*@
288:   KSPMonitorResidualRange - Prints the percentage of residual elements that are more than 10 percent of the maximum value.

290:   Collective

292:   Input Parameters:
293: + ksp   - iterative context
294: . it    - iteration number
295: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
296: - vf    - The viewer context

298:   Options Database Key:
299: . -ksp_monitor_range - Activates `KSPMonitorResidualRange()`

301:   Level: intermediate

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

307: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorResidual()`
308: @*/
309: PetscErrorCode KSPMonitorResidualRange(KSP ksp, PetscInt it, PetscReal rnorm, PetscViewerAndFormat *vf)
310: {
311:   static PetscReal  prev;
312:   PetscViewer       viewer = vf->viewer;
313:   PetscViewerFormat format = vf->format;
314:   PetscInt          tablevel;
315:   const char       *prefix;
316:   PetscReal         perc, rel;

318:   PetscFunctionBegin;
320:   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
321:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
322:   PetscCall(PetscViewerPushFormat(viewer, format));
323:   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
324:   if (!it) prev = rnorm;
325:   if (it == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
326:   PetscCall(KSPMonitorRange_Private(ksp, it, &perc));
327:   rel  = (prev - rnorm) / prev;
328:   prev = rnorm;
329:   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 * perc), (double)rel, (double)(rel / perc)));
330:   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
331:   PetscCall(PetscViewerPopFormat(viewer));
332:   PetscFunctionReturn(PETSC_SUCCESS);
333: }

335: /*@
336:   KSPMonitorTrueResidual - Prints the true residual norm, as well as the (possibly preconditioned, possibly approximate) residual norm,
337:   at each iteration of a `KSPSolve()` iterative solver.

339:   Collective

341:   Input Parameters:
342: + ksp   - iterative context
343: . n     - iteration number
344: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
345: - vf    - The viewer context

347:   Options Database Key:
348: . -ksp_monitor_true_residual - Activates `KSPMonitorTrueResidual()` to print both norm values at each iteration

350:   Level: intermediate

352:   Notes:
353:   When using right preconditioning, the two norm values are equivalent.

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

358: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`, `PetscViewerAndFormat`
359: @*/
360: PetscErrorCode KSPMonitorTrueResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
361: {
362:   PetscViewer       viewer = vf->viewer;
363:   PetscViewerFormat format = vf->format;
364:   Vec               r;
365:   PetscReal         truenorm, bnorm;
366:   char              normtype[256];
367:   PetscInt          tablevel;
368:   const char       *prefix;

370:   PetscFunctionBegin;
372:   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
373:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
374:   PetscCall(PetscStrncpy(normtype, KSPNormTypes[ksp->normtype], sizeof(normtype)));
375:   PetscCall(PetscStrtolower(normtype));
376:   PetscCall(KSPBuildResidual(ksp, NULL, NULL, &r));
377:   PetscCall(VecNorm(r, NORM_2, &truenorm));
378:   PetscCall(VecNorm(ksp->vec_rhs, NORM_2, &bnorm));
379:   PetscCall(VecDestroy(&r));

381:   PetscCall(PetscViewerPushFormat(viewer, format));
382:   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
383:   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
384:   if (bnorm == 0) {
385:     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));
386:   } else {
387:     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)));
388:   }
389:   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
390:   PetscCall(PetscViewerPopFormat(viewer));
391:   PetscFunctionReturn(PETSC_SUCCESS);
392: }

394: /*@
395:   KSPMonitorTrueResidualView - Plots the true residual at each iteration of an iterative solver.

397:   Collective

399:   Input Parameters:
400: + ksp   - iterative context
401: . n     - iteration number
402: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
403: - vf    - The viewer context of type `PETSCVIEWERDRAW`

405:   Options Database Key:
406: . -ksp_monitor_true_residual viewertype - Activates `KSPMonitorTrueResidualView()`

408:   Level: intermediate

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

414: .seealso: [](ch_ksp), `PETSCVIEWERDRAW`, `KSP`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorResidual()`,
415:           `KSPMonitorTrueResidualDrawLG()`, `PetscViewerAndFormat`
416: @*/
417: PetscErrorCode KSPMonitorTrueResidualView(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
418: {
419:   PetscViewer       viewer = vf->viewer;
420:   PetscViewerFormat format = vf->format;
421:   Vec               r;

423:   PetscFunctionBegin;
425:   PetscCall(PetscViewerPushFormat(viewer, format));
426:   PetscCall(KSPBuildResidual(ksp, NULL, NULL, &r));
427:   PetscCall(PetscObjectSetName((PetscObject)r, "True Residual"));
428:   PetscCall(PetscObjectCompose((PetscObject)r, "__Vec_bc_zero__", (PetscObject)ksp));
429:   PetscCall(VecView(r, viewer));
430:   PetscCall(PetscObjectCompose((PetscObject)r, "__Vec_bc_zero__", NULL));
431:   PetscCall(VecDestroy(&r));
432:   PetscCall(PetscViewerPopFormat(viewer));
433:   PetscFunctionReturn(PETSC_SUCCESS);
434: }

436: /*@
437:   KSPMonitorTrueResidualDrawLG - Plots the true residual norm at each iteration of an iterative solver.

439:   Collective

441:   Input Parameters:
442: + ksp   - iterative context
443: . n     - iteration number
444: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
445: - vf    - The viewer context

447:   Options Database Key:
448: . -ksp_monitor_true_residual draw::draw_lg - Activates `KSPMonitorTrueResidualDrawLG()`

450:   Level: intermediate

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

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

458: .seealso: [](ch_ksp), `PETSCVIEWERDRAW`, `KSP`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorTrueResidualDraw()`, `KSPMonitorResidual`,
459:           `KSPMonitorTrueResidualDrawLGCreate()`
460: @*/
461: PetscErrorCode KSPMonitorTrueResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
462: {
463:   PetscViewer        viewer = vf->viewer;
464:   PetscViewerFormat  format = vf->format;
465:   Vec                r;
466:   KSPConvergedReason reason;
467:   PetscReal          truenorm, x[2], y[2];
468:   PetscDrawLG        lg;

470:   PetscFunctionBegin;
472:   PetscCall(KSPBuildResidual(ksp, NULL, NULL, &r));
473:   PetscCall(VecNorm(r, NORM_2, &truenorm));
474:   PetscCall(VecDestroy(&r));
475:   PetscCall(PetscViewerPushFormat(viewer, format));
476:   PetscCall(PetscViewerDrawGetDrawLG(viewer, 0, &lg));
477:   if (!n) PetscCall(PetscDrawLGReset(lg));
478:   x[0] = (PetscReal)n;
479:   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
480:   else y[0] = -15.0;
481:   x[1] = (PetscReal)n;
482:   if (truenorm > 0.0) y[1] = PetscLog10Real(truenorm);
483:   else y[1] = -15.0;
484:   PetscCall(PetscDrawLGAddPoint(lg, x, y));
485:   PetscCall(KSPGetConvergedReason(ksp, &reason));
486:   if (n <= 20 || !(n % 5) || reason) {
487:     PetscCall(PetscDrawLGDraw(lg));
488:     PetscCall(PetscDrawLGSave(lg));
489:   }
490:   PetscCall(PetscViewerPopFormat(viewer));
491:   PetscFunctionReturn(PETSC_SUCCESS);
492: }

494: /*@
495:   KSPMonitorTrueResidualDrawLGCreate - Creates the context for the true residual monitor `KSPMonitorTrueResidualDrawLG()`

497:   Collective

499:   Input Parameters:
500: + viewer - The `PetscViewer` of type `PETSCVIEWERDRAW`
501: . format - The viewer format
502: - ctx    - An optional application context

504:   Output Parameter:
505: . vf - The viewer context

507:   Level: intermediate

509: .seealso: [](ch_ksp), `PETSCVIEWERDRAW`, `KSP`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `PetscViewerAndFormat`
510: @*/
511: PetscErrorCode KSPMonitorTrueResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, PetscCtx ctx, PetscViewerAndFormat **vf)
512: {
513:   const char *names[] = {"preconditioned", "true"};

515:   PetscFunctionBegin;
516:   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
517:   (*vf)->data = ctx;
518:   PetscCall(PetscViewerMonitorLGSetUp(viewer, NULL, NULL, "Log Residual Norm", 2, names, PETSC_DECIDE, PETSC_DECIDE, 400, 300));
519:   PetscFunctionReturn(PETSC_SUCCESS);
520: }

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

525:   Collective

527:   Input Parameters:
528: + ksp   - iterative context
529: . n     - iteration number
530: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
531: - vf    - The viewer context

533:   Options Database Key:
534: . -ksp_monitor_true_residual_max - Activates `KSPMonitorTrueResidualMax()`

536:   Level: intermediate

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

542: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`
543: @*/
544: PetscErrorCode KSPMonitorTrueResidualMax(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
545: {
546:   PetscViewer       viewer = vf->viewer;
547:   PetscViewerFormat format = vf->format;
548:   Vec               r;
549:   PetscReal         truenorm, bnorm;
550:   char              normtype[256];
551:   PetscInt          tablevel;
552:   const char       *prefix;

554:   PetscFunctionBegin;
556:   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
557:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
558:   PetscCall(PetscStrncpy(normtype, KSPNormTypes[ksp->normtype], sizeof(normtype)));
559:   PetscCall(PetscStrtolower(normtype));
560:   PetscCall(KSPBuildResidual(ksp, NULL, NULL, &r));
561:   PetscCall(VecNorm(r, NORM_INFINITY, &truenorm));
562:   PetscCall(VecNorm(ksp->vec_rhs, NORM_INFINITY, &bnorm));
563:   PetscCall(VecDestroy(&r));

565:   PetscCall(PetscViewerPushFormat(viewer, format));
566:   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
567:   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
568:   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)));
569:   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
570:   PetscCall(PetscViewerPopFormat(viewer));
571:   PetscFunctionReturn(PETSC_SUCCESS);
572: }

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

577:   Collective

579:   Input Parameters:
580: + ksp   - iterative context
581: . n     - iteration number
582: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
583: - vf    - The viewer context

585:   Options Database Key:
586: . -ksp_monitor_error - Activates `KSPMonitorError()`

588:   Level: intermediate

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

594: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`
595: @*/
596: PetscErrorCode KSPMonitorError(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
597: {
598:   PetscViewer       viewer = vf->viewer;
599:   PetscViewerFormat format = vf->format;
600:   DM                dm;
601:   Vec               sol;
602:   PetscReal        *errors;
603:   PetscInt          Nf, f;
604:   PetscInt          tablevel;
605:   const char       *prefix;

607:   PetscFunctionBegin;
609:   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
610:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
611:   PetscCall(KSPGetDM(ksp, &dm));
612:   PetscCall(DMGetNumFields(dm, &Nf));
613:   PetscCall(DMGetGlobalVector(dm, &sol));
614:   PetscCall(KSPBuildSolution(ksp, sol, NULL));
615:   /* TODO: Make a different monitor that flips sign for SNES, Newton system is A dx = -b, so we need to negate the solution */
616:   PetscCall(VecScale(sol, -1.0));
617:   PetscCall(PetscCalloc1(Nf, &errors));
618:   PetscCall(DMComputeError(dm, sol, errors, NULL));

620:   PetscCall(PetscViewerPushFormat(viewer, format));
621:   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
622:   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Error norms for %s solve.\n", prefix));
623:   PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Error norm %s", n, Nf > 1 ? "[" : ""));
624:   PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
625:   for (f = 0; f < Nf; ++f) {
626:     if (f > 0) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
627:     PetscCall(PetscViewerASCIIPrintf(viewer, "%14.12e", (double)errors[f]));
628:   }
629:   PetscCall(PetscViewerASCIIPrintf(viewer, "%s resid norm %14.12e\n", Nf > 1 ? "]" : "", (double)rnorm));
630:   PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
631:   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
632:   PetscCall(PetscViewerPopFormat(viewer));
633:   PetscCall(DMRestoreGlobalVector(dm, &sol));
634:   PetscFunctionReturn(PETSC_SUCCESS);
635: }

637: /*@
638:   KSPMonitorErrorDraw - Plots the error at each iteration of an iterative solver.

640:   Collective

642:   Input Parameters:
643: + ksp   - iterative context
644: . n     - iteration number
645: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
646: - vf    - The viewer context

648:   Options Database Key:
649: . -ksp_monitor_error draw - Activates `KSPMonitorErrorDraw()`

651:   Level: intermediate

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

657: .seealso: [](ch_ksp), `PETSCVIEWERDRAW`, `KSP`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorErrorDrawLG()`
658: @*/
659: PetscErrorCode KSPMonitorErrorDraw(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
660: {
661:   PetscViewer       viewer = vf->viewer;
662:   PetscViewerFormat format = vf->format;
663:   DM                dm;
664:   Vec               sol, e;

666:   PetscFunctionBegin;
668:   PetscCall(PetscViewerPushFormat(viewer, format));
669:   PetscCall(KSPGetDM(ksp, &dm));
670:   PetscCall(DMGetGlobalVector(dm, &sol));
671:   PetscCall(KSPBuildSolution(ksp, sol, NULL));
672:   PetscCall(DMComputeError(dm, sol, NULL, &e));
673:   PetscCall(PetscObjectSetName((PetscObject)e, "Error"));
674:   PetscCall(PetscObjectCompose((PetscObject)e, "__Vec_bc_zero__", (PetscObject)ksp));
675:   PetscCall(VecView(e, viewer));
676:   PetscCall(PetscObjectCompose((PetscObject)e, "__Vec_bc_zero__", NULL));
677:   PetscCall(VecDestroy(&e));
678:   PetscCall(DMRestoreGlobalVector(dm, &sol));
679:   PetscCall(PetscViewerPopFormat(viewer));
680:   PetscFunctionReturn(PETSC_SUCCESS);
681: }

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

686:   Collective

688:   Input Parameters:
689: + ksp   - iterative context
690: . n     - iteration number
691: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
692: - vf    - The viewer context

694:   Options Database Key:
695: . -ksp_monitor_error draw::draw_lg - Activates `KSPMonitorTrueResidualDrawLG()`

697:   Level: intermediate

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

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

705: .seealso: [](ch_ksp), `PETSCVIEWERDRAW`, `KSP`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorErrorDraw()`
706: @*/
707: PetscErrorCode KSPMonitorErrorDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
708: {
709:   PetscViewer        viewer = vf->viewer;
710:   PetscViewerFormat  format = vf->format;
711:   PetscDrawLG        lg;
712:   DM                 dm;
713:   Vec                sol;
714:   KSPConvergedReason reason;
715:   PetscReal         *x, *errors;
716:   PetscInt           Nf;

718:   PetscFunctionBegin;
720:   PetscCall(PetscViewerDrawGetDrawLG(viewer, 0, &lg));
721:   PetscCall(KSPGetDM(ksp, &dm));
722:   PetscCall(DMGetNumFields(dm, &Nf));
723:   PetscCall(DMGetGlobalVector(dm, &sol));
724:   PetscCall(KSPBuildSolution(ksp, sol, NULL));
725:   /* TODO: Make a different monitor that flips sign for SNES, Newton system is A dx = -b, so we need to negate the solution */
726:   PetscCall(VecScale(sol, -1.0));
727:   PetscCall(PetscCalloc2(Nf + 1, &x, Nf + 1, &errors));
728:   PetscCall(DMComputeError(dm, sol, errors, NULL));

730:   PetscCall(PetscViewerPushFormat(viewer, format));
731:   if (!n) PetscCall(PetscDrawLGReset(lg));
732:   for (PetscInt f = 0; f < Nf; ++f) {
733:     x[f]      = (PetscReal)n;
734:     errors[f] = errors[f] > 0.0 ? PetscLog10Real(errors[f]) : -15.;
735:   }
736:   x[Nf]      = (PetscReal)n;
737:   errors[Nf] = rnorm > 0.0 ? PetscLog10Real(rnorm) : -15.;
738:   PetscCall(PetscDrawLGAddPoint(lg, x, errors));
739:   PetscCall(KSPGetConvergedReason(ksp, &reason));
740:   if (n <= 20 || !(n % 5) || reason) {
741:     PetscCall(PetscDrawLGDraw(lg));
742:     PetscCall(PetscDrawLGSave(lg));
743:   }
744:   PetscCall(PetscViewerPopFormat(viewer));
745:   PetscFunctionReturn(PETSC_SUCCESS);
746: }

748: /*@
749:   KSPMonitorErrorDrawLGCreate - Creates the context for the error and preconditioned residual plotter `KSPMonitorErrorDrawLG()`

751:   Collective

753:   Input Parameters:
754: + viewer - The `PetscViewer`
755: . format - The viewer format
756: - ctx    - An optional application context

758:   Output Parameter:
759: . vf - The viewer context

761:   Level: intermediate

763: .seealso: [](ch_ksp), `PETSCVIEWERDRAW`, `KSP`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorErrorDrawLG()`
764: @*/
765: PetscErrorCode KSPMonitorErrorDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, PetscCtx ctx, PetscViewerAndFormat **vf)
766: {
767:   KSP      ksp = (KSP)ctx;
768:   DM       dm;
769:   char   **names;
770:   PetscInt Nf;

772:   PetscFunctionBegin;
773:   PetscCall(KSPGetDM(ksp, &dm));
774:   PetscCall(DMGetNumFields(dm, &Nf));
775:   PetscCall(PetscMalloc1(Nf + 1, &names));
776:   for (PetscInt f = 0; f < Nf; ++f) {
777:     PetscObject disc;
778:     const char *fname;
779:     char        lname[PETSC_MAX_PATH_LEN];

781:     PetscCall(DMGetField(dm, f, NULL, &disc));
782:     PetscCall(PetscObjectGetName(disc, &fname));
783:     PetscCall(PetscStrncpy(lname, fname, PETSC_MAX_PATH_LEN));
784:     PetscCall(PetscStrlcat(lname, " Error", PETSC_MAX_PATH_LEN));
785:     PetscCall(PetscStrallocpy(lname, &names[f]));
786:   }
787:   PetscCall(PetscStrallocpy("residual", &names[Nf]));
788:   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
789:   (*vf)->data = ctx;
790:   PetscCall(PetscViewerMonitorLGSetUp(viewer, NULL, NULL, "Log Error Norm", Nf + 1, (const char **)names, PETSC_DECIDE, PETSC_DECIDE, 400, 300));
791:   for (PetscInt f = 0; f <= Nf; ++f) PetscCall(PetscFree(names[f]));
792:   PetscCall(PetscFree(names));
793:   PetscFunctionReturn(PETSC_SUCCESS);
794: }

796: /*@
797:   KSPMonitorSolution - Print the solution norm at each iteration of an iterative solver.

799:   Collective

801:   Input Parameters:
802: + ksp   - iterative context
803: . n     - iteration number
804: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
805: - vf    - The viewer context

807:   Options Database Key:
808: . -ksp_monitor_solution - Activates `KSPMonitorSolution()`

810:   Level: intermediate

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

816: .seealso: [](ch_ksp), `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
817: @*/
818: PetscErrorCode KSPMonitorSolution(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
819: {
820:   PetscViewer       viewer = vf->viewer;
821:   PetscViewerFormat format = vf->format;
822:   Vec               x;
823:   PetscReal         snorm;
824:   PetscInt          tablevel;
825:   const char       *prefix;

827:   PetscFunctionBegin;
829:   PetscCall(KSPBuildSolution(ksp, NULL, &x));
830:   PetscCall(VecNorm(x, NORM_2, &snorm));
831:   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
832:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
833:   PetscCall(PetscViewerPushFormat(viewer, format));
834:   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
835:   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Solution norms for %s solve.\n", prefix));
836:   PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Solution norm %14.12e\n", n, (double)snorm));
837:   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
838:   PetscCall(PetscViewerPopFormat(viewer));
839:   PetscFunctionReturn(PETSC_SUCCESS);
840: }

842: /*@
843:   KSPMonitorSolutionDraw - Plots the solution at each iteration of an iterative solver.

845:   Collective

847:   Input Parameters:
848: + ksp   - iterative context
849: . n     - iteration number
850: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
851: - vf    - The viewer context

853:   Options Database Key:
854: . -ksp_monitor_solution draw - Activates `KSPMonitorSolutionDraw()`

856:   Level: intermediate

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

862: .seealso: [](ch_ksp), `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
863: @*/
864: PetscErrorCode KSPMonitorSolutionDraw(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
865: {
866:   PetscViewer       viewer = vf->viewer;
867:   PetscViewerFormat format = vf->format;
868:   Vec               x;

870:   PetscFunctionBegin;
872:   PetscCall(KSPBuildSolution(ksp, NULL, &x));
873:   PetscCall(PetscViewerPushFormat(viewer, format));
874:   PetscCall(PetscObjectSetName((PetscObject)x, "Solution"));
875:   PetscCall(PetscObjectCompose((PetscObject)x, "__Vec_bc_zero__", (PetscObject)ksp));
876:   PetscCall(VecView(x, viewer));
877:   PetscCall(PetscObjectCompose((PetscObject)x, "__Vec_bc_zero__", NULL));
878:   PetscCall(PetscViewerPopFormat(viewer));
879:   PetscFunctionReturn(PETSC_SUCCESS);
880: }

882: /*@
883:   KSPMonitorSolutionDrawLG - Plots the solution norm at each iteration of an iterative solver.

885:   Collective

887:   Input Parameters:
888: + ksp   - iterative context
889: . n     - iteration number
890: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
891: - vf    - The viewer context

893:   Options Database Key:
894: . -ksp_monitor_solution draw::draw_lg - Activates `KSPMonitorSolutionDrawLG()`

896:   Level: intermediate

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

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

904: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorSolutionDrawLGCreate()`
905: @*/
906: PetscErrorCode KSPMonitorSolutionDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
907: {
908:   PetscViewer        viewer = vf->viewer;
909:   PetscViewerFormat  format = vf->format;
910:   PetscDrawLG        lg;
911:   Vec                u;
912:   KSPConvergedReason reason;
913:   PetscReal          snorm, x, y;

915:   PetscFunctionBegin;
917:   PetscCall(PetscViewerDrawGetDrawLG(viewer, 0, &lg));
918:   PetscCall(KSPBuildSolution(ksp, NULL, &u));
919:   PetscCall(VecNorm(u, NORM_2, &snorm));
920:   PetscCall(PetscViewerPushFormat(viewer, format));
921:   if (!n) PetscCall(PetscDrawLGReset(lg));
922:   x = (PetscReal)n;
923:   if (snorm > 0.0) y = PetscLog10Real(snorm);
924:   else y = -15.0;
925:   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
926:   PetscCall(KSPGetConvergedReason(ksp, &reason));
927:   if (n <= 20 || !(n % 5) || reason) {
928:     PetscCall(PetscDrawLGDraw(lg));
929:     PetscCall(PetscDrawLGSave(lg));
930:   }
931:   PetscCall(PetscViewerPopFormat(viewer));
932:   PetscFunctionReturn(PETSC_SUCCESS);
933: }

935: /*@
936:   KSPMonitorSolutionDrawLGCreate - Creates the context for the `KSP` monitor `KSPMonitorSolutionDrawLG()`

938:   Collective

940:   Input Parameters:
941: + viewer - The `PetscViewer`
942: . format - The viewer format
943: - ctx    - An optional application context

945:   Output Parameter:
946: . vf - The viewer context

948:   Level: intermediate

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

954: .seealso: [](ch_ksp), `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
955: @*/
956: PetscErrorCode KSPMonitorSolutionDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, PetscCtx ctx, PetscViewerAndFormat **vf)
957: {
958:   PetscFunctionBegin;
959:   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
960:   (*vf)->data = ctx;
961:   PetscCall(PetscViewerMonitorLGSetUp(viewer, NULL, NULL, "Log Solution Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300));
962:   PetscFunctionReturn(PETSC_SUCCESS);
963: }

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

968:   Logically Collective

970:   Input Parameters:
971: + ksp   - the iterative context
972: . n     - the iteration
973: . rnorm - the two norm of the residual
974: - vf    - The viewer context

976:   Options Database Key:
977: . -ksp_monitor_singular_value - Activates `KSPMonitorSingularValue()`

979:   Level: intermediate

981:   Notes:
982:   The `KSPCG` solver uses the Lanczos technique for eigenvalue computation,
983:   while `KSPGMRES` uses the Arnoldi technique; other iterative methods do
984:   not currently compute singular values.

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

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

991: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPComputeExtremeSingularValues()`, `KSPMonitorSingularValueCreate()`
992: @*/
993: PetscErrorCode KSPMonitorSingularValue(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
994: {
995:   PetscViewer       viewer = vf->viewer;
996:   PetscViewerFormat format = vf->format;
997:   PetscReal         emin, emax;
998:   PetscInt          tablevel;
999:   const char       *prefix;

1001:   PetscFunctionBegin;
1004:   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
1005:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
1006:   PetscCall(PetscViewerPushFormat(viewer, format));
1007:   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
1008:   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
1009:   if (!ksp->calc_sings) {
1010:     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Residual norm %14.12e\n", n, (double)rnorm));
1011:   } else {
1012:     PetscCall(KSPComputeExtremeSingularValues(ksp, &emax, &emin));
1013:     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)));
1014:   }
1015:   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
1016:   PetscCall(PetscViewerPopFormat(viewer));
1017:   PetscFunctionReturn(PETSC_SUCCESS);
1018: }

1020: /*@
1021:   KSPMonitorSingularValueCreate - Creates the singular value monitor context needed by `KSPMonitorSingularValue()`

1023:   Collective

1025:   Input Parameters:
1026: + viewer - The PetscViewer
1027: . format - The viewer format
1028: - ctx    - An optional application context

1030:   Output Parameter:
1031: . vf - The viewer context

1033:   Level: intermediate

1035: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorSingularValue()`, `PetscViewer`
1036: @*/
1037: PetscErrorCode KSPMonitorSingularValueCreate(PetscViewer viewer, PetscViewerFormat format, PetscCtx ctx, PetscViewerAndFormat **vf)
1038: {
1039:   KSP ksp = (KSP)ctx;

1041:   PetscFunctionBegin;
1042:   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
1043:   (*vf)->data = ctx;
1044:   PetscCall(KSPSetComputeSingularValues(ksp, PETSC_TRUE));
1045:   PetscFunctionReturn(PETSC_SUCCESS);
1046: }

1048: /*@
1049:   KSPMonitorDynamicToleranceCreate - Creates the context used by `KSPMonitorDynamicTolerance()`

1051:   Logically Collective

1053:   Output Parameter:
1054: . ctx - a void pointer

1056:   Options Database Key:
1057: . -sub_ksp_dynamic_tolerance coef - coefficient of dynamic tolerance for inner solver, default is 1.0

1059:   Level: advanced

1061:   Note:
1062:   Use before calling `KSPMonitorSet()` with `KSPMonitorDynamicTolerance()`

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

1066: .seealso: [](sec_flexibleksp), `KSP`, `KSPMonitorDynamicTolerance()`, `KSPMonitorDynamicToleranceDestroy()`, `KSPMonitorDynamicToleranceSetCoefficient()`
1067: @*/
1068: PetscErrorCode KSPMonitorDynamicToleranceCreate(PetscCtx ctx)
1069: {
1070:   KSPDynTolCtx *scale;

1072:   PetscFunctionBegin;
1073:   PetscCall(PetscMalloc1(1, &scale));
1074:   scale->bnrm   = -1.0;
1075:   scale->coef   = 1.0;
1076:   *(void **)ctx = scale;
1077:   PetscFunctionReturn(PETSC_SUCCESS);
1078: }

1080: /*@
1081:   KSPMonitorDynamicToleranceSetCoefficient - Sets the coefficient in the context used by `KSPMonitorDynamicTolerance()`

1083:   Logically Collective

1085:   Output Parameters:
1086: + ctx   - the context for `KSPMonitorDynamicTolerance()`
1087: - coeff - the coefficient, default is 1.0

1089:   Options Database Key:
1090: . -sub_ksp_dynamic_tolerance coef - coefficient of dynamic tolerance for inner solver, default is 1.0

1092:   Level: advanced

1094:   Note:
1095:   Use before calling `KSPMonitorSet()` and after `KSPMonitorDynamicToleranceCreate()`

1097: .seealso: [](sec_flexibleksp), `KSP`, `KSPMonitorDynamicTolerance()`, `KSPMonitorDynamicToleranceDestroy()`, `KSPMonitorDynamicToleranceCreate()`
1098: @*/
1099: PetscErrorCode KSPMonitorDynamicToleranceSetCoefficient(PetscCtx ctx, PetscReal coeff)
1100: {
1101:   KSPDynTolCtx *scale = (KSPDynTolCtx *)ctx;

1103:   PetscFunctionBegin;
1104:   scale->coef = coeff;
1105:   PetscFunctionReturn(PETSC_SUCCESS);
1106: }

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

1111:   Collective

1113:   Input Parameters:
1114: + ksp   - iterative context
1115: . its   - iteration number (not used)
1116: . fnorm - the current residual norm
1117: - ctx   - context used by monitor

1119:   Options Database Key:
1120: . -sub_ksp_dynamic_tolerance coef - coefficient of dynamic tolerance for inner solver, default is 1.0

1122:   Level: advanced

1124:   Notes:
1125:   Applies for `PCKSP`, `PCBJACOBI`, and `PCDEFLATION` preconditioners

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

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

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

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

1138: .seealso: [](sec_flexibleksp), `KSP`, `KSPMonitorDynamicToleranceCreate()`, `KSPMonitorDynamicToleranceDestroy()`, `KSPMonitorDynamicToleranceSetCoefficient()`
1139: @*/
1140: PetscErrorCode KSPMonitorDynamicTolerance(KSP ksp, PetscInt its, PetscReal fnorm, PetscCtx ctx)
1141: {
1142:   PC            pc;
1143:   PetscReal     outer_rtol, outer_abstol, outer_dtol, inner_rtol;
1144:   PetscInt      outer_maxits, nksp, first, i;
1145:   KSPDynTolCtx *scale  = (KSPDynTolCtx *)ctx;
1146:   KSP          *subksp = NULL;
1147:   KSP           kspinner;
1148:   PetscBool     flg;

1150:   PetscFunctionBegin;
1151:   PetscCall(KSPGetPC(ksp, &pc));

1153:   /* compute inner_rtol */
1154:   if (scale->bnrm < 0.0) {
1155:     Vec b;
1156:     PetscCall(KSPGetRhs(ksp, &b));
1157:     PetscCall(VecNorm(b, NORM_2, &scale->bnrm));
1158:   }
1159:   PetscCall(KSPGetTolerances(ksp, &outer_rtol, &outer_abstol, &outer_dtol, &outer_maxits));
1160:   inner_rtol = PetscMin(scale->coef * scale->bnrm * outer_rtol / fnorm, 0.999);

1162:   /* if pc is ksp */
1163:   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCKSP, &flg));
1164:   if (flg) {
1165:     PetscCall(PCKSPGetKSP(pc, &kspinner));
1166:     PetscCall(KSPSetTolerances(kspinner, inner_rtol, outer_abstol, outer_dtol, outer_maxits));
1167:     PetscFunctionReturn(PETSC_SUCCESS);
1168:   }

1170:   /* if pc is bjacobi */
1171:   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCBJACOBI, &flg));
1172:   if (flg) {
1173:     PetscCall(PCBJacobiGetSubKSP(pc, &nksp, &first, &subksp));
1174:     if (subksp) {
1175:       for (i = 0; i < nksp; i++) PetscCall(KSPSetTolerances(subksp[i], inner_rtol, outer_abstol, outer_dtol, outer_maxits));
1176:       PetscFunctionReturn(PETSC_SUCCESS);
1177:     }
1178:   }

1180:   /* if pc is deflation*/
1181:   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCDEFLATION, &flg));
1182:   if (flg) {
1183:     PetscCall(PCDeflationGetCoarseKSP(pc, &kspinner));
1184:     PetscCall(KSPSetTolerances(kspinner, inner_rtol, outer_abstol, outer_dtol, PETSC_CURRENT));
1185:     PetscFunctionReturn(PETSC_SUCCESS);
1186:   }

1188:   /* TODO: dynamic tolerance may apply to other types of pc */
1189:   PetscFunctionReturn(PETSC_SUCCESS);
1190: }

1192: /*@
1193:   KSPMonitorDynamicToleranceDestroy - Destroy the monitor context used in `KSPMonitorDynamicTolerance()`

1195:   Input Parameter:
1196: . ctx - the monitor context

1198:   Level: advanced

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

1203: .seealso: [](ch_ksp), `KSP`, `KSPMonitorDynamicTolerance()`, `KSPMonitorSet()`, `KSPMonitorDynamicToleranceCreate()`
1204: @*/
1205: PetscErrorCode KSPMonitorDynamicToleranceDestroy(PetscCtxRt ctx)
1206: {
1207:   PetscFunctionBegin;
1208:   PetscCall(PetscFree(*(void **)ctx));
1209:   PetscFunctionReturn(PETSC_SUCCESS);
1210: }

1212: /*@
1213:   KSPConvergedSkip - Convergence test that do not return as converged
1214:   until the maximum number of iterations is reached.

1216:   Collective

1218:   Input Parameters:
1219: + ksp   - iterative context
1220: . n     - iteration number
1221: . rnorm - 2-norm residual value (may be estimated)
1222: - dtx   - unused convergence context

1224:   Output Parameter:
1225: . reason - `KSP_CONVERGED_ITERATING` or `KSP_CONVERGED_ITS`

1227:   Options Database Key:
1228: . -ksp_convergence_test skip - skips the test

1230:   Level: advanced

1232:   Note:
1233:   This should be used as the convergence test with the option
1234:   `KSPSetNormType`(ksp,`KSP_NORM_NONE`), since norms of the residual are
1235:   not computed. Convergence is then declared after the maximum number
1236:   of iterations have been reached. Useful when one is using `KSPCG` or
1237:   `KSPBCGS`. [](sec_flexibleksp)

1239: .seealso: [](ch_ksp), `KSP`, `KSPCG`, `KSPBCGS`, `KSPConvergenceTestFn`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPSetNormType()`, [](sec_flexibleksp),
1240:           `KSPConvergedReason`
1241: @*/
1242: PetscErrorCode KSPConvergedSkip(KSP ksp, PetscInt n, PetscReal rnorm, KSPConvergedReason *reason, PetscCtx dtx)
1243: {
1244:   PetscFunctionBegin;
1246:   PetscAssertPointer(reason, 4);
1247:   *reason = KSP_CONVERGED_ITERATING;
1248:   if (n >= ksp->max_it) *reason = KSP_CONVERGED_ITS;
1249:   PetscFunctionReturn(PETSC_SUCCESS);
1250: }

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

1255:   Collective

1257:   Input Parameters:
1258: + ksp - iterative context
1259: - flg - the Boolean value

1261:   Options Database Key:
1262: . -ksp_converged_neg_curve (true|false) - Declare convergence if negative curvature is detected

1264:   Level: advanced

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

1269: .seealso: [](ch_ksp), `KSP`, `KSPConvergedReason`, `KSPGetConvergedNegativeCurvature()`
1270: @*/
1271: PetscErrorCode KSPSetConvergedNegativeCurvature(KSP ksp, PetscBool flg)
1272: {
1273:   PetscFunctionBegin;
1276:   ksp->converged_neg_curve = flg;
1277:   PetscFunctionReturn(PETSC_SUCCESS);
1278: }

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

1283:   Collective

1285:   Input Parameter:
1286: . ksp - iterative context

1288:   Output Parameter:
1289: . flg - the Boolean value

1291:   Level: advanced

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

1304: /*@
1305:   KSPConvergedDefaultCreate - Creates and initializes the context used by the `KSPConvergedDefault()` function

1307:   Not Collective

1309:   Output Parameter:
1310: . ctx - convergence context

1312:   Level: intermediate

1314: .seealso: [](ch_ksp), `KSP`, `KSPConvergedDefault()`, `KSPConvergedDefaultDestroy()`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`,
1315:           `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetUMIRNorm()`,
1316:           `KSPConvergedDefaultSetConvergedMaxits()`
1317: @*/
1318: PetscErrorCode KSPConvergedDefaultCreate(void **ctx) PeNS
1319: {
1320:   KSPConvergedDefaultCtx *cctx;

1322:   PetscFunctionBegin;
1323:   PetscCall(PetscNew(&cctx));
1324:   *ctx = cctx;
1325:   PetscFunctionReturn(PETSC_SUCCESS);
1326: }

1328: /*@
1329:   KSPConvergedDefaultSetUIRNorm - makes the default convergence test use $ || B*(b - A*(initial guess))||$
1330:   instead of $ || B*b ||$. In the case of right preconditioner or if `KSPSetNormType`(ksp,`KSP_NORM_UNPRECONDITIONED`)
1331:   is used there is no B in the above formula.

1333:   Collective

1335:   Input Parameters:
1336: . ksp - iterative context

1338:   Options Database Key:
1339: . -ksp_converged_use_initial_residual_norm (true|false) - Use initial residual norm for computing relative convergence

1341:   Level: intermediate

1343:   Notes:
1344:   UIRNorm is short for Use Initial Residual Norm.

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

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

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

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

1355: .seealso: [](ch_ksp), `KSP`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUMIRNorm()`, `KSPConvergedDefaultSetConvergedMaxits()`
1356: @*/
1357: PetscErrorCode KSPConvergedDefaultSetUIRNorm(KSP ksp)
1358: {
1359:   KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx *)ksp->cnvP;

1361:   PetscFunctionBegin;
1363:   if (ksp->converged != KSPConvergedDefault) PetscFunctionReturn(PETSC_SUCCESS);
1364:   PetscCheck(!ctx->mininitialrtol, PetscObjectComm((PetscObject)ksp), PETSC_ERR_ARG_WRONGSTATE, "Cannot use KSPConvergedDefaultSetUIRNorm() and KSPConvergedDefaultSetUMIRNorm() together");
1365:   ctx->initialrtol = PETSC_TRUE;
1366:   PetscFunctionReturn(PETSC_SUCCESS);
1367: }

1369: /*@
1370:   KSPConvergedDefaultSetUMIRNorm - makes the default convergence test use $\min(|| B*(b - A*(initial guess))||,|| B*b ||)$
1371:   In the case of right preconditioner or if `KSPSetNormType`(ksp,`KSP_NORM_UNPRECONDITIONED`)
1372:   is used there is no $B$ in the above formula.

1374:   Collective

1376:   Input Parameters:
1377: . ksp - iterative context

1379:   Options Database Key:
1380: . -ksp_converged_use_min_initial_residual_norm (true|false) - Use minimum of initial residual norm and b for computing relative convergence

1382:   Level: intermediate

1384:   Notes:
1385:   UMIRNorm is short for Use Minimum Initial Residual Norm.

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

1389: .seealso: [](ch_ksp), `KSP`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetConvergedMaxits()`
1390: @*/
1391: PetscErrorCode KSPConvergedDefaultSetUMIRNorm(KSP ksp)
1392: {
1393:   KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx *)ksp->cnvP;

1395:   PetscFunctionBegin;
1397:   if (ksp->converged != KSPConvergedDefault) PetscFunctionReturn(PETSC_SUCCESS);
1398:   PetscCheck(!ctx->initialrtol, PetscObjectComm((PetscObject)ksp), PETSC_ERR_ARG_WRONGSTATE, "Cannot use KSPConvergedDefaultSetUIRNorm() and KSPConvergedDefaultSetUMIRNorm() together");
1399:   ctx->mininitialrtol = PETSC_TRUE;
1400:   PetscFunctionReturn(PETSC_SUCCESS);
1401: }

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

1406:   Collective

1408:   Input Parameters:
1409: + ksp - iterative context
1410: - flg - boolean flag

1412:   Options Database Key:
1413: . -ksp_converged_maxits (true|false) - Declare convergence if the maximum number of iterations is reached

1415:   Level: intermediate

1417: .seealso: [](ch_ksp), `KSP`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUMIRNorm()`, `KSPConvergedDefaultSetUIRNorm()`
1418: @*/
1419: PetscErrorCode KSPConvergedDefaultSetConvergedMaxits(KSP ksp, PetscBool flg)
1420: {
1421:   KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx *)ksp->cnvP;

1423:   PetscFunctionBegin;
1426:   if (ksp->converged != KSPConvergedDefault) PetscFunctionReturn(PETSC_SUCCESS);
1427:   ctx->convmaxits = flg;
1428:   PetscFunctionReturn(PETSC_SUCCESS);
1429: }

1431: /*@
1432:   KSPConvergedDefault - Default code to determine convergence of the linear iterative solvers

1434:   Collective

1436:   Input Parameters:
1437: + ksp   - iterative context
1438: . n     - iteration number
1439: . rnorm - residual norm (may be estimated, depending on the method may be the preconditioned residual norm)
1440: - ctx   - convergence context which must be created by `KSPConvergedDefaultCreate()`

1442:   Output Parameter:
1443: . reason - the convergence reason; it is positive if the iteration has converged,
1444:            negative if the iteration has diverged, and `KSP_CONVERGED_ITERATING` otherwise

1446:   Options Database Keys:
1447: + -ksp_max_it                                  - maximum number of linear iterations
1448: . -ksp_min_it                                  - minimum number of linear iterations, defaults to 0
1449: . -ksp_rtol rtol                               - relative tolerance used in default determination of convergence, i.e. if residual norm decreases by this factor than convergence is declared
1450: . -ksp_atol abstol                             - absolute tolerance used in default convergence test, i.e. if residual norm is less than this then convergence is declared
1451: . -ksp_divtol tol                              - if residual norm increases by this factor than divergence is declared
1452: . -ksp_converged_use_initial_residual_norm     - see `KSPConvergedDefaultSetUIRNorm()`
1453: . -ksp_converged_use_min_initial_residual_norm - see `KSPConvergedDefaultSetUMIRNorm()`
1454: - -ksp_converged_maxits                        - see `KSPConvergedDefaultSetConvergedMaxits()`

1456:   Level: advanced

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

1464:   where\:
1465: +     `rtol` - relative tolerance,
1466: .     `abstol` - absolute tolerance.
1467: .     `dtol` - divergence tolerance,
1468: -     `rnorm_0` - the two norm of the right-hand side (or the preconditioned norm, depending on what was set with
1469:   `KSPSetNormType()`). When initial guess is non-zero you
1470:   can call `KSPConvergedDefaultSetUIRNorm()` to use the norm of (b - A*(initial guess))
1471:   as the starting point for relative norm convergence testing, that is as `rnorm_0`.
1472:   Call `KSPConvergedDefaultSetUMIRNorm()` to use the minimum of the norm of (b - A*(initial guess)) and the norm of b as the starting point.
1473:   During `KSPMatSolve()`, when the iteration is performed on a whole batch of right-hand sides at once, a batch being the whole block unless `KSPSetMatSolveBatchSize()` is used,
1474:   `rnorm_0` is by default the Frobenius norm of that batch of (preconditioned) right-hand sides.

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

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

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

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

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

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

1488: .seealso: [](ch_ksp), `KSP`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`,
1489:           `KSPSetMinimumIterations()`, `KSPConvergenceTestFn`,
1490:           `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetUMIRNorm()`, `KSPConvergedDefaultSetConvergedMaxits()`, `KSPConvergedDefaultCreate()`, `KSPConvergedDefaultDestroy()`
1491: @*/
1492: PetscErrorCode KSPConvergedDefault(KSP ksp, PetscInt n, PetscReal rnorm, KSPConvergedReason *reason, PetscCtx ctx)
1493: {
1494:   KSPConvergedDefaultCtx *cctx = (KSPConvergedDefaultCtx *)ctx;
1495:   KSPNormType             normtype;

1497:   PetscFunctionBegin;
1500:   PetscAssertPointer(reason, 4);
1501:   PetscCheck(cctx, PetscObjectComm((PetscObject)ksp), PETSC_ERR_ARG_NULL, "Convergence context must have been created with KSPConvergedDefaultCreate()");
1502:   *reason = KSP_CONVERGED_ITERATING;

1504:   if (cctx->convmaxits && n >= ksp->max_it) {
1505:     *reason = KSP_CONVERGED_ITS;
1506:     PetscCall(PetscInfo(ksp, "Linear solver has converged. Maximum number of iterations reached %" PetscInt_FMT "\n", n));
1507:     PetscFunctionReturn(PETSC_SUCCESS);
1508:   }
1509:   PetscCall(KSPGetNormType(ksp, &normtype));
1510:   if (normtype == KSP_NORM_NONE) PetscFunctionReturn(PETSC_SUCCESS);

1512:   if (!n) {
1513:     /* if user gives initial guess need to compute norm of b */
1514:     if (!ksp->guess_zero && !cctx->initialrtol) {
1515:       PetscReal snorm = 0.0;
1516:       if (ksp->normtype == KSP_NORM_UNPRECONDITIONED || ksp->pc_side == PC_RIGHT) {
1517:         if (ksp->mat_rhs) {
1518:           PetscCall(PetscInfo(ksp, "user has provided nonzero initial guess, computing Frobenius norm of the batch of RHS\n"));
1519:           PetscCall(MatNorm(ksp->mat_rhs, NORM_FROBENIUS, &snorm)); /*     <- trace(B'*B) */
1520:         } else {
1521:           PetscCall(PetscInfo(ksp, "user has provided nonzero initial guess, computing 2-norm of RHS\n"));
1522:           PetscCall(VecNorm(ksp->vec_rhs, NORM_2, &snorm)); /*     <- b'*b */
1523:         }
1524:       } else if (ksp->mat_rhs) {
1525:         Mat Z;

1527:         PetscCheck(ksp->normtype != KSP_NORM_NATURAL, PetscObjectComm((PetscObject)ksp), PETSC_ERR_SUP, "KSPConvergedDefault() does not support KSP_NORM_NATURAL with a batch of right-hand sides and a nonzero initial guess, use KSPConvergedDefaultSetUIRNorm()");
1528:         /* As with the Vec below, Z cannot be stashed in cctx because the number of right-hand sides may change between solves */
1529:         PetscCall(MatDuplicate(ksp->mat_rhs, MAT_DO_NOT_COPY_VALUES, &Z));
1530:         PetscCall(KSP_PCMatApply(ksp, ksp->mat_rhs, Z));
1531:         /* KSP_PCApply() below removes the null space of Amat, so the batch of preconditioned right-hand sides must be projected as well */
1532:         PetscCall(KSP_RemoveNullSpaceMat(ksp, Z));
1533:         PetscCall(PetscInfo(ksp, "user has provided nonzero initial guess, computing Frobenius norm of the preconditioned batch of RHS\n"));
1534:         PetscCall(MatNorm(Z, NORM_FROBENIUS, &snorm)); /*    dp <- trace(B'*P'*P*B) */
1535:         PetscCall(MatDestroy(&Z));
1536:       } else {
1537:         Vec z;
1538:         /* Should avoid allocating the z vector each time but cannot stash it in cctx because if KSPReset() is called the vector size might change */
1539:         PetscCall(VecDuplicate(ksp->vec_rhs, &z));
1540:         PetscCall(KSP_PCApply(ksp, ksp->vec_rhs, z));
1541:         if (ksp->normtype == KSP_NORM_PRECONDITIONED) {
1542:           PetscCall(PetscInfo(ksp, "user has provided nonzero initial guess, computing 2-norm of preconditioned RHS\n"));
1543:           PetscCall(VecNorm(z, NORM_2, &snorm)); /*    dp <- b'*B'*B*b */
1544:         } else if (ksp->normtype == KSP_NORM_NATURAL) {
1545:           PetscScalar norm;
1546:           PetscCall(PetscInfo(ksp, "user has provided nonzero initial guess, computing natural norm of RHS\n"));
1547:           PetscCall(VecDot(ksp->vec_rhs, z, &norm));
1548:           snorm = PetscSqrtReal(PetscAbsScalar(norm)); /*    dp <- b'*B*b */
1549:         }
1550:         PetscCall(VecDestroy(&z));
1551:       }
1552:       /* handle special case of zero RHS and nonzero guess */
1553:       if (!snorm) {
1554:         PetscCall(PetscInfo(ksp, "Special case, user has provided nonzero initial guess and zero RHS\n"));
1555:         snorm = rnorm;
1556:       }
1557:       if (cctx->mininitialrtol) ksp->rnorm0 = PetscMin(snorm, rnorm);
1558:       else ksp->rnorm0 = snorm;
1559:     } else {
1560:       ksp->rnorm0 = rnorm;
1561:     }
1562:     ksp->ttol = PetscMax(ksp->rtol * ksp->rnorm0, ksp->abstol);
1563:   }

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

1567:   if (PetscIsInfOrNanReal(rnorm)) {
1568:     PCFailedReason pcreason;
1569:     PetscCall(PCReduceFailedReason(ksp->pc));
1570:     PetscCall(PCGetFailedReason(ksp->pc, &pcreason));
1571:     if (pcreason) {
1572:       *reason = KSP_DIVERGED_PC_FAILED;
1573:       PetscCall(PetscInfo(ksp, "Linear solver pcsetup fails, declaring divergence \n"));
1574:     } else {
1575:       *reason = KSP_DIVERGED_NANORINF;
1576:       PetscCall(PetscInfo(ksp, "Linear solver has created a not a number (NaN) as the residual norm, declaring divergence \n"));
1577:     }
1578:     PetscFunctionReturn(PETSC_SUCCESS);
1579:   }

1581:   if (n < ksp->min_it) PetscFunctionReturn(PETSC_SUCCESS);

1583:   if (rnorm <= ksp->ttol) {
1584:     if (rnorm < ksp->abstol) {
1585:       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));
1586:       *reason = KSP_CONVERGED_ATOL;
1587:     } else {
1588:       if (cctx->initialrtol) {
1589:         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));
1590:       } else {
1591:         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));
1592:       }
1593:       *reason = KSP_CONVERGED_RTOL;
1594:     }
1595:   } else if (rnorm >= ksp->divtol * ksp->rnorm0) {
1596:     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));
1597:     *reason = KSP_DIVERGED_DTOL;
1598:   }
1599:   PetscFunctionReturn(PETSC_SUCCESS);
1600: }

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

1605:   Not Collective

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

1610:   Level: intermediate

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

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

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

1628: /*@
1629:   KSPBuildSolutionDefault - Default code to build/move the solution.

1631:   Collective

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

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

1640:   Level: advanced

1642:   Note:
1643:   Some `KSP` methods such as `KSPGMRES` do not compute the explicit solution at each iteration, this routine takes the information
1644:   they have computed during the previous iterations and uses it to compute the explicit solution

1646:   Developer Note:
1647:   This is `PETSC_EXTERN` because it may be used by user written plugin `KSPType` implementations

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

1686: /*@
1687:   KSPBuildResidualDefault - Default code to compute the residual.

1689:   Collecive on ksp

1691:   Input Parameters:
1692: + ksp - iterative context
1693: . t   - pointer to temporary vector
1694: - v   - pointer to user vector

1696:   Output Parameter:
1697: . V - pointer to a vector containing the residual

1699:   Level: advanced

1701:   Note:
1702:   Some `KSP` methods such as `KSPGMRES` do not compute the explicit residual at each iteration, this routine takes the information
1703:   they have computed during the previous iterations and uses it to compute the explicit residual via the formula r = b - A*x.

1705:   Developer Note:
1706:   This is `PETSC_EXTERN` because it may be used by user written plugin `KSPType` implementations

1708: .seealso: [](ch_ksp), `KSP`, `KSPBuildSolutionDefault()`
1709: @*/
1710: PetscErrorCode KSPBuildResidualDefault(KSP ksp, Vec t, Vec v, Vec *V)
1711: {
1712:   Mat Amat, Pmat;

1714:   PetscFunctionBegin;
1715:   if (!ksp->pc) PetscCall(KSPGetPC(ksp, &ksp->pc));
1716:   PetscCall(PCGetOperators(ksp->pc, &Amat, &Pmat));
1717:   PetscCall(KSPBuildSolution(ksp, t, NULL));
1718:   PetscCall(KSP_MatMult(ksp, Amat, t, v));
1719:   PetscCall(VecAYPX(v, -1.0, ksp->vec_rhs));
1720:   *V = v;
1721:   PetscFunctionReturn(PETSC_SUCCESS);
1722: }

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

1727:   Collective

1729:   Input Parameters:
1730: + ksp    - iterative context
1731: . rightn - number of right work vectors to allocate
1732: - leftn  - number of left work vectors to allocate

1734:   Output Parameters:
1735: + right - the array of vectors created
1736: - left  - the array of left vectors

1738:   Level: advanced

1740:   Notes:
1741:   The right vector has as many elements as the matrix has columns. The left
1742:   vector has as many elements as the matrix has rows, see `MatSetSizes()` for details on the layout of the vectors.

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

1746:   PETSc `Vec` always have all zero entries when created with `KSPCreateVecs()` until routines such as `VecSet()` or `VecSetValues()`
1747:   are used to change the values. There is no reason to call `VecZeroEntries()` after creation.

1749:   Developer Note:
1750:   First tries to duplicate the rhs and solution vectors of the `KSP`, if they do not exist tries to get them from the matrix with `MatCreateVecs()`, if
1751:   that does not exist tries to get them from the `DM` (if it is provided) with `DMCreateGlobalVectors()`.

1753: .seealso: [](ch_ksp), `MatCreateVecs()`, `VecDestroyVecs()`, `KSPSetWorkVecs()`
1754: @*/
1755: PetscErrorCode KSPCreateVecs(KSP ksp, PetscInt rightn, Vec *right[], PetscInt leftn, Vec *left[])
1756: {
1757:   Vec       vecr = NULL, vecl = NULL;
1758:   PetscBool matset, pmatset, isshell, preferdm = PETSC_FALSE;
1759:   Mat       mat = NULL;

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

1831: /*@
1832:   KSPSetWorkVecs - Sets a number of work vectors into a `KSP` object

1834:   Collective

1836:   Input Parameters:
1837: + ksp - iterative context
1838: - nw  - number of work vectors to allocate

1840:   Level: developer

1842:   Developer Note:
1843:   This is `PETSC_EXTERN` because it may be used by user written plugin `KSPType` implementations

1845: .seealso: [](ch_ksp), `KSP`, `KSPCreateVecs()`
1846: @*/
1847: PetscErrorCode KSPSetWorkVecs(KSP ksp, PetscInt nw)
1848: {
1849:   PetscFunctionBegin;
1850:   PetscCall(VecDestroyVecs(ksp->nwork, &ksp->work));
1851:   ksp->nwork = nw;
1852:   PetscCall(KSPCreateVecs(ksp, nw, &ksp->work, 0, NULL));
1853:   PetscFunctionReturn(PETSC_SUCCESS);
1854: }

1856: /*@
1857:   KSPDestroyDefault - Destroys an iterative context variable for methods with no separate context.  Preferred calling sequence `KSPDestroy()`.

1859:   Collective

1861:   Input Parameter:
1862: . ksp - the iterative context

1864:   Level: advanced

1866:   Developer Note:
1867:   This is `PETSC_EXTERN` because it may be used by user written plugin `KSPType` implementations

1869: .seealso: [](ch_ksp), `KSP`, `KSPDestroy()`
1870: @*/
1871: PetscErrorCode KSPDestroyDefault(KSP ksp)
1872: {
1873:   PetscFunctionBegin;
1875:   PetscCall(PetscFree(ksp->data));
1876:   PetscFunctionReturn(PETSC_SUCCESS);
1877: }

1879: /*@
1880:   KSPGetConvergedReason - Gets the reason the `KSP` iteration was stopped.

1882:   Not Collective

1884:   Input Parameter:
1885: . ksp - the `KSP` context

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

1890:   Options Database Key:
1891: . -ksp_converged_reason - prints the reason to standard out when the solve ends

1893:   Level: intermediate

1895:   Note:
1896:   If this routine is called before or doing the `KSPSolve()` the value of `KSP_CONVERGED_ITERATING` is returned

1898: .seealso: [](ch_ksp), `KSPConvergedReason`, `KSP`, `KSPSetConvergenceTest()`, `KSPConvergedDefault()`, `KSPSetTolerances()`,
1899:           `KSPConvergedReasonView()`, `KSPGetConvergedReasonString()`
1900: @*/
1901: PetscErrorCode KSPGetConvergedReason(KSP ksp, KSPConvergedReason *reason)
1902: {
1903:   PetscFunctionBegin;
1905:   PetscAssertPointer(reason, 2);
1906:   *reason = ksp->reason;
1907:   PetscFunctionReturn(PETSC_SUCCESS);
1908: }

1910: /*@
1911:   KSPGetConvergedReasonString - Return a human readable string for a `KSPConvergedReason`

1913:   Not Collective

1915:   Input Parameter:
1916: . ksp - the `KSP` context

1918:   Output Parameter:
1919: . strreason - a human readable string that describes ksp converged reason

1921:   Level: beginner

1923: .seealso: [](ch_ksp), `KSP`, `KSPGetConvergedReason()`
1924: @*/
1925: PetscErrorCode KSPGetConvergedReasonString(KSP ksp, const char *strreason[])
1926: {
1927:   PetscFunctionBegin;
1929:   PetscAssertPointer(strreason, 2);
1930:   *strreason = KSPConvergedReasons[ksp->reason];
1931:   PetscFunctionReturn(PETSC_SUCCESS);
1932: }

1934: #include <petsc/private/dmimpl.h>
1935: /*@
1936:   KSPSetDM - Sets the `DM` that may be used by some preconditioners and that may be used to construct the linear system

1938:   Logically Collective

1940:   Input Parameters:
1941: + ksp - the `KSP`
1942: - dm  - the `DM`, cannot be `NULL` to remove a previously set `DM`

1944:   Level: intermediate

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

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

1955: .seealso: [](ch_ksp), `KSP`, `DM`, `KSPGetDM()`, `KSPSetDMActive()`, `KSPSetComputeOperators()`, `KSPSetComputeRHS()`, `KSPSetComputeInitialGuess()`, `DMKSPSetComputeOperators()`, `DMKSPSetComputeRHS()`, `DMKSPSetComputeInitialGuess()`
1956: @*/
1957: PetscErrorCode KSPSetDM(KSP ksp, DM dm)
1958: {
1959:   PetscFunctionBegin;
1962:   PetscCall(PetscObjectReference((PetscObject)dm));
1963:   if (ksp->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */
1964:     if (ksp->dm->dmksp && !dm->dmksp) {
1965:       DMKSP kdm;
1966:       PetscCall(DMCopyDMKSP(ksp->dm, dm));
1967:       PetscCall(DMGetDMKSP(ksp->dm, &kdm));
1968:       if (kdm->originaldm == ksp->dm) kdm->originaldm = dm; /* Grant write privileges to the replacement DM */
1969:     }
1970:     PetscCall(DMDestroy(&ksp->dm));
1971:   }
1972:   ksp->dm       = dm;
1973:   ksp->dmAuto   = PETSC_FALSE;
1974:   ksp->dmActive = KSP_DMACTIVE_ALL;
1975:   if (ksp->pc) PetscCall(PCSetDM(ksp->pc, dm));
1976:   PetscFunctionReturn(PETSC_SUCCESS);
1977: }

1979: /*@
1980:   KSPSetDMActive - Indicates the `DM` should be used to generate the linear system matrix, the right-hand side vector, and the initial guess

1982:   Logically Collective

1984:   Input Parameters:
1985: + ksp    - the `KSP`
1986: . active - one of `KSP_DMACTIVE_OPERATOR`, `KSP_DMACTIVE_RHS`, or `KSP_DMACTIVE_INITIAL_GUESS`
1987: - flg    - use the `DM`

1989:   Level: intermediate

1991:   Note:
1992:   By default `KSPSetDM()` sets the `DM` as active.

1994: .seealso: [](ch_ksp), `KSP`, `DM`, `KSPGetDM()`, `KSPSetDM()`, `SNESSetDM()`, `KSPSetComputeOperators()`, `KSPSetComputeRHS()`, `KSPSetComputeInitialGuess()`
1995: @*/
1996: PetscErrorCode KSPSetDMActive(KSP ksp, KSPDMActive active, PetscBool flg)
1997: {
1998:   PetscFunctionBegin;
2001:   if (flg) ksp->dmActive = (KSPDMActive)(ksp->dmActive | active);
2002:   else ksp->dmActive = (KSPDMActive)(ksp->dmActive & ~active);
2003:   PetscFunctionReturn(PETSC_SUCCESS);
2004: }

2006: /*@
2007:   KSPGetDM - Gets the `DM` that may be used by some preconditioners and that may be used to construct the linear system

2009:   Not Collective

2011:   Input Parameter:
2012: . ksp - the `KSP`

2014:   Output Parameter:
2015: . dm - the `DM`

2017:   Level: intermediate

2019: .seealso: [](ch_ksp), `KSP`, `DM`, `KSPSetDM()`, `KSPSetDMActive()`
2020: @*/
2021: PetscErrorCode KSPGetDM(KSP ksp, DM *dm)
2022: {
2023:   PetscFunctionBegin;
2025:   if (!ksp->dm) {
2026:     PetscCall(DMShellCreate(PetscObjectComm((PetscObject)ksp), &ksp->dm));
2027:     ksp->dmAuto = PETSC_TRUE;
2028:   }
2029:   *dm = ksp->dm;
2030:   PetscFunctionReturn(PETSC_SUCCESS);
2031: }

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

2036:   Logically Collective

2038:   Input Parameters:
2039: + ksp - the `KSP` context
2040: - ctx - application context

2042:   Level: intermediate

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

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

2049:   Fortran Note:
2050:   This only works when `ctx` is a Fortran derived type (it cannot be a `PetscObject`), we recommend writing a Fortran interface definition for this
2051:   function that tells the Fortran compiler the derived data type that is passed in as the `ctx` argument. See `KSPGetApplicationContext()` for
2052:   an example.

2054: .seealso: [](ch_ksp), `KSP`, `KSPGetApplicationContext()`
2055: @*/
2056: PetscErrorCode KSPSetApplicationContext(KSP ksp, PetscCtx ctx)
2057: {
2058:   PC pc;

2060:   PetscFunctionBegin;
2062:   ksp->ctx = ctx;
2063:   PetscCall(KSPGetPC(ksp, &pc));
2064:   PetscCall(PCSetApplicationContext(pc, ctx));
2065:   PetscFunctionReturn(PETSC_SUCCESS);
2066: }

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

2071:   Not Collective

2073:   Input Parameter:
2074: . ksp - `KSP` context

2076:   Output Parameter:
2077: . ctx - a pointer to the application context

2079:   Level: intermediate

2081:   Fortran Notes:
2082:   This only works when the context is a Fortran derived type or a `PetscObject`. Define `ctx` with
2083: .vb
2084:   type(tUsertype), pointer :: ctx
2085: .ve

2087: .seealso: [](ch_ksp), `KSP`, `KSPSetApplicationContext()`
2088: @*/
2089: PetscErrorCode KSPGetApplicationContext(KSP ksp, PetscCtxRt ctx)
2090: {
2091:   PetscFunctionBegin;
2093:   *(void **)ctx = ksp->ctx;
2094:   PetscFunctionReturn(PETSC_SUCCESS);
2095: }

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

2099: static PetscErrorCode KSPCheckSolve_Private(KSP ksp, PC pc, Vec vec, Mat mat)
2100: {
2101:   PCFailedReason pcreason;
2102:   PC             subpc;
2103:   PetscBool      failed;

2105:   PetscFunctionBegin;
2106:   PetscCall(KSPGetPC(ksp, &subpc));
2107:   PetscCall(PCGetFailedReason(subpc, &pcreason));
2108:   failed = (PetscBool)(pcreason || (ksp->reason < 0 && ksp->reason != KSP_DIVERGED_ITS));
2109:   PetscCall(VecFlag(vec, failed));
2110:   PetscCall(MatFlag(mat, failed));
2111:   if (failed) {
2112:     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]);
2113:     PetscCall(PetscInfo(ksp, "Detected not converged in KSP inner solve: KSP reason %s PC reason %s\n", KSPConvergedReasons[ksp->reason], PCFailedReasons[pcreason]));
2114:     pc->failedreason = PC_SUBPC_ERROR;
2115:   }
2116:   PetscFunctionReturn(PETSC_SUCCESS);
2117: }

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

2123:   Logically Collective

2125:   Input Parameters:
2126: + ksp - the linear solver `KSP` context.
2127: . pc  - the preconditioner context
2128: - vec - a vector that will be initialized with infinity to indicate lack of convergence

2130:   Level: developer

2132:   Note:
2133:   This is called within `PCApply()` implementations to check if an error has been detected on any particular MPI processes. By initializing the vector
2134:   with infinity the next call to `KSPCheckNorm()` or `KSPCheckDot()` will provide the same information to all the MPI processes that an error occurred on
2135:   at least one of the processes.

2137:   If `vec` is `NULL`, it must be `NULL` on all calling processes.

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

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

2144: .seealso: [](ch_ksp), `KSP`, `KSPCreate()`, `KSPSetType()`, `KSPCheckNorm()`, `KSPCheckDot()`, `KSPCheckMatSolve()`
2145: @*/
2146: PetscErrorCode KSPCheckSolve(KSP ksp, PC pc, Vec vec)
2147: {
2148:   PetscFunctionBegin;
2149:   PetscCall(KSPCheckSolve_Private(ksp, pc, vec, NULL));
2150:   PetscFunctionReturn(PETSC_SUCCESS);
2151: }

2153: /*@
2154:   KSPCheckMatSolve - Checks whether an inner matrix solve failed and flags its solution and the outer preconditioner

2156:   Logically Collective

2158:   Input Parameters:
2159: + ksp - the inner linear solver context
2160: . pc  - the outer preconditioner context
2161: - mat - the `MATDENSE` solution matrix to flag

2163:   Level: developer

2165:   Notes:
2166:   This is the matrix counterpart of `KSPCheckSolve()`, for use after `KSPMatSolve()` or `KSPMatSolveTranspose()`
2167:   within a `PCMatApply()` or `PCMatApplyTranspose()` implementation.

2169:   If the inner preconditioner reports a failure, or `ksp` has a negative convergence reason other than `KSP_DIVERGED_ITS`,
2170:   the local portion of `mat` is set to infinity with `MatFlag()` and the outer `pc` is marked with `PC_SUBPC_ERROR`.
2171:   If the outer `pc` is configured to raise an error on failure, this routine raises the error after flagging `mat`.

2173:   Without a failure, the entries of `mat` are unchanged. Its object state is increased in either case.

2175:   If `mat` is `NULL`, it must be `NULL` on all calling processes.

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

2179:   Example Usage:
2180: .vb
2181:   PetscCall(KSPMatSolve(ksp, B, X));
2182:   PetscCall(KSPCheckMatSolve(ksp, pc, X));
2183: .ve

2185: .seealso: [](ch_ksp), `KSP`, `PC`, `KSPCheckSolve()`, `KSPMatSolve()`, `KSPMatSolveTranspose()`, `MatFlag()`, `PCGetFailedReason()`, `PCSetErrorIfFailure()`
2186: @*/
2187: PetscErrorCode KSPCheckMatSolve(KSP ksp, PC pc, Mat mat)
2188: {
2189:   PetscFunctionBegin;
2190:   PetscCall(KSPCheckSolve_Private(ksp, pc, NULL, mat));
2191:   PetscFunctionReturn(PETSC_SUCCESS);
2192: }