Actual source code: dmnetworkts.c

  1: #include <petsc/private/dmnetworkimpl.h>
  2: #include <petscts.h>
  3: #include <petscdraw.h>

  5: /*
  6:    TSMonitorLGCtxDestroy - Destroys  line graph contexts that where created with TSMonitorLGCtxNetworkCreate().

  8:    Collective

 10:    Input Parameter:
 11: .  ctx - the monitor context

 13: */
 14: PetscErrorCode TSMonitorLGCtxNetworkDestroy(TSMonitorLGCtxNetwork *ctx)
 15: {
 16:   PetscInt i;

 18:   for (i = 0; i < (*ctx)->nlg; i++) PetscDrawLGDestroy(&(*ctx)->lg[i]);
 19:   PetscFree((*ctx)->lg);
 20:   PetscFree(*ctx);
 21:   return 0;
 22: }

 24: PetscErrorCode TSMonitorLGCtxNetworkCreate(TS ts, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, TSMonitorLGCtxNetwork *ctx)
 25: {
 26:   PetscDraw draw;
 27:   MPI_Comm  comm;
 28:   DM        dm;
 29:   PetscInt  i, Start, End, e, nvar;

 31:   TSGetDM(ts, &dm);
 32:   PetscObjectGetComm((PetscObject)ts, &comm);
 33:   PetscNew(ctx);
 34:   i = 0;
 35:   /* loop over edges counting number of line graphs needed */
 36:   DMNetworkGetEdgeRange(dm, &Start, &End);
 37:   for (e = Start; e < End; e++) {
 38:     DMNetworkGetComponent(dm, e, ALL_COMPONENTS, NULL, NULL, &nvar);
 39:     if (!nvar) continue;
 40:     i++;
 41:   }
 42:   /* loop over vertices */
 43:   DMNetworkGetVertexRange(dm, &Start, &End);
 44:   for (e = Start; e < End; e++) {
 45:     DMNetworkGetComponent(dm, e, ALL_COMPONENTS, NULL, NULL, &nvar);
 46:     if (!nvar) continue;
 47:     i++;
 48:   }
 49:   (*ctx)->nlg = i;
 50:   PetscMalloc1(i, &(*ctx)->lg);

 52:   i = 0;
 53:   /* loop over edges creating all needed line graphs*/
 54:   DMNetworkGetEdgeRange(dm, &Start, &End);
 55:   for (e = Start; e < End; e++) {
 56:     DMNetworkGetComponent(dm, e, ALL_COMPONENTS, NULL, NULL, &nvar);
 57:     if (!nvar) continue;
 58:     PetscDrawCreate(comm, host, label, x, y, m, n, &draw);
 59:     PetscDrawSetFromOptions(draw);
 60:     PetscDrawLGCreate(draw, nvar, &(*ctx)->lg[i]);
 61:     PetscDrawLGSetFromOptions((*ctx)->lg[i]);
 62:     PetscDrawDestroy(&draw);
 63:     i++;
 64:   }
 65:   /* loop over vertices */
 66:   DMNetworkGetVertexRange(dm, &Start, &End);
 67:   for (e = Start; e < End; e++) {
 68:     DMNetworkGetComponent(dm, e, ALL_COMPONENTS, NULL, NULL, &nvar);
 69:     if (!nvar) continue;
 70:     PetscDrawCreate(comm, host, label, x, y, m, n, &draw);
 71:     PetscDrawSetFromOptions(draw);
 72:     PetscDrawLGCreate(draw, nvar, &(*ctx)->lg[i]);
 73:     PetscDrawLGSetFromOptions((*ctx)->lg[i]);
 74:     PetscDrawDestroy(&draw);
 75:     i++;
 76:   }
 77:   PetscDrawDestroy(&draw);
 78:   (*ctx)->howoften = howoften;
 79:   return 0;
 80: }

 82: /*
 83:    TSMonitorLGCtxNetworkSolution - Monitors progress of the `TS` solvers for a `DMNETWORK` solution with one window for each vertex and each edge

 85:    Collective

 87:    Input Parameters:
 88: +  ts - the `TS` context
 89: .  step - current time-step
 90: .  ptime - current time
 91: .  u - current solution
 92: -  dctx - the `TSMonitorLGCtxNetwork` object that contains all the options for the monitoring, this is created with `TSMonitorLGCtxCreateNetwork()`

 94:    Options Database Key:
 95: .   -ts_monitor_lg_solution_variables

 97:    Level: intermediate

 99:    Note:
100:     Each process in a parallel run displays its component solutions in a separate window

102: */
103: PetscErrorCode TSMonitorLGCtxNetworkSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx)
104: {
105:   TSMonitorLGCtxNetwork ctx = (TSMonitorLGCtxNetwork)dctx;
106:   const PetscScalar    *xv;
107:   PetscScalar          *yv;
108:   PetscInt              i, v, Start, End, offset, nvar, e;
109:   TSConvergedReason     reason;
110:   DM                    dm;
111:   Vec                   uv;

113:   if (step < 0) return 0; /* -1 indicates interpolated solution */
114:   if (!step) {
115:     PetscDrawAxis axis;

117:     for (i = 0; i < ctx->nlg; i++) {
118:       PetscDrawLGGetAxis(ctx->lg[i], &axis);
119:       PetscDrawAxisSetLabels(axis, "Solution as function of time", "Time", "Solution");
120:       PetscDrawLGReset(ctx->lg[i]);
121:     }
122:   }

124:   if (ctx->semilogy) {
125:     PetscInt n, j;

127:     VecDuplicate(u, &uv);
128:     VecCopy(u, uv);
129:     VecGetArray(uv, &yv);
130:     VecGetLocalSize(uv, &n);
131:     for (j = 0; j < n; j++) {
132:       if (PetscRealPart(yv[j]) <= 0.0) yv[j] = -12;
133:       else yv[j] = PetscLog10Real(PetscRealPart(yv[j]));
134:     }
135:     xv = yv;
136:   } else {
137:     VecGetArrayRead(u, &xv);
138:   }
139:   /* iterate over edges */
140:   TSGetDM(ts, &dm);
141:   i = 0;
142:   DMNetworkGetEdgeRange(dm, &Start, &End);
143:   for (e = Start; e < End; e++) {
144:     DMNetworkGetComponent(dm, e, ALL_COMPONENTS, NULL, NULL, &nvar);
145:     if (!nvar) continue;

147:     DMNetworkGetLocalVecOffset(dm, e, ALL_COMPONENTS, &offset);
148:     PetscDrawLGAddCommonPoint(ctx->lg[i], ptime, (const PetscReal *)(xv + offset));
149:     i++;
150:   }

152:   /* iterate over vertices */
153:   DMNetworkGetVertexRange(dm, &Start, &End);
154:   for (v = Start; v < End; v++) {
155:     DMNetworkGetComponent(dm, v, ALL_COMPONENTS, NULL, NULL, &nvar);
156:     if (!nvar) continue;

158:     DMNetworkGetLocalVecOffset(dm, v, ALL_COMPONENTS, &offset);
159:     PetscDrawLGAddCommonPoint(ctx->lg[i], ptime, (const PetscReal *)(xv + offset));
160:     i++;
161:   }
162:   if (ctx->semilogy) {
163:     VecRestoreArray(uv, &yv);
164:     VecDestroy(&uv);
165:   } else {
166:     VecRestoreArrayRead(u, &xv);
167:   }

169:   TSGetConvergedReason(ts, &reason);
170:   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && reason)) {
171:     for (i = 0; i < ctx->nlg; i++) {
172:       PetscDrawLGDraw(ctx->lg[i]);
173:       PetscDrawLGSave(ctx->lg[i]);
174:     }
175:   }
176:   return 0;
177: }