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 (approximate preconditioned)
 14:    residual norm that has been computed.

 16:    Not Collective

 18:    Input Parameters:
 19: .  ksp - the iterative context

 21:    Output Parameters:
 22: .  rnorm - residual norm

 24:    Level: intermediate

 26: .seealso: `KSPBuildResidual()`
 27: @*/
 28: PetscErrorCode KSPGetResidualNorm(KSP ksp, PetscReal *rnorm)
 29: {
 32:   *rnorm = ksp->rnorm;
 33:   return 0;
 34: }

 36: /*@
 37:    KSPGetIterationNumber - Gets the current iteration number; if the
 38:          KSPSolve() is complete, returns the number of iterations
 39:          used.

 41:    Not Collective

 43:    Input Parameters:
 44: .  ksp - the iterative context

 46:    Output Parameters:
 47: .  its - number of iterations

 49:    Level: intermediate

 51:    Notes:
 52:       During the ith iteration this returns i-1
 53: .seealso: `KSPBuildResidual()`, `KSPGetResidualNorm()`, `KSPGetTotalIterations()`
 54: @*/
 55: PetscErrorCode KSPGetIterationNumber(KSP ksp, PetscInt *its)
 56: {
 59:   *its = ksp->its;
 60:   return 0;
 61: }

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

 66:    Not Collective

 68:    Input Parameters:
 69: .  ksp - the iterative context

 71:    Output Parameters:
 72: .  its - total number of iterations

 74:    Level: intermediate

 76:    Notes:
 77:     Use KSPGetIterationNumber() to get the count for the most recent solve only
 78:    If this is called within a linear solve (such as in a KSPMonitor routine) then it does not include iterations within that current solve

 80: .seealso: `KSPBuildResidual()`, `KSPGetResidualNorm()`, `KSPGetIterationNumber()`
 81: @*/
 82: PetscErrorCode KSPGetTotalIterations(KSP ksp, PetscInt *its)
 83: {
 86:   *its = ksp->totalits;
 87:   return 0;
 88: }

 90: /*@C
 91:   KSPMonitorResidual - Print the preconditioned residual norm at each iteration of an iterative solver.

 93:   Collective on ksp

 95:   Input Parameters:
 96: + ksp   - iterative context
 97: . n     - iteration number
 98: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
 99: - vf    - The viewer context

101:   Options Database Key:
102: . -ksp_monitor - Activates KSPMonitorResidual()

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

108:   Level: intermediate

110: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`,  `KSPMonitorResidualDraw()`, `KSPMonitorResidualDrawLG()`,
111:           `KSPMonitorResidualRange()`, `KSPMonitorTrueResidualDraw()`, `KSPMonitorTrueResidualDrawLG()`, `KSPMonitorTrueResidualMax()`,
112:           `KSPMonitorSingularValue()`, `KSPMonitorSolutionDrawLG()`, `KSPMonitorSolutionDraw()`, `KSPMonitorSolution()`,
113:           `KSPMonitorErrorDrawLG()`, `KSPMonitorErrorDraw()`, KSPMonitorError()`
114: @*/
115: PetscErrorCode KSPMonitorResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
116: {
117:   PetscViewer       viewer = vf->viewer;
118:   PetscViewerFormat format = vf->format;
119:   PetscInt          tablevel;
120:   const char       *prefix;

123:   PetscObjectGetTabLevel((PetscObject)ksp, &tablevel);
124:   PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
125:   PetscViewerPushFormat(viewer, format);
126:   PetscViewerASCIIAddTab(viewer, tablevel);
127:   if (n == 0 && prefix) PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix);
128:   PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Residual norm %14.12e \n", n, (double)rnorm);
129:   PetscViewerASCIISubtractTab(viewer, tablevel);
130:   PetscViewerPopFormat(viewer);
131:   return 0;
132: }

134: /*@C
135:   KSPMonitorResidualDraw - Plots the preconditioned residual at each iteration of an iterative solver.

137:   Collective on ksp

139:   Input Parameters:
140: + ksp   - iterative context
141: . n     - iteration number
142: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
143: - vf    - The viewer context

145:   Options Database Key:
146: . -ksp_monitor draw - Activates KSPMonitorResidualDraw()

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

152:   Level: intermediate

154: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, , `KSPMonitorResidual()`, `KSPMonitorResidualDrawLG()`
155: @*/
156: PetscErrorCode KSPMonitorResidualDraw(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
157: {
158:   PetscViewer       viewer = vf->viewer;
159:   PetscViewerFormat format = vf->format;
160:   Vec               r;

163:   PetscViewerPushFormat(viewer, format);
164:   KSPBuildResidual(ksp, NULL, NULL, &r);
165:   PetscObjectSetName((PetscObject)r, "Residual");
166:   PetscObjectCompose((PetscObject)r, "__Vec_bc_zero__", (PetscObject)ksp);
167:   VecView(r, viewer);
168:   PetscObjectCompose((PetscObject)r, "__Vec_bc_zero__", NULL);
169:   VecDestroy(&r);
170:   PetscViewerPopFormat(viewer);
171:   return 0;
172: }

174: /*@C
175:   KSPMonitorResidualDrawLG - Plots the preconditioned residual norm at each iteration of an iterative solver.

177:   Collective on ksp

179:   Input Parameters:
180: + ksp   - iterative context
181: . n     - iteration number
182: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
183: - vf    - The viewer context

185:   Options Database Key:
186: . -ksp_monitor draw::draw_lg - Activates KSPMonitorResidualDrawLG()

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

192:   Level: intermediate

194: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorResidualDraw()`, `KSPMonitorResidual()`
195: @*/
196: PetscErrorCode KSPMonitorResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
197: {
198:   PetscViewer        viewer = vf->viewer;
199:   PetscViewerFormat  format = vf->format;
200:   PetscDrawLG        lg     = vf->lg;
201:   KSPConvergedReason reason;
202:   PetscReal          x, y;

206:   PetscViewerPushFormat(viewer, format);
207:   if (!n) PetscDrawLGReset(lg);
208:   x = (PetscReal)n;
209:   if (rnorm > 0.0) y = PetscLog10Real(rnorm);
210:   else y = -15.0;
211:   PetscDrawLGAddPoint(lg, &x, &y);
212:   KSPGetConvergedReason(ksp, &reason);
213:   if (n <= 20 || !(n % 5) || reason) {
214:     PetscDrawLGDraw(lg);
215:     PetscDrawLGSave(lg);
216:   }
217:   PetscViewerPopFormat(viewer);
218:   return 0;
219: }

221: /*@C
222:   KSPMonitorResidualDrawLGCreate - Creates the plotter for the preconditioned residual.

224:   Collective on ksp

226:   Input Parameters:
227: + viewer - The PetscViewer
228: . format - The viewer format
229: - ctx    - An optional user context

231:   Output Parameter:
232: . vf    - The viewer context

234:   Level: intermediate

236: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
237: @*/
238: PetscErrorCode KSPMonitorResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
239: {
240:   PetscViewerAndFormatCreate(viewer, format, vf);
241:   (*vf)->data = ctx;
242:   KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Residual Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg);
243:   return 0;
244: }

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

