Actual source code: xmon.c

  1: #include <petsc/private/kspimpl.h>
  2: #include <petscdraw.h>

  4: 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)
  5: {
  6:   PetscDraw     draw;
  7:   PetscDrawAxis axis;
  8:   PetscDrawLG   lg;

 10:   PetscFunctionBegin;
 11:   PetscCall(PetscDrawCreate(comm, host, label, x, y, m, n, &draw));
 12:   PetscCall(PetscDrawSetFromOptions(draw));
 13:   PetscCall(PetscDrawLGCreate(draw, l, &lg));
 14:   if (names) PetscCall(PetscDrawLGSetLegend(lg, names));
 15:   PetscCall(PetscDrawLGSetFromOptions(lg));
 16:   PetscCall(PetscDrawLGGetAxis(lg, &axis));
 17:   PetscCall(PetscDrawAxisSetLabels(axis, "Convergence", "Iteration", metric));
 18:   PetscCall(PetscDrawDestroy(&draw));
 19:   *lgctx = lg;
 20:   PetscFunctionReturn(PETSC_SUCCESS);
 21: }

 23: PetscErrorCode KSPMonitorLGRange(KSP ksp, PetscInt n, PetscReal rnorm, void *monctx)
 24: {
 25:   PetscDrawLG      lg;
 26:   PetscReal        x, y, per;
 27:   PetscViewer      v = (PetscViewer)monctx;
 28:   static PetscReal prev; /* should be in the context */
 29:   PetscDraw        draw;

 31:   PetscFunctionBegin;

 34:   PetscCall(KSPMonitorRange_Private(ksp, n, &per));
 35:   if (!n) prev = rnorm;

 37:   PetscCall(PetscViewerDrawGetDrawLG(v, 0, &lg));
 38:   if (!n) PetscCall(PetscDrawLGReset(lg));
 39:   PetscCall(PetscDrawLGGetDraw(lg, &draw));
 40:   PetscCall(PetscDrawSetTitle(draw, "Residual norm"));
 41:   x = (PetscReal)n;
 42:   if (rnorm > 0.0) y = PetscLog10Real(rnorm);
 43:   else y = -15.0;
 44:   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
 45:   if (n < 20 || !(n % 5) || ksp->reason) {
 46:     PetscCall(PetscDrawLGDraw(lg));
 47:     PetscCall(PetscDrawLGSave(lg));
 48:   }

 50:   PetscCall(PetscViewerDrawGetDrawLG(v, 1, &lg));
 51:   if (!n) PetscCall(PetscDrawLGReset(lg));
 52:   PetscCall(PetscDrawLGGetDraw(lg, &draw));
 53:   PetscCall(PetscDrawSetTitle(draw, "% elements > .2*max element"));
 54:   x = (PetscReal)n;
 55:   y = 100.0 * per;
 56:   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
 57:   if (n < 20 || !(n % 5) || ksp->reason) {
 58:     PetscCall(PetscDrawLGDraw(lg));
 59:     PetscCall(PetscDrawLGSave(lg));
 60:   }

 62:   PetscCall(PetscViewerDrawGetDrawLG(v, 2, &lg));
 63:   if (!n) PetscCall(PetscDrawLGReset(lg));
 64:   PetscCall(PetscDrawLGGetDraw(lg, &draw));
 65:   PetscCall(PetscDrawSetTitle(draw, "(norm-oldnorm)/oldnorm"));
 66:   x = (PetscReal)n;
 67:   y = (prev - rnorm) / prev;
 68:   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
 69:   if (n < 20 || !(n % 5) || ksp->reason) {
 70:     PetscCall(PetscDrawLGDraw(lg));
 71:     PetscCall(PetscDrawLGSave(lg));
 72:   }

 74:   PetscCall(PetscViewerDrawGetDrawLG(v, 3, &lg));
 75:   if (!n) PetscCall(PetscDrawLGReset(lg));
 76:   PetscCall(PetscDrawLGGetDraw(lg, &draw));
 77:   PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm*(% > .2 max)"));
 78:   x = (PetscReal)n;
 79:   y = (prev - rnorm) / (prev * per);
 80:   if (n > 5) PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
 81:   if (n < 20 || !(n % 5) || ksp->reason) {
 82:     PetscCall(PetscDrawLGDraw(lg));
 83:     PetscCall(PetscDrawLGSave(lg));
 84:   }

 86:   prev = rnorm;
 87:   PetscFunctionReturn(PETSC_SUCCESS);
 88: }