xref: /petsc/src/ts/utils/dmnetworkts.c (revision be37439ebbbdb2f81c3420c175a94aa72e59929c)
1 #include <petsc/private/dmnetworkimpl.h> /*I "petscdmplex.h" I*/
2 #include <petscts.h>
3 #include <petscdraw.h>
4 
5 /*@C
6   TSMonitorLGCtxNetworkDestroy - Destroys  line graph contexts that where created with `TSMonitorLGCtxNetworkCreate()`.
7 
8   Collective
9 
10   Input Parameter:
11 . ctx - the monitor context
12 
13   Level: intermediate
14 
15 .seealso: [](ch_ts), `TS`, `TSMonitorLGCtxNetworkSolution()`
16 @*/
TSMonitorLGCtxNetworkDestroy(TSMonitorLGCtxNetwork * ctx)17 PetscErrorCode TSMonitorLGCtxNetworkDestroy(TSMonitorLGCtxNetwork *ctx)
18 {
19   PetscInt i;
20 
21   PetscFunctionBegin;
22   for (i = 0; i < (*ctx)->nlg; i++) PetscCall(PetscDrawLGDestroy(&(*ctx)->lg[i]));
23   PetscCall(PetscFree((*ctx)->lg));
24   PetscCall(PetscFree(*ctx));
25   PetscFunctionReturn(PETSC_SUCCESS);
26 }
27 
TSMonitorLGCtxNetworkCreate(TS ts,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtxNetwork * ctx)28 PetscErrorCode TSMonitorLGCtxNetworkCreate(TS ts, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, TSMonitorLGCtxNetwork *ctx)
29 {
30   PetscDraw draw;
31   MPI_Comm  comm;
32   DM        dm;
33   PetscInt  i, Start, End, e, nvar;
34 
35   PetscFunctionBegin;
36   PetscCall(TSGetDM(ts, &dm));
37   PetscCall(PetscObjectGetComm((PetscObject)ts, &comm));
38   PetscCall(PetscNew(ctx));
39   i = 0;
40   /* loop over edges counting number of line graphs needed */
41   PetscCall(DMNetworkGetEdgeRange(dm, &Start, &End));
42   for (e = Start; e < End; e++) {
43     PetscCall(DMNetworkGetComponent(dm, e, ALL_COMPONENTS, NULL, NULL, &nvar));
44     if (!nvar) continue;
45     i++;
46   }
47   /* loop over vertices */
48   PetscCall(DMNetworkGetVertexRange(dm, &Start, &End));
49   for (e = Start; e < End; e++) {
50     PetscCall(DMNetworkGetComponent(dm, e, ALL_COMPONENTS, NULL, NULL, &nvar));
51     if (!nvar) continue;
52     i++;
53   }
54   (*ctx)->nlg = i;
55   PetscCall(PetscMalloc1(i, &(*ctx)->lg));
56 
57   i = 0;
58   /* loop over edges creating all needed line graphs*/
59   PetscCall(DMNetworkGetEdgeRange(dm, &Start, &End));
60   for (e = Start; e < End; e++) {
61     PetscCall(DMNetworkGetComponent(dm, e, ALL_COMPONENTS, NULL, NULL, &nvar));
62     if (!nvar) continue;
63     PetscCall(PetscDrawCreate(comm, host, label, x, y, m, n, &draw));
64     PetscCall(PetscDrawSetFromOptions(draw));
65     PetscCall(PetscDrawLGCreate(draw, nvar, &(*ctx)->lg[i]));
66     PetscCall(PetscDrawLGSetFromOptions((*ctx)->lg[i]));
67     PetscCall(PetscDrawDestroy(&draw));
68     i++;
69   }
70   /* loop over vertices */
71   PetscCall(DMNetworkGetVertexRange(dm, &Start, &End));
72   for (e = Start; e < End; e++) {
73     PetscCall(DMNetworkGetComponent(dm, e, ALL_COMPONENTS, NULL, NULL, &nvar));
74     if (!nvar) continue;
75     PetscCall(PetscDrawCreate(comm, host, label, x, y, m, n, &draw));
76     PetscCall(PetscDrawSetFromOptions(draw));
77     PetscCall(PetscDrawLGCreate(draw, nvar, &(*ctx)->lg[i]));
78     PetscCall(PetscDrawLGSetFromOptions((*ctx)->lg[i]));
79     PetscCall(PetscDrawDestroy(&draw));
80     i++;
81   }
82   PetscCall(PetscDrawDestroy(&draw));
83   (*ctx)->howoften = howoften;
84   PetscFunctionReturn(PETSC_SUCCESS);
85 }
86 
87 /*@C
88   TSMonitorLGCtxNetworkSolution - Monitors progress of the `TS` solvers for a `DMNETWORK` solution with one window for each vertex and each edge
89 
90   Collective
91 
92   Input Parameters:
93 + ts    - the `TS` context
94 . step  - current time-step
95 . ptime - current time
96 . u     - current solution
97 - dctx  - the `TSMonitorLGCtxNetwork` object that contains all the options for the monitoring, this is created with `TSMonitorLGCtxCreateNetwork()`
98 
99   Options Database Key:
100 . -ts_monitor_lg_solution_variables - monitor solution variables
101 
102   Level: intermediate
103 
104   Note:
105   Each process in a parallel run displays its component solutions in a separate graphics window
106 
107 .seealso: [](ch_ts), `TS`, `TSMonitorLGCtxNetworkDestroy()`
108 @*/
TSMonitorLGCtxNetworkSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void * dctx)109 PetscErrorCode TSMonitorLGCtxNetworkSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx)
110 {
111 #if defined(PETSC_USE_COMPLEX)
112   PetscFunctionBegin;
113   PetscFunctionReturn(PETSC_SUCCESS);
114 #else
115   TSMonitorLGCtxNetwork ctx = (TSMonitorLGCtxNetwork)dctx;
116   const PetscScalar    *xv;
117   PetscScalar          *yv;
118   PetscInt              i, v, Start, End, offset, nvar, e;
119   TSConvergedReason     reason;
120   DM                    dm;
121   Vec                   uv;
122 
123   PetscFunctionBegin;
124   if (step < 0) PetscFunctionReturn(PETSC_SUCCESS); /* -1 indicates interpolated solution */
125   if (!step) {
126     PetscDrawAxis axis;
127 
128     for (i = 0; i < ctx->nlg; i++) {
129       PetscCall(PetscDrawLGGetAxis(ctx->lg[i], &axis));
130       PetscCall(PetscDrawAxisSetLabels(axis, "Solution as function of time", "Time", "Solution"));
131       PetscCall(PetscDrawLGReset(ctx->lg[i]));
132     }
133   }
134 
135   if (ctx->semilogy) {
136     PetscInt n, j;
137 
138     PetscCall(VecDuplicate(u, &uv));
139     PetscCall(VecCopy(u, uv));
140     PetscCall(VecGetArray(uv, &yv));
141     PetscCall(VecGetLocalSize(uv, &n));
142     for (j = 0; j < n; j++) {
143       if (PetscRealPart(yv[j]) <= 0.0) yv[j] = -12;
144       else yv[j] = PetscLog10Real(PetscRealPart(yv[j]));
145     }
146     xv = yv;
147   } else {
148     PetscCall(VecGetArrayRead(u, &xv));
149   }
150   /* iterate over edges */
151   PetscCall(TSGetDM(ts, &dm));
152   i = 0;
153   PetscCall(DMNetworkGetEdgeRange(dm, &Start, &End));
154   for (e = Start; e < End; e++) {
155     PetscCall(DMNetworkGetComponent(dm, e, ALL_COMPONENTS, NULL, NULL, &nvar));
156     if (!nvar) continue;
157 
158     PetscCall(DMNetworkGetLocalVecOffset(dm, e, ALL_COMPONENTS, &offset));
159     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg[i], ptime, xv + offset));
160     i++;
161   }
162 
163   /* iterate over vertices */
164   PetscCall(DMNetworkGetVertexRange(dm, &Start, &End));
165   for (v = Start; v < End; v++) {
166     PetscCall(DMNetworkGetComponent(dm, v, ALL_COMPONENTS, NULL, NULL, &nvar));
167     if (!nvar) continue;
168 
169     PetscCall(DMNetworkGetLocalVecOffset(dm, v, ALL_COMPONENTS, &offset));
170     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg[i], ptime, xv + offset));
171     i++;
172   }
173   if (ctx->semilogy) {
174     PetscCall(VecRestoreArray(uv, &yv));
175     PetscCall(VecDestroy(&uv));
176   } else {
177     PetscCall(VecRestoreArrayRead(u, &xv));
178   }
179 
180   PetscCall(TSGetConvergedReason(ts, &reason));
181   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && reason)) {
182     for (i = 0; i < ctx->nlg; i++) {
183       PetscCall(PetscDrawLGDraw(ctx->lg[i]));
184       PetscCall(PetscDrawLGSave(ctx->lg[i]));
185     }
186   }
187   PetscFunctionReturn(PETSC_SUCCESS);
188 #endif
189 }
190