251:   Deprecated: Intentionally has no manual page
252: */
253: PetscErrorCode KSPMonitorResidualShort(KSP ksp, PetscInt its, PetscReal fnorm, PetscViewerAndFormat *vf)
254: {
255:   PetscViewer       viewer = vf->viewer;
256:   PetscViewerFormat format = vf->format;
257:   PetscInt          tablevel;
258:   const char       *prefix;

261:   PetscObjectGetTabLevel((PetscObject)ksp, &tablevel);
262:   PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
263:   PetscViewerPushFormat(viewer, format);
264:   PetscViewerASCIIAddTab(viewer, tablevel);
265:   if (its == 0 && prefix) PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix);
266:   if (fnorm > 1.e-9) PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Residual norm %g \n", its, (double)fnorm);
267:   else if (fnorm > 1.e-11) PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Residual norm %5.3e \n", its, (double)fnorm);
268:   else PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Residual norm < 1.e-11\n", its);
269:   PetscViewerASCIISubtractTab(viewer, tablevel);
270:   PetscViewerPopFormat(viewer);
271:   return 0;
272: }

274: PetscErrorCode KSPMonitorRange_Private(KSP ksp, PetscInt it, PetscReal *per)
275: {
276:   Vec                resid;
277:   const PetscScalar *r;
278:   PetscReal          rmax, pwork;
279:   PetscInt           i, n, N;

281:   KSPBuildResidual(ksp, NULL, NULL, &resid);
282:   VecNorm(resid, NORM_INFINITY, &rmax);
283:   VecGetLocalSize(resid, &n);
284:   VecGetSize(resid, &N);
285:   VecGetArrayRead(resid, &r);
286:   pwork = 0.0;
287:   for (i = 0; i < n; ++i) pwork += (PetscAbsScalar(r[i]) > .20 * rmax);
288:   VecRestoreArrayRead(resid, &r);
289:   VecDestroy(&resid);
290:   MPIU_Allreduce(&pwork, per, 1, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)ksp));
291:   *per = *per / N;
292:   return 0;
293: }

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

298:   Collective on ksp

300:   Input Parameters:
301: + ksp   - iterative context
302: . it    - iteration number
303: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
304: - vf    - The viewer context

306:   Options Database Key:
307: . -ksp_monitor_range - Activates KSPMonitorResidualRange()

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

313:   Level: intermediate

315: .seealso: `KSPMonitorSet()`, `KSPMonitorResidual()`
316: @*/
317: PetscErrorCode KSPMonitorResidualRange(KSP ksp, PetscInt it, PetscReal rnorm, PetscViewerAndFormat *vf)
318: {
319:   static PetscReal  prev;
320:   PetscViewer       viewer = vf->viewer;
321:   PetscViewerFormat format = vf->format;
322:   PetscInt          tablevel;
323:   const char       *prefix;
324:   PetscReal         perc, rel;

327:   PetscObjectGetTabLevel((PetscObject)ksp, &tablevel);
328:   PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
329:   PetscViewerPushFormat(viewer, format);
330:   PetscViewerASCIIAddTab(viewer, tablevel);
331:   if (!it) prev = rnorm;
332:   if (it == 0 && prefix) PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix);
333:   KSPMonitorRange_Private(ksp, it, &perc);
334:   rel  = (prev - rnorm) / prev;
335:   prev = rnorm;
336:   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));
337:   PetscViewerASCIISubtractTab(viewer, tablevel);
338:   PetscViewerPopFormat(viewer);
339:   return 0;
340: }

342: /*@C
343:   KSPMonitorTrueResidual - Prints the true residual norm, as well as the preconditioned residual norm, at each iteration of an iterative solver.

345:   Collective on ksp

347:   Input Parameters:
348: + ksp   - iterative context
349: . n     - iteration number
350: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
351: - vf    - The viewer context

353:   Options Database Key:
354: . -ksp_monitor_true_residual - Activates KSPMonitorTrueResidual()

356:   Notes:
357:   When using right preconditioning, these values are equivalent.

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

362:   Level: intermediate

364: .seealso: `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`
365: @*/
366: PetscErrorCode KSPMonitorTrueResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
367: {
368:   PetscViewer       viewer = vf->viewer;
369:   PetscViewerFormat format = vf->format;
370:   Vec               r;
371:   PetscReal         truenorm, bnorm;
372:   char              normtype[256];
373:   PetscInt          tablevel;
374:   const char       *prefix;

377:   PetscObjectGetTabLevel((PetscObject)ksp, &tablevel);
378:   PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
379:   PetscStrncpy(normtype, KSPNormTypes[ksp->normtype], sizeof(normtype));
380:   PetscStrtolower(normtype);
381:   KSPBuildResidual(ksp, NULL, NULL, &r);
382:   VecNorm(r, NORM_2, &truenorm);
383:   VecNorm(ksp->vec_rhs, NORM_2, &bnorm);
384:   VecDestroy(&r);

386:   PetscViewerPushFormat(viewer, format);
387:   PetscViewerASCIIAddTab(viewer, tablevel);
388:   if (n == 0 && prefix) PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix);
389:   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));
390:   PetscViewerASCIISubtractTab(viewer, tablevel);
391:   PetscViewerPopFormat(viewer);
392:   return 0;
393: }

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

398:   Collective on ksp

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

406:   Options Database Key:
407: . -ksp_monitor_true_residual draw - Activates KSPMonitorResidualDraw()

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

413:   Level: intermediate

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

424:   PetscViewerPushFormat(viewer, format);
425:   KSPBuildResidual(ksp, NULL, NULL, &r);
426:   PetscObjectSetName((PetscObject)r, "Residual");
427:   PetscObjectCompose((PetscObject)r, "__Vec_bc_zero__", (PetscObject)ksp);
428:   VecView(r, viewer);
429:   PetscObjectCompose((PetscObject)r, "__Vec_bc_zero__", NULL);
430:   VecDestroy(&r);
431:   PetscViewerPopFormat(viewer);
432:   return 0;
433: }

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

438:   Collective on ksp

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

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

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

453:   Level: intermediate

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

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

