Actual source code: iterativ.c
1: /*$Id: iterativ.c,v 1.105 2001/04/04 18:19:34 bsmith Exp $*/
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 src/sles/ksp/kspimpl.h
12: /*
13: KSPDefaultFreeWork - Free work vectors
15: Input Parameters:
16: . ksp - iterative context
17: */
18: int KSPDefaultFreeWork(KSP ksp)
19: {
23: if (ksp->work) {
24: VecDestroyVecs(ksp->work,ksp->nwork);
25: }
26: return(0);
27: }
29: /*@C
30: KSPGetResidualNorm - Gets the last (approximate preconditioned)
31: residual norm that has been computed.
32:
33: Not Collective
35: Input Parameters:
36: . ksp - the iterative context
38: Output Parameters:
39: . rnorm - residual norm
41: Level: intermediate
43: .keywords: KSP, get, residual norm
45: .seealso: KSPComputeResidual()
46: @*/
47: int KSPGetResidualNorm(KSP ksp,PetscReal *rnorm)
48: {
51: *rnorm = ksp->rnorm;
52: return(0);
53: }
55: /*@
56: KSPGetIterationNumber - Gets the current iteration number (if the
57: KSPSolve() (SLESSolve()) is complete, returns the number of iterations
58: used.
59:
60: Not Collective
62: Input Parameters:
63: . ksp - the iterative context
65: Output Parameters:
66: . its - number of iterations
68: Level: intermediate
70: Notes:
71: During the ith iteration this returns i-1
72: .keywords: KSP, get, residual norm
74: .seealso: KSPComputeResidual(), KSPGetResidualNorm()
75: @*/
76: int KSPGetIterationNumber(KSP ksp,int *its)
77: {
80: *its = ksp->its;
81: return(0);
82: }
84: /*@C
85: KSPSingularValueMonitor - Prints the two norm of the true residual and
86: estimation of the extreme singular values of the preconditioned problem
87: at each iteration.
88:
89: Collective on KSP
91: Input Parameters:
92: + ksp - the iterative context
93: . n - the iteration
94: - rnorm - the two norm of the residual
96: Options Database Key:
97: . -ksp_singmonitor - Activates KSPSingularValueMonitor()
99: Notes:
100: The CG solver uses the Lanczos technique for eigenvalue computation,
101: while GMRES uses the Arnoldi technique; other iterative methods do
102: not currently compute singular values.
104: Level: intermediate
106: .keywords: KSP, CG, default, monitor, extreme, singular values, Lanczos, Arnoldi
108: .seealso: KSPComputeExtremeSingularValues()
109: @*/
110: int KSPSingularValueMonitor(KSP ksp,int n,PetscReal rnorm,void *dummy)
111: {
112: PetscReal emin,emax,c;
113: int ierr;
117: if (!ksp->calc_sings) {
118: PetscPrintf(ksp->comm,"%3d KSP Residual norm %14.12e n",n,rnorm);
119: } else {
120: KSPComputeExtremeSingularValues(ksp,&emax,&emin);
121: c = emax/emin;
122: PetscPrintf(ksp->comm,"%3d KSP Residual norm %14.12e %% max %g min %g max/min %gn",n,rnorm,emax,emin,c);
123: }
124: return(0);
125: }
127: /*@C
128: KSPVecViewMonitor - Monitors progress of the KSP solvers by calling
129: VecView() for the approximate solution at each iteration.
131: Collective on KSP
133: Input Parameters:
134: + ksp - the KSP context
135: . its - iteration number
136: . fgnorm - 2-norm of residual (or gradient)
137: - dummy - either a viewer or PETSC_NULL
139: Level: intermediate
141: Notes:
142: For some Krylov methods such as GMRES constructing the solution at
143: each iteration is expensive, hence using this will slow the code.
145: .keywords: KSP, nonlinear, vector, monitor, view
147: .seealso: KSPSetMonitor(), KSPDefaultMonitor(), VecView()
148: @*/
149: int KSPVecViewMonitor(KSP ksp,int its,PetscReal fgnorm,void *dummy)
150: {
151: int ierr;
152: Vec x;
153: PetscViewer viewer = (PetscViewer) dummy;
156: KSPBuildSolution(ksp,PETSC_NULL,&x);
157: if (!viewer) {
158: MPI_Comm comm;
159: ierr = PetscObjectGetComm((PetscObject)ksp,&comm);
160: viewer = PETSC_VIEWER_DRAW_(comm);
161: }
162: VecView(x,viewer);
164: return(0);
165: }
167: /*@C
168: KSPDefaultMonitor - Print the residual norm at each iteration of an
169: iterative solver.
171: Collective on KSP
173: Input Parameters:
174: + ksp - iterative context
175: . n - iteration number
176: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
177: - dummy - unused monitor context
179: Level: intermediate
181: .keywords: KSP, default, monitor, residual
183: .seealso: KSPSetMonitor(), KSPTrueMonitor(), KSPLGMonitorCreate()
184: @*/
185: int KSPDefaultMonitor(KSP ksp,int n,PetscReal rnorm,void *dummy)
186: {
187: int ierr;
188: PetscViewer viewer = (PetscViewer) dummy;
191: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(ksp->comm);
192: PetscViewerASCIIPrintf(viewer,"%3d KSP Residual norm %14.12e n",n,rnorm);
193: return(0);
194: }
196: /*@C
197: KSPTrueMonitor - Prints the true residual norm as well as the preconditioned
198: residual norm at each iteration of an iterative solver.
200: Collective on KSP
202: Input Parameters:
203: + ksp - iterative context
204: . n - iteration number
205: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
206: - dummy - unused monitor context
208: Options Database Key:
209: . -ksp_truemonitor - Activates KSPTrueMonitor()
211: Notes:
212: When using right preconditioning, these values are equivalent.
214: When using either ICC or ILU preconditioners in BlockSolve95
215: (via MATMPIROWBS matrix format), then use this monitor will
216: print both the residual norm associated with the original
217: (unscaled) matrix.
219: Level: intermediate
221: .keywords: KSP, default, monitor, residual
223: .seealso: KSPSetMonitor(), KSPDefaultMonitor(), KSPLGMonitorCreate()
224: @*/
225: int KSPTrueMonitor(KSP ksp,int n,PetscReal rnorm,void *dummy)
226: {
227: int ierr;
228: Vec resid,work;
229: PetscReal scnorm;
230: PC pc;
231: Mat A,B;
232: PetscViewer viewer = (PetscViewer) dummy;
233:
235: VecDuplicate(ksp->vec_rhs,&work);
236: KSPBuildResidual(ksp,0,work,&resid);
238: /*
239: Unscale the residual if the matrix is, for example, a BlockSolve matrix
240: but only if both matrices are the same matrix, since only then would
241: they be scaled.
242: */
243: VecCopy(resid,work);
244: KSPGetPC(ksp,&pc);
245: PCGetOperators(pc,&A,&B,PETSC_NULL);
246: if (A == B) {
247: MatUnScaleSystem(A,PETSC_NULL,work);
248: }
249: VecNorm(work,NORM_2,&scnorm);
250: VecDestroy(work);
251: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(ksp->comm);
252: PetscViewerASCIIPrintf(viewer,"%3d KSP preconditioned resid norm %14.12e true resid norm %14.12en",n,rnorm,scnorm);
253: return(0);
254: }
256: /*
257: Default (short) KSP Monitor, same as KSPDefaultMonitor() except
258: it prints fewer digits of the residual as the residual gets smaller.
259: This is because the later digits are meaningless and are often
260: different on different machines; by using this routine different
261: machines will usually generate the same output.
262: */
263: int KSPDefaultSMonitor(KSP ksp,int its,PetscReal fnorm,void *dummy)
264: {
265: int ierr;
266: PetscViewer viewer = (PetscViewer) dummy;
269: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(ksp->comm);
271: if (fnorm > 1.e-9) {
272: PetscViewerASCIIPrintf(viewer,"%3d KSP Residual norm %g n",its,fnorm);
273: } else if (fnorm > 1.e-11){
274: PetscViewerASCIIPrintf(viewer,"%3d KSP Residual norm %5.3e n",its,fnorm);
275: } else {
276: PetscViewerASCIIPrintf(viewer,"%3d KSP Residual norm < 1.e-11n",its);
277: }
278: return(0);
279: }
281: /*@C
282: KSPSkipConverged - Convergence test that NEVER returns as converged.
284: Collective on KSP
286: Input Parameters:
287: + ksp - iterative context
288: . n - iteration number
289: . rnorm - 2-norm residual value (may be estimated)
290: - dummy - unused convergence context
292: Returns:
293: . 0 - always
295: Notes:
296: This is used as the convergence test with the option KSPSetAvoidNorms(),
297: since norms of the residual are not computed. Convergence is then declared
298: after a fixed number of iterations have been used. Useful when one is
299: using CG or Bi-CG-stab as a smoother.
300:
301: Level: advanced
303: .keywords: KSP, default, convergence, residual
305: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSetAvoidNorms()
306: @*/
307: int KSPSkipConverged(KSP ksp,int n,PetscReal rnorm,KSPConvergedReason *reason,void *dummy)
308: {
311: return(0);
312: }
314: /*@C
315: KSPDefaultConverged - Determines convergence of
316: the iterative solvers (default code).
318: Collective on KSP
320: Input Parameters:
321: + ksp - iterative context
322: . n - iteration number
323: . rnorm - 2-norm residual value (may be estimated)
324: - dummy - unused convergence context
326: Returns:
327: + 1 - if the iteration has converged;
328: . -1 - if residual norm exceeds divergence threshold;
329: - 0 - otherwise.
331: Notes:
332: KSPDefaultConverged() reaches convergence when
333: $ rnorm < MAX (rtol * rnorm_0, atol);
334: Divergence is detected if
335: $ rnorm > dtol * rnorm_0,
337: where
338: + rtol = relative tolerance,
339: . atol = absolute tolerance.
340: . dtol = divergence tolerance,
341: - rnorm_0 = initial residual norm
343: Use KSPSetTolerances() to alter the defaults for rtol, atol, dtol.
345: Level: intermediate
347: .keywords: KSP, default, convergence, residual
349: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSkipConverged()
350: @*/
351: int KSPDefaultConverged(KSP ksp,int n,PetscReal rnorm,KSPConvergedReason *reason,void *dummy)
352: {
355: *reason = KSP_CONVERGED_ITERATING;
357: if (!n) {
358: ksp->ttol = PetscMax(ksp->rtol*rnorm,ksp->atol);
359: ksp->rnorm0 = rnorm;
360: }
361: if (rnorm <= ksp->ttol) {
362: if (rnorm < ksp->atol) *reason = KSP_CONVERGED_ATOL;
363: else *reason = KSP_CONVERGED_RTOL;
364: } else if (rnorm >= ksp->divtol*ksp->rnorm0 || rnorm != rnorm) {
365: *reason = KSP_DIVERGED_DTOL;
366: }
367: return(0);
368: }
370: /*
371: KSPDefaultBuildSolution - Default code to create/move the solution.
373: Input Parameters:
374: + ksp - iterative context
375: - v - pointer to the user's vector
377: Output Parameter:
378: . V - pointer to a vector containing the solution
380: Level: advanced
382: .keywords: KSP, build, solution, default
384: .seealso: KSPGetSolution(), KSPDefaultBuildResidual()
385: */
386: int KSPDefaultBuildSolution(KSP ksp,Vec v,Vec *V)
387: {
390: if (ksp->pc_side == PC_RIGHT) {
391: if (ksp->B) {
392: if (v) {KSP_PCApply(ksp,ksp->B,ksp->vec_sol,v); *V = v;}
393: else {SETERRQ(PETSC_ERR_SUP,"Not working with right preconditioner");}
394: } else {
395: if (v) {VecCopy(ksp->vec_sol,v); *V = v;}
396: else { *V = ksp->vec_sol;}
397: }
398: } else if (ksp->pc_side == PC_SYMMETRIC) {
399: if (ksp->B) {
400: if (ksp->transpose_solve) SETERRQ(PETSC_ERR_SUP,"Not working with symmetric preconditioner and transpose solve");
401: if (v) {PCApplySymmetricRight(ksp->B,ksp->vec_sol,v); *V = v;}
402: else {SETERRQ(PETSC_ERR_SUP,"Not working with symmetric preconditioner");}
403: } else {
404: if (v) {VecCopy(ksp->vec_sol,v); *V = v;}
405: else { *V = ksp->vec_sol;}
406: }
407: } else {
408: if (v) {VecCopy(ksp->vec_sol,v); *V = v;}
409: else { *V = ksp->vec_sol; }
410: }
411: return(0);
412: }
414: /*
415: KSPDefaultBuildResidual - Default code to compute the residual.
417: Input Parameters:
418: . ksp - iterative context
419: . t - pointer to temporary vector
420: . v - pointer to user vector
422: Output Parameter:
423: . V - pointer to a vector containing the residual
425: Level: advanced
427: .keywords: KSP, build, residual, default
429: .seealso: KSPDefaultBuildSolution()
430: */
431: int KSPDefaultBuildResidual(KSP ksp,Vec t,Vec v,Vec *V)
432: {
433: int ierr;
434: MatStructure pflag;
435: Vec T;
436: Scalar mone = -1.0;
437: Mat Amat,Pmat;
440: PCGetOperators(ksp->B,&Amat,&Pmat,&pflag);
441: KSPBuildSolution(ksp,t,&T);
442: KSP_MatMult(ksp,Amat,t,v);
443: VecAYPX(&mone,ksp->vec_rhs,v);
444: *V = v;
445: return(0);
446: }
448: /*
449: KSPDefaultGetWork - Gets a number of work vectors.
451: Input Parameters:
452: . ksp - iterative context
453: . nw - number of work vectors to allocate
455: Notes:
456: Call this only if no work vectors have been allocated
457: */
458: int KSPDefaultGetWork(KSP ksp,int nw)
459: {
463: if (ksp->work) {KSPDefaultFreeWork(ksp);}
464: ksp->nwork = nw;
465: VecDuplicateVecs(ksp->vec_rhs,nw,&ksp->work);
466: PetscLogObjectParents(ksp,nw,ksp->work);
467: return(0);
468: }
470: /*
471: KSPDefaultDestroy - Destroys a iterative context variable for methods with
472: no separate context. Preferred calling sequence KSPDestroy().
474: Input Parameter:
475: . ksp - the iterative context
476: */
477: int KSPDefaultDestroy(KSP ksp)
478: {
483: if (ksp->data) {PetscFree(ksp->data);}
485: /* free work vectors */
486: KSPDefaultFreeWork(ksp);
487: return(0);
488: }
490: /*@C
491: KSPGetConvergedReason - Gets the reason the KSP iteration was stopped.
493: Not Collective
495: Input Parameter:
496: . ksp - the KSP context
498: Output Parameter:
499: . reason - negative value indicates diverged, positive value converged, see KSPConvergedReason
501: Possible values for reason:
502: + KSP_CONVERGED_RTOL (residual norm decreased by a factor of rtol)
503: . KSP_CONVERGED_ATOL (residual norm less than atol)
504: . KSP_CONVERGED_ITS (used by the preonly preconditioner that always uses ONE iteration)
505: . KSP_CONVERGED_QCG_NEG_CURVE
506: . KSP_CONVERGED_QCG_CONSTRAINED
507: . KSP_CONVERGED_STEP_LENGTH
508: . KSP_DIVERGED_ITS (required more than its to reach convergence)
509: . KSP_DIVERGED_DTOL (residual norm increased by a factor of divtol)
510: . KSP_DIVERGED_BREAKDOWN (generic breakdown in method)
511: - KSP_DIVERGED_BREAKDOWN_BICG (Initial residual is orthogonal to preconditioned initial
512: residual. Try a different preconditioner, or a different initial guess.
513:
515: Level: intermediate
517: Notes: Can only be called after the call the KSPSolve() is complete.
519: .keywords: KSP, nonlinear, set, convergence, test
521: .seealso: KSPSetConvergenceTest(), KSPDefaultConverged(), KSPSetTolerances(), KSPConvergedReason
522: @*/
523: int KSPGetConvergedReason(KSP ksp,KSPConvergedReason *reason)
524: {
527: *reason = ksp->reason;
528: return(0);
529: }