Actual source code: iterativ.c
petsc-3.10.5 2019-03-28
Report Typos and Errors

      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>
      9:  #include <petscdmshell.h>

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

     15:    Not Collective

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

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

     23:    Level: intermediate

     25: .keywords: KSP, get, residual norm

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

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

     43:    Not Collective

     45:    Input Parameters:
     46: .  ksp - the iterative context

     48:    Output Parameters:
     49: .  its - number of iterations

     51:    Level: intermediate

     53:    Notes:
     54:       During the ith iteration this returns i-1
     55: .keywords: KSP, get, residual norm

     57: .seealso: KSPBuildResidual(), KSPGetResidualNorm(), KSPGetTotalIterations()
     58: @*/
     59: PetscErrorCode  KSPGetIterationNumber(KSP ksp,PetscInt *its)
     60: {
     64:   *its = ksp->its;
     65:   return(0);
     66: }

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

     71:    Not Collective

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

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

     79:    Level: intermediate

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

     85: .keywords: KSP, get, residual norm

     87: .seealso: KSPBuildResidual(), KSPGetResidualNorm(), KSPGetIterationNumber()
     88: @*/
     89: PetscErrorCode  KSPGetTotalIterations(KSP ksp,PetscInt *its)
     90: {
     94:   *its = ksp->totalits;
     95:   return(0);
     96: }

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

    103:     Logically Collective on KSP

    105:     Input Parameters:
    106: +   ksp - the iterative context
    107: .   n  - the iteration
    108: -   rnorm - the two norm of the residual

    110:     Options Database Key:
    111: .   -ksp_monitor_singular_value - Activates KSPMonitorSingularValue()

    113:     Notes:
    114:     The CG solver uses the Lanczos technique for eigenvalue computation,
    115:     while GMRES uses the Arnoldi technique; other iterative methods do
    116:     not currently compute singular values.

    118:     Level: intermediate

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

    122: .seealso: KSPComputeExtremeSingularValues()
    123: @*/
    124: PetscErrorCode  KSPMonitorSingularValue(KSP ksp,PetscInt n,PetscReal rnorm,PetscViewerAndFormat *dummy)
    125: {
    126:   PetscReal      emin,emax,c;
    128:   PetscViewer    viewer = dummy->viewer;

    133:   PetscViewerPushFormat(viewer,dummy->format);
    134:   PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);
    135:   if (!ksp->calc_sings) {
    136:     PetscViewerASCIIPrintf(viewer,"%3D KSP Residual norm %14.12e \n",n,(double)rnorm);
    137:   } else {
    138:     KSPComputeExtremeSingularValues(ksp,&emax,&emin);
    139:     c    = emax/emin;
    140:     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);
    141:   }
    142:   PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);
    143:   PetscViewerPopFormat(viewer);
    144:   return(0);
    145: }

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

    151:    Collective on KSP

    153:    Input Parameters:
    154: +  ksp - the KSP context
    155: .  its - iteration number
    156: .  fgnorm - 2-norm of residual (or gradient)
    157: -  dummy - a viewer

    159:    Level: intermediate

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

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

    167: .seealso: KSPMonitorSet(), KSPMonitorDefault(), VecView()
    168: @*/
    169: PetscErrorCode  KSPMonitorSolution(KSP ksp,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *dummy)
    170: {
    172:   Vec            x;
    173:   PetscViewer    viewer = dummy->viewer;

    177:   KSPBuildSolution(ksp,NULL,&x);
    178:   PetscViewerPushFormat(viewer,dummy->format);
    179:   VecView(x,viewer);
    180:   PetscViewerPopFormat(viewer);
    181:   return(0);
    182: }

    184: /*@C
    185:    KSPMonitorDefault - Print the residual norm at each iteration of an
    186:    iterative solver.

    188:    Collective on KSP

    190:    Input Parameters:
    191: +  ksp   - iterative context
    192: .  n     - iteration number
    193: .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
    194: -  dummy - an ASCII PetscViewer

    196:    Level: intermediate

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

    200: .seealso: KSPMonitorSet(), KSPMonitorTrueResidualNorm(), KSPMonitorLGResidualNormCreate()
    201: @*/
    202: PetscErrorCode  KSPMonitorDefault(KSP ksp,PetscInt n,PetscReal rnorm,PetscViewerAndFormat *dummy)
    203: {
    205:   PetscViewer    viewer =  dummy->viewer;

    209:   PetscViewerPushFormat(viewer,dummy->format);
    210:   PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);
    211:   if (n == 0 && ((PetscObject)ksp)->prefix) {
    212:     PetscViewerASCIIPrintf(viewer,"  Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);
    213:   }
    214:   PetscViewerASCIIPrintf(viewer,"%3D KSP Residual norm %14.12e \n",n,(double)rnorm);
    215:   PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);
    216:   PetscViewerPopFormat(viewer);
    217:   return(0);
    218: }

    220: /*@C
    221:    KSPMonitorTrueResidualNorm - Prints the true residual norm as well as the preconditioned
    222:    residual norm at each iteration of an iterative solver.

    224:    Collective on KSP

    226:    Input Parameters:
    227: +  ksp   - iterative context
    228: .  n     - iteration number
    229: .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
    230: -  dummy - an ASCII PetscViewer

    232:    Options Database Key:
    233: .  -ksp_monitor_true_residual - Activates KSPMonitorTrueResidualNorm()

    235:    Notes:
    236:    When using right preconditioning, these values are equivalent.

    238:    Level: intermediate

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

    242: .seealso: KSPMonitorSet(), KSPMonitorDefault(), KSPMonitorLGResidualNormCreate(),KSPMonitorTrueResidualMaxNorm()
    243: @*/
    244: PetscErrorCode  KSPMonitorTrueResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,PetscViewerAndFormat *dummy)
    245: {
    247:   Vec            resid;
    248:   PetscReal      truenorm,bnorm;
    249:   PetscViewer    viewer = dummy->viewer;
    250:   char           normtype[256];

    254:   PetscViewerPushFormat(viewer,dummy->format);
    255:   PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);
    256:   if (n == 0 && ((PetscObject)ksp)->prefix) {
    257:     PetscViewerASCIIPrintf(viewer,"  Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);
    258:   }
    259:   KSPBuildResidual(ksp,NULL,NULL,&resid);
    260:   VecNorm(resid,NORM_2,&truenorm);
    261:   VecDestroy(&resid);
    262:   VecNorm(ksp->vec_rhs,NORM_2,&bnorm);
    263:   PetscStrncpy(normtype,KSPNormTypes[ksp->normtype],sizeof(normtype));
    264:   PetscStrtolower(normtype);
    265:   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));
    266:   PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);
    267:   PetscViewerPopFormat(viewer);
    268:   return(0);
    269: }

    271: /*@C
    272:    KSPMonitorTrueResidualMaxNorm - Prints the true residual max norm each iteration of an iterative solver.

    274:    Collective on KSP

    276:    Input Parameters:
    277: +  ksp   - iterative context
    278: .  n     - iteration number
    279: .  rnorm - norm (preconditioned) residual value (may be estimated).
    280: -  dummy - an ASCII viewer

    282:    Options Database Key:
    283: .  -ksp_monitor_max - Activates KSPMonitorTrueResidualMaxNorm()

    285:    Notes:
    286:    This could be implemented (better) with a flag in ksp.

    288:    Level: intermediate

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

    292: .seealso: KSPMonitorSet(), KSPMonitorDefault(), KSPMonitorLGResidualNormCreate(),KSPMonitorTrueResidualNorm()
    293: @*/
    294: PetscErrorCode  KSPMonitorTrueResidualMaxNorm(KSP ksp,PetscInt n,PetscReal rnorm,PetscViewerAndFormat *dummy)
    295: {
    297:   Vec            resid;
    298:   PetscReal      truenorm,bnorm;
    299:   PetscViewer    viewer = dummy->viewer;
    300:   char           normtype[256];

    304:   PetscViewerPushFormat(viewer,dummy->format);
    305:   PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);
    306:   if (n == 0 && ((PetscObject)ksp)->prefix) {
    307:     PetscViewerASCIIPrintf(viewer,"  Residual norms (max) for %s solve.\n",((PetscObject)ksp)->prefix);
    308:   }
    309:   KSPBuildResidual(ksp,NULL,NULL,&resid);
    310:   VecNorm(resid,NORM_INFINITY,&truenorm);
    311:   VecDestroy(&resid);
    312:   VecNorm(ksp->vec_rhs,NORM_INFINITY,&bnorm);
    313:   PetscStrncpy(normtype,KSPNormTypes[ksp->normtype],sizeof(normtype));
    314:   PetscStrtolower(normtype);
    315:   PetscViewerASCIIPrintf(viewer,"%3D KSP true resid max norm %14.12e ||r(i)||/||b|| %14.12e\n",n,(double)truenorm,(double)(truenorm/bnorm));
    316:   PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);
    317:   PetscViewerPopFormat(viewer);
    318:   return(0);
    319: }

    321: PetscErrorCode  KSPMonitorRange_Private(KSP ksp,PetscInt it,PetscReal *per)
    322: {
    324:   Vec            resid;
    325:   PetscReal      rmax,pwork;
    326:   PetscInt       i,n,N;
    327:   const PetscScalar *r;

    330:   KSPBuildResidual(ksp,NULL,NULL,&resid);
    331:   VecNorm(resid,NORM_INFINITY,&rmax);
    332:   VecGetLocalSize(resid,&n);
    333:   VecGetSize(resid,&N);
    334:   VecGetArrayRead(resid,&r);
    335:   pwork = 0.0;
    336:   for (i=0; i<n; i++) pwork += (PetscAbsScalar(r[i]) > .20*rmax);
    337:   VecRestoreArrayRead(resid,&r);
    338:   VecDestroy(&resid);
    339:   MPIU_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ksp));
    340:   *per = *per/N;
    341:   return(0);
    342: }

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

    347:    Collective on KSP

    349:    Input Parameters:
    350: +  ksp   - iterative context
    351: .  it    - iteration number
    352: .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
    353: -  dummy - an ASCII viewer

    355:    Options Database Key:
    356: .  -ksp_monitor_range - Activates KSPMonitorRange()

    358:    Level: intermediate

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

    362: .seealso: KSPMonitorSet(), KSPMonitorDefault(), KSPMonitorLGResidualNormCreate()
    363: @*/
    364: PetscErrorCode  KSPMonitorRange(KSP ksp,PetscInt it,PetscReal rnorm,PetscViewerAndFormat *dummy)
    365: {
    366:   PetscErrorCode   ierr;
    367:   PetscReal        perc,rel;
    368:   PetscViewer      viewer = dummy->viewer;
    369:   /* should be in a MonitorRangeContext */
    370:   static PetscReal prev;

    374:   PetscViewerPushFormat(viewer,dummy->format);
    375:   PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);
    376:   if (!it) prev = rnorm;
    377:   if (it == 0 && ((PetscObject)ksp)->prefix) {
    378:     PetscViewerASCIIPrintf(viewer,"  Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);
    379:   }
    380:   KSPMonitorRange_Private(ksp,it,&perc);

    382:   rel  = (prev - rnorm)/prev;
    383:   prev = rnorm;
    384:   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));
    385:   PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);
    386:   PetscViewerPopFormat(viewer);
    387:   return(0);
    388: }

    390: /*@C
    391:    KSPMonitorDynamicTolerance - Recompute the inner tolerance in every
    392:    outer iteration in an adaptive way.

    394:    Collective on KSP

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

    405:    Notes:
    406:    This may be useful for a flexibly preconditioner Krylov method to
    407:    control the accuracy of the inner solves needed to gaurantee the
    408:    convergence of the outer iterations.

    410:    Level: advanced

    412: .keywords: KSP, inner tolerance

    414: .seealso: KSPMonitorDynamicToleranceDestroy()
    415: @*/
    416: PetscErrorCode KSPMonitorDynamicTolerance(KSP ksp,PetscInt its,PetscReal fnorm,void *dummy)
    417: {
    419:   PC             pc;
    420:   PetscReal      outer_rtol, outer_abstol, outer_dtol, inner_rtol;
    421:   PetscInt       outer_maxits,nksp,first,i;
    422:   KSPDynTolCtx   *scale   = (KSPDynTolCtx*)dummy;
    423:   KSP            *subksp = NULL;
    424:   PetscBool      isksp;

    427:   KSPGetPC(ksp, &pc);

    429:   /* compute inner_rtol */
    430:   if (scale->bnrm < 0.0) {
    431:     Vec b;
    432:     KSPGetRhs(ksp, &b);
    433:     VecNorm(b, NORM_2, &(scale->bnrm));
    434:   }
    435:   KSPGetTolerances(ksp, &outer_rtol, &outer_abstol, &outer_dtol, &outer_maxits);
    436:   inner_rtol = PetscMin(scale->coef * scale->bnrm * outer_rtol / fnorm, 0.999);
    437:   /*PetscPrintf(PETSC_COMM_WORLD, "        Inner rtol = %g\n", (double)inner_rtol);*/

    439:   /* if pc is ksp */
    440:   PetscObjectTypeCompare((PetscObject)pc,PCKSP,&isksp);
    441:   if (isksp) {
    442:     KSP kspinner;

    444:     PCKSPGetKSP(pc, &kspinner);
    445:     KSPSetTolerances(kspinner, inner_rtol, outer_abstol, outer_dtol, outer_maxits);
    446:     return(0);
    447:   }

    449:   /* if pc is bjacobi */
    450:   PCBJacobiGetSubKSP(pc, &nksp, &first, &subksp);
    451:   if (subksp) {
    452:     for (i=0; i<nksp; i++) {
    453:       KSPSetTolerances(subksp[i], inner_rtol, outer_abstol, outer_dtol, outer_maxits);
    454:     }
    455:     return(0);
    456:   }

    458:   /* todo: dynamic tolerance may apply to other types of pc too */
    459:   return(0);
    460: }

    462: /*
    463:   Destroy the dummy context used in KSPMonitorDynamicTolerance()
    464: */
    465: PetscErrorCode KSPMonitorDynamicToleranceDestroy(void **dummy)
    466: {

    470:   PetscFree(*dummy);
    471:   return(0);
    472: }

    474: /*
    475:   Default (short) KSP Monitor, same as KSPMonitorDefault() except
    476:   it prints fewer digits of the residual as the residual gets smaller.
    477:   This is because the later digits are meaningless and are often
    478:   different on different machines; by using this routine different
    479:   machines will usually generate the same output.

    481:   Deprecated: Intentionally has no manual page
    482: */
    483: PetscErrorCode  KSPMonitorDefaultShort(KSP ksp,PetscInt its,PetscReal fnorm,PetscViewerAndFormat *dummy)
    484: {
    486:   PetscViewer    viewer = dummy->viewer;

    490:   PetscViewerPushFormat(viewer,dummy->format);
    491:   PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);
    492:   if (its == 0 && ((PetscObject)ksp)->prefix) {
    493:     PetscViewerASCIIPrintf(viewer,"  Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);
    494:   }

    496:   if (fnorm > 1.e-9) {
    497:     PetscViewerASCIIPrintf(viewer,"%3D KSP Residual norm %g \n",its,(double)fnorm);
    498:   } else if (fnorm > 1.e-11) {
    499:     PetscViewerASCIIPrintf(viewer,"%3D KSP Residual norm %5.3e \n",its,(double)fnorm);
    500:   } else {
    501:     PetscViewerASCIIPrintf(viewer,"%3D KSP Residual norm < 1.e-11\n",its);
    502:   }
    503:   PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);
    504:   PetscViewerPopFormat(viewer);
    505:   return(0);
    506: }

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

    512:    Collective on KSP

    514:    Input Parameters:
    515: +  ksp   - iterative context
    516: .  n     - iteration number
    517: .  rnorm - 2-norm residual value (may be estimated)
    518: -  dummy - unused convergence context

    520:    Returns:
    521: .  reason - KSP_CONVERGED_ITERATING, KSP_CONVERGED_ITS

    523:    Notes:
    524:    This should be used as the convergence test with the option
    525:    KSPSetNormType(ksp,KSP_NORM_NONE), since norms of the residual are
    526:    not computed. Convergence is then declared after the maximum number
    527:    of iterations have been reached. Useful when one is using CG or
    528:    BiCGStab as a smoother.

    530:    Level: advanced

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

    534: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSetNormType()
    535: @*/
    536: PetscErrorCode  KSPConvergedSkip(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *dummy)
    537: {
    541:   *reason = KSP_CONVERGED_ITERATING;
    542:   if (n >= ksp->max_it) *reason = KSP_CONVERGED_ITS;
    543:   return(0);
    544: }

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

    550:    Collective on KSP

    552:    Output Parameter:
    553: .  ctx - convergence context

    555:    Level: intermediate

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

    559: .seealso: KSPConvergedDefault(), KSPConvergedDefaultDestroy(), KSPSetConvergenceTest(), KSPSetTolerances(),
    560:           KSPConvergedSkip(), KSPConvergedReason, KSPGetConvergedReason(), KSPConvergedDefaultSetUIRNorm(), KSPConvergedDefaultSetUMIRNorm()
    561: @*/
    562: PetscErrorCode  KSPConvergedDefaultCreate(void **ctx)
    563: {
    564:   PetscErrorCode         ierr;
    565:   KSPConvergedDefaultCtx *cctx;

    568:   PetscNew(&cctx);
    569:   *ctx = cctx;
    570:   return(0);
    571: }

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

    578:    Collective on KSP

    580:    Input Parameters:
    581: .  ksp   - iterative context

    583:    Options Database:
    584: .   -ksp_converged_use_initial_residual_norm

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

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

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

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

    597:    Level: intermediate

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

    601: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPConvergedSkip(), KSPConvergedReason, KSPGetConvergedReason(), KSPConvergedDefaultSetUMIRNorm()
    602: @*/
    603: PetscErrorCode  KSPConvergedDefaultSetUIRNorm(KSP ksp)
    604: {
    605:   KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx*) ksp->cnvP;

    609:   if (ksp->converged != KSPConvergedDefault) return(0);
    610:   if (ctx->mininitialrtol) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_WRONGSTATE,"Cannot use KSPConvergedDefaultSetUIRNorm() and KSPConvergedDefaultSetUMIRNorm() together");
    611:   ctx->initialrtol = PETSC_TRUE;
    612:   return(0);
    613: }

    615: /*@
    616:    KSPConvergedDefaultSetUMIRNorm - 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(), KSPConvergedSkip(), KSPConvergedReason, KSPGetConvergedReason(), KSPConvergedDefaultSetUIRNorm()
    638: @*/
    639: PetscErrorCode  KSPConvergedDefaultSetUMIRNorm(KSP ksp)
    640: {
    641:   KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx*) ksp->cnvP;

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

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

    654:    Collective on KSP

    656:    Input Parameters:
    657: +  ksp   - iterative context
    658: .  n     - iteration number
    659: .  rnorm - residual norm (may be estimated, depending on the method may be the preconditioned residual norm)
    660: -  ctx - convergence context which must be created by KSPConvergedDefaultCreate()

    662:    Output Parameter:
    663: +   positive - if the iteration has converged;
    664: .   negative - if residual norm exceeds divergence threshold;
    665: -   0 - otherwise.

    667:    Notes:
    668:    KSPConvergedDefault() reaches convergence when   rnorm < MAX (rtol * rnorm_0, abstol);
    669:    Divergence is detected if  rnorm > dtol * rnorm_0,

    671:    where:
    672: +     rtol = relative tolerance,
    673: .     abstol = absolute tolerance.
    674: .     dtol = divergence tolerance,
    675: -     rnorm_0 is the two norm of the right hand side (or the preconditioned norm, depending on what was set with
    676:           KSPSetNormType(). When initial guess is non-zero you
    677:           can call KSPConvergedDefaultSetUIRNorm() to use the norm of (b - A*(initial guess))
    678:           as the starting point for relative norm convergence testing, that is as rnorm_0

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

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

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

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

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

    690:    Level: intermediate

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

    694: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPConvergedSkip(), KSPConvergedReason, KSPGetConvergedReason(),
    695:           KSPConvergedDefaultSetUIRNorm(), KSPConvergedDefaultSetUMIRNorm(), KSPConvergedDefaultCreate(), KSPConvergedDefaultDestroy()
    696: @*/
    697: PetscErrorCode  KSPConvergedDefault(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *ctx)
    698: {
    699:   PetscErrorCode         ierr;
    700:   KSPConvergedDefaultCtx *cctx = (KSPConvergedDefaultCtx*) ctx;
    701:   KSPNormType            normtype;

    706:   *reason = KSP_CONVERGED_ITERATING;

    708:   KSPGetNormType(ksp,&normtype);
    709:   if (normtype == KSP_NORM_NONE) return(0);

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

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

    750:   if (PetscIsInfOrNanReal(rnorm)) {
    751:     PCFailedReason pcreason;
    752:     PetscInt       sendbuf,pcreason_max;
    753:     PCGetSetUpFailedReason(ksp->pc,&pcreason);
    754:     sendbuf = (PetscInt)pcreason;
    755:     MPI_Allreduce(&sendbuf,&pcreason_max,1,MPIU_INT,MPIU_MAX,PetscObjectComm((PetscObject)ksp));
    756:     if (pcreason_max) {
    757:       *reason = KSP_DIVERGED_PCSETUP_FAILED;
    758:       VecSetInf(ksp->vec_sol);
    759:       PetscInfo(ksp,"Linear solver pcsetup fails, declaring divergence \n");
    760:     } else {
    761:       *reason = KSP_DIVERGED_NANORINF;
    762:       PetscInfo(ksp,"Linear solver has created a not a number (NaN) as the residual norm, declaring divergence \n");
    763:     }
    764:   } else if (rnorm <= ksp->ttol) {
    765:     if (rnorm < ksp->abstol) {
    766:       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);
    767:       *reason = KSP_CONVERGED_ATOL;
    768:     } else {
    769:       if (cctx->initialrtol) {
    770:         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);
    771:       } else {
    772:         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);
    773:       }
    774:       *reason = KSP_CONVERGED_RTOL;
    775:     }
    776:   } else if (rnorm >= ksp->divtol*ksp->rnorm0) {
    777:     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);
    778:     *reason = KSP_DIVERGED_DTOL;
    779:   }
    780:   return(0);
    781: }

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

    786:    Collective on KSP

    788:    Input Parameters:
    789: .  ctx - convergence context

    791:    Level: intermediate

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

    795: .seealso: KSPConvergedDefault(), KSPConvergedDefaultCreate(), KSPSetConvergenceTest(), KSPSetTolerances(), KSPConvergedSkip(),
    796:           KSPConvergedReason, KSPGetConvergedReason(), KSPConvergedDefaultSetUIRNorm(), KSPConvergedDefaultSetUMIRNorm()
    797: @*/
    798: PetscErrorCode  KSPConvergedDefaultDestroy(void *ctx)
    799: {
    800:   PetscErrorCode         ierr;
    801:   KSPConvergedDefaultCtx *cctx = (KSPConvergedDefaultCtx*) ctx;

    804:   VecDestroy(&cctx->work);
    805:   PetscFree(ctx);
    806:   return(0);
    807: }

    809: /*
    810:    KSPBuildSolutionDefault - Default code to create/move the solution.

    812:    Input Parameters:
    813: +  ksp - iterative context
    814: -  v   - pointer to the user's vector

    816:    Output Parameter:
    817: .  V - pointer to a vector containing the solution

    819:    Level: advanced

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

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

    825: .seealso: KSPGetSolution(), KSPBuildResidualDefault()
    826: */
    827: PetscErrorCode KSPBuildSolutionDefault(KSP ksp,Vec v,Vec *V)
    828: {

    832:   if (ksp->pc_side == PC_RIGHT) {
    833:     if (ksp->pc) {
    834:       if (v) {
    835:         KSP_PCApply(ksp,ksp->vec_sol,v); *V = v;
    836:       } else SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Not working with right preconditioner");
    837:     } else {
    838:       if (v) {
    839:         VecCopy(ksp->vec_sol,v); *V = v;
    840:       } else *V = ksp->vec_sol;
    841:     }
    842:   } else if (ksp->pc_side == PC_SYMMETRIC) {
    843:     if (ksp->pc) {
    844:       if (ksp->transpose_solve) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Not working with symmetric preconditioner and transpose solve");
    845:       if (v) {
    846:         PCApplySymmetricRight(ksp->pc,ksp->vec_sol,v);
    847:         *V = v;
    848:       } else SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Not working with symmetric preconditioner");
    849:     } else {
    850:       if (v) {
    851:         VecCopy(ksp->vec_sol,v); *V = v;
    852:       } else *V = ksp->vec_sol;
    853:     }
    854:   } else {
    855:     if (v) {
    856:       VecCopy(ksp->vec_sol,v); *V = v;
    857:     } else *V = ksp->vec_sol;
    858:   }
    859:   return(0);
    860: }

    862: /*
    863:    KSPBuildResidualDefault - Default code to compute the residual.

    865:    Input Parameters:
    866: .  ksp - iterative context
    867: .  t   - pointer to temporary vector
    868: .  v   - pointer to user vector

    870:    Output Parameter:
    871: .  V - pointer to a vector containing the residual

    873:    Level: advanced

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

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

    879: .seealso: KSPBuildSolutionDefault()
    880: */
    881: PetscErrorCode KSPBuildResidualDefault(KSP ksp,Vec t,Vec v,Vec *V)
    882: {
    884:   Mat            Amat,Pmat;

    887:   if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
    888:   PCGetOperators(ksp->pc,&Amat,&Pmat);
    889:   KSPBuildSolution(ksp,t,NULL);
    890:   KSP_MatMult(ksp,Amat,t,v);
    891:   VecAYPX(v,-1.0,ksp->vec_rhs);
    892:   *V   = v;
    893:   return(0);
    894: }

    896: /*@C
    897:   KSPCreateVecs - Gets a number of work vectors.

    899:   Input Parameters:
    900: + ksp  - iterative context
    901: . rightn  - number of right work vectors
    902: - leftn   - number of left work vectors to allocate

    904:   Output Parameter:
    905: +  right - the array of vectors created
    906: -  left - the array of left vectors

    908:    Note: The right vector has as many elements as the matrix has columns. The left
    909:      vector has as many elements as the matrix has rows.

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

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

    916:    Level: advanced

    918: .seealso:   MatCreateVecs(), VecDestroyVecs()

    920: @*/
    921: PetscErrorCode KSPCreateVecs(KSP ksp,PetscInt rightn, Vec **right,PetscInt leftn,Vec **left)
    922: {
    924:   Vec            vecr = NULL,vecl = NULL;
    925:   PetscBool      matset,pmatset;
    926:   Mat            mat = NULL;

    929:   if (rightn) {
    930:     if (!right) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_INCOMP,"You asked for right vectors but did not pass a pointer to hold them");
    931:     if (ksp->vec_sol) vecr = ksp->vec_sol;
    932:     else {
    933:       if (ksp->pc) {
    934:         PCGetOperatorsSet(ksp->pc,&matset,&pmatset);
    935:         /* check for mat before pmat because for KSPLSQR pmat may be a different size than mat since pmat maybe mat'*mat */
    936:         if (matset) {
    937:           PCGetOperators(ksp->pc,&mat,NULL);
    938:           MatCreateVecs(mat,&vecr,NULL);
    939:         } else if (pmatset) {
    940:           PCGetOperators(ksp->pc,NULL,&mat);
    941:           MatCreateVecs(mat,&vecr,NULL);
    942:         }
    943:       }
    944:       if (!vecr) {
    945:         if (ksp->dm) {
    946:           DMGetGlobalVector(ksp->dm,&vecr);
    947:         } else SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_WRONGSTATE,"You requested a vector from a KSP that cannot provide one");
    948:       }
    949:     }
    950:     VecDuplicateVecs(vecr,rightn,right);
    951:     if (!ksp->vec_sol) {
    952:       if (mat) {
    953:         VecDestroy(&vecr);
    954:       } else if (ksp->dm) {
    955:         DMRestoreGlobalVector(ksp->dm,&vecr);
    956:       }
    957:     }
    958:   }
    959:   if (leftn) {
    960:     if (!left) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_INCOMP,"You asked for left vectors but did not pass a pointer to hold them");
    961:     if (ksp->vec_rhs) vecl = ksp->vec_rhs;
    962:     else {
    963:       if (ksp->pc) {
    964:         PCGetOperatorsSet(ksp->pc,&matset,&pmatset);
    965:         /* check for mat before pmat because for KSPLSQR pmat may be a different size than mat since pmat maybe mat'*mat */
    966:         if (matset) {
    967:           PCGetOperators(ksp->pc,&mat,NULL);
    968:           MatCreateVecs(mat,NULL,&vecl);
    969:         } else if (pmatset) {
    970:           PCGetOperators(ksp->pc,NULL,&mat);
    971:           MatCreateVecs(mat,NULL,&vecl);
    972:         }
    973:       }
    974:       if (!vecl) {
    975:         if (ksp->dm) {
    976:           DMGetGlobalVector(ksp->dm,&vecl);
    977:         } else SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_WRONGSTATE,"You requested a vector from a KSP that cannot provide one");
    978:       }
    979:     }
    980:     VecDuplicateVecs(vecl,leftn,left);
    981:     if (!ksp->vec_rhs) {
    982:       if (mat) {
    983:         VecDestroy(&vecl);
    984:       } else if (ksp->dm) {
    985:         DMRestoreGlobalVector(ksp->dm,&vecl);
    986:       }
    987:     }
    988:   }
    989:   return(0);
    990: }

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

    995:   Collective on KSP

    997:   Input Parameters:
    998: + ksp  - iterative context
    999: - nw   - number of work vectors to allocate

    1001:   Level: developer

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

    1005: @*/
    1006: PetscErrorCode KSPSetWorkVecs(KSP ksp,PetscInt nw)
    1007: {

    1011:   VecDestroyVecs(ksp->nwork,&ksp->work);
    1012:   ksp->nwork = nw;
    1013:   KSPCreateVecs(ksp,nw,&ksp->work,0,NULL);
    1014:   PetscLogObjectParents(ksp,nw,ksp->work);
    1015:   return(0);
    1016: }

    1018: /*
    1019:   KSPDestroyDefault - Destroys a iterative context variable for methods with
    1020:   no separate context.  Preferred calling sequence KSPDestroy().

    1022:   Input Parameter:
    1023: . ksp - the iterative context

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

    1027: */
    1028: PetscErrorCode KSPDestroyDefault(KSP ksp)
    1029: {

    1034:   PetscFree(ksp->data);
    1035:   return(0);
    1036: }

    1038: /*@
    1039:    KSPGetConvergedReason - Gets the reason the KSP iteration was stopped.

    1041:    Not Collective

    1043:    Input Parameter:
    1044: .  ksp - the KSP context

    1046:    Output Parameter:
    1047: .  reason - negative value indicates diverged, positive value converged, see KSPConvergedReason

    1049:    Possible values for reason: See also manual page for each reason
    1050: $  KSP_CONVERGED_RTOL (residual 2-norm decreased by a factor of rtol, from 2-norm of right hand side)
    1051: $  KSP_CONVERGED_ATOL (residual 2-norm less than abstol)
    1052: $  KSP_CONVERGED_ITS (used by the preonly preconditioner that always uses ONE iteration, or when the KSPConvergedSkip() convergence test routine is set.
    1053: $  KSP_CONVERGED_CG_NEG_CURVE (see note below)
    1054: $  KSP_CONVERGED_CG_CONSTRAINED (see note below)
    1055: $  KSP_CONVERGED_STEP_LENGTH (see note below)
    1056: $  KSP_CONVERGED_ITERATING (returned if the solver is not yet finished)
    1057: $  KSP_DIVERGED_ITS  (required more than its to reach convergence)
    1058: $  KSP_DIVERGED_DTOL (residual norm increased by a factor of divtol)
    1059: $  KSP_DIVERGED_NANORINF (residual norm became Not-a-number or Inf likely due to 0/0)
    1060: $  KSP_DIVERGED_BREAKDOWN (generic breakdown in method)
    1061: $  KSP_DIVERGED_BREAKDOWN_BICG (Initial residual is orthogonal to preconditioned initial residual. Try a different preconditioner, or a different initial Level.)

    1063:    Options Database:
    1064: .   -ksp_converged_reason - prints the reason to standard out

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

    1069:    The values  KSP_CONVERGED_CG_NEG_CURVE, KSP_CONVERGED_CG_CONSTRAINED, and KSP_CONVERGED_STEP_LENGTH are returned only by the special KSPCGNASH, KSPCGSTCG, and KSPCGGLTR
    1070:    solvers which are used by the SNESNEWTONTR (trust region) solver.

    1072:    Level: intermediate

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

    1076: .seealso: KSPSetConvergenceTest(), KSPConvergedDefault(), KSPSetTolerances(), KSPConvergedReason
    1077: @*/
    1078: PetscErrorCode  KSPGetConvergedReason(KSP ksp,KSPConvergedReason *reason)
    1079: {
    1083:   *reason = ksp->reason;
    1084:   return(0);
    1085: }

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

    1091:    Logically Collective on KSP

    1093:    Input Parameters:
    1094: +  ksp - the preconditioner context
    1095: -  dm - the dm, cannot be NULL

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

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

    1106:    Level: intermediate

    1108: .seealso: KSPGetDM(), KSPSetDMActive(), KSPSetComputeOperators(), KSPSetComputeRHS(), KSPSetComputeInitialGuess(), DMKSPSetComputeOperators(), DMKSPSetComputeRHS(), DMKSPSetComputeInitialGuess()
    1109: @*/
    1110: PetscErrorCode  KSPSetDM(KSP ksp,DM dm)
    1111: {
    1113:   PC             pc;

    1118:   PetscObjectReference((PetscObject)dm);
    1119:   if (ksp->dm) {                /* Move the DMSNES context over to the new DM unless the new DM already has one */
    1120:     if (ksp->dm->dmksp && !dm->dmksp) {
    1121:       DMKSP kdm;
    1122:       DMCopyDMKSP(ksp->dm,dm);
    1123:       DMGetDMKSP(ksp->dm,&kdm);
    1124:       if (kdm->originaldm == ksp->dm) kdm->originaldm = dm; /* Grant write privileges to the replacement DM */
    1125:     }
    1126:     DMDestroy(&ksp->dm);
    1127:   }
    1128:   ksp->dm       = dm;
    1129:   ksp->dmAuto   = PETSC_FALSE;
    1130:   KSPGetPC(ksp,&pc);
    1131:   PCSetDM(pc,dm);
    1132:   ksp->dmActive = PETSC_TRUE;
    1133:   return(0);
    1134: }

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

    1139:    Logically Collective on KSP

    1141:    Input Parameters:
    1142: +  ksp - the preconditioner context
    1143: -  flg - use the DM

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

    1148:    Level: intermediate

    1150: .seealso: KSPGetDM(), KSPSetDM(), SNESSetDM(), KSPSetComputeOperators(), KSPSetComputeRHS(), KSPSetComputeInitialGuess()
    1151: @*/
    1152: PetscErrorCode  KSPSetDMActive(KSP ksp,PetscBool flg)
    1153: {
    1157:   ksp->dmActive = flg;
    1158:   return(0);
    1159: }

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

    1164:    Not Collective

    1166:    Input Parameter:
    1167: . ksp - the preconditioner context

    1169:    Output Parameter:
    1170: .  dm - the dm

    1172:    Level: intermediate

    1175: .seealso: KSPSetDM(), KSPSetDMActive()
    1176: @*/
    1177: PetscErrorCode  KSPGetDM(KSP ksp,DM *dm)
    1178: {

    1183:   if (!ksp->dm) {
    1184:     DMShellCreate(PetscObjectComm((PetscObject)ksp),&ksp->dm);
    1185:     ksp->dmAuto = PETSC_TRUE;
    1186:   }
    1187:   *dm = ksp->dm;
    1188:   return(0);
    1189: }

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

    1194:    Logically Collective on KSP

    1196:    Input Parameters:
    1197: +  ksp - the KSP context
    1198: -  usrP - optional user context

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

    1204:    Level: intermediate

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

    1208: .seealso: KSPGetApplicationContext()
    1209: @*/
    1210: PetscErrorCode  KSPSetApplicationContext(KSP ksp,void *usrP)
    1211: {
    1213:   PC             pc;

    1217:   ksp->user = usrP;
    1218:   KSPGetPC(ksp,&pc);
    1219:   PCSetApplicationContext(pc,usrP);
    1220:   return(0);
    1221: }

    1223: /*@
    1224:    KSPGetApplicationContext - Gets the user-defined context for the linear solver.

    1226:    Not Collective

    1228:    Input Parameter:
    1229: .  ksp - KSP context

    1231:    Output Parameter:
    1232: .  usrP - user context

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

    1238:    Level: intermediate

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

    1242: .seealso: KSPSetApplicationContext()
    1243: @*/
    1244: PetscErrorCode  KSPGetApplicationContext(KSP ksp,void *usrP)
    1245: {
    1248:   *(void**)usrP = ksp->user;
    1249:   return(0);
    1250: }