489: /*@C
490:   KSPMonitorTrueResidualDrawLGCreate - Creates the plotter for the preconditioned residual.

492:   Collective on ksp

494:   Input Parameters:
495: + viewer - The PetscViewer
496: . format - The viewer format
497: - ctx    - An optional user context

499:   Output Parameter:
500: . vf    - The viewer context

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

506:   Level: intermediate

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

514:   PetscViewerAndFormatCreate(viewer, format, vf);
515:   (*vf)->data = ctx;
516:   KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Residual Norm", 2, names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg);
517:   return 0;
518: }

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

523:   Collective on ksp

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

531:   Options Database Key:
532: . -ksp_monitor_true_residual_max - Activates KSPMonitorTrueResidualMax()

534:   Notes:
535:   When using right preconditioning, these values are equivalent.

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

540:   Level: intermediate

542: .seealso: `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;

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

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

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

576:   Collective on ksp

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

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

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

591:   Level: intermediate

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

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

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

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

638:   Collective on ksp

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

646:   Options Database Key:
647: . -ksp_monitor_error draw - Activates KSPMonitorErrorDraw()

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

653:   Level: intermediate

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

665:   PetscViewerPushFormat(viewer, format);
666:   KSPGetDM(ksp, &dm);
667:   DMGetGlobalVector(dm, &sol);
668:   KSPBuildSolution(ksp, sol, NULL);
669:   DMComputeError(dm, sol, NULL, &e);
670:   PetscObjectSetName((PetscObject)e, "Error");
671:   PetscObjectCompose((PetscObject)e, "__Vec_bc_zero__", (PetscObject)ksp);
672:   VecView(e, viewer);
673:   PetscObjectCompose((PetscObject)e, "__Vec_bc_zero__", NULL);
674:   VecDestroy(&e);
675:   DMRestoreGlobalVector(dm, &sol);
676:   PetscViewerPopFormat(viewer);
677:   return 0;
678: }

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

683:   Collective on ksp

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

691:   Options Database Key:
692: . -ksp_monitor_error draw::draw_lg - Activates KSPMonitorTrueResidualDrawLG()

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

698:   Level: intermediate

700: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
701: @*/
702: PetscErrorCode KSPMonitorErrorDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
703: {
704:   PetscViewer        viewer = vf->viewer;
705:   PetscViewerFormat  format = vf->format;
706:   PetscDrawLG        lg     = vf->lg;
707:   DM                 dm;
708:   Vec                sol;
709:   KSPConvergedReason reason;
710:   PetscReal         *x, *errors;
711:   PetscInt           Nf, f;

715:   KSPGetDM(ksp, &dm);
716:   DMGetNumFields(dm, &Nf);
717:   DMGetGlobalVector(dm, &sol);
718:   KSPBuildSolution(ksp, sol, NULL);
719:   /* TODO: Make a different monitor that flips sign for SNES, Newton system is A dx = -b, so we need to negate the solution */
720:   VecScale(sol, -1.0);
721:   PetscCalloc2(Nf + 1, &x, Nf + 1, &errors);
722:   DMComputeError(dm, sol, errors, NULL);

724:   PetscViewerPushFormat(viewer, format);
725:   if (!n) PetscDrawLGReset(lg);
726:   for (f = 0; f < Nf; ++f) {
727:     x[f]      = (PetscReal)n;
728:     errors[f] = errors[f] > 0.0 ? PetscLog10Real(errors[f]) : -15.;
729:   }
730:   x[Nf]      = (PetscReal)n;
731:   errors[Nf] = rnorm > 0.0 ? PetscLog10Real(rnorm) : -15.;
732:   PetscDrawLGAddPoint(lg, x, errors);
733:   KSPGetConvergedReason(ksp, &reason);
734:   if (n <= 20 || !(n % 5) || reason) {
735:     PetscDrawLGDraw(lg);
736:     PetscDrawLGSave(lg);
737:   }
738:   PetscViewerPopFormat(viewer);
739:   return 0;
740: }

742: /*@C
743:   KSPMonitorErrorDrawLGCreate - Creates the plotter for the error and preconditioned residual.

745:   Collective on ksp

747:   Input Parameters:
748: + viewer - The PetscViewer
749: . format - The viewer format
750: - ctx    - An optional user context

752:   Output Parameter:
753: . vf    - The viewer context

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

759:   Level: intermediate

761: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
762: @*/
763: PetscErrorCode KSPMonitorErrorDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
764: {
765:   KSP      ksp = (KSP)ctx;
766:   DM       dm;
767:   char   **names;
768:   PetscInt Nf, f;

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

778:     DMGetField(dm, f, NULL, &disc);
779:     PetscObjectGetName(disc, &fname);
780:     PetscStrncpy(lname, fname, PETSC_MAX_PATH_LEN);
781:     PetscStrlcat(lname, " Error", PETSC_MAX_PATH_LEN);
782:     PetscStrallocpy(lname, &names[f]);
783:   }
784:   PetscStrallocpy("residual", &names[Nf]);
785:   PetscViewerAndFormatCreate(viewer, format, vf);
786:   (*vf)->data = ctx;
787:   KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Error Norm", Nf + 1, (const char **)names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg);
788:   for (f = 0; f <= Nf; ++f) PetscFree(names[f]);
789:   PetscFree(names);
790:   return 0;
791: }

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

796:   Collective on ksp

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

804:   Options Database Key:
805: . -ksp_monitor_solution - Activates KSPMonitorSolution()

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

811:   Level: intermediate

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

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

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

841:   Collective on ksp

843:   Input Parameters:
844: + ksp   - iterative context
845: . n     - iteration number
846: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
847: - vf    - The viewer context

849:   Options Database Key:
850: . -ksp_monitor_solution draw - Activates KSPMonitorSolutionDraw()

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

856:   Level: intermediate

858: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
859: @*/
860: PetscErrorCode KSPMonitorSolutionDraw(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
861: {
862:   PetscViewer       viewer = vf->viewer;
863:   PetscViewerFormat format = vf->format;
864:   Vec               x;

867:   KSPBuildSolution(ksp, NULL, &x);
868:   PetscViewerPushFormat(viewer, format);
869:   PetscObjectSetName((PetscObject)x, "Solution");
870:   PetscObjectCompose((PetscObject)x, "__Vec_bc_zero__", (PetscObject)ksp);
871:   VecView(x, viewer);
872:   PetscObjectCompose((PetscObject)x, "__Vec_bc_zero__", NULL);
873:   PetscViewerPopFormat(viewer);
874:   return 0;
875: }

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

880:   Collective on ksp

882:   Input Parameters:
883: + ksp   - iterative context
884: . n     - iteration number
885: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
886: - vf    - The viewer context

888:   Options Database Key:
889: . -ksp_monitor_solution draw::draw_lg - Activates KSPMonitorSolutionDrawLG()

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

895:   Level: intermediate

897: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
898: @*/
899: PetscErrorCode KSPMonitorSolutionDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
900: {
901:   PetscViewer        viewer = vf->viewer;
902:   PetscViewerFormat  format = vf->format;
903:   PetscDrawLG        lg     = vf->lg;
904:   Vec                u;
905:   KSPConvergedReason reason;
906:   PetscReal          snorm, x, y;

910:   KSPBuildSolution(ksp, NULL, &u);
911:   VecNorm(u, NORM_2, &snorm);
912:   PetscViewerPushFormat(viewer, format);
913:   if (!n) PetscDrawLGReset(lg);
914:   x = (PetscReal)n;
915:   if (snorm > 0.0) y = PetscLog10Real(snorm);
916:   else y = -15.0;
917:   PetscDrawLGAddPoint(lg, &x, &y);
918:   KSPGetConvergedReason(ksp, &reason);
919:   if (n <= 20 || !(n % 5) || reason) {
920:     PetscDrawLGDraw(lg);
921:     PetscDrawLGSave(lg);
922:   }
923:   PetscViewerPopFormat(viewer);
924:   return 0;
925: }

927: /*@C
928:   KSPMonitorSolutionDrawLGCreate - Creates the plotter for the solution.

930:   Collective on ksp

932:   Input Parameters:
933: + viewer - The PetscViewer
934: . format - The viewer format
935: - ctx    - An optional user context

937:   Output Parameter:
938: . vf    - The viewer context

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

944:   Level: intermediate

946: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
947: @*/
948: PetscErrorCode KSPMonitorSolutionDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
949: {
950:   PetscViewerAndFormatCreate(viewer, format, vf);
951:   (*vf)->data = ctx;
952:   KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Solution Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg);
953:   return 0;
954: }

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

