Date: 2013-07-02T14:47:52+00:00

Actual source code: iterativ.c
petsc-3.4.2 2013-07-02

      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 truely necessary
      6:    files)
      7:  */
      8: #include <petsc-private/kspimpl.h>   /*I "petscksp.h" I*/
      9: #include <petscdmshell.h>

     13: /*@
     14:    KSPGetResidualNorm - Gets the last (approximate preconditioned)
     15:    residual norm that has been computed.

     17:    Not Collective

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

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

     25:    Level: intermediate

     27: .keywords: KSP, get, residual norm

     29: .seealso: KSPBuildResidual()
     30: @*/
     31: PetscErrorCode  KSPGetResidualNorm(KSP ksp,PetscReal *rnorm)
     32: {
     36:   *rnorm = ksp->rnorm;
     37:   return(0);
     38: }

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

     47:    Not Collective

     49:    Input Parameters:
     50: .  ksp - the iterative context

     52:    Output Parameters:
     53: .  its - number of iterations

     55:    Level: intermediate

     57:    Notes:
     58:       During the ith iteration this returns i-1
     59: .keywords: KSP, get, residual norm

     61: .seealso: KSPBuildResidual(), KSPGetResidualNorm()
     62: @*/
     63: PetscErrorCode  KSPGetIterationNumber(KSP ksp,PetscInt *its)
     64: {
     68:   *its = ksp->its;
     69:   return(0);
     70: }

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

     79:     Logically Collective on KSP

     81:     Input Parameters:
     82: +   ksp - the iterative context
     83: .   n  - the iteration
     84: -   rnorm - the two norm of the residual

     86:     Options Database Key:
     87: .   -ksp_monitor_singular_value - Activates KSPMonitorSingularValue()

     89:     Notes:
     90:     The CG solver uses the Lanczos technique for eigenvalue computation,
     91:     while GMRES uses the Arnoldi technique; other iterative methods do
     92:     not currently compute singular values.

     94:     Level: intermediate

     96: .keywords: KSP, CG, default, monitor, extreme, singular values, Lanczos, Arnoldi

     98: .seealso: KSPComputeExtremeSingularValues()
     99: @*/
    100: PetscErrorCode  KSPMonitorSingularValue(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy)
    101: {
    102:   PetscReal      emin,emax,c;
    104:   PetscViewer    viewer = (PetscViewer) dummy;

    108:   if (!viewer) {
    109:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);
    110:   }
    111:   PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);
    112:   if (!ksp->calc_sings) {
    113:     PetscViewerASCIIPrintf(viewer,"%3D KSP Residual norm %14.12e \n",n,(double)rnorm);
    114:   } else {
    115:     KSPComputeExtremeSingularValues(ksp,&emax,&emin);
    116:     c    = emax/emin;
    117:     PetscViewerASCIIPrintf(viewer,"%3D KSP Residual norm %14.12e %% max %14.12e min %14.12e max/min %14.12e\n",n,(double)rnorm,(double)emax,(double)emin,(double)c);
    118:   }
    119:   PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);
    120:   return(0);
    121: }

    125: /*@C
    126:    KSPMonitorSolution - Monitors progress of the KSP solvers by calling
    127:    VecView() for the approximate solution at each iteration.

    129:    Collective on KSP

    131:    Input Parameters:
    132: +  ksp - the KSP context
    133: .  its - iteration number
    134: .  fgnorm - 2-norm of residual (or gradient)
    135: -  dummy - either a viewer or NULL

    137:    Level: intermediate

    139:    Notes:
    140:     For some Krylov methods such as GMRES constructing the solution at
    141:   each iteration is expensive, hence using this will slow the code.

    143: .keywords: KSP, nonlinear, vector, monitor, view

    145: .seealso: KSPMonitorSet(), KSPMonitorDefault(), VecView()
    146: @*/
    147: PetscErrorCode  KSPMonitorSolution(KSP ksp,PetscInt its,PetscReal fgnorm,void *dummy)
    148: {
    150:   Vec            x;
    151:   PetscViewer    viewer = (PetscViewer) dummy;

    154:   KSPBuildSolution(ksp,NULL,&x);
    155:   if (!viewer) {
    156:     MPI_Comm comm;
    157:     PetscObjectGetComm((PetscObject)ksp,&comm);
    158:     viewer = PETSC_VIEWER_DRAW_(comm);
    159:   }
    160:   VecView(x,viewer);
    161:   return(0);
    162: }

    166: /*@C
    167:    KSPMonitorDefault - Print the residual norm at each iteration of an
    168:    iterative solver.

    170:    Collective on KSP

    172:    Input Parameters:
    173: +  ksp   - iterative context
    174: .  n     - iteration number
    175: .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
    176: -  dummy - unused monitor context

    178:    Level: intermediate

    180: .keywords: KSP, default, monitor, residual

    182: .seealso: KSPMonitorSet(), KSPMonitorTrueResidualNorm(), KSPMonitorLGResidualNormCreate()
    183: @*/
    184: PetscErrorCode  KSPMonitorDefault(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy)
    185: {
    187:   PetscViewer    viewer = (PetscViewer) dummy;

    190:   if (!viewer) {
    191:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);
    192:   }
    193:   PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);
    194:   if (n == 0 && ((PetscObject)ksp)->prefix) {
    195:     PetscViewerASCIIPrintf(viewer,"  Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);
    196:   }
    197:   PetscViewerASCIIPrintf(viewer,"%3D KSP Residual norm %14.12e \n",n,(double)rnorm);
    198:   PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);
    199:   return(0);
    200: }

    204: /*@C
    205:    KSPMonitorTrueResidualNorm - Prints the true residual norm as well as the preconditioned
    206:    residual norm at each iteration of an iterative solver.

    208:    Collective on KSP

    210:    Input Parameters:
    211: +  ksp   - iterative context
    212: .  n     - iteration number
    213: .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
    214: -  dummy - unused monitor context

    216:    Options Database Key:
    217: .  -ksp_monitor_true_residual - Activates KSPMonitorTrueResidualNorm()

    219:    Notes:
    220:    When using right preconditioning, these values are equivalent.

    222:    Level: intermediate

    224: .keywords: KSP, default, monitor, residual

    226: .seealso: KSPMonitorSet(), KSPMonitorDefault(), KSPMonitorLGResidualNormCreate(),KSPMonitorTrueResidualMaxNorm()
    227: @*/
    228: PetscErrorCode  KSPMonitorTrueResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy)
    229: {
    231:   Vec            resid;
    232:   PetscReal      truenorm,bnorm;
    233:   PetscViewer    viewer = (PetscViewer)dummy;
    234:   char           normtype[256];

    237:   if (!viewer) {
    238:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);
    239:   }
    240:   PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);
    241:   if (n == 0 && ((PetscObject)ksp)->prefix) {
    242:     PetscViewerASCIIPrintf(viewer,"  Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);
    243:   }
    244:   KSPBuildResidual(ksp,NULL,NULL,&resid);
    245:   VecNorm(resid,NORM_2,&truenorm);
    246:   VecDestroy(&resid);
    247:   VecNorm(ksp->vec_rhs,NORM_2,&bnorm);
    248:   PetscStrncpy(normtype,KSPNormTypes[ksp->normtype],sizeof(normtype));
    249:   PetscStrtolower(normtype);
    250:   PetscViewerASCIIPrintf(viewer,"%3D 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));
    251:   PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);
    252:   return(0);
    253: }

    257: /*@C
    258:    KSPMonitorTrueResidualMaxNorm - Prints the true residual max norm as well as the preconditioned
    259:    residual norm at each iteration of an iterative solver.

    261:    Collective on KSP

    263:    Input Parameters:
    264: +  ksp   - iterative context
    265: .  n     - iteration number
    266: .  rnorm - norm (preconditioned) residual value (may be estimated).
    267: -  dummy - unused monitor context

    269:    Options Database Key:
    270: .  -ksp_monitor_max - Activates KSPMonitorTrueResidualMaxNorm()

    272:    Notes:
    273:    This could be implemented (better) with a flag in ksp.

    275:    Level: intermediate

    277: .keywords: KSP, default, monitor, residual

    279: .seealso: KSPMonitorSet(), KSPMonitorDefault(), KSPMonitorLGResidualNormCreate(),KSPMonitorTrueResidualNorm()
    280: @*/
    281: PetscErrorCode  KSPMonitorTrueResidualMaxNorm(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy)
    282: {
    284:   Vec            resid;
    285:   PetscReal      truenorm,bnorm;
    286:   PetscViewer    viewer = (PetscViewer)dummy;
    287:   char           normtype[256];

    290:   if (!viewer) {
    291:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);
    292:   }
    293:   PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);
    294:   if (n == 0 && ((PetscObject)ksp)->prefix) {
    295:     PetscViewerASCIIPrintf(viewer,"  Residual norms (max) for %s solve.\n",((PetscObject)ksp)->prefix);
    296:   }
    297:   KSPBuildResidual(ksp,NULL,NULL,&resid);
    298:   VecNorm(resid,NORM_INFINITY,&truenorm);
    299:   VecDestroy(&resid);
    300:   VecNorm(ksp->vec_rhs,NORM_INFINITY,&bnorm);
    301:   PetscStrncpy(normtype,KSPNormTypes[ksp->normtype],sizeof(normtype));
    302:   PetscStrtolower(normtype);
    303:   /* PetscViewerASCIIPrintf(viewer,"%3D KSP %s resid norm %14.12e true resid norm %14.12e ||r(i)||_inf/||b||_inf %14.12e\n",n,normtype,(double)rnorm,(double)truenorm,(double)(truenorm/bnorm)); */
    304:   PetscViewerASCIIPrintf(viewer,"%3D KSP true resid max norm %14.12e ||r(i)||/||b|| %14.12e\n",n,(double)truenorm,(double)(truenorm/bnorm));
    305:   PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);
    306:   return(0);
    307: }

    311: PetscErrorCode  KSPMonitorRange_Private(KSP ksp,PetscInt it,PetscReal *per)
    312: {
    314:   Vec            resid;
    315:   PetscReal      rmax,pwork;
    316:   PetscInt       i,n,N;
    317:   const PetscScalar *r;

    320:   KSPBuildResidual(ksp,NULL,NULL,&resid);
    321:   VecNorm(resid,NORM_INFINITY,&rmax);
    322:   VecGetLocalSize(resid,&n);
    323:   VecGetSize(resid,&N);
    324:   VecGetArrayRead(resid,&r);
    325:   pwork = 0.0;
    326:   for (i=0; i<n; i++) pwork += (PetscAbsScalar(r[i]) > .20*rmax);
    327:   VecRestoreArrayRead(resid,&r);
    328:   VecDestroy(&resid);
    329:   MPI_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ksp));
    330:   *per = *per/N;
    331:   return(0);
    332: }

    336: /*@C
    337:    KSPMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.

    339:    Collective on KSP

    341:    Input Parameters:
    342: +  ksp   - iterative context
    343: .  it    - iteration number
    344: .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
    345: -  dummy - unused monitor context

    347:    Options Database Key:
    348: .  -ksp_monitor_range - Activates KSPMonitorRange()

    350:    Level: intermediate

    352: .keywords: KSP, default, monitor, residual

    354: .seealso: KSPMonitorSet(), KSPMonitorDefault(), KSPMonitorLGResidualNormCreate()
    355: @*/
    356: PetscErrorCode  KSPMonitorRange(KSP ksp,PetscInt it,PetscReal rnorm,void *dummy)
    357: {
    358:   PetscErrorCode   ierr;
    359:   PetscReal        perc,rel;
    360:   PetscViewer      viewer = (PetscViewer)dummy;
    361:   /* should be in a MonitorRangeContext */
    362:   static PetscReal prev;

    365:   if (!viewer) {
    366:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);
    367:   }
    368:   PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);
    369:   if (!it) prev = rnorm;
    370:   if (it == 0 && ((PetscObject)ksp)->prefix) {
    371:     PetscViewerASCIIPrintf(viewer,"  Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);
    372:   }
    373:   KSPMonitorRange_Private(ksp,it,&perc);

    375:   rel  = (prev - rnorm)/prev;
    376:   prev = rnorm;
    377:   PetscViewerASCIIPrintf(viewer,"%3D KSP preconditioned resid norm %14.12e Percent values above 20 percent of maximum %5.2f relative decrease %5.2e ratio %5.2e \n",it,(double)rnorm,(double)100.0*perc,(double)rel,(double)rel/perc);
    378:   PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);
    379:   return(0);
    380: }

    384: /*@C
    385:    KSPMonitorDynamicTolerance - Recompute the inner tolerance in every
    386:    outer iteration in an adaptive way.

    388:    Collective on KSP

    390:    Input Parameters:
    391: +  ksp   - iterative context
    392: .  n     - iteration number (not used)
    393: .  fnorm - the current residual norm
    394: .  dummy - some context as a C struct. fields:
    395:              coef: a scaling coefficient. default 1.0. can be passed through
    396:                    -sub_ksp_dynamic_tolerance_param
    397:              bnrm: norm of the right-hand side. store it to avoid repeated calculation

    399:    Notes:
    400:    This may be useful for a flexibly preconditioner Krylov method to
    401:    control the accuracy of the inner solves needed to gaurantee the
    402:    convergence of the outer iterations.

    404:    Level: advanced

    406: .keywords: KSP, inner tolerance

    408: .seealso: KSPMonitorDynamicToleranceDestroy()
    409: @*/
    410: PetscErrorCode KSPMonitorDynamicTolerance(KSP ksp,PetscInt its,PetscReal fnorm,void *dummy)
    411: {
    413:   PC             pc;
    414:   PetscReal      outer_rtol, outer_abstol, outer_dtol, inner_rtol;
    415:   PetscInt       outer_maxits,nksp,first,i;
    416:   KSPDynTolCtx   *scale   = (KSPDynTolCtx*)dummy;
    417:   KSP            kspinner = NULL, *subksp = NULL;

    420:   KSPGetPC(ksp, &pc);

    422:   /* compute inner_rtol */
    423:   if (scale->bnrm < 0.0) {
    424:     Vec b;
    425:     KSPGetRhs(ksp, &b);
    426:     VecNorm(b, NORM_2, &(scale->bnrm));
    427:   }
    428:   KSPGetTolerances(ksp, &outer_rtol, &outer_abstol, &outer_dtol, &outer_maxits);
    429:   inner_rtol = PetscMin(scale->coef * scale->bnrm * outer_rtol / fnorm, 0.999);
    430:   /*PetscPrintf(PETSC_COMM_WORLD, "        Inner rtol = %G\n", inner_rtol);*/

    432:   /* if pc is ksp */
    433:   PCKSPGetKSP(pc, &kspinner);
    434:   if (kspinner) {
    435:     KSPSetTolerances(kspinner, inner_rtol, outer_abstol, outer_dtol, outer_maxits);
    436:     return(0);
    437:   }

    439:   /* if pc is bjacobi */
    440:   PCBJacobiGetSubKSP(pc, &nksp, &first, &subksp);
    441:   if (subksp) {
    442:     for (i=0; i<nksp; i++) {
    443:       KSPSetTolerances(subksp[i], inner_rtol, outer_abstol, outer_dtol, outer_maxits);
    444:     }
    445:     return(0);
    446:   }

    448:   /* todo: dynamic tolerance may apply to other types of pc too */
    449:   return(0);
    450: }

    454: /*
    455:   Destroy the dummy context used in KSPMonitorDynamicTolerance()
    456: */
    457: PetscErrorCode KSPMonitorDynamicToleranceDestroy(void **dummy)
    458: {

    462:   PetscFree(*dummy);
    463:   return(0);
    464: }

    468: /*
    469:   Default (short) KSP Monitor, same as KSPMonitorDefault() except
    470:   it prints fewer digits of the residual as the residual gets smaller.
    471:   This is because the later digits are meaningless and are often
    472:   different on different machines; by using this routine different
    473:   machines will usually generate the same output.
    474: */
    475: PetscErrorCode  KSPMonitorDefaultShort(KSP ksp,PetscInt its,PetscReal fnorm,void *dummy)
    476: {
    478:   PetscViewer    viewer = (PetscViewer)dummy;

    481:   if (!viewer) {
    482:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);
    483:   }
    484:   PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);
    485:   if (its == 0 && ((PetscObject)ksp)->prefix) {
    486:     PetscViewerASCIIPrintf(viewer,"  Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);
    487:   }

    489:   if (fnorm > 1.e-9) {
    490:     PetscViewerASCIIPrintf(viewer,"%3D KSP Residual norm %G \n",its,fnorm);
    491:   } else if (fnorm > 1.e-11) {
    492:     PetscViewerASCIIPrintf(viewer,"%3D KSP Residual norm %5.3e \n",its,(double)fnorm);
    493:   } else {
    494:     PetscViewerASCIIPrintf(viewer,"%3D KSP Residual norm < 1.e-11\n",its);
    495:   }
    496:   PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);
    497:   return(0);
    498: }

    502: /*@C
    503:    KSPSkipConverged - Convergence test that do not return as converged
    504:    until the maximum number of iterations is reached.

    506:    Collective on KSP

    508:    Input Parameters:
    509: +  ksp   - iterative context
    510: .  n     - iteration number
    511: .  rnorm - 2-norm residual value (may be estimated)
    512: -  dummy - unused convergence context

    514:    Returns:
    515: .  reason - KSP_CONVERGED_ITERATING, KSP_CONVERGED_ITS

    517:    Notes:
    518:    This should be used as the convergence test with the option
    519:    KSPSetNormType(ksp,KSP_NORM_NONE), since norms of the residual are
    520:    not computed. Convergence is then declared after the maximum number
    521:    of iterations have been reached. Useful when one is using CG or
    522:    BiCGStab as a smoother.

    524:    Level: advanced

    526: .keywords: KSP, default, convergence, residual

    528: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSetNormType()
    529: @*/
    530: PetscErrorCode  KSPSkipConverged(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *dummy)
    531: {
    535:   *reason = KSP_CONVERGED_ITERATING;
    536:   if (n >= ksp->max_it) *reason = KSP_CONVERGED_ITS;
    537:   return(0);
    538: }

    543: /*@C
    544:    KSPDefaultConvergedCreate - Creates and initializes the space used by the KSPDefaultConverged() function context

    546:    Collective on KSP

    548:    Output Parameter:
    549: .  ctx - convergence context

    551:    Level: intermediate

    553: .keywords: KSP, default, convergence, residual

    555: .seealso: KSPDefaultConverged(), KSPDefaultConvergedDestroy(), KSPSetConvergenceTest(), KSPSetTolerances(),
    556:           KSPSkipConverged(), KSPConvergedReason, KSPGetConvergedReason(), KSPDefaultConvergedSetUIRNorm(), KSPDefaultConvergedSetUMIRNorm()
    557: @*/
    558: PetscErrorCode  KSPDefaultConvergedCreate(void **ctx)
    559: {
    560:   PetscErrorCode         ierr;
    561:   KSPDefaultConvergedCtx *cctx;

    564:   PetscNew(KSPDefaultConvergedCtx,&cctx);
    565:   *ctx = cctx;
    566:   return(0);
    567: }

    571: /*@
    572:    KSPDefaultConvergedSetUIRNorm - makes the default convergence test use || B*(b - A*(initial guess))||
    573:       instead of || B*b ||. In the case of right preconditioner or if KSPSetNormType(ksp,KSP_NORM_UNPRECONDIITONED)
    574:       is used there is no B in the above formula. UIRNorm is short for Use Initial Residual Norm.

    576:    Collective on KSP

    578:    Input Parameters:
    579: .  ksp   - iterative context

    581:    Options Database:
    582: .   -ksp_converged_use_initial_residual_norm

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

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

    590:    If the convergence test is not KSPDefaultConverged() then this is ignored.

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

    595:    Level: intermediate

    597: .keywords: KSP, default, convergence, residual

    599: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSkipConverged(), KSPConvergedReason, KSPGetConvergedReason(), KSPDefaultConvergedSetUMIRNorm()
    600: @*/
    601: PetscErrorCode  KSPDefaultConvergedSetUIRNorm(KSP ksp)
    602: {
    603:   KSPDefaultConvergedCtx *ctx = (KSPDefaultConvergedCtx*) ksp->cnvP;

    607:   if (ksp->converged != KSPDefaultConverged) return(0);
    608:   if (ctx->mininitialrtol) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_WRONGSTATE,"Cannot use KSPDefaultConvergedSetUIRNorm() and KSPDefaultConvergedSetUMIRNorm() together");
    609:   ctx->initialrtol = PETSC_TRUE;
    610:   return(0);
    611: }

    615: /*@
    616:    KSPDefaultConvergedSetUMIRNorm - makes the default convergence test use min(|| B*(b - A*(initial guess))||,|| B*b ||)
    617:       In the case of right preconditioner or if KSPSetNormType(ksp,KSP_NORM_UNPRECONDIITONED)
    618:       is used there is no B in the above formula. UMIRNorm is short for Use Minimum Initial Residual Norm.

    620:    Collective on KSP

    622:    Input Parameters:
    623: .  ksp   - iterative context

    625:    Options Database:
    626: .   -ksp_converged_use_min_initial_residual_norm

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

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

    633:    Level: intermediate

    635: .keywords: KSP, default, convergence, residual

    637: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSkipConverged(), KSPConvergedReason, KSPGetConvergedReason(), KSPDefaultConvergedSetUIRNorm()
    638: @*/
    639: PetscErrorCode  KSPDefaultConvergedSetUMIRNorm(KSP ksp)
    640: {
    641:   KSPDefaultConvergedCtx *ctx = (KSPDefaultConvergedCtx*) ksp->cnvP;

    645:   if (ksp->converged != KSPDefaultConverged) return(0);
    646:   if (ctx->initialrtol) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_WRONGSTATE,"Cannot use KSPDefaultConvergedSetUIRNorm() and KSPDefaultConvergedSetUMIRNorm() together");
    647:   ctx->mininitialrtol = PETSC_TRUE;
    648:   return(0);
    649: }

    653: /*@C
    654:    KSPDefaultConverged - Determines convergence of
    655:    the iterative solvers (default code).

    657:    Collective on KSP

    659:    Input Parameters:
    660: +  ksp   - iterative context
    661: .  n     - iteration number
    662: .  rnorm - 2-norm residual value (may be estimated)
    663: -  ctx - convergence context which must be created by KSPDefaultConvergedCreate()

    665:    reason is set to:
    666: +   positive - if the iteration has converged;
    667: .   negative - if residual norm exceeds divergence threshold;
    668: -   0 - otherwise.

    670:    Notes:
    671:    KSPDefaultConverged() reaches convergence when
    672: $      rnorm < MAX (rtol * rnorm_0, abstol);
    673:    Divergence is detected if
    674: $      rnorm > dtol * rnorm_0,

    676:    where
    677: +     rtol = relative tolerance,
    678: .     abstol = absolute tolerance.
    679: .     dtol = divergence tolerance,
    680: -     rnorm_0 is the two norm of the right hand side. When initial guess is non-zero you
    681:           can call KSPDefaultConvergedSetUIRNorm() to use the norm of (b - A*(initial guess))
    682:           as the starting point for relative norm convergence testing.

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

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

    689:    Level: intermediate

    691: .keywords: KSP, default, convergence, residual

    693: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSkipConverged(), KSPConvergedReason, KSPGetConvergedReason(),
    694:           KSPDefaultConvergedSetUIRNorm(), KSPDefaultConvergedSetUMIRNorm(), KSPDefaultConvergedCreate(), KSPDefaultConvergedDestroy()
    695: @*/
    696: PetscErrorCode  KSPDefaultConverged(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *ctx)
    697: {
    698:   PetscErrorCode         ierr;
    699:   KSPDefaultConvergedCtx *cctx = (KSPDefaultConvergedCtx*) ctx;
    700:   KSPNormType            normtype;

    705:   *reason = KSP_CONVERGED_ITERATING;

    707:   KSPGetNormType(ksp,&normtype);
    708:   if (normtype == KSP_NORM_NONE) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_WRONGSTATE,"Use KSPSkipConverged() with KSPNormType of KSP_NORM_NONE");

    710:   if (!cctx) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_NULL,"Convergence context must have been created with KSPDefaultConvergedCreate()");
    711:   if (!n) {
    712:     /* if user gives initial guess need to compute norm of b */
    713:     if (!ksp->guess_zero && !cctx->initialrtol) {
    714:       PetscReal snorm;
    715:       if (ksp->normtype == KSP_NORM_UNPRECONDITIONED || ksp->pc_side == PC_RIGHT) {
    716:         PetscInfo(ksp,"user has provided nonzero initial guess, computing 2-norm of RHS\n");
    717:         VecNorm(ksp->vec_rhs,NORM_2,&snorm);        /*     <- b'*b */
    718:       } else {
    719:         Vec z;
    720:         /* Should avoid allocating the z vector each time but cannot stash it in cctx because if KSPReset() is called the vector size might change */
    721:         VecDuplicate(ksp->vec_rhs,&z);
    722:         KSP_PCApply(ksp,ksp->vec_rhs,z);
    723:         if (ksp->normtype == KSP_NORM_PRECONDITIONED) {
    724:           PetscInfo(ksp,"user has provided nonzero initial guess, computing 2-norm of preconditioned RHS\n");
    725:           VecNorm(z,NORM_2,&snorm);                 /*    dp <- b'*B'*B*b */
    726:         } else if (ksp->normtype == KSP_NORM_NATURAL) {
    727:           PetscScalar norm;
    728:           PetscInfo(ksp,"user has provided nonzero initial guess, computing natural norm of RHS\n");
    729:           VecDot(ksp->vec_rhs,z,&norm);
    730:           snorm = PetscSqrtReal(PetscAbsScalar(norm));                            /*    dp <- b'*B*b */
    731:         }
    732:         VecDestroy(&z);
    733:       }
    734:       /* handle special case of zero RHS and nonzero guess */
    735:       if (!snorm) {
    736:         PetscInfo(ksp,"Special case, user has provided nonzero initial guess and zero RHS\n");
    737:         snorm = rnorm;
    738:       }
    739:       if (cctx->mininitialrtol) ksp->rnorm0 = PetscMin(snorm,rnorm);
    740:       else ksp->rnorm0 = snorm;
    741:     } else {
    742:       ksp->rnorm0 = rnorm;
    743:     }
    744:     ksp->ttol = PetscMax(ksp->rtol*ksp->rnorm0,ksp->abstol);
    745:   }

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

    749:   if (PetscIsInfOrNanScalar(rnorm)) {
    750:     PetscInfo(ksp,"Linear solver has created a not a number (NaN) as the residual norm, declaring divergence \n");
    751:     *reason = KSP_DIVERGED_NANORINF;
    752:   } else if (rnorm <= ksp->ttol) {
    753:     if (rnorm < ksp->abstol) {
    754:       PetscInfo3(ksp,"Linear solver has converged. Residual norm %14.12e is less than absolute tolerance %14.12e at iteration %D\n",(double)rnorm,(double)ksp->abstol,n);
    755:       *reason = KSP_CONVERGED_ATOL;
    756:     } else {
    757:       if (cctx->initialrtol) {
    758:         PetscInfo4(ksp,"Linear solver has converged. Residual norm %14.12e is less than relative tolerance %14.12e times initial residual norm %14.12e at iteration %D\n",(double)rnorm,(double)ksp->rtol,(double)ksp->rnorm0,n);
    759:       } else {
    760:         PetscInfo4(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 %D\n",(double)rnorm,(double)ksp->rtol,(double)ksp->rnorm0,n);
    761:       }
    762:       *reason = KSP_CONVERGED_RTOL;
    763:     }
    764:   } else if (rnorm >= ksp->divtol*ksp->rnorm0) {
    765:     PetscInfo3(ksp,"Linear solver is diverging. Initial right hand size norm %14.12e, current residual norm %14.12e at iteration %D\n",(double)ksp->rnorm0,(double)rnorm,n);
    766:     *reason = KSP_DIVERGED_DTOL;
    767:   }
    768:   return(0);
    769: }

    773: /*@C
    774:    KSPDefaultConvergedDestroy - Frees the space used by the KSPDefaultConverged() function context

    776:    Collective on KSP

    778:    Input Parameters:
    779: .  ctx - convergence context

    781:    Level: intermediate

    783: .keywords: KSP, default, convergence, residual

    785: .seealso: KSPDefaultConverged(), KSPDefaultConvergedCreate(), KSPSetConvergenceTest(), KSPSetTolerances(), KSPSkipConverged(),
    786:           KSPConvergedReason, KSPGetConvergedReason(), KSPDefaultConvergedSetUIRNorm(), KSPDefaultConvergedSetUMIRNorm()
    787: @*/
    788: PetscErrorCode  KSPDefaultConvergedDestroy(void *ctx)
    789: {
    790:   PetscErrorCode         ierr;
    791:   KSPDefaultConvergedCtx *cctx = (KSPDefaultConvergedCtx*) ctx;

    794:   VecDestroy(&cctx->work);
    795:   PetscFree(ctx);
    796:   return(0);
    797: }

    801: /*
    802:    KSPBuildSolutionDefault - Default code to create/move the solution.

    804:    Input Parameters:
    805: +  ksp - iterative context
    806: -  v   - pointer to the user's vector

    808:    Output Parameter:
    809: .  V - pointer to a vector containing the solution

    811:    Level: advanced

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

    815: .keywords:  KSP, build, solution, default

    817: .seealso: KSPGetSolution(), KSPBuildResidualDefault()
    818: */
    819: PetscErrorCode KSPBuildSolutionDefault(KSP ksp,Vec v,Vec *V)
    820: {

    824:   if (ksp->pc_side == PC_RIGHT) {
    825:     if (ksp->pc) {
    826:       if (v) {
    827:         KSP_PCApply(ksp,ksp->vec_sol,v); *V = v;
    828:       } else SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Not working with right preconditioner");
    829:     } else {
    830:       if (v) {
    831:         VecCopy(ksp->vec_sol,v); *V = v;
    832:       } else *V = ksp->vec_sol;
    833:     }
    834:   } else if (ksp->pc_side == PC_SYMMETRIC) {
    835:     if (ksp->pc) {
    836:       if (ksp->transpose_solve) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Not working with symmetric preconditioner and transpose solve");
    837:       if (v) {
    838:         PCApplySymmetricRight(ksp->pc,ksp->vec_sol,v);
    839:         *V = v;
    840:       } else SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Not working with symmetric preconditioner");
    841:     } else {
    842:       if (v) {
    843:         VecCopy(ksp->vec_sol,v); *V = v;
    844:       } else *V = ksp->vec_sol;
    845:     }
    846:   } else {
    847:     if (v) {
    848:       VecCopy(ksp->vec_sol,v); *V = v;
    849:     } else *V = ksp->vec_sol;
    850:   }
    851:   return(0);
    852: }

    856: /*
    857:    KSPBuildResidualDefault - Default code to compute the residual.

    859:    Input Parameters:
    860: .  ksp - iterative context
    861: .  t   - pointer to temporary vector
    862: .  v   - pointer to user vector

    864:    Output Parameter:
    865: .  V - pointer to a vector containing the residual

    867:    Level: advanced

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

    871: .keywords:  KSP, build, residual, default

    873: .seealso: KSPBuildSolutionDefault()
    874: */
    875: PetscErrorCode KSPBuildResidualDefault(KSP ksp,Vec t,Vec v,Vec *V)
    876: {
    878:   MatStructure   pflag;
    879:   Mat            Amat,Pmat;

    882:   if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
    883:   PCGetOperators(ksp->pc,&Amat,&Pmat,&pflag);
    884:   KSPBuildSolution(ksp,t,NULL);
    885:   KSP_MatMult(ksp,Amat,t,v);
    886:   VecAYPX(v,-1.0,ksp->vec_rhs);
    887:   *V   = v;
    888:   return(0);
    889: }

    893: /*@C
    894:   KSPGetVecs - Gets a number of work vectors.

    896:   Input Parameters:
    897: + ksp  - iterative context
    898: . rightn  - number of right work vectors
    899: - leftn   - number of left work vectors to allocate

    901:   Output Parameter:
    902: +  right - the array of vectors created
    903: -  left - the array of left vectors

    905:    Note: The right vector has as many elements as the matrix has columns. The left
    906:      vector has as many elements as the matrix has rows.

    908:    Level: advanced

    910: .seealso:   MatGetVecs()

    912: @*/
    913: PetscErrorCode KSPGetVecs(KSP ksp,PetscInt rightn, Vec **right,PetscInt leftn,Vec **left)
    914: {
    916:   Vec            vecr,vecl;

    919:   if (rightn) {
    920:     if (!right) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_INCOMP,"You asked for right vectors but did not pass a pointer to hold them");
    921:     if (ksp->vec_sol) vecr = ksp->vec_sol;
    922:     else {
    923:       if (ksp->dm) {
    924:         DMGetGlobalVector(ksp->dm,&vecr);
    925:       } else {
    926:         Mat mat;
    927:         if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
    928:         PCGetOperators(ksp->pc,&mat,NULL,NULL);
    929:         MatGetVecs(mat,&vecr,NULL);
    930:       }
    931:     }
    932:     VecDuplicateVecs(vecr,rightn,right);
    933:     if (!ksp->vec_sol) {
    934:       if (ksp->dm) {
    935:         DMRestoreGlobalVector(ksp->dm,&vecr);
    936:       } else {
    937:         VecDestroy(&vecr);
    938:       }
    939:     }
    940:   }
    941:   if (leftn) {
    942:     if (!left) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_INCOMP,"You asked for left vectors but did not pass a pointer to hold them");
    943:     if (ksp->vec_rhs) vecl = ksp->vec_rhs;
    944:     else {
    945:       if (ksp->dm) {
    946:         DMGetGlobalVector(ksp->dm,&vecl);
    947:       } else {
    948:         Mat mat;
    949:         if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
    950:         PCGetOperators(ksp->pc,&mat,NULL,NULL);
    951:         MatGetVecs(mat,NULL,&vecl);
    952:       }
    953:     }
    954:     VecDuplicateVecs(vecl,leftn,left);
    955:     if (!ksp->vec_rhs) {
    956:       if (ksp->dm) {
    957:         DMRestoreGlobalVector(ksp->dm,&vecl);
    958:       } else {
    959:         VecDestroy(&vecl);
    960:       }
    961:     }
    962:   }
    963:   return(0);
    964: }

    968: /*
    969:   KSPSetWorkVecs - Sets a number of work vectors into a KSP object

    971:   Input Parameters:
    972: . ksp  - iterative context
    973: . nw   - number of work vectors to allocate

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

    977:  */
    978: PetscErrorCode KSPSetWorkVecs(KSP ksp,PetscInt nw)
    979: {

    983:   VecDestroyVecs(ksp->nwork,&ksp->work);
    984:   ksp->nwork = nw;
    985:   KSPGetVecs(ksp,nw,&ksp->work,0,NULL);
    986:   PetscLogObjectParents(ksp,nw,ksp->work);
    987:   return(0);
    988: }

    992: /*
    993:   KSPDestroyDefault - Destroys a iterative context variable for methods with
    994:   no separate context.  Preferred calling sequence KSPDestroy().

    996:   Input Parameter:
    997: . ksp - the iterative context

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

    1001: */
    1002: PetscErrorCode KSPDestroyDefault(KSP ksp)
    1003: {

    1008:   PetscFree(ksp->data);
    1009:   return(0);
    1010: }

    1014: /*@
    1015:    KSPGetConvergedReason - Gets the reason the KSP iteration was stopped.

    1017:    Not Collective

    1019:    Input Parameter:
    1020: .  ksp - the KSP context

    1022:    Output Parameter:
    1023: .  reason - negative value indicates diverged, positive value converged, see KSPConvergedReason

    1025:    Possible values for reason:
    1026: +  KSP_CONVERGED_RTOL (residual 2-norm decreased by a factor of rtol, from 2-norm of right hand side)
    1027: .  KSP_CONVERGED_ATOL (residual 2-norm less than abstol)
    1028: .  KSP_CONVERGED_ITS (used by the preonly preconditioner that always uses ONE iteration, or when the KSPSkipConverged() convergence
    1029:            test routine is set.
    1030: .  KSP_CONVERGED_CG_NEG_CURVE
    1031: .  KSP_CONVERGED_CG_CONSTRAINED
    1032: .  KSP_CONVERGED_STEP_LENGTH
    1033: .  KSP_DIVERGED_ITS  (required more than its to reach convergence)
    1034: .  KSP_DIVERGED_DTOL (residual norm increased by a factor of divtol)
    1035: .  KSP_DIVERGED_NANORINF (residual norm became Not-a-number or Inf likely due to 0/0)
    1036: .  KSP_DIVERGED_BREAKDOWN (generic breakdown in method)
    1037: -  KSP_DIVERGED_BREAKDOWN_BICG (Initial residual is orthogonal to preconditioned initial
    1038:                                 residual. Try a different preconditioner, or a different initial Level.)

    1040:    See also manual page for each reason.

    1042:    guess: beginner

    1044:    Notes: Can only be called after the call the KSPSolve() is complete.

    1046:    Level: intermediate

    1048: .keywords: KSP, nonlinear, set, convergence, test

    1050: .seealso: KSPSetConvergenceTest(), KSPDefaultConverged(), KSPSetTolerances(), KSPConvergedReason
    1051: @*/
    1052: PetscErrorCode  KSPGetConvergedReason(KSP ksp,KSPConvergedReason *reason)
    1053: {
    1057:   *reason = ksp->reason;
    1058:   return(0);
    1059: }

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

    1067:    Logically Collective on KSP

    1069:    Input Parameters:
    1070: +  ksp - the preconditioner context
    1071: -  dm - the dm

    1073:    Level: intermediate

    1076: .seealso: KSPGetDM(), KSPSetDM(), KSPGetDM()
    1077: @*/
    1078: PetscErrorCode  KSPSetDM(KSP ksp,DM dm)
    1079: {
    1081:   PC             pc;

    1085:   if (dm) {PetscObjectReference((PetscObject)dm);}
    1086:   if (ksp->dm) {                /* Move the DMSNES context over to the new DM unless the new DM already has one */
    1087:     if (ksp->dm->dmksp && ksp->dmAuto && !dm->dmksp) {
    1088:       DMKSP kdm;
    1089:       DMCopyDMKSP(ksp->dm,dm);
    1090:       DMGetDMKSP(ksp->dm,&kdm);
    1091:       if (kdm->originaldm == ksp->dm) kdm->originaldm = dm; /* Grant write privileges to the replacement DM */
    1092:     }
    1093:     DMDestroy(&ksp->dm);
    1094:   }
    1095:   ksp->dm       = dm;
    1096:   ksp->dmAuto   = PETSC_FALSE;
    1097:   KSPGetPC(ksp,&pc);
    1098:   PCSetDM(pc,dm);
    1099:   ksp->dmActive = PETSC_TRUE;
    1100:   return(0);
    1101: }

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

    1108:    Logically Collective on KSP

    1110:    Input Parameters:
    1111: +  ksp - the preconditioner context
    1112: -  flg - use the DM

    1114:    Level: intermediate

    1116:    Notes:
    1117:    By default KSPSetDM() sets the DM as active, call KSPSetDMActive(dm,PETSC_FALSE); after KSPSetDM(dm) to not have the KSP object use the DM to generate the matrices

    1119: .seealso: KSPGetDM(), KSPSetDM(), KSPGetDM()
    1120: @*/
    1121: PetscErrorCode  KSPSetDMActive(KSP ksp,PetscBool flg)
    1122: {
    1126:   ksp->dmActive = flg;
    1127:   return(0);
    1128: }

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

    1135:    Not Collective

    1137:    Input Parameter:
    1138: . ksp - the preconditioner context

    1140:    Output Parameter:
    1141: .  dm - the dm

    1143:    Level: intermediate

    1146: .seealso: KSPSetDM(), KSPSetDM(), KSPGetDM()
    1147: @*/
    1148: PetscErrorCode  KSPGetDM(KSP ksp,DM *dm)
    1149: {

    1154:   if (!ksp->dm) {
    1155:     DMShellCreate(PetscObjectComm((PetscObject)ksp),&ksp->dm);
    1156:     ksp->dmAuto = PETSC_TRUE;
    1157:   }
    1158:   *dm = ksp->dm;
    1159:   return(0);
    1160: }

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

    1167:    Logically Collective on KSP

    1169:    Input Parameters:
    1170: +  ksp - the KSP context
    1171: -  usrP - optional user context

    1173:    Level: intermediate

    1175: .keywords: KSP, set, application, context

    1177: .seealso: KSPGetApplicationContext()
    1178: @*/
    1179: PetscErrorCode  KSPSetApplicationContext(KSP ksp,void *usrP)
    1180: {
    1182:   PC             pc;

    1186:   ksp->user = usrP;
    1187:   KSPGetPC(ksp,&pc);
    1188:   PCSetApplicationContext(pc,usrP);
    1189:   return(0);
    1190: }

    1194: /*@
    1195:    KSPGetApplicationContext - Gets the user-defined context for the linear solver.

    1197:    Not Collective

    1199:    Input Parameter:
    1200: .  ksp - KSP context

    1202:    Output Parameter:
    1203: .  usrP - user context

    1205:    Level: intermediate

    1207: .keywords: KSP, get, application, context

    1209: .seealso: KSPSetApplicationContext()
    1210: @*/
    1211: PetscErrorCode  KSPGetApplicationContext(KSP ksp,void *usrP)
    1212: {
    1215:   *(void**)usrP = ksp->user;
    1216:   return(0);
    1217: }