xref: /petsc/src/ts/interface/tsmon.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
1d0c080abSJoseph Pusztay #include <petsc/private/tsimpl.h> /*I "petscts.h"  I*/
2d0c080abSJoseph Pusztay #include <petscdm.h>
307eaae0cSMatthew G. Knepley #include <petscds.h>
4ab43fcacSJoe Pusztay #include <petscdmswarm.h>
5d0c080abSJoseph Pusztay #include <petscdraw.h>
6d0c080abSJoseph Pusztay 
7d0c080abSJoseph Pusztay /*@C
8d0c080abSJoseph Pusztay    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()
9d0c080abSJoseph Pusztay 
10d0c080abSJoseph Pusztay    Collective on TS
11d0c080abSJoseph Pusztay 
12d0c080abSJoseph Pusztay    Input Parameters:
13d0c080abSJoseph Pusztay +  ts - time stepping context obtained from TSCreate()
14d0c080abSJoseph Pusztay .  step - step number that has just completed
15d0c080abSJoseph Pusztay .  ptime - model time of the state
16d0c080abSJoseph Pusztay -  u - state at the current model time
17d0c080abSJoseph Pusztay 
18d0c080abSJoseph Pusztay    Notes:
19d0c080abSJoseph Pusztay    TSMonitor() is typically used automatically within the time stepping implementations.
20d0c080abSJoseph Pusztay    Users would almost never call this routine directly.
21d0c080abSJoseph Pusztay 
22d0c080abSJoseph Pusztay    A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions
23d0c080abSJoseph Pusztay 
24d0c080abSJoseph Pusztay    Level: developer
25d0c080abSJoseph Pusztay 
26d0c080abSJoseph Pusztay @*/
279371c9d4SSatish Balay PetscErrorCode TSMonitor(TS ts, PetscInt step, PetscReal ptime, Vec u) {
28d0c080abSJoseph Pusztay   DM       dm;
29d0c080abSJoseph Pusztay   PetscInt i, n = ts->numbermonitors;
30d0c080abSJoseph Pusztay 
31d0c080abSJoseph Pusztay   PetscFunctionBegin;
32d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
33d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(u, VEC_CLASSID, 4);
34d0c080abSJoseph Pusztay 
359566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
369566063dSJacob Faibussowitsch   PetscCall(DMSetOutputSequenceNumber(dm, step, ptime));
37d0c080abSJoseph Pusztay 
389566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(u));
39*48a46eb9SPierre Jolivet   for (i = 0; i < n; i++) PetscCall((*ts->monitor[i])(ts, step, ptime, u, ts->monitorcontext[i]));
409566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(u));
41d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
42d0c080abSJoseph Pusztay }
43d0c080abSJoseph Pusztay 
44d0c080abSJoseph Pusztay /*@C
45d0c080abSJoseph Pusztay    TSMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
46d0c080abSJoseph Pusztay 
47d0c080abSJoseph Pusztay    Collective on TS
48d0c080abSJoseph Pusztay 
49d0c080abSJoseph Pusztay    Input Parameters:
50d0c080abSJoseph Pusztay +  ts - TS object you wish to monitor
51d0c080abSJoseph Pusztay .  name - the monitor type one is seeking
52d0c080abSJoseph Pusztay .  help - message indicating what monitoring is done
53d0c080abSJoseph Pusztay .  manual - manual page for the monitor
54d0c080abSJoseph Pusztay .  monitor - the monitor function
55d0c080abSJoseph Pusztay -  monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the TS or PetscViewer objects
56d0c080abSJoseph Pusztay 
57d0c080abSJoseph Pusztay    Level: developer
58d0c080abSJoseph Pusztay 
59db781477SPatrick Sanan .seealso: `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
60db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
61db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
62db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
63c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
64db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
65db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
66d0c080abSJoseph Pusztay @*/
679371c9d4SSatish Balay PetscErrorCode TSMonitorSetFromOptions(TS ts, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(TS, PetscInt, PetscReal, Vec, PetscViewerAndFormat *), PetscErrorCode (*monitorsetup)(TS, PetscViewerAndFormat *)) {
68d0c080abSJoseph Pusztay   PetscViewer       viewer;
69d0c080abSJoseph Pusztay   PetscViewerFormat format;
70d0c080abSJoseph Pusztay   PetscBool         flg;
71d0c080abSJoseph Pusztay 
72d0c080abSJoseph Pusztay   PetscFunctionBegin;
739566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts), ((PetscObject)ts)->options, ((PetscObject)ts)->prefix, name, &viewer, &format, &flg));
74d0c080abSJoseph Pusztay   if (flg) {
75d0c080abSJoseph Pusztay     PetscViewerAndFormat *vf;
769566063dSJacob Faibussowitsch     PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf));
779566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject)viewer));
781baa6e33SBarry Smith     if (monitorsetup) PetscCall((*monitorsetup)(ts, vf));
799566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, (PetscErrorCode(*)(TS, PetscInt, PetscReal, Vec, void *))monitor, vf, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy));
80d0c080abSJoseph Pusztay   }
81d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
82d0c080abSJoseph Pusztay }
83d0c080abSJoseph Pusztay 
84d0c080abSJoseph Pusztay /*@C
85d0c080abSJoseph Pusztay    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
86d0c080abSJoseph Pusztay    timestep to display the iteration's  progress.
87d0c080abSJoseph Pusztay 
88d0c080abSJoseph Pusztay    Logically Collective on TS
89d0c080abSJoseph Pusztay 
90d0c080abSJoseph Pusztay    Input Parameters:
91d0c080abSJoseph Pusztay +  ts - the TS context obtained from TSCreate()
92d0c080abSJoseph Pusztay .  monitor - monitoring routine
93d0c080abSJoseph Pusztay .  mctx - [optional] user-defined context for private data for the
94d0c080abSJoseph Pusztay              monitor routine (use NULL if no context is desired)
95d0c080abSJoseph Pusztay -  monitordestroy - [optional] routine that frees monitor context
96d0c080abSJoseph Pusztay           (may be NULL)
97d0c080abSJoseph Pusztay 
98d0c080abSJoseph Pusztay    Calling sequence of monitor:
99d0c080abSJoseph Pusztay $    PetscErrorCode monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
100d0c080abSJoseph Pusztay 
101d0c080abSJoseph Pusztay +    ts - the TS context
102d0c080abSJoseph Pusztay .    steps - iteration number (after the final time step the monitor routine may be called with a step of -1, this indicates the solution has been interpolated to this time)
103d0c080abSJoseph Pusztay .    time - current time
104d0c080abSJoseph Pusztay .    u - current iterate
105d0c080abSJoseph Pusztay -    mctx - [optional] monitoring context
106d0c080abSJoseph Pusztay 
107d0c080abSJoseph Pusztay    Notes:
108d0c080abSJoseph Pusztay    This routine adds an additional monitor to the list of monitors that
109d0c080abSJoseph Pusztay    already has been loaded.
110d0c080abSJoseph Pusztay 
111d0c080abSJoseph Pusztay    Fortran Notes:
112d0c080abSJoseph Pusztay     Only a single monitor function can be set for each TS object
113d0c080abSJoseph Pusztay 
114d0c080abSJoseph Pusztay    Level: intermediate
115d0c080abSJoseph Pusztay 
1163a61192cSBarry Smith .seealso: `TSMonitorDefault()`, `TSMonitorCancel()`, `TSDMSwarmMonitorMoments()`, `TSMonitorExtreme()`,  `TSMonitorDrawSolution()`,
1173a61192cSBarry Smith           `TSMonitorDrawSolutionPhase()`, `TSMonitorDrawSolutionFunction()`, `TSMonitorDrawError()`, `TSMonitorSolution()`, `TSMonitorSolutionVTK()`,
1183a61192cSBarry Smith           `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorSPSwarmSolution()`, `TSMonitorError()`, `TSMonitorEnvelope()`, `TSDMSwarmMonitorMoments()`
119d0c080abSJoseph Pusztay @*/
1209371c9d4SSatish Balay PetscErrorCode TSMonitorSet(TS ts, PetscErrorCode (*monitor)(TS, PetscInt, PetscReal, Vec, void *), void *mctx, PetscErrorCode (*mdestroy)(void **)) {
121d0c080abSJoseph Pusztay   PetscInt  i;
122d0c080abSJoseph Pusztay   PetscBool identical;
123d0c080abSJoseph Pusztay 
124d0c080abSJoseph Pusztay   PetscFunctionBegin;
125d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
126d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
1279566063dSJacob Faibussowitsch     PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))monitor, mctx, mdestroy, (PetscErrorCode(*)(void))ts->monitor[i], ts->monitorcontext[i], ts->monitordestroy[i], &identical));
128d0c080abSJoseph Pusztay     if (identical) PetscFunctionReturn(0);
129d0c080abSJoseph Pusztay   }
1303c633725SBarry Smith   PetscCheck(ts->numbermonitors < MAXTSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set");
131d0c080abSJoseph Pusztay   ts->monitor[ts->numbermonitors]          = monitor;
132d0c080abSJoseph Pusztay   ts->monitordestroy[ts->numbermonitors]   = mdestroy;
133d0c080abSJoseph Pusztay   ts->monitorcontext[ts->numbermonitors++] = (void *)mctx;
134d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
135d0c080abSJoseph Pusztay }
136d0c080abSJoseph Pusztay 
137d0c080abSJoseph Pusztay /*@C
138d0c080abSJoseph Pusztay    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
139d0c080abSJoseph Pusztay 
140d0c080abSJoseph Pusztay    Logically Collective on TS
141d0c080abSJoseph Pusztay 
142d0c080abSJoseph Pusztay    Input Parameters:
143d0c080abSJoseph Pusztay .  ts - the TS context obtained from TSCreate()
144d0c080abSJoseph Pusztay 
145d0c080abSJoseph Pusztay    Notes:
146d0c080abSJoseph Pusztay    There is no way to remove a single, specific monitor.
147d0c080abSJoseph Pusztay 
148d0c080abSJoseph Pusztay    Level: intermediate
149d0c080abSJoseph Pusztay 
150db781477SPatrick Sanan .seealso: `TSMonitorDefault()`, `TSMonitorSet()`
151d0c080abSJoseph Pusztay @*/
1529371c9d4SSatish Balay PetscErrorCode TSMonitorCancel(TS ts) {
153d0c080abSJoseph Pusztay   PetscInt i;
154d0c080abSJoseph Pusztay 
155d0c080abSJoseph Pusztay   PetscFunctionBegin;
156d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
157d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
158*48a46eb9SPierre Jolivet     if (ts->monitordestroy[i]) PetscCall((*ts->monitordestroy[i])(&ts->monitorcontext[i]));
159d0c080abSJoseph Pusztay   }
160d0c080abSJoseph Pusztay   ts->numbermonitors = 0;
161d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
162d0c080abSJoseph Pusztay }
163d0c080abSJoseph Pusztay 
164d0c080abSJoseph Pusztay /*@C
165d0c080abSJoseph Pusztay    TSMonitorDefault - The Default monitor, prints the timestep and time for each step
166d0c080abSJoseph Pusztay 
1673a61192cSBarry Smith    Options Database:
1683a61192cSBarry Smith .  -ts_monitor - monitors the time integration
1693a61192cSBarry Smith 
1703a61192cSBarry Smith    Notes:
1713a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
1723a61192cSBarry Smith    to be used during the TS integration.
1733a61192cSBarry Smith 
174d0c080abSJoseph Pusztay    Level: intermediate
175d0c080abSJoseph Pusztay 
1763a61192cSBarry Smith .seealso: `TSMonitorSet()`,  `TSDMSwarmMonitorMoments()`, `TSMonitorExtreme()`,  `TSMonitorDrawSolution()`,
1773a61192cSBarry Smith           `TSMonitorDrawSolutionPhase()`, `TSMonitorDrawSolutionFunction()`, `TSMonitorDrawError()`, `TSMonitorSolution()`, `TSMonitorSolutionVTK()`,
1783a61192cSBarry Smith           `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorSPSwarmSolution()`, `TSMonitorError()`, `TSMonitorEnvelope()`, `TSDMSwarmMonitorMoments()`
179d0c080abSJoseph Pusztay @*/
1809371c9d4SSatish Balay PetscErrorCode TSMonitorDefault(TS ts, PetscInt step, PetscReal ptime, Vec v, PetscViewerAndFormat *vf) {
181d0c080abSJoseph Pusztay   PetscViewer viewer = vf->viewer;
182d0c080abSJoseph Pusztay   PetscBool   iascii, ibinary;
183d0c080abSJoseph Pusztay 
184d0c080abSJoseph Pusztay   PetscFunctionBegin;
185064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 5);
1869566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
1879566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &ibinary));
1889566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
189d0c080abSJoseph Pusztay   if (iascii) {
1909566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)ts)->tablevel));
191d0c080abSJoseph Pusztay     if (step == -1) { /* this indicates it is an interpolated solution */
19263a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Interpolated solution at time %g between steps %" PetscInt_FMT " and %" PetscInt_FMT "\n", (double)ptime, ts->steps - 1, ts->steps));
193d0c080abSJoseph Pusztay     } else {
19463a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " TS dt %g time %g%s", step, (double)ts->time_step, (double)ptime, ts->steprollback ? " (r)\n" : "\n"));
195d0c080abSJoseph Pusztay     }
1969566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)ts)->tablevel));
197d0c080abSJoseph Pusztay   } else if (ibinary) {
198d0c080abSJoseph Pusztay     PetscMPIInt rank;
1999566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
200c5853193SPierre Jolivet     if (rank == 0) {
201d0c080abSJoseph Pusztay       PetscBool skipHeader;
202d0c080abSJoseph Pusztay       PetscInt  classid = REAL_FILE_CLASSID;
203d0c080abSJoseph Pusztay 
2049566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
205*48a46eb9SPierre Jolivet       if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, &classid, 1, PETSC_INT));
2069566063dSJacob Faibussowitsch       PetscCall(PetscRealView(1, &ptime, viewer));
207d0c080abSJoseph Pusztay     } else {
2089566063dSJacob Faibussowitsch       PetscCall(PetscRealView(0, &ptime, viewer));
209d0c080abSJoseph Pusztay     }
210d0c080abSJoseph Pusztay   }
2119566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
212d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
213d0c080abSJoseph Pusztay }
214d0c080abSJoseph Pusztay 
215d0c080abSJoseph Pusztay /*@C
216d0c080abSJoseph Pusztay    TSMonitorExtreme - Prints the extreme values of the solution at each timestep
217d0c080abSJoseph Pusztay 
2183a61192cSBarry Smith    Notes:
2193a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
2203a61192cSBarry Smith    to be used during the TS integration.
2213a61192cSBarry Smith 
222d0c080abSJoseph Pusztay    Level: intermediate
223d0c080abSJoseph Pusztay 
224db781477SPatrick Sanan .seealso: `TSMonitorSet()`
225d0c080abSJoseph Pusztay @*/
2269371c9d4SSatish Balay PetscErrorCode TSMonitorExtreme(TS ts, PetscInt step, PetscReal ptime, Vec v, PetscViewerAndFormat *vf) {
227d0c080abSJoseph Pusztay   PetscViewer viewer = vf->viewer;
228d0c080abSJoseph Pusztay   PetscBool   iascii;
229d0c080abSJoseph Pusztay   PetscReal   max, min;
230d0c080abSJoseph Pusztay 
231d0c080abSJoseph Pusztay   PetscFunctionBegin;
232064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 5);
2339566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
2349566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
235d0c080abSJoseph Pusztay   if (iascii) {
2369566063dSJacob Faibussowitsch     PetscCall(VecMax(v, NULL, &max));
2379566063dSJacob Faibussowitsch     PetscCall(VecMin(v, NULL, &min));
2389566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)ts)->tablevel));
23963a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " TS dt %g time %g%s max %g min %g\n", step, (double)ts->time_step, (double)ptime, ts->steprollback ? " (r)" : "", (double)max, (double)min));
2409566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)ts)->tablevel));
241d0c080abSJoseph Pusztay   }
2429566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
243d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
244d0c080abSJoseph Pusztay }
245d0c080abSJoseph Pusztay 
246d0c080abSJoseph Pusztay /*@C
247d0c080abSJoseph Pusztay    TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with
248d0c080abSJoseph Pusztay    TS to monitor the solution process graphically in various ways
249d0c080abSJoseph Pusztay 
250d0c080abSJoseph Pusztay    Collective on TS
251d0c080abSJoseph Pusztay 
252d0c080abSJoseph Pusztay    Input Parameters:
253d0c080abSJoseph Pusztay +  host - the X display to open, or null for the local machine
254d0c080abSJoseph Pusztay .  label - the title to put in the title bar
255d0c080abSJoseph Pusztay .  x, y - the screen coordinates of the upper left coordinate of the window
256d0c080abSJoseph Pusztay .  m, n - the screen width and height in pixels
257d0c080abSJoseph Pusztay -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
258d0c080abSJoseph Pusztay 
259d0c080abSJoseph Pusztay    Output Parameter:
260d0c080abSJoseph Pusztay .  ctx - the context
261d0c080abSJoseph Pusztay 
262d0c080abSJoseph Pusztay    Options Database Key:
263d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep - automatically sets line graph monitor
264d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep_log - automatically sets line graph monitor
265d0c080abSJoseph Pusztay .  -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables())
266d0c080abSJoseph Pusztay .  -ts_monitor_lg_error -  monitor the error
267d0c080abSJoseph Pusztay .  -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep
268d0c080abSJoseph Pusztay .  -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep
269d0c080abSJoseph Pusztay -  -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true
270d0c080abSJoseph Pusztay 
271d0c080abSJoseph Pusztay    Notes:
272d0c080abSJoseph Pusztay    Use TSMonitorLGCtxDestroy() to destroy.
273d0c080abSJoseph Pusztay 
274d0c080abSJoseph Pusztay    One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform()
275d0c080abSJoseph Pusztay 
276d0c080abSJoseph Pusztay    Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the
277d0c080abSJoseph Pusztay    first argument (if that TS object does not have a TSMonitorLGCtx associated with it the function call is ignored) and the second takes a TSMonitorLGCtx object
278d0c080abSJoseph Pusztay    as the first argument.
279d0c080abSJoseph Pusztay 
280d0c080abSJoseph Pusztay    One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames()
281d0c080abSJoseph Pusztay 
282d0c080abSJoseph Pusztay    Level: intermediate
283d0c080abSJoseph Pusztay 
284db781477SPatrick Sanan .seealso: `TSMonitorLGTimeStep()`, `TSMonitorSet()`, `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorDefault()`, `VecView()`,
285db781477SPatrick Sanan           `TSMonitorLGCtxCreate()`, `TSMonitorLGCtxSetVariableNames()`, `TSMonitorLGCtxGetVariableNames()`,
286db781477SPatrick Sanan           `TSMonitorLGSetVariableNames()`, `TSMonitorLGGetVariableNames()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetDisplayVariables()`,
287db781477SPatrick Sanan           `TSMonitorLGCtxSetTransform()`, `TSMonitorLGSetTransform()`, `TSMonitorLGError()`, `TSMonitorLGSNESIterations()`, `TSMonitorLGKSPIterations()`,
288db781477SPatrick Sanan           `TSMonitorEnvelopeCtxCreate()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxDestroy()`, `TSMonitorEnvelop()`
289d0c080abSJoseph Pusztay 
290d0c080abSJoseph Pusztay @*/
2919371c9d4SSatish Balay PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, TSMonitorLGCtx *ctx) {
292d0c080abSJoseph Pusztay   PetscDraw draw;
293d0c080abSJoseph Pusztay 
294d0c080abSJoseph Pusztay   PetscFunctionBegin;
2959566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
2969566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm, host, label, x, y, m, n, &draw));
2979566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetFromOptions(draw));
2989566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGCreate(draw, 1, &(*ctx)->lg));
2999566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGSetFromOptions((*ctx)->lg));
3009566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw));
301d0c080abSJoseph Pusztay   (*ctx)->howoften = howoften;
302d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
303d0c080abSJoseph Pusztay }
304d0c080abSJoseph Pusztay 
3059371c9d4SSatish Balay PetscErrorCode TSMonitorLGTimeStep(TS ts, PetscInt step, PetscReal ptime, Vec v, void *monctx) {
306d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx)monctx;
307d0c080abSJoseph Pusztay   PetscReal      x   = ptime, y;
308d0c080abSJoseph Pusztay 
309d0c080abSJoseph Pusztay   PetscFunctionBegin;
310d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */
311d0c080abSJoseph Pusztay   if (!step) {
312d0c080abSJoseph Pusztay     PetscDrawAxis axis;
313d0c080abSJoseph Pusztay     const char   *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step";
3149566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
3159566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Timestep as function of time", "Time", ylabel));
3169566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
317d0c080abSJoseph Pusztay   }
3189566063dSJacob Faibussowitsch   PetscCall(TSGetTimeStep(ts, &y));
319d0c080abSJoseph Pusztay   if (ctx->semilogy) y = PetscLog10Real(y);
3209566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg, &x, &y));
321d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
3229566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
3239566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
324d0c080abSJoseph Pusztay   }
325d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
326d0c080abSJoseph Pusztay }
327d0c080abSJoseph Pusztay 
328d0c080abSJoseph Pusztay /*@C
329d0c080abSJoseph Pusztay    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
330d0c080abSJoseph Pusztay    with TSMonitorLGCtxCreate().
331d0c080abSJoseph Pusztay 
332d0c080abSJoseph Pusztay    Collective on TSMonitorLGCtx
333d0c080abSJoseph Pusztay 
334d0c080abSJoseph Pusztay    Input Parameter:
335d0c080abSJoseph Pusztay .  ctx - the monitor context
336d0c080abSJoseph Pusztay 
337d0c080abSJoseph Pusztay    Level: intermediate
338d0c080abSJoseph Pusztay 
339db781477SPatrick Sanan .seealso: `TSMonitorLGCtxCreate()`, `TSMonitorSet()`, `TSMonitorLGTimeStep();`
340d0c080abSJoseph Pusztay @*/
3419371c9d4SSatish Balay PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx) {
342d0c080abSJoseph Pusztay   PetscFunctionBegin;
343*48a46eb9SPierre Jolivet   if ((*ctx)->transformdestroy) PetscCall(((*ctx)->transformdestroy)((*ctx)->transformctx));
3449566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGDestroy(&(*ctx)->lg));
3459566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&(*ctx)->names));
3469566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&(*ctx)->displaynames));
3479566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ctx)->displayvariables));
3489566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ctx)->displayvalues));
3499566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
350d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
351d0c080abSJoseph Pusztay }
352d0c080abSJoseph Pusztay 
353d7462660SMatthew Knepley /* Creates a TS Monitor SPCtx for use with DMSwarm particle visualizations */
3549371c9d4SSatish Balay PetscErrorCode TSMonitorSPCtxCreate(MPI_Comm comm, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, PetscInt retain, PetscBool phase, TSMonitorSPCtx *ctx) {
355d0c080abSJoseph Pusztay   PetscDraw draw;
356d0c080abSJoseph Pusztay 
357d0c080abSJoseph Pusztay   PetscFunctionBegin;
3589566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
3599566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm, host, label, x, y, m, n, &draw));
3609566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetFromOptions(draw));
3619566063dSJacob Faibussowitsch   PetscCall(PetscDrawSPCreate(draw, 1, &(*ctx)->sp));
3629566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw));
363d0c080abSJoseph Pusztay   (*ctx)->howoften = howoften;
364d7462660SMatthew Knepley   (*ctx)->retain   = retain;
365d7462660SMatthew Knepley   (*ctx)->phase    = phase;
366d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
367d0c080abSJoseph Pusztay }
368d0c080abSJoseph Pusztay 
369d0c080abSJoseph Pusztay /*
370d0c080abSJoseph Pusztay   Destroys a TSMonitorSPCtx that was created with TSMonitorSPCtxCreate
371d0c080abSJoseph Pusztay */
3729371c9d4SSatish Balay PetscErrorCode TSMonitorSPCtxDestroy(TSMonitorSPCtx *ctx) {
373d0c080abSJoseph Pusztay   PetscFunctionBegin;
374d0c080abSJoseph Pusztay 
3759566063dSJacob Faibussowitsch   PetscCall(PetscDrawSPDestroy(&(*ctx)->sp));
3769566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
377d0c080abSJoseph Pusztay 
378d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
379d0c080abSJoseph Pusztay }
380d0c080abSJoseph Pusztay 
381d0c080abSJoseph Pusztay /*@C
382d0c080abSJoseph Pusztay    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
383d0c080abSJoseph Pusztay    VecView() for the solution at each timestep
384d0c080abSJoseph Pusztay 
385d0c080abSJoseph Pusztay    Collective on TS
386d0c080abSJoseph Pusztay 
387d0c080abSJoseph Pusztay    Input Parameters:
388d0c080abSJoseph Pusztay +  ts - the TS context
389d0c080abSJoseph Pusztay .  step - current time-step
390d0c080abSJoseph Pusztay .  ptime - current time
391d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
392d0c080abSJoseph Pusztay 
393d0c080abSJoseph Pusztay    Options Database:
394d0c080abSJoseph Pusztay .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
395d0c080abSJoseph Pusztay 
396d0c080abSJoseph Pusztay    Notes:
3973a61192cSBarry Smith    The initial solution and current solution are not displayed with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
398d0c080abSJoseph Pusztay    will look bad
399d0c080abSJoseph Pusztay 
4003a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
4013a61192cSBarry Smith    to be used during the TS integration.
4023a61192cSBarry Smith 
403d0c080abSJoseph Pusztay    Level: intermediate
404d0c080abSJoseph Pusztay 
405db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
406d0c080abSJoseph Pusztay @*/
4079371c9d4SSatish Balay PetscErrorCode TSMonitorDrawSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy) {
408d0c080abSJoseph Pusztay   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
409d0c080abSJoseph Pusztay   PetscDraw        draw;
410d0c080abSJoseph Pusztay 
411d0c080abSJoseph Pusztay   PetscFunctionBegin;
412d0c080abSJoseph Pusztay   if (!step && ictx->showinitial) {
413*48a46eb9SPierre Jolivet     if (!ictx->initialsolution) PetscCall(VecDuplicate(u, &ictx->initialsolution));
4149566063dSJacob Faibussowitsch     PetscCall(VecCopy(u, ictx->initialsolution));
415d0c080abSJoseph Pusztay   }
416d0c080abSJoseph Pusztay   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
417d0c080abSJoseph Pusztay 
418d0c080abSJoseph Pusztay   if (ictx->showinitial) {
419d0c080abSJoseph Pusztay     PetscReal pause;
4209566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetPause(ictx->viewer, &pause));
4219566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetPause(ictx->viewer, 0.0));
4229566063dSJacob Faibussowitsch     PetscCall(VecView(ictx->initialsolution, ictx->viewer));
4239566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetPause(ictx->viewer, pause));
4249566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetHold(ictx->viewer, PETSC_TRUE));
425d0c080abSJoseph Pusztay   }
4269566063dSJacob Faibussowitsch   PetscCall(VecView(u, ictx->viewer));
427d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
428d0c080abSJoseph Pusztay     PetscReal xl, yl, xr, yr, h;
429d0c080abSJoseph Pusztay     char      time[32];
430d0c080abSJoseph Pusztay 
4319566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(ictx->viewer, 0, &draw));
4329566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(time, 32, "Timestep %d Time %g", (int)step, (double)ptime));
4339566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
434d0c080abSJoseph Pusztay     h = yl + .95 * (yr - yl);
4359566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw, .5 * (xl + xr), h, PETSC_DRAW_BLACK, time));
4369566063dSJacob Faibussowitsch     PetscCall(PetscDrawFlush(draw));
437d0c080abSJoseph Pusztay   }
438d0c080abSJoseph Pusztay 
4391baa6e33SBarry Smith   if (ictx->showinitial) PetscCall(PetscViewerDrawSetHold(ictx->viewer, PETSC_FALSE));
440d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
441d0c080abSJoseph Pusztay }
442d0c080abSJoseph Pusztay 
443d0c080abSJoseph Pusztay /*@C
444d0c080abSJoseph Pusztay    TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram
445d0c080abSJoseph Pusztay 
446d0c080abSJoseph Pusztay    Collective on TS
447d0c080abSJoseph Pusztay 
448d0c080abSJoseph Pusztay    Input Parameters:
449d0c080abSJoseph Pusztay +  ts - the TS context
450d0c080abSJoseph Pusztay .  step - current time-step
451d0c080abSJoseph Pusztay .  ptime - current time
452d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
453d0c080abSJoseph Pusztay 
4543a61192cSBarry Smith    Notes:
4553a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
4563a61192cSBarry Smith    to be used during the TS integration.
4573a61192cSBarry Smith 
458d0c080abSJoseph Pusztay    Level: intermediate
459d0c080abSJoseph Pusztay 
460db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
461d0c080abSJoseph Pusztay @*/
4629371c9d4SSatish Balay PetscErrorCode TSMonitorDrawSolutionPhase(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy) {
463d0c080abSJoseph Pusztay   TSMonitorDrawCtx   ictx = (TSMonitorDrawCtx)dummy;
464d0c080abSJoseph Pusztay   PetscDraw          draw;
465d0c080abSJoseph Pusztay   PetscDrawAxis      axis;
466d0c080abSJoseph Pusztay   PetscInt           n;
467d0c080abSJoseph Pusztay   PetscMPIInt        size;
468d0c080abSJoseph Pusztay   PetscReal          U0, U1, xl, yl, xr, yr, h;
469d0c080abSJoseph Pusztay   char               time[32];
470d0c080abSJoseph Pusztay   const PetscScalar *U;
471d0c080abSJoseph Pusztay 
472d0c080abSJoseph Pusztay   PetscFunctionBegin;
4739566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)ts), &size));
4743c633725SBarry Smith   PetscCheck(size == 1, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Only allowed for sequential runs");
4759566063dSJacob Faibussowitsch   PetscCall(VecGetSize(u, &n));
4763c633725SBarry Smith   PetscCheck(n == 2, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Only for ODEs with two unknowns");
477d0c080abSJoseph Pusztay 
4789566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(ictx->viewer, 0, &draw));
4799566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDrawAxis(ictx->viewer, 0, &axis));
4809566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisGetLimits(axis, &xl, &xr, &yl, &yr));
481d0c080abSJoseph Pusztay   if (!step) {
4829566063dSJacob Faibussowitsch     PetscCall(PetscDrawClear(draw));
4839566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisDraw(axis));
484d0c080abSJoseph Pusztay   }
485d0c080abSJoseph Pusztay 
4869566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(u, &U));
487d0c080abSJoseph Pusztay   U0 = PetscRealPart(U[0]);
488d0c080abSJoseph Pusztay   U1 = PetscRealPart(U[1]);
4899566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(u, &U));
490d0c080abSJoseph Pusztay   if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0);
491d0c080abSJoseph Pusztay 
492d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
4939566063dSJacob Faibussowitsch   PetscCall(PetscDrawPoint(draw, U0, U1, PETSC_DRAW_BLACK));
494d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
4959566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
4969566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(time, 32, "Timestep %d Time %g", (int)step, (double)ptime));
497d0c080abSJoseph Pusztay     h = yl + .95 * (yr - yl);
4989566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw, .5 * (xl + xr), h, PETSC_DRAW_BLACK, time));
499d0c080abSJoseph Pusztay   }
500d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
5019566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
5029566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
5039566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
504d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
505d0c080abSJoseph Pusztay }
506d0c080abSJoseph Pusztay 
507d0c080abSJoseph Pusztay /*@C
508d0c080abSJoseph Pusztay    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
509d0c080abSJoseph Pusztay 
510d0c080abSJoseph Pusztay    Collective on TS
511d0c080abSJoseph Pusztay 
512d0c080abSJoseph Pusztay    Input Parameters:
513d0c080abSJoseph Pusztay .    ctx - the monitor context
514d0c080abSJoseph Pusztay 
515d0c080abSJoseph Pusztay    Level: intermediate
516d0c080abSJoseph Pusztay 
517db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawSolution()`, `TSMonitorDrawError()`
518d0c080abSJoseph Pusztay @*/
5199371c9d4SSatish Balay PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) {
520d0c080abSJoseph Pusztay   PetscFunctionBegin;
5219566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&(*ictx)->viewer));
5229566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ictx)->initialsolution));
5239566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ictx));
524d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
525d0c080abSJoseph Pusztay }
526d0c080abSJoseph Pusztay 
527d0c080abSJoseph Pusztay /*@C
528d0c080abSJoseph Pusztay    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
529d0c080abSJoseph Pusztay 
530d0c080abSJoseph Pusztay    Collective on TS
531d0c080abSJoseph Pusztay 
532d0c080abSJoseph Pusztay    Input Parameter:
533d0c080abSJoseph Pusztay .    ts - time-step context
534d0c080abSJoseph Pusztay 
535d0c080abSJoseph Pusztay    Output Patameter:
536d0c080abSJoseph Pusztay .    ctx - the monitor context
537d0c080abSJoseph Pusztay 
538d0c080abSJoseph Pusztay    Options Database:
539d0c080abSJoseph Pusztay .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
540d0c080abSJoseph Pusztay 
541d0c080abSJoseph Pusztay    Level: intermediate
542d0c080abSJoseph Pusztay 
543db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawCtx()`
544d0c080abSJoseph Pusztay @*/
5459371c9d4SSatish Balay PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, TSMonitorDrawCtx *ctx) {
546d0c080abSJoseph Pusztay   PetscFunctionBegin;
5479566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
5489566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawOpen(comm, host, label, x, y, m, n, &(*ctx)->viewer));
5499566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetFromOptions((*ctx)->viewer));
550d0c080abSJoseph Pusztay 
551d0c080abSJoseph Pusztay   (*ctx)->howoften    = howoften;
552d0c080abSJoseph Pusztay   (*ctx)->showinitial = PETSC_FALSE;
5539566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-ts_monitor_draw_solution_initial", &(*ctx)->showinitial, NULL));
554d0c080abSJoseph Pusztay 
555d0c080abSJoseph Pusztay   (*ctx)->showtimestepandtime = PETSC_FALSE;
5569566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-ts_monitor_draw_solution_show_time", &(*ctx)->showtimestepandtime, NULL));
557d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
558d0c080abSJoseph Pusztay }
559d0c080abSJoseph Pusztay 
560d0c080abSJoseph Pusztay /*@C
561d0c080abSJoseph Pusztay    TSMonitorDrawSolutionFunction - Monitors progress of the TS solvers by calling
562d0c080abSJoseph Pusztay    VecView() for the solution provided by TSSetSolutionFunction() at each timestep
563d0c080abSJoseph Pusztay 
564d0c080abSJoseph Pusztay    Collective on TS
565d0c080abSJoseph Pusztay 
566d0c080abSJoseph Pusztay    Input Parameters:
567d0c080abSJoseph Pusztay +  ts - the TS context
568d0c080abSJoseph Pusztay .  step - current time-step
569d0c080abSJoseph Pusztay .  ptime - current time
570d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
571d0c080abSJoseph Pusztay 
572d0c080abSJoseph Pusztay    Options Database:
573d0c080abSJoseph Pusztay .  -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
574d0c080abSJoseph Pusztay 
5753a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
5763a61192cSBarry Smith    to be used during the TS integration.
5773a61192cSBarry Smith 
578d0c080abSJoseph Pusztay    Level: intermediate
579d0c080abSJoseph Pusztay 
580db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
581d0c080abSJoseph Pusztay @*/
5829371c9d4SSatish Balay PetscErrorCode TSMonitorDrawSolutionFunction(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy) {
583d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
584d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
585d0c080abSJoseph Pusztay   Vec              work;
586d0c080abSJoseph Pusztay 
587d0c080abSJoseph Pusztay   PetscFunctionBegin;
588d0c080abSJoseph Pusztay   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
5899566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u, &work));
5909566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts, ptime, work));
5919566063dSJacob Faibussowitsch   PetscCall(VecView(work, viewer));
5929566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work));
593d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
594d0c080abSJoseph Pusztay }
595d0c080abSJoseph Pusztay 
596d0c080abSJoseph Pusztay /*@C
597d0c080abSJoseph Pusztay    TSMonitorDrawError - Monitors progress of the TS solvers by calling
598d0c080abSJoseph Pusztay    VecView() for the error at each timestep
599d0c080abSJoseph Pusztay 
600d0c080abSJoseph Pusztay    Collective on TS
601d0c080abSJoseph Pusztay 
602d0c080abSJoseph Pusztay    Input Parameters:
603d0c080abSJoseph Pusztay +  ts - the TS context
604d0c080abSJoseph Pusztay .  step - current time-step
605d0c080abSJoseph Pusztay .  ptime - current time
606d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
607d0c080abSJoseph Pusztay 
608d0c080abSJoseph Pusztay    Options Database:
609d0c080abSJoseph Pusztay .  -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
610d0c080abSJoseph Pusztay 
6113a61192cSBarry Smith    Notes:
6123a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
6133a61192cSBarry Smith    to be used during the TS integration.
6143a61192cSBarry Smith 
615d0c080abSJoseph Pusztay    Level: intermediate
616d0c080abSJoseph Pusztay 
617db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
618d0c080abSJoseph Pusztay @*/
6199371c9d4SSatish Balay PetscErrorCode TSMonitorDrawError(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy) {
620d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
621d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
622d0c080abSJoseph Pusztay   Vec              work;
623d0c080abSJoseph Pusztay 
624d0c080abSJoseph Pusztay   PetscFunctionBegin;
625d0c080abSJoseph Pusztay   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
6269566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u, &work));
6279566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts, ptime, work));
6289566063dSJacob Faibussowitsch   PetscCall(VecAXPY(work, -1.0, u));
6299566063dSJacob Faibussowitsch   PetscCall(VecView(work, viewer));
6309566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work));
631d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
632d0c080abSJoseph Pusztay }
633d0c080abSJoseph Pusztay 
634d0c080abSJoseph Pusztay /*@C
635d0c080abSJoseph Pusztay    TSMonitorSolution - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file or a PetscDraw object
636d0c080abSJoseph Pusztay 
637d0c080abSJoseph Pusztay    Collective on TS
638d0c080abSJoseph Pusztay 
639d0c080abSJoseph Pusztay    Input Parameters:
640d0c080abSJoseph Pusztay +  ts - the TS context
641d0c080abSJoseph Pusztay .  step - current time-step
642d0c080abSJoseph Pusztay .  ptime - current time
643d0c080abSJoseph Pusztay .  u - current state
644d0c080abSJoseph Pusztay -  vf - viewer and its format
645d0c080abSJoseph Pusztay 
6463a61192cSBarry Smith    Notes:
6473a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
6483a61192cSBarry Smith    to be used during the TS integration.
6493a61192cSBarry Smith 
650d0c080abSJoseph Pusztay    Level: intermediate
651d0c080abSJoseph Pusztay 
652db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
653d0c080abSJoseph Pusztay @*/
6549371c9d4SSatish Balay PetscErrorCode TSMonitorSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, PetscViewerAndFormat *vf) {
655d0c080abSJoseph Pusztay   PetscFunctionBegin;
6569566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(vf->viewer, vf->format));
6579566063dSJacob Faibussowitsch   PetscCall(VecView(u, vf->viewer));
6589566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(vf->viewer));
659d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
660d0c080abSJoseph Pusztay }
661d0c080abSJoseph Pusztay 
662d0c080abSJoseph Pusztay /*@C
663d0c080abSJoseph Pusztay    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
664d0c080abSJoseph Pusztay 
665d0c080abSJoseph Pusztay    Collective on TS
666d0c080abSJoseph Pusztay 
667d0c080abSJoseph Pusztay    Input Parameters:
668d0c080abSJoseph Pusztay +  ts - the TS context
669d0c080abSJoseph Pusztay .  step - current time-step
670d0c080abSJoseph Pusztay .  ptime - current time
671d0c080abSJoseph Pusztay .  u - current state
67263a3b9bcSJacob Faibussowitsch -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03" PetscInt_FMT ")
673d0c080abSJoseph Pusztay 
674d0c080abSJoseph Pusztay    Level: intermediate
675d0c080abSJoseph Pusztay 
676d0c080abSJoseph Pusztay    Notes:
677d0c080abSJoseph Pusztay    The VTK format does not allow writing multiple time steps in the same file, therefore a different file will be written for each time step.
678d0c080abSJoseph Pusztay    These are named according to the file name template.
679d0c080abSJoseph Pusztay 
6803a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
6813a61192cSBarry Smith    to be used during the TS integration.
682d0c080abSJoseph Pusztay 
683db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
684d0c080abSJoseph Pusztay @*/
6859371c9d4SSatish Balay PetscErrorCode TSMonitorSolutionVTK(TS ts, PetscInt step, PetscReal ptime, Vec u, void *filenametemplate) {
686d0c080abSJoseph Pusztay   char        filename[PETSC_MAX_PATH_LEN];
687d0c080abSJoseph Pusztay   PetscViewer viewer;
688d0c080abSJoseph Pusztay 
689d0c080abSJoseph Pusztay   PetscFunctionBegin;
690d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
6919566063dSJacob Faibussowitsch   PetscCall(PetscSNPrintf(filename, sizeof(filename), (const char *)filenametemplate, step));
6929566063dSJacob Faibussowitsch   PetscCall(PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts), filename, FILE_MODE_WRITE, &viewer));
6939566063dSJacob Faibussowitsch   PetscCall(VecView(u, viewer));
6949566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&viewer));
695d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
696d0c080abSJoseph Pusztay }
697d0c080abSJoseph Pusztay 
698d0c080abSJoseph Pusztay /*@C
699d0c080abSJoseph Pusztay    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
700d0c080abSJoseph Pusztay 
701d0c080abSJoseph Pusztay    Collective on TS
702d0c080abSJoseph Pusztay 
703d0c080abSJoseph Pusztay    Input Parameters:
70463a3b9bcSJacob Faibussowitsch .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03" PetscInt_FMT ")
705d0c080abSJoseph Pusztay 
706d0c080abSJoseph Pusztay    Level: intermediate
707d0c080abSJoseph Pusztay 
708d0c080abSJoseph Pusztay    Note:
709d0c080abSJoseph Pusztay    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
710d0c080abSJoseph Pusztay 
711db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorSolutionVTK()`
712d0c080abSJoseph Pusztay @*/
7139371c9d4SSatish Balay PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) {
714d0c080abSJoseph Pusztay   PetscFunctionBegin;
7159566063dSJacob Faibussowitsch   PetscCall(PetscFree(*(char **)filenametemplate));
716d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
717d0c080abSJoseph Pusztay }
718d0c080abSJoseph Pusztay 
719d0c080abSJoseph Pusztay /*@C
720d0c080abSJoseph Pusztay    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
721d0c080abSJoseph Pusztay        in a time based line graph
722d0c080abSJoseph Pusztay 
723d0c080abSJoseph Pusztay    Collective on TS
724d0c080abSJoseph Pusztay 
725d0c080abSJoseph Pusztay    Input Parameters:
726d0c080abSJoseph Pusztay +  ts - the TS context
727d0c080abSJoseph Pusztay .  step - current time-step
728d0c080abSJoseph Pusztay .  ptime - current time
729d0c080abSJoseph Pusztay .  u - current solution
730d0c080abSJoseph Pusztay -  dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate()
731d0c080abSJoseph Pusztay 
732d0c080abSJoseph Pusztay    Options Database:
73367b8a455SSatish Balay .   -ts_monitor_lg_solution_variables - enable monitor of lg solution variables
734d0c080abSJoseph Pusztay 
735d0c080abSJoseph Pusztay    Level: intermediate
736d0c080abSJoseph Pusztay 
737d0c080abSJoseph Pusztay    Notes:
738d0c080abSJoseph Pusztay    Each process in a parallel run displays its component solutions in a separate window
739d0c080abSJoseph Pusztay 
7403a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
7413a61192cSBarry Smith    to be used during the TS integration.
7423a61192cSBarry Smith 
743db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGCtxCreate()`, `TSMonitorLGCtxSetVariableNames()`, `TSMonitorLGCtxGetVariableNames()`,
744db781477SPatrick Sanan           `TSMonitorLGSetVariableNames()`, `TSMonitorLGGetVariableNames()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetDisplayVariables()`,
745db781477SPatrick Sanan           `TSMonitorLGCtxSetTransform()`, `TSMonitorLGSetTransform()`, `TSMonitorLGError()`, `TSMonitorLGSNESIterations()`, `TSMonitorLGKSPIterations()`,
746db781477SPatrick Sanan           `TSMonitorEnvelopeCtxCreate()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxDestroy()`, `TSMonitorEnvelop()`
747d0c080abSJoseph Pusztay @*/
7489371c9d4SSatish Balay PetscErrorCode TSMonitorLGSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx) {
749d0c080abSJoseph Pusztay   TSMonitorLGCtx     ctx = (TSMonitorLGCtx)dctx;
750d0c080abSJoseph Pusztay   const PetscScalar *yy;
751d0c080abSJoseph Pusztay   Vec                v;
752d0c080abSJoseph Pusztay 
753d0c080abSJoseph Pusztay   PetscFunctionBegin;
754d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
755d0c080abSJoseph Pusztay   if (!step) {
756d0c080abSJoseph Pusztay     PetscDrawAxis axis;
757d0c080abSJoseph Pusztay     PetscInt      dim;
7589566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
7599566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Solution as function of time", "Time", "Solution"));
760d0c080abSJoseph Pusztay     if (!ctx->names) {
761d0c080abSJoseph Pusztay       PetscBool flg;
762d0c080abSJoseph Pusztay       /* user provides names of variables to plot but no names has been set so assume names are integer values */
7639566063dSJacob Faibussowitsch       PetscCall(PetscOptionsHasName(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_monitor_lg_solution_variables", &flg));
764d0c080abSJoseph Pusztay       if (flg) {
765d0c080abSJoseph Pusztay         PetscInt i, n;
766d0c080abSJoseph Pusztay         char   **names;
7679566063dSJacob Faibussowitsch         PetscCall(VecGetSize(u, &n));
7689566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(n + 1, &names));
769d0c080abSJoseph Pusztay         for (i = 0; i < n; i++) {
7709566063dSJacob Faibussowitsch           PetscCall(PetscMalloc1(5, &names[i]));
77163a3b9bcSJacob Faibussowitsch           PetscCall(PetscSNPrintf(names[i], 5, "%" PetscInt_FMT, i));
772d0c080abSJoseph Pusztay         }
773d0c080abSJoseph Pusztay         names[n]   = NULL;
774d0c080abSJoseph Pusztay         ctx->names = names;
775d0c080abSJoseph Pusztay       }
776d0c080abSJoseph Pusztay     }
777d0c080abSJoseph Pusztay     if (ctx->names && !ctx->displaynames) {
778d0c080abSJoseph Pusztay       char    **displaynames;
779d0c080abSJoseph Pusztay       PetscBool flg;
7809566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u, &dim));
7819566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(dim + 1, &displaynames));
7829566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetStringArray(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_monitor_lg_solution_variables", displaynames, &dim, &flg));
7831baa6e33SBarry Smith       if (flg) PetscCall(TSMonitorLGCtxSetDisplayVariables(ctx, (const char *const *)displaynames));
7849566063dSJacob Faibussowitsch       PetscCall(PetscStrArrayDestroy(&displaynames));
785d0c080abSJoseph Pusztay     }
786d0c080abSJoseph Pusztay     if (ctx->displaynames) {
7879566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg, ctx->ndisplayvariables));
7889566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetLegend(ctx->lg, (const char *const *)ctx->displaynames));
789d0c080abSJoseph Pusztay     } else if (ctx->names) {
7909566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u, &dim));
7919566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg, dim));
7929566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetLegend(ctx->lg, (const char *const *)ctx->names));
793d0c080abSJoseph Pusztay     } else {
7949566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u, &dim));
7959566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg, dim));
796d0c080abSJoseph Pusztay     }
7979566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
798d0c080abSJoseph Pusztay   }
799d0c080abSJoseph Pusztay 
800d0c080abSJoseph Pusztay   if (!ctx->transform) v = u;
8019566063dSJacob Faibussowitsch   else PetscCall((*ctx->transform)(ctx->transformctx, u, &v));
8029566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(v, &yy));
803d0c080abSJoseph Pusztay   if (ctx->displaynames) {
804d0c080abSJoseph Pusztay     PetscInt i;
8059371c9d4SSatish Balay     for (i = 0; i < ctx->ndisplayvariables; i++) ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]);
8069566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, ctx->displayvalues));
807d0c080abSJoseph Pusztay   } else {
808d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
809d0c080abSJoseph Pusztay     PetscInt   i, n;
810d0c080abSJoseph Pusztay     PetscReal *yreal;
8119566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(v, &n));
8129566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &yreal));
813d0c080abSJoseph Pusztay     for (i = 0; i < n; i++) yreal[i] = PetscRealPart(yy[i]);
8149566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yreal));
8159566063dSJacob Faibussowitsch     PetscCall(PetscFree(yreal));
816d0c080abSJoseph Pusztay #else
8179566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yy));
818d0c080abSJoseph Pusztay #endif
819d0c080abSJoseph Pusztay   }
8209566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(v, &yy));
8219566063dSJacob Faibussowitsch   if (ctx->transform) PetscCall(VecDestroy(&v));
822d0c080abSJoseph Pusztay 
823d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
8249566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
8259566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
826d0c080abSJoseph Pusztay   }
827d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
828d0c080abSJoseph Pusztay }
829d0c080abSJoseph Pusztay 
830d0c080abSJoseph Pusztay /*@C
831d0c080abSJoseph Pusztay    TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
832d0c080abSJoseph Pusztay 
833d0c080abSJoseph Pusztay    Collective on TS
834d0c080abSJoseph Pusztay 
835d0c080abSJoseph Pusztay    Input Parameters:
836d0c080abSJoseph Pusztay +  ts - the TS context
837d0c080abSJoseph Pusztay -  names - the names of the components, final string must be NULL
838d0c080abSJoseph Pusztay 
839d0c080abSJoseph Pusztay    Level: intermediate
840d0c080abSJoseph Pusztay 
841d0c080abSJoseph Pusztay    Notes:
842d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
843d0c080abSJoseph Pusztay 
844db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetVariableNames()`
845d0c080abSJoseph Pusztay @*/
8469371c9d4SSatish Balay PetscErrorCode TSMonitorLGSetVariableNames(TS ts, const char *const *names) {
847d0c080abSJoseph Pusztay   PetscInt i;
848d0c080abSJoseph Pusztay 
849d0c080abSJoseph Pusztay   PetscFunctionBegin;
850d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
851d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
8529566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i], names));
853d0c080abSJoseph Pusztay       break;
854d0c080abSJoseph Pusztay     }
855d0c080abSJoseph Pusztay   }
856d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
857d0c080abSJoseph Pusztay }
858d0c080abSJoseph Pusztay 
859d0c080abSJoseph Pusztay /*@C
860d0c080abSJoseph Pusztay    TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
861d0c080abSJoseph Pusztay 
862d0c080abSJoseph Pusztay    Collective on TS
863d0c080abSJoseph Pusztay 
864d0c080abSJoseph Pusztay    Input Parameters:
865d0c080abSJoseph Pusztay +  ts - the TS context
866d0c080abSJoseph Pusztay -  names - the names of the components, final string must be NULL
867d0c080abSJoseph Pusztay 
868d0c080abSJoseph Pusztay    Level: intermediate
869d0c080abSJoseph Pusztay 
870db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGSetVariableNames()`
871d0c080abSJoseph Pusztay @*/
8729371c9d4SSatish Balay PetscErrorCode TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx, const char *const *names) {
873d0c080abSJoseph Pusztay   PetscFunctionBegin;
8749566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&ctx->names));
8759566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(names, &ctx->names));
876d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
877d0c080abSJoseph Pusztay }
878d0c080abSJoseph Pusztay 
879d0c080abSJoseph Pusztay /*@C
880d0c080abSJoseph Pusztay    TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot
881d0c080abSJoseph Pusztay 
882d0c080abSJoseph Pusztay    Collective on TS
883d0c080abSJoseph Pusztay 
884d0c080abSJoseph Pusztay    Input Parameter:
885d0c080abSJoseph Pusztay .  ts - the TS context
886d0c080abSJoseph Pusztay 
887d0c080abSJoseph Pusztay    Output Parameter:
888d0c080abSJoseph Pusztay .  names - the names of the components, final string must be NULL
889d0c080abSJoseph Pusztay 
890d0c080abSJoseph Pusztay    Level: intermediate
891d0c080abSJoseph Pusztay 
892d0c080abSJoseph Pusztay    Notes:
893d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
894d0c080abSJoseph Pusztay 
895db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`
896d0c080abSJoseph Pusztay @*/
8979371c9d4SSatish Balay PetscErrorCode TSMonitorLGGetVariableNames(TS ts, const char *const **names) {
898d0c080abSJoseph Pusztay   PetscInt i;
899d0c080abSJoseph Pusztay 
900d0c080abSJoseph Pusztay   PetscFunctionBegin;
901d0c080abSJoseph Pusztay   *names = NULL;
902d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
903d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
904d0c080abSJoseph Pusztay       TSMonitorLGCtx ctx = (TSMonitorLGCtx)ts->monitorcontext[i];
905d0c080abSJoseph Pusztay       *names             = (const char *const *)ctx->names;
906d0c080abSJoseph Pusztay       break;
907d0c080abSJoseph Pusztay     }
908d0c080abSJoseph Pusztay   }
909d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
910d0c080abSJoseph Pusztay }
911d0c080abSJoseph Pusztay 
912d0c080abSJoseph Pusztay /*@C
913d0c080abSJoseph Pusztay    TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor
914d0c080abSJoseph Pusztay 
915d0c080abSJoseph Pusztay    Collective on TS
916d0c080abSJoseph Pusztay 
917d0c080abSJoseph Pusztay    Input Parameters:
918d0c080abSJoseph Pusztay +  ctx - the TSMonitorLG context
919d0c080abSJoseph Pusztay -  displaynames - the names of the components, final string must be NULL
920d0c080abSJoseph Pusztay 
921d0c080abSJoseph Pusztay    Level: intermediate
922d0c080abSJoseph Pusztay 
923db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`
924d0c080abSJoseph Pusztay @*/
9259371c9d4SSatish Balay PetscErrorCode TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx, const char *const *displaynames) {
926d0c080abSJoseph Pusztay   PetscInt j = 0, k;
927d0c080abSJoseph Pusztay 
928d0c080abSJoseph Pusztay   PetscFunctionBegin;
929d0c080abSJoseph Pusztay   if (!ctx->names) PetscFunctionReturn(0);
9309566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&ctx->displaynames));
9319566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(displaynames, &ctx->displaynames));
932d0c080abSJoseph Pusztay   while (displaynames[j]) j++;
933d0c080abSJoseph Pusztay   ctx->ndisplayvariables = j;
9349566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx->ndisplayvariables, &ctx->displayvariables));
9359566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx->ndisplayvariables, &ctx->displayvalues));
936d0c080abSJoseph Pusztay   j = 0;
937d0c080abSJoseph Pusztay   while (displaynames[j]) {
938d0c080abSJoseph Pusztay     k = 0;
939d0c080abSJoseph Pusztay     while (ctx->names[k]) {
940d0c080abSJoseph Pusztay       PetscBool flg;
9419566063dSJacob Faibussowitsch       PetscCall(PetscStrcmp(displaynames[j], ctx->names[k], &flg));
942d0c080abSJoseph Pusztay       if (flg) {
943d0c080abSJoseph Pusztay         ctx->displayvariables[j] = k;
944d0c080abSJoseph Pusztay         break;
945d0c080abSJoseph Pusztay       }
946d0c080abSJoseph Pusztay       k++;
947d0c080abSJoseph Pusztay     }
948d0c080abSJoseph Pusztay     j++;
949d0c080abSJoseph Pusztay   }
950d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
951d0c080abSJoseph Pusztay }
952d0c080abSJoseph Pusztay 
953d0c080abSJoseph Pusztay /*@C
954d0c080abSJoseph Pusztay    TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor
955d0c080abSJoseph Pusztay 
956d0c080abSJoseph Pusztay    Collective on TS
957d0c080abSJoseph Pusztay 
958d0c080abSJoseph Pusztay    Input Parameters:
959d0c080abSJoseph Pusztay +  ts - the TS context
960d0c080abSJoseph Pusztay -  displaynames - the names of the components, final string must be NULL
961d0c080abSJoseph Pusztay 
962d0c080abSJoseph Pusztay    Notes:
963d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
964d0c080abSJoseph Pusztay 
965d0c080abSJoseph Pusztay    Level: intermediate
966d0c080abSJoseph Pusztay 
967db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`
968d0c080abSJoseph Pusztay @*/
9699371c9d4SSatish Balay PetscErrorCode TSMonitorLGSetDisplayVariables(TS ts, const char *const *displaynames) {
970d0c080abSJoseph Pusztay   PetscInt i;
971d0c080abSJoseph Pusztay 
972d0c080abSJoseph Pusztay   PetscFunctionBegin;
973d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
974d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
9759566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i], displaynames));
976d0c080abSJoseph Pusztay       break;
977d0c080abSJoseph Pusztay     }
978d0c080abSJoseph Pusztay   }
979d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
980d0c080abSJoseph Pusztay }
981d0c080abSJoseph Pusztay 
982d0c080abSJoseph Pusztay /*@C
983d0c080abSJoseph Pusztay    TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed
984d0c080abSJoseph Pusztay 
985d0c080abSJoseph Pusztay    Collective on TS
986d0c080abSJoseph Pusztay 
987d0c080abSJoseph Pusztay    Input Parameters:
988d0c080abSJoseph Pusztay +  ts - the TS context
989d0c080abSJoseph Pusztay .  transform - the transform function
990d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
991d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
992d0c080abSJoseph Pusztay 
993d0c080abSJoseph Pusztay    Notes:
994d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
995d0c080abSJoseph Pusztay 
996d0c080abSJoseph Pusztay    Level: intermediate
997d0c080abSJoseph Pusztay 
998db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`, `TSMonitorLGCtxSetTransform()`
999d0c080abSJoseph Pusztay @*/
10009371c9d4SSatish Balay PetscErrorCode TSMonitorLGSetTransform(TS ts, PetscErrorCode (*transform)(void *, Vec, Vec *), PetscErrorCode (*destroy)(void *), void *tctx) {
1001d0c080abSJoseph Pusztay   PetscInt i;
1002d0c080abSJoseph Pusztay 
1003d0c080abSJoseph Pusztay   PetscFunctionBegin;
1004d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
1005*48a46eb9SPierre Jolivet     if (ts->monitor[i] == TSMonitorLGSolution) PetscCall(TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i], transform, destroy, tctx));
1006d0c080abSJoseph Pusztay   }
1007d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1008d0c080abSJoseph Pusztay }
1009d0c080abSJoseph Pusztay 
1010d0c080abSJoseph Pusztay /*@C
1011d0c080abSJoseph Pusztay    TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed
1012d0c080abSJoseph Pusztay 
1013d0c080abSJoseph Pusztay    Collective on TSLGCtx
1014d0c080abSJoseph Pusztay 
1015d0c080abSJoseph Pusztay    Input Parameters:
1016d0c080abSJoseph Pusztay +  ts - the TS context
1017d0c080abSJoseph Pusztay .  transform - the transform function
1018d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
1019d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
1020d0c080abSJoseph Pusztay 
1021d0c080abSJoseph Pusztay    Level: intermediate
1022d0c080abSJoseph Pusztay 
1023db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`, `TSMonitorLGSetTransform()`
1024d0c080abSJoseph Pusztay @*/
10259371c9d4SSatish Balay PetscErrorCode TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx, PetscErrorCode (*transform)(void *, Vec, Vec *), PetscErrorCode (*destroy)(void *), void *tctx) {
1026d0c080abSJoseph Pusztay   PetscFunctionBegin;
1027d0c080abSJoseph Pusztay   ctx->transform        = transform;
1028d0c080abSJoseph Pusztay   ctx->transformdestroy = destroy;
1029d0c080abSJoseph Pusztay   ctx->transformctx     = tctx;
1030d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1031d0c080abSJoseph Pusztay }
1032d0c080abSJoseph Pusztay 
1033d0c080abSJoseph Pusztay /*@C
1034d0c080abSJoseph Pusztay    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error
1035d0c080abSJoseph Pusztay        in a time based line graph
1036d0c080abSJoseph Pusztay 
1037d0c080abSJoseph Pusztay    Collective on TS
1038d0c080abSJoseph Pusztay 
1039d0c080abSJoseph Pusztay    Input Parameters:
1040d0c080abSJoseph Pusztay +  ts - the TS context
1041d0c080abSJoseph Pusztay .  step - current time-step
1042d0c080abSJoseph Pusztay .  ptime - current time
1043d0c080abSJoseph Pusztay .  u - current solution
1044d0c080abSJoseph Pusztay -  dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate()
1045d0c080abSJoseph Pusztay 
10463a61192cSBarry Smith    Options Database Keys:
10473a61192cSBarry Smith .  -ts_monitor_lg_error - create a graphical monitor of error history
10483a61192cSBarry Smith 
1049d0c080abSJoseph Pusztay    Level: intermediate
1050d0c080abSJoseph Pusztay 
1051d0c080abSJoseph Pusztay    Notes:
1052d0c080abSJoseph Pusztay     Each process in a parallel run displays its component errors in a separate window
1053d0c080abSJoseph Pusztay 
1054d0c080abSJoseph Pusztay    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
1055d0c080abSJoseph Pusztay 
10563a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
10573a61192cSBarry Smith    to be used during the TS integration.
1058d0c080abSJoseph Pusztay 
1059db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
1060d0c080abSJoseph Pusztay @*/
10619371c9d4SSatish Balay PetscErrorCode TSMonitorLGError(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy) {
1062d0c080abSJoseph Pusztay   TSMonitorLGCtx     ctx = (TSMonitorLGCtx)dummy;
1063d0c080abSJoseph Pusztay   const PetscScalar *yy;
1064d0c080abSJoseph Pusztay   Vec                y;
1065d0c080abSJoseph Pusztay 
1066d0c080abSJoseph Pusztay   PetscFunctionBegin;
1067d0c080abSJoseph Pusztay   if (!step) {
1068d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1069d0c080abSJoseph Pusztay     PetscInt      dim;
10709566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
10719566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Error in solution as function of time", "Time", "Error"));
10729566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(u, &dim));
10739566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSetDimension(ctx->lg, dim));
10749566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1075d0c080abSJoseph Pusztay   }
10769566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u, &y));
10779566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts, ptime, y));
10789566063dSJacob Faibussowitsch   PetscCall(VecAXPY(y, -1.0, u));
10799566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(y, &yy));
1080d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
1081d0c080abSJoseph Pusztay   {
1082d0c080abSJoseph Pusztay     PetscReal *yreal;
1083d0c080abSJoseph Pusztay     PetscInt   i, n;
10849566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(y, &n));
10859566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &yreal));
1086d0c080abSJoseph Pusztay     for (i = 0; i < n; i++) yreal[i] = PetscRealPart(yy[i]);
10879566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yreal));
10889566063dSJacob Faibussowitsch     PetscCall(PetscFree(yreal));
1089d0c080abSJoseph Pusztay   }
1090d0c080abSJoseph Pusztay #else
10919566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yy));
1092d0c080abSJoseph Pusztay #endif
10939566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(y, &yy));
10949566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&y));
1095d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
10969566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
10979566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1098d0c080abSJoseph Pusztay   }
1099d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1100d0c080abSJoseph Pusztay }
1101d0c080abSJoseph Pusztay 
1102d0c080abSJoseph Pusztay /*@C
1103d0c080abSJoseph Pusztay    TSMonitorSPSwarmSolution - Graphically displays phase plots of DMSwarm particles on a scatter plot
1104d0c080abSJoseph Pusztay 
1105d0c080abSJoseph Pusztay    Input Parameters:
1106d0c080abSJoseph Pusztay +  ts - the TS context
1107d0c080abSJoseph Pusztay .  step - current time-step
1108d0c080abSJoseph Pusztay .  ptime - current time
1109d0c080abSJoseph Pusztay .  u - current solution
1110d0c080abSJoseph Pusztay -  dctx - the TSMonitorSPCtx object that contains all the options for the monitoring, this is created with TSMonitorSPCtxCreate()
1111d0c080abSJoseph Pusztay 
1112d0c080abSJoseph Pusztay    Options Database:
1113d7462660SMatthew Knepley + -ts_monitor_sp_swarm <n>          - Monitor the solution every n steps, or -1 for plotting only the final solution
1114d7462660SMatthew Knepley . -ts_monitor_sp_swarm_retain <n>   - Retain n old points so we can see the history, or -1 for all points
1115d7462660SMatthew Knepley - -ts_monitor_sp_swarm_phase <bool> - Plot in phase space, as opposed to coordinate space
1116d0c080abSJoseph Pusztay 
1117d0c080abSJoseph Pusztay    Level: intermediate
1118d0c080abSJoseph Pusztay 
11193a61192cSBarry Smith    Notes:
11203a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
11213a61192cSBarry Smith    to be used during the TS integration.
11223a61192cSBarry Smith 
1123db781477SPatrick Sanan .seealso: `TSMonitoSet()`
1124d0c080abSJoseph Pusztay @*/
11259371c9d4SSatish Balay PetscErrorCode TSMonitorSPSwarmSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx) {
1126d0c080abSJoseph Pusztay   TSMonitorSPCtx     ctx = (TSMonitorSPCtx)dctx;
1127f98b2f00SMatthew G. Knepley   PetscDraw          draw;
1128d7462660SMatthew Knepley   DM                 dm, cdm;
1129d0c080abSJoseph Pusztay   const PetscScalar *yy;
1130d0c080abSJoseph Pusztay   PetscInt           Np, p, dim = 2;
1131d0c080abSJoseph Pusztay 
1132d0c080abSJoseph Pusztay   PetscFunctionBegin;
1133d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1134d0c080abSJoseph Pusztay   if (!step) {
1135d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1136ab43fcacSJoe Pusztay     PetscReal     dmboxlower[2], dmboxupper[2];
1137f98b2f00SMatthew G. Knepley 
11389566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &dm));
11399566063dSJacob Faibussowitsch     PetscCall(DMGetDimension(dm, &dim));
11403c633725SBarry Smith     PetscCheck(dim == 2, PETSC_COMM_SELF, PETSC_ERR_SUP, "Monitor only supports two dimensional fields");
11419566063dSJacob Faibussowitsch     PetscCall(DMSwarmGetCellDM(dm, &cdm));
11429566063dSJacob Faibussowitsch     PetscCall(DMGetBoundingBox(cdm, dmboxlower, dmboxupper));
11439566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(u, &Np));
1144d7462660SMatthew Knepley     Np /= dim * 2;
11459566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPGetAxis(ctx->sp, &axis));
11468c87cf4dSdanfinn     if (ctx->phase) {
11479566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(axis, "Particles", "X", "V"));
11489566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], -5, 5));
11498c87cf4dSdanfinn     } else {
11509566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(axis, "Particles", "X", "Y"));
11519566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], dmboxlower[1], dmboxupper[1]));
11528c87cf4dSdanfinn     }
11539566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetHoldLimits(axis, PETSC_TRUE));
11549566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPReset(ctx->sp));
1155d0c080abSJoseph Pusztay   }
11569566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(u, &Np));
1157d7462660SMatthew Knepley   Np /= dim * 2;
1158d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
11599566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPGetDraw(ctx->sp, &draw));
1160*48a46eb9SPierre Jolivet     if ((ctx->retain == 0) || (ctx->retain > 0 && !(step % ctx->retain))) PetscCall(PetscDrawClear(draw));
11619566063dSJacob Faibussowitsch     PetscCall(PetscDrawFlush(draw));
11629566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPReset(ctx->sp));
1163f98b2f00SMatthew G. Knepley     PetscCall(VecGetArrayRead(u, &yy));
1164f98b2f00SMatthew G. Knepley     for (p = 0; p < Np; ++p) {
1165f98b2f00SMatthew G. Knepley       PetscReal x, y;
1166f98b2f00SMatthew G. Knepley 
1167f98b2f00SMatthew G. Knepley       if (ctx->phase) {
1168f98b2f00SMatthew G. Knepley         x = PetscRealPart(yy[p * dim * 2]);
1169f98b2f00SMatthew G. Knepley         y = PetscRealPart(yy[p * dim * 2 + dim]);
1170f98b2f00SMatthew G. Knepley       } else {
1171f98b2f00SMatthew G. Knepley         x = PetscRealPart(yy[p * dim * 2]);
1172f98b2f00SMatthew G. Knepley         y = PetscRealPart(yy[p * dim * 2 + 1]);
1173f98b2f00SMatthew G. Knepley       }
1174f98b2f00SMatthew G. Knepley       PetscCall(PetscDrawSPAddPoint(ctx->sp, &x, &y));
1175f98b2f00SMatthew G. Knepley     }
1176f98b2f00SMatthew G. Knepley     PetscCall(VecRestoreArrayRead(u, &yy));
11779566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPDraw(ctx->sp, PETSC_FALSE));
11789566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPSave(ctx->sp));
1179d0c080abSJoseph Pusztay   }
1180d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1181d0c080abSJoseph Pusztay }
1182d0c080abSJoseph Pusztay 
1183d0c080abSJoseph Pusztay /*@C
1184d0c080abSJoseph Pusztay    TSMonitorError - Monitors progress of the TS solvers by printing the 2 norm of the error at each timestep
1185d0c080abSJoseph Pusztay 
1186d0c080abSJoseph Pusztay    Collective on TS
1187d0c080abSJoseph Pusztay 
1188d0c080abSJoseph Pusztay    Input Parameters:
1189d0c080abSJoseph Pusztay +  ts - the TS context
1190d0c080abSJoseph Pusztay .  step - current time-step
1191d0c080abSJoseph Pusztay .  ptime - current time
1192d0c080abSJoseph Pusztay .  u - current solution
1193d0c080abSJoseph Pusztay -  dctx - unused context
1194d0c080abSJoseph Pusztay 
1195d0c080abSJoseph Pusztay    Level: intermediate
1196d0c080abSJoseph Pusztay 
11973a61192cSBarry Smith    Notes:
11983a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
11993a61192cSBarry Smith    to be used during the TS integration.
12003a61192cSBarry Smith 
1201d0c080abSJoseph Pusztay    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
1202d0c080abSJoseph Pusztay 
1203d0c080abSJoseph Pusztay    Options Database Keys:
1204d0c080abSJoseph Pusztay .  -ts_monitor_error - create a graphical monitor of error history
1205d0c080abSJoseph Pusztay 
1206db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
1207d0c080abSJoseph Pusztay @*/
12089371c9d4SSatish Balay PetscErrorCode TSMonitorError(TS ts, PetscInt step, PetscReal ptime, Vec u, PetscViewerAndFormat *vf) {
120907eaae0cSMatthew G. Knepley   DM        dm;
121007eaae0cSMatthew G. Knepley   PetscDS   ds = NULL;
121107eaae0cSMatthew G. Knepley   PetscInt  Nf = -1, f;
1212d0c080abSJoseph Pusztay   PetscBool flg;
1213d0c080abSJoseph Pusztay 
1214d0c080abSJoseph Pusztay   PetscFunctionBegin;
12159566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
12169566063dSJacob Faibussowitsch   if (dm) PetscCall(DMGetDS(dm, &ds));
12179566063dSJacob Faibussowitsch   if (ds) PetscCall(PetscDSGetNumFields(ds, &Nf));
121807eaae0cSMatthew G. Knepley   if (Nf <= 0) {
121907eaae0cSMatthew G. Knepley     Vec       y;
122007eaae0cSMatthew G. Knepley     PetscReal nrm;
122107eaae0cSMatthew G. Knepley 
12229566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u, &y));
12239566063dSJacob Faibussowitsch     PetscCall(TSComputeSolutionFunction(ts, ptime, y));
12249566063dSJacob Faibussowitsch     PetscCall(VecAXPY(y, -1.0, u));
12259566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer, PETSCVIEWERASCII, &flg));
1226d0c080abSJoseph Pusztay     if (flg) {
12279566063dSJacob Faibussowitsch       PetscCall(VecNorm(y, NORM_2, &nrm));
12289566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vf->viewer, "2-norm of error %g\n", (double)nrm));
1229d0c080abSJoseph Pusztay     }
12309566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer, PETSCVIEWERDRAW, &flg));
12311baa6e33SBarry Smith     if (flg) PetscCall(VecView(y, vf->viewer));
12329566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&y));
123307eaae0cSMatthew G. Knepley   } else {
123407eaae0cSMatthew G. Knepley     PetscErrorCode (**exactFuncs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx);
123507eaae0cSMatthew G. Knepley     void    **ctxs;
123607eaae0cSMatthew G. Knepley     Vec       v;
123707eaae0cSMatthew G. Knepley     PetscReal ferrors[1];
123807eaae0cSMatthew G. Knepley 
12399566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(Nf, &exactFuncs, Nf, &ctxs));
12409566063dSJacob Faibussowitsch     for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(ds, f, &exactFuncs[f], &ctxs[f]));
12419566063dSJacob Faibussowitsch     PetscCall(DMComputeL2FieldDiff(dm, ptime, exactFuncs, ctxs, u, ferrors));
12429566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Timestep: %04d time = %-8.4g \t L_2 Error: [", (int)step, (double)ptime));
124307eaae0cSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
12449566063dSJacob Faibussowitsch       if (f > 0) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ", "));
12459566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%2.3g", (double)ferrors[f]));
124607eaae0cSMatthew G. Knepley     }
12479566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "]\n"));
124807eaae0cSMatthew G. Knepley 
12499566063dSJacob Faibussowitsch     PetscCall(VecViewFromOptions(u, NULL, "-sol_vec_view"));
125007eaae0cSMatthew G. Knepley 
12519566063dSJacob Faibussowitsch     PetscCall(PetscOptionsHasName(NULL, NULL, "-exact_vec_view", &flg));
125207eaae0cSMatthew G. Knepley     if (flg) {
12539566063dSJacob Faibussowitsch       PetscCall(DMGetGlobalVector(dm, &v));
12549566063dSJacob Faibussowitsch       PetscCall(DMProjectFunction(dm, ptime, exactFuncs, ctxs, INSERT_ALL_VALUES, v));
12559566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetName((PetscObject)v, "Exact Solution"));
12569566063dSJacob Faibussowitsch       PetscCall(VecViewFromOptions(v, NULL, "-exact_vec_view"));
12579566063dSJacob Faibussowitsch       PetscCall(DMRestoreGlobalVector(dm, &v));
125807eaae0cSMatthew G. Knepley     }
12599566063dSJacob Faibussowitsch     PetscCall(PetscFree2(exactFuncs, ctxs));
126007eaae0cSMatthew G. Knepley   }
1261d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1262d0c080abSJoseph Pusztay }
1263d0c080abSJoseph Pusztay 
12649371c9d4SSatish Balay PetscErrorCode TSMonitorLGSNESIterations(TS ts, PetscInt n, PetscReal ptime, Vec v, void *monctx) {
1265d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx)monctx;
1266d0c080abSJoseph Pusztay   PetscReal      x   = ptime, y;
1267d0c080abSJoseph Pusztay   PetscInt       its;
1268d0c080abSJoseph Pusztay 
1269d0c080abSJoseph Pusztay   PetscFunctionBegin;
1270d0c080abSJoseph Pusztay   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1271d0c080abSJoseph Pusztay   if (!n) {
1272d0c080abSJoseph Pusztay     PetscDrawAxis axis;
12739566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
12749566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Nonlinear iterations as function of time", "Time", "SNES Iterations"));
12759566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1276d0c080abSJoseph Pusztay     ctx->snes_its = 0;
1277d0c080abSJoseph Pusztay   }
12789566063dSJacob Faibussowitsch   PetscCall(TSGetSNESIterations(ts, &its));
1279d0c080abSJoseph Pusztay   y = its - ctx->snes_its;
12809566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg, &x, &y));
1281d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
12829566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
12839566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1284d0c080abSJoseph Pusztay   }
1285d0c080abSJoseph Pusztay   ctx->snes_its = its;
1286d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1287d0c080abSJoseph Pusztay }
1288d0c080abSJoseph Pusztay 
12899371c9d4SSatish Balay PetscErrorCode TSMonitorLGKSPIterations(TS ts, PetscInt n, PetscReal ptime, Vec v, void *monctx) {
1290d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx)monctx;
1291d0c080abSJoseph Pusztay   PetscReal      x   = ptime, y;
1292d0c080abSJoseph Pusztay   PetscInt       its;
1293d0c080abSJoseph Pusztay 
1294d0c080abSJoseph Pusztay   PetscFunctionBegin;
1295d0c080abSJoseph Pusztay   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1296d0c080abSJoseph Pusztay   if (!n) {
1297d0c080abSJoseph Pusztay     PetscDrawAxis axis;
12989566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
12999566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Linear iterations as function of time", "Time", "KSP Iterations"));
13009566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1301d0c080abSJoseph Pusztay     ctx->ksp_its = 0;
1302d0c080abSJoseph Pusztay   }
13039566063dSJacob Faibussowitsch   PetscCall(TSGetKSPIterations(ts, &its));
1304d0c080abSJoseph Pusztay   y = its - ctx->ksp_its;
13059566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg, &x, &y));
1306d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
13079566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
13089566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1309d0c080abSJoseph Pusztay   }
1310d0c080abSJoseph Pusztay   ctx->ksp_its = its;
1311d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1312d0c080abSJoseph Pusztay }
1313d0c080abSJoseph Pusztay 
1314d0c080abSJoseph Pusztay /*@C
1315d0c080abSJoseph Pusztay    TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope()
1316d0c080abSJoseph Pusztay 
1317d0c080abSJoseph Pusztay    Collective on TS
1318d0c080abSJoseph Pusztay 
1319d0c080abSJoseph Pusztay    Input Parameters:
1320d0c080abSJoseph Pusztay .  ts  - the ODE solver object
1321d0c080abSJoseph Pusztay 
1322d0c080abSJoseph Pusztay    Output Parameter:
1323d0c080abSJoseph Pusztay .  ctx - the context
1324d0c080abSJoseph Pusztay 
1325d0c080abSJoseph Pusztay    Level: intermediate
1326d0c080abSJoseph Pusztay 
1327db781477SPatrick Sanan .seealso: `TSMonitorLGTimeStep()`, `TSMonitorSet()`, `TSMonitorLGSolution()`, `TSMonitorLGError()`
1328d0c080abSJoseph Pusztay 
1329d0c080abSJoseph Pusztay @*/
13309371c9d4SSatish Balay PetscErrorCode TSMonitorEnvelopeCtxCreate(TS ts, TSMonitorEnvelopeCtx *ctx) {
1331d0c080abSJoseph Pusztay   PetscFunctionBegin;
13329566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
1333d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1334d0c080abSJoseph Pusztay }
1335d0c080abSJoseph Pusztay 
1336d0c080abSJoseph Pusztay /*@C
1337d0c080abSJoseph Pusztay    TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution
1338d0c080abSJoseph Pusztay 
1339d0c080abSJoseph Pusztay    Collective on TS
1340d0c080abSJoseph Pusztay 
1341d0c080abSJoseph Pusztay    Input Parameters:
1342d0c080abSJoseph Pusztay +  ts - the TS context
1343d0c080abSJoseph Pusztay .  step - current time-step
1344d0c080abSJoseph Pusztay .  ptime - current time
1345d0c080abSJoseph Pusztay .  u  - current solution
1346d0c080abSJoseph Pusztay -  dctx - the envelope context
1347d0c080abSJoseph Pusztay 
1348d0c080abSJoseph Pusztay    Options Database:
134967b8a455SSatish Balay .  -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time
1350d0c080abSJoseph Pusztay 
1351d0c080abSJoseph Pusztay    Level: intermediate
1352d0c080abSJoseph Pusztay 
1353d0c080abSJoseph Pusztay    Notes:
13543a61192cSBarry Smith    After a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope
13553a61192cSBarry Smith 
13563a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
13573a61192cSBarry Smith    to be used during the TS integration.
1358d0c080abSJoseph Pusztay 
1359db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxCreate()`
1360d0c080abSJoseph Pusztay @*/
13619371c9d4SSatish Balay PetscErrorCode TSMonitorEnvelope(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx) {
1362d0c080abSJoseph Pusztay   TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx;
1363d0c080abSJoseph Pusztay 
1364d0c080abSJoseph Pusztay   PetscFunctionBegin;
1365d0c080abSJoseph Pusztay   if (!ctx->max) {
13669566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u, &ctx->max));
13679566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u, &ctx->min));
13689566063dSJacob Faibussowitsch     PetscCall(VecCopy(u, ctx->max));
13699566063dSJacob Faibussowitsch     PetscCall(VecCopy(u, ctx->min));
1370d0c080abSJoseph Pusztay   } else {
13719566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMax(ctx->max, u, ctx->max));
13729566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMin(ctx->min, u, ctx->min));
1373d0c080abSJoseph Pusztay   }
1374d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1375d0c080abSJoseph Pusztay }
1376d0c080abSJoseph Pusztay 
1377d0c080abSJoseph Pusztay /*@C
1378d0c080abSJoseph Pusztay    TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution
1379d0c080abSJoseph Pusztay 
1380d0c080abSJoseph Pusztay    Collective on TS
1381d0c080abSJoseph Pusztay 
1382d0c080abSJoseph Pusztay    Input Parameter:
1383d0c080abSJoseph Pusztay .  ts - the TS context
1384d0c080abSJoseph Pusztay 
1385d8d19677SJose E. Roman    Output Parameters:
1386d0c080abSJoseph Pusztay +  max - the maximum values
1387d0c080abSJoseph Pusztay -  min - the minimum values
1388d0c080abSJoseph Pusztay 
1389d0c080abSJoseph Pusztay    Notes:
1390d0c080abSJoseph Pusztay     If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored
1391d0c080abSJoseph Pusztay 
1392d0c080abSJoseph Pusztay    Level: intermediate
1393d0c080abSJoseph Pusztay 
1394db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`
1395d0c080abSJoseph Pusztay @*/
13969371c9d4SSatish Balay PetscErrorCode TSMonitorEnvelopeGetBounds(TS ts, Vec *max, Vec *min) {
1397d0c080abSJoseph Pusztay   PetscInt i;
1398d0c080abSJoseph Pusztay 
1399d0c080abSJoseph Pusztay   PetscFunctionBegin;
1400d0c080abSJoseph Pusztay   if (max) *max = NULL;
1401d0c080abSJoseph Pusztay   if (min) *min = NULL;
1402d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
1403d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorEnvelope) {
1404d0c080abSJoseph Pusztay       TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)ts->monitorcontext[i];
1405d0c080abSJoseph Pusztay       if (max) *max = ctx->max;
1406d0c080abSJoseph Pusztay       if (min) *min = ctx->min;
1407d0c080abSJoseph Pusztay       break;
1408d0c080abSJoseph Pusztay     }
1409d0c080abSJoseph Pusztay   }
1410d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1411d0c080abSJoseph Pusztay }
1412d0c080abSJoseph Pusztay 
1413d0c080abSJoseph Pusztay /*@C
1414d0c080abSJoseph Pusztay    TSMonitorEnvelopeCtxDestroy - Destroys a context that was created  with TSMonitorEnvelopeCtxCreate().
1415d0c080abSJoseph Pusztay 
1416d0c080abSJoseph Pusztay    Collective on TSMonitorEnvelopeCtx
1417d0c080abSJoseph Pusztay 
1418d0c080abSJoseph Pusztay    Input Parameter:
1419d0c080abSJoseph Pusztay .  ctx - the monitor context
1420d0c080abSJoseph Pusztay 
1421d0c080abSJoseph Pusztay    Level: intermediate
1422d0c080abSJoseph Pusztay 
1423db781477SPatrick Sanan .seealso: `TSMonitorLGCtxCreate()`, `TSMonitorSet()`, `TSMonitorLGTimeStep()`
1424d0c080abSJoseph Pusztay @*/
14259371c9d4SSatish Balay PetscErrorCode TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx) {
1426d0c080abSJoseph Pusztay   PetscFunctionBegin;
14279566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ctx)->min));
14289566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ctx)->max));
14299566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
1430d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1431d0c080abSJoseph Pusztay }
1432d0c080abSJoseph Pusztay 
1433d0c080abSJoseph Pusztay /*@C
1434d0c080abSJoseph Pusztay   TSDMSwarmMonitorMoments - Monitors the first three moments of a DMSarm being evolved by the TS
1435d0c080abSJoseph Pusztay 
1436d0c080abSJoseph Pusztay   Not collective
1437d0c080abSJoseph Pusztay 
1438d0c080abSJoseph Pusztay   Input Parameters:
1439d0c080abSJoseph Pusztay + ts   - the TS context
1440d0c080abSJoseph Pusztay . step - current timestep
1441d0c080abSJoseph Pusztay . t    - current time
1442d0c080abSJoseph Pusztay . u    - current solution
1443d0c080abSJoseph Pusztay - ctx  - not used
1444d0c080abSJoseph Pusztay 
1445d0c080abSJoseph Pusztay   Options Database:
144667b8a455SSatish Balay . -ts_dmswarm_monitor_moments - Monitor moments of particle distribution
1447d0c080abSJoseph Pusztay 
1448d0c080abSJoseph Pusztay   Level: intermediate
1449d0c080abSJoseph Pusztay 
1450d0c080abSJoseph Pusztay   Notes:
1451d0c080abSJoseph Pusztay   This requires a DMSwarm be attached to the TS.
1452d0c080abSJoseph Pusztay 
14533a61192cSBarry Smith   This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
14543a61192cSBarry Smith   to be used during the TS integration.
14553a61192cSBarry Smith 
1456db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `DMSWARM`
1457d0c080abSJoseph Pusztay @*/
14589371c9d4SSatish Balay PetscErrorCode TSDMSwarmMonitorMoments(TS ts, PetscInt step, PetscReal t, Vec U, PetscViewerAndFormat *vf) {
1459d0c080abSJoseph Pusztay   DM                 sw;
1460d0c080abSJoseph Pusztay   const PetscScalar *u;
1461d0c080abSJoseph Pusztay   PetscReal          m = 1.0, totE = 0., totMom[3] = {0., 0., 0.};
1462d0c080abSJoseph Pusztay   PetscInt           dim, d, Np, p;
1463d0c080abSJoseph Pusztay   MPI_Comm           comm;
1464d0c080abSJoseph Pusztay 
1465d0c080abSJoseph Pusztay   PetscFunctionBeginUser;
14669566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &sw));
1467d0c080abSJoseph Pusztay   if (!sw || step % ts->monitorFrequency != 0) PetscFunctionReturn(0);
14689566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)ts, &comm));
14699566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(sw, &dim));
14709566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(U, &Np));
1471d0c080abSJoseph Pusztay   Np /= dim;
14729566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U, &u));
1473d0c080abSJoseph Pusztay   for (p = 0; p < Np; ++p) {
1474d0c080abSJoseph Pusztay     for (d = 0; d < dim; ++d) {
1475d0c080abSJoseph Pusztay       totE += PetscRealPart(u[p * dim + d] * u[p * dim + d]);
1476d0c080abSJoseph Pusztay       totMom[d] += PetscRealPart(u[p * dim + d]);
1477d0c080abSJoseph Pusztay     }
1478d0c080abSJoseph Pusztay   }
14799566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U, &u));
1480d0c080abSJoseph Pusztay   for (d = 0; d < dim; ++d) totMom[d] *= m;
1481d0c080abSJoseph Pusztay   totE *= 0.5 * m;
148263a3b9bcSJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "Step %4" PetscInt_FMT " Total Energy: %10.8lf", step, (double)totE));
148363a3b9bcSJacob Faibussowitsch   for (d = 0; d < dim; ++d) PetscCall(PetscPrintf(comm, "    Total Momentum %c: %10.8lf", (char)('x' + d), (double)totMom[d]));
14849566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "\n"));
1485d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1486d0c080abSJoseph Pusztay }
1487