959:   Logically Collective on ksp

961:   Input Parameters:
962: + ksp   - the iterative context
963: . n     - the iteration
964: . rnorm - the two norm of the residual
965: - vf    - The viewer context

967:   Options Database Key:
968: . -ksp_monitor_singular_value - Activates KSPMonitorSingularValue()

970:   Notes:
971:   The CG solver uses the Lanczos technique for eigenvalue computation,
972:   while GMRES uses the Arnoldi technique; other iterative methods do
973:   not currently compute singular values.

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

978:   Level: intermediate

980: .seealso: `KSPComputeExtremeSingularValues()`, `KSPMonitorSingularValueCreate()`
981: @*/
982: PetscErrorCode KSPMonitorSingularValue(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
983: {
984:   PetscViewer       viewer = vf->viewer;
985:   PetscViewerFormat format = vf->format;
986:   PetscReal         emin, emax;
987:   PetscInt          tablevel;
988:   const char       *prefix;

992:   PetscObjectGetTabLevel((PetscObject)ksp, &tablevel);
993:   PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
994:   PetscViewerPushFormat(viewer, format);
995:   PetscViewerASCIIAddTab(viewer, tablevel);
996:   if (n == 0 && prefix) PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix);
997:   if (!ksp->calc_sings) {
998:     PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Residual norm %14.12e \n", n, (double)rnorm);
999:   } else {
1000:     KSPComputeExtremeSingularValues(ksp, &emax, &emin);
1001:     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));
1002:   }
1003:   PetscViewerASCIISubtractTab(viewer, tablevel);
1004:   PetscViewerPopFormat(viewer);
1005:   return 0;
1006: }

1008: /*@C
1009:   KSPMonitorSingularValueCreate - Creates the singular value monitor.

1011:   Collective on ksp

1013:   Input Parameters:
1014: + viewer - The PetscViewer
1015: . format - The viewer format
1016: - ctx    - An optional user context

1018:   Output Parameter:
1019: . vf    - The viewer context

1021:   Level: intermediate

1023: .seealso: `KSPMonitorSet()`, `KSPMonitorSingularValue()`
1024: @*/
1025: PetscErrorCode KSPMonitorSingularValueCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
1026: {
1027:   KSP ksp = (KSP)ctx;

1029:   PetscViewerAndFormatCreate(viewer, format, vf);
1030:   (*vf)->data = ctx;
1031:   KSPSetComputeSingularValues(ksp, PETSC_TRUE);
1032:   return 0;
1033: }

1035: /*@C
1036:    KSPMonitorDynamicTolerance - Recompute the inner tolerance in every outer iteration in an adaptive way.

1038:    Collective on ksp

1040:    Input Parameters:
1041: +  ksp   - iterative context
1042: .  n     - iteration number (not used)
1043: .  fnorm - the current residual norm
1044: -  dummy - some context as a C struct. fields:
1045:              coef: a scaling coefficient. default 1.0. can be passed through
1046:                    -sub_ksp_dynamic_tolerance_param
1047:              bnrm: norm of the right-hand side. store it to avoid repeated calculation

1049:    Notes:
1050:    This may be useful for a flexibly preconditioner Krylov method to
1051:    control the accuracy of the inner solves needed to guarantee the
1052:    convergence of the outer iterations.

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

1057:    Level: advanced

1059: .seealso: `KSPMonitorDynamicToleranceDestroy()`
1060: @*/
1061: PetscErrorCode KSPMonitorDynamicTolerance(KSP ksp, PetscInt its, PetscReal fnorm, void *dummy)
1062: {
1063:   PC            pc;
1064:   PetscReal     outer_rtol, outer_abstol, outer_dtol, inner_rtol;
1065:   PetscInt      outer_maxits, nksp, first, i;
1066:   KSPDynTolCtx *scale  = (KSPDynTolCtx *)dummy;
1067:   KSP          *subksp = NULL;
1068:   KSP           kspinner;
1069:   PetscBool     flg;

1071:   KSPGetPC(ksp, &pc);

1073:   /* compute inner_rtol */
1074:   if (scale->bnrm < 0.0) {
1075:     Vec b;
1076:     KSPGetRhs(ksp, &b);
1077:     VecNorm(b, NORM_2, &(scale->bnrm));
1078:   }
1079:   KSPGetTolerances(ksp, &outer_rtol, &outer_abstol, &outer_dtol, &outer_maxits);
1080:   inner_rtol = PetscMin(scale->coef * scale->bnrm * outer_rtol / fnorm, 0.999);
1081:   /* PetscCall(PetscPrintf(PETSC_COMM_WORLD, "        Inner rtol = %g\n",
1082:      (double)inner_rtol)); */

1084:   /* if pc is ksp */
1085:   PetscObjectTypeCompare((PetscObject)pc, PCKSP, &flg);
1086:   if (flg) {
1087:     PCKSPGetKSP(pc, &kspinner);
1088:     KSPSetTolerances(kspinner, inner_rtol, outer_abstol, outer_dtol, outer_maxits);
1089:     return 0;
1090:   }

1092:   /* if pc is bjacobi */
1093:   PetscObjectTypeCompare((PetscObject)pc, PCBJACOBI, &flg);
1094:   if (flg) {
1095:     PCBJacobiGetSubKSP(pc, &nksp, &first, &subksp);
1096:     if (subksp) {
1097:       for (i = 0; i < nksp; i++) KSPSetTolerances(subksp[i], inner_rtol, outer_abstol, outer_dtol, outer_maxits);
1098:       return 0;
1099:     }
1100:   }

1102:   /* if pc is deflation*/
1103:   PetscObjectTypeCompare((PetscObject)pc, PCDEFLATION, &flg);
1104:   if (flg) {
1105:     PCDeflationGetCoarseKSP(pc, &kspinner);
1106:     KSPSetTolerances(kspinner, inner_rtol, outer_abstol, outer_dtol, PETSC_DEFAULT);
1107:     return 0;
1108:   }

1110:   /* todo: dynamic tolerance may apply to other types of pc too */
1111:   return 0;
1112: }

1114: /*
1115:   Destroy the dummy context used in KSPMonitorDynamicTolerance()
1116: */
1117: PetscErrorCode KSPMonitorDynamicToleranceDestroy(void **dummy)
1118: {
1119:   PetscFree(*dummy);
1120:   return 0;
1121: }

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

1127:    Collective on ksp

1129:    Input Parameters:
1130: +  ksp   - iterative context
1131: .  n     - iteration number
1132: .  rnorm - 2-norm residual value (may be estimated)
1133: -  dummy - unused convergence context

1135:    Returns:
1136: .  reason - KSP_CONVERGED_ITERATING, KSP_CONVERGED_ITS

