Actual source code: iterativ.c
petsc-main 2021-03-07
1: /*
2: This file contains some simple default routines.
3: These routines should be SHORT, since they will be included in every
4: executable image that uses the iterative routines (note that, through
5: the registry system, we provide a way to load only the truly necessary
6: files)
7: */
8: #include <petsc/private/kspimpl.h>
9: #include <petscdmshell.h>
10: #include <petscdraw.h>
12: /*@
13: KSPGetResidualNorm - Gets the last (approximate preconditioned)
14: residual norm that has been computed.
16: Not Collective
18: Input Parameters:
19: . ksp - the iterative context
21: Output Parameters:
22: . rnorm - residual norm
24: Level: intermediate
26: .seealso: KSPBuildResidual()
27: @*/
28: PetscErrorCode KSPGetResidualNorm(KSP ksp,PetscReal *rnorm)
29: {
33: *rnorm = ksp->rnorm;
34: return(0);
35: }
37: /*@
38: KSPGetIterationNumber - Gets the current iteration number; if the
39: KSPSolve() is complete, returns the number of iterations
40: used.
42: Not Collective
44: Input Parameters:
45: . ksp - the iterative context
47: Output Parameters:
48: . its - number of iterations
50: Level: intermediate
52: Notes:
53: During the ith iteration this returns i-1
54: .seealso: KSPBuildResidual(), KSPGetResidualNorm(), KSPGetTotalIterations()
55: @*/
56: PetscErrorCode KSPGetIterationNumber(KSP ksp,PetscInt *its)
57: {
61: *its = ksp->its;
62: return(0);
63: }
65: /*@
66: KSPGetTotalIterations - Gets the total number of iterations this KSP object has performed since was created, counted over all linear solves
68: Not Collective
70: Input Parameters:
71: . ksp - the iterative context
73: Output Parameters:
74: . its - total number of iterations
76: Level: intermediate
78: Notes:
79: Use KSPGetIterationNumber() to get the count for the most recent solve only
80: If this is called within a linear solve (such as in a KSPMonitor routine) then it does not include iterations within that current solve
82: .seealso: KSPBuildResidual(), KSPGetResidualNorm(), KSPGetIterationNumber()
83: @*/
84: PetscErrorCode KSPGetTotalIterations(KSP ksp,PetscInt *its)
85: {
89: *its = ksp->totalits;
90: return(0);
91: }
93: /*@C
94: KSPMonitorResidual - Print the preconditioned residual norm at each iteration of an iterative solver.
96: Collective on ksp
98: Input Parameters:
99: + ksp - iterative context
100: . n - iteration number
101: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
102: - vf - The viewer context
104: Options Database Key:
105: . -ksp_monitor - Activates KSPMonitorResidual()
107: Level: intermediate
109: .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
110: @*/
111: PetscErrorCode KSPMonitorResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
112: {
113: PetscViewer viewer = vf->viewer;
114: PetscViewerFormat format = vf->format;
115: PetscInt tablevel;
116: const char *prefix;
117: PetscErrorCode ierr;
121: PetscObjectGetTabLevel((PetscObject) ksp, &tablevel);
122: PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);
123: PetscViewerPushFormat(viewer, format);
124: PetscViewerASCIIAddTab(viewer, tablevel);
125: if (n == 0 && prefix) {PetscViewerASCIIPrintf(viewer, " Residual norms for %s solve.\n", prefix);}
126: PetscViewerASCIIPrintf(viewer, "%3D KSP Residual norm %14.12e \n", n, (double) rnorm);
127: PetscViewerASCIISubtractTab(viewer, tablevel);
128: PetscViewerPopFormat(viewer);
129: return(0);
130: }
132: /*@C
133: KSPMonitorResidualDraw - Plots the preconditioned residual at each iteration of an iterative solver.
135: Collective on ksp
137: Input Parameters:
138: + ksp - iterative context
139: . n - iteration number
140: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
141: - vf - The viewer context
143: Options Database Key:
144: . -ksp_monitor draw - Activates KSPMonitorResidualDraw()
146: Level: intermediate
148: .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
149: @*/
150: PetscErrorCode KSPMonitorResidualDraw(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
151: {
152: PetscViewer viewer = vf->viewer;
153: PetscViewerFormat format = vf->format;
154: Vec r;
155: PetscErrorCode ierr;
159: PetscViewerPushFormat(viewer, format);
160: KSPBuildResidual(ksp, NULL, NULL, &r);
161: PetscObjectSetName((PetscObject) r, "Residual");
162: PetscObjectCompose((PetscObject) r, "__Vec_bc_zero__", (PetscObject) ksp);
163: VecView(r, viewer);
164: PetscObjectCompose((PetscObject) r, "__Vec_bc_zero__", NULL);
165: VecDestroy(&r);
166: PetscViewerPopFormat(viewer);
167: return(0);
168: }
170: /*@C
171: KSPMonitorResidualDrawLG - Plots the preconditioned residual norm at each iteration of an iterative solver.
173: Collective on ksp
175: Input Parameters:
176: + ksp - iterative context
177: . n - iteration number
178: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
179: - vf - The viewer context
181: Options Database Key:
182: . -ksp_monitor draw::draw_lg - Activates KSPMonitorResidualDrawLG()
184: Level: intermediate
186: .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
187: @*/
188: PetscErrorCode KSPMonitorResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
189: {
190: PetscViewer viewer = vf->viewer;
191: PetscViewerFormat format = vf->format;
192: PetscDrawLG lg = vf->lg;
193: KSPConvergedReason reason;
194: PetscReal x, y;
195: PetscErrorCode ierr;
200: PetscViewerPushFormat(viewer, format);
201: if (!n) {PetscDrawLGReset(lg);}
202: x = (PetscReal) n;
203: if (rnorm > 0.0) y = PetscLog10Real(rnorm);
204: else y = -15.0;
205: PetscDrawLGAddPoint(lg, &x, &y);
206: KSPGetConvergedReason(ksp, &reason);
207: if (n <= 20 || !(n % 5) || reason) {
208: PetscDrawLGDraw(lg);
209: PetscDrawLGSave(lg);
210: }
211: PetscViewerPopFormat(viewer);
212: return(0);
213: }
215: /*@C
216: KSPMonitorResidualDrawLGCreate - Creates the plotter for the preconditioned residual.
218: Collective on ksp
220: Input Parameters:
221: + viewer - The PetscViewer
222: . format - The viewer format
223: - ctx - An optional user context
225: Output Parameter:
226: . vf - The viewer context
228: Level: intermediate
230: .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
231: @*/
232: PetscErrorCode KSPMonitorResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
233: {
237: PetscViewerAndFormatCreate(viewer, format, vf);
238: (*vf)->data = ctx;
239: KSPMonitorLGCreate(PetscObjectComm((PetscObject) viewer), NULL, NULL, "Log Residual Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg);
240: return(0);
241: }
243: /*
244: This is the same as KSPMonitorResidual() except it prints fewer digits of the residual as the residual gets smaller.
245: This is because the later digits are meaningless and are often different on different machines; by using this routine different
246: machines will usually generate the same output.
248: Deprecated: Intentionally has no manual page
249: */
250: PetscErrorCode KSPMonitorResidualShort(KSP ksp, PetscInt its, PetscReal fnorm, PetscViewerAndFormat *vf)
251: {
252: PetscViewer viewer = vf->viewer;
253: PetscViewerFormat format = vf->format;
254: PetscInt tablevel;
255: const char *prefix;
256: PetscErrorCode ierr;
260: PetscObjectGetTabLevel((PetscObject) ksp, &tablevel);
261: PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);
262: PetscViewerPushFormat(viewer, format);
263: PetscViewerASCIIAddTab(viewer, tablevel);
264: if (its == 0 && prefix) {PetscViewerASCIIPrintf(viewer, " Residual norms for %s solve.\n", prefix);}
265: if (fnorm > 1.e-9) {PetscViewerASCIIPrintf(viewer, "%3D KSP Residual norm %g \n", its, (double) fnorm);}
266: else if (fnorm > 1.e-11) {PetscViewerASCIIPrintf(viewer, "%3D KSP Residual norm %5.3e \n", its, (double) fnorm);}
267: else {PetscViewerASCIIPrintf(viewer, "%3D KSP Residual norm < 1.e-11\n", its);}
268: PetscViewerASCIISubtractTab(viewer, tablevel);
269: PetscViewerPopFormat(viewer);
270: return(0);
271: }
273: PetscErrorCode KSPMonitorRange_Private(KSP ksp, PetscInt it, PetscReal *per)
274: {
275: Vec resid;
276: const PetscScalar *r;
277: PetscReal rmax, pwork;
278: PetscInt i, n, N;
279: PetscErrorCode ierr;
282: KSPBuildResidual(ksp, NULL, NULL, &resid);
283: VecNorm(resid, NORM_INFINITY, &rmax);
284: VecGetLocalSize(resid, &n);
285: VecGetSize(resid, &N);
286: VecGetArrayRead(resid, &r);
287: pwork = 0.0;
288: for (i = 0; i < n; ++i) pwork += (PetscAbsScalar(r[i]) > .20*rmax);
289: VecRestoreArrayRead(resid, &r);
290: VecDestroy(&resid);
291: MPIU_Allreduce(&pwork, per, 1, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject) ksp));
292: *per = *per/N;
293: return(0);
294: }
296: /*@C
297: KSPMonitorResidualRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
299: Collective on ksp
301: Input Parameters:
302: + ksp - iterative context
303: . it - iteration number
304: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
305: - vf - The viewer context
307: Options Database Key:
308: . -ksp_monitor_range - Activates KSPMonitorResidualRange()
310: Level: intermediate
312: .seealso: KSPMonitorSet(), KSPMonitorResidual()
313: @*/
314: PetscErrorCode KSPMonitorResidualRange(KSP ksp, PetscInt it, PetscReal rnorm, PetscViewerAndFormat *vf)
315: {
316: static PetscReal prev;
317: PetscViewer viewer = vf->viewer;
318: PetscViewerFormat format = vf->format;
319: PetscInt tablevel;
320: const char *prefix;
321: PetscReal perc, rel;
322: PetscErrorCode ierr;
326: PetscObjectGetTabLevel((PetscObject) ksp, &tablevel);
327: PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);
328: PetscViewerPushFormat(viewer, format);
329: PetscViewerASCIIAddTab(viewer, tablevel);
330: if (!it) prev = rnorm;
331: if (it == 0 && prefix) {PetscViewerASCIIPrintf(viewer, " Residual norms for %s solve.\n", prefix);}
332: KSPMonitorRange_Private(ksp, it, &perc);
333: rel = (prev - rnorm)/prev;
334: prev = rnorm;
335: PetscViewerASCIIPrintf(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, (double) rnorm, (double) (100.0*perc), (double) rel, (double) (rel/perc));
336: PetscViewerASCIISubtractTab(viewer, tablevel);
337: PetscViewerPopFormat(viewer);
338: return(0);
339: }
341: /*@C
342: KSPMonitorTrueResidual - Prints the true residual norm, as well as the preconditioned residual norm, at each iteration of an iterative solver.
344: Collective on ksp
346: Input Parameters:
347: + ksp - iterative context
348: . n - iteration number
349: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
350: - vf - The viewer context
352: Options Database Key:
353: . -ksp_monitor_true_residual - Activates KSPMonitorTrueResidual()
355: Notes:
356: When using right preconditioning, these values are equivalent.
358: Level: intermediate
360: .seealso: KSPMonitorSet(), KSPMonitorResidual(),KSPMonitorTrueResidualMaxNorm()
361: @*/
362: PetscErrorCode KSPMonitorTrueResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
363: {
364: PetscViewer viewer = vf->viewer;
365: PetscViewerFormat format = vf->format;
366: Vec r;
367: PetscReal truenorm, bnorm;
368: char normtype[256];
369: PetscInt tablevel;
370: const char *prefix;
371: PetscErrorCode ierr;
375: PetscObjectGetTabLevel((PetscObject) ksp, &tablevel);
376: PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);
377: PetscStrncpy(normtype, KSPNormTypes[ksp->normtype], sizeof(normtype));
378: PetscStrtolower(normtype);
379: KSPBuildResidual(ksp, NULL, NULL, &r);
380: VecNorm(r, NORM_2, &truenorm);
381: VecNorm(ksp->vec_rhs, NORM_2, &bnorm);
382: VecDestroy(&r);
384: PetscViewerPushFormat(viewer, format);
385: PetscViewerASCIIAddTab(viewer, tablevel);
386: if (n == 0 && prefix) {PetscViewerASCIIPrintf(viewer, " Residual norms for %s solve.\n", prefix);}
387: PetscViewerASCIIPrintf(viewer, "%3D KSP %s resid norm %14.12e true resid norm %14.12e ||r(i)||/||b|| %14.12e\n", n, normtype, (double) rnorm, (double) truenorm, (double) (truenorm/bnorm));
388: PetscViewerASCIISubtractTab(viewer, tablevel);
389: PetscViewerPopFormat(viewer);
390: return(0);
391: }
393: /*@C
394: KSPMonitorTrueResidualDraw - Plots the true residual at each iteration of an iterative solver.
396: Collective on ksp
398: Input Parameters:
399: + ksp - iterative context
400: . n - iteration number
401: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
402: - vf - The viewer context
404: Options Database Key:
405: . -ksp_monitor_true_residual draw - Activates KSPMonitorResidualDraw()
407: Level: intermediate
409: .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
410: @*/
411: PetscErrorCode KSPMonitorTrueResidualDraw(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
412: {
413: PetscViewer viewer = vf->viewer;
414: PetscViewerFormat format = vf->format;
415: Vec r;
416: PetscErrorCode ierr;
420: PetscViewerPushFormat(viewer, format);
421: KSPBuildResidual(ksp, NULL, NULL, &r);
422: PetscObjectSetName((PetscObject) r, "Residual");
423: PetscObjectCompose((PetscObject) r, "__Vec_bc_zero__", (PetscObject) ksp);
424: VecView(r, viewer);
425: PetscObjectCompose((PetscObject) r, "__Vec_bc_zero__", NULL);
426: VecDestroy(&r);
427: PetscViewerPopFormat(viewer);
428: return(0);
429: }
431: /*@C
432: KSPMonitorTrueResidualDrawLG - Plots the true residual norm at each iteration of an iterative solver.
434: Collective on ksp
436: Input Parameters:
437: + ksp - iterative context
438: . n - iteration number
439: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
440: - vf - The viewer context
442: Options Database Key:
443: . -ksp_monitor_true_residual draw::draw_lg - Activates KSPMonitorTrueResidualDrawLG()
445: Level: intermediate
447: .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
448: @*/
449: PetscErrorCode KSPMonitorTrueResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
450: {
451: PetscViewer viewer = vf->viewer;
452: PetscViewerFormat format = vf->format;
453: PetscDrawLG lg = vf->lg;
454: Vec r;
455: KSPConvergedReason reason;
456: PetscReal truenorm, x[2], y[2];
457: PetscErrorCode ierr;
462: KSPBuildResidual(ksp, NULL, NULL, &r);
463: VecNorm(r, NORM_2, &truenorm);
464: VecDestroy(&r);
465: PetscViewerPushFormat(viewer, format);
466: if (!n) {PetscDrawLGReset(lg);}
467: x[0] = (PetscReal) n;
468: if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
469: else y[0] = -15.0;
470: x[1] = (PetscReal) n;
471: if (truenorm > 0.0) y[1] = PetscLog10Real(truenorm);
472: else y[1] = -15.0;
473: PetscDrawLGAddPoint(lg, x, y);
474: KSPGetConvergedReason(ksp, &reason);
475: if (n <= 20 || !(n % 5) || reason) {
476: PetscDrawLGDraw(lg);
477: PetscDrawLGSave(lg);
478: }
479: PetscViewerPopFormat(viewer);
480: return(0);
481: }
483: /*@C
484: KSPMonitorTrueResidualDrawLGCreate - Creates the plotter for the preconditioned residual.
486: Collective on ksp
488: Input Parameters:
489: + viewer - The PetscViewer
490: . format - The viewer format
491: - ctx - An optional user context
493: Output Parameter:
494: . vf - The viewer context
496: Level: intermediate
498: .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
499: @*/
500: PetscErrorCode KSPMonitorTrueResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
501: {
502: const char *names[] = {"preconditioned", "true"};
506: PetscViewerAndFormatCreate(viewer, format, vf);
507: (*vf)->data = ctx;
508: KSPMonitorLGCreate(PetscObjectComm((PetscObject) viewer), NULL, NULL, "Log Residual Norm", 2, names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg);
509: return(0);
510: }
512: /*@C
513: KSPMonitorTrueResidualMax - Prints the true residual max norm at each iteration of an iterative solver.
515: Collective on ksp
517: Input Parameters:
518: + ksp - iterative context
519: . n - iteration number
520: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
521: - vf - The viewer context
523: Options Database Key:
524: . -ksp_monitor_true_residual_max - Activates KSPMonitorTrueResidualMax()
526: Notes:
527: When using right preconditioning, these values are equivalent.
529: Level: intermediate
531: .seealso: KSPMonitorSet(), KSPMonitorResidual(),KSPMonitorTrueResidualMaxNorm()
532: @*/
533: PetscErrorCode KSPMonitorTrueResidualMax(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
534: {
535: PetscViewer viewer = vf->viewer;
536: PetscViewerFormat format = vf->format;
537: Vec r;
538: PetscReal truenorm, bnorm;
539: char normtype[256];
540: PetscInt tablevel;
541: const char *prefix;
542: PetscErrorCode ierr;
546: PetscObjectGetTabLevel((PetscObject) ksp, &tablevel);
547: PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);
548: PetscStrncpy(normtype, KSPNormTypes[ksp->normtype], sizeof(normtype));
549: PetscStrtolower(normtype);
550: KSPBuildResidual(ksp, NULL, NULL, &r);
551: VecNorm(r, NORM_INFINITY, &truenorm);
552: VecNorm(ksp->vec_rhs, NORM_INFINITY, &bnorm);
553: VecDestroy(&r);
555: PetscViewerPushFormat(viewer, format);
556: PetscViewerASCIIAddTab(viewer, tablevel);
557: if (n == 0 && prefix) {PetscViewerASCIIPrintf(viewer, " Residual norms for %s solve.\n", prefix);}
558: PetscViewerASCIIPrintf(viewer, "%3D KSP %s true resid max norm %14.12e ||r(i)||/||b|| %14.12e\n", n, normtype, (double) truenorm, (double) (truenorm/bnorm));
559: PetscViewerASCIISubtractTab(viewer, tablevel);
560: PetscViewerPopFormat(viewer);
561: return(0);
562: }
564: /*@C
565: KSPMonitorError - Prints the error norm, as well as the preconditioned residual norm, at each iteration of an iterative solver.
567: Collective on ksp
569: Input Parameters:
570: + ksp - iterative context
571: . n - iteration number
572: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
573: - vf - The viewer context
575: Options Database Key:
576: . -ksp_monitor_error - Activates KSPMonitorError()
578: Level: intermediate
580: .seealso: KSPMonitorSet(), KSPMonitorResidual(),KSPMonitorTrueResidualMaxNorm()
581: @*/
582: PetscErrorCode KSPMonitorError(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
583: {
584: PetscViewer viewer = vf->viewer;
585: PetscViewerFormat format = vf->format;
586: DM dm;
587: Vec sol;
588: PetscReal *errors;
589: PetscInt Nf, f;
590: PetscInt tablevel;
591: const char *prefix;
592: PetscErrorCode ierr;
596: PetscObjectGetTabLevel((PetscObject) ksp, &tablevel);
597: PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);
598: KSPGetDM(ksp, &dm);
599: DMGetNumFields(dm, &Nf);
600: DMGetGlobalVector(dm, &sol);
601: KSPBuildSolution(ksp, sol, NULL);
602: /* TODO: Make a different monitor that flips sign for SNES, Newton system is A dx = -b, so we need to negate the solution */
603: VecScale(sol, -1.0);
604: PetscCalloc1(Nf, &errors);
605: DMComputeError(dm, sol, errors, NULL);
607: PetscViewerPushFormat(viewer, format);
608: PetscViewerASCIIAddTab(viewer, tablevel);
609: if (n == 0 && prefix) {PetscViewerASCIIPrintf(viewer, " Error norms for %s solve.\n", prefix);}
610: PetscViewerASCIIPrintf(viewer, "%3D KSP Error norm %s", n, Nf > 1 ? "[" : "");
611: PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);
612: for (f = 0; f < Nf; ++f) {
613: if (f > 0) {PetscViewerASCIIPrintf(viewer, ", ");}
614: PetscViewerASCIIPrintf(viewer, "%14.12e", (double) errors[f]);
615: }
616: PetscViewerASCIIPrintf(viewer, "%s resid norm %14.12e\n", Nf > 1 ? "]" : "", (double) rnorm);
617: PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);
618: PetscViewerASCIISubtractTab(viewer, tablevel);
619: PetscViewerPopFormat(viewer);
620: DMRestoreGlobalVector(dm, &sol);
621: return(0);
622: }
624: /*@C
625: KSPMonitorErrorDraw - Plots the error at each iteration of an iterative solver.
627: Collective on ksp
629: Input Parameters:
630: + ksp - iterative context
631: . n - iteration number
632: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
633: - vf - The viewer context
635: Options Database Key:
636: . -ksp_monitor_error draw - Activates KSPMonitorErrorDraw()
638: Level: intermediate
640: .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
641: @*/
642: PetscErrorCode KSPMonitorErrorDraw(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
643: {
644: PetscViewer viewer = vf->viewer;
645: PetscViewerFormat format = vf->format;
646: DM dm;
647: Vec sol, e;
648: PetscErrorCode ierr;
652: PetscViewerPushFormat(viewer, format);
653: KSPGetDM(ksp, &dm);
654: DMGetGlobalVector(dm, &sol);
655: KSPBuildSolution(ksp, sol, NULL);
656: DMComputeError(dm, sol, NULL, &e);
657: PetscObjectSetName((PetscObject) e, "Error");
658: PetscObjectCompose((PetscObject) e, "__Vec_bc_zero__", (PetscObject) ksp);
659: VecView(e, viewer);
660: PetscObjectCompose((PetscObject) e, "__Vec_bc_zero__", NULL);
661: VecDestroy(&e);
662: DMRestoreGlobalVector(dm, &sol);
663: PetscViewerPopFormat(viewer);
664: return(0);
665: }
667: /*@C
668: KSPMonitorErrorDrawLG - Plots the error and residual norm at each iteration of an iterative solver.
670: Collective on ksp
672: Input Parameters:
673: + ksp - iterative context
674: . n - iteration number
675: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
676: - vf - The viewer context
678: Options Database Key:
679: . -ksp_monitor_error draw::draw_lg - Activates KSPMonitorTrueResidualDrawLG()
681: Level: intermediate
683: .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
684: @*/
685: PetscErrorCode KSPMonitorErrorDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
686: {
687: PetscViewer viewer = vf->viewer;
688: PetscViewerFormat format = vf->format;
689: PetscDrawLG lg = vf->lg;
690: DM dm;
691: Vec sol;
692: KSPConvergedReason reason;
693: PetscReal *x, *errors;
694: PetscInt Nf, f;
695: PetscErrorCode ierr;
700: KSPGetDM(ksp, &dm);
701: DMGetNumFields(dm, &Nf);
702: DMGetGlobalVector(dm, &sol);
703: KSPBuildSolution(ksp, sol, NULL);
704: /* TODO: Make a different monitor that flips sign for SNES, Newton system is A dx = -b, so we need to negate the solution */
705: VecScale(sol, -1.0);
706: PetscCalloc2(Nf+1, &x, Nf+1, &errors);
707: DMComputeError(dm, sol, errors, NULL);
709: PetscViewerPushFormat(viewer, format);
710: if (!n) {PetscDrawLGReset(lg);}
711: for (f = 0; f < Nf; ++f) {
712: x[f] = (PetscReal) n;
713: errors[f] = errors[f] > 0.0 ? PetscLog10Real(errors[f]) : -15.;
714: }
715: x[Nf] = (PetscReal) n;
716: errors[Nf] = rnorm > 0.0 ? PetscLog10Real(rnorm) : -15.;
717: PetscDrawLGAddPoint(lg, x, errors);
718: KSPGetConvergedReason(ksp, &reason);
719: if (n <= 20 || !(n % 5) || reason) {
720: PetscDrawLGDraw(lg);
721: PetscDrawLGSave(lg);
722: }
723: PetscViewerPopFormat(viewer);
724: return(0);
725: }
727: /*@C
728: KSPMonitorErrorDrawLGCreate - Creates the plotter for the error and preconditioned residual.
730: Collective on ksp
732: Input Parameters:
733: + viewer - The PetscViewer
734: . format - The viewer format
735: - ctx - An optional user context
737: Output Parameter:
738: . vf - The viewer context
740: Level: intermediate
742: .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
743: @*/
744: PetscErrorCode KSPMonitorErrorDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
745: {
746: KSP ksp = (KSP) ctx;
747: DM dm;
748: char **names;
749: PetscInt Nf, f;
753: KSPGetDM(ksp, &dm);
754: DMGetNumFields(dm, &Nf);
755: PetscMalloc1(Nf+1, &names);
756: for (f = 0; f < Nf; ++f) {
757: PetscObject disc;
758: const char *fname;
759: char lname[PETSC_MAX_PATH_LEN];
761: DMGetField(dm, f, NULL, &disc);
762: PetscObjectGetName(disc, &fname);
763: PetscStrncpy(lname, fname, PETSC_MAX_PATH_LEN);
764: PetscStrlcat(lname, " Error", PETSC_MAX_PATH_LEN);
765: PetscStrallocpy(lname, &names[f]);
766: }
767: PetscStrallocpy("residual", &names[Nf]);
768: PetscViewerAndFormatCreate(viewer, format, vf);
769: (*vf)->data = ctx;
770: KSPMonitorLGCreate(PetscObjectComm((PetscObject) viewer), NULL, NULL, "Log Error Norm", Nf+1, (const char **) names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg);
771: for (f = 0; f <= Nf; ++f) {PetscFree(names[f]);}
772: PetscFree(names);
773: return(0);
774: }
776: /*@C
777: KSPMonitorSolution - Print the solution norm at each iteration of an iterative solver.
779: Collective on ksp
781: Input Parameters:
782: + ksp - iterative context
783: . n - iteration number
784: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
785: - vf - The viewer context
787: Options Database Key:
788: . -ksp_monitor_solution - Activates KSPMonitorSolution()
790: Level: intermediate
792: .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
793: @*/
794: PetscErrorCode KSPMonitorSolution(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
795: {
796: PetscViewer viewer = vf->viewer;
797: PetscViewerFormat format = vf->format;
798: Vec x;
799: PetscReal snorm;
800: PetscInt tablevel;
801: const char *prefix;
802: PetscErrorCode ierr;
806: KSPBuildSolution(ksp, NULL, &x);
807: VecNorm(x, NORM_2, &snorm);
808: PetscObjectGetTabLevel((PetscObject) ksp, &tablevel);
809: PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);
810: PetscViewerPushFormat(viewer, format);
811: PetscViewerASCIIAddTab(viewer, tablevel);
812: if (n == 0 && prefix) {PetscViewerASCIIPrintf(viewer, " Solution norms for %s solve.\n", prefix);}
813: PetscViewerASCIIPrintf(viewer, "%3D KSP Solution norm %14.12e \n", n, (double) snorm);
814: PetscViewerASCIISubtractTab(viewer, tablevel);
815: PetscViewerPopFormat(viewer);
816: return(0);
817: }
819: /*@C
820: KSPMonitorSolutionDraw - Plots the solution at each iteration of an iterative solver.
822: Collective on ksp
824: Input Parameters:
825: + ksp - iterative context
826: . n - iteration number
827: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
828: - vf - The viewer context
830: Options Database Key:
831: . -ksp_monitor_solution draw - Activates KSPMonitorSolutionDraw()
833: Level: intermediate
835: .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
836: @*/
837: PetscErrorCode KSPMonitorSolutionDraw(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
838: {
839: PetscViewer viewer = vf->viewer;
840: PetscViewerFormat format = vf->format;
841: Vec x;
842: PetscErrorCode ierr;
846: KSPBuildSolution(ksp, NULL, &x);
847: PetscViewerPushFormat(viewer, format);
848: PetscObjectSetName((PetscObject) x, "Solution");
849: PetscObjectCompose((PetscObject) x, "__Vec_bc_zero__", (PetscObject) ksp);
850: VecView(x, viewer);
851: PetscObjectCompose((PetscObject) x, "__Vec_bc_zero__", NULL);
852: PetscViewerPopFormat(viewer);
853: return(0);
854: }
856: /*@C
857: KSPMonitorSolutionDrawLG - Plots the solution norm at each iteration of an iterative solver.
859: Collective on ksp
861: Input Parameters:
862: + ksp - iterative context
863: . n - iteration number
864: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
865: - vf - The viewer context
867: Options Database Key:
868: . -ksp_monitor_solution draw::draw_lg - Activates KSPMonitorSolutionDrawLG()
870: Level: intermediate
872: .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
873: @*/
874: PetscErrorCode KSPMonitorSolutionDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
875: {
876: PetscViewer viewer = vf->viewer;
877: PetscViewerFormat format = vf->format;
878: PetscDrawLG lg = vf->lg;
879: Vec u;
880: KSPConvergedReason reason;
881: PetscReal snorm, x, y;
882: PetscErrorCode ierr;
887: KSPBuildSolution(ksp, NULL, &u);
888: VecNorm(u, NORM_2, &snorm);
889: PetscViewerPushFormat(viewer, format);
890: if (!n) {PetscDrawLGReset(lg);}
891: x = (PetscReal) n;
892: if (snorm > 0.0) y = PetscLog10Real(snorm);
893: else y = -15.0;
894: PetscDrawLGAddPoint(lg, &x, &y);
895: KSPGetConvergedReason(ksp, &reason);
896: if (n <= 20 || !(n % 5) || reason) {
897: PetscDrawLGDraw(lg);
898: PetscDrawLGSave(lg);
899: }
900: PetscViewerPopFormat(viewer);
901: return(0);
902: }
904: /*@C
905: KSPMonitorSolutionDrawLGCreate - Creates the plotter for the solution.
907: Collective on ksp
909: Input Parameters:
910: + viewer - The PetscViewer
911: . format - The viewer format
912: - ctx - An optional user context
914: Output Parameter:
915: . vf - The viewer context
917: Level: intermediate
919: .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
920: @*/
921: PetscErrorCode KSPMonitorSolutionDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
922: {
926: PetscViewerAndFormatCreate(viewer, format, vf);
927: (*vf)->data = ctx;
928: KSPMonitorLGCreate(PetscObjectComm((PetscObject) viewer), NULL, NULL, "Log Solution Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg);
929: return(0);
930: }
932: /*@C
933: KSPMonitorSingularValue - Prints the two norm of the true residual and estimation of the extreme singular values of the preconditioned problem at each iteration.
935: Logically Collective on ksp
937: Input Parameters:
938: + ksp - the iterative context
939: . n - the iteration
940: . rnorm - the two norm of the residual
941: - vf - The viewer context
943: Options Database Key:
944: . -ksp_monitor_singular_value - Activates KSPMonitorSingularValue()
946: Notes:
947: The CG solver uses the Lanczos technique for eigenvalue computation,
948: while GMRES uses the Arnoldi technique; other iterative methods do
949: not currently compute singular values.
951: Level: intermediate
953: .seealso: KSPComputeExtremeSingularValues()
954: @*/
955: PetscErrorCode KSPMonitorSingularValue(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
956: {
957: PetscViewer viewer = vf->viewer;
958: PetscViewerFormat format = vf->format;
959: PetscReal emin, emax;
960: PetscInt tablevel;
961: const char *prefix;
962: PetscErrorCode ierr;
967: PetscObjectGetTabLevel((PetscObject) ksp, &tablevel);
968: PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);
969: PetscViewerPushFormat(viewer, format);
970: PetscViewerASCIIAddTab(viewer, tablevel);
971: if (n == 0 && prefix) {PetscViewerASCIIPrintf(viewer, " Residual norms for %s solve.\n", prefix);}
972: if (!ksp->calc_sings) {
973: PetscViewerASCIIPrintf(viewer, "%3D KSP Residual norm %14.12e \n", n, (double) rnorm);
974: } else {
975: KSPComputeExtremeSingularValues(ksp, &emax, &emin);
976: PetscViewerASCIIPrintf(viewer, "%3D KSP Residual norm %14.12e %% max %14.12e min %14.12e max/min %14.12e\n", n, (double) rnorm, (double) emax, (double) emin, (double) (emax/emin));
977: }
978: PetscViewerASCIISubtractTab(viewer, tablevel);
979: PetscViewerPopFormat(viewer);
980: return(0);
981: }
983: /*@C
984: KSPMonitorSingularValueCreate - Creates the singular value monitor.
986: Collective on ksp
988: Input Parameters:
989: + viewer - The PetscViewer
990: . format - The viewer format
991: - ctx - An optional user context
993: Output Parameter:
994: . vf - The viewer context
996: Level: intermediate
998: .seealso: KSPMonitorSet(), KSPMonitorSingularValue()
999: @*/
1000: PetscErrorCode KSPMonitorSingularValueCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
1001: {
1002: KSP ksp = (KSP) ctx;
1006: PetscViewerAndFormatCreate(viewer, format, vf);
1007: (*vf)->data = ctx;
1008: KSPSetComputeSingularValues(ksp, PETSC_TRUE);
1009: return(0);
1010: }
1012: /*@C
1013: KSPMonitorDynamicTolerance - Recompute the inner tolerance in every outer iteration in an adaptive way.
1015: Collective on ksp
1017: Input Parameters:
1018: + ksp - iterative context
1019: . n - iteration number (not used)
1020: . fnorm - the current residual norm
1021: - dummy - some context as a C struct. fields:
1022: coef: a scaling coefficient. default 1.0. can be passed through
1023: -sub_ksp_dynamic_tolerance_param
1024: bnrm: norm of the right-hand side. store it to avoid repeated calculation
1026: Notes:
1027: This may be useful for a flexibly preconditioner Krylov method to
1028: control the accuracy of the inner solves needed to gaurantee the
1029: convergence of the outer iterations.
1031: Level: advanced
1033: .seealso: KSPMonitorDynamicToleranceDestroy()
1034: @*/
1035: PetscErrorCode KSPMonitorDynamicTolerance(KSP ksp,PetscInt its,PetscReal fnorm,void *dummy)
1036: {
1038: PC pc;
1039: PetscReal outer_rtol, outer_abstol, outer_dtol, inner_rtol;
1040: PetscInt outer_maxits,nksp,first,i;
1041: KSPDynTolCtx *scale = (KSPDynTolCtx*)dummy;
1042: KSP *subksp = NULL;
1043: KSP kspinner;
1044: PetscBool flg;
1047: KSPGetPC(ksp, &pc);
1049: /* compute inner_rtol */
1050: if (scale->bnrm < 0.0) {
1051: Vec b;
1052: KSPGetRhs(ksp, &b);
1053: VecNorm(b, NORM_2, &(scale->bnrm));
1054: }
1055: KSPGetTolerances(ksp, &outer_rtol, &outer_abstol, &outer_dtol, &outer_maxits);
1056: inner_rtol = PetscMin(scale->coef * scale->bnrm * outer_rtol / fnorm, 0.999);
1057: /*PetscPrintf(PETSC_COMM_WORLD, " Inner rtol = %g\n", (double)inner_rtol);*/
1059: /* if pc is ksp */
1060: PetscObjectTypeCompare((PetscObject)pc,PCKSP,&flg);
1061: if (flg) {
1062: PCKSPGetKSP(pc, &kspinner);
1063: KSPSetTolerances(kspinner, inner_rtol, outer_abstol, outer_dtol, outer_maxits);
1064: return(0);
1065: }
1067: /* if pc is bjacobi */
1068: PetscObjectTypeCompare((PetscObject)pc,PCBJACOBI,&flg);
1069: if (flg) {
1070: PCBJacobiGetSubKSP(pc, &nksp, &first, &subksp);
1071: if (subksp) {
1072: for (i=0; i<nksp; i++) {
1073: KSPSetTolerances(subksp[i], inner_rtol, outer_abstol, outer_dtol, outer_maxits);
1074: }
1075: return(0);
1076: }
1077: }
1079: /* if pc is deflation*/
1080: PetscObjectTypeCompare((PetscObject)pc,PCDEFLATION,&flg);
1081: if (flg) {
1082: PCDeflationGetCoarseKSP(pc,&kspinner);
1083: KSPSetTolerances(kspinner,inner_rtol,outer_abstol,outer_dtol,PETSC_DEFAULT);
1084: return(0);
1085: }
1087: /* todo: dynamic tolerance may apply to other types of pc too */
1088: return(0);
1089: }
1091: /*
1092: Destroy the dummy context used in KSPMonitorDynamicTolerance()
1093: */
1094: PetscErrorCode KSPMonitorDynamicToleranceDestroy(void **dummy)
1095: {
1099: PetscFree(*dummy);
1100: return(0);
1101: }
1103: /*@C
1104: KSPConvergedSkip - Convergence test that do not return as converged
1105: until the maximum number of iterations is reached.
1107: Collective on ksp
1109: Input Parameters:
1110: + ksp - iterative context
1111: . n - iteration number
1112: . rnorm - 2-norm residual value (may be estimated)
1113: - dummy - unused convergence context
1115: Returns:
1116: . reason - KSP_CONVERGED_ITERATING, KSP_CONVERGED_ITS
1118: Notes:
1119: This should be used as the convergence test with the option
1120: KSPSetNormType(ksp,KSP_NORM_NONE), since norms of the residual are
1121: not computed. Convergence is then declared after the maximum number
1122: of iterations have been reached. Useful when one is using CG or
1123: BiCGStab as a smoother.
1125: Level: advanced
1127: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPSetNormType()
1128: @*/
1129: PetscErrorCode KSPConvergedSkip(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *dummy)
1130: {
1134: *reason = KSP_CONVERGED_ITERATING;
1135: if (n >= ksp->max_it) *reason = KSP_CONVERGED_ITS;
1136: return(0);
1137: }
1140: /*@C
1141: KSPConvergedDefaultCreate - Creates and initializes the space used by the KSPConvergedDefault() function context
1143: Note Collective
1145: Output Parameter:
1146: . ctx - convergence context
1148: Level: intermediate
1150: .seealso: KSPConvergedDefault(), KSPConvergedDefaultDestroy(), KSPSetConvergenceTest(), KSPSetTolerances(),
1151: KSPConvergedSkip(), KSPConvergedReason, KSPGetConvergedReason(), KSPConvergedDefaultSetUIRNorm(), KSPConvergedDefaultSetUMIRNorm(), KSPConvergedDefaultSetConvergedMaxits()
1152: @*/
1153: PetscErrorCode KSPConvergedDefaultCreate(void **ctx)
1154: {
1155: PetscErrorCode ierr;
1156: KSPConvergedDefaultCtx *cctx;
1159: PetscNew(&cctx);
1160: *ctx = cctx;
1161: return(0);
1162: }
1164: /*@
1165: KSPConvergedDefaultSetUIRNorm - makes the default convergence test use || B*(b - A*(initial guess))||
1166: instead of || B*b ||. In the case of right preconditioner or if KSPSetNormType(ksp,KSP_NORM_UNPRECONDIITONED)
1167: is used there is no B in the above formula. UIRNorm is short for Use Initial Residual Norm.
1169: Collective on ksp
1171: Input Parameters:
1172: . ksp - iterative context
1174: Options Database:
1175: . -ksp_converged_use_initial_residual_norm
1177: Notes:
1178: Use KSPSetTolerances() to alter the defaults for rtol, abstol, dtol.
1180: The precise values of reason are macros such as KSP_CONVERGED_RTOL, which
1181: are defined in petscksp.h.
1183: If the convergence test is not KSPConvergedDefault() then this is ignored.
1185: If right preconditioning is being used then B does not appear in the above formula.
1188: Level: intermediate
1190: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPConvergedSkip(), KSPConvergedReason, KSPGetConvergedReason(), KSPConvergedDefaultSetUMIRNorm(), KSPConvergedDefaultSetConvergedMaxits()
1191: @*/
1192: PetscErrorCode KSPConvergedDefaultSetUIRNorm(KSP ksp)
1193: {
1194: KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx*) ksp->cnvP;
1198: if (ksp->converged != KSPConvergedDefault) return(0);
1199: if (ctx->mininitialrtol) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_WRONGSTATE,"Cannot use KSPConvergedDefaultSetUIRNorm() and KSPConvergedDefaultSetUMIRNorm() together");
1200: ctx->initialrtol = PETSC_TRUE;
1201: return(0);
1202: }
1204: /*@
1205: KSPConvergedDefaultSetUMIRNorm - makes the default convergence test use min(|| B*(b - A*(initial guess))||,|| B*b ||)
1206: In the case of right preconditioner or if KSPSetNormType(ksp,KSP_NORM_UNPRECONDIITONED)
1207: is used there is no B in the above formula. UMIRNorm is short for Use Minimum Initial Residual Norm.
1209: Collective on ksp
1211: Input Parameters:
1212: . ksp - iterative context
1214: Options Database:
1215: . -ksp_converged_use_min_initial_residual_norm
1217: Use KSPSetTolerances() to alter the defaults for rtol, abstol, dtol.
1219: The precise values of reason are macros such as KSP_CONVERGED_RTOL, which
1220: are defined in petscksp.h.
1222: Level: intermediate
1224: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPConvergedSkip(), KSPConvergedReason, KSPGetConvergedReason(), KSPConvergedDefaultSetUIRNorm(), KSPConvergedDefaultSetConvergedMaxits()
1225: @*/
1226: PetscErrorCode KSPConvergedDefaultSetUMIRNorm(KSP ksp)
1227: {
1228: KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx*) ksp->cnvP;
1232: if (ksp->converged != KSPConvergedDefault) return(0);
1233: if (ctx->initialrtol) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_WRONGSTATE,"Cannot use KSPConvergedDefaultSetUIRNorm() and KSPConvergedDefaultSetUMIRNorm() together");
1234: ctx->mininitialrtol = PETSC_TRUE;
1235: return(0);
1236: }
1238: /*@
1239: KSPConvergedDefaultSetConvergedMaxits - allows the default convergence test to declare convergence and return KSP_CONVERGED_ITS if the maximum number of iterations is reached
1241: Collective on ksp
1243: Input Parameters:
1244: + ksp - iterative context
1245: - flg - boolean flag
1247: Options Database:
1248: . -ksp_converged_maxits
1250: Use KSPSetTolerances() to alter the defaults for rtol, abstol, dtol.
1252: The precise values of reason are macros such as KSP_CONVERGED_RTOL, which
1253: are defined in petscksp.h.
1255: Level: intermediate
1257: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPConvergedSkip(), KSPConvergedReason, KSPGetConvergedReason(), KSPConvergedDefaultSetUMIRNorm(), KSPConvergedDefaultSetUIRNorm()
1258: @*/
1259: PetscErrorCode KSPConvergedDefaultSetConvergedMaxits(KSP ksp, PetscBool flg)
1260: {
1261: KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx*) ksp->cnvP;
1266: if (ksp->converged != KSPConvergedDefault) return(0);
1267: ctx->convmaxits = flg;
1268: return(0);
1269: }
1271: /*@C
1272: KSPConvergedDefault - Determines convergence of the linear iterative solvers by default
1274: Collective on ksp
1276: Input Parameters:
1277: + ksp - iterative context
1278: . n - iteration number
1279: . rnorm - residual norm (may be estimated, depending on the method may be the preconditioned residual norm)
1280: - ctx - convergence context which must be created by KSPConvergedDefaultCreate()
1282: Output Parameter:
1283: + positive - if the iteration has converged
1284: . negative - if the iteration has diverged
1285: - KSP_CONVERGED_ITERATING - otherwise.
1287: Notes:
1288: KSPConvergedDefault() reaches convergence when rnorm < MAX (rtol * rnorm_0, abstol);
1289: Divergence is detected if rnorm > dtol * rnorm_0, or when failures are detected throughout the iteration.
1290: By default, reaching the maximum number of iterations is considered divergence (i.e. KSP_DIVERGED_ITS).
1291: In order to have PETSc declaring convergence in such a case (i.e. KSP_CONVERGED_ITS), users can use KSPConvergedDefaultSetConvergedMaxits()
1293: where:
1294: + rtol = relative tolerance,
1295: . abstol = absolute tolerance.
1296: . dtol = divergence tolerance,
1297: - rnorm_0 is the two norm of the right hand side (or the preconditioned norm, depending on what was set with
1298: KSPSetNormType(). When initial guess is non-zero you
1299: can call KSPConvergedDefaultSetUIRNorm() to use the norm of (b - A*(initial guess))
1300: as the starting point for relative norm convergence testing, that is as rnorm_0
1302: Use KSPSetTolerances() to alter the defaults for rtol, abstol, dtol.
1304: Use KSPSetNormType() (or -ksp_norm_type <none,preconditioned,unpreconditioned,natural>) to change the norm used for computing rnorm
1306: The precise values of reason are macros such as KSP_CONVERGED_RTOL, which are defined in petscksp.h.
1308: This routine is used by KSP by default so the user generally never needs call it directly.
1310: Use KSPSetConvergenceTest() to provide your own test instead of using this one.
1312: Level: intermediate
1314: .seealso: KSPSetConvergenceTest(), KSPSetTolerances(), KSPConvergedSkip(), KSPConvergedReason, KSPGetConvergedReason(),
1315: KSPConvergedDefaultSetUIRNorm(), KSPConvergedDefaultSetUMIRNorm(), KSPConvergedDefaultSetConvergedMaxits(), KSPConvergedDefaultCreate(), KSPConvergedDefaultDestroy()
1316: @*/
1317: PetscErrorCode KSPConvergedDefault(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *ctx)
1318: {
1319: PetscErrorCode ierr;
1320: KSPConvergedDefaultCtx *cctx = (KSPConvergedDefaultCtx*) ctx;
1321: KSPNormType normtype;
1327: if (!cctx) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_NULL,"Convergence context must have been created with KSPConvergedDefaultCreate()");
1328: *reason = KSP_CONVERGED_ITERATING;
1330: if (cctx->convmaxits && n >= ksp->max_it) {
1331: *reason = KSP_CONVERGED_ITS;
1332: PetscInfo1(ksp,"Linear solver has converged. Maximum number of iterations reached %D\n",n);
1333: return(0);
1334: }
1335: KSPGetNormType(ksp,&normtype);
1336: if (normtype == KSP_NORM_NONE) return(0);
1338: if (!n) {
1339: /* if user gives initial guess need to compute norm of b */
1340: if (!ksp->guess_zero && !cctx->initialrtol) {
1341: PetscReal snorm = 0.0;
1342: if (ksp->normtype == KSP_NORM_UNPRECONDITIONED || ksp->pc_side == PC_RIGHT) {
1343: PetscInfo(ksp,"user has provided nonzero initial guess, computing 2-norm of RHS\n");
1344: VecNorm(ksp->vec_rhs,NORM_2,&snorm); /* <- b'*b */
1345: } else {
1346: Vec z;
1347: /* Should avoid allocating the z vector each time but cannot stash it in cctx because if KSPReset() is called the vector size might change */
1348: VecDuplicate(ksp->vec_rhs,&z);
1349: KSP_PCApply(ksp,ksp->vec_rhs,z);
1350: if (ksp->normtype == KSP_NORM_PRECONDITIONED) {
1351: PetscInfo(ksp,"user has provided nonzero initial guess, computing 2-norm of preconditioned RHS\n");
1352: VecNorm(z,NORM_2,&snorm); /* dp <- b'*B'*B*b */
1353: } else if (ksp->normtype == KSP_NORM_NATURAL) {
1354: PetscScalar norm;
1355: PetscInfo(ksp,"user has provided nonzero initial guess, computing natural norm of RHS\n");
1356: VecDot(ksp->vec_rhs,z,&norm);
1357: snorm = PetscSqrtReal(PetscAbsScalar(norm)); /* dp <- b'*B*b */
1358: }
1359: VecDestroy(&z);
1360: }
1361: /* handle special case of zero RHS and nonzero guess */
1362: if (!snorm) {
1363: PetscInfo(ksp,"Special case, user has provided nonzero initial guess and zero RHS\n");
1364: snorm = rnorm;
1365: }
1366: if (cctx->mininitialrtol) ksp->rnorm0 = PetscMin(snorm,rnorm);
1367: else ksp->rnorm0 = snorm;
1368: } else {
1369: ksp->rnorm0 = rnorm;
1370: }
1371: ksp->ttol = PetscMax(ksp->rtol*ksp->rnorm0,ksp->abstol);
1372: }
1374: if (n <= ksp->chknorm) return(0);
1376: if (PetscIsInfOrNanReal(rnorm)) {
1377: PCFailedReason pcreason;
1378: PetscInt sendbuf,recvbuf;
1379: PCGetFailedReasonRank(ksp->pc,&pcreason);
1380: sendbuf = (PetscInt)pcreason;
1381: MPI_Allreduce(&sendbuf,&recvbuf,1,MPIU_INT,MPIU_MAX,PetscObjectComm((PetscObject)ksp));
1382: if (recvbuf) {
1383: *reason = KSP_DIVERGED_PC_FAILED;
1384: PCSetFailedReason(ksp->pc,(PCFailedReason)recvbuf);
1385: PetscInfo(ksp,"Linear solver pcsetup fails, declaring divergence \n");
1386: } else {
1387: *reason = KSP_DIVERGED_NANORINF;
1388: PetscInfo(ksp,"Linear solver has created a not a number (NaN) as the residual norm, declaring divergence \n");
1389: }
1390: } else if (rnorm <= ksp->ttol) {
1391: if (rnorm < ksp->abstol) {
1392: PetscInfo3(ksp,"Linear solver has converged. Residual norm %14.12e is less than absolute tolerance %14.12e at iteration %D\n",(double)rnorm,(double)ksp->abstol,n);
1393: *reason = KSP_CONVERGED_ATOL;
1394: } else {
1395: if (cctx->initialrtol) {
1396: PetscInfo4(ksp,"Linear solver has converged. Residual norm %14.12e is less than relative tolerance %14.12e times initial residual norm %14.12e at iteration %D\n",(double)rnorm,(double)ksp->rtol,(double)ksp->rnorm0,n);
1397: } else {
1398: PetscInfo4(ksp,"Linear solver has converged. Residual norm %14.12e is less than relative tolerance %14.12e times initial right hand side norm %14.12e at iteration %D\n",(double)rnorm,(double)ksp->rtol,(double)ksp->rnorm0,n);
1399: }
1400: *reason = KSP_CONVERGED_RTOL;
1401: }
1402: } else if (rnorm >= ksp->divtol*ksp->rnorm0) {
1403: PetscInfo3(ksp,"Linear solver is diverging. Initial right hand size norm %14.12e, current residual norm %14.12e at iteration %D\n",(double)ksp->rnorm0,(double)rnorm,n);
1404: *reason = KSP_DIVERGED_DTOL;
1405: }
1406: return(0);
1407: }
1409: /*@C
1410: KSPConvergedDefaultDestroy - Frees the space used by the KSPConvergedDefault() function context
1412: Not Collective
1414: Input Parameters:
1415: . ctx - convergence context
1417: Level: intermediate
1419: .seealso: KSPConvergedDefault(), KSPConvergedDefaultCreate(), KSPSetConvergenceTest(), KSPSetTolerances(), KSPConvergedSkip(),
1420: KSPConvergedReason, KSPGetConvergedReason(), KSPConvergedDefaultSetUIRNorm(), KSPConvergedDefaultSetUMIRNorm()
1421: @*/
1422: PetscErrorCode KSPConvergedDefaultDestroy(void *ctx)
1423: {
1424: PetscErrorCode ierr;
1425: KSPConvergedDefaultCtx *cctx = (KSPConvergedDefaultCtx*) ctx;
1428: VecDestroy(&cctx->work);
1429: PetscFree(ctx);
1430: return(0);
1431: }
1433: /*
1434: KSPBuildSolutionDefault - Default code to create/move the solution.
1436: Collective on ksp
1438: Input Parameters:
1439: + ksp - iterative context
1440: - v - pointer to the user's vector
1442: Output Parameter:
1443: . V - pointer to a vector containing the solution
1445: Level: advanced
1447: Developers Note: This is PETSC_EXTERN because it may be used by user written plugin KSP implementations
1449: .seealso: KSPGetSolution(), KSPBuildResidualDefault()
1450: */
1451: PetscErrorCode KSPBuildSolutionDefault(KSP ksp,Vec v,Vec *V)
1452: {
1456: if (ksp->pc_side == PC_RIGHT) {
1457: if (ksp->pc) {
1458: if (v) {
1459: KSP_PCApply(ksp,ksp->vec_sol,v); *V = v;
1460: } else SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Not working with right preconditioner");
1461: } else {
1462: if (v) {
1463: VecCopy(ksp->vec_sol,v); *V = v;
1464: } else *V = ksp->vec_sol;
1465: }
1466: } else if (ksp->pc_side == PC_SYMMETRIC) {
1467: if (ksp->pc) {
1468: if (ksp->transpose_solve) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Not working with symmetric preconditioner and transpose solve");
1469: if (v) {
1470: PCApplySymmetricRight(ksp->pc,ksp->vec_sol,v);
1471: *V = v;
1472: } else SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Not working with symmetric preconditioner");
1473: } else {
1474: if (v) {
1475: VecCopy(ksp->vec_sol,v); *V = v;
1476: } else *V = ksp->vec_sol;
1477: }
1478: } else {
1479: if (v) {
1480: VecCopy(ksp->vec_sol,v); *V = v;
1481: } else *V = ksp->vec_sol;
1482: }
1483: return(0);
1484: }
1486: /*
1487: KSPBuildResidualDefault - Default code to compute the residual.
1489: Collecive on ksp
1491: Input Parameters:
1492: . ksp - iterative context
1493: . t - pointer to temporary vector
1494: . v - pointer to user vector
1496: Output Parameter:
1497: . V - pointer to a vector containing the residual
1499: Level: advanced
1501: Developers Note: This is PETSC_EXTERN because it may be used by user written plugin KSP implementations
1503: .seealso: KSPBuildSolutionDefault()
1504: */
1505: PetscErrorCode KSPBuildResidualDefault(KSP ksp,Vec t,Vec v,Vec *V)
1506: {
1508: Mat Amat,Pmat;
1511: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
1512: PCGetOperators(ksp->pc,&Amat,&Pmat);
1513: KSPBuildSolution(ksp,t,NULL);
1514: KSP_MatMult(ksp,Amat,t,v);
1515: VecAYPX(v,-1.0,ksp->vec_rhs);
1516: *V = v;
1517: return(0);
1518: }
1520: /*@C
1521: KSPCreateVecs - Gets a number of work vectors.
1523: Collective on ksp
1525: Input Parameters:
1526: + ksp - iterative context
1527: . rightn - number of right work vectors
1528: - leftn - number of left work vectors to allocate
1530: Output Parameter:
1531: + right - the array of vectors created
1532: - left - the array of left vectors
1534: Note: The right vector has as many elements as the matrix has columns. The left
1535: vector has as many elements as the matrix has rows.
1537: The vectors are new vectors that are not owned by the KSP, they should be destroyed with calls to VecDestroyVecs() when no longer needed.
1539: Developers Note: First tries to duplicate the rhs and solution vectors of the KSP, if they do not exist tries to get them from the matrix, if
1540: that does not exist tries to get them from the DM (if it is provided).
1542: Level: advanced
1544: .seealso: MatCreateVecs(), VecDestroyVecs()
1546: @*/
1547: PetscErrorCode KSPCreateVecs(KSP ksp,PetscInt rightn, Vec **right,PetscInt leftn,Vec **left)
1548: {
1550: Vec vecr = NULL,vecl = NULL;
1551: PetscBool matset,pmatset;
1552: Mat mat = NULL;
1555: if (rightn) {
1556: if (!right) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_INCOMP,"You asked for right vectors but did not pass a pointer to hold them");
1557: if (ksp->vec_sol) vecr = ksp->vec_sol;
1558: else {
1559: if (ksp->pc) {
1560: PCGetOperatorsSet(ksp->pc,&matset,&pmatset);
1561: /* check for mat before pmat because for KSPLSQR pmat may be a different size than mat since pmat maybe mat'*mat */
1562: if (matset) {
1563: PCGetOperators(ksp->pc,&mat,NULL);
1564: MatCreateVecs(mat,&vecr,NULL);
1565: } else if (pmatset) {
1566: PCGetOperators(ksp->pc,NULL,&mat);
1567: MatCreateVecs(mat,&vecr,NULL);
1568: }
1569: }
1570: if (!vecr) {
1571: if (ksp->dm) {
1572: DMGetGlobalVector(ksp->dm,&vecr);
1573: } else SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_WRONGSTATE,"You requested a vector from a KSP that cannot provide one");
1574: }
1575: }
1576: VecDuplicateVecs(vecr,rightn,right);
1577: if (!ksp->vec_sol) {
1578: if (mat) {
1579: VecDestroy(&vecr);
1580: } else if (ksp->dm) {
1581: DMRestoreGlobalVector(ksp->dm,&vecr);
1582: }
1583: }
1584: }
1585: if (leftn) {
1586: if (!left) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_INCOMP,"You asked for left vectors but did not pass a pointer to hold them");
1587: if (ksp->vec_rhs) vecl = ksp->vec_rhs;
1588: else {
1589: if (ksp->pc) {
1590: PCGetOperatorsSet(ksp->pc,&matset,&pmatset);
1591: /* check for mat before pmat because for KSPLSQR pmat may be a different size than mat since pmat maybe mat'*mat */
1592: if (matset) {
1593: PCGetOperators(ksp->pc,&mat,NULL);
1594: MatCreateVecs(mat,NULL,&vecl);
1595: } else if (pmatset) {
1596: PCGetOperators(ksp->pc,NULL,&mat);
1597: MatCreateVecs(mat,NULL,&vecl);
1598: }
1599: }
1600: if (!vecl) {
1601: if (ksp->dm) {
1602: DMGetGlobalVector(ksp->dm,&vecl);
1603: } else SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_WRONGSTATE,"You requested a vector from a KSP that cannot provide one");
1604: }
1605: }
1606: VecDuplicateVecs(vecl,leftn,left);
1607: if (!ksp->vec_rhs) {
1608: if (mat) {
1609: VecDestroy(&vecl);
1610: } else if (ksp->dm) {
1611: DMRestoreGlobalVector(ksp->dm,&vecl);
1612: }
1613: }
1614: }
1615: return(0);
1616: }
1618: /*@C
1619: KSPSetWorkVecs - Sets a number of work vectors into a KSP object
1621: Collective on ksp
1623: Input Parameters:
1624: + ksp - iterative context
1625: - nw - number of work vectors to allocate
1627: Level: developer
1629: Developers Note: This is PETSC_EXTERN because it may be used by user written plugin KSP implementations
1631: @*/
1632: PetscErrorCode KSPSetWorkVecs(KSP ksp,PetscInt nw)
1633: {
1637: VecDestroyVecs(ksp->nwork,&ksp->work);
1638: ksp->nwork = nw;
1639: KSPCreateVecs(ksp,nw,&ksp->work,0,NULL);
1640: PetscLogObjectParents(ksp,nw,ksp->work);
1641: return(0);
1642: }
1644: /*
1645: KSPDestroyDefault - Destroys a iterative context variable for methods with
1646: no separate context. Preferred calling sequence KSPDestroy().
1648: Input Parameter:
1649: . ksp - the iterative context
1651: Developers Note: This is PETSC_EXTERN because it may be used by user written plugin KSP implementations
1653: */
1654: PetscErrorCode KSPDestroyDefault(KSP ksp)
1655: {
1660: PetscFree(ksp->data);
1661: return(0);
1662: }
1664: /*@
1665: KSPGetConvergedReason - Gets the reason the KSP iteration was stopped.
1667: Not Collective
1669: Input Parameter:
1670: . ksp - the KSP context
1672: Output Parameter:
1673: . reason - negative value indicates diverged, positive value converged, see KSPConvergedReason
1675: Possible values for reason: See also manual page for each reason
1676: $ KSP_CONVERGED_RTOL (residual 2-norm decreased by a factor of rtol, from 2-norm of right hand side)
1677: $ KSP_CONVERGED_ATOL (residual 2-norm less than abstol)
1678: $ KSP_CONVERGED_ITS (used by the preonly preconditioner that always uses ONE iteration, or when the KSPConvergedSkip() convergence test routine is set.
1679: $ KSP_CONVERGED_CG_NEG_CURVE (see note below)
1680: $ KSP_CONVERGED_CG_CONSTRAINED (see note below)
1681: $ KSP_CONVERGED_STEP_LENGTH (see note below)
1682: $ KSP_CONVERGED_ITERATING (returned if the solver is not yet finished)
1683: $ KSP_DIVERGED_ITS (required more than its to reach convergence)
1684: $ KSP_DIVERGED_DTOL (residual norm increased by a factor of divtol)
1685: $ KSP_DIVERGED_NANORINF (residual norm became Not-a-number or Inf likely due to 0/0)
1686: $ KSP_DIVERGED_BREAKDOWN (generic breakdown in method)
1687: $ KSP_DIVERGED_BREAKDOWN_BICG (Initial residual is orthogonal to preconditioned initial residual. Try a different preconditioner, or a different initial Level.)
1689: Options Database:
1690: . -ksp_converged_reason - prints the reason to standard out
1692: Notes:
1693: If this routine is called before or doing the KSPSolve() the value of KSP_CONVERGED_ITERATING is returned
1695: The values KSP_CONVERGED_CG_NEG_CURVE, KSP_CONVERGED_CG_CONSTRAINED, and KSP_CONVERGED_STEP_LENGTH are returned only by the special KSPNASH, KSPSTCG, and KSPGLTR
1696: solvers which are used by the SNESNEWTONTR (trust region) solver.
1698: Level: intermediate
1700: .seealso: KSPSetConvergenceTest(), KSPConvergedDefault(), KSPSetTolerances(), KSPConvergedReason,
1701: KSPConvergedReasonView()
1702: @*/
1703: PetscErrorCode KSPGetConvergedReason(KSP ksp,KSPConvergedReason *reason)
1704: {
1708: *reason = ksp->reason;
1709: return(0);
1710: }
1712: /*@C
1713: KSPGetConvergedReasonString - Return a human readable string for ksp converged reason
1715: Not Collective
1717: Input Parameter:
1718: . ksp - the KSP context
1720: Output Parameter:
1721: . strreason - a human readable string that describes ksp converged reason
1723: Level: basic
1725: .seealso: KSPGetConvergedReason()
1726: @*/
1727: PetscErrorCode KSPGetConvergedReasonString(KSP ksp,const char** strreason)
1728: {
1732: *strreason = KSPConvergedReasons[ksp->reason];
1733: return(0);
1734: }
1736: #include <petsc/private/dmimpl.h>
1737: /*@
1738: KSPSetDM - Sets the DM that may be used by some preconditioners
1740: Logically Collective on ksp
1742: Input Parameters:
1743: + ksp - the preconditioner context
1744: - dm - the dm, cannot be NULL
1746: Notes:
1747: If this is used then the KSP will attempt to use the DM to create the matrix and use the routine set with
1748: DMKSPSetComputeOperators(). Use KSPSetDMActive(ksp,PETSC_FALSE) to instead use the matrix you've provided with
1749: KSPSetOperators().
1751: A DM can only be used for solving one problem at a time because information about the problem is stored on the DM,
1752: even when not using interfaces like DMKSPSetComputeOperators(). Use DMClone() to get a distinct DM when solving
1753: different problems using the same function space.
1755: Level: intermediate
1757: .seealso: KSPGetDM(), KSPSetDMActive(), KSPSetComputeOperators(), KSPSetComputeRHS(), KSPSetComputeInitialGuess(), DMKSPSetComputeOperators(), DMKSPSetComputeRHS(), DMKSPSetComputeInitialGuess()
1758: @*/
1759: PetscErrorCode KSPSetDM(KSP ksp,DM dm)
1760: {
1762: PC pc;
1767: PetscObjectReference((PetscObject)dm);
1768: if (ksp->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */
1769: if (ksp->dm->dmksp && !dm->dmksp) {
1770: DMKSP kdm;
1771: DMCopyDMKSP(ksp->dm,dm);
1772: DMGetDMKSP(ksp->dm,&kdm);
1773: if (kdm->originaldm == ksp->dm) kdm->originaldm = dm; /* Grant write privileges to the replacement DM */
1774: }
1775: DMDestroy(&ksp->dm);
1776: }
1777: ksp->dm = dm;
1778: ksp->dmAuto = PETSC_FALSE;
1779: KSPGetPC(ksp,&pc);
1780: PCSetDM(pc,dm);
1781: ksp->dmActive = PETSC_TRUE;
1782: return(0);
1783: }
1785: /*@
1786: KSPSetDMActive - Indicates the DM should be used to generate the linear system matrix and right hand side
1788: Logically Collective on ksp
1790: Input Parameters:
1791: + ksp - the preconditioner context
1792: - flg - use the DM
1794: Notes:
1795: By default KSPSetDM() sets the DM as active, call KSPSetDMActive(ksp,PETSC_FALSE); after KSPSetDM(ksp,dm) to not have the KSP object use the DM to generate the matrices.
1797: Level: intermediate
1799: .seealso: KSPGetDM(), KSPSetDM(), SNESSetDM(), KSPSetComputeOperators(), KSPSetComputeRHS(), KSPSetComputeInitialGuess()
1800: @*/
1801: PetscErrorCode KSPSetDMActive(KSP ksp,PetscBool flg)
1802: {
1806: ksp->dmActive = flg;
1807: return(0);
1808: }
1810: /*@
1811: KSPGetDM - Gets the DM that may be used by some preconditioners
1813: Not Collective
1815: Input Parameter:
1816: . ksp - the preconditioner context
1818: Output Parameter:
1819: . dm - the dm
1821: Level: intermediate
1824: .seealso: KSPSetDM(), KSPSetDMActive()
1825: @*/
1826: PetscErrorCode KSPGetDM(KSP ksp,DM *dm)
1827: {
1832: if (!ksp->dm) {
1833: DMShellCreate(PetscObjectComm((PetscObject)ksp),&ksp->dm);
1834: ksp->dmAuto = PETSC_TRUE;
1835: }
1836: *dm = ksp->dm;
1837: return(0);
1838: }
1840: /*@
1841: KSPSetApplicationContext - Sets the optional user-defined context for the linear solver.
1843: Logically Collective on ksp
1845: Input Parameters:
1846: + ksp - the KSP context
1847: - usrP - optional user context
1849: Fortran Notes:
1850: To use this from Fortran you must write a Fortran interface definition for this
1851: function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1853: Level: intermediate
1855: .seealso: KSPGetApplicationContext()
1856: @*/
1857: PetscErrorCode KSPSetApplicationContext(KSP ksp,void *usrP)
1858: {
1860: PC pc;
1864: ksp->user = usrP;
1865: KSPGetPC(ksp,&pc);
1866: PCSetApplicationContext(pc,usrP);
1867: return(0);
1868: }
1870: /*@
1871: KSPGetApplicationContext - Gets the user-defined context for the linear solver.
1873: Not Collective
1875: Input Parameter:
1876: . ksp - KSP context
1878: Output Parameter:
1879: . usrP - user context
1881: Fortran Notes:
1882: To use this from Fortran you must write a Fortran interface definition for this
1883: function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1885: Level: intermediate
1887: .seealso: KSPSetApplicationContext()
1888: @*/
1889: PetscErrorCode KSPGetApplicationContext(KSP ksp,void *usrP)
1890: {
1893: *(void**)usrP = ksp->user;
1894: return(0);
1895: }
1897: #include <petsc/private/pcimpl.h>
1899: /*@
1900: KSPCheckSolve - Checks if the PCSetUp() or KSPSolve() failed and set the error flag for the outer PC. A KSP_DIVERGED_ITS is
1901: not considered a failure in this context
1903: Collective on ksp
1905: Input Parameter:
1906: + ksp - the linear solver (KSP) context.
1907: . pc - the preconditioner context
1908: - vec - a vector that will be initialized with Inf to indicate lack of convergence
1910: Notes: this may be called by a subset of the processes in the PC
1912: Level: developer
1914: Developer Note: this is used to manage returning from preconditioners whose inner KSP solvers have failed in some way
1916: .seealso: KSPCreate(), KSPSetType(), KSP, KSPCheckNorm(), KSPCheckDot()
1917: @*/
1918: PetscErrorCode KSPCheckSolve(KSP ksp,PC pc,Vec vec)
1919: {
1920: PetscErrorCode ierr;
1921: PCFailedReason pcreason;
1922: PC subpc;
1925: KSPGetPC(ksp,&subpc);
1926: PCGetFailedReason(subpc,&pcreason);
1927: if (pcreason || (ksp->reason < 0 && ksp->reason != KSP_DIVERGED_ITS)) {
1928: if (pc->erroriffailure) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_NOT_CONVERGED,"Detected not converged in KSP inner solve: KSP reason %s PC reason %s",KSPConvergedReasons[ksp->reason],PCFailedReasons[pcreason]);
1929: else {
1930: PetscInfo2(ksp,"Detected not converged in KSP inner solve: KSP reason %s PC reason %s\n",KSPConvergedReasons[ksp->reason],PCFailedReasons[pcreason]);
1931: pc->failedreason = PC_SUBPC_ERROR;
1932: if (vec) {
1933: VecSetInf(vec);
1934: }
1935: }
1936: }
1937: return(0);
1938: }