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: }