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: /*@C
     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: /*@C
    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: /*@C
    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: /*@C
    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 user 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: /*
    266:   This is the same as KSPMonitorResidual() except it prints fewer digits of the residual as the residual gets smaller.
    267:   This is because the later digits are meaningless and are often different on different machines; by using this routine different
    268:   machines will usually generate the same output.

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

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

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

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

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

    319:   Collective

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

    327:   Options Database Key:
    328: . -ksp_monitor_range - Activates `KSPMonitorResidualRange()`

    330:   Level: intermediate

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

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

    347:   PetscFunctionBegin;
    349:   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
    350:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
    351:   PetscCall(PetscViewerPushFormat(viewer, format));
    352:   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
    353:   if (!it) prev = rnorm;
    354:   if (it == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
    355:   PetscCall(KSPMonitorRange_Private(ksp, it, &perc));
    356:   rel  = (prev - rnorm) / prev;
    357:   prev = rnorm;
    358:   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)));
    359:   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
    360:   PetscCall(PetscViewerPopFormat(viewer));
    361:   PetscFunctionReturn(PETSC_SUCCESS);
    362: }

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

    368:   Collective

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

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

    379:   Level: intermediate

    381:   Notes:
    382:   When using right preconditioning, the two norm values are equivalent.

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

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

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

    410:   PetscCall(PetscViewerPushFormat(viewer, format));
    411:   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
    412:   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
    413:   if (bnorm == 0) {
    414:     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));
    415:   } else {
    416:     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)));
    417:   }
    418:   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
    419:   PetscCall(PetscViewerPopFormat(viewer));
    420:   PetscFunctionReturn(PETSC_SUCCESS);
    421: }

    423: /*@C
    424:   KSPMonitorTrueResidualView - Plots the true residual at each iteration of an iterative solver.

    426:   Collective

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

    434:   Options Database Key:
    435: . -ksp_monitor_true_residual viewertype - Activates `KSPMonitorTrueResidualView()`

    437:   Level: intermediate

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

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

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

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

    468:   Collective

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

    476:   Options Database Key:
    477: . -ksp_monitor_true_residual draw::draw_lg - Activates `KSPMonitorTrueResidualDrawLG()`

    479:   Level: intermediate

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

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

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

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

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

    526:   Collective

    528:   Input Parameters:
    529: + viewer - The `PetscViewer` of type `PETSCVIEWERDRAW`
    530: . format - The viewer format
    531: - ctx    - An optional user context

    533:   Output Parameter:
    534: . vf - The viewer context

    536:   Level: intermediate

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

    544:   PetscFunctionBegin;
    545:   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
    546:   (*vf)->data = ctx;
    547:   PetscCall(PetscViewerMonitorLGSetUp(viewer, NULL, NULL, "Log Residual Norm", 2, names, PETSC_DECIDE, PETSC_DECIDE, 400, 300));
    548:   PetscFunctionReturn(PETSC_SUCCESS);
    549: }

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

    554:   Collective

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

    562:   Options Database Key:
    563: . -ksp_monitor_true_residual_max - Activates `KSPMonitorTrueResidualMax()`

    565:   Level: intermediate

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

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

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

    594:   PetscCall(PetscViewerPushFormat(viewer, format));
    595:   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
    596:   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
    597:   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)));
    598:   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
    599:   PetscCall(PetscViewerPopFormat(viewer));
    600:   PetscFunctionReturn(PETSC_SUCCESS);
    601: }

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

    606:   Collective

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

    614:   Options Database Key:
    615: . -ksp_monitor_error - Activates `KSPMonitorError()`

    617:   Level: intermediate

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

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

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

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

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

    669:   Collective

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

    677:   Options Database Key:
    678: . -ksp_monitor_error draw - Activates `KSPMonitorErrorDraw()`

    680:   Level: intermediate

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

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

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

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

    715:   Collective

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

    723:   Options Database Key:
    724: . -ksp_monitor_error draw::draw_lg - Activates `KSPMonitorTrueResidualDrawLG()`

    726:   Level: intermediate

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

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

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

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

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

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

    780:   Collective

    782:   Input Parameters:
    783: + viewer - The `PetscViewer`
    784: . format - The viewer format
    785: - ctx    - An optional user context

    787:   Output Parameter:
    788: . vf - The viewer context

    790:   Level: intermediate

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

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

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

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

    828:   Collective

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

    836:   Options Database Key:
    837: . -ksp_monitor_solution - Activates `KSPMonitorSolution()`

    839:   Level: intermediate

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

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

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

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

    874:   Collective

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

    882:   Options Database Key:
    883: . -ksp_monitor_solution draw - Activates `KSPMonitorSolutionDraw()`

    885:   Level: intermediate

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

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

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

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

    914:   Collective

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

    922:   Options Database Key:
    923: . -ksp_monitor_solution draw::draw_lg - Activates `KSPMonitorSolutionDrawLG()`

    925:   Level: intermediate

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

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

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

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

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

    967:   Collective

    969:   Input Parameters:
    970: + viewer - The `PetscViewer`
    971: . format - The viewer format
    972: - ctx    - An optional user context

    974:   Output Parameter:
    975: . vf - The viewer context

    977:   Level: intermediate

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

    983: .seealso: [](ch_ksp), `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
    984: @*/
    985: PetscErrorCode KSPMonitorSolutionDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, PetscCtx ctx, PetscViewerAndFormat **vf)
    986: {
    987:   PetscFunctionBegin;
    988:   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
    989:   (*vf)->data = ctx;
    990:   PetscCall(PetscViewerMonitorLGSetUp(viewer, NULL, NULL, "Log Solution Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300));
    991:   PetscFunctionReturn(PETSC_SUCCESS);
    992: }

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

    997:   Logically Collective

    999:   Input Parameters:
    1000: + ksp   - the iterative context
    1001: . n     - the iteration
    1002: . rnorm - the two norm of the residual
    1003: - vf    - The viewer context

    1005:   Options Database Key:
    1006: . -ksp_monitor_singular_value - Activates `KSPMonitorSingularValue()`

    1008:   Level: intermediate

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

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

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

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

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

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

    1052:   Collective

    1054:   Input Parameters:
    1055: + viewer - The PetscViewer
    1056: . format - The viewer format
    1057: - ctx    - An optional user context

    1059:   Output Parameter:
    1060: . vf - The viewer context

    1062:   Level: intermediate

    1064: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorSingularValue()`, `PetscViewer`
    1065: @*/
    1066: PetscErrorCode KSPMonitorSingularValueCreate(PetscViewer viewer, PetscViewerFormat format, PetscCtx ctx, PetscViewerAndFormat **vf)
    1067: {
    1068:   KSP ksp = (KSP)ctx;

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

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

    1080:   Logically Collective

    1082:   Output Parameter:
    1083: . ctx - a void pointer

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

    1088:   Level: advanced

    1090:   Note:
    1091:   Use before calling `KSPMonitorSet()` with `KSPMonitorDynamicTolerance()`

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

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

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

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

    1112:   Logically Collective

    1114:   Output Parameters:
    1115: + ctx   - the context for `KSPMonitorDynamicTolerance()`
    1116: - coeff - the coefficient, default is 1.0

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

    1121:   Level: advanced

    1123:   Note:
    1124:   Use before calling `KSPMonitorSet()` and after `KSPMonitorDynamicToleranceCreate()`

    1126: .seealso: [](sec_flexibleksp), `KSP`, `KSPMonitorDynamicTolerance()`, `KSPMonitorDynamicToleranceDestroy()`, `KSPMonitorDynamicToleranceCreate()`
    1127: @*/
    1128: PetscErrorCode KSPMonitorDynamicToleranceSetCoefficient(PetscCtx ctx, PetscReal coeff)
    1129: {
    1130:   KSPDynTolCtx *scale = (KSPDynTolCtx *)ctx;

    1132:   PetscFunctionBegin;
    1133:   scale->coef = coeff;
    1134:   PetscFunctionReturn(PETSC_SUCCESS);
    1135: }

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

    1140:   Collective

    1142:   Input Parameters:
    1143: + ksp   - iterative context
    1144: . its   - iteration number (not used)
    1145: . fnorm - the current residual norm
    1146: - ctx   - context used by monitor

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

    1151:   Level: advanced

    1153:   Notes:
    1154:   Applies for `PCKSP`, `PCBJACOBI`, and `PCDEFLATION` preconditioners

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

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

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

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

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

    1179:   PetscFunctionBegin;
    1180:   PetscCall(KSPGetPC(ksp, &pc));

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

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

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

    1209:   /* if pc is deflation*/
    1210:   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCDEFLATION, &flg));
    1211:   if (flg) {
    1212:     PetscCall(PCDeflationGetCoarseKSP(pc, &kspinner));
    1213:     PetscCall(KSPSetTolerances(kspinner, inner_rtol, outer_abstol, outer_dtol, PETSC_CURRENT));
    1214:     PetscFunctionReturn(PETSC_SUCCESS);
    1215:   }

    1217:   /* TODO: dynamic tolerance may apply to other types of pc */
    1218:   PetscFunctionReturn(PETSC_SUCCESS);
    1219: }

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

    1224:   Input Parameter:
    1225: . ctx - the monitor context

    1227:   Level: advanced

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

    1232: .seealso: [](ch_ksp), `KSP`, `KSPMonitorDynamicTolerance()`, `KSPMonitorSet()`, `KSPMonitorDynamicToleranceCreate()`
    1233: @*/
    1234: PetscErrorCode KSPMonitorDynamicToleranceDestroy(PetscCtxRt ctx)
    1235: {
    1236:   PetscFunctionBegin;
    1237:   PetscCall(PetscFree(*(void **)ctx));
    1238:   PetscFunctionReturn(PETSC_SUCCESS);
    1239: }

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

    1245:   Collective

    1247:   Input Parameters:
    1248: + ksp   - iterative context
    1249: . n     - iteration number
    1250: . rnorm - 2-norm residual value (may be estimated)
    1251: - dtx   - unused convergence context

    1253:   Output Parameter:
    1254: . reason - `KSP_CONVERGED_ITERATING` or `KSP_CONVERGED_ITS`

    1256:   Options Database Key:
    1257: . -ksp_convergence_test skip - skips the test

    1259:   Level: advanced

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

    1268: .seealso: [](ch_ksp), `KSP`, `KSPCG`, `KSPBCGS`, `KSPConvergenceTestFn`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPSetNormType()`, [](sec_flexibleksp),
    1269:           `KSPConvergedReason`
    1270: @*/
    1271: PetscErrorCode KSPConvergedSkip(KSP ksp, PetscInt n, PetscReal rnorm, KSPConvergedReason *reason, PetscCtx dtx)
    1272: {
    1273:   PetscFunctionBegin;
    1275:   PetscAssertPointer(reason, 4);
    1276:   *reason = KSP_CONVERGED_ITERATING;
    1277:   if (n >= ksp->max_it) *reason = KSP_CONVERGED_ITS;
    1278:   PetscFunctionReturn(PETSC_SUCCESS);
    1279: }

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

    1284:   Collective

    1286:   Input Parameters:
    1287: + ksp - iterative context
    1288: - flg - the Boolean value

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

    1293:   Level: advanced

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

    1298: .seealso: [](ch_ksp), `KSP`, `KSPConvergedReason`, `KSPGetConvergedNegativeCurvature()`
    1299: @*/
    1300: PetscErrorCode KSPSetConvergedNegativeCurvature(KSP ksp, PetscBool flg)
    1301: {
    1302:   PetscFunctionBegin;
    1305:   ksp->converged_neg_curve = flg;
    1306:   PetscFunctionReturn(PETSC_SUCCESS);
    1307: }

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

    1312:   Collective

    1314:   Input Parameter:
    1315: . ksp - iterative context

    1317:   Output Parameter:
    1318: . flg - the Boolean value

    1320:   Level: advanced

    1322: .seealso: [](ch_ksp), `KSP`, `KSPConvergedReason`, `KSPSetConvergedNegativeCurvature()`
    1323: @*/
    1324: PetscErrorCode KSPGetConvergedNegativeCurvature(KSP ksp, PetscBool *flg)
    1325: {
    1326:   PetscFunctionBegin;
    1328:   PetscAssertPointer(flg, 2);
    1329:   *flg = ksp->converged_neg_curve;
    1330:   PetscFunctionReturn(PETSC_SUCCESS);
    1331: }

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

    1336:   Not Collective

    1338:   Output Parameter:
    1339: . ctx - convergence context

    1341:   Level: intermediate

    1343: .seealso: [](ch_ksp), `KSP`, `KSPConvergedDefault()`, `KSPConvergedDefaultDestroy()`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`,
    1344:           `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetUMIRNorm()`,
    1345:           `KSPConvergedDefaultSetConvergedMaxits()`
    1346: @*/
    1347: PetscErrorCode KSPConvergedDefaultCreate(void **ctx) PeNS
    1348: {
    1349:   KSPConvergedDefaultCtx *cctx;

    1351:   PetscFunctionBegin;
    1352:   PetscCall(PetscNew(&cctx));
    1353:   *ctx = cctx;
    1354:   PetscFunctionReturn(PETSC_SUCCESS);
    1355: }

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

    1362:   Collective

    1364:   Input Parameters:
    1365: . ksp - iterative context

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

    1370:   Level: intermediate

    1372:   Notes:
    1373:   UIRNorm is short for Use Initial Residual Norm.

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

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

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

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

    1384: .seealso: [](ch_ksp), `KSP`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUMIRNorm()`, `KSPConvergedDefaultSetConvergedMaxits()`
    1385: @*/
    1386: PetscErrorCode KSPConvergedDefaultSetUIRNorm(KSP ksp)
    1387: {
    1388:   KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx *)ksp->cnvP;

    1390:   PetscFunctionBegin;
    1392:   if (ksp->converged != KSPConvergedDefault) PetscFunctionReturn(PETSC_SUCCESS);
    1393:   PetscCheck(!ctx->mininitialrtol, PetscObjectComm((PetscObject)ksp), PETSC_ERR_ARG_WRONGSTATE, "Cannot use KSPConvergedDefaultSetUIRNorm() and KSPConvergedDefaultSetUMIRNorm() together");
    1394:   ctx->initialrtol = PETSC_TRUE;
    1395:   PetscFunctionReturn(PETSC_SUCCESS);
    1396: }

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

    1403:   Collective

    1405:   Input Parameters:
    1406: . ksp - iterative context

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

    1411:   Level: intermediate

    1413:   Notes:
    1414:   UMIRNorm is short for Use Minimum Initial Residual Norm.

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

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

    1424:   PetscFunctionBegin;
    1426:   if (ksp->converged != KSPConvergedDefault) PetscFunctionReturn(PETSC_SUCCESS);
    1427:   PetscCheck(!ctx->initialrtol, PetscObjectComm((PetscObject)ksp), PETSC_ERR_ARG_WRONGSTATE, "Cannot use KSPConvergedDefaultSetUIRNorm() and KSPConvergedDefaultSetUMIRNorm() together");
    1428:   ctx->mininitialrtol = PETSC_TRUE;
    1429:   PetscFunctionReturn(PETSC_SUCCESS);
    1430: }

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

    1435:   Collective

    1437:   Input Parameters:
    1438: + ksp - iterative context
    1439: - flg - boolean flag

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

    1444:   Level: intermediate

    1446: .seealso: [](ch_ksp), `KSP`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUMIRNorm()`, `KSPConvergedDefaultSetUIRNorm()`
    1447: @*/
    1448: PetscErrorCode KSPConvergedDefaultSetConvergedMaxits(KSP ksp, PetscBool flg)
    1449: {
    1450:   KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx *)ksp->cnvP;

    1452:   PetscFunctionBegin;
    1455:   if (ksp->converged != KSPConvergedDefault) PetscFunctionReturn(PETSC_SUCCESS);
    1456:   ctx->convmaxits = flg;
    1457:   PetscFunctionReturn(PETSC_SUCCESS);
    1458: }

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

    1463:   Collective

    1465:   Input Parameters:
    1466: + ksp   - iterative context
    1467: . n     - iteration number
    1468: . rnorm - residual norm (may be estimated, depending on the method may be the preconditioned residual norm)
    1469: - ctx   - convergence context which must be created by `KSPConvergedDefaultCreate()`

    1471:   Output Parameter:
    1472: . reason - the convergence reason; it is positive if the iteration has converged,
    1473:            negative if the iteration has diverged, and `KSP_CONVERGED_ITERATING` otherwise

    1475:   Options Database Keys:
    1476: + -ksp_max_it                                  - maximum number of linear iterations
    1477: . -ksp_min_it                                  - minimum number of linear iterations, defaults to 0
    1478: . -ksp_rtol rtol                               - relative tolerance used in default determination of convergence, i.e. if residual norm decreases by this factor than convergence is declared
    1479: . -ksp_atol abstol                             - absolute tolerance used in default convergence test, i.e. if residual norm is less than this then convergence is declared
    1480: . -ksp_divtol tol                              - if residual norm increases by this factor than divergence is declared
    1481: . -ksp_converged_use_initial_residual_norm     - see `KSPConvergedDefaultSetUIRNorm()`
    1482: . -ksp_converged_use_min_initial_residual_norm - see `KSPConvergedDefaultSetUMIRNorm()`
    1483: - -ksp_converged_maxits                        - see `KSPConvergedDefaultSetConvergedMaxits()`

    1485:   Level: advanced

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

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

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

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

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

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

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

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

    1515: .seealso: [](ch_ksp), `KSP`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`,
    1516:           `KSPSetMinimumIterations()`, `KSPConvergenceTestFn`,
    1517:           `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetUMIRNorm()`, `KSPConvergedDefaultSetConvergedMaxits()`, `KSPConvergedDefaultCreate()`, `KSPConvergedDefaultDestroy()`
    1518: @*/
    1519: PetscErrorCode KSPConvergedDefault(KSP ksp, PetscInt n, PetscReal rnorm, KSPConvergedReason *reason, PetscCtx ctx)
    1520: {
    1521:   KSPConvergedDefaultCtx *cctx = (KSPConvergedDefaultCtx *)ctx;
    1522:   KSPNormType             normtype;

    1524:   PetscFunctionBegin;
    1527:   PetscAssertPointer(reason, 4);
    1528:   PetscCheck(cctx, PetscObjectComm((PetscObject)ksp), PETSC_ERR_ARG_NULL, "Convergence context must have been created with KSPConvergedDefaultCreate()");
    1529:   *reason = KSP_CONVERGED_ITERATING;

    1531:   if (cctx->convmaxits && n >= ksp->max_it) {
    1532:     *reason = KSP_CONVERGED_ITS;
    1533:     PetscCall(PetscInfo(ksp, "Linear solver has converged. Maximum number of iterations reached %" PetscInt_FMT "\n", n));
    1534:     PetscFunctionReturn(PETSC_SUCCESS);
    1535:   }
    1536:   PetscCall(KSPGetNormType(ksp, &normtype));
    1537:   if (normtype == KSP_NORM_NONE) PetscFunctionReturn(PETSC_SUCCESS);

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

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

    1577:   if (PetscIsInfOrNanReal(rnorm)) {
    1578:     PCFailedReason pcreason;
    1579:     PetscCall(PCReduceFailedReason(ksp->pc));
    1580:     PetscCall(PCGetFailedReason(ksp->pc, &pcreason));
    1581:     if (pcreason) {
    1582:       *reason = KSP_DIVERGED_PC_FAILED;
    1583:       PetscCall(PetscInfo(ksp, "Linear solver pcsetup fails, declaring divergence \n"));
    1584:     } else {
    1585:       *reason = KSP_DIVERGED_NANORINF;
    1586:       PetscCall(PetscInfo(ksp, "Linear solver has created a not a number (NaN) as the residual norm, declaring divergence \n"));
    1587:     }
    1588:     PetscFunctionReturn(PETSC_SUCCESS);
    1589:   }

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

    1593:   if (rnorm <= ksp->ttol) {
    1594:     if (rnorm < ksp->abstol) {
    1595:       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));
    1596:       *reason = KSP_CONVERGED_ATOL;
    1597:     } else {
    1598:       if (cctx->initialrtol) {
    1599:         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));
    1600:       } else {
    1601:         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));
    1602:       }
    1603:       *reason = KSP_CONVERGED_RTOL;
    1604:     }
    1605:   } else if (rnorm >= ksp->divtol * ksp->rnorm0) {
    1606:     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));
    1607:     *reason = KSP_DIVERGED_DTOL;
    1608:   }
    1609:   PetscFunctionReturn(PETSC_SUCCESS);
    1610: }

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

    1615:   Not Collective

    1617:   Input Parameter:
    1618: . ctx - convergence context

    1620:   Level: intermediate

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

    1625: .seealso: [](ch_ksp), `KSP`, `KSPConvergedDefault()`, `KSPConvergedDefaultCreate()`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`,
    1626:           `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetUMIRNorm()`
    1627: @*/
    1628: PetscErrorCode KSPConvergedDefaultDestroy(PetscCtxRt ctx)
    1629: {
    1630:   KSPConvergedDefaultCtx *cctx = *(KSPConvergedDefaultCtx **)ctx;

    1632:   PetscFunctionBegin;
    1633:   PetscCall(VecDestroy(&cctx->work));
    1634:   PetscCall(PetscFree(cctx));
    1635:   PetscFunctionReturn(PETSC_SUCCESS);
    1636: }

    1638: // PetscClangLinter pragma disable: -fdoc-sowing-chars
    1639: /*
    1640:   KSPBuildSolutionDefault - Default code to build/move the solution.

    1642:   Collective

    1644:   Input Parameters:
    1645: + ksp - iterative context
    1646: - v   - pointer to the user's vector

    1648:   Output Parameter:
    1649: . V - pointer to a vector containing the solution

    1651:   Level: advanced

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

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

    1660: .seealso: [](ch_ksp), `KSP`, `KSPGetSolution()`, `KSPBuildResidualDefault()`
    1661: */
    1662: PetscErrorCode KSPBuildSolutionDefault(KSP ksp, Vec v, Vec *V)
    1663: {
    1664:   PetscFunctionBegin;
    1665:   if (ksp->pc_side == PC_RIGHT) {
    1666:     if (ksp->pc) {
    1667:       PetscCheck(v, PetscObjectComm((PetscObject)ksp), PETSC_ERR_SUP, "Not working with right preconditioner");
    1668:       PetscCall(KSP_PCApply(ksp, ksp->vec_sol, v));
    1669:       *V = v;
    1670:     } else {
    1671:       if (v) {
    1672:         PetscCall(VecCopy(ksp->vec_sol, v));
    1673:         *V = v;
    1674:       } else *V = ksp->vec_sol;
    1675:     }
    1676:   } else if (ksp->pc_side == PC_SYMMETRIC) {
    1677:     if (ksp->pc) {
    1678:       PetscCheck(!ksp->transpose_solve, PetscObjectComm((PetscObject)ksp), PETSC_ERR_SUP, "Not working with symmetric preconditioner and transpose solve");
    1679:       PetscCheck(v, PetscObjectComm((PetscObject)ksp), PETSC_ERR_SUP, "Not working with symmetric preconditioner");
    1680:       PetscCall(PCApplySymmetricRight(ksp->pc, ksp->vec_sol, v));
    1681:       *V = v;
    1682:     } else {
    1683:       if (v) {
    1684:         PetscCall(VecCopy(ksp->vec_sol, v));
    1685:         *V = v;
    1686:       } else *V = ksp->vec_sol;
    1687:     }
    1688:   } else {
    1689:     if (v) {
    1690:       PetscCall(VecCopy(ksp->vec_sol, v));
    1691:       *V = v;
    1692:     } else *V = ksp->vec_sol;
    1693:   }
    1694:   PetscFunctionReturn(PETSC_SUCCESS);
    1695: }

    1697: /*@
    1698:   KSPBuildResidualDefault - Default code to compute the residual.

    1700:   Collecive on ksp

    1702:   Input Parameters:
    1703: + ksp - iterative context
    1704: . t   - pointer to temporary vector
    1705: - v   - pointer to user vector

    1707:   Output Parameter:
    1708: . V - pointer to a vector containing the residual

    1710:   Level: advanced

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

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

    1719: .seealso: [](ch_ksp), `KSP`, `KSPBuildSolutionDefault()`
    1720: @*/
    1721: PetscErrorCode KSPBuildResidualDefault(KSP ksp, Vec t, Vec v, Vec *V)
    1722: {
    1723:   Mat Amat, Pmat;

    1725:   PetscFunctionBegin;
    1726:   if (!ksp->pc) PetscCall(KSPGetPC(ksp, &ksp->pc));
    1727:   PetscCall(PCGetOperators(ksp->pc, &Amat, &Pmat));
    1728:   PetscCall(KSPBuildSolution(ksp, t, NULL));
    1729:   PetscCall(KSP_MatMult(ksp, Amat, t, v));
    1730:   PetscCall(VecAYPX(v, -1.0, ksp->vec_rhs));
    1731:   *V = v;
    1732:   PetscFunctionReturn(PETSC_SUCCESS);
    1733: }

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

    1738:   Collective

    1740:   Input Parameters:
    1741: + ksp    - iterative context
    1742: . rightn - number of right work vectors to allocate
    1743: - leftn  - number of left work vectors to allocate

    1745:   Output Parameters:
    1746: + right - the array of vectors created
    1747: - left  - the array of left vectors

    1749:   Level: advanced

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

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

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

    1760:   Developer Note:
    1761:   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
    1762:   that does not exist tries to get them from the `DM` (if it is provided) with `DMCreateGlobalVectors()`.

    1764: .seealso: [](ch_ksp), `MatCreateVecs()`, `VecDestroyVecs()`, `KSPSetWorkVecs()`
    1765: @*/
    1766: PetscErrorCode KSPCreateVecs(KSP ksp, PetscInt rightn, Vec *right[], PetscInt leftn, Vec *left[])
    1767: {
    1768:   Vec       vecr = NULL, vecl = NULL;
    1769:   PetscBool matset, pmatset, isshell, preferdm = PETSC_FALSE;
    1770:   Mat       mat = NULL;

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

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

    1845:   Collective

    1847:   Input Parameters:
    1848: + ksp - iterative context
    1849: - nw  - number of work vectors to allocate

    1851:   Level: developer

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

    1856: .seealso: [](ch_ksp), `KSP`, `KSPCreateVecs()`
    1857: @*/
    1858: PetscErrorCode KSPSetWorkVecs(KSP ksp, PetscInt nw)
    1859: {
    1860:   PetscFunctionBegin;
    1861:   PetscCall(VecDestroyVecs(ksp->nwork, &ksp->work));
    1862:   ksp->nwork = nw;
    1863:   PetscCall(KSPCreateVecs(ksp, nw, &ksp->work, 0, NULL));
    1864:   PetscFunctionReturn(PETSC_SUCCESS);
    1865: }

    1867: // PetscClangLinter pragma disable: -fdoc-sowing-chars
    1868: /*
    1869:   KSPDestroyDefault - Destroys a iterative context variable for methods with no separate context.  Preferred calling sequence `KSPDestroy()`.

    1871:   Input Parameter:
    1872: . ksp - the iterative context

    1874:   Level: advanced

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

    1879: .seealso: [](ch_ksp), `KSP`, `KSPDestroy()`
    1880: */
    1881: PetscErrorCode KSPDestroyDefault(KSP ksp)
    1882: {
    1883:   PetscFunctionBegin;
    1885:   PetscCall(PetscFree(ksp->data));
    1886:   PetscFunctionReturn(PETSC_SUCCESS);
    1887: }

    1889: /*@
    1890:   KSPGetConvergedReason - Gets the reason the `KSP` iteration was stopped.

    1892:   Not Collective

    1894:   Input Parameter:
    1895: . ksp - the `KSP` context

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

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

    1903:   Level: intermediate

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

    1908: .seealso: [](ch_ksp), `KSPConvergedReason`, `KSP`, `KSPSetConvergenceTest()`, `KSPConvergedDefault()`, `KSPSetTolerances()`,
    1909:           `KSPConvergedReasonView()`, `KSPGetConvergedReasonString()`
    1910: @*/
    1911: PetscErrorCode KSPGetConvergedReason(KSP ksp, KSPConvergedReason *reason)
    1912: {
    1913:   PetscFunctionBegin;
    1915:   PetscAssertPointer(reason, 2);
    1916:   *reason = ksp->reason;
    1917:   PetscFunctionReturn(PETSC_SUCCESS);
    1918: }

    1920: /*@C
    1921:   KSPGetConvergedReasonString - Return a human readable string for a `KSPConvergedReason`

    1923:   Not Collective

    1925:   Input Parameter:
    1926: . ksp - the `KSP` context

    1928:   Output Parameter:
    1929: . strreason - a human readable string that describes ksp converged reason

    1931:   Level: beginner

    1933: .seealso: [](ch_ksp), `KSP`, `KSPGetConvergedReason()`
    1934: @*/
    1935: PetscErrorCode KSPGetConvergedReasonString(KSP ksp, const char *strreason[])
    1936: {
    1937:   PetscFunctionBegin;
    1939:   PetscAssertPointer(strreason, 2);
    1940:   *strreason = KSPConvergedReasons[ksp->reason];
    1941:   PetscFunctionReturn(PETSC_SUCCESS);
    1942: }

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

    1948:   Logically Collective

    1950:   Input Parameters:
    1951: + ksp - the `KSP`
    1952: - dm  - the `DM`, cannot be `NULL` to remove a previously set `DM`

    1954:   Level: intermediate

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

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

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

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

    1992:   Logically Collective

    1994:   Input Parameters:
    1995: + ksp    - the `KSP`
    1996: . active - one of `KSP_DMACTIVE_OPERATOR`, `KSP_DMACTIVE_RHS`, or `KSP_DMACTIVE_INITIAL_GUESS`
    1997: - flg    - use the `DM`

    1999:   Level: intermediate

    2001:   Note:
    2002:   By default `KSPSetDM()` sets the `DM` as active.

    2004: .seealso: [](ch_ksp), `KSP`, `DM`, `KSPGetDM()`, `KSPSetDM()`, `SNESSetDM()`, `KSPSetComputeOperators()`, `KSPSetComputeRHS()`, `KSPSetComputeInitialGuess()`
    2005: @*/
    2006: PetscErrorCode KSPSetDMActive(KSP ksp, KSPDMActive active, PetscBool flg)
    2007: {
    2008:   PetscFunctionBegin;
    2011:   if (flg) ksp->dmActive = (KSPDMActive)(ksp->dmActive | active);
    2012:   else ksp->dmActive = (KSPDMActive)(ksp->dmActive & ~active);
    2013:   PetscFunctionReturn(PETSC_SUCCESS);
    2014: }

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

    2019:   Not Collective

    2021:   Input Parameter:
    2022: . ksp - the `KSP`

    2024:   Output Parameter:
    2025: . dm - the `DM`

    2027:   Level: intermediate

    2029: .seealso: [](ch_ksp), `KSP`, `DM`, `KSPSetDM()`, `KSPSetDMActive()`
    2030: @*/
    2031: PetscErrorCode KSPGetDM(KSP ksp, DM *dm)
    2032: {
    2033:   PetscFunctionBegin;
    2035:   if (!ksp->dm) {
    2036:     PetscCall(DMShellCreate(PetscObjectComm((PetscObject)ksp), &ksp->dm));
    2037:     ksp->dmAuto = PETSC_TRUE;
    2038:   }
    2039:   *dm = ksp->dm;
    2040:   PetscFunctionReturn(PETSC_SUCCESS);
    2041: }

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

    2046:   Logically Collective

    2048:   Input Parameters:
    2049: + ksp - the `KSP` context
    2050: - ctx - user context

    2052:   Level: intermediate

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

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

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

    2064: .seealso: [](ch_ksp), `KSP`, `KSPGetApplicationContext()`
    2065: @*/
    2066: PetscErrorCode KSPSetApplicationContext(KSP ksp, PetscCtx ctx)
    2067: {
    2068:   PC pc;

    2070:   PetscFunctionBegin;
    2072:   ksp->ctx = ctx;
    2073:   PetscCall(KSPGetPC(ksp, &pc));
    2074:   PetscCall(PCSetApplicationContext(pc, ctx));
    2075:   PetscFunctionReturn(PETSC_SUCCESS);
    2076: }

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

    2081:   Not Collective

    2083:   Input Parameter:
    2084: . ksp - `KSP` context

    2086:   Output Parameter:
    2087: . ctx - a pointer to the application context

    2089:   Level: intermediate

    2091:   Fortran Notes:
    2092:   This only works when the context is a Fortran derived type or a `PetscObject`. Define `ctx` with
    2093: .vb
    2094:   type(tUsertype), pointer :: ctx
    2095: .ve

    2097: .seealso: [](ch_ksp), `KSP`, `KSPSetApplicationContext()`
    2098: @*/
    2099: PetscErrorCode KSPGetApplicationContext(KSP ksp, PetscCtxRt ctx)
    2100: {
    2101:   PetscFunctionBegin;
    2103:   *(void **)ctx = ksp->ctx;
    2104:   PetscFunctionReturn(PETSC_SUCCESS);
    2105: }

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

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

    2113:   Collective

    2115:   Input Parameters:
    2116: + ksp - the linear solver `KSP` context.
    2117: . pc  - the preconditioner context
    2118: - vec - a vector that will be initialized with infinity to indicate lack of convergence

    2120:   Level: developer

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

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

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

    2132: .seealso: [](ch_ksp), `KSP`, `KSPCreate()`, `KSPSetType()`, `KSPCheckNorm()`, `KSPCheckDot()`
    2133: @*/
    2134: PetscErrorCode KSPCheckSolve(KSP ksp, PC pc, Vec vec)
    2135: {
    2136:   PCFailedReason pcreason;
    2137:   PC             subpc;

    2139:   PetscFunctionBegin;
    2140:   PetscCall(KSPGetPC(ksp, &subpc));
    2141:   PetscCall(PCGetFailedReason(subpc, &pcreason));
    2142:   PetscCall(VecFlag(vec, pcreason || (ksp->reason < 0 && ksp->reason != KSP_DIVERGED_ITS)));
    2143:   if (pcreason || (ksp->reason < 0 && ksp->reason != KSP_DIVERGED_ITS)) {
    2144:     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]);
    2145:     PetscCall(PetscInfo(ksp, "Detected not converged in KSP inner solve: KSP reason %s PC reason %s\n", KSPConvergedReasons[ksp->reason], PCFailedReasons[pcreason]));
    2146:     pc->failedreason = PC_SUBPC_ERROR;
    2147:   }
    2148:   PetscFunctionReturn(PETSC_SUCCESS);
    2149: }