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(((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: 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 - 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(((PetscObject)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(((PetscObject)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 do not return as converged
311: until the maximum number of iterations is reached.
313: Collective on KSP
315: Input Parameters:
316: + ksp - iterative context
317: . n - iteration number
318: . rnorm - 2-norm residual value (may be estimated)
319: - dummy - unused convergence context
321: Returns:
322: . reason - KSP_CONVERGED_ITERATING, KSP_CONVERGED_ITS
324: Notes:
325: This should be used as the convergence test with the option
326: KSPSetNormType(ksp,KSP_NORM_NO), since norms of the residual are
327: not computed. Convergence is then declared after the maximum number
328: of iterations have been reached. Useful when one is using CG or
329: BiCGStab as a smoother.
330:
331: Level: advanced
333: .keywords: KSP, default, convergence, residual
335: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSetNormType()
336: @*/
337: PetscErrorCode KSPSkipConverged(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *dummy)
338: {
342: *reason = KSP_CONVERGED_ITERATING;
343: if (n >= ksp->max_it) *reason = KSP_CONVERGED_ITS;
344: return(0);
345: }
347: typedef struct {
348: PetscTruth initialrtol; /* default relative residual decrease is computing from initial residual, not rhs */
349: PetscTruth mininitialrtol; /* default relative residual decrease is computing from min of initial residual and rhs */
350: Vec work;
351: } KSPDefaultConvergedCtx;
355: /*@C
356: KSPDefaultConvergedCreate - Creates and initializes the space used by the KSPDefaultConverged() function context
358: Collective on KSP
360: Output Parameter:
361: . ctx - convergence context
363: Level: intermediate
365: .keywords: KSP, default, convergence, residual
367: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSkipConverged(), KSPConvergedReason, KSPGetConvergedReason(),
368: KSPDefaultConvergedSetUIRNorm(), KSPDefaultConvergedSetUMIRNorm(), KSPDefaultConvergedDestroy()
369: @*/
370: PetscErrorCode KSPDefaultConvergedCreate(void **ctx)
371: {
372: PetscErrorCode ierr;
373: KSPDefaultConvergedCtx *cctx;
376: PetscNew(KSPDefaultConvergedCtx,&cctx);
377: *ctx = cctx;
378: return(0);
379: }
383: /*@
384: KSPDefaultConvergedSetUIRNorm - makes the default convergence test use || B*(b - A*(initial guess))||
385: instead of || B*b ||. In the case of right preconditioner or if KSPSetNormType(ksp,KSP_NORM_UNPRECONDIITONED)
386: is used there is no B in the above formula. UIRNorm is short for Use Initial Residual Norm.
388: Collective on KSP
390: Input Parameters:
391: . ksp - iterative context
393: Options Database:
394: . -ksp_converged_use_initial_residual_norm
396: Use KSPSetTolerances() to alter the defaults for rtol, abstol, dtol.
398: The precise values of reason are macros such as KSP_CONVERGED_RTOL, which
399: are defined in petscksp.h.
401: If the convergence test is not KSPDefaultConverged() then this is ignored.
402: Level: intermediate
404: .keywords: KSP, default, convergence, residual
406: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSkipConverged(), KSPConvergedReason, KSPGetConvergedReason(), KSPDefaultConvergedSetUMIRNorm()
407: @*/
408: PetscErrorCode KSPDefaultConvergedSetUIRNorm(KSP ksp)
409: {
410: KSPDefaultConvergedCtx *ctx = (KSPDefaultConvergedCtx*) ksp->cnvP;
414: if (ksp->converged != KSPDefaultConverged) return(0);
415: if (ctx->mininitialrtol) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot use KSPDefaultConvergedSetUIRNorm() and KSPDefaultConvergedSetUMIRNorm() together");
416: ctx->initialrtol = PETSC_TRUE;
417: return(0);
418: }
422: /*@
423: KSPDefaultConvergedSetUMIRNorm - makes the default convergence test use min(|| B*(b - A*(initial guess))||,|| B*b ||)
424: In the case of right preconditioner or if KSPSetNormType(ksp,KSP_NORM_UNPRECONDIITONED)
425: is used there is no B in the above formula. UMIRNorm is short for Use Minimum Initial Residual Norm.
427: Collective on KSP
429: Input Parameters:
430: . ksp - iterative context
432: Options Database:
433: . -ksp_converged_use_min_initial_residual_norm
435: Use KSPSetTolerances() to alter the defaults for rtol, abstol, dtol.
437: The precise values of reason are macros such as KSP_CONVERGED_RTOL, which
438: are defined in petscksp.h.
440: Level: intermediate
442: .keywords: KSP, default, convergence, residual
444: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSkipConverged(), KSPConvergedReason, KSPGetConvergedReason(), KSPDefaultConvergedSetUIRNorm()
445: @*/
446: PetscErrorCode KSPDefaultConvergedSetUMIRNorm(KSP ksp)
447: {
448: KSPDefaultConvergedCtx *ctx = (KSPDefaultConvergedCtx*) ksp->cnvP;
452: if (ksp->converged != KSPDefaultConverged) return(0);
453: if (ctx->initialrtol) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot use KSPDefaultConvergedSetUIRNorm() and KSPDefaultConvergedSetUMIRNorm() together");
454: ctx->mininitialrtol = PETSC_TRUE;
455: return(0);
456: }
460: /*@C
461: KSPDefaultConverged - Determines convergence of
462: the iterative solvers (default code).
464: Collective on KSP
466: Input Parameters:
467: + ksp - iterative context
468: . n - iteration number
469: . rnorm - 2-norm residual value (may be estimated)
470: - dummy - unused convergence context
472: reason is set to:
473: + positive - if the iteration has converged;
474: . negative - if residual norm exceeds divergence threshold;
475: - 0 - otherwise.
477: Notes:
478: KSPDefaultConverged() reaches convergence when
479: $ rnorm < MAX (rtol * rnorm_0, abstol);
480: Divergence is detected if
481: $ rnorm > dtol * rnorm_0,
483: where
484: + rtol = relative tolerance,
485: . abstol = absolute tolerance.
486: . dtol = divergence tolerance,
487: - rnorm_0 is the two norm of the right hand side. When initial guess is non-zero you
488: can call KSPDefaultConvergedSetUIRNorm() to use the norm of (b - A*(initial guess))
489: as the starting point for relative norm convergence testing.
491: Use KSPSetTolerances() to alter the defaults for rtol, abstol, dtol.
493: The precise values of reason are macros such as KSP_CONVERGED_RTOL, which
494: are defined in petscksp.h.
496: Level: intermediate
498: .keywords: KSP, default, convergence, residual
500: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSkipConverged(), KSPConvergedReason, KSPGetConvergedReason(),
501: KSPDefaultConvergedSetUIRNorm(), KSPDefaultConvergedSetUMIRNorm(), KSPDefaultConvergedCreate(), KSPDefaultConvergedDestroy()
502: @*/
503: PetscErrorCode KSPDefaultConverged(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *dummy)
504: {
505: PetscErrorCode ierr;
506: KSPDefaultConvergedCtx *ctx = (KSPDefaultConvergedCtx*) dummy;
507: KSPNormType normtype;
512: *reason = KSP_CONVERGED_ITERATING;
513:
514: KSPGetNormType(ksp,&normtype);
515: if (normtype == KSP_NORM_NO) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Use KSPSkipConverged() with KSPNormType of KSP_NORM_NO");
517: if (!ctx) SETERRQ(PETSC_ERR_ARG_NULL,"Convergence context must have been created with KSPDefaultConvergedCreate()");
518: if (!n) {
519: /* if user gives initial guess need to compute norm of b */
520: if (!ksp->guess_zero && !ctx->initialrtol) {
521: PetscReal snorm;
522: if (ksp->normtype == KSP_NORM_UNPRECONDITIONED || ksp->pc_side == PC_RIGHT) {
523: PetscInfo(ksp,"user has provided nonzero initial guess, computing 2-norm of RHS\n");
524: VecNorm(ksp->vec_rhs,NORM_2,&snorm); /* <- b'*b */
525: } else {
526: Vec z;
527: if (!ctx->work) {
528: VecDuplicate(ksp->vec_rhs,&ctx->work);
529: }
530: z = ctx->work;
531: KSP_PCApply(ksp,ksp->vec_rhs,z);
532: if (ksp->normtype == KSP_NORM_PRECONDITIONED) {
533: PetscInfo(ksp,"user has provided nonzero initial guess, computing 2-norm of preconditioned RHS\n");
534: VecNorm(z,NORM_2,&snorm); /* dp <- b'*B'*B*b */
535: } else if (ksp->normtype == KSP_NORM_NATURAL) {
536: PetscScalar norm;
537: PetscInfo(ksp,"user has provided nonzero initial guess, computing natural norm of RHS\n");
538: VecDot(ksp->vec_rhs,z,&norm);
539: snorm = sqrt(PetscAbsScalar(norm)); /* dp <- b'*B*b */
540: }
541: }
542: /* handle special case of zero RHS and nonzero guess */
543: if (!snorm) {
544: PetscInfo(ksp,"Special case, user has provided nonzero initial guess and zero RHS\n");
545: snorm = rnorm;
546: }
547: if (ctx->mininitialrtol) {
548: ksp->rnorm0 = PetscMin(snorm,rnorm);
549: } else {
550: ksp->rnorm0 = snorm;
551: }
552: } else {
553: ksp->rnorm0 = rnorm;
554: }
555: ksp->ttol = PetscMax(ksp->rtol*ksp->rnorm0,ksp->abstol);
556: }
558: if (n <= ksp->chknorm) return(0);
560: if (rnorm != rnorm) {
561: PetscInfo(ksp,"Linear solver has created a not a number (NaN) as the residual norm, declaring divergence \n");
562: *reason = KSP_DIVERGED_NAN;
563: } else if (rnorm <= ksp->ttol) {
564: if (rnorm < ksp->abstol) {
565: PetscInfo3(ksp,"Linear solver has converged. Residual norm %G is less than absolute tolerance %G at iteration %D\n",rnorm,ksp->abstol,n);
566: *reason = KSP_CONVERGED_ATOL;
567: } else {
568: if (ctx->initialrtol) {
569: 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);
570: } else {
571: 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);
572: }
573: *reason = KSP_CONVERGED_RTOL;
574: }
575: } else if (rnorm >= ksp->divtol*ksp->rnorm0) {
576: PetscInfo3(ksp,"Linear solver is diverging. Initial right hand size norm %G, current residual norm %G at iteration %D\n",ksp->rnorm0,rnorm,n);
577: *reason = KSP_DIVERGED_DTOL;
578: }
579: return(0);
580: }
584: /*@C
585: KSPDefaultConvergedDestroy - Frees the space used by the KSPDefaultConverged() function context
587: Collective on KSP
589: Input Parameters:
590: . ctx - convergence context
592: Level: intermediate
594: .keywords: KSP, default, convergence, residual
596: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSkipConverged(), KSPConvergedReason, KSPGetConvergedReason(),
597: KSPDefaultConvergedSetUIRNorm(), KSPDefaultConvergedSetUMIRNorm(), KSPDefaultConvergedCreate()
598: @*/
599: PetscErrorCode KSPDefaultConvergedDestroy(void *ctx)
600: {
601: PetscErrorCode ierr;
602: KSPDefaultConvergedCtx *cctx = (KSPDefaultConvergedCtx*) ctx;
605: if (cctx->work) {VecDestroy(cctx->work);}
606: PetscFree(cctx);
607: return(0);
608: }
612: /*
613: KSPDefaultBuildSolution - Default code to create/move the solution.
615: Input Parameters:
616: + ksp - iterative context
617: - v - pointer to the user's vector
619: Output Parameter:
620: . V - pointer to a vector containing the solution
622: Level: advanced
624: .keywords: KSP, build, solution, default
626: .seealso: KSPGetSolution(), KSPDefaultBuildResidual()
627: */
628: PetscErrorCode KSPDefaultBuildSolution(KSP ksp,Vec v,Vec *V)
629: {
632: if (ksp->pc_side == PC_RIGHT) {
633: if (ksp->pc) {
634: if (v) {KSP_PCApply(ksp,ksp->vec_sol,v); *V = v;}
635: else {SETERRQ(PETSC_ERR_SUP,"Not working with right preconditioner");}
636: } else {
637: if (v) {VecCopy(ksp->vec_sol,v); *V = v;}
638: else { *V = ksp->vec_sol;}
639: }
640: } else if (ksp->pc_side == PC_SYMMETRIC) {
641: if (ksp->pc) {
642: if (ksp->transpose_solve) SETERRQ(PETSC_ERR_SUP,"Not working with symmetric preconditioner and transpose solve");
643: if (v) {PCApplySymmetricRight(ksp->pc,ksp->vec_sol,v); *V = v;}
644: else {SETERRQ(PETSC_ERR_SUP,"Not working with symmetric preconditioner");}
645: } else {
646: if (v) {VecCopy(ksp->vec_sol,v); *V = v;}
647: else { *V = ksp->vec_sol;}
648: }
649: } else {
650: if (v) {VecCopy(ksp->vec_sol,v); *V = v;}
651: else { *V = ksp->vec_sol; }
652: }
653: return(0);
654: }
658: /*
659: KSPDefaultBuildResidual - Default code to compute the residual.
661: Input Parameters:
662: . ksp - iterative context
663: . t - pointer to temporary vector
664: . v - pointer to user vector
666: Output Parameter:
667: . V - pointer to a vector containing the residual
669: Level: advanced
671: .keywords: KSP, build, residual, default
673: .seealso: KSPDefaultBuildSolution()
674: */
675: PetscErrorCode KSPDefaultBuildResidual(KSP ksp,Vec t,Vec v,Vec *V)
676: {
678: MatStructure pflag;
679: Mat Amat,Pmat;
682: PCGetOperators(ksp->pc,&Amat,&Pmat,&pflag);
683: KSPBuildSolution(ksp,t,PETSC_NULL);
684: KSP_MatMult(ksp,Amat,t,v);
685: VecAYPX(v,-1.0,ksp->vec_rhs);
686: *V = v;
687: return(0);
688: }
692: /*@C
693: KSPGetVecs - Gets a number of work vectors.
695: Input Parameters:
696: + ksp - iterative context
697: . rightn - number of right work vectors
698: - leftn - number of left work vectors to allocate
700: Output Parameter:
701: + right - the array of vectors created
702: - left - the array of left vectors
704: Note: The right vector has as many elements as the matrix has columns. The left
705: vector has as many elements as the matrix has rows.
707: Level: advanced
709: .seealso: MatGetVecs()
711: @*/
712: PetscErrorCode KSPGetVecs(KSP ksp,PetscInt rightn, Vec **right,PetscInt leftn,Vec **left)
713: {
715: Vec vecr,vecl;
718: if (rightn) {
719: if (!right) SETERRQ(PETSC_ERR_ARG_INCOMP,"You asked for right vectors but did not pass a pointer to hold them");
720: if (ksp->vec_sol) vecr = ksp->vec_sol;
721: else {
722: Mat pmat;
723: PCGetOperators(ksp->pc,PETSC_NULL,&pmat,PETSC_NULL);
724: MatGetVecs(pmat,&vecr,PETSC_NULL);
725: }
726: VecDuplicateVecs(vecr,rightn,right);
727: if (!ksp->vec_sol) {
728: VecDestroy(vecr);
729: }
730: }
731: if (leftn) {
732: if (!left) SETERRQ(PETSC_ERR_ARG_INCOMP,"You asked for left vectors but did not pass a pointer to hold them");
733: if (ksp->vec_rhs) vecl = ksp->vec_rhs;
734: else {
735: Mat pmat;
736: PCGetOperators(ksp->pc,PETSC_NULL,&pmat,PETSC_NULL);
737: MatGetVecs(pmat,PETSC_NULL,&vecl);
738: }
739: VecDuplicateVecs(vecl,leftn,left);
740: if (!ksp->vec_rhs) {
741: VecDestroy(vecl);
742: }
743: }
744: return(0);
745: }
749: /*
750: KSPDefaultGetWork - Gets a number of work vectors.
752: Input Parameters:
753: . ksp - iterative context
754: . nw - number of work vectors to allocate
756: Notes:
757: Call this only if no work vectors have been allocated
758: */
759: PetscErrorCode KSPDefaultGetWork(KSP ksp,PetscInt nw)
760: {
764: if (ksp->work) {KSPDefaultFreeWork(ksp);}
765: ksp->nwork = nw;
766: KSPGetVecs(ksp,nw,&ksp->work,0,PETSC_NULL);
767: PetscLogObjectParents(ksp,nw,ksp->work);
768: return(0);
769: }
773: /*
774: KSPDefaultDestroy - Destroys a iterative context variable for methods with
775: no separate context. Preferred calling sequence KSPDestroy().
777: Input Parameter:
778: . ksp - the iterative context
779: */
780: PetscErrorCode KSPDefaultDestroy(KSP ksp)
781: {
786: /* free work vectors */
787: KSPDefaultFreeWork(ksp);
788: /* free private data structure */
789: PetscFree(ksp->data);
790: return(0);
791: }
795: /*@
796: KSPGetConvergedReason - Gets the reason the KSP iteration was stopped.
798: Not Collective
800: Input Parameter:
801: . ksp - the KSP context
803: Output Parameter:
804: . reason - negative value indicates diverged, positive value converged, see KSPConvergedReason
806: Possible values for reason:
807: + KSP_CONVERGED_RTOL (residual 2-norm decreased by a factor of rtol, from 2-norm of right hand side)
808: . KSP_CONVERGED_ATOL (residual 2-norm less than abstol)
809: . KSP_CONVERGED_ITS (used by the preonly preconditioner that always uses ONE iteration)
810: . KSP_CONVERGED_QCG_NEG_CURVE
811: . KSP_CONVERGED_QCG_CONSTRAINED
812: . KSP_CONVERGED_STEP_LENGTH
813: . KSP_DIVERGED_ITS (required more than its to reach convergence)
814: . KSP_DIVERGED_DTOL (residual norm increased by a factor of divtol)
815: . KSP_DIVERGED_NAN (residual norm became Not-a-number likely do to 0/0)
816: . KSP_DIVERGED_BREAKDOWN (generic breakdown in method)
817: - KSP_DIVERGED_BREAKDOWN_BICG (Initial residual is orthogonal to preconditioned initial
818: residual. Try a different preconditioner, or a different initial guess.)
819:
821: Level: beginner
823: Notes: Can only be called after the call the KSPSolve() is complete.
825: .keywords: KSP, nonlinear, set, convergence, test
827: .seealso: KSPSetConvergenceTest(), KSPDefaultConverged(), KSPSetTolerances(), KSPConvergedReason
828: @*/
829: PetscErrorCode KSPGetConvergedReason(KSP ksp,KSPConvergedReason *reason)
830: {
834: *reason = ksp->reason;
835: return(0);
836: }