Actual source code: iterativ.c
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: {
32: *rnorm = ksp->rnorm;
33: return 0;
34: }
36: /*@
37: KSPGetIterationNumber - Gets the current iteration number; if the
38: KSPSolve() is complete, returns the number of iterations
39: used.
41: Not Collective
43: Input Parameters:
44: . ksp - the iterative context
46: Output Parameters:
47: . its - number of iterations
49: Level: intermediate
51: Notes:
52: During the ith iteration this returns i-1
53: .seealso: `KSPBuildResidual()`, `KSPGetResidualNorm()`, `KSPGetTotalIterations()`
54: @*/
55: PetscErrorCode KSPGetIterationNumber(KSP ksp, PetscInt *its)
56: {
59: *its = ksp->its;
60: return 0;
61: }
63: /*@
64: KSPGetTotalIterations - Gets the total number of iterations this KSP object has performed since was created, counted over all linear solves
66: Not Collective
68: Input Parameters:
69: . ksp - the iterative context
71: Output Parameters:
72: . its - total number of iterations
74: Level: intermediate
76: Notes:
77: Use KSPGetIterationNumber() to get the count for the most recent solve only
78: If this is called within a linear solve (such as in a KSPMonitor routine) then it does not include iterations within that current solve
80: .seealso: `KSPBuildResidual()`, `KSPGetResidualNorm()`, `KSPGetIterationNumber()`
81: @*/
82: PetscErrorCode KSPGetTotalIterations(KSP ksp, PetscInt *its)
83: {
86: *its = ksp->totalits;
87: return 0;
88: }
90: /*@C
91: KSPMonitorResidual - Print the preconditioned residual norm at each iteration of an iterative solver.
93: Collective on ksp
95: Input Parameters:
96: + ksp - iterative context
97: . n - iteration number
98: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
99: - vf - The viewer context
101: Options Database Key:
102: . -ksp_monitor - Activates KSPMonitorResidual()
104: Notes:
105: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
106: to be used during the KSP solve.
108: Level: intermediate
110: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorResidualDraw()`, `KSPMonitorResidualDrawLG()`,
111: `KSPMonitorResidualRange()`, `KSPMonitorTrueResidualDraw()`, `KSPMonitorTrueResidualDrawLG()`, `KSPMonitorTrueResidualMax()`,
112: `KSPMonitorSingularValue()`, `KSPMonitorSolutionDrawLG()`, `KSPMonitorSolutionDraw()`, `KSPMonitorSolution()`,
113: `KSPMonitorErrorDrawLG()`, `KSPMonitorErrorDraw()`, KSPMonitorError()`
114: @*/
115: PetscErrorCode KSPMonitorResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
116: {
117: PetscViewer viewer = vf->viewer;
118: PetscViewerFormat format = vf->format;
119: PetscInt tablevel;
120: const char *prefix;
123: PetscObjectGetTabLevel((PetscObject)ksp, &tablevel);
124: PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
125: PetscViewerPushFormat(viewer, format);
126: PetscViewerASCIIAddTab(viewer, tablevel);
127: if (n == 0 && prefix) PetscViewerASCIIPrintf(viewer, " Residual norms for %s solve.\n", prefix);
128: PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Residual norm %14.12e \n", n, (double)rnorm);
129: PetscViewerASCIISubtractTab(viewer, tablevel);
130: PetscViewerPopFormat(viewer);
131: return 0;
132: }
134: /*@C
135: KSPMonitorResidualDraw - Plots the preconditioned residual at each iteration of an iterative solver.
137: Collective on ksp
139: Input Parameters:
140: + ksp - iterative context
141: . n - iteration number
142: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
143: - vf - The viewer context
145: Options Database Key:
146: . -ksp_monitor draw - Activates KSPMonitorResidualDraw()
148: Notes:
149: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
150: to be used during the KSP solve.
152: Level: intermediate
154: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, , `KSPMonitorResidual()`, `KSPMonitorResidualDrawLG()`
155: @*/
156: PetscErrorCode KSPMonitorResidualDraw(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
157: {
158: PetscViewer viewer = vf->viewer;
159: PetscViewerFormat format = vf->format;
160: Vec r;
163: PetscViewerPushFormat(viewer, format);
164: KSPBuildResidual(ksp, NULL, NULL, &r);
165: PetscObjectSetName((PetscObject)r, "Residual");
166: PetscObjectCompose((PetscObject)r, "__Vec_bc_zero__", (PetscObject)ksp);
167: VecView(r, viewer);
168: PetscObjectCompose((PetscObject)r, "__Vec_bc_zero__", NULL);
169: VecDestroy(&r);
170: PetscViewerPopFormat(viewer);
171: return 0;
172: }
174: /*@C
175: KSPMonitorResidualDrawLG - Plots the preconditioned residual norm at each iteration of an iterative solver.
177: Collective on ksp
179: Input Parameters:
180: + ksp - iterative context
181: . n - iteration number
182: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
183: - vf - The viewer context
185: Options Database Key:
186: . -ksp_monitor draw::draw_lg - Activates KSPMonitorResidualDrawLG()
188: Notes:
189: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
190: to be used during the KSP solve.
192: Level: intermediate
194: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `KSPMonitorResidualDraw()`, `KSPMonitorResidual()`
195: @*/
196: PetscErrorCode KSPMonitorResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
197: {
198: PetscViewer viewer = vf->viewer;
199: PetscViewerFormat format = vf->format;
200: PetscDrawLG lg = vf->lg;
201: KSPConvergedReason reason;
202: PetscReal x, y;
206: PetscViewerPushFormat(viewer, format);
207: if (!n) PetscDrawLGReset(lg);
208: x = (PetscReal)n;
209: if (rnorm > 0.0) y = PetscLog10Real(rnorm);
210: else y = -15.0;
211: PetscDrawLGAddPoint(lg, &x, &y);
212: KSPGetConvergedReason(ksp, &reason);
213: if (n <= 20 || !(n % 5) || reason) {
214: PetscDrawLGDraw(lg);
215: PetscDrawLGSave(lg);
216: }
217: PetscViewerPopFormat(viewer);
218: return 0;
219: }
221: /*@C
222: KSPMonitorResidualDrawLGCreate - Creates the plotter for the preconditioned residual.
224: Collective on ksp
226: Input Parameters:
227: + viewer - The PetscViewer
228: . format - The viewer format
229: - ctx - An optional user context
231: Output Parameter:
232: . vf - The viewer context
234: Level: intermediate
236: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
237: @*/
238: PetscErrorCode KSPMonitorResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
239: {
240: PetscViewerAndFormatCreate(viewer, format, vf);
241: (*vf)->data = ctx;
242: KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Residual Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg);
243: return 0;
244: }
246: /*
247: This is the same as KSPMonitorResidual() except it prints fewer digits of the residual as the residual gets smaller.
248: This is because the later digits are meaningless and are often different on different machines; by using this routine different
249: machines will usually generate the same output.
251: Deprecated: Intentionally has no manual page
252: */
253: PetscErrorCode KSPMonitorResidualShort(KSP ksp, PetscInt its, PetscReal fnorm, PetscViewerAndFormat *vf)
254: {
255: PetscViewer viewer = vf->viewer;
256: PetscViewerFormat format = vf->format;
257: PetscInt tablevel;
258: const char *prefix;
261: PetscObjectGetTabLevel((PetscObject)ksp, &tablevel);
262: PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
263: PetscViewerPushFormat(viewer, format);
264: PetscViewerASCIIAddTab(viewer, tablevel);
265: if (its == 0 && prefix) PetscViewerASCIIPrintf(viewer, " Residual norms for %s solve.\n", prefix);
266: if (fnorm > 1.e-9) PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Residual norm %g \n", its, (double)fnorm);
267: else if (fnorm > 1.e-11) PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Residual norm %5.3e \n", its, (double)fnorm);
268: else PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Residual norm < 1.e-11\n", its);
269: PetscViewerASCIISubtractTab(viewer, tablevel);
270: PetscViewerPopFormat(viewer);
271: return 0;
272: }
274: PetscErrorCode KSPMonitorRange_Private(KSP ksp, PetscInt it, PetscReal *per)
275: {
276: Vec resid;
277: const PetscScalar *r;
278: PetscReal rmax, pwork;
279: PetscInt i, n, N;
281: KSPBuildResidual(ksp, NULL, NULL, &resid);
282: VecNorm(resid, NORM_INFINITY, &rmax);
283: VecGetLocalSize(resid, &n);
284: VecGetSize(resid, &N);
285: VecGetArrayRead(resid, &r);
286: pwork = 0.0;
287: for (i = 0; i < n; ++i) pwork += (PetscAbsScalar(r[i]) > .20 * rmax);
288: VecRestoreArrayRead(resid, &r);
289: VecDestroy(&resid);
290: MPIU_Allreduce(&pwork, per, 1, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)ksp));
291: *per = *per / N;
292: return 0;
293: }
295: /*@C
296: KSPMonitorResidualRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
298: Collective on ksp
300: Input Parameters:
301: + ksp - iterative context
302: . it - iteration number
303: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
304: - vf - The viewer context
306: Options Database Key:
307: . -ksp_monitor_range - Activates KSPMonitorResidualRange()
309: Notes:
310: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
311: to be used during the KSP solve.
313: Level: intermediate
315: .seealso: `KSPMonitorSet()`, `KSPMonitorResidual()`
316: @*/
317: PetscErrorCode KSPMonitorResidualRange(KSP ksp, PetscInt it, PetscReal rnorm, PetscViewerAndFormat *vf)
318: {
319: static PetscReal prev;
320: PetscViewer viewer = vf->viewer;
321: PetscViewerFormat format = vf->format;
322: PetscInt tablevel;
323: const char *prefix;
324: PetscReal perc, rel;
327: PetscObjectGetTabLevel((PetscObject)ksp, &tablevel);
328: PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
329: PetscViewerPushFormat(viewer, format);
330: PetscViewerASCIIAddTab(viewer, tablevel);
331: if (!it) prev = rnorm;
332: if (it == 0 && prefix) PetscViewerASCIIPrintf(viewer, " Residual norms for %s solve.\n", prefix);
333: KSPMonitorRange_Private(ksp, it, &perc);
334: rel = (prev - rnorm) / prev;
335: prev = rnorm;
336: PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " 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));
337: PetscViewerASCIISubtractTab(viewer, tablevel);
338: PetscViewerPopFormat(viewer);
339: return 0;
340: }
342: /*@C
343: KSPMonitorTrueResidual - Prints the true residual norm, as well as the preconditioned residual norm, at each iteration of an iterative solver.
345: Collective on ksp
347: Input Parameters:
348: + ksp - iterative context
349: . n - iteration number
350: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
351: - vf - The viewer context
353: Options Database Key:
354: . -ksp_monitor_true_residual - Activates KSPMonitorTrueResidual()
356: Notes:
357: When using right preconditioning, these values are equivalent.
359: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
360: to be used during the KSP solve.
362: Level: intermediate
364: .seealso: `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`
365: @*/
366: PetscErrorCode KSPMonitorTrueResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
367: {
368: PetscViewer viewer = vf->viewer;
369: PetscViewerFormat format = vf->format;
370: Vec r;
371: PetscReal truenorm, bnorm;
372: char normtype[256];
373: PetscInt tablevel;
374: const char *prefix;
377: PetscObjectGetTabLevel((PetscObject)ksp, &tablevel);
378: PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
379: PetscStrncpy(normtype, KSPNormTypes[ksp->normtype], sizeof(normtype));
380: PetscStrtolower(normtype);
381: KSPBuildResidual(ksp, NULL, NULL, &r);
382: VecNorm(r, NORM_2, &truenorm);
383: VecNorm(ksp->vec_rhs, NORM_2, &bnorm);
384: VecDestroy(&r);
386: PetscViewerPushFormat(viewer, format);
387: PetscViewerASCIIAddTab(viewer, tablevel);
388: if (n == 0 && prefix) PetscViewerASCIIPrintf(viewer, " Residual norms for %s solve.\n", prefix);
389: PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " 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));
390: PetscViewerASCIISubtractTab(viewer, tablevel);
391: PetscViewerPopFormat(viewer);
392: return 0;
393: }
395: /*@C
396: KSPMonitorTrueResidualDraw - Plots the true residual at each iteration of an iterative solver.
398: Collective on ksp
400: Input Parameters:
401: + ksp - iterative context
402: . n - iteration number
403: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
404: - vf - The viewer context
406: Options Database Key:
407: . -ksp_monitor_true_residual draw - Activates KSPMonitorResidualDraw()
409: Notes:
410: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
411: to be used during the KSP solve.
413: Level: intermediate
415: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
416: @*/
417: PetscErrorCode KSPMonitorTrueResidualDraw(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
418: {
419: PetscViewer viewer = vf->viewer;
420: PetscViewerFormat format = vf->format;
421: Vec r;
424: PetscViewerPushFormat(viewer, format);
425: KSPBuildResidual(ksp, NULL, NULL, &r);
426: PetscObjectSetName((PetscObject)r, "Residual");
427: PetscObjectCompose((PetscObject)r, "__Vec_bc_zero__", (PetscObject)ksp);
428: VecView(r, viewer);
429: PetscObjectCompose((PetscObject)r, "__Vec_bc_zero__", NULL);
430: VecDestroy(&r);
431: PetscViewerPopFormat(viewer);
432: return 0;
433: }
435: /*@C
436: KSPMonitorTrueResidualDrawLG - Plots the true residual norm at each iteration of an iterative solver.
438: Collective on ksp
440: Input Parameters:
441: + ksp - iterative context
442: . n - iteration number
443: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
444: - vf - The viewer context
446: Options Database Key:
447: . -ksp_monitor_true_residual draw::draw_lg - Activates KSPMonitorTrueResidualDrawLG()
449: Notes:
450: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
451: to be used during the KSP solve.
453: Level: intermediate
455: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
456: @*/
457: PetscErrorCode KSPMonitorTrueResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
458: {
459: PetscViewer viewer = vf->viewer;
460: PetscViewerFormat format = vf->format;
461: PetscDrawLG lg = vf->lg;
462: Vec r;
463: KSPConvergedReason reason;
464: PetscReal truenorm, x[2], y[2];
468: KSPBuildResidual(ksp, NULL, NULL, &r);
469: VecNorm(r, NORM_2, &truenorm);
470: VecDestroy(&r);
471: PetscViewerPushFormat(viewer, format);
472: if (!n) PetscDrawLGReset(lg);
473: x[0] = (PetscReal)n;
474: if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
475: else y[0] = -15.0;
476: x[1] = (PetscReal)n;
477: if (truenorm > 0.0) y[1] = PetscLog10Real(truenorm);
478: else y[1] = -15.0;
479: PetscDrawLGAddPoint(lg, x, y);
480: KSPGetConvergedReason(ksp, &reason);
481: if (n <= 20 || !(n % 5) || reason) {
482: PetscDrawLGDraw(lg);
483: PetscDrawLGSave(lg);
484: }
485: PetscViewerPopFormat(viewer);
486: return 0;
487: }
489: /*@C
490: KSPMonitorTrueResidualDrawLGCreate - Creates the plotter for the preconditioned residual.
492: Collective on ksp
494: Input Parameters:
495: + viewer - The PetscViewer
496: . format - The viewer format
497: - ctx - An optional user context
499: Output Parameter:
500: . vf - The viewer context
502: Notes:
503: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
504: to be used during the KSP solve.
506: Level: intermediate
508: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
509: @*/
510: PetscErrorCode KSPMonitorTrueResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
511: {
512: const char *names[] = {"preconditioned", "true"};
514: PetscViewerAndFormatCreate(viewer, format, vf);
515: (*vf)->data = ctx;
516: KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Residual Norm", 2, names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg);
517: return 0;
518: }
520: /*@C
521: KSPMonitorTrueResidualMax - Prints the true residual max norm at each iteration of an iterative solver.
523: Collective on ksp
525: Input Parameters:
526: + ksp - iterative context
527: . n - iteration number
528: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
529: - vf - The viewer context
531: Options Database Key:
532: . -ksp_monitor_true_residual_max - Activates KSPMonitorTrueResidualMax()
534: Notes:
535: When using right preconditioning, these values are equivalent.
537: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
538: to be used during the KSP solve.
540: Level: intermediate
542: .seealso: `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`
543: @*/
544: PetscErrorCode KSPMonitorTrueResidualMax(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
545: {
546: PetscViewer viewer = vf->viewer;
547: PetscViewerFormat format = vf->format;
548: Vec r;
549: PetscReal truenorm, bnorm;
550: char normtype[256];
551: PetscInt tablevel;
552: const char *prefix;
555: PetscObjectGetTabLevel((PetscObject)ksp, &tablevel);
556: PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
557: PetscStrncpy(normtype, KSPNormTypes[ksp->normtype], sizeof(normtype));
558: PetscStrtolower(normtype);
559: KSPBuildResidual(ksp, NULL, NULL, &r);
560: VecNorm(r, NORM_INFINITY, &truenorm);
561: VecNorm(ksp->vec_rhs, NORM_INFINITY, &bnorm);
562: VecDestroy(&r);
564: PetscViewerPushFormat(viewer, format);
565: PetscViewerASCIIAddTab(viewer, tablevel);
566: if (n == 0 && prefix) PetscViewerASCIIPrintf(viewer, " Residual norms for %s solve.\n", prefix);
567: PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP %s true resid max norm %14.12e ||r(i)||/||b|| %14.12e\n", n, normtype, (double)truenorm, (double)(truenorm / bnorm));
568: PetscViewerASCIISubtractTab(viewer, tablevel);
569: PetscViewerPopFormat(viewer);
570: return 0;
571: }
573: /*@C
574: KSPMonitorError - Prints the error norm, as well as the preconditioned residual norm, at each iteration of an iterative solver.
576: Collective on ksp
578: Input Parameters:
579: + ksp - iterative context
580: . n - iteration number
581: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
582: - vf - The viewer context
584: Options Database Key:
585: . -ksp_monitor_error - Activates KSPMonitorError()
587: Notes:
588: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
589: to be used during the KSP solve.
591: Level: intermediate
593: .seealso: `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`
594: @*/
595: PetscErrorCode KSPMonitorError(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
596: {
597: PetscViewer viewer = vf->viewer;
598: PetscViewerFormat format = vf->format;
599: DM dm;
600: Vec sol;
601: PetscReal *errors;
602: PetscInt Nf, f;
603: PetscInt tablevel;
604: const char *prefix;
607: PetscObjectGetTabLevel((PetscObject)ksp, &tablevel);
608: PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
609: KSPGetDM(ksp, &dm);
610: DMGetNumFields(dm, &Nf);
611: DMGetGlobalVector(dm, &sol);
612: KSPBuildSolution(ksp, sol, NULL);
613: /* TODO: Make a different monitor that flips sign for SNES, Newton system is A dx = -b, so we need to negate the solution */
614: VecScale(sol, -1.0);
615: PetscCalloc1(Nf, &errors);
616: DMComputeError(dm, sol, errors, NULL);
618: PetscViewerPushFormat(viewer, format);
619: PetscViewerASCIIAddTab(viewer, tablevel);
620: if (n == 0 && prefix) PetscViewerASCIIPrintf(viewer, " Error norms for %s solve.\n", prefix);
621: PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Error norm %s", n, Nf > 1 ? "[" : "");
622: PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);
623: for (f = 0; f < Nf; ++f) {
624: if (f > 0) PetscViewerASCIIPrintf(viewer, ", ");
625: PetscViewerASCIIPrintf(viewer, "%14.12e", (double)errors[f]);
626: }
627: PetscViewerASCIIPrintf(viewer, "%s resid norm %14.12e\n", Nf > 1 ? "]" : "", (double)rnorm);
628: PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);
629: PetscViewerASCIISubtractTab(viewer, tablevel);
630: PetscViewerPopFormat(viewer);
631: DMRestoreGlobalVector(dm, &sol);
632: return 0;
633: }
635: /*@C
636: KSPMonitorErrorDraw - Plots the error at each iteration of an iterative solver.
638: Collective on ksp
640: Input Parameters:
641: + ksp - iterative context
642: . n - iteration number
643: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
644: - vf - The viewer context
646: Options Database Key:
647: . -ksp_monitor_error draw - Activates KSPMonitorErrorDraw()
649: Notes:
650: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
651: to be used during the KSP solve.
653: Level: intermediate
655: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
656: @*/
657: PetscErrorCode KSPMonitorErrorDraw(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
658: {
659: PetscViewer viewer = vf->viewer;
660: PetscViewerFormat format = vf->format;
661: DM dm;
662: Vec sol, e;
665: PetscViewerPushFormat(viewer, format);
666: KSPGetDM(ksp, &dm);
667: DMGetGlobalVector(dm, &sol);
668: KSPBuildSolution(ksp, sol, NULL);
669: DMComputeError(dm, sol, NULL, &e);
670: PetscObjectSetName((PetscObject)e, "Error");
671: PetscObjectCompose((PetscObject)e, "__Vec_bc_zero__", (PetscObject)ksp);
672: VecView(e, viewer);
673: PetscObjectCompose((PetscObject)e, "__Vec_bc_zero__", NULL);
674: VecDestroy(&e);
675: DMRestoreGlobalVector(dm, &sol);
676: PetscViewerPopFormat(viewer);
677: return 0;
678: }
680: /*@C
681: KSPMonitorErrorDrawLG - Plots the error and residual norm at each iteration of an iterative solver.
683: Collective on ksp
685: Input Parameters:
686: + ksp - iterative context
687: . n - iteration number
688: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
689: - vf - The viewer context
691: Options Database Key:
692: . -ksp_monitor_error draw::draw_lg - Activates KSPMonitorTrueResidualDrawLG()
694: Notes:
695: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
696: to be used during the KSP solve.
698: Level: intermediate
700: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
701: @*/
702: PetscErrorCode KSPMonitorErrorDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
703: {
704: PetscViewer viewer = vf->viewer;
705: PetscViewerFormat format = vf->format;
706: PetscDrawLG lg = vf->lg;
707: DM dm;
708: Vec sol;
709: KSPConvergedReason reason;
710: PetscReal *x, *errors;
711: PetscInt Nf, f;
715: KSPGetDM(ksp, &dm);
716: DMGetNumFields(dm, &Nf);
717: DMGetGlobalVector(dm, &sol);
718: KSPBuildSolution(ksp, sol, NULL);
719: /* TODO: Make a different monitor that flips sign for SNES, Newton system is A dx = -b, so we need to negate the solution */
720: VecScale(sol, -1.0);
721: PetscCalloc2(Nf + 1, &x, Nf + 1, &errors);
722: DMComputeError(dm, sol, errors, NULL);
724: PetscViewerPushFormat(viewer, format);
725: if (!n) PetscDrawLGReset(lg);
726: for (f = 0; f < Nf; ++f) {
727: x[f] = (PetscReal)n;
728: errors[f] = errors[f] > 0.0 ? PetscLog10Real(errors[f]) : -15.;
729: }
730: x[Nf] = (PetscReal)n;
731: errors[Nf] = rnorm > 0.0 ? PetscLog10Real(rnorm) : -15.;
732: PetscDrawLGAddPoint(lg, x, errors);
733: KSPGetConvergedReason(ksp, &reason);
734: if (n <= 20 || !(n % 5) || reason) {
735: PetscDrawLGDraw(lg);
736: PetscDrawLGSave(lg);
737: }
738: PetscViewerPopFormat(viewer);
739: return 0;
740: }
742: /*@C
743: KSPMonitorErrorDrawLGCreate - Creates the plotter for the error and preconditioned residual.
745: Collective on ksp
747: Input Parameters:
748: + viewer - The PetscViewer
749: . format - The viewer format
750: - ctx - An optional user context
752: Output Parameter:
753: . vf - The viewer context
755: Notes:
756: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
757: to be used during the KSP solve.
759: Level: intermediate
761: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
762: @*/
763: PetscErrorCode KSPMonitorErrorDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
764: {
765: KSP ksp = (KSP)ctx;
766: DM dm;
767: char **names;
768: PetscInt Nf, f;
770: KSPGetDM(ksp, &dm);
771: DMGetNumFields(dm, &Nf);
772: PetscMalloc1(Nf + 1, &names);
773: for (f = 0; f < Nf; ++f) {
774: PetscObject disc;
775: const char *fname;
776: char lname[PETSC_MAX_PATH_LEN];
778: DMGetField(dm, f, NULL, &disc);
779: PetscObjectGetName(disc, &fname);
780: PetscStrncpy(lname, fname, PETSC_MAX_PATH_LEN);
781: PetscStrlcat(lname, " Error", PETSC_MAX_PATH_LEN);
782: PetscStrallocpy(lname, &names[f]);
783: }
784: PetscStrallocpy("residual", &names[Nf]);
785: PetscViewerAndFormatCreate(viewer, format, vf);
786: (*vf)->data = ctx;
787: KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Error Norm", Nf + 1, (const char **)names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg);
788: for (f = 0; f <= Nf; ++f) PetscFree(names[f]);
789: PetscFree(names);
790: return 0;
791: }
793: /*@C
794: KSPMonitorSolution - Print the solution norm at each iteration of an iterative solver.
796: Collective on ksp
798: Input Parameters:
799: + ksp - iterative context
800: . n - iteration number
801: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
802: - vf - The viewer context
804: Options Database Key:
805: . -ksp_monitor_solution - Activates KSPMonitorSolution()
807: Notes:
808: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
809: to be used during the KSP solve.
811: Level: intermediate
813: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
814: @*/
815: PetscErrorCode KSPMonitorSolution(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
816: {
817: PetscViewer viewer = vf->viewer;
818: PetscViewerFormat format = vf->format;
819: Vec x;
820: PetscReal snorm;
821: PetscInt tablevel;
822: const char *prefix;
825: KSPBuildSolution(ksp, NULL, &x);
826: VecNorm(x, NORM_2, &snorm);
827: PetscObjectGetTabLevel((PetscObject)ksp, &tablevel);
828: PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
829: PetscViewerPushFormat(viewer, format);
830: PetscViewerASCIIAddTab(viewer, tablevel);
831: if (n == 0 && prefix) PetscViewerASCIIPrintf(viewer, " Solution norms for %s solve.\n", prefix);
832: PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Solution norm %14.12e \n", n, (double)snorm);
833: PetscViewerASCIISubtractTab(viewer, tablevel);
834: PetscViewerPopFormat(viewer);
835: return 0;
836: }
838: /*@C
839: KSPMonitorSolutionDraw - Plots the solution at each iteration of an iterative solver.
841: Collective on ksp
843: Input Parameters:
844: + ksp - iterative context
845: . n - iteration number
846: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
847: - vf - The viewer context
849: Options Database Key:
850: . -ksp_monitor_solution draw - Activates KSPMonitorSolutionDraw()
852: Notes:
853: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
854: to be used during the KSP solve.
856: Level: intermediate
858: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
859: @*/
860: PetscErrorCode KSPMonitorSolutionDraw(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
861: {
862: PetscViewer viewer = vf->viewer;
863: PetscViewerFormat format = vf->format;
864: Vec x;
867: KSPBuildSolution(ksp, NULL, &x);
868: PetscViewerPushFormat(viewer, format);
869: PetscObjectSetName((PetscObject)x, "Solution");
870: PetscObjectCompose((PetscObject)x, "__Vec_bc_zero__", (PetscObject)ksp);
871: VecView(x, viewer);
872: PetscObjectCompose((PetscObject)x, "__Vec_bc_zero__", NULL);
873: PetscViewerPopFormat(viewer);
874: return 0;
875: }
877: /*@C
878: KSPMonitorSolutionDrawLG - Plots the solution norm at each iteration of an iterative solver.
880: Collective on ksp
882: Input Parameters:
883: + ksp - iterative context
884: . n - iteration number
885: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
886: - vf - The viewer context
888: Options Database Key:
889: . -ksp_monitor_solution draw::draw_lg - Activates KSPMonitorSolutionDrawLG()
891: Notes:
892: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
893: to be used during the KSP solve.
895: Level: intermediate
897: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
898: @*/
899: PetscErrorCode KSPMonitorSolutionDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
900: {
901: PetscViewer viewer = vf->viewer;
902: PetscViewerFormat format = vf->format;
903: PetscDrawLG lg = vf->lg;
904: Vec u;
905: KSPConvergedReason reason;
906: PetscReal snorm, x, y;
910: KSPBuildSolution(ksp, NULL, &u);
911: VecNorm(u, NORM_2, &snorm);
912: PetscViewerPushFormat(viewer, format);
913: if (!n) PetscDrawLGReset(lg);
914: x = (PetscReal)n;
915: if (snorm > 0.0) y = PetscLog10Real(snorm);
916: else y = -15.0;
917: PetscDrawLGAddPoint(lg, &x, &y);
918: KSPGetConvergedReason(ksp, &reason);
919: if (n <= 20 || !(n % 5) || reason) {
920: PetscDrawLGDraw(lg);
921: PetscDrawLGSave(lg);
922: }
923: PetscViewerPopFormat(viewer);
924: return 0;
925: }
927: /*@C
928: KSPMonitorSolutionDrawLGCreate - Creates the plotter for the solution.
930: Collective on ksp
932: Input Parameters:
933: + viewer - The PetscViewer
934: . format - The viewer format
935: - ctx - An optional user context
937: Output Parameter:
938: . vf - The viewer context
940: Notes:
941: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
942: to be used during the KSP solve.
944: Level: intermediate
946: .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
947: @*/
948: PetscErrorCode KSPMonitorSolutionDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
949: {
950: PetscViewerAndFormatCreate(viewer, format, vf);
951: (*vf)->data = ctx;
952: KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Solution Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg);
953: return 0;
954: }
956: /*@C
957: KSPMonitorSingularValue - Prints the two norm of the true residual and estimation of the extreme singular values of the preconditioned problem at each iteration.
959: Logically Collective on ksp
961: Input Parameters:
962: + ksp - the iterative context
963: . n - the iteration
964: . rnorm - the two norm of the residual
965: - vf - The viewer context
967: Options Database Key:
968: . -ksp_monitor_singular_value - Activates KSPMonitorSingularValue()
970: Notes:
971: The CG solver uses the Lanczos technique for eigenvalue computation,
972: while GMRES uses the Arnoldi technique; other iterative methods do
973: not currently compute singular values.
975: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
976: to be used during the KSP solve.
978: Level: intermediate
980: .seealso: `KSPComputeExtremeSingularValues()`, `KSPMonitorSingularValueCreate()`
981: @*/
982: PetscErrorCode KSPMonitorSingularValue(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
983: {
984: PetscViewer viewer = vf->viewer;
985: PetscViewerFormat format = vf->format;
986: PetscReal emin, emax;
987: PetscInt tablevel;
988: const char *prefix;
992: PetscObjectGetTabLevel((PetscObject)ksp, &tablevel);
993: PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
994: PetscViewerPushFormat(viewer, format);
995: PetscViewerASCIIAddTab(viewer, tablevel);
996: if (n == 0 && prefix) PetscViewerASCIIPrintf(viewer, " Residual norms for %s solve.\n", prefix);
997: if (!ksp->calc_sings) {
998: PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " KSP Residual norm %14.12e \n", n, (double)rnorm);
999: } else {
1000: KSPComputeExtremeSingularValues(ksp, &emax, &emin);
1001: PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " 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));
1002: }
1003: PetscViewerASCIISubtractTab(viewer, tablevel);
1004: PetscViewerPopFormat(viewer);
1005: return 0;
1006: }
1008: /*@C
1009: KSPMonitorSingularValueCreate - Creates the singular value monitor.
1011: Collective on ksp
1013: Input Parameters:
1014: + viewer - The PetscViewer
1015: . format - The viewer format
1016: - ctx - An optional user context
1018: Output Parameter:
1019: . vf - The viewer context
1021: Level: intermediate
1023: .seealso: `KSPMonitorSet()`, `KSPMonitorSingularValue()`
1024: @*/
1025: PetscErrorCode KSPMonitorSingularValueCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
1026: {
1027: KSP ksp = (KSP)ctx;
1029: PetscViewerAndFormatCreate(viewer, format, vf);
1030: (*vf)->data = ctx;
1031: KSPSetComputeSingularValues(ksp, PETSC_TRUE);
1032: return 0;
1033: }
1035: /*@C
1036: KSPMonitorDynamicTolerance - Recompute the inner tolerance in every outer iteration in an adaptive way.
1038: Collective on ksp
1040: Input Parameters:
1041: + ksp - iterative context
1042: . n - iteration number (not used)
1043: . fnorm - the current residual norm
1044: - dummy - some context as a C struct. fields:
1045: coef: a scaling coefficient. default 1.0. can be passed through
1046: -sub_ksp_dynamic_tolerance_param
1047: bnrm: norm of the right-hand side. store it to avoid repeated calculation
1049: Notes:
1050: This may be useful for a flexibly preconditioner Krylov method to
1051: control the accuracy of the inner solves needed to guarantee the
1052: convergence of the outer iterations.
1054: This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
1055: to be used during the KSP solve.
1057: Level: advanced
1059: .seealso: `KSPMonitorDynamicToleranceDestroy()`
1060: @*/
1061: PetscErrorCode KSPMonitorDynamicTolerance(KSP ksp, PetscInt its, PetscReal fnorm, void *dummy)
1062: {
1063: PC pc;
1064: PetscReal outer_rtol, outer_abstol, outer_dtol, inner_rtol;
1065: PetscInt outer_maxits, nksp, first, i;
1066: KSPDynTolCtx *scale = (KSPDynTolCtx *)dummy;
1067: KSP *subksp = NULL;
1068: KSP kspinner;
1069: PetscBool flg;
1071: KSPGetPC(ksp, &pc);
1073: /* compute inner_rtol */
1074: if (scale->bnrm < 0.0) {
1075: Vec b;
1076: KSPGetRhs(ksp, &b);
1077: VecNorm(b, NORM_2, &(scale->bnrm));
1078: }
1079: KSPGetTolerances(ksp, &outer_rtol, &outer_abstol, &outer_dtol, &outer_maxits);
1080: inner_rtol = PetscMin(scale->coef * scale->bnrm * outer_rtol / fnorm, 0.999);
1081: /* PetscCall(PetscPrintf(PETSC_COMM_WORLD, " Inner rtol = %g\n",
1082: (double)inner_rtol)); */
1084: /* if pc is ksp */
1085: PetscObjectTypeCompare((PetscObject)pc, PCKSP, &flg);
1086: if (flg) {
1087: PCKSPGetKSP(pc, &kspinner);
1088: KSPSetTolerances(kspinner, inner_rtol, outer_abstol, outer_dtol, outer_maxits);
1089: return 0;
1090: }
1092: /* if pc is bjacobi */
1093: PetscObjectTypeCompare((PetscObject)pc, PCBJACOBI, &flg);
1094: if (flg) {
1095: PCBJacobiGetSubKSP(pc, &nksp, &first, &subksp);
1096: if (subksp) {
1097: for (i = 0; i < nksp; i++) KSPSetTolerances(subksp[i], inner_rtol, outer_abstol, outer_dtol, outer_maxits);
1098: return 0;
1099: }
1100: }
1102: /* if pc is deflation*/
1103: PetscObjectTypeCompare((PetscObject)pc, PCDEFLATION, &flg);
1104: if (flg) {
1105: PCDeflationGetCoarseKSP(pc, &kspinner);
1106: KSPSetTolerances(kspinner, inner_rtol, outer_abstol, outer_dtol, PETSC_DEFAULT);
1107: return 0;
1108: }
1110: /* todo: dynamic tolerance may apply to other types of pc too */
1111: return 0;
1112: }
1114: /*
1115: Destroy the dummy context used in KSPMonitorDynamicTolerance()
1116: */
1117: PetscErrorCode KSPMonitorDynamicToleranceDestroy(void **dummy)
1118: {
1119: PetscFree(*dummy);
1120: return 0;
1121: }
1123: /*@C
1124: KSPConvergedSkip - Convergence test that do not return as converged
1125: until the maximum number of iterations is reached.
1127: Collective on ksp
1129: Input Parameters:
1130: + ksp - iterative context
1131: . n - iteration number
1132: . rnorm - 2-norm residual value (may be estimated)
1133: - dummy - unused convergence context
1135: Returns:
1136: . reason - KSP_CONVERGED_ITERATING, KSP_CONVERGED_ITS
1138: Notes:
1139: This should be used as the convergence test with the option
1140: KSPSetNormType(ksp,KSP_NORM_NONE), since norms of the residual are
1141: not computed. Convergence is then declared after the maximum number
1142: of iterations have been reached. Useful when one is using CG or
1143: BiCGStab as a smoother.
1145: Level: advanced
1147: .seealso: `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPSetNormType()`
1148: @*/
1149: PetscErrorCode KSPConvergedSkip(KSP ksp, PetscInt n, PetscReal rnorm, KSPConvergedReason *reason, void *dummy)
1150: {
1153: *reason = KSP_CONVERGED_ITERATING;
1154: if (n >= ksp->max_it) *reason = KSP_CONVERGED_ITS;
1155: return 0;
1156: }
1158: /*@C
1159: KSPConvergedDefaultCreate - Creates and initializes the space used by the KSPConvergedDefault() function context
1161: Note Collective
1163: Output Parameter:
1164: . ctx - convergence context
1166: Level: intermediate
1168: .seealso: `KSPConvergedDefault()`, `KSPConvergedDefaultDestroy()`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`,
1169: `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetUMIRNorm()`, `KSPConvergedDefaultSetConvergedMaxits()`
1170: @*/
1171: PetscErrorCode KSPConvergedDefaultCreate(void **ctx)
1172: {
1173: KSPConvergedDefaultCtx *cctx;
1175: PetscNew(&cctx);
1176: *ctx = cctx;
1177: return 0;
1178: }
1180: /*@
1181: KSPConvergedDefaultSetUIRNorm - makes the default convergence test use || B*(b - A*(initial guess))||
1182: instead of || B*b ||. In the case of right preconditioner or if KSPSetNormType(ksp,KSP_NORM_UNPRECONDITIONED)
1183: is used there is no B in the above formula. UIRNorm is short for Use Initial Residual Norm.
1185: Collective on ksp
1187: Input Parameters:
1188: . ksp - iterative context
1190: Options Database:
1191: . -ksp_converged_use_initial_residual_norm <bool> - Use initial residual norm for computing relative convergence
1193: Notes:
1194: Use KSPSetTolerances() to alter the defaults for rtol, abstol, dtol.
1196: The precise values of reason are macros such as KSP_CONVERGED_RTOL, which
1197: are defined in petscksp.h.
1199: If the convergence test is not KSPConvergedDefault() then this is ignored.
1201: If right preconditioning is being used then B does not appear in the above formula.
1203: Level: intermediate
1205: .seealso: `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUMIRNorm()`, `KSPConvergedDefaultSetConvergedMaxits()`
1206: @*/
1207: PetscErrorCode KSPConvergedDefaultSetUIRNorm(KSP ksp)
1208: {
1209: KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx *)ksp->cnvP;
1212: if (ksp->converged != KSPConvergedDefault) return 0;
1214: ctx->initialrtol = PETSC_TRUE;
1215: return 0;
1216: }
1218: /*@
1219: KSPConvergedDefaultSetUMIRNorm - makes the default convergence test use min(|| B*(b - A*(initial guess))||,|| B*b ||)
1220: In the case of right preconditioner or if KSPSetNormType(ksp,KSP_NORM_UNPRECONDITIONED)
1221: is used there is no B in the above formula. UMIRNorm is short for Use Minimum Initial Residual Norm.
1223: Collective on ksp
1225: Input Parameters:
1226: . ksp - iterative context
1228: Options Database:
1229: . -ksp_converged_use_min_initial_residual_norm <bool> - Use minimum of initial residual norm and b for computing relative convergence
1231: Use KSPSetTolerances() to alter the defaults for rtol, abstol, dtol.
1233: The precise values of reason are macros such as KSP_CONVERGED_RTOL, which
1234: are defined in petscksp.h.
1236: Level: intermediate
1238: .seealso: `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetConvergedMaxits()`
1239: @*/
1240: PetscErrorCode KSPConvergedDefaultSetUMIRNorm(KSP ksp)
1241: {
1242: KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx *)ksp->cnvP;
1245: if (ksp->converged != KSPConvergedDefault) return 0;
1247: ctx->mininitialrtol = PETSC_TRUE;
1248: return 0;
1249: }
1251: /*@
1252: KSPConvergedDefaultSetConvergedMaxits - allows the default convergence test to declare convergence and return KSP_CONVERGED_ITS if the maximum number of iterations is reached
1254: Collective on ksp
1256: Input Parameters:
1257: + ksp - iterative context
1258: - flg - boolean flag
1260: Options Database:
1261: . -ksp_converged_maxits <bool> - Declare convergence if the maximum number of iterations is reached
1263: Use KSPSetTolerances() to alter the defaults for rtol, abstol, dtol.
1265: The precise values of reason are macros such as KSP_CONVERGED_RTOL, which
1266: are defined in petscksp.h.
1268: Level: intermediate
1270: .seealso: `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUMIRNorm()`, `KSPConvergedDefaultSetUIRNorm()`
1271: @*/
1272: PetscErrorCode KSPConvergedDefaultSetConvergedMaxits(KSP ksp, PetscBool flg)
1273: {
1274: KSPConvergedDefaultCtx *ctx = (KSPConvergedDefaultCtx *)ksp->cnvP;
1278: if (ksp->converged != KSPConvergedDefault) return 0;
1279: ctx->convmaxits = flg;
1280: return 0;
1281: }
1283: /*@C
1284: KSPConvergedDefault - Determines convergence of the linear iterative solvers by default
1286: Collective on ksp
1288: Input Parameters:
1289: + ksp - iterative context
1290: . n - iteration number
1291: . rnorm - residual norm (may be estimated, depending on the method may be the preconditioned residual norm)
1292: - ctx - convergence context which must be created by KSPConvergedDefaultCreate()
1294: Output Parameter:
1295: . reason - the convergence reason; it is positive if the iteration has converged,
1296: negative if the iteration has diverged, and KSP_CONVERGED_ITERATING otherwise
1298: Notes:
1299: KSPConvergedDefault() reaches convergence when rnorm < MAX (rtol * rnorm_0, abstol);
1300: Divergence is detected if rnorm > dtol * rnorm_0, or when failures are detected throughout the iteration.
1301: By default, reaching the maximum number of iterations is considered divergence (i.e. KSP_DIVERGED_ITS).
1302: In order to have PETSc declaring convergence in such a case (i.e. KSP_CONVERGED_ITS), users can use KSPConvergedDefaultSetConvergedMaxits()
1304: where:
1305: + rtol - relative tolerance,
1306: . abstol - absolute tolerance.
1307: . dtol - divergence tolerance,
1308: - rnorm_0 - the two norm of the right hand side (or the preconditioned norm, depending on what was set with
1309: KSPSetNormType(). When initial guess is non-zero you
1310: can call KSPConvergedDefaultSetUIRNorm() to use the norm of (b - A*(initial guess))
1311: as the starting point for relative norm convergence testing, that is as rnorm_0
1313: Use KSPSetTolerances() to alter the defaults for rtol, abstol, dtol.
1315: Use KSPSetNormType() (or -ksp_norm_type <none,preconditioned,unpreconditioned,natural>) to change the norm used for computing rnorm
1317: The precise values of reason are macros such as KSP_CONVERGED_RTOL, which are defined in petscksp.h.
1319: This routine is used by KSP by default so the user generally never needs call it directly.
1321: Use KSPSetConvergenceTest() to provide your own test instead of using this one.
1323: Level: intermediate
1325: .seealso: `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`, `KSPConvergedReason`, `KSPGetConvergedReason()`,
1326: `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetUMIRNorm()`, `KSPConvergedDefaultSetConvergedMaxits()`, `KSPConvergedDefaultCreate()`, `KSPConvergedDefaultDestroy()`
1327: @*/
1328: PetscErrorCode KSPConvergedDefault(KSP ksp, PetscInt n, PetscReal rnorm, KSPConvergedReason *reason, void *ctx)
1329: {
1330: KSPConvergedDefaultCtx *cctx = (KSPConvergedDefaultCtx *)ctx;
1331: KSPNormType normtype;
1337: *reason = KSP_CONVERGED_ITERATING;
1339: if (cctx->convmaxits && n >= ksp->max_it) {
1340: *reason = KSP_CONVERGED_ITS;
1341: PetscInfo(ksp, "Linear solver has converged. Maximum number of iterations reached %" PetscInt_FMT "\n", n);
1342: return 0;
1343: }
1344: KSPGetNormType(ksp, &normtype);
1345: if (normtype == KSP_NORM_NONE) return 0;
1347: if (!n) {
1348: /* if user gives initial guess need to compute norm of b */
1349: if (!ksp->guess_zero && !cctx->initialrtol) {
1350: PetscReal snorm = 0.0;
1351: if (ksp->normtype == KSP_NORM_UNPRECONDITIONED || ksp->pc_side == PC_RIGHT) {
1352: PetscInfo(ksp, "user has provided nonzero initial guess, computing 2-norm of RHS\n");
1353: VecNorm(ksp->vec_rhs, NORM_2, &snorm); /* <- b'*b */
1354: } else {
1355: Vec z;
1356: /* Should avoid allocating the z vector each time but cannot stash it in cctx because if KSPReset() is called the vector size might change */
1357: VecDuplicate(ksp->vec_rhs, &z);
1358: KSP_PCApply(ksp, ksp->vec_rhs, z);
1359: if (ksp->normtype == KSP_NORM_PRECONDITIONED) {
1360: PetscInfo(ksp, "user has provided nonzero initial guess, computing 2-norm of preconditioned RHS\n");
1361: VecNorm(z, NORM_2, &snorm); /* dp <- b'*B'*B*b */
1362: } else if (ksp->normtype == KSP_NORM_NATURAL) {
1363: PetscScalar norm;
1364: PetscInfo(ksp, "user has provided nonzero initial guess, computing natural norm of RHS\n");
1365: VecDot(ksp->vec_rhs, z, &norm);
1366: snorm = PetscSqrtReal(PetscAbsScalar(norm)); /* dp <- b'*B*b */
1367: }
1368: VecDestroy(&z);
1369: }
1370: /* handle special case of zero RHS and nonzero guess */
1371: if (!snorm) {
1372: PetscInfo(ksp, "Special case, user has provided nonzero initial guess and zero RHS\n");
1373: snorm = rnorm;
1374: }
1375: if (cctx->mininitialrtol) ksp->rnorm0 = PetscMin(snorm, rnorm);
1376: else ksp->rnorm0 = snorm;
1377: } else {
1378: ksp->rnorm0 = rnorm;
1379: }
1380: ksp->ttol = PetscMax(ksp->rtol * ksp->rnorm0, ksp->abstol);
1381: }
1383: if (n <= ksp->chknorm) return 0;
1385: if (PetscIsInfOrNanReal(rnorm)) {
1386: PCFailedReason pcreason;
1387: PetscInt sendbuf, recvbuf;
1388: PCGetFailedReasonRank(ksp->pc, &pcreason);
1389: sendbuf = (PetscInt)pcreason;
1390: MPI_Allreduce(&sendbuf, &recvbuf, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)ksp));
1391: if (recvbuf) {
1392: *reason = KSP_DIVERGED_PC_FAILED;
1393: PCSetFailedReason(ksp->pc, (PCFailedReason)recvbuf);
1394: PetscInfo(ksp, "Linear solver pcsetup fails, declaring divergence \n");
1395: } else {
1396: *reason = KSP_DIVERGED_NANORINF;
1397: PetscInfo(ksp, "Linear solver has created a not a number (NaN) as the residual norm, declaring divergence \n");
1398: }
1399: } else if (rnorm <= ksp->ttol) {
1400: if (rnorm < ksp->abstol) {
1401: PetscInfo(ksp, "Linear solver has converged. Residual norm %14.12e is less than absolute tolerance %14.12e at iteration %" PetscInt_FMT "\n", (double)rnorm, (double)ksp->abstol, n);
1402: *reason = KSP_CONVERGED_ATOL;
1403: } else {
1404: if (cctx->initialrtol) {
1405: PetscInfo(ksp, "Linear solver has converged. Residual norm %14.12e is less than relative tolerance %14.12e times initial residual norm %14.12e at iteration %" PetscInt_FMT "\n", (double)rnorm, (double)ksp->rtol, (double)ksp->rnorm0, n);
1406: } else {
1407: PetscInfo(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 %" PetscInt_FMT "\n", (double)rnorm, (double)ksp->rtol, (double)ksp->rnorm0, n);
1408: }
1409: *reason = KSP_CONVERGED_RTOL;
1410: }
1411: } else if (rnorm >= ksp->divtol * ksp->rnorm0) {
1412: PetscInfo(ksp, "Linear solver is diverging. Initial right hand size norm %14.12e, current residual norm %14.12e at iteration %" PetscInt_FMT "\n", (double)ksp->rnorm0, (double)rnorm, n);
1413: *reason = KSP_DIVERGED_DTOL;
1414: }
1415: return 0;
1416: }
1418: /*@C
1419: KSPConvergedDefaultDestroy - Frees the space used by the KSPConvergedDefault() function context
1421: Not Collective
1423: Input Parameters:
1424: . ctx - convergence context
1426: Level: intermediate
1428: .seealso: `KSPConvergedDefault()`, `KSPConvergedDefaultCreate()`, `KSPSetConvergenceTest()`, `KSPSetTolerances()`, `KSPConvergedSkip()`,
1429: `KSPConvergedReason`, `KSPGetConvergedReason()`, `KSPConvergedDefaultSetUIRNorm()`, `KSPConvergedDefaultSetUMIRNorm()`
1430: @*/
1431: PetscErrorCode KSPConvergedDefaultDestroy(void *ctx)
1432: {
1433: KSPConvergedDefaultCtx *cctx = (KSPConvergedDefaultCtx *)ctx;
1435: VecDestroy(&cctx->work);
1436: PetscFree(ctx);
1437: return 0;
1438: }
1440: /*
1441: KSPBuildSolutionDefault - Default code to create/move the solution.
1443: Collective on ksp
1445: Input Parameters:
1446: + ksp - iterative context
1447: - v - pointer to the user's vector
1449: Output Parameter:
1450: . V - pointer to a vector containing the solution
1452: Level: advanced
1454: Developers Note: This is PETSC_EXTERN because it may be used by user written plugin KSP implementations
1456: .seealso: `KSPGetSolution()`, `KSPBuildResidualDefault()`
1457: */
1458: PetscErrorCode KSPBuildSolutionDefault(KSP ksp, Vec v, Vec *V)
1459: {
1460: if (ksp->pc_side == PC_RIGHT) {
1461: if (ksp->pc) {
1462: if (v) {
1463: KSP_PCApply(ksp, ksp->vec_sol, v);
1464: *V = v;
1465: } else SETERRQ(PetscObjectComm((PetscObject)ksp), PETSC_ERR_SUP, "Not working with right preconditioner");
1466: } else {
1467: if (v) {
1468: VecCopy(ksp->vec_sol, v);
1469: *V = v;
1470: } else *V = ksp->vec_sol;
1471: }
1472: } else if (ksp->pc_side == PC_SYMMETRIC) {
1473: if (ksp->pc) {
1475: if (v) {
1476: PCApplySymmetricRight(ksp->pc, ksp->vec_sol, v);
1477: *V = v;
1478: } else SETERRQ(PetscObjectComm((PetscObject)ksp), PETSC_ERR_SUP, "Not working with symmetric preconditioner");
1479: } else {
1480: if (v) {
1481: VecCopy(ksp->vec_sol, v);
1482: *V = v;
1483: } else *V = ksp->vec_sol;
1484: }
1485: } else {
1486: if (v) {
1487: VecCopy(ksp->vec_sol, v);
1488: *V = v;
1489: } else *V = ksp->vec_sol;
1490: }
1491: return 0;
1492: }
1494: /*
1495: KSPBuildResidualDefault - Default code to compute the residual.
1497: Collecive on ksp
1499: Input Parameters:
1500: . ksp - iterative context
1501: . t - pointer to temporary vector
1502: . v - pointer to user vector
1504: Output Parameter:
1505: . V - pointer to a vector containing the residual
1507: Level: advanced
1509: Developers Note: This is PETSC_EXTERN because it may be used by user written plugin KSP implementations
1511: .seealso: `KSPBuildSolutionDefault()`
1512: */
1513: PetscErrorCode KSPBuildResidualDefault(KSP ksp, Vec t, Vec v, Vec *V)
1514: {
1515: Mat Amat, Pmat;
1517: if (!ksp->pc) KSPGetPC(ksp, &ksp->pc);
1518: PCGetOperators(ksp->pc, &Amat, &Pmat);
1519: KSPBuildSolution(ksp, t, NULL);
1520: KSP_MatMult(ksp, Amat, t, v);
1521: VecAYPX(v, -1.0, ksp->vec_rhs);
1522: *V = v;
1523: return 0;
1524: }
1526: /*@C
1527: KSPCreateVecs - Gets a number of work vectors.
1529: Collective on ksp
1531: Input Parameters:
1532: + ksp - iterative context
1533: . rightn - number of right work vectors
1534: - leftn - number of left work vectors to allocate
1536: Output Parameters:
1537: + right - the array of vectors created
1538: - left - the array of left vectors
1540: Note: The right vector has as many elements as the matrix has columns. The left
1541: vector has as many elements as the matrix has rows.
1543: The vectors are new vectors that are not owned by the KSP, they should be destroyed with calls to VecDestroyVecs() when no longer needed.
1545: 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
1546: that does not exist tries to get them from the DM (if it is provided).
1548: Level: advanced
1550: .seealso: `MatCreateVecs()`, `VecDestroyVecs()`
1552: @*/
1553: PetscErrorCode KSPCreateVecs(KSP ksp, PetscInt rightn, Vec **right, PetscInt leftn, Vec **left)
1554: {
1555: Vec vecr = NULL, vecl = NULL;
1556: PetscBool matset, pmatset, isshell, preferdm = PETSC_FALSE;
1557: Mat mat = NULL;
1559: if (ksp->dm) {
1560: PetscObjectTypeCompare((PetscObject)ksp->dm, DMSHELL, &isshell);
1561: preferdm = isshell ? PETSC_FALSE : PETSC_TRUE;
1562: }
1563: if (rightn) {
1565: if (ksp->vec_sol) vecr = ksp->vec_sol;
1566: else {
1567: if (preferdm) {
1568: DMGetGlobalVector(ksp->dm, &vecr);
1569: } else if (ksp->pc) {
1570: PCGetOperatorsSet(ksp->pc, &matset, &pmatset);
1571: /* check for mat before pmat because for KSPLSQR pmat may be a different size than mat since pmat maybe mat'*mat */
1572: if (matset) {
1573: PCGetOperators(ksp->pc, &mat, NULL);
1574: MatCreateVecs(mat, &vecr, NULL);
1575: } else if (pmatset) {
1576: PCGetOperators(ksp->pc, NULL, &mat);
1577: MatCreateVecs(mat, &vecr, NULL);
1578: }
1579: }
1580: if (!vecr && ksp->dm) DMGetGlobalVector(ksp->dm, &vecr);
1582: }
1583: VecDuplicateVecs(vecr, rightn, right);
1584: if (!ksp->vec_sol) {
1585: if (preferdm) {
1586: DMRestoreGlobalVector(ksp->dm, &vecr);
1587: } else if (mat) {
1588: VecDestroy(&vecr);
1589: } else if (ksp->dm) {
1590: DMRestoreGlobalVector(ksp->dm, &vecr);
1591: }
1592: }
1593: }
1594: if (leftn) {
1596: if (ksp->vec_rhs) vecl = ksp->vec_rhs;
1597: else {
1598: if (preferdm) {
1599: DMGetGlobalVector(ksp->dm, &vecl);
1600: } else if (ksp->pc) {
1601: PCGetOperatorsSet(ksp->pc, &matset, &pmatset);
1602: /* check for mat before pmat because for KSPLSQR pmat may be a different size than mat since pmat maybe mat'*mat */
1603: if (matset) {
1604: PCGetOperators(ksp->pc, &mat, NULL);
1605: MatCreateVecs(mat, NULL, &vecl);
1606: } else if (pmatset) {
1607: PCGetOperators(ksp->pc, NULL, &mat);
1608: MatCreateVecs(mat, NULL, &vecl);
1609: }
1610: }
1611: if (!vecl && ksp->dm) DMGetGlobalVector(ksp->dm, &vecl);
1613: }
1614: VecDuplicateVecs(vecl, leftn, left);
1615: if (!ksp->vec_rhs) {
1616: if (preferdm) {
1617: DMRestoreGlobalVector(ksp->dm, &vecl);
1618: } else if (mat) {
1619: VecDestroy(&vecl);
1620: } else if (ksp->dm) {
1621: DMRestoreGlobalVector(ksp->dm, &vecl);
1622: }
1623: }
1624: }
1625: return 0;
1626: }
1628: /*@C
1629: KSPSetWorkVecs - Sets a number of work vectors into a KSP object
1631: Collective on ksp
1633: Input Parameters:
1634: + ksp - iterative context
1635: - nw - number of work vectors to allocate
1637: Level: developer
1639: Developers Note: This is PETSC_EXTERN because it may be used by user written plugin KSP implementations
1641: @*/
1642: PetscErrorCode KSPSetWorkVecs(KSP ksp, PetscInt nw)
1643: {
1644: VecDestroyVecs(ksp->nwork, &ksp->work);
1645: ksp->nwork = nw;
1646: KSPCreateVecs(ksp, nw, &ksp->work, 0, NULL);
1647: return 0;
1648: }
1650: /*
1651: KSPDestroyDefault - Destroys a iterative context variable for methods with
1652: no separate context. Preferred calling sequence KSPDestroy().
1654: Input Parameter:
1655: . ksp - the iterative context
1657: Developers Note: This is PETSC_EXTERN because it may be used by user written plugin KSP implementations
1659: */
1660: PetscErrorCode KSPDestroyDefault(KSP ksp)
1661: {
1663: PetscFree(ksp->data);
1664: return 0;
1665: }
1667: /*@
1668: KSPGetConvergedReason - Gets the reason the KSP iteration was stopped.
1670: Not Collective
1672: Input Parameter:
1673: . ksp - the KSP context
1675: Output Parameter:
1676: . reason - negative value indicates diverged, positive value converged, see KSPConvergedReason
1678: Possible values for reason: See also manual page for each reason
1679: $ KSP_CONVERGED_RTOL (residual 2-norm decreased by a factor of rtol, from 2-norm of right hand side)
1680: $ KSP_CONVERGED_ATOL (residual 2-norm less than abstol)
1681: $ KSP_CONVERGED_ITS (used by the preonly preconditioner that always uses ONE iteration, or when the KSPConvergedSkip() convergence test routine is set.
1682: $ KSP_CONVERGED_CG_NEG_CURVE (see note below)
1683: $ KSP_CONVERGED_CG_CONSTRAINED (see note below)
1684: $ KSP_CONVERGED_STEP_LENGTH (see note below)
1685: $ KSP_CONVERGED_ITERATING (returned if the solver is not yet finished)
1686: $ KSP_DIVERGED_ITS (required more than its to reach convergence)
1687: $ KSP_DIVERGED_DTOL (residual norm increased by a factor of divtol)
1688: $ KSP_DIVERGED_NANORINF (residual norm became Not-a-number or Inf likely due to 0/0)
1689: $ KSP_DIVERGED_BREAKDOWN (generic breakdown in method)
1690: $ KSP_DIVERGED_BREAKDOWN_BICG (Initial residual is orthogonal to preconditioned initial residual. Try a different preconditioner, or a different initial Level.)
1692: Options Database:
1693: . -ksp_converged_reason - prints the reason to standard out
1695: Notes:
1696: If this routine is called before or doing the KSPSolve() the value of KSP_CONVERGED_ITERATING is returned
1698: 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
1699: solvers which are used by the SNESNEWTONTR (trust region) solver.
1701: Level: intermediate
1703: .seealso: `KSPSetConvergenceTest()`, `KSPConvergedDefault()`, `KSPSetTolerances()`, `KSPConvergedReason`,
1704: `KSPConvergedReasonView()`
1705: @*/
1706: PetscErrorCode KSPGetConvergedReason(KSP ksp, KSPConvergedReason *reason)
1707: {
1710: *reason = ksp->reason;
1711: return 0;
1712: }
1714: /*@C
1715: KSPGetConvergedReasonString - Return a human readable string for ksp converged reason
1717: Not Collective
1719: Input Parameter:
1720: . ksp - the KSP context
1722: Output Parameter:
1723: . strreason - a human readable string that describes ksp converged reason
1725: Level: beginner
1727: .seealso: `KSPGetConvergedReason()`
1728: @*/
1729: PetscErrorCode KSPGetConvergedReasonString(KSP ksp, const char **strreason)
1730: {
1733: *strreason = KSPConvergedReasons[ksp->reason];
1734: return 0;
1735: }
1737: #include <petsc/private/dmimpl.h>
1738: /*@
1739: KSPSetDM - Sets the DM that may be used by some preconditioners
1741: Logically Collective on ksp
1743: Input Parameters:
1744: + ksp - the preconditioner context
1745: - dm - the dm, cannot be NULL
1747: Notes:
1748: If this is used then the KSP will attempt to use the DM to create the matrix and use the routine set with
1749: DMKSPSetComputeOperators(). Use KSPSetDMActive(ksp,PETSC_FALSE) to instead use the matrix you've provided with
1750: KSPSetOperators().
1752: A DM can only be used for solving one problem at a time because information about the problem is stored on the DM,
1753: even when not using interfaces like DMKSPSetComputeOperators(). Use DMClone() to get a distinct DM when solving
1754: different problems using the same function space.
1756: Level: intermediate
1758: .seealso: `KSPGetDM()`, `KSPSetDMActive()`, `KSPSetComputeOperators()`, `KSPSetComputeRHS()`, `KSPSetComputeInitialGuess()`, `DMKSPSetComputeOperators()`, `DMKSPSetComputeRHS()`, `DMKSPSetComputeInitialGuess()`
1759: @*/
1760: PetscErrorCode KSPSetDM(KSP ksp, DM dm)
1761: {
1762: PC pc;
1766: PetscObjectReference((PetscObject)dm);
1767: if (ksp->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */
1768: if (ksp->dm->dmksp && !dm->dmksp) {
1769: DMKSP kdm;
1770: DMCopyDMKSP(ksp->dm, dm);
1771: DMGetDMKSP(ksp->dm, &kdm);
1772: if (kdm->originaldm == ksp->dm) kdm->originaldm = dm; /* Grant write privileges to the replacement DM */
1773: }
1774: DMDestroy(&ksp->dm);
1775: }
1776: ksp->dm = dm;
1777: ksp->dmAuto = PETSC_FALSE;
1778: KSPGetPC(ksp, &pc);
1779: PCSetDM(pc, dm);
1780: ksp->dmActive = PETSC_TRUE;
1781: return 0;
1782: }
1784: /*@
1785: KSPSetDMActive - Indicates the DM should be used to generate the linear system matrix and right hand side
1787: Logically Collective on ksp
1789: Input Parameters:
1790: + ksp - the preconditioner context
1791: - flg - use the DM
1793: Notes:
1794: 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.
1796: Level: intermediate
1798: .seealso: `KSPGetDM()`, `KSPSetDM()`, `SNESSetDM()`, `KSPSetComputeOperators()`, `KSPSetComputeRHS()`, `KSPSetComputeInitialGuess()`
1799: @*/
1800: PetscErrorCode KSPSetDMActive(KSP ksp, PetscBool flg)
1801: {
1804: ksp->dmActive = flg;
1805: return 0;
1806: }
1808: /*@
1809: KSPGetDM - Gets the DM that may be used by some preconditioners
1811: Not Collective
1813: Input Parameter:
1814: . ksp - the preconditioner context
1816: Output Parameter:
1817: . dm - the dm
1819: Level: intermediate
1821: .seealso: `KSPSetDM()`, `KSPSetDMActive()`
1822: @*/
1823: PetscErrorCode KSPGetDM(KSP ksp, DM *dm)
1824: {
1826: if (!ksp->dm) {
1827: DMShellCreate(PetscObjectComm((PetscObject)ksp), &ksp->dm);
1828: ksp->dmAuto = PETSC_TRUE;
1829: }
1830: *dm = ksp->dm;
1831: return 0;
1832: }
1834: /*@
1835: KSPSetApplicationContext - Sets the optional user-defined context for the linear solver.
1837: Logically Collective on ksp
1839: Input Parameters:
1840: + ksp - the KSP context
1841: - usrP - optional user context
1843: Fortran Notes:
1844: To use this from Fortran you must write a Fortran interface definition for this
1845: function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1847: Level: intermediate
1849: .seealso: `KSPGetApplicationContext()`
1850: @*/
1851: PetscErrorCode KSPSetApplicationContext(KSP ksp, void *usrP)
1852: {
1853: PC pc;
1856: ksp->user = usrP;
1857: KSPGetPC(ksp, &pc);
1858: PCSetApplicationContext(pc, usrP);
1859: return 0;
1860: }
1862: /*@
1863: KSPGetApplicationContext - Gets the user-defined context for the linear solver.
1865: Not Collective
1867: Input Parameter:
1868: . ksp - KSP context
1870: Output Parameter:
1871: . usrP - user context
1873: Fortran Notes:
1874: To use this from Fortran you must write a Fortran interface definition for this
1875: function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1877: Level: intermediate
1879: .seealso: `KSPSetApplicationContext()`
1880: @*/
1881: PetscErrorCode KSPGetApplicationContext(KSP ksp, void *usrP)
1882: {
1884: *(void **)usrP = ksp->user;
1885: return 0;
1886: }
1888: #include <petsc/private/pcimpl.h>
1890: /*@
1891: KSPCheckSolve - Checks if the PCSetUp() or KSPSolve() failed and set the error flag for the outer PC. A KSP_DIVERGED_ITS is
1892: not considered a failure in this context
1894: Collective on ksp
1896: Input Parameters:
1897: + ksp - the linear solver (KSP) context.
1898: . pc - the preconditioner context
1899: - vec - a vector that will be initialized with Inf to indicate lack of convergence
1901: Notes: this may be called by a subset of the processes in the PC
1903: Level: developer
1905: Developer Note: this is used to manage returning from preconditioners whose inner KSP solvers have failed in some way
1907: .seealso: `KSPCreate()`, `KSPSetType()`, `KSP`, `KSPCheckNorm()`, `KSPCheckDot()`
1908: @*/
1909: PetscErrorCode KSPCheckSolve(KSP ksp, PC pc, Vec vec)
1910: {
1911: PCFailedReason pcreason;
1912: PC subpc;
1914: KSPGetPC(ksp, &subpc);
1915: PCGetFailedReason(subpc, &pcreason);
1916: if (pcreason || (ksp->reason < 0 && ksp->reason != KSP_DIVERGED_ITS)) {
1918: PetscInfo(ksp, "Detected not converged in KSP inner solve: KSP reason %s PC reason %s\n", KSPConvergedReasons[ksp->reason], PCFailedReasons[pcreason]);
1919: pc->failedreason = PC_SUBPC_ERROR;
1920: if (vec) VecSetInf(vec);
1921: }
1922: return 0;
1923: }