1138:    Notes:
1139:    This should be used as the convergence test with the option
1140:    KSPSetNormType(ksp,KSP_NORM_NONE), since norms of the residual are
1141:    not computed. Convergence is then declared after the maximum number
1142:    of iterations have been reached. Useful when one is using CG or
1143:    BiCGStab as a smoother.

1145:    Level: advanced

1147: .seealso: `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPSetNormType()`
1148: @*/
1149: PetscErrorCode KSPConvergedSkip(KSP ksp, PetscInt n, PetscReal rnorm, KSPConvergedReason *reason, void *dummy)
1150: {
1153:   *reason = KSP_CONVERGED_ITERATING;
1154:   if (n >= ksp->max_it) *reason = KSP_CONVERGED_ITS;
1155:   return 0;
1156: }

1158: /*@C
1159:    KSPConvergedDefaultCreate - Creates and initializes the space used by the KSPConvergedDefault() function context

1161:    Note Collective

1163:    Output Parameter:
1164: .  ctx - convergence context

1166:    Level: intermediate

1168: .seealso: `KSPConvergedDefault()`, `KSPConvergedDefaultDestroy()`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`,
1169:           `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetUMIRNorm()`, `KSPConvergedDefaultSetConvergedMaxits()`
1170: @*/
1171: PetscErrorCode KSPConvergedDefaultCreate(void **ctx)
1172: {
1173:   KSPConvergedDefaultCtx *cctx;

1175:   PetscNew(&cctx);
1176:   *ctx = cctx;
1177:   return 0;
1178: }

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

1185:    Collective on ksp

1187:    Input Parameters:
1188: .  ksp   - iterative context

1190:    Options Database:
1191: .   -ksp_converged_use_initial_residual_norm <bool> - Use initial residual norm for computing relative convergence

1193:    Notes:
1194:    Use KSPSetTolerances() to alter the defaults for rtol, abstol, dtol.

1196:    The precise values of reason are macros such as KSP_CONVERGED_RTOL, which
1197:    are defined in petscksp.h.

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

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

1203:    Level: intermediate

1205: .seealso: `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUMIRNorm()`, `KSPConvergedDefaultSetConvergedMaxits()`
1206: @*/
1207: PetscErrorCode KSPConvergedDefaultSetUIRNorm(KSP ksp)
1208: {
1209:   KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx *)ksp->cnvP;

1212:   if (ksp->converged != KSPConvergedDefault) return 0;
1214:   ctx->initialrtol = PETSC_TRUE;
1215:   return 0;
1216: }

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

1223:    Collective on ksp

1225:    Input Parameters:
1226: .  ksp   - iterative context

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

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

1233:    The precise values of reason are macros such as KSP_CONVERGED_RTOL, which
1234:    are defined in petscksp.h.

1236:    Level: intermediate

1238: .seealso: `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetConvergedMaxits()`
1239: @*/
1240: PetscErrorCode KSPConvergedDefaultSetUMIRNorm(KSP ksp)
1241: {
1242:   KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx *)ksp->cnvP;

1245:   if (ksp->converged != KSPConvergedDefault) return 0;
1247:   ctx->mininitialrtol = PETSC_TRUE;
1248:   return 0;
1249: }

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

1254:    Collective on ksp

1256:    Input Parameters:
1257: +  ksp - iterative context
1258: -  flg - boolean flag

1260:    Options Database:
1261: .   -ksp_converged_maxits <bool> - Declare convergence if the maximum number of iterations is reached

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

1265:    The precise values of reason are macros such as KSP_CONVERGED_RTOL, which
1266:    are defined in petscksp.h.

1268:    Level: intermediate

1270: .seealso: `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUMIRNorm()`, `KSPConvergedDefaultSetUIRNorm()`
1271: @*/
1272: PetscErrorCode KSPConvergedDefaultSetConvergedMaxits(KSP ksp, PetscBool flg)
1273: {
1274:   KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx *)ksp->cnvP;

1278:   if (ksp->converged != KSPConvergedDefault) return 0;
1279:   ctx->convmaxits = flg;
1280:   return 0;
1281: }

1283: /*@C
1284:    KSPConvergedDefault - Determines convergence of the linear iterative solvers by default

1286:    Collective on ksp

1288:    Input Parameters:
1289: +  ksp   - iterative context
1290: .  n     - iteration number
1291: .  rnorm - residual norm (may be estimated, depending on the method may be the preconditioned residual norm)
1292: -  ctx - convergence context which must be created by KSPConvergedDefaultCreate()

1294:    Output Parameter:
1295: .  reason - the convergence reason; it is positive if the iteration has converged,
1296:             negative if the iteration has diverged, and KSP_CONVERGED_ITERATING otherwise

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

1304:    where:
1305: +     rtol - relative tolerance,
1306: .     abstol - absolute tolerance.
1307: .     dtol - divergence tolerance,
1308: -     rnorm_0 - the two norm of the right hand side (or the preconditioned norm, depending on what was set with
1309:           KSPSetNormType(). When initial guess is non-zero you
1310:           can call KSPConvergedDefaultSetUIRNorm() to use the norm of (b - A*(initial guess))
1311:           as the starting point for relative norm convergence testing, that is as rnorm_0

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

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

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

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

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

1323:    Level: intermediate

1325: .seealso: `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`,
1326:           `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetUMIRNorm()`, `KSPConvergedDefaultSetConvergedMaxits()`, `KSPConvergedDefaultCreate()`, `KSPConvergedDefaultDestroy()`
1327: @*/
1328: PetscErrorCode KSPConvergedDefault(KSP ksp, PetscInt n, PetscReal rnorm, KSPConvergedReason *reason, void *ctx)
1329: {
1330:   KSPConvergedDefaultCtx *cctx = (KSPConvergedDefaultCtx *)ctx;
1331:   KSPNormType             normtype;

1337:   *reason = KSP_CONVERGED_ITERATING;

1339:   if (cctx->convmaxits && n >= ksp->max_it) {
1340:     *reason = KSP_CONVERGED_ITS;
1341:     PetscInfo(ksp, "Linear solver has converged. Maximum number of iterations reached %" PetscInt_FMT "\n", n);
1342:     return 0;
1343:   }
1344:   KSPGetNormType(ksp, &normtype);
1345:   if (normtype == KSP_NORM_NONE) return 0;

1347:   if (!n) {
1348:     /* if user gives initial guess need to compute norm of b */
1349:     if (!ksp->guess_zero && !cctx->initialrtol) {
1350:       PetscReal snorm = 0.0;
1351:       if (ksp->normtype == KSP_NORM_UNPRECONDITIONED || ksp->pc_side == PC_RIGHT) {
1352:         PetscInfo(ksp, "user has provided nonzero initial guess, computing 2-norm of RHS\n");
1353:         VecNorm(ksp->vec_rhs, NORM_2, &snorm); /*     <- b'*b */
1354:       } else {
1355:         Vec z;
1356:         /* Should avoid allocating the z vector each time but cannot stash it in cctx because if KSPReset() is called the vector size might change */
1357:         VecDuplicate(ksp->vec_rhs, &z);
1358:         KSP_PCApply(ksp, ksp->vec_rhs, z);
1359:         if (ksp->normtype == KSP_NORM_PRECONDITIONED) {
1360:           PetscInfo(ksp, "user has provided nonzero initial guess, computing 2-norm of preconditioned RHS\n");
1361:           VecNorm(z, NORM_2, &snorm); /*    dp <- b'*B'*B*b */
1362:         } else if (ksp->normtype == KSP_NORM_NATURAL) {
1363:           PetscScalar norm;
1364:           PetscInfo(ksp, "user has provided nonzero initial guess, computing natural norm of RHS\n");
1365:           VecDot(ksp->vec_rhs, z, &norm);
1366:           snorm = PetscSqrtReal(PetscAbsScalar(norm)); /*    dp <- b'*B*b */
1367:         }
1368:         VecDestroy(&z);
1369:       }
1370:       /* handle special case of zero RHS and nonzero guess */
1371:       if (!snorm) {
1372:         PetscInfo(ksp, "Special case, user has provided nonzero initial guess and zero RHS\n");
1373:         snorm = rnorm;
1374:       }
1375:       if (cctx->mininitialrtol) ksp->rnorm0 = PetscMin(snorm, rnorm);
1376:       else ksp->rnorm0 = snorm;
1377:     } else {
1378:       ksp->rnorm0 = rnorm;
1379:     }
1380:     ksp->ttol = PetscMax(ksp->rtol * ksp->rnorm0, ksp->abstol);
1381:   }

1383:   if (n <= ksp->chknorm) return 0;

1385:   if (PetscIsInfOrNanReal(rnorm)) {
1386:     PCFailedReason pcreason;
1387:     PetscInt       sendbuf, recvbuf;
1388:     PCGetFailedReasonRank(ksp->pc, &pcreason);
1389:     sendbuf = (PetscInt)pcreason;
1390:     MPI_Allreduce(&sendbuf, &recvbuf, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)ksp));
1391:     if (recvbuf) {
1392:       *reason = KSP_DIVERGED_PC_FAILED;
1393:       PCSetFailedReason(ksp->pc, (PCFailedReason)recvbuf);
1394:       PetscInfo(ksp, "Linear solver pcsetup fails, declaring divergence \n");
1395:     } else {
1396:       *reason = KSP_DIVERGED_NANORINF;
1397:       PetscInfo(ksp, "Linear solver has created a not a number (NaN) as the residual norm, declaring divergence \n");
1398:     }
1399:   } else if (rnorm <= ksp->ttol) {
1400:     if (rnorm < ksp->abstol) {
1401:       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);
1402:       *reason = KSP_CONVERGED_ATOL;
1403:     } else {
1404:       if (cctx->initialrtol) {
1405:         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);
1406:       } else {
1407:         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);
1408:       }
1409:       *reason = KSP_CONVERGED_RTOL;
1410:     }
1411:   } else if (rnorm >= ksp->divtol * ksp->rnorm0) {
1412:     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);
1413:     *reason = KSP_DIVERGED_DTOL;
1414:   }
1415:   return 0;
1416: }

