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: }