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 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(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(ksp->comm,"stdout",0,&viewer);}
210:   PetscViewerASCIIMonitorPrintf(viewer,"%3D KSP Residual norm %14.12e \n",n,rnorm);
211:   if (!dummy) {PetscViewerASCIIMonitorDestroy(viewer);}
212:   return(0);
213: }

217: /*@C
218:    KSPMonitorTrueResidualNorm - Prints the true residual norm as well as the preconditioned
219:    residual norm at each iteration of an iterative solver.

221:    Collective on KSP

223:    Input Parameters:
224: +  ksp   - iterative context
225: .  n     - iteration number
226: .  rnorm - 2-norm (preconditioned) residual value (may be estimated).  
227: -  dummy - unused monitor context 

229:    Options Database Key:
230: .  -ksp_monitor_true_residual_norm - Activates KSPMonitorTrueResidualNorm()

232:    Notes:
233:    When using right preconditioning, these values are equivalent.

235:    When using either ICC or ILU preconditioners in BlockSolve95 
236:    (via MATMPIROWBS matrix format), then use this monitor will
237:    print both the residual norm associated with the original
238:    (unscaled) matrix.

240:    Level: intermediate

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

244: .seealso: KSPMonitorSet(), KSPMonitorDefault(), KSPMonitorLGCreate()
245: @*/
246: PetscErrorCode  KSPMonitorTrueResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy)
247: {
248:   PetscErrorCode          ierr;
249:   Vec                     resid,work;
250:   PetscReal               scnorm,bnorm;
251:   PC                      pc;
252:   Mat                     A,B;
253:   PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy;
254: 
256:   if (!dummy) {PetscViewerASCIIMonitorCreate(ksp->comm,"stdout",0,&viewer);}
257:   VecDuplicate(ksp->vec_rhs,&work);
258:   KSPBuildResidual(ksp,0,work,&resid);

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

281: /*
282:   Default (short) KSP Monitor, same as KSPMonitorDefault() except
283:   it prints fewer digits of the residual as the residual gets smaller.
284:   This is because the later digits are meaningless and are often 
285:   different on different machines; by using this routine different 
286:   machines will usually generate the same output.
287: */
288: PetscErrorCode  KSPMonitorDefaultShort(KSP ksp,PetscInt its,PetscReal fnorm,void *dummy)
289: {
290:   PetscErrorCode          ierr;
291:   PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy;

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

296:   if (fnorm > 1.e-9) {
297:     PetscViewerASCIIMonitorPrintf(viewer,"%3D KSP Residual norm %G \n",its,fnorm);
298:   } else if (fnorm > 1.e-11){
299:     PetscViewerASCIIMonitorPrintf(viewer,"%3D KSP Residual norm %5.3e \n",its,fnorm);
300:   } else {
301:     PetscViewerASCIIMonitorPrintf(viewer,"%3D KSP Residual norm < 1.e-11\n",its);
302:   }
303:   if (!dummy) {PetscViewerASCIIMonitorDestroy(viewer);}
304:   return(0);
305: }

309: /*@C
310:    KSPSkipConverged - Convergence test that NEVER returns as converged.

312:    Collective on KSP

314:    Input Parameters:
315: +  ksp   - iterative context
316: .  n     - iteration number
317: .  rnorm - 2-norm residual value (may be estimated)
318: -  dummy - unused convergence context 

320:    Returns:
321: .  reason - always KSP_CONVERGED_ITERATING

323:    Notes:
324:    This is used as the convergence test with the option KSPSetNormType(ksp,KSP_NO_NORM),
325:    since norms of the residual are not computed. Convergence is then declared 
326:    after a fixed number of iterations have been used. Useful when one is 
327:    using CG or Bi-CG-stab as a smoother.
328:                     
329:    Level: advanced

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

333: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSetNormType()
334: @*/
335: PetscErrorCode  KSPSkipConverged(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *dummy)
336: {
339:   return(0);
340: }

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

349:    Collective on KSP

351:    Input Parameters:
352: .  ksp   - iterative context

354:    Options Database:
355: .   -ksp_converged_use_initial_residual_norm

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

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

362:    Level: intermediate

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

366: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSkipConverged(), KSPConvergedReason, KSPGetConvergedReason(), KSPDefaultConvergedSetUMIRNorm()
367: @*/
368: PetscErrorCode  KSPDefaultConvergedSetUIRNorm(KSP ksp)
369: {
372:   if (ksp->defaultconvergedmininitialrtol) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Can use KSPDefaultConvergedSetUIRNorm() and KSPDefaultConvergedSetUMIRNorm() together");
373:   ksp->defaultconvergedinitialrtol = PETSC_TRUE;
374:   return(0);
375: }

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

384:    Collective on KSP

386:    Input Parameters:
387: .  ksp   - iterative context

389:    Options Database:
390: .   -ksp_converged_use_min_initial_residual_norm

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

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

397:    Level: intermediate

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

401: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSkipConverged(), KSPConvergedReason, KSPGetConvergedReason(), KSPDefaultConvergedSetUIRNorm()
402: @*/
403: PetscErrorCode  KSPDefaultConvergedSetUMIRNorm(KSP ksp)
404: {
407:   if (ksp->defaultconvergedinitialrtol) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot use KSPDefaultConvergedSetUIRNorm() and KSPDefaultConvergedSetUMIRNorm() together");
408:   ksp->defaultconvergedmininitialrtol = PETSC_TRUE;
409:   return(0);
410: }

414: /*@C
415:    KSPDefaultConverged - Determines convergence of
416:    the iterative solvers (default code).

418:    Collective on KSP

420:    Input Parameters:
421: +  ksp   - iterative context
422: .  n     - iteration number
423: .  rnorm - 2-norm residual value (may be estimated)
424: -  dummy - unused convergence context 

426:    Returns:
427: +   positive - if the iteration has converged;
428: .   negative - if residual norm exceeds divergence threshold;
429: -   0 - otherwise.

431:    Notes:
432:    KSPDefaultConverged() reaches convergence when
433: $      rnorm < MAX (rtol * rnorm_0, abstol);
434:    Divergence is detected if
435: $      rnorm > dtol * rnorm_0,

437:    where 
438: +     rtol = relative tolerance,
439: .     abstol = absolute tolerance.
440: .     dtol = divergence tolerance,
441: -     rnorm_0 is the two norm of the right hand side. When initial guess is non-zero you 
442:           can call KSPDefaultConvergedSetUIRNorm() to use the norm of (b - A*(initial guess))
443:           as the starting point for relative norm convergence testing.

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

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

450:    Level: intermediate

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

454: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSkipConverged(), KSPConvergedReason, KSPGetConvergedReason(),
455:           KSPDefaultConvergedSetUIRNorm(), KSPDefaultConvergedSetUMIRNorm().
456: @*/
457: PetscErrorCode  KSPDefaultConverged(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *dummy)
458: {

464:   *reason = KSP_CONVERGED_ITERATING;

466:   if (!n) {
467:     /* if user gives initial guess need to compute norm of b */
468:     if (!ksp->guess_zero && !ksp->defaultconvergedinitialrtol) {
469:       PetscReal      snorm;
470:       if (ksp->normtype == KSP_UNPRECONDITIONED_NORM || ksp->pc_side == PC_RIGHT) {
471:         PetscInfo(ksp,"user has provided nonzero initial guess, computing 2-norm of RHS\n");
472:         VecNorm(ksp->vec_rhs,NORM_2,&snorm);        /*     <- b'*b */
473:       } else {
474:         Vec z;
475:         VecDuplicate(ksp->vec_rhs,&z);
476:         KSP_PCApply(ksp,ksp->vec_rhs,z);
477:         if (ksp->normtype == KSP_PRECONDITIONED_NORM) {
478:           PetscInfo(ksp,"user has provided nonzero initial guess, computing 2-norm of preconditioned RHS\n");
479:           VecNorm(z,NORM_2,&snorm);                 /*    dp <- b'*B'*B*b */
480:         } else if (ksp->normtype == KSP_NATURAL_NORM) {
481:           PetscScalar norm;
482:           PetscInfo(ksp,"user has provided nonzero initial guess, computing natural norm of RHS\n");
483:           VecDot(ksp->vec_rhs,z,&norm);
484:           snorm = sqrt(PetscAbsScalar(norm));                            /*    dp <- b'*B*b */
485:         }
486:         VecDestroy(z);
487:       }
488:       /* handle special case of zero RHS and nonzero guess */
489:       if (!snorm) {
490:         PetscInfo(ksp,"Special case, user has provided nonzero initial guess and zero RHS\n");
491:         snorm = rnorm;
492:       }
493:       if (ksp->defaultconvergedmininitialrtol) {
494:         ksp->rnorm0 = PetscMin(snorm,rnorm);
495:       } else {
496:         ksp->rnorm0 = snorm;
497:       }
498:     } else {
499:       ksp->rnorm0 = rnorm;
500:     }
501:     ksp->ttol   = PetscMax(ksp->rtol*ksp->rnorm0,ksp->abstol);
502:   }

504:   if (rnorm != rnorm) {
505:     PetscInfo(ksp,"Linear solver has created a not a number (NaN) as the residual norm, declaring divergence \n");
506:     *reason = KSP_DIVERGED_NAN;
507:   } else if (rnorm <= ksp->ttol) {
508:     if (rnorm < ksp->abstol) {
509:       PetscInfo3(ksp,"Linear solver has converged. Residual norm %G is less than absolute tolerance %G at iteration %D\n",rnorm,ksp->abstol,n);
510:       *reason = KSP_CONVERGED_ATOL;
511:     } else {
512:       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);
513:       *reason = KSP_CONVERGED_RTOL;
514:     }
515:   } else if (rnorm >= ksp->divtol*ksp->rnorm0) {
516:     PetscInfo3(ksp,"Linear solver is diverging. Initial right hand size norm %G, current residual norm %G at iteration %D\n",ksp->rnorm0,rnorm,n);
517:     *reason = KSP_DIVERGED_DTOL;
518:   }
519:   return(0);
520: }