1418: /*@C
1419:    KSPConvergedDefaultDestroy - Frees the space used by the KSPConvergedDefault() function context

1421:    Not Collective

1423:    Input Parameters:
1424: .  ctx - convergence context

1426:    Level: intermediate

1428: .seealso: `KSPConvergedDefault()`, `KSPConvergedDefaultCreate()`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`,
1429:           `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetUMIRNorm()`
1430: @*/
1431: PetscErrorCode KSPConvergedDefaultDestroy(void *ctx)
1432: {
1433:   KSPConvergedDefaultCtx *cctx = (KSPConvergedDefaultCtx *)ctx;

1435:   VecDestroy(&cctx->work);
1436:   PetscFree(ctx);
1437:   return 0;
1438: }

1440: /*
1441:    KSPBuildSolutionDefault - Default code to create/move the solution.

1443:    Collective on ksp

1445:    Input Parameters:
1446: +  ksp - iterative context
1447: -  v   - pointer to the user's vector

1449:    Output Parameter:
1450: .  V - pointer to a vector containing the solution

1452:    Level: advanced

1454:    Developers Note: This is PETSC_EXTERN because it may be used by user written plugin KSP implementations

1456: .seealso: `KSPGetSolution()`, `KSPBuildResidualDefault()`
1457: */
1458: PetscErrorCode KSPBuildSolutionDefault(KSP ksp, Vec v, Vec *V)
1459: {
1460:   if (ksp->pc_side == PC_RIGHT) {
1461:     if (ksp->pc) {
1462:       if (v) {
1463:         KSP_PCApply(ksp, ksp->vec_sol, v);
1464:         *V = v;
1465:       } else SETERRQ(PetscObjectComm((PetscObject)ksp), PETSC_ERR_SUP, "Not working with right preconditioner");
1466:     } else {
1467:       if (v) {
1468:         VecCopy(ksp->vec_sol, v);
1469:         *V = v;
1470:       } else *V = ksp->vec_sol;
1471:     }
1472:   } else if (ksp->pc_side == PC_SYMMETRIC) {
1473:     if (ksp->pc) {
1475:       if (v) {
1476:         PCApplySymmetricRight(ksp->pc, ksp->vec_sol, v);
1477:         *V = v;
1478:       } else SETERRQ(PetscObjectComm((PetscObject)ksp), PETSC_ERR_SUP, "Not working with symmetric preconditioner");
1479:     } else {
1480:       if (v) {
1481:         VecCopy(ksp->vec_sol, v);
1482:         *V = v;
1483:       } else *V = ksp->vec_sol;
1484:     }
1485:   } else {
1486:     if (v) {
1487:       VecCopy(ksp->vec_sol, v);
1488:       *V = v;
1489:     } else *V = ksp->vec_sol;
1490:   }
1491:   return 0;
1492: }

1494: /*
1495:    KSPBuildResidualDefault - Default code to compute the residual.

1497:    Collecive on ksp

1499:    Input Parameters:
1500: .  ksp - iterative context
1501: .  t   - pointer to temporary vector
1502: .  v   - pointer to user vector

1504:    Output Parameter:
1505: .  V - pointer to a vector containing the residual

1507:    Level: advanced

1509:    Developers Note: This is PETSC_EXTERN because it may be used by user written plugin KSP implementations

1511: .seealso: `KSPBuildSolutionDefault()`
1512: */
1513: PetscErrorCode KSPBuildResidualDefault(KSP ksp, Vec t, Vec v, Vec *V)
1514: {
1515:   Mat Amat, Pmat;

1517:   if (!ksp->pc) KSPGetPC(ksp, &ksp->pc);
1518:   PCGetOperators(ksp->pc, &Amat, &Pmat);
1519:   KSPBuildSolution(ksp, t, NULL);
1520:   KSP_MatMult(ksp, Amat, t, v);
1521:   VecAYPX(v, -1.0, ksp->vec_rhs);
1522:   *V = v;
1523:   return 0;
1524: }

1526: /*@C
1527:   KSPCreateVecs - Gets a number of work vectors.

1529:   Collective on ksp

1531:   Input Parameters:
1532: + ksp  - iterative context
1533: . rightn  - number of right work vectors
1534: - leftn   - number of left work vectors to allocate

1536:   Output Parameters:
1537: +  right - the array of vectors created
1538: -  left - the array of left vectors

1540:    Note: The right vector has as many elements as the matrix has columns. The left
1541:      vector has as many elements as the matrix has rows.

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

1545:    Developers Note: 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
1546:                     that does not exist tries to get them from the DM (if it is provided).

1548:    Level: advanced

1550: .seealso: `MatCreateVecs()`, `VecDestroyVecs()`

1552: @*/
1553: PetscErrorCode KSPCreateVecs(KSP ksp, PetscInt rightn, Vec **right, PetscInt leftn, Vec **left)
1554: {
1555:   Vec       vecr = NULL, vecl = NULL;
1556:   PetscBool matset, pmatset, isshell, preferdm = PETSC_FALSE;
1557:   Mat       mat = NULL;

1559:   if (ksp->dm) {
1560:     PetscObjectTypeCompare((PetscObject)ksp->dm, DMSHELL, &isshell);
1561:     preferdm = isshell ? PETSC_FALSE : PETSC_TRUE;
1562:   }
1563:   if (rightn) {
1565:     if (ksp->vec_sol) vecr = ksp->vec_sol;
1566:     else {
1567:       if (preferdm) {
1568:         DMGetGlobalVector(ksp->dm, &vecr);
1569:       } else if (ksp->pc) {
1570:         PCGetOperatorsSet(ksp->pc, &matset, &pmatset);
1571:         /* check for mat before pmat because for KSPLSQR pmat may be a different size than mat since pmat maybe mat'*mat */
1572:         if (matset) {
1573:           PCGetOperators(ksp->pc, &mat, NULL);
1574:           MatCreateVecs(mat, &vecr, NULL);
1575:         } else if (pmatset) {
1576:           PCGetOperators(ksp->pc, NULL, &mat);
1577:           MatCreateVecs(mat, &vecr, NULL);
1578:         }
1579:       }
1580:       if (!vecr && ksp->dm) DMGetGlobalVector(ksp->dm, &vecr);
1582:     }
1583:     VecDuplicateVecs(vecr, rightn, right);
1584:     if (!ksp->vec_sol) {
1585:       if (preferdm) {
1586:         DMRestoreGlobalVector(ksp->dm, &vecr);
1587:       } else if (mat) {
1588:         VecDestroy(&vecr);
1589:       } else if (ksp->dm) {
1590:         DMRestoreGlobalVector(ksp->dm, &vecr);
1591:       }
1592:     }
1593:   }
1594:   if (leftn) {
1596:     if (ksp->vec_rhs) vecl = ksp->vec_rhs;
1597:     else {
1598:       if (preferdm) {
1599:         DMGetGlobalVector(ksp->dm, &vecl);
1600:       } else if (ksp->pc) {
1601:         PCGetOperatorsSet(ksp->pc, &matset, &pmatset);
1602:         /* check for mat before pmat because for KSPLSQR pmat may be a different size than mat since pmat maybe mat'*mat */
1603:         if (matset) {
1604:           PCGetOperators(ksp->pc, &mat, NULL);
1605:           MatCreateVecs(mat, NULL, &vecl);
1606:         } else if (pmatset) {
1607:           PCGetOperators(ksp->pc, NULL, &mat);
1608:           MatCreateVecs(mat, NULL, &vecl);
1609:         }
1610:       }
1611:       if (!vecl && ksp->dm) DMGetGlobalVector(ksp->dm, &vecl);
1613:     }
1614:     VecDuplicateVecs(vecl, leftn, left);
1615:     if (!ksp->vec_rhs) {
1616:       if (preferdm) {
1617:         DMRestoreGlobalVector(ksp->dm, &vecl);
1618:       } else if (mat) {
1619:         VecDestroy(&vecl);
1620:       } else if (ksp->dm) {
1621:         DMRestoreGlobalVector(ksp->dm, &vecl);
1622:       }
1623:     }
1624:   }
1625:   return 0;
1626: }

1628: /*@C
1629:   KSPSetWorkVecs - Sets a number of work vectors into a KSP object

1631:   Collective on ksp

1633:   Input Parameters:
1634: + ksp  - iterative context
1635: - nw   - number of work vectors to allocate

1637:   Level: developer

1639:   Developers Note: This is PETSC_EXTERN because it may be used by user written plugin KSP implementations

1641: @*/
1642: PetscErrorCode KSPSetWorkVecs(KSP ksp, PetscInt nw)
1643: {
1644:   VecDestroyVecs(ksp->nwork, &ksp->work);
1645:   ksp->nwork = nw;
1646:   KSPCreateVecs(ksp, nw, &ksp->work, 0, NULL);
1647:   return 0;
1648: }

1650: /*
1651:   KSPDestroyDefault - Destroys a iterative context variable for methods with
1652:   no separate context.  Preferred calling sequence KSPDestroy().

1654:   Input Parameter:
1655: . ksp - the iterative context

1657:    Developers Note: This is PETSC_EXTERN because it may be used by user written plugin KSP implementations

1659: */
1660: PetscErrorCode KSPDestroyDefault(KSP ksp)
1661: {
1663:   PetscFree(ksp->data);
1664:   return 0;
1665: }

1667: /*@
1668:    KSPGetConvergedReason - Gets the reason the KSP iteration was stopped.

1670:    Not Collective

1672:    Input Parameter:
1673: .  ksp - the KSP context

1675:    Output Parameter:
1676: .  reason - negative value indicates diverged, positive value converged, see KSPConvergedReason

1678:    Possible values for reason: See also manual page for each reason
1679: $  KSP_CONVERGED_RTOL (residual 2-norm decreased by a factor of rtol, from 2-norm of right hand side)
1680: $  KSP_CONVERGED_ATOL (residual 2-norm less than abstol)
1681: $  KSP_CONVERGED_ITS (used by the preonly preconditioner that always uses ONE iteration, or when the KSPConvergedSkip() convergence test routine is set.
1682: $  KSP_CONVERGED_CG_NEG_CURVE (see note below)
1683: $  KSP_CONVERGED_CG_CONSTRAINED (see note below)
1684: $  KSP_CONVERGED_STEP_LENGTH (see note below)
1685: $  KSP_CONVERGED_ITERATING (returned if the solver is not yet finished)
1686: $  KSP_DIVERGED_ITS  (required more than its to reach convergence)
1687: $  KSP_DIVERGED_DTOL (residual norm increased by a factor of divtol)
1688: $  KSP_DIVERGED_NANORINF (residual norm became Not-a-number or Inf likely due to 0/0)
1689: $  KSP_DIVERGED_BREAKDOWN (generic breakdown in method)
1690: $  KSP_DIVERGED_BREAKDOWN_BICG (Initial residual is orthogonal to preconditioned initial residual. Try a different preconditioner, or a different initial Level.)

1692:    Options Database:
1693: .   -ksp_converged_reason - prints the reason to standard out

1695:    Notes:
1696:     If this routine is called before or doing the KSPSolve() the value of KSP_CONVERGED_ITERATING is returned

1698:    The values  KSP_CONVERGED_CG_NEG_CURVE, KSP_CONVERGED_CG_CONSTRAINED, and KSP_CONVERGED_STEP_LENGTH are returned only by the special KSPNASH, KSPSTCG, and KSPGLTR
1699:    solvers which are used by the SNESNEWTONTR (trust region) solver.

1701:    Level: intermediate

1703: .seealso: `KSPSetConvergenceTest()`, `KSPConvergedDefault()`, `KSPSetTolerances()`, `KSPConvergedReason`,
1704:           `KSPConvergedReasonView()`
1705: @*/
1706: PetscErrorCode KSPGetConvergedReason(KSP ksp, KSPConvergedReason *reason)
1707: {
1710:   *reason = ksp->reason;
1711:   return 0;
1712: }

1714: /*@C
1715:    KSPGetConvergedReasonString - Return a human readable string for ksp converged reason

1717:    Not Collective

1719:    Input Parameter:
1720: .  ksp - the KSP context

1722:    Output Parameter:
1723: .  strreason - a human readable string that describes ksp converged reason

1725:    Level: beginner

1727: .seealso: `KSPGetConvergedReason()`
1728: @*/
1729: PetscErrorCode KSPGetConvergedReasonString(KSP ksp, const char **strreason)
1730: {
1733:   *strreason = KSPConvergedReasons[ksp->reason];
1734:   return 0;
1735: }

1737: #include <petsc/private/dmimpl.h>
1738: /*@
1739:    KSPSetDM - Sets the DM that may be used by some preconditioners

1741:    Logically Collective on ksp

1743:    Input Parameters:
1744: +  ksp - the preconditioner context
1745: -  dm - the dm, cannot be NULL

1747:    Notes:
1748:    If this is used then the KSP will attempt to use the DM to create the matrix and use the routine set with
1749:    DMKSPSetComputeOperators(). Use KSPSetDMActive(ksp,PETSC_FALSE) to instead use the matrix you've provided with
1750:    KSPSetOperators().

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

1756:    Level: intermediate

1758: .seealso: `KSPGetDM()`, `KSPSetDMActive()`, `KSPSetComputeOperators()`, `KSPSetComputeRHS()`, `KSPSetComputeInitialGuess()`, `DMKSPSetComputeOperators()`, `DMKSPSetComputeRHS()`, `DMKSPSetComputeInitialGuess()`
1759: @*/
1760: PetscErrorCode KSPSetDM(KSP ksp, DM dm)
1761: {
1762:   PC pc;

1766:   PetscObjectReference((PetscObject)dm);
1767:   if (ksp->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */
1768:     if (ksp->dm->dmksp && !dm->dmksp) {
1769:       DMKSP kdm;
1770:       DMCopyDMKSP(ksp->dm, dm);
1771:       DMGetDMKSP(ksp->dm, &kdm);
1772:       if (kdm->originaldm == ksp->dm) kdm->originaldm = dm; /* Grant write privileges to the replacement DM */
1773:     }
1774:     DMDestroy(&ksp->dm);
1775:   }
1776:   ksp->dm     = dm;
1777:   ksp->dmAuto = PETSC_FALSE;
1778:   KSPGetPC(ksp, &pc);
1779:   PCSetDM(pc, dm);
1780:   ksp->dmActive = PETSC_TRUE;
1781:   return 0;
1782: }

1784: /*@
1785:    KSPSetDMActive - Indicates the DM should be used to generate the linear system matrix and right hand side

1787:    Logically Collective on ksp

1789:    Input Parameters:
1790: +  ksp - the preconditioner context
1791: -  flg - use the DM

1793:    Notes:
1794:    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.

1796:    Level: intermediate

1798: .seealso: `KSPGetDM()`, `KSPSetDM()`, `SNESSetDM()`, `KSPSetComputeOperators()`, `KSPSetComputeRHS()`, `KSPSetComputeInitialGuess()`
1799: @*/
1800: PetscErrorCode KSPSetDMActive(KSP ksp, PetscBool flg)
1801: {
1804:   ksp->dmActive = flg;
1805:   return 0;
1806: }

1808: /*@
1809:    KSPGetDM - Gets the DM that may be used by some preconditioners

1811:    Not Collective

1813:    Input Parameter:
1814: . ksp - the preconditioner context

1816:    Output Parameter:
1817: .  dm - the dm

1819:    Level: intermediate

1821: .seealso: `KSPSetDM()`, `KSPSetDMActive()`
1822: @*/
1823: PetscErrorCode KSPGetDM(KSP ksp, DM *dm)
1824: {
1826:   if (!ksp->dm) {
1827:     DMShellCreate(PetscObjectComm((PetscObject)ksp), &ksp->dm);
1828:     ksp->dmAuto = PETSC_TRUE;
1829:   }
1830:   *dm = ksp->dm;
1831:   return 0;
1832: }

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

1837:    Logically Collective on ksp

1839:    Input Parameters:
1840: +  ksp - the KSP context
1841: -  usrP - optional user context

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

1847:    Level: intermediate

1849: .seealso: `KSPGetApplicationContext()`
1850: @*/
1851: PetscErrorCode KSPSetApplicationContext(KSP ksp, void *usrP)
1852: {
1853:   PC pc;

1856:   ksp->user = usrP;
1857:   KSPGetPC(ksp, &pc);
1858:   PCSetApplicationContext(pc, usrP);
1859:   return 0;
1860: }

1862: /*@
1863:    KSPGetApplicationContext - Gets the user-defined context for the linear solver.

1865:    Not Collective

1867:    Input Parameter:
1868: .  ksp - KSP context

1870:    Output Parameter:
1871: .  usrP - user context

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

1877:    Level: intermediate

1879: .seealso: `KSPSetApplicationContext()`
1880: @*/
1881: PetscErrorCode KSPGetApplicationContext(KSP ksp, void *usrP)
1882: {
1884:   *(void **)usrP = ksp->user;
1885:   return 0;
1886: }

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

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

1894:    Collective on ksp

1896:    Input Parameters:
1897: +  ksp - the linear solver (KSP) context.
1898: .  pc - the preconditioner context
1899: -  vec - a vector that will be initialized with Inf to indicate lack of convergence

1901:    Notes: this may be called by a subset of the processes in the PC

1903:    Level: developer

1905:    Developer Note: this is used to manage returning from preconditioners whose inner KSP solvers have failed in some way

1907: .seealso: `KSPCreate()`, `KSPSetType()`, `KSP`, `KSPCheckNorm()`, `KSPCheckDot()`
1908: @*/
1909: PetscErrorCode KSPCheckSolve(KSP ksp, PC pc, Vec vec)
1910: {
1911:   PCFailedReason pcreason;
1912:   PC             subpc;

1914:   KSPGetPC(ksp, &subpc);
1915:   PCGetFailedReason(subpc, &pcreason);
1916:   if (pcreason || (ksp->reason < 0 && ksp->reason != KSP_DIVERGED_ITS)) {
1918:     PetscInfo(ksp, "Detected not converged in KSP inner solve: KSP reason %s PC reason %s\n", KSPConvergedReasons[ksp->reason], PCFailedReasons[pcreason]);
1919:     pc->failedreason = PC_SUBPC_ERROR;
1920:     if (vec) VecSetInf(vec);
1921:   }
1922:   return 0;
1923: }