Actual source code: iterativ.c

  1: #define PETSCKSP_DLL

  3: /*
  4:    This file contains some simple default routines.  
  5:    These routines should be SHORT, since they will be included in every
  6:    executable image that uses the iterative routines (note that, through
  7:    the registry system, we provide a way to load only the truely necessary
  8:    files) 
  9:  */
 10:  #include private/kspimpl.h

 14: /*
 15:   KSPDefaultFreeWork - Free work vectors

 17:   Input Parameters:
 18: . ksp  - iterative context
 19:  */
 20: PetscErrorCode KSPDefaultFreeWork(KSP ksp)
 21: {
 25:   if (ksp->work)  {
 26:     VecDestroyVecs(ksp->work,ksp->nwork);
 27:     ksp->work = PETSC_NULL;
 28:   }
 29:   return(0);
 30: }

 34: /*@
 35:    KSPGetResidualNorm - Gets the last (approximate preconditioned)
 36:    residual norm that has been computed.
 37:  
 38:    Not Collective

 40:    Input Parameters:
 41: .  ksp - the iterative context

 43:    Output Parameters:
 44: .  rnorm - residual norm

 46:    Level: intermediate

 48: .keywords: KSP, get, residual norm

 50: .seealso: KSPBuildResidual()
 51: @*/
 52: PetscErrorCode  KSPGetResidualNorm(KSP ksp,PetscReal *rnorm)
 53: {
 57:   *rnorm = ksp->rnorm;
 58:   return(0);
 59: }

 63: /*@
 64:    KSPGetIterationNumber - Gets the current iteration number; if the 
 65:          KSPSolve() is complete, returns the number of iterations
 66:          used.
 67:  
 68:    Not Collective

 70:    Input Parameters:
 71: .  ksp - the iterative context

 73:    Output Parameters:
 74: .  its - number of iterations

 76:    Level: intermediate

 78:    Notes:
 79:       During the ith iteration this returns i-1
 80: .keywords: KSP, get, residual norm

 82: .seealso: KSPBuildResidual(), KSPGetResidualNorm()
 83: @*/
 84: PetscErrorCode  KSPGetIterationNumber(KSP ksp,PetscInt *its)
 85: {
 89:   *its = ksp->its;
 90:   return(0);
 91: }

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

102:     Input Parameters:
103: +   ksp - the iterative context
104: .   n  - the iteration
105: -   rnorm - the two norm of the residual

107:     Options Database Key:
108: .   -ksp_monitor_singular_value - Activates KSPMonitorSingularValue()

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

115:     Level: intermediate

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

119: .seealso: KSPComputeExtremeSingularValues()
120: @*/
121: PetscErrorCode  KSPMonitorSingularValue(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy)
122: {
123:   PetscReal               emin,emax,c;
124:   PetscErrorCode          ierr;
125:   PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy;

129:   if (!dummy) {PetscViewerASCIIMonitorCreate(((PetscObject)ksp)->comm,"stdout",0,&viewer);}
130:   if (!ksp->calc_sings) {
131:     PetscViewerASCIIMonitorPrintf(viewer,"%3D KSP Residual norm %14.12e \n",n,rnorm);
132:   } else {
133:     KSPComputeExtremeSingularValues(ksp,&emax,&emin);
134:     c = emax/emin;
135:     PetscViewerASCIIMonitorPrintf(viewer,"%3D KSP Residual norm %14.12e %% max %G min %G max/min %G\n",n,rnorm,emax,emin,c);
136:   }
137:   if (!dummy) {PetscViewerASCIIMonitorDestroy(viewer);}
138:   return(0);
139: }

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

147:    Collective on KSP

149:    Input Parameters:
150: +  ksp - the KSP context
151: .  its - iteration number
152: .  fgnorm - 2-norm of residual (or gradient)
153: -  dummy - either a viewer or PETSC_NULL

155:    Level: intermediate

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

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

163: .seealso: KSPMonitorSet(), KSPMonitorDefault(), VecView()
164: @*/
165: PetscErrorCode  KSPMonitorSolution(KSP ksp,PetscInt its,PetscReal fgnorm,void *dummy)
166: {
168:   Vec            x;
169:   PetscViewer    viewer = (PetscViewer) dummy;

172:   KSPBuildSolution(ksp,PETSC_NULL,&x);
173:   if (!viewer) {
174:     MPI_Comm comm;
175:     PetscObjectGetComm((PetscObject)ksp,&comm);
176:     viewer = PETSC_VIEWER_DRAW_(comm);
177:   }
178:   VecView(x,viewer);

180:   return(0);
181: }

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

189:    Collective on KSP

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

197:    Level: intermediate

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

201: .seealso: KSPMonitorSet(), KSPMonitorTrueResidualNorm(), KSPMonitorLGCreate()
202: @*/
203: PetscErrorCode  KSPMonitorDefault(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy)
204: {
205:   PetscErrorCode          ierr;
206:   PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy;

209:   if (!dummy) {PetscViewerASCIIMonitorCreate(((PetscObject)ksp)->comm,"stdout",0,&viewer);}
210:   if (n == 0 && ((PetscObject)ksp)->prefix) {
211:     PetscViewerASCIIMonitorPrintf(viewer,"  Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);
212:   }
213:   PetscViewerASCIIMonitorPrintf(viewer,"%3D KSP Residual norm %14.12e \n",n,rnorm);
214:   if (!dummy) {PetscViewerASCIIMonitorDestroy(viewer);}
215:   return(0);
216: }

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 - unused monitor context 

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(), KSPMonitorLGCreate()
243: @*/
244: PetscErrorCode  KSPMonitorTrueResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy)
245: {
246:   PetscErrorCode          ierr;
247:   Vec                     resid,work;
248:   PetscReal               scnorm,bnorm;
249:   PC                      pc;
250:   Mat                     A,B;
251:   PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy;
252: 
254:   if (!dummy) {PetscViewerASCIIMonitorCreate(((PetscObject)ksp)->comm,"stdout",0,&viewer);}
255:   VecDuplicate(ksp->vec_rhs,&work);
256:   KSPBuildResidual(ksp,0,work,&resid);

258:   /*
259:      Unscale the residual but only if both matrices are the same matrix, since only then would 
260:     they be scaled.
261:   */
262:   VecCopy(resid,work);
263:   KSPGetPC(ksp,&pc);
264:   PCGetOperators(pc,&A,&B,PETSC_NULL);
265:   if (A == B) {
266:     MatUnScaleSystem(A,work,PETSC_NULL);
267:   }
268:   VecNorm(work,NORM_2,&scnorm);
269:   VecDestroy(work);
270:   VecNorm(ksp->vec_rhs,NORM_2,&bnorm);
271:   PetscViewerASCIIMonitorPrintf(viewer,"%3D KSP preconditioned resid norm %14.12e true resid norm %14.12e ||Ae||/||Ax|| %14.12e\n",n,rnorm,scnorm,scnorm/bnorm);
272:   if (!dummy) {PetscViewerASCIIMonitorDestroy(viewer);}
273:   return(0);
274: }

278: PetscErrorCode  KSPMonitorRange_Private(KSP ksp,PetscInt it,PetscReal *per)
279: {
280:   PetscErrorCode          ierr;
281:   Vec                     resid,work;
282:   PetscReal               rmax,pwork;
283:   PC                      pc;
284:   Mat                     A,B;
285:   PetscInt                i,n,N;
286:   PetscScalar             *r;

289:   VecDuplicate(ksp->vec_rhs,&work);
290:   KSPBuildResidual(ksp,0,work,&resid);

292:   /*
293:      Unscale the residual if the matrix is, but only if both matrices are the same matrix, since only then would 
294:     they be scaled.
295:   */
296:   VecCopy(resid,work);
297:   KSPGetPC(ksp,&pc);
298:   PCGetOperators(pc,&A,&B,PETSC_NULL);
299:   if (A == B) {
300:     MatUnScaleSystem(A,work,PETSC_NULL);
301:   }
302:   VecNorm(work,NORM_INFINITY,&rmax);
303:   VecGetLocalSize(work,&n);
304:   VecGetSize(work,&N);
305:   VecGetArray(work,&r);
306:   pwork = 0.0;
307:   for (i=0; i<n; i++) {
308:     pwork += (PetscAbsScalar(r[i]) > .20*rmax);
309:   }
310:   MPI_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,((PetscObject)ksp)->comm);
311:   VecRestoreArray(work,&r);
312:   VecDestroy(work);
313:   *per  = *per/N;
314:   return(0);
315: }

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

322:    Collective on KSP

324:    Input Parameters:
325: +  ksp   - iterative context
326: .  it    - iteration number
327: .  rnorm - 2-norm (preconditioned) residual value (may be estimated).  
328: -  dummy - unused monitor context 

330:    Options Database Key:
331: .  -ksp_monitor_range - Activates KSPMonitorRange()

333:    Level: intermediate

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

337: .seealso: KSPMonitorSet(), KSPMonitorDefault(), KSPMonitorLGCreate()
338: @*/
339: PetscErrorCode  KSPMonitorRange(KSP ksp,PetscInt it,PetscReal rnorm,void *dummy)
340: {
341:   PetscErrorCode          ierr;
342:   PetscReal               perc,rel;
343:   PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy;
344:   /* should be in a MonitorRangeContext */
345:   static PetscReal        prev;

348:   if (!it) prev = rnorm;
349:   if (!dummy) {PetscViewerASCIIMonitorCreate(((PetscObject)ksp)->comm,"stdout",0,&viewer);}
350:   KSPMonitorRange_Private(ksp,it,&perc);

352:   rel  = (prev - rnorm)/prev;
353:   prev = rnorm;
354:   PetscViewerASCIIMonitorPrintf(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,rnorm,100.0*perc,rel,rel/perc);
355:   if (!dummy) {PetscViewerASCIIMonitorDestroy(viewer);}
356:   return(0);
357: }

361: /*
362:   Default (short) KSP Monitor, same as KSPMonitorDefault() except
363:   it prints fewer digits of the residual as the residual gets smaller.
364:   This is because the later digits are meaningless and are often 
365:   different on different machines; by using this routine different 
366:   machines will usually generate the same output.
367: */
368: PetscErrorCode  KSPMonitorDefaultShort(KSP ksp,PetscInt its,PetscReal fnorm,void *dummy)
369: {
370:   PetscErrorCode          ierr;
371:   PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy;

374:   if (!dummy) {PetscViewerASCIIMonitorCreate(((PetscObject)ksp)->comm,"stdout",0,&viewer);}

376:   if (fnorm > 1.e-9) {
377:     PetscViewerASCIIMonitorPrintf(viewer,"%3D KSP Residual norm %G \n",its,fnorm);
378:   } else if (fnorm > 1.e-11){
379:     PetscViewerASCIIMonitorPrintf(viewer,"%3D KSP Residual norm %5.3e \n",its,fnorm);
380:   } else {
381:     PetscViewerASCIIMonitorPrintf(viewer,"%3D KSP Residual norm < 1.e-11\n",its);
382:   }
383:   if (!dummy) {PetscViewerASCIIMonitorDestroy(viewer);}
384:   return(0);
385: }

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

393:    Collective on KSP

395:    Input Parameters:
396: +  ksp   - iterative context
397: .  n     - iteration number
398: .  rnorm - 2-norm residual value (may be estimated)
399: -  dummy - unused convergence context 

401:    Returns:
402: .  reason - KSP_CONVERGED_ITERATING, KSP_CONVERGED_ITS

404:    Notes: 
405:    This should be used as the convergence test with the option
406:    KSPSetNormType(ksp,KSP_NORM_NO), since norms of the residual are
407:    not computed. Convergence is then declared after the maximum number
408:    of iterations have been reached. Useful when one is using CG or
409:    BiCGStab as a smoother.
410:                     
411:    Level: advanced

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

415: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSetNormType()
416: @*/
417: PetscErrorCode  KSPSkipConverged(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *dummy)
418: {
422:   *reason = KSP_CONVERGED_ITERATING;
423:   if (n >= ksp->max_it) *reason = KSP_CONVERGED_ITS;
424:   return(0);
425: }

427: typedef struct {
428:   PetscTruth initialrtol;    /* default relative residual decrease is computing from initial residual, not rhs */
429:   PetscTruth mininitialrtol; /* default relative residual decrease is computing from min of initial residual and rhs */
430:   Vec        work;
431: } KSPDefaultConvergedCtx;

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

438:    Collective on KSP

440:    Output Parameter:
441: .  ctx - convergence context 

443:    Level: intermediate

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

447: .seealso: KSPDefaultConverged(), KSPDefaultConvergedDestroy(), KSPSetConvergenceTest(), KSPSetTolerances(),
448:           KSPSkipConverged(), KSPConvergedReason, KSPGetConvergedReason(), KSPDefaultConvergedSetUIRNorm(), KSPDefaultConvergedSetUMIRNorm()
449: @*/
450: PetscErrorCode  KSPDefaultConvergedCreate(void **ctx)
451: {
452:   PetscErrorCode         ierr;
453:   KSPDefaultConvergedCtx *cctx;

456:   PetscNew(KSPDefaultConvergedCtx,&cctx);
457:   *ctx = cctx;
458:   return(0);
459: }

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

468:    Collective on KSP

470:    Input Parameters:
471: .  ksp   - iterative context

473:    Options Database:
474: .   -ksp_converged_use_initial_residual_norm

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

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

481:    If the convergence test is not KSPDefaultConverged() then this is ignored.
482:    Level: intermediate

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

486: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSkipConverged(), KSPConvergedReason, KSPGetConvergedReason(), KSPDefaultConvergedSetUMIRNorm()
487: @*/
488: PetscErrorCode  KSPDefaultConvergedSetUIRNorm(KSP ksp)
489: {
490:   KSPDefaultConvergedCtx *ctx = (KSPDefaultConvergedCtx*) ksp->cnvP;

494:   if (ksp->converged != KSPDefaultConverged) return(0);
495:   if (ctx->mininitialrtol) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot use KSPDefaultConvergedSetUIRNorm() and KSPDefaultConvergedSetUMIRNorm() together");
496:   ctx->initialrtol = PETSC_TRUE;
497:   return(0);
498: }

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

507:    Collective on KSP

509:    Input Parameters:
510: .  ksp   - iterative context

512:    Options Database:
513: .   -ksp_converged_use_min_initial_residual_norm

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

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

520:    Level: intermediate

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

524: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSkipConverged(), KSPConvergedReason, KSPGetConvergedReason(), KSPDefaultConvergedSetUIRNorm()
525: @*/
526: PetscErrorCode  KSPDefaultConvergedSetUMIRNorm(KSP ksp)
527: {
528:   KSPDefaultConvergedCtx *ctx = (KSPDefaultConvergedCtx*) ksp->cnvP;

532:   if (ksp->converged != KSPDefaultConverged) return(0);
533:   if (ctx->initialrtol) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot use KSPDefaultConvergedSetUIRNorm() and KSPDefaultConvergedSetUMIRNorm() together");
534:   ctx->mininitialrtol = PETSC_TRUE;
535:    return(0);
536: }

540: /*@C
541:    KSPDefaultConverged - Determines convergence of
542:    the iterative solvers (default code).

544:    Collective on KSP

546:    Input Parameters:
547: +  ksp   - iterative context
548: .  n     - iteration number
549: .  rnorm - 2-norm residual value (may be estimated)
550: -  ctx - convergence context which must be created by KSPDefaultConvergedCreate()

552:    reason is set to:
553: +   positive - if the iteration has converged;
554: .   negative - if residual norm exceeds divergence threshold;
555: -   0 - otherwise.

557:    Notes:
558:    KSPDefaultConverged() reaches convergence when
559: $      rnorm < MAX (rtol * rnorm_0, abstol);
560:    Divergence is detected if
561: $      rnorm > dtol * rnorm_0,

563:    where 
564: +     rtol = relative tolerance,
565: .     abstol = absolute tolerance.
566: .     dtol = divergence tolerance,
567: -     rnorm_0 is the two norm of the right hand side. When initial guess is non-zero you 
568:           can call KSPDefaultConvergedSetUIRNorm() to use the norm of (b - A*(initial guess))
569:           as the starting point for relative norm convergence testing.

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

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

576:    Level: intermediate

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

580: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSkipConverged(), KSPConvergedReason, KSPGetConvergedReason(),
581:           KSPDefaultConvergedSetUIRNorm(), KSPDefaultConvergedSetUMIRNorm(), KSPDefaultConvergedCreate(), KSPDefaultConvergedDestroy()
582: @*/
583: PetscErrorCode  KSPDefaultConverged(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *ctx)
584: {
585:   PetscErrorCode         ierr;
586:   KSPDefaultConvergedCtx *cctx = (KSPDefaultConvergedCtx*) ctx;
587:   KSPNormType            normtype;

592:   *reason = KSP_CONVERGED_ITERATING;
593: 
594:   KSPGetNormType(ksp,&normtype);
595:   if (normtype == KSP_NORM_NO) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Use KSPSkipConverged() with KSPNormType of KSP_NORM_NO");

597:   if (!cctx) SETERRQ(PETSC_ERR_ARG_NULL,"Convergence context must have been created with KSPDefaultConvergedCreate()");
598:   if (!n) {
599:     /* if user gives initial guess need to compute norm of b */
600:     if (!ksp->guess_zero && !cctx->initialrtol) {
601:       PetscReal      snorm;
602:       if (ksp->normtype == KSP_NORM_UNPRECONDITIONED || ksp->pc_side == PC_RIGHT) {
603:         PetscInfo(ksp,"user has provided nonzero initial guess, computing 2-norm of RHS\n");
604:         VecNorm(ksp->vec_rhs,NORM_2,&snorm);        /*     <- b'*b */
605:       } else {
606:         Vec z;
607:         if (!cctx->work) {
608:           VecDuplicate(ksp->vec_rhs,&cctx->work);
609:         }
610:         z = cctx->work;
611:         KSP_PCApply(ksp,ksp->vec_rhs,z);
612:         if (ksp->normtype == KSP_NORM_PRECONDITIONED) {
613:           PetscInfo(ksp,"user has provided nonzero initial guess, computing 2-norm of preconditioned RHS\n");
614:           VecNorm(z,NORM_2,&snorm);                 /*    dp <- b'*B'*B*b */
615:         } else if (ksp->normtype == KSP_NORM_NATURAL) {
616:           PetscScalar norm;
617:            PetscInfo(ksp,"user has provided nonzero initial guess, computing natural norm of RHS\n");
618:           VecDot(ksp->vec_rhs,z,&norm);
619:           snorm = sqrt(PetscAbsScalar(norm));                            /*    dp <- b'*B*b */
620:         }
621:       }
622:       /* handle special case of zero RHS and nonzero guess */
623:       if (!snorm) {
624:         PetscInfo(ksp,"Special case, user has provided nonzero initial guess and zero RHS\n");
625:         snorm = rnorm;
626:       }
627:       if (cctx->mininitialrtol) {
628:         ksp->rnorm0 = PetscMin(snorm,rnorm);
629:       } else {
630:         ksp->rnorm0 = snorm;
631:       }
632:     } else {
633:       ksp->rnorm0 = rnorm;
634:     }
635:     ksp->ttol   = PetscMax(ksp->rtol*ksp->rnorm0,ksp->abstol);
636:   }

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

640:   if (PetscIsInfOrNanScalar(rnorm)) {
641:     PetscInfo(ksp,"Linear solver has created a not a number (NaN) as the residual norm, declaring divergence \n");
642:     *reason = KSP_DIVERGED_NAN;
643:   } else if (rnorm <= ksp->ttol) {
644:     if (rnorm < ksp->abstol) {
645:       PetscInfo3(ksp,"Linear solver has converged. Residual norm %G is less than absolute tolerance %G at iteration %D\n",rnorm,ksp->abstol,n);
646:       *reason = KSP_CONVERGED_ATOL;
647:     } else {
648:       if (cctx->initialrtol) {
649:         PetscInfo4(ksp,"Linear solver has converged. Residual norm %G is less than relative tolerance %G times initial residual norm %G at iteration %D\n",rnorm,ksp->rtol,ksp->rnorm0,n);
650:       } else {
651:         PetscInfo4(ksp,"Linear solver has converged. Residual norm %G is less than relative tolerance %G times initial right hand side norm %G at iteration %D\n",rnorm,ksp->rtol,ksp->rnorm0,n);
652:       }
653:       *reason = KSP_CONVERGED_RTOL;
654:     }
655:   } else if (rnorm >= ksp->divtol*ksp->rnorm0) {
656:     PetscInfo3(ksp,"Linear solver is diverging. Initial right hand size norm %G, current residual norm %G at iteration %D\n",ksp->rnorm0,rnorm,n);
657:     *reason = KSP_DIVERGED_DTOL;
658:   }
659:   return(0);
660: }

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

667:    Collective on KSP

669:    Input Parameters:
670: .  ctx - convergence context 

672:    Level: intermediate

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

676: .seealso: KSPDefaultConverged(), KSPDefaultConvergedCreate(), KSPSetConvergenceTest(), KSPSetTolerances(), KSPSkipConverged(),
677:           KSPConvergedReason, KSPGetConvergedReason(), KSPDefaultConvergedSetUIRNorm(), KSPDefaultConvergedSetUMIRNorm()
678: @*/
679: PetscErrorCode  KSPDefaultConvergedDestroy(void *ctx)
680: {
681:   PetscErrorCode         ierr;
682:   KSPDefaultConvergedCtx *cctx = (KSPDefaultConvergedCtx*) ctx;

685:   if (cctx->work) {VecDestroy(cctx->work);}
686:   PetscFree(cctx);
687:   return(0);
688: }

692: /*
693:    KSPDefaultBuildSolution - Default code to create/move the solution.

695:    Input Parameters:
696: +  ksp - iterative context
697: -  v   - pointer to the user's vector  

699:    Output Parameter:
700: .  V - pointer to a vector containing the solution

702:    Level: advanced

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

706: .seealso: KSPGetSolution(), KSPDefaultBuildResidual()
707: */
708: PetscErrorCode KSPDefaultBuildSolution(KSP ksp,Vec v,Vec *V)
709: {
712:   if (ksp->pc_side == PC_RIGHT) {
713:     if (ksp->pc) {
714:       if (v) {KSP_PCApply(ksp,ksp->vec_sol,v); *V = v;}
715:       else {SETERRQ(PETSC_ERR_SUP,"Not working with right preconditioner");}
716:     } else {
717:       if (v) {VecCopy(ksp->vec_sol,v); *V = v;}
718:       else { *V = ksp->vec_sol;}
719:     }
720:   } else if (ksp->pc_side == PC_SYMMETRIC) {
721:     if (ksp->pc) {
722:       if (ksp->transpose_solve) SETERRQ(PETSC_ERR_SUP,"Not working with symmetric preconditioner and transpose solve");
723:       if (v) {PCApplySymmetricRight(ksp->pc,ksp->vec_sol,v); *V = v;}
724:       else {SETERRQ(PETSC_ERR_SUP,"Not working with symmetric preconditioner");}
725:     } else  {
726:       if (v) {VecCopy(ksp->vec_sol,v); *V = v;}
727:       else { *V = ksp->vec_sol;}
728:     }
729:   } else {
730:     if (v) {VecCopy(ksp->vec_sol,v); *V = v;}
731:     else { *V = ksp->vec_sol; }
732:   }
733:   return(0);
734: }

738: /*
739:    KSPDefaultBuildResidual - Default code to compute the residual.

741:    Input Parameters:
742: .  ksp - iterative context
743: .  t   - pointer to temporary vector
744: .  v   - pointer to user vector  

746:    Output Parameter:
747: .  V - pointer to a vector containing the residual

749:    Level: advanced

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

753: .seealso: KSPDefaultBuildSolution()
754: */
755: PetscErrorCode KSPDefaultBuildResidual(KSP ksp,Vec t,Vec v,Vec *V)
756: {
758:   MatStructure   pflag;
759:   Mat            Amat,Pmat;

762:   if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
763:   PCGetOperators(ksp->pc,&Amat,&Pmat,&pflag);
764:   KSPBuildSolution(ksp,t,PETSC_NULL);
765:   KSP_MatMult(ksp,Amat,t,v);
766:   VecAYPX(v,-1.0,ksp->vec_rhs);
767:   *V = v;
768:   return(0);
769: }

773: /*@C
774:   KSPGetVecs - Gets a number of work vectors.

776:   Input Parameters:
777: + ksp  - iterative context
778: . rightn  - number of right work vectors
779: - leftn   - number of left work vectors to allocate

781:   Output Parameter:
782: +  right - the array of vectors created
783: -  left - the array of left vectors

785:    Note: The right vector has as many elements as the matrix has columns. The left
786:      vector has as many elements as the matrix has rows.

788:    Level: advanced

790: .seealso:   MatGetVecs()

792: @*/
793: PetscErrorCode KSPGetVecs(KSP ksp,PetscInt rightn, Vec **right,PetscInt leftn,Vec **left)
794: {
796:   Vec            vecr,vecl;

799:   if (rightn) {
800:     if (!right) SETERRQ(PETSC_ERR_ARG_INCOMP,"You asked for right vectors but did not pass a pointer to hold them");
801:     if (ksp->vec_sol) vecr = ksp->vec_sol;
802:     else {
803:       Mat pmat;
804:       if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
805:       PCGetOperators(ksp->pc,PETSC_NULL,&pmat,PETSC_NULL);
806:       MatGetVecs(pmat,&vecr,PETSC_NULL);
807:     }
808:     VecDuplicateVecs(vecr,rightn,right);
809:     if (!ksp->vec_sol) {
810:       VecDestroy(vecr);
811:     }
812:   }
813:   if (leftn) {
814:     if (!left) SETERRQ(PETSC_ERR_ARG_INCOMP,"You asked for left vectors but did not pass a pointer to hold them");
815:     if (ksp->vec_rhs) vecl = ksp->vec_rhs;
816:     else {
817:       Mat pmat;
818:       if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
819:       PCGetOperators(ksp->pc,PETSC_NULL,&pmat,PETSC_NULL);
820:       MatGetVecs(pmat,PETSC_NULL,&vecl);
821:     }
822:     VecDuplicateVecs(vecl,leftn,left);
823:     if (!ksp->vec_rhs) {
824:       VecDestroy(vecl);
825:     }
826:   }
827:   return(0);
828: }

832: /*
833:   KSPDefaultGetWork - Gets a number of work vectors.

835:   Input Parameters:
836: . ksp  - iterative context
837: . nw   - number of work vectors to allocate

839:   Notes:
840:   Call this only if no work vectors have been allocated 
841:  */
842: PetscErrorCode KSPDefaultGetWork(KSP ksp,PetscInt nw)
843: {

847:   if (ksp->work) {KSPDefaultFreeWork(ksp);}
848:   ksp->nwork = nw;
849:   KSPGetVecs(ksp,nw,&ksp->work,0,PETSC_NULL);
850:   PetscLogObjectParents(ksp,nw,ksp->work);
851:   return(0);
852: }

856: /*
857:   KSPDefaultDestroy - Destroys a iterative context variable for methods with
858:   no separate context.  Preferred calling sequence KSPDestroy().

860:   Input Parameter: 
861: . ksp - the iterative context
862: */
863: PetscErrorCode KSPDefaultDestroy(KSP ksp)
864: {

869:   /* free work vectors */
870:   KSPDefaultFreeWork(ksp);
871:   /* free private data structure */
872:   PetscFree(ksp->data);
873:   return(0);
874: }

878: /*@
879:    KSPGetConvergedReason - Gets the reason the KSP iteration was stopped.

881:    Not Collective

883:    Input Parameter:
884: .  ksp - the KSP context

886:    Output Parameter:
887: .  reason - negative value indicates diverged, positive value converged, see KSPConvergedReason

889:    Possible values for reason:
890: +  KSP_CONVERGED_RTOL (residual 2-norm decreased by a factor of rtol, from 2-norm of right hand side)
891: .  KSP_CONVERGED_ATOL (residual 2-norm less than abstol)
892: .  KSP_CONVERGED_ITS (used by the preonly preconditioner that always uses ONE iteration, or when the KSPSkipConverged() convergence 
893:            test routine is set.
894: .  KSP_CONVERGED_CG_NEG_CURVE
895: .  KSP_CONVERGED_CG_CONSTRAINED
896: .  KSP_CONVERGED_STEP_LENGTH
897: .  KSP_DIVERGED_ITS  (required more than its to reach convergence)
898: .  KSP_DIVERGED_DTOL (residual norm increased by a factor of divtol)
899: .  KSP_DIVERGED_NAN (residual norm became Not-a-number likely due to 0/0)
900: .  KSP_DIVERGED_BREAKDOWN (generic breakdown in method)
901: -  KSP_DIVERGED_BREAKDOWN_BICG (Initial residual is orthogonal to preconditioned initial
902:                                 residual. Try a different preconditioner, or a different initial Level.)
903:  
904:    See also manual page for each reason.

906:    guess: beginner

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

910:    Level: intermediate
911:  
912: .keywords: KSP, nonlinear, set, convergence, test

914: .seealso: KSPSetConvergenceTest(), KSPDefaultConverged(), KSPSetTolerances(), KSPConvergedReason
915: @*/
916: PetscErrorCode  KSPGetConvergedReason(KSP ksp,KSPConvergedReason *reason)
917: {
921:   *reason = ksp->reason;
922:   return(0);
923: }