524: /*
525:    KSPDefaultBuildSolution - Default code to create/move the solution.

527:    Input Parameters:
528: +  ksp - iterative context
529: -  v   - pointer to the user's vector  

531:    Output Parameter:
532: .  V - pointer to a vector containing the solution

534:    Level: advanced

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

538: .seealso: KSPGetSolution(), KSPDefaultBuildResidual()
539: */
540: PetscErrorCode KSPDefaultBuildSolution(KSP ksp,Vec v,Vec *V)
541: {
544:   if (ksp->pc_side == PC_RIGHT) {
545:     if (ksp->pc) {
546:       if (v) {KSP_PCApply(ksp,ksp->vec_sol,v); *V = v;}
547:       else {SETERRQ(PETSC_ERR_SUP,"Not working with right preconditioner");}
548:     } else {
549:       if (v) {VecCopy(ksp->vec_sol,v); *V = v;}
550:       else { *V = ksp->vec_sol;}
551:     }
552:   } else if (ksp->pc_side == PC_SYMMETRIC) {
553:     if (ksp->pc) {
554:       if (ksp->transpose_solve) SETERRQ(PETSC_ERR_SUP,"Not working with symmetric preconditioner and transpose solve");
555:       if (v) {PCApplySymmetricRight(ksp->pc,ksp->vec_sol,v); *V = v;}
556:       else {SETERRQ(PETSC_ERR_SUP,"Not working with symmetric preconditioner");}
557:     } else  {
558:       if (v) {VecCopy(ksp->vec_sol,v); *V = v;}
559:       else { *V = ksp->vec_sol;}
560:     }
561:   } else {
562:     if (v) {VecCopy(ksp->vec_sol,v); *V = v;}
563:     else { *V = ksp->vec_sol; }
564:   }
565:   return(0);
566: }

570: /*
571:    KSPDefaultBuildResidual - Default code to compute the residual.

573:    Input Parameters:
574: .  ksp - iterative context
575: .  t   - pointer to temporary vector
576: .  v   - pointer to user vector  

578:    Output Parameter:
579: .  V - pointer to a vector containing the residual

581:    Level: advanced

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

585: .seealso: KSPDefaultBuildSolution()
586: */
587: PetscErrorCode KSPDefaultBuildResidual(KSP ksp,Vec t,Vec v,Vec *V)
588: {
590:   MatStructure   pflag;
591:   Mat            Amat,Pmat;

594:   PCGetOperators(ksp->pc,&Amat,&Pmat,&pflag);
595:   KSPBuildSolution(ksp,t,PETSC_NULL);
596:   KSP_MatMult(ksp,Amat,t,v);
597:   VecAYPX(v,-1.0,ksp->vec_rhs);
598:   *V = v;
599:   return(0);
600: }

604: /*@C
605:   KSPGetVecs - Gets a number of work vectors.

607:   Input Parameters:
608: + ksp  - iterative context
609: . rightn  - number of right work vectors
610: - leftn   - number of left work vectors to allocate

612:   Output Parameter:
613: +  right - the array of vectors created
614: -  left - the array of left vectors

616:    Note: The right vector has as many elements as the matrix has columns. The left
617:      vector has as many elements as the matrix has rows.

619:    Level: advanced

621: .seealso:   MatGetVecs()

623: @*/
624: PetscErrorCode KSPGetVecs(KSP ksp,PetscInt rightn, Vec **right,PetscInt leftn,Vec **left)
625: {
627:   Vec            vecr,vecl;

630:   if (rightn) {
631:     if (!right) SETERRQ(PETSC_ERR_ARG_INCOMP,"You asked for right vectors but did not pass a pointer to hold them");
632:     if (ksp->vec_sol) vecr = ksp->vec_sol;
633:     else {
634:       Mat pmat;
635:       PCGetOperators(ksp->pc,PETSC_NULL,&pmat,PETSC_NULL);
636:       MatGetVecs(pmat,&vecr,PETSC_NULL);
637:     }
638:     VecDuplicateVecs(vecr,rightn,right);
639:     if (!ksp->vec_sol) {
640:       VecDestroy(vecr);
641:     }
642:   }
643:   if (leftn) {
644:     if (!left) SETERRQ(PETSC_ERR_ARG_INCOMP,"You asked for left vectors but did not pass a pointer to hold them");
645:     if (ksp->vec_rhs) vecl = ksp->vec_rhs;
646:     else {
647:       Mat pmat;
648:       PCGetOperators(ksp->pc,PETSC_NULL,&pmat,PETSC_NULL);
649:       MatGetVecs(pmat,PETSC_NULL,&vecl);
650:     }
651:     VecDuplicateVecs(vecl,leftn,left);
652:     if (!ksp->vec_rhs) {
653:       VecDestroy(vecl);
654:     }
655:   }
656:   return(0);
657: }

661: /*
662:   KSPDefaultGetWork - Gets a number of work vectors.

664:   Input Parameters:
665: . ksp  - iterative context
666: . nw   - number of work vectors to allocate

668:   Notes:
669:   Call this only if no work vectors have been allocated 
670:  */
671: PetscErrorCode KSPDefaultGetWork(KSP ksp,PetscInt nw)
672: {

676:   if (ksp->work) {KSPDefaultFreeWork(ksp);}
677:   ksp->nwork = nw;
678:   KSPGetVecs(ksp,nw,&ksp->work,0,PETSC_NULL);
679:   PetscLogObjectParents(ksp,nw,ksp->work);
680:   return(0);
681: }

685: /*
686:   KSPDefaultDestroy - Destroys a iterative context variable for methods with
687:   no separate context.  Preferred calling sequence KSPDestroy().

689:   Input Parameter: 
690: . ksp - the iterative context
691: */
692: PetscErrorCode KSPDefaultDestroy(KSP ksp)
693: {

698:   PetscFree(ksp->data);

700:   /* free work vectors */
701:   KSPDefaultFreeWork(ksp);
702:   return(0);
703: }

707: /*@
708:    KSPGetConvergedReason - Gets the reason the KSP iteration was stopped.

710:    Not Collective

712:    Input Parameter:
713: .  ksp - the KSP context

715:    Output Parameter:
716: .  reason - negative value indicates diverged, positive value converged, see KSPConvergedReason

718:    Possible values for reason:
719: +  KSP_CONVERGED_RTOL (residual 2-norm decreased by a factor of rtol, from 2-norm of right hand side)
720: .  KSP_CONVERGED_ATOL (residual 2-norm less than abstol)
721: .  KSP_CONVERGED_ITS (used by the preonly preconditioner that always uses ONE iteration) 
722: .  KSP_CONVERGED_QCG_NEG_CURVE
723: .  KSP_CONVERGED_QCG_CONSTRAINED
724: .  KSP_CONVERGED_STEP_LENGTH
725: .  KSP_DIVERGED_ITS  (required more than its to reach convergence)
726: .  KSP_DIVERGED_DTOL (residual norm increased by a factor of divtol)
727: .  KSP_DIVERGED_NAN (residual norm became Not-a-number likely do to 0/0)
728: .  KSP_DIVERGED_BREAKDOWN (generic breakdown in method)
729: -  KSP_DIVERGED_BREAKDOWN_BICG (Initial residual is orthogonal to preconditioned initial
730:                                 residual. Try a different preconditioner, or a different initial guess.)
731:  

733:    Level: beginner

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

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

739: .seealso: KSPSetConvergenceTest(), KSPDefaultConverged(), KSPSetTolerances(), KSPConvergedReason
740: @*/
741: PetscErrorCode  KSPGetConvergedReason(KSP ksp,KSPConvergedReason *reason)
742: {
746:   *reason = ksp->reason;
747:   return(0);
748: }