xref: /petsc/src/ksp/ksp/interface/xmon.c (revision ea9ee2c1d69c9e3cf6d2b3c8a205b9880d3dba39)
1 
2 #include <petsc/private/kspimpl.h> /*I  "petscksp.h"   I*/
3 #include <petscdraw.h>
4 
5 PetscErrorCode KSPMonitorLGCreate(MPI_Comm comm, const char host[], const char label[], const char metric[], PetscInt l, const char *names[], int x, int y, int m, int n, PetscDrawLG *lgctx)
6 {
7   PetscDraw     draw;
8   PetscDrawAxis axis;
9   PetscDrawLG   lg;
10 
11   PetscFunctionBegin;
12   PetscCall(PetscDrawCreate(comm, host, label, x, y, m, n, &draw));
13   PetscCall(PetscDrawSetFromOptions(draw));
14   PetscCall(PetscDrawLGCreate(draw, l, &lg));
15   if (names) PetscCall(PetscDrawLGSetLegend(lg, names));
16   PetscCall(PetscDrawLGSetFromOptions(lg));
17   PetscCall(PetscDrawLGGetAxis(lg, &axis));
18   PetscCall(PetscDrawAxisSetLabels(axis, "Convergence", "Iteration", metric));
19   PetscCall(PetscDrawDestroy(&draw));
20   *lgctx = lg;
21   PetscFunctionReturn(PETSC_SUCCESS);
22 }
23 
24 PetscErrorCode KSPMonitorLGRange(KSP ksp, PetscInt n, PetscReal rnorm, void *monctx)
25 {
26   PetscDrawLG      lg;
27   PetscReal        x, y, per;
28   PetscViewer      v = (PetscViewer)monctx;
29   static PetscReal prev; /* should be in the context */
30   PetscDraw        draw;
31 
32   PetscFunctionBegin;
33   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 4);
34 
35   PetscCall(KSPMonitorRange_Private(ksp, n, &per));
36   if (!n) prev = rnorm;
37 
38   PetscCall(PetscViewerDrawGetDrawLG(v, 0, &lg));
39   if (!n) PetscCall(PetscDrawLGReset(lg));
40   PetscCall(PetscDrawLGGetDraw(lg, &draw));
41   PetscCall(PetscDrawSetTitle(draw, "Residual norm"));
42   x = (PetscReal)n;
43   if (rnorm > 0.0) y = PetscLog10Real(rnorm);
44   else y = -15.0;
45   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
46   if (n < 20 || !(n % 5) || ksp->reason) {
47     PetscCall(PetscDrawLGDraw(lg));
48     PetscCall(PetscDrawLGSave(lg));
49   }
50 
51   PetscCall(PetscViewerDrawGetDrawLG(v, 1, &lg));
52   if (!n) PetscCall(PetscDrawLGReset(lg));
53   PetscCall(PetscDrawLGGetDraw(lg, &draw));
54   PetscCall(PetscDrawSetTitle(draw, "% elements > .2*max element"));
55   x = (PetscReal)n;
56   y = 100.0 * per;
57   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
58   if (n < 20 || !(n % 5) || ksp->reason) {
59     PetscCall(PetscDrawLGDraw(lg));
60     PetscCall(PetscDrawLGSave(lg));
61   }
62 
63   PetscCall(PetscViewerDrawGetDrawLG(v, 2, &lg));
64   if (!n) PetscCall(PetscDrawLGReset(lg));
65   PetscCall(PetscDrawLGGetDraw(lg, &draw));
66   PetscCall(PetscDrawSetTitle(draw, "(norm-oldnorm)/oldnorm"));
67   x = (PetscReal)n;
68   y = (prev - rnorm) / prev;
69   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
70   if (n < 20 || !(n % 5) || ksp->reason) {
71     PetscCall(PetscDrawLGDraw(lg));
72     PetscCall(PetscDrawLGSave(lg));
73   }
74 
75   PetscCall(PetscViewerDrawGetDrawLG(v, 3, &lg));
76   if (!n) PetscCall(PetscDrawLGReset(lg));
77   PetscCall(PetscDrawLGGetDraw(lg, &draw));
78   PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm*(% > .2 max)"));
79   x = (PetscReal)n;
80   y = (prev - rnorm) / (prev * per);
81   if (n > 5) PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
82   if (n < 20 || !(n % 5) || ksp->reason) {
83     PetscCall(PetscDrawLGDraw(lg));
84     PetscCall(PetscDrawLGSave(lg));
85   }
86 
87   prev = rnorm;
88   PetscFunctionReturn(PETSC_SUCCESS);
89 }
90