xref: /petsc/src/ts/interface/tsmon.c (revision d71ae5a4db6382e7f06317b8d368875286fe9008)
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 @*/
27*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitor(TS ts, PetscInt step, PetscReal ptime, Vec u)
28*d71ae5a4SJacob Faibussowitsch {
29d0c080abSJoseph Pusztay   DM       dm;
30d0c080abSJoseph Pusztay   PetscInt i, n = ts->numbermonitors;
31d0c080abSJoseph Pusztay 
32d0c080abSJoseph Pusztay   PetscFunctionBegin;
33d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
34d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(u, VEC_CLASSID, 4);
35d0c080abSJoseph Pusztay 
369566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
379566063dSJacob Faibussowitsch   PetscCall(DMSetOutputSequenceNumber(dm, step, ptime));
38d0c080abSJoseph Pusztay 
399566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(u));
4048a46eb9SPierre Jolivet   for (i = 0; i < n; i++) PetscCall((*ts->monitor[i])(ts, step, ptime, u, ts->monitorcontext[i]));
419566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(u));
42d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
43d0c080abSJoseph Pusztay }
44d0c080abSJoseph Pusztay 
45d0c080abSJoseph Pusztay /*@C
46d0c080abSJoseph Pusztay    TSMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
47d0c080abSJoseph Pusztay 
48d0c080abSJoseph Pusztay    Collective on TS
49d0c080abSJoseph Pusztay 
50d0c080abSJoseph Pusztay    Input Parameters:
51d0c080abSJoseph Pusztay +  ts - TS object you wish to monitor
52d0c080abSJoseph Pusztay .  name - the monitor type one is seeking
53d0c080abSJoseph Pusztay .  help - message indicating what monitoring is done
54d0c080abSJoseph Pusztay .  manual - manual page for the monitor
55d0c080abSJoseph Pusztay .  monitor - the monitor function
56d0c080abSJoseph 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
57d0c080abSJoseph Pusztay 
58d0c080abSJoseph Pusztay    Level: developer
59d0c080abSJoseph Pusztay 
60db781477SPatrick Sanan .seealso: `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
61db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
62db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
63db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
64c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
65db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
66db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
67d0c080abSJoseph Pusztay @*/
68*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSetFromOptions(TS ts, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(TS, PetscInt, PetscReal, Vec, PetscViewerAndFormat *), PetscErrorCode (*monitorsetup)(TS, PetscViewerAndFormat *))
69*d71ae5a4SJacob Faibussowitsch {
70d0c080abSJoseph Pusztay   PetscViewer       viewer;
71d0c080abSJoseph Pusztay   PetscViewerFormat format;
72d0c080abSJoseph Pusztay   PetscBool         flg;
73d0c080abSJoseph Pusztay 
74d0c080abSJoseph Pusztay   PetscFunctionBegin;
759566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts), ((PetscObject)ts)->options, ((PetscObject)ts)->prefix, name, &viewer, &format, &flg));
76d0c080abSJoseph Pusztay   if (flg) {
77d0c080abSJoseph Pusztay     PetscViewerAndFormat *vf;
789566063dSJacob Faibussowitsch     PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf));
799566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject)viewer));
801baa6e33SBarry Smith     if (monitorsetup) PetscCall((*monitorsetup)(ts, vf));
819566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, (PetscErrorCode(*)(TS, PetscInt, PetscReal, Vec, void *))monitor, vf, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy));
82d0c080abSJoseph Pusztay   }
83d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
84d0c080abSJoseph Pusztay }
85d0c080abSJoseph Pusztay 
86d0c080abSJoseph Pusztay /*@C
87d0c080abSJoseph Pusztay    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
88d0c080abSJoseph Pusztay    timestep to display the iteration's  progress.
89d0c080abSJoseph Pusztay 
90d0c080abSJoseph Pusztay    Logically Collective on TS
91d0c080abSJoseph Pusztay 
92d0c080abSJoseph Pusztay    Input Parameters:
93d0c080abSJoseph Pusztay +  ts - the TS context obtained from TSCreate()
94d0c080abSJoseph Pusztay .  monitor - monitoring routine
95d0c080abSJoseph Pusztay .  mctx - [optional] user-defined context for private data for the
96d0c080abSJoseph Pusztay              monitor routine (use NULL if no context is desired)
97d0c080abSJoseph Pusztay -  monitordestroy - [optional] routine that frees monitor context
98d0c080abSJoseph Pusztay           (may be NULL)
99d0c080abSJoseph Pusztay 
100d0c080abSJoseph Pusztay    Calling sequence of monitor:
101d0c080abSJoseph Pusztay $    PetscErrorCode monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
102d0c080abSJoseph Pusztay 
103d0c080abSJoseph Pusztay +    ts - the TS context
104d0c080abSJoseph 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)
105d0c080abSJoseph Pusztay .    time - current time
106d0c080abSJoseph Pusztay .    u - current iterate
107d0c080abSJoseph Pusztay -    mctx - [optional] monitoring context
108d0c080abSJoseph Pusztay 
109d0c080abSJoseph Pusztay    Notes:
110d0c080abSJoseph Pusztay    This routine adds an additional monitor to the list of monitors that
111d0c080abSJoseph Pusztay    already has been loaded.
112d0c080abSJoseph Pusztay 
113d0c080abSJoseph Pusztay    Fortran Notes:
114d0c080abSJoseph Pusztay     Only a single monitor function can be set for each TS object
115d0c080abSJoseph Pusztay 
116d0c080abSJoseph Pusztay    Level: intermediate
117d0c080abSJoseph Pusztay 
1183a61192cSBarry Smith .seealso: `TSMonitorDefault()`, `TSMonitorCancel()`, `TSDMSwarmMonitorMoments()`, `TSMonitorExtreme()`,  `TSMonitorDrawSolution()`,
1193a61192cSBarry Smith           `TSMonitorDrawSolutionPhase()`, `TSMonitorDrawSolutionFunction()`, `TSMonitorDrawError()`, `TSMonitorSolution()`, `TSMonitorSolutionVTK()`,
1203a61192cSBarry Smith           `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorSPSwarmSolution()`, `TSMonitorError()`, `TSMonitorEnvelope()`, `TSDMSwarmMonitorMoments()`
121d0c080abSJoseph Pusztay @*/
122*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSet(TS ts, PetscErrorCode (*monitor)(TS, PetscInt, PetscReal, Vec, void *), void *mctx, PetscErrorCode (*mdestroy)(void **))
123*d71ae5a4SJacob Faibussowitsch {
124d0c080abSJoseph Pusztay   PetscInt  i;
125d0c080abSJoseph Pusztay   PetscBool identical;
126d0c080abSJoseph Pusztay 
127d0c080abSJoseph Pusztay   PetscFunctionBegin;
128d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
129d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
1309566063dSJacob Faibussowitsch     PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))monitor, mctx, mdestroy, (PetscErrorCode(*)(void))ts->monitor[i], ts->monitorcontext[i], ts->monitordestroy[i], &identical));
131d0c080abSJoseph Pusztay     if (identical) PetscFunctionReturn(0);
132d0c080abSJoseph Pusztay   }
1333c633725SBarry Smith   PetscCheck(ts->numbermonitors < MAXTSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set");
134d0c080abSJoseph Pusztay   ts->monitor[ts->numbermonitors]          = monitor;
135d0c080abSJoseph Pusztay   ts->monitordestroy[ts->numbermonitors]   = mdestroy;
136d0c080abSJoseph Pusztay   ts->monitorcontext[ts->numbermonitors++] = (void *)mctx;
137d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
138d0c080abSJoseph Pusztay }
139d0c080abSJoseph Pusztay 
140d0c080abSJoseph Pusztay /*@C
141d0c080abSJoseph Pusztay    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
142d0c080abSJoseph Pusztay 
143d0c080abSJoseph Pusztay    Logically Collective on TS
144d0c080abSJoseph Pusztay 
145d0c080abSJoseph Pusztay    Input Parameters:
146d0c080abSJoseph Pusztay .  ts - the TS context obtained from TSCreate()
147d0c080abSJoseph Pusztay 
148d0c080abSJoseph Pusztay    Notes:
149d0c080abSJoseph Pusztay    There is no way to remove a single, specific monitor.
150d0c080abSJoseph Pusztay 
151d0c080abSJoseph Pusztay    Level: intermediate
152d0c080abSJoseph Pusztay 
153db781477SPatrick Sanan .seealso: `TSMonitorDefault()`, `TSMonitorSet()`
154d0c080abSJoseph Pusztay @*/
155*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorCancel(TS ts)
156*d71ae5a4SJacob Faibussowitsch {
157d0c080abSJoseph Pusztay   PetscInt i;
158d0c080abSJoseph Pusztay 
159d0c080abSJoseph Pusztay   PetscFunctionBegin;
160d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
161d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
16248a46eb9SPierre Jolivet     if (ts->monitordestroy[i]) PetscCall((*ts->monitordestroy[i])(&ts->monitorcontext[i]));
163d0c080abSJoseph Pusztay   }
164d0c080abSJoseph Pusztay   ts->numbermonitors = 0;
165d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
166d0c080abSJoseph Pusztay }
167d0c080abSJoseph Pusztay 
168d0c080abSJoseph Pusztay /*@C
169d0c080abSJoseph Pusztay    TSMonitorDefault - The Default monitor, prints the timestep and time for each step
170d0c080abSJoseph Pusztay 
1713a61192cSBarry Smith    Options Database:
1723a61192cSBarry Smith .  -ts_monitor - monitors the time integration
1733a61192cSBarry Smith 
1743a61192cSBarry Smith    Notes:
1753a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
1763a61192cSBarry Smith    to be used during the TS integration.
1773a61192cSBarry Smith 
178d0c080abSJoseph Pusztay    Level: intermediate
179d0c080abSJoseph Pusztay 
1803a61192cSBarry Smith .seealso: `TSMonitorSet()`,  `TSDMSwarmMonitorMoments()`, `TSMonitorExtreme()`,  `TSMonitorDrawSolution()`,
1813a61192cSBarry Smith           `TSMonitorDrawSolutionPhase()`, `TSMonitorDrawSolutionFunction()`, `TSMonitorDrawError()`, `TSMonitorSolution()`, `TSMonitorSolutionVTK()`,
1823a61192cSBarry Smith           `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorSPSwarmSolution()`, `TSMonitorError()`, `TSMonitorEnvelope()`, `TSDMSwarmMonitorMoments()`
183d0c080abSJoseph Pusztay @*/
184*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDefault(TS ts, PetscInt step, PetscReal ptime, Vec v, PetscViewerAndFormat *vf)
185*d71ae5a4SJacob Faibussowitsch {
186d0c080abSJoseph Pusztay   PetscViewer viewer = vf->viewer;
187d0c080abSJoseph Pusztay   PetscBool   iascii, ibinary;
188d0c080abSJoseph Pusztay 
189d0c080abSJoseph Pusztay   PetscFunctionBegin;
190064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 5);
1919566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
1929566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &ibinary));
1939566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
194d0c080abSJoseph Pusztay   if (iascii) {
1959566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)ts)->tablevel));
196d0c080abSJoseph Pusztay     if (step == -1) { /* this indicates it is an interpolated solution */
19763a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Interpolated solution at time %g between steps %" PetscInt_FMT " and %" PetscInt_FMT "\n", (double)ptime, ts->steps - 1, ts->steps));
198d0c080abSJoseph Pusztay     } else {
19963a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " TS dt %g time %g%s", step, (double)ts->time_step, (double)ptime, ts->steprollback ? " (r)\n" : "\n"));
200d0c080abSJoseph Pusztay     }
2019566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)ts)->tablevel));
202d0c080abSJoseph Pusztay   } else if (ibinary) {
203d0c080abSJoseph Pusztay     PetscMPIInt rank;
2049566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
205c5853193SPierre Jolivet     if (rank == 0) {
206d0c080abSJoseph Pusztay       PetscBool skipHeader;
207d0c080abSJoseph Pusztay       PetscInt  classid = REAL_FILE_CLASSID;
208d0c080abSJoseph Pusztay 
2099566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
21048a46eb9SPierre Jolivet       if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, &classid, 1, PETSC_INT));
2119566063dSJacob Faibussowitsch       PetscCall(PetscRealView(1, &ptime, viewer));
212d0c080abSJoseph Pusztay     } else {
2139566063dSJacob Faibussowitsch       PetscCall(PetscRealView(0, &ptime, viewer));
214d0c080abSJoseph Pusztay     }
215d0c080abSJoseph Pusztay   }
2169566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
217d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
218d0c080abSJoseph Pusztay }
219d0c080abSJoseph Pusztay 
220d0c080abSJoseph Pusztay /*@C
221d0c080abSJoseph Pusztay    TSMonitorExtreme - Prints the extreme values of the solution at each timestep
222d0c080abSJoseph Pusztay 
2233a61192cSBarry Smith    Notes:
2243a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
2253a61192cSBarry Smith    to be used during the TS integration.
2263a61192cSBarry Smith 
227d0c080abSJoseph Pusztay    Level: intermediate
228d0c080abSJoseph Pusztay 
229db781477SPatrick Sanan .seealso: `TSMonitorSet()`
230d0c080abSJoseph Pusztay @*/
231*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorExtreme(TS ts, PetscInt step, PetscReal ptime, Vec v, PetscViewerAndFormat *vf)
232*d71ae5a4SJacob Faibussowitsch {
233d0c080abSJoseph Pusztay   PetscViewer viewer = vf->viewer;
234d0c080abSJoseph Pusztay   PetscBool   iascii;
235d0c080abSJoseph Pusztay   PetscReal   max, min;
236d0c080abSJoseph Pusztay 
237d0c080abSJoseph Pusztay   PetscFunctionBegin;
238064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 5);
2399566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
2409566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
241d0c080abSJoseph Pusztay   if (iascii) {
2429566063dSJacob Faibussowitsch     PetscCall(VecMax(v, NULL, &max));
2439566063dSJacob Faibussowitsch     PetscCall(VecMin(v, NULL, &min));
2449566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)ts)->tablevel));
24563a3b9bcSJacob 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));
2469566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)ts)->tablevel));
247d0c080abSJoseph Pusztay   }
2489566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
249d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
250d0c080abSJoseph Pusztay }
251d0c080abSJoseph Pusztay 
252d0c080abSJoseph Pusztay /*@C
253d0c080abSJoseph Pusztay    TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with
254d0c080abSJoseph Pusztay    TS to monitor the solution process graphically in various ways
255d0c080abSJoseph Pusztay 
256d0c080abSJoseph Pusztay    Collective on TS
257d0c080abSJoseph Pusztay 
258d0c080abSJoseph Pusztay    Input Parameters:
259d0c080abSJoseph Pusztay +  host - the X display to open, or null for the local machine
260d0c080abSJoseph Pusztay .  label - the title to put in the title bar
261d0c080abSJoseph Pusztay .  x, y - the screen coordinates of the upper left coordinate of the window
262d0c080abSJoseph Pusztay .  m, n - the screen width and height in pixels
263d0c080abSJoseph Pusztay -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
264d0c080abSJoseph Pusztay 
265d0c080abSJoseph Pusztay    Output Parameter:
266d0c080abSJoseph Pusztay .  ctx - the context
267d0c080abSJoseph Pusztay 
268d0c080abSJoseph Pusztay    Options Database Key:
269d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep - automatically sets line graph monitor
270d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep_log - automatically sets line graph monitor
271d0c080abSJoseph Pusztay .  -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables())
272d0c080abSJoseph Pusztay .  -ts_monitor_lg_error -  monitor the error
273d0c080abSJoseph Pusztay .  -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep
274d0c080abSJoseph Pusztay .  -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep
275d0c080abSJoseph Pusztay -  -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true
276d0c080abSJoseph Pusztay 
277d0c080abSJoseph Pusztay    Notes:
278d0c080abSJoseph Pusztay    Use TSMonitorLGCtxDestroy() to destroy.
279d0c080abSJoseph Pusztay 
280d0c080abSJoseph Pusztay    One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform()
281d0c080abSJoseph Pusztay 
282d0c080abSJoseph 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
283d0c080abSJoseph 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
284d0c080abSJoseph Pusztay    as the first argument.
285d0c080abSJoseph Pusztay 
286d0c080abSJoseph Pusztay    One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames()
287d0c080abSJoseph Pusztay 
288d0c080abSJoseph Pusztay    Level: intermediate
289d0c080abSJoseph Pusztay 
290db781477SPatrick Sanan .seealso: `TSMonitorLGTimeStep()`, `TSMonitorSet()`, `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorDefault()`, `VecView()`,
291db781477SPatrick Sanan           `TSMonitorLGCtxCreate()`, `TSMonitorLGCtxSetVariableNames()`, `TSMonitorLGCtxGetVariableNames()`,
292db781477SPatrick Sanan           `TSMonitorLGSetVariableNames()`, `TSMonitorLGGetVariableNames()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetDisplayVariables()`,
293db781477SPatrick Sanan           `TSMonitorLGCtxSetTransform()`, `TSMonitorLGSetTransform()`, `TSMonitorLGError()`, `TSMonitorLGSNESIterations()`, `TSMonitorLGKSPIterations()`,
294db781477SPatrick Sanan           `TSMonitorEnvelopeCtxCreate()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxDestroy()`, `TSMonitorEnvelop()`
295d0c080abSJoseph Pusztay 
296d0c080abSJoseph Pusztay @*/
297*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, TSMonitorLGCtx *ctx)
298*d71ae5a4SJacob Faibussowitsch {
299d0c080abSJoseph Pusztay   PetscDraw draw;
300d0c080abSJoseph Pusztay 
301d0c080abSJoseph Pusztay   PetscFunctionBegin;
3029566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
3039566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm, host, label, x, y, m, n, &draw));
3049566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetFromOptions(draw));
3059566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGCreate(draw, 1, &(*ctx)->lg));
3069566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGSetFromOptions((*ctx)->lg));
3079566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw));
308d0c080abSJoseph Pusztay   (*ctx)->howoften = howoften;
309d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
310d0c080abSJoseph Pusztay }
311d0c080abSJoseph Pusztay 
312*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGTimeStep(TS ts, PetscInt step, PetscReal ptime, Vec v, void *monctx)
313*d71ae5a4SJacob Faibussowitsch {
314d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx)monctx;
315d0c080abSJoseph Pusztay   PetscReal      x   = ptime, y;
316d0c080abSJoseph Pusztay 
317d0c080abSJoseph Pusztay   PetscFunctionBegin;
318d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */
319d0c080abSJoseph Pusztay   if (!step) {
320d0c080abSJoseph Pusztay     PetscDrawAxis axis;
321d0c080abSJoseph Pusztay     const char   *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step";
3229566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
3239566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Timestep as function of time", "Time", ylabel));
3249566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
325d0c080abSJoseph Pusztay   }
3269566063dSJacob Faibussowitsch   PetscCall(TSGetTimeStep(ts, &y));
327d0c080abSJoseph Pusztay   if (ctx->semilogy) y = PetscLog10Real(y);
3289566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg, &x, &y));
329d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
3309566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
3319566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
332d0c080abSJoseph Pusztay   }
333d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
334d0c080abSJoseph Pusztay }
335d0c080abSJoseph Pusztay 
336d0c080abSJoseph Pusztay /*@C
337d0c080abSJoseph Pusztay    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
338d0c080abSJoseph Pusztay    with TSMonitorLGCtxCreate().
339d0c080abSJoseph Pusztay 
340d0c080abSJoseph Pusztay    Collective on TSMonitorLGCtx
341d0c080abSJoseph Pusztay 
342d0c080abSJoseph Pusztay    Input Parameter:
343d0c080abSJoseph Pusztay .  ctx - the monitor context
344d0c080abSJoseph Pusztay 
345d0c080abSJoseph Pusztay    Level: intermediate
346d0c080abSJoseph Pusztay 
347db781477SPatrick Sanan .seealso: `TSMonitorLGCtxCreate()`, `TSMonitorSet()`, `TSMonitorLGTimeStep();`
348d0c080abSJoseph Pusztay @*/
349*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
350*d71ae5a4SJacob Faibussowitsch {
351d0c080abSJoseph Pusztay   PetscFunctionBegin;
35248a46eb9SPierre Jolivet   if ((*ctx)->transformdestroy) PetscCall(((*ctx)->transformdestroy)((*ctx)->transformctx));
3539566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGDestroy(&(*ctx)->lg));
3549566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&(*ctx)->names));
3559566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&(*ctx)->displaynames));
3569566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ctx)->displayvariables));
3579566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ctx)->displayvalues));
3589566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
359d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
360d0c080abSJoseph Pusztay }
361d0c080abSJoseph Pusztay 
362d7462660SMatthew Knepley /* Creates a TS Monitor SPCtx for use with DMSwarm particle visualizations */
363*d71ae5a4SJacob Faibussowitsch 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)
364*d71ae5a4SJacob Faibussowitsch {
365d0c080abSJoseph Pusztay   PetscDraw draw;
366d0c080abSJoseph Pusztay 
367d0c080abSJoseph Pusztay   PetscFunctionBegin;
3689566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
3699566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm, host, label, x, y, m, n, &draw));
3709566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetFromOptions(draw));
3719566063dSJacob Faibussowitsch   PetscCall(PetscDrawSPCreate(draw, 1, &(*ctx)->sp));
3729566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw));
373d0c080abSJoseph Pusztay   (*ctx)->howoften = howoften;
374d7462660SMatthew Knepley   (*ctx)->retain   = retain;
375d7462660SMatthew Knepley   (*ctx)->phase    = phase;
376d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
377d0c080abSJoseph Pusztay }
378d0c080abSJoseph Pusztay 
379d0c080abSJoseph Pusztay /*
380d0c080abSJoseph Pusztay   Destroys a TSMonitorSPCtx that was created with TSMonitorSPCtxCreate
381d0c080abSJoseph Pusztay */
382*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSPCtxDestroy(TSMonitorSPCtx *ctx)
383*d71ae5a4SJacob Faibussowitsch {
384d0c080abSJoseph Pusztay   PetscFunctionBegin;
385d0c080abSJoseph Pusztay 
3869566063dSJacob Faibussowitsch   PetscCall(PetscDrawSPDestroy(&(*ctx)->sp));
3879566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
388d0c080abSJoseph Pusztay 
389d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
390d0c080abSJoseph Pusztay }
391d0c080abSJoseph Pusztay 
392d0c080abSJoseph Pusztay /*@C
393d0c080abSJoseph Pusztay    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
394d0c080abSJoseph Pusztay    VecView() for the solution at each timestep
395d0c080abSJoseph Pusztay 
396d0c080abSJoseph Pusztay    Collective on TS
397d0c080abSJoseph Pusztay 
398d0c080abSJoseph Pusztay    Input Parameters:
399d0c080abSJoseph Pusztay +  ts - the TS context
400d0c080abSJoseph Pusztay .  step - current time-step
401d0c080abSJoseph Pusztay .  ptime - current time
402d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
403d0c080abSJoseph Pusztay 
404d0c080abSJoseph Pusztay    Options Database:
405d0c080abSJoseph Pusztay .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
406d0c080abSJoseph Pusztay 
407d0c080abSJoseph Pusztay    Notes:
4083a61192cSBarry Smith    The initial solution and current solution are not displayed with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
409d0c080abSJoseph Pusztay    will look bad
410d0c080abSJoseph Pusztay 
4113a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
4123a61192cSBarry Smith    to be used during the TS integration.
4133a61192cSBarry Smith 
414d0c080abSJoseph Pusztay    Level: intermediate
415d0c080abSJoseph Pusztay 
416db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
417d0c080abSJoseph Pusztay @*/
418*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy)
419*d71ae5a4SJacob Faibussowitsch {
420d0c080abSJoseph Pusztay   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
421d0c080abSJoseph Pusztay   PetscDraw        draw;
422d0c080abSJoseph Pusztay 
423d0c080abSJoseph Pusztay   PetscFunctionBegin;
424d0c080abSJoseph Pusztay   if (!step && ictx->showinitial) {
42548a46eb9SPierre Jolivet     if (!ictx->initialsolution) PetscCall(VecDuplicate(u, &ictx->initialsolution));
4269566063dSJacob Faibussowitsch     PetscCall(VecCopy(u, ictx->initialsolution));
427d0c080abSJoseph Pusztay   }
428d0c080abSJoseph Pusztay   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
429d0c080abSJoseph Pusztay 
430d0c080abSJoseph Pusztay   if (ictx->showinitial) {
431d0c080abSJoseph Pusztay     PetscReal pause;
4329566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetPause(ictx->viewer, &pause));
4339566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetPause(ictx->viewer, 0.0));
4349566063dSJacob Faibussowitsch     PetscCall(VecView(ictx->initialsolution, ictx->viewer));
4359566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetPause(ictx->viewer, pause));
4369566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetHold(ictx->viewer, PETSC_TRUE));
437d0c080abSJoseph Pusztay   }
4389566063dSJacob Faibussowitsch   PetscCall(VecView(u, ictx->viewer));
439d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
440d0c080abSJoseph Pusztay     PetscReal xl, yl, xr, yr, h;
441d0c080abSJoseph Pusztay     char      time[32];
442d0c080abSJoseph Pusztay 
4439566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(ictx->viewer, 0, &draw));
4449566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(time, 32, "Timestep %d Time %g", (int)step, (double)ptime));
4459566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
446d0c080abSJoseph Pusztay     h = yl + .95 * (yr - yl);
4479566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw, .5 * (xl + xr), h, PETSC_DRAW_BLACK, time));
4489566063dSJacob Faibussowitsch     PetscCall(PetscDrawFlush(draw));
449d0c080abSJoseph Pusztay   }
450d0c080abSJoseph Pusztay 
4511baa6e33SBarry Smith   if (ictx->showinitial) PetscCall(PetscViewerDrawSetHold(ictx->viewer, PETSC_FALSE));
452d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
453d0c080abSJoseph Pusztay }
454d0c080abSJoseph Pusztay 
455d0c080abSJoseph Pusztay /*@C
456d0c080abSJoseph Pusztay    TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram
457d0c080abSJoseph Pusztay 
458d0c080abSJoseph Pusztay    Collective on TS
459d0c080abSJoseph Pusztay 
460d0c080abSJoseph Pusztay    Input Parameters:
461d0c080abSJoseph Pusztay +  ts - the TS context
462d0c080abSJoseph Pusztay .  step - current time-step
463d0c080abSJoseph Pusztay .  ptime - current time
464d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
465d0c080abSJoseph Pusztay 
4663a61192cSBarry Smith    Notes:
4673a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
4683a61192cSBarry Smith    to be used during the TS integration.
4693a61192cSBarry Smith 
470d0c080abSJoseph Pusztay    Level: intermediate
471d0c080abSJoseph Pusztay 
472db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
473d0c080abSJoseph Pusztay @*/
474*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawSolutionPhase(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy)
475*d71ae5a4SJacob Faibussowitsch {
476d0c080abSJoseph Pusztay   TSMonitorDrawCtx   ictx = (TSMonitorDrawCtx)dummy;
477d0c080abSJoseph Pusztay   PetscDraw          draw;
478d0c080abSJoseph Pusztay   PetscDrawAxis      axis;
479d0c080abSJoseph Pusztay   PetscInt           n;
480d0c080abSJoseph Pusztay   PetscMPIInt        size;
481d0c080abSJoseph Pusztay   PetscReal          U0, U1, xl, yl, xr, yr, h;
482d0c080abSJoseph Pusztay   char               time[32];
483d0c080abSJoseph Pusztay   const PetscScalar *U;
484d0c080abSJoseph Pusztay 
485d0c080abSJoseph Pusztay   PetscFunctionBegin;
4869566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)ts), &size));
4873c633725SBarry Smith   PetscCheck(size == 1, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Only allowed for sequential runs");
4889566063dSJacob Faibussowitsch   PetscCall(VecGetSize(u, &n));
4893c633725SBarry Smith   PetscCheck(n == 2, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Only for ODEs with two unknowns");
490d0c080abSJoseph Pusztay 
4919566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(ictx->viewer, 0, &draw));
4929566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDrawAxis(ictx->viewer, 0, &axis));
4939566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisGetLimits(axis, &xl, &xr, &yl, &yr));
494d0c080abSJoseph Pusztay   if (!step) {
4959566063dSJacob Faibussowitsch     PetscCall(PetscDrawClear(draw));
4969566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisDraw(axis));
497d0c080abSJoseph Pusztay   }
498d0c080abSJoseph Pusztay 
4999566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(u, &U));
500d0c080abSJoseph Pusztay   U0 = PetscRealPart(U[0]);
501d0c080abSJoseph Pusztay   U1 = PetscRealPart(U[1]);
5029566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(u, &U));
503d0c080abSJoseph Pusztay   if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0);
504d0c080abSJoseph Pusztay 
505d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
5069566063dSJacob Faibussowitsch   PetscCall(PetscDrawPoint(draw, U0, U1, PETSC_DRAW_BLACK));
507d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
5089566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
5099566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(time, 32, "Timestep %d Time %g", (int)step, (double)ptime));
510d0c080abSJoseph Pusztay     h = yl + .95 * (yr - yl);
5119566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw, .5 * (xl + xr), h, PETSC_DRAW_BLACK, time));
512d0c080abSJoseph Pusztay   }
513d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
5149566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
5159566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
5169566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
517d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
518d0c080abSJoseph Pusztay }
519d0c080abSJoseph Pusztay 
520d0c080abSJoseph Pusztay /*@C
521d0c080abSJoseph Pusztay    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
522d0c080abSJoseph Pusztay 
523d0c080abSJoseph Pusztay    Collective on TS
524d0c080abSJoseph Pusztay 
525d0c080abSJoseph Pusztay    Input Parameters:
526d0c080abSJoseph Pusztay .    ctx - the monitor context
527d0c080abSJoseph Pusztay 
528d0c080abSJoseph Pusztay    Level: intermediate
529d0c080abSJoseph Pusztay 
530db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawSolution()`, `TSMonitorDrawError()`
531d0c080abSJoseph Pusztay @*/
532*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
533*d71ae5a4SJacob Faibussowitsch {
534d0c080abSJoseph Pusztay   PetscFunctionBegin;
5359566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&(*ictx)->viewer));
5369566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ictx)->initialsolution));
5379566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ictx));
538d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
539d0c080abSJoseph Pusztay }
540d0c080abSJoseph Pusztay 
541d0c080abSJoseph Pusztay /*@C
542d0c080abSJoseph Pusztay    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
543d0c080abSJoseph Pusztay 
544d0c080abSJoseph Pusztay    Collective on TS
545d0c080abSJoseph Pusztay 
546d0c080abSJoseph Pusztay    Input Parameter:
547d0c080abSJoseph Pusztay .    ts - time-step context
548d0c080abSJoseph Pusztay 
549d0c080abSJoseph Pusztay    Output Patameter:
550d0c080abSJoseph Pusztay .    ctx - the monitor context
551d0c080abSJoseph Pusztay 
552d0c080abSJoseph Pusztay    Options Database:
553d0c080abSJoseph Pusztay .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
554d0c080abSJoseph Pusztay 
555d0c080abSJoseph Pusztay    Level: intermediate
556d0c080abSJoseph Pusztay 
557db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawCtx()`
558d0c080abSJoseph Pusztay @*/
559*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, TSMonitorDrawCtx *ctx)
560*d71ae5a4SJacob Faibussowitsch {
561d0c080abSJoseph Pusztay   PetscFunctionBegin;
5629566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
5639566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawOpen(comm, host, label, x, y, m, n, &(*ctx)->viewer));
5649566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetFromOptions((*ctx)->viewer));
565d0c080abSJoseph Pusztay 
566d0c080abSJoseph Pusztay   (*ctx)->howoften    = howoften;
567d0c080abSJoseph Pusztay   (*ctx)->showinitial = PETSC_FALSE;
5689566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-ts_monitor_draw_solution_initial", &(*ctx)->showinitial, NULL));
569d0c080abSJoseph Pusztay 
570d0c080abSJoseph Pusztay   (*ctx)->showtimestepandtime = PETSC_FALSE;
5719566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-ts_monitor_draw_solution_show_time", &(*ctx)->showtimestepandtime, NULL));
572d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
573d0c080abSJoseph Pusztay }
574d0c080abSJoseph Pusztay 
575d0c080abSJoseph Pusztay /*@C
576d0c080abSJoseph Pusztay    TSMonitorDrawSolutionFunction - Monitors progress of the TS solvers by calling
577d0c080abSJoseph Pusztay    VecView() for the solution provided by TSSetSolutionFunction() at each timestep
578d0c080abSJoseph Pusztay 
579d0c080abSJoseph Pusztay    Collective on TS
580d0c080abSJoseph Pusztay 
581d0c080abSJoseph Pusztay    Input Parameters:
582d0c080abSJoseph Pusztay +  ts - the TS context
583d0c080abSJoseph Pusztay .  step - current time-step
584d0c080abSJoseph Pusztay .  ptime - current time
585d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
586d0c080abSJoseph Pusztay 
587d0c080abSJoseph Pusztay    Options Database:
588d0c080abSJoseph Pusztay .  -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
589d0c080abSJoseph Pusztay 
5903a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
5913a61192cSBarry Smith    to be used during the TS integration.
5923a61192cSBarry Smith 
593d0c080abSJoseph Pusztay    Level: intermediate
594d0c080abSJoseph Pusztay 
595db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
596d0c080abSJoseph Pusztay @*/
597*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawSolutionFunction(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy)
598*d71ae5a4SJacob Faibussowitsch {
599d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
600d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
601d0c080abSJoseph Pusztay   Vec              work;
602d0c080abSJoseph Pusztay 
603d0c080abSJoseph Pusztay   PetscFunctionBegin;
604d0c080abSJoseph Pusztay   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
6059566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u, &work));
6069566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts, ptime, work));
6079566063dSJacob Faibussowitsch   PetscCall(VecView(work, viewer));
6089566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work));
609d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
610d0c080abSJoseph Pusztay }
611d0c080abSJoseph Pusztay 
612d0c080abSJoseph Pusztay /*@C
613d0c080abSJoseph Pusztay    TSMonitorDrawError - Monitors progress of the TS solvers by calling
614d0c080abSJoseph Pusztay    VecView() for the error at each timestep
615d0c080abSJoseph Pusztay 
616d0c080abSJoseph Pusztay    Collective on TS
617d0c080abSJoseph Pusztay 
618d0c080abSJoseph Pusztay    Input Parameters:
619d0c080abSJoseph Pusztay +  ts - the TS context
620d0c080abSJoseph Pusztay .  step - current time-step
621d0c080abSJoseph Pusztay .  ptime - current time
622d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
623d0c080abSJoseph Pusztay 
624d0c080abSJoseph Pusztay    Options Database:
625d0c080abSJoseph Pusztay .  -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
626d0c080abSJoseph Pusztay 
6273a61192cSBarry Smith    Notes:
6283a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
6293a61192cSBarry Smith    to be used during the TS integration.
6303a61192cSBarry Smith 
631d0c080abSJoseph Pusztay    Level: intermediate
632d0c080abSJoseph Pusztay 
633db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
634d0c080abSJoseph Pusztay @*/
635*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawError(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy)
636*d71ae5a4SJacob Faibussowitsch {
637d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
638d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
639d0c080abSJoseph Pusztay   Vec              work;
640d0c080abSJoseph Pusztay 
641d0c080abSJoseph Pusztay   PetscFunctionBegin;
642d0c080abSJoseph Pusztay   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
6439566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u, &work));
6449566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts, ptime, work));
6459566063dSJacob Faibussowitsch   PetscCall(VecAXPY(work, -1.0, u));
6469566063dSJacob Faibussowitsch   PetscCall(VecView(work, viewer));
6479566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work));
648d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
649d0c080abSJoseph Pusztay }
650d0c080abSJoseph Pusztay 
651d0c080abSJoseph Pusztay /*@C
652d0c080abSJoseph 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
653d0c080abSJoseph Pusztay 
654d0c080abSJoseph Pusztay    Collective on TS
655d0c080abSJoseph Pusztay 
656d0c080abSJoseph Pusztay    Input Parameters:
657d0c080abSJoseph Pusztay +  ts - the TS context
658d0c080abSJoseph Pusztay .  step - current time-step
659d0c080abSJoseph Pusztay .  ptime - current time
660d0c080abSJoseph Pusztay .  u - current state
661d0c080abSJoseph Pusztay -  vf - viewer and its format
662d0c080abSJoseph Pusztay 
6633a61192cSBarry Smith    Notes:
6643a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
6653a61192cSBarry Smith    to be used during the TS integration.
6663a61192cSBarry Smith 
667d0c080abSJoseph Pusztay    Level: intermediate
668d0c080abSJoseph Pusztay 
669db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
670d0c080abSJoseph Pusztay @*/
671*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, PetscViewerAndFormat *vf)
672*d71ae5a4SJacob Faibussowitsch {
673d0c080abSJoseph Pusztay   PetscFunctionBegin;
6749566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(vf->viewer, vf->format));
6759566063dSJacob Faibussowitsch   PetscCall(VecView(u, vf->viewer));
6769566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(vf->viewer));
677d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
678d0c080abSJoseph Pusztay }
679d0c080abSJoseph Pusztay 
680d0c080abSJoseph Pusztay /*@C
681d0c080abSJoseph Pusztay    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
682d0c080abSJoseph Pusztay 
683d0c080abSJoseph Pusztay    Collective on TS
684d0c080abSJoseph Pusztay 
685d0c080abSJoseph Pusztay    Input Parameters:
686d0c080abSJoseph Pusztay +  ts - the TS context
687d0c080abSJoseph Pusztay .  step - current time-step
688d0c080abSJoseph Pusztay .  ptime - current time
689d0c080abSJoseph Pusztay .  u - current state
69063a3b9bcSJacob Faibussowitsch -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03" PetscInt_FMT ")
691d0c080abSJoseph Pusztay 
692d0c080abSJoseph Pusztay    Level: intermediate
693d0c080abSJoseph Pusztay 
694d0c080abSJoseph Pusztay    Notes:
695d0c080abSJoseph 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.
696d0c080abSJoseph Pusztay    These are named according to the file name template.
697d0c080abSJoseph Pusztay 
6983a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
6993a61192cSBarry Smith    to be used during the TS integration.
700d0c080abSJoseph Pusztay 
701db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
702d0c080abSJoseph Pusztay @*/
703*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSolutionVTK(TS ts, PetscInt step, PetscReal ptime, Vec u, void *filenametemplate)
704*d71ae5a4SJacob Faibussowitsch {
705d0c080abSJoseph Pusztay   char        filename[PETSC_MAX_PATH_LEN];
706d0c080abSJoseph Pusztay   PetscViewer viewer;
707d0c080abSJoseph Pusztay 
708d0c080abSJoseph Pusztay   PetscFunctionBegin;
709d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
7109566063dSJacob Faibussowitsch   PetscCall(PetscSNPrintf(filename, sizeof(filename), (const char *)filenametemplate, step));
7119566063dSJacob Faibussowitsch   PetscCall(PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts), filename, FILE_MODE_WRITE, &viewer));
7129566063dSJacob Faibussowitsch   PetscCall(VecView(u, viewer));
7139566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&viewer));
714d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
715d0c080abSJoseph Pusztay }
716d0c080abSJoseph Pusztay 
717d0c080abSJoseph Pusztay /*@C
718d0c080abSJoseph Pusztay    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
719d0c080abSJoseph Pusztay 
720d0c080abSJoseph Pusztay    Collective on TS
721d0c080abSJoseph Pusztay 
722d0c080abSJoseph Pusztay    Input Parameters:
72363a3b9bcSJacob Faibussowitsch .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03" PetscInt_FMT ")
724d0c080abSJoseph Pusztay 
725d0c080abSJoseph Pusztay    Level: intermediate
726d0c080abSJoseph Pusztay 
727d0c080abSJoseph Pusztay    Note:
728d0c080abSJoseph Pusztay    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
729d0c080abSJoseph Pusztay 
730db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorSolutionVTK()`
731d0c080abSJoseph Pusztay @*/
732*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
733*d71ae5a4SJacob Faibussowitsch {
734d0c080abSJoseph Pusztay   PetscFunctionBegin;
7359566063dSJacob Faibussowitsch   PetscCall(PetscFree(*(char **)filenametemplate));
736d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
737d0c080abSJoseph Pusztay }
738d0c080abSJoseph Pusztay 
739d0c080abSJoseph Pusztay /*@C
740d0c080abSJoseph Pusztay    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
741d0c080abSJoseph Pusztay        in a time based line graph
742d0c080abSJoseph Pusztay 
743d0c080abSJoseph Pusztay    Collective on TS
744d0c080abSJoseph Pusztay 
745d0c080abSJoseph Pusztay    Input Parameters:
746d0c080abSJoseph Pusztay +  ts - the TS context
747d0c080abSJoseph Pusztay .  step - current time-step
748d0c080abSJoseph Pusztay .  ptime - current time
749d0c080abSJoseph Pusztay .  u - current solution
750d0c080abSJoseph Pusztay -  dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate()
751d0c080abSJoseph Pusztay 
752d0c080abSJoseph Pusztay    Options Database:
75367b8a455SSatish Balay .   -ts_monitor_lg_solution_variables - enable monitor of lg solution variables
754d0c080abSJoseph Pusztay 
755d0c080abSJoseph Pusztay    Level: intermediate
756d0c080abSJoseph Pusztay 
757d0c080abSJoseph Pusztay    Notes:
758d0c080abSJoseph Pusztay    Each process in a parallel run displays its component solutions in a separate window
759d0c080abSJoseph Pusztay 
7603a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
7613a61192cSBarry Smith    to be used during the TS integration.
7623a61192cSBarry Smith 
763db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGCtxCreate()`, `TSMonitorLGCtxSetVariableNames()`, `TSMonitorLGCtxGetVariableNames()`,
764db781477SPatrick Sanan           `TSMonitorLGSetVariableNames()`, `TSMonitorLGGetVariableNames()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetDisplayVariables()`,
765db781477SPatrick Sanan           `TSMonitorLGCtxSetTransform()`, `TSMonitorLGSetTransform()`, `TSMonitorLGError()`, `TSMonitorLGSNESIterations()`, `TSMonitorLGKSPIterations()`,
766db781477SPatrick Sanan           `TSMonitorEnvelopeCtxCreate()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxDestroy()`, `TSMonitorEnvelop()`
767d0c080abSJoseph Pusztay @*/
768*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx)
769*d71ae5a4SJacob Faibussowitsch {
770d0c080abSJoseph Pusztay   TSMonitorLGCtx     ctx = (TSMonitorLGCtx)dctx;
771d0c080abSJoseph Pusztay   const PetscScalar *yy;
772d0c080abSJoseph Pusztay   Vec                v;
773d0c080abSJoseph Pusztay 
774d0c080abSJoseph Pusztay   PetscFunctionBegin;
775d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
776d0c080abSJoseph Pusztay   if (!step) {
777d0c080abSJoseph Pusztay     PetscDrawAxis axis;
778d0c080abSJoseph Pusztay     PetscInt      dim;
7799566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
7809566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Solution as function of time", "Time", "Solution"));
781d0c080abSJoseph Pusztay     if (!ctx->names) {
782d0c080abSJoseph Pusztay       PetscBool flg;
783d0c080abSJoseph Pusztay       /* user provides names of variables to plot but no names has been set so assume names are integer values */
7849566063dSJacob Faibussowitsch       PetscCall(PetscOptionsHasName(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_monitor_lg_solution_variables", &flg));
785d0c080abSJoseph Pusztay       if (flg) {
786d0c080abSJoseph Pusztay         PetscInt i, n;
787d0c080abSJoseph Pusztay         char   **names;
7889566063dSJacob Faibussowitsch         PetscCall(VecGetSize(u, &n));
7899566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(n + 1, &names));
790d0c080abSJoseph Pusztay         for (i = 0; i < n; i++) {
7919566063dSJacob Faibussowitsch           PetscCall(PetscMalloc1(5, &names[i]));
79263a3b9bcSJacob Faibussowitsch           PetscCall(PetscSNPrintf(names[i], 5, "%" PetscInt_FMT, i));
793d0c080abSJoseph Pusztay         }
794d0c080abSJoseph Pusztay         names[n]   = NULL;
795d0c080abSJoseph Pusztay         ctx->names = names;
796d0c080abSJoseph Pusztay       }
797d0c080abSJoseph Pusztay     }
798d0c080abSJoseph Pusztay     if (ctx->names && !ctx->displaynames) {
799d0c080abSJoseph Pusztay       char    **displaynames;
800d0c080abSJoseph Pusztay       PetscBool flg;
8019566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u, &dim));
8029566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(dim + 1, &displaynames));
8039566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetStringArray(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_monitor_lg_solution_variables", displaynames, &dim, &flg));
8041baa6e33SBarry Smith       if (flg) PetscCall(TSMonitorLGCtxSetDisplayVariables(ctx, (const char *const *)displaynames));
8059566063dSJacob Faibussowitsch       PetscCall(PetscStrArrayDestroy(&displaynames));
806d0c080abSJoseph Pusztay     }
807d0c080abSJoseph Pusztay     if (ctx->displaynames) {
8089566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg, ctx->ndisplayvariables));
8099566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetLegend(ctx->lg, (const char *const *)ctx->displaynames));
810d0c080abSJoseph Pusztay     } else if (ctx->names) {
8119566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u, &dim));
8129566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg, dim));
8139566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetLegend(ctx->lg, (const char *const *)ctx->names));
814d0c080abSJoseph Pusztay     } else {
8159566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u, &dim));
8169566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg, dim));
817d0c080abSJoseph Pusztay     }
8189566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
819d0c080abSJoseph Pusztay   }
820d0c080abSJoseph Pusztay 
821d0c080abSJoseph Pusztay   if (!ctx->transform) v = u;
8229566063dSJacob Faibussowitsch   else PetscCall((*ctx->transform)(ctx->transformctx, u, &v));
8239566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(v, &yy));
824d0c080abSJoseph Pusztay   if (ctx->displaynames) {
825d0c080abSJoseph Pusztay     PetscInt i;
8269371c9d4SSatish Balay     for (i = 0; i < ctx->ndisplayvariables; i++) ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]);
8279566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, ctx->displayvalues));
828d0c080abSJoseph Pusztay   } else {
829d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
830d0c080abSJoseph Pusztay     PetscInt   i, n;
831d0c080abSJoseph Pusztay     PetscReal *yreal;
8329566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(v, &n));
8339566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &yreal));
834d0c080abSJoseph Pusztay     for (i = 0; i < n; i++) yreal[i] = PetscRealPart(yy[i]);
8359566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yreal));
8369566063dSJacob Faibussowitsch     PetscCall(PetscFree(yreal));
837d0c080abSJoseph Pusztay #else
8389566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yy));
839d0c080abSJoseph Pusztay #endif
840d0c080abSJoseph Pusztay   }
8419566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(v, &yy));
8429566063dSJacob Faibussowitsch   if (ctx->transform) PetscCall(VecDestroy(&v));
843d0c080abSJoseph Pusztay 
844d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
8459566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
8469566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
847d0c080abSJoseph Pusztay   }
848d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
849d0c080abSJoseph Pusztay }
850d0c080abSJoseph Pusztay 
851d0c080abSJoseph Pusztay /*@C
852d0c080abSJoseph Pusztay    TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
853d0c080abSJoseph Pusztay 
854d0c080abSJoseph Pusztay    Collective on TS
855d0c080abSJoseph Pusztay 
856d0c080abSJoseph Pusztay    Input Parameters:
857d0c080abSJoseph Pusztay +  ts - the TS context
858d0c080abSJoseph Pusztay -  names - the names of the components, final string must be NULL
859d0c080abSJoseph Pusztay 
860d0c080abSJoseph Pusztay    Level: intermediate
861d0c080abSJoseph Pusztay 
862d0c080abSJoseph Pusztay    Notes:
863d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
864d0c080abSJoseph Pusztay 
865db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetVariableNames()`
866d0c080abSJoseph Pusztay @*/
867*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSetVariableNames(TS ts, const char *const *names)
868*d71ae5a4SJacob Faibussowitsch {
869d0c080abSJoseph Pusztay   PetscInt i;
870d0c080abSJoseph Pusztay 
871d0c080abSJoseph Pusztay   PetscFunctionBegin;
872d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
873d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
8749566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i], names));
875d0c080abSJoseph Pusztay       break;
876d0c080abSJoseph Pusztay     }
877d0c080abSJoseph Pusztay   }
878d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
879d0c080abSJoseph Pusztay }
880d0c080abSJoseph Pusztay 
881d0c080abSJoseph Pusztay /*@C
882d0c080abSJoseph Pusztay    TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
883d0c080abSJoseph Pusztay 
884d0c080abSJoseph Pusztay    Collective on TS
885d0c080abSJoseph Pusztay 
886d0c080abSJoseph Pusztay    Input Parameters:
887d0c080abSJoseph Pusztay +  ts - the TS context
888d0c080abSJoseph Pusztay -  names - the names of the components, final string must be NULL
889d0c080abSJoseph Pusztay 
890d0c080abSJoseph Pusztay    Level: intermediate
891d0c080abSJoseph Pusztay 
892db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGSetVariableNames()`
893d0c080abSJoseph Pusztay @*/
894*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx, const char *const *names)
895*d71ae5a4SJacob Faibussowitsch {
896d0c080abSJoseph Pusztay   PetscFunctionBegin;
8979566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&ctx->names));
8989566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(names, &ctx->names));
899d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
900d0c080abSJoseph Pusztay }
901d0c080abSJoseph Pusztay 
902d0c080abSJoseph Pusztay /*@C
903d0c080abSJoseph Pusztay    TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot
904d0c080abSJoseph Pusztay 
905d0c080abSJoseph Pusztay    Collective on TS
906d0c080abSJoseph Pusztay 
907d0c080abSJoseph Pusztay    Input Parameter:
908d0c080abSJoseph Pusztay .  ts - the TS context
909d0c080abSJoseph Pusztay 
910d0c080abSJoseph Pusztay    Output Parameter:
911d0c080abSJoseph Pusztay .  names - the names of the components, final string must be NULL
912d0c080abSJoseph Pusztay 
913d0c080abSJoseph Pusztay    Level: intermediate
914d0c080abSJoseph Pusztay 
915d0c080abSJoseph Pusztay    Notes:
916d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
917d0c080abSJoseph Pusztay 
918db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`
919d0c080abSJoseph Pusztay @*/
920*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGGetVariableNames(TS ts, const char *const **names)
921*d71ae5a4SJacob Faibussowitsch {
922d0c080abSJoseph Pusztay   PetscInt i;
923d0c080abSJoseph Pusztay 
924d0c080abSJoseph Pusztay   PetscFunctionBegin;
925d0c080abSJoseph Pusztay   *names = NULL;
926d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
927d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
928d0c080abSJoseph Pusztay       TSMonitorLGCtx ctx = (TSMonitorLGCtx)ts->monitorcontext[i];
929d0c080abSJoseph Pusztay       *names             = (const char *const *)ctx->names;
930d0c080abSJoseph Pusztay       break;
931d0c080abSJoseph Pusztay     }
932d0c080abSJoseph Pusztay   }
933d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
934d0c080abSJoseph Pusztay }
935d0c080abSJoseph Pusztay 
936d0c080abSJoseph Pusztay /*@C
937d0c080abSJoseph Pusztay    TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor
938d0c080abSJoseph Pusztay 
939d0c080abSJoseph Pusztay    Collective on TS
940d0c080abSJoseph Pusztay 
941d0c080abSJoseph Pusztay    Input Parameters:
942d0c080abSJoseph Pusztay +  ctx - the TSMonitorLG context
943d0c080abSJoseph Pusztay -  displaynames - the names of the components, final string must be NULL
944d0c080abSJoseph Pusztay 
945d0c080abSJoseph Pusztay    Level: intermediate
946d0c080abSJoseph Pusztay 
947db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`
948d0c080abSJoseph Pusztay @*/
949*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx, const char *const *displaynames)
950*d71ae5a4SJacob Faibussowitsch {
951d0c080abSJoseph Pusztay   PetscInt j = 0, k;
952d0c080abSJoseph Pusztay 
953d0c080abSJoseph Pusztay   PetscFunctionBegin;
954d0c080abSJoseph Pusztay   if (!ctx->names) PetscFunctionReturn(0);
9559566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&ctx->displaynames));
9569566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(displaynames, &ctx->displaynames));
957d0c080abSJoseph Pusztay   while (displaynames[j]) j++;
958d0c080abSJoseph Pusztay   ctx->ndisplayvariables = j;
9599566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx->ndisplayvariables, &ctx->displayvariables));
9609566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx->ndisplayvariables, &ctx->displayvalues));
961d0c080abSJoseph Pusztay   j = 0;
962d0c080abSJoseph Pusztay   while (displaynames[j]) {
963d0c080abSJoseph Pusztay     k = 0;
964d0c080abSJoseph Pusztay     while (ctx->names[k]) {
965d0c080abSJoseph Pusztay       PetscBool flg;
9669566063dSJacob Faibussowitsch       PetscCall(PetscStrcmp(displaynames[j], ctx->names[k], &flg));
967d0c080abSJoseph Pusztay       if (flg) {
968d0c080abSJoseph Pusztay         ctx->displayvariables[j] = k;
969d0c080abSJoseph Pusztay         break;
970d0c080abSJoseph Pusztay       }
971d0c080abSJoseph Pusztay       k++;
972d0c080abSJoseph Pusztay     }
973d0c080abSJoseph Pusztay     j++;
974d0c080abSJoseph Pusztay   }
975d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
976d0c080abSJoseph Pusztay }
977d0c080abSJoseph Pusztay 
978d0c080abSJoseph Pusztay /*@C
979d0c080abSJoseph Pusztay    TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor
980d0c080abSJoseph Pusztay 
981d0c080abSJoseph Pusztay    Collective on TS
982d0c080abSJoseph Pusztay 
983d0c080abSJoseph Pusztay    Input Parameters:
984d0c080abSJoseph Pusztay +  ts - the TS context
985d0c080abSJoseph Pusztay -  displaynames - the names of the components, final string must be NULL
986d0c080abSJoseph Pusztay 
987d0c080abSJoseph Pusztay    Notes:
988d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
989d0c080abSJoseph Pusztay 
990d0c080abSJoseph Pusztay    Level: intermediate
991d0c080abSJoseph Pusztay 
992db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`
993d0c080abSJoseph Pusztay @*/
994*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSetDisplayVariables(TS ts, const char *const *displaynames)
995*d71ae5a4SJacob Faibussowitsch {
996d0c080abSJoseph Pusztay   PetscInt i;
997d0c080abSJoseph Pusztay 
998d0c080abSJoseph Pusztay   PetscFunctionBegin;
999d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
1000d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
10019566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i], displaynames));
1002d0c080abSJoseph Pusztay       break;
1003d0c080abSJoseph Pusztay     }
1004d0c080abSJoseph Pusztay   }
1005d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1006d0c080abSJoseph Pusztay }
1007d0c080abSJoseph Pusztay 
1008d0c080abSJoseph Pusztay /*@C
1009d0c080abSJoseph Pusztay    TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed
1010d0c080abSJoseph Pusztay 
1011d0c080abSJoseph Pusztay    Collective on TS
1012d0c080abSJoseph Pusztay 
1013d0c080abSJoseph Pusztay    Input Parameters:
1014d0c080abSJoseph Pusztay +  ts - the TS context
1015d0c080abSJoseph Pusztay .  transform - the transform function
1016d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
1017d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
1018d0c080abSJoseph Pusztay 
1019d0c080abSJoseph Pusztay    Notes:
1020d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
1021d0c080abSJoseph Pusztay 
1022d0c080abSJoseph Pusztay    Level: intermediate
1023d0c080abSJoseph Pusztay 
1024db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`, `TSMonitorLGCtxSetTransform()`
1025d0c080abSJoseph Pusztay @*/
1026*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSetTransform(TS ts, PetscErrorCode (*transform)(void *, Vec, Vec *), PetscErrorCode (*destroy)(void *), void *tctx)
1027*d71ae5a4SJacob Faibussowitsch {
1028d0c080abSJoseph Pusztay   PetscInt i;
1029d0c080abSJoseph Pusztay 
1030d0c080abSJoseph Pusztay   PetscFunctionBegin;
1031d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
103248a46eb9SPierre Jolivet     if (ts->monitor[i] == TSMonitorLGSolution) PetscCall(TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i], transform, destroy, tctx));
1033d0c080abSJoseph Pusztay   }
1034d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1035d0c080abSJoseph Pusztay }
1036d0c080abSJoseph Pusztay 
1037d0c080abSJoseph Pusztay /*@C
1038d0c080abSJoseph Pusztay    TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed
1039d0c080abSJoseph Pusztay 
1040d0c080abSJoseph Pusztay    Collective on TSLGCtx
1041d0c080abSJoseph Pusztay 
1042d0c080abSJoseph Pusztay    Input Parameters:
1043d0c080abSJoseph Pusztay +  ts - the TS context
1044d0c080abSJoseph Pusztay .  transform - the transform function
1045d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
1046d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
1047d0c080abSJoseph Pusztay 
1048d0c080abSJoseph Pusztay    Level: intermediate
1049d0c080abSJoseph Pusztay 
1050db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`, `TSMonitorLGSetTransform()`
1051d0c080abSJoseph Pusztay @*/
1052*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx, PetscErrorCode (*transform)(void *, Vec, Vec *), PetscErrorCode (*destroy)(void *), void *tctx)
1053*d71ae5a4SJacob Faibussowitsch {
1054d0c080abSJoseph Pusztay   PetscFunctionBegin;
1055d0c080abSJoseph Pusztay   ctx->transform        = transform;
1056d0c080abSJoseph Pusztay   ctx->transformdestroy = destroy;
1057d0c080abSJoseph Pusztay   ctx->transformctx     = tctx;
1058d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1059d0c080abSJoseph Pusztay }
1060d0c080abSJoseph Pusztay 
1061d0c080abSJoseph Pusztay /*@C
1062d0c080abSJoseph Pusztay    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error
1063d0c080abSJoseph Pusztay        in a time based line graph
1064d0c080abSJoseph Pusztay 
1065d0c080abSJoseph Pusztay    Collective on TS
1066d0c080abSJoseph Pusztay 
1067d0c080abSJoseph Pusztay    Input Parameters:
1068d0c080abSJoseph Pusztay +  ts - the TS context
1069d0c080abSJoseph Pusztay .  step - current time-step
1070d0c080abSJoseph Pusztay .  ptime - current time
1071d0c080abSJoseph Pusztay .  u - current solution
1072d0c080abSJoseph Pusztay -  dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate()
1073d0c080abSJoseph Pusztay 
10743a61192cSBarry Smith    Options Database Keys:
10753a61192cSBarry Smith .  -ts_monitor_lg_error - create a graphical monitor of error history
10763a61192cSBarry Smith 
1077d0c080abSJoseph Pusztay    Level: intermediate
1078d0c080abSJoseph Pusztay 
1079d0c080abSJoseph Pusztay    Notes:
1080d0c080abSJoseph Pusztay     Each process in a parallel run displays its component errors in a separate window
1081d0c080abSJoseph Pusztay 
1082d0c080abSJoseph Pusztay    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
1083d0c080abSJoseph Pusztay 
10843a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
10853a61192cSBarry Smith    to be used during the TS integration.
1086d0c080abSJoseph Pusztay 
1087db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
1088d0c080abSJoseph Pusztay @*/
1089*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGError(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy)
1090*d71ae5a4SJacob Faibussowitsch {
1091d0c080abSJoseph Pusztay   TSMonitorLGCtx     ctx = (TSMonitorLGCtx)dummy;
1092d0c080abSJoseph Pusztay   const PetscScalar *yy;
1093d0c080abSJoseph Pusztay   Vec                y;
1094d0c080abSJoseph Pusztay 
1095d0c080abSJoseph Pusztay   PetscFunctionBegin;
1096d0c080abSJoseph Pusztay   if (!step) {
1097d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1098d0c080abSJoseph Pusztay     PetscInt      dim;
10999566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
11009566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Error in solution as function of time", "Time", "Error"));
11019566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(u, &dim));
11029566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSetDimension(ctx->lg, dim));
11039566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1104d0c080abSJoseph Pusztay   }
11059566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u, &y));
11069566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts, ptime, y));
11079566063dSJacob Faibussowitsch   PetscCall(VecAXPY(y, -1.0, u));
11089566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(y, &yy));
1109d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
1110d0c080abSJoseph Pusztay   {
1111d0c080abSJoseph Pusztay     PetscReal *yreal;
1112d0c080abSJoseph Pusztay     PetscInt   i, n;
11139566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(y, &n));
11149566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &yreal));
1115d0c080abSJoseph Pusztay     for (i = 0; i < n; i++) yreal[i] = PetscRealPart(yy[i]);
11169566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yreal));
11179566063dSJacob Faibussowitsch     PetscCall(PetscFree(yreal));
1118d0c080abSJoseph Pusztay   }
1119d0c080abSJoseph Pusztay #else
11209566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yy));
1121d0c080abSJoseph Pusztay #endif
11229566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(y, &yy));
11239566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&y));
1124d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
11259566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
11269566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1127d0c080abSJoseph Pusztay   }
1128d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1129d0c080abSJoseph Pusztay }
1130d0c080abSJoseph Pusztay 
1131d0c080abSJoseph Pusztay /*@C
1132d0c080abSJoseph Pusztay    TSMonitorSPSwarmSolution - Graphically displays phase plots of DMSwarm particles on a scatter plot
1133d0c080abSJoseph Pusztay 
1134d0c080abSJoseph Pusztay    Input Parameters:
1135d0c080abSJoseph Pusztay +  ts - the TS context
1136d0c080abSJoseph Pusztay .  step - current time-step
1137d0c080abSJoseph Pusztay .  ptime - current time
1138d0c080abSJoseph Pusztay .  u - current solution
1139d0c080abSJoseph Pusztay -  dctx - the TSMonitorSPCtx object that contains all the options for the monitoring, this is created with TSMonitorSPCtxCreate()
1140d0c080abSJoseph Pusztay 
1141d0c080abSJoseph Pusztay    Options Database:
1142d7462660SMatthew Knepley + -ts_monitor_sp_swarm <n>          - Monitor the solution every n steps, or -1 for plotting only the final solution
1143d7462660SMatthew Knepley . -ts_monitor_sp_swarm_retain <n>   - Retain n old points so we can see the history, or -1 for all points
1144d7462660SMatthew Knepley - -ts_monitor_sp_swarm_phase <bool> - Plot in phase space, as opposed to coordinate space
1145d0c080abSJoseph Pusztay 
1146d0c080abSJoseph Pusztay    Level: intermediate
1147d0c080abSJoseph Pusztay 
11483a61192cSBarry Smith    Notes:
11493a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
11503a61192cSBarry Smith    to be used during the TS integration.
11513a61192cSBarry Smith 
1152db781477SPatrick Sanan .seealso: `TSMonitoSet()`
1153d0c080abSJoseph Pusztay @*/
1154*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSPSwarmSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx)
1155*d71ae5a4SJacob Faibussowitsch {
1156d0c080abSJoseph Pusztay   TSMonitorSPCtx     ctx = (TSMonitorSPCtx)dctx;
1157f98b2f00SMatthew G. Knepley   PetscDraw          draw;
1158d7462660SMatthew Knepley   DM                 dm, cdm;
1159d0c080abSJoseph Pusztay   const PetscScalar *yy;
1160d0c080abSJoseph Pusztay   PetscInt           Np, p, dim = 2;
1161d0c080abSJoseph Pusztay 
1162d0c080abSJoseph Pusztay   PetscFunctionBegin;
1163d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1164d0c080abSJoseph Pusztay   if (!step) {
1165d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1166ab43fcacSJoe Pusztay     PetscReal     dmboxlower[2], dmboxupper[2];
1167f98b2f00SMatthew G. Knepley 
11689566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &dm));
11699566063dSJacob Faibussowitsch     PetscCall(DMGetDimension(dm, &dim));
11703c633725SBarry Smith     PetscCheck(dim == 2, PETSC_COMM_SELF, PETSC_ERR_SUP, "Monitor only supports two dimensional fields");
11719566063dSJacob Faibussowitsch     PetscCall(DMSwarmGetCellDM(dm, &cdm));
11729566063dSJacob Faibussowitsch     PetscCall(DMGetBoundingBox(cdm, dmboxlower, dmboxupper));
11739566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(u, &Np));
1174d7462660SMatthew Knepley     Np /= dim * 2;
11759566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPGetAxis(ctx->sp, &axis));
11768c87cf4dSdanfinn     if (ctx->phase) {
11779566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(axis, "Particles", "X", "V"));
11789566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], -5, 5));
11798c87cf4dSdanfinn     } else {
11809566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(axis, "Particles", "X", "Y"));
11819566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], dmboxlower[1], dmboxupper[1]));
11828c87cf4dSdanfinn     }
11839566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetHoldLimits(axis, PETSC_TRUE));
11849566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPReset(ctx->sp));
1185d0c080abSJoseph Pusztay   }
11869566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(u, &Np));
1187d7462660SMatthew Knepley   Np /= dim * 2;
1188d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
11899566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPGetDraw(ctx->sp, &draw));
119048a46eb9SPierre Jolivet     if ((ctx->retain == 0) || (ctx->retain > 0 && !(step % ctx->retain))) PetscCall(PetscDrawClear(draw));
11919566063dSJacob Faibussowitsch     PetscCall(PetscDrawFlush(draw));
11929566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPReset(ctx->sp));
1193f98b2f00SMatthew G. Knepley     PetscCall(VecGetArrayRead(u, &yy));
1194f98b2f00SMatthew G. Knepley     for (p = 0; p < Np; ++p) {
1195f98b2f00SMatthew G. Knepley       PetscReal x, y;
1196f98b2f00SMatthew G. Knepley 
1197f98b2f00SMatthew G. Knepley       if (ctx->phase) {
1198f98b2f00SMatthew G. Knepley         x = PetscRealPart(yy[p * dim * 2]);
1199f98b2f00SMatthew G. Knepley         y = PetscRealPart(yy[p * dim * 2 + dim]);
1200f98b2f00SMatthew G. Knepley       } else {
1201f98b2f00SMatthew G. Knepley         x = PetscRealPart(yy[p * dim * 2]);
1202f98b2f00SMatthew G. Knepley         y = PetscRealPart(yy[p * dim * 2 + 1]);
1203f98b2f00SMatthew G. Knepley       }
1204f98b2f00SMatthew G. Knepley       PetscCall(PetscDrawSPAddPoint(ctx->sp, &x, &y));
1205f98b2f00SMatthew G. Knepley     }
1206f98b2f00SMatthew G. Knepley     PetscCall(VecRestoreArrayRead(u, &yy));
12079566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPDraw(ctx->sp, PETSC_FALSE));
12089566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPSave(ctx->sp));
1209d0c080abSJoseph Pusztay   }
1210d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1211d0c080abSJoseph Pusztay }
1212d0c080abSJoseph Pusztay 
1213d0c080abSJoseph Pusztay /*@C
1214d0c080abSJoseph Pusztay    TSMonitorError - Monitors progress of the TS solvers by printing the 2 norm of the error at each timestep
1215d0c080abSJoseph Pusztay 
1216d0c080abSJoseph Pusztay    Collective on TS
1217d0c080abSJoseph Pusztay 
1218d0c080abSJoseph Pusztay    Input Parameters:
1219d0c080abSJoseph Pusztay +  ts - the TS context
1220d0c080abSJoseph Pusztay .  step - current time-step
1221d0c080abSJoseph Pusztay .  ptime - current time
1222d0c080abSJoseph Pusztay .  u - current solution
1223d0c080abSJoseph Pusztay -  dctx - unused context
1224d0c080abSJoseph Pusztay 
1225d0c080abSJoseph Pusztay    Level: intermediate
1226d0c080abSJoseph Pusztay 
12273a61192cSBarry Smith    Notes:
12283a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
12293a61192cSBarry Smith    to be used during the TS integration.
12303a61192cSBarry Smith 
1231d0c080abSJoseph Pusztay    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
1232d0c080abSJoseph Pusztay 
1233d0c080abSJoseph Pusztay    Options Database Keys:
1234d0c080abSJoseph Pusztay .  -ts_monitor_error - create a graphical monitor of error history
1235d0c080abSJoseph Pusztay 
1236db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
1237d0c080abSJoseph Pusztay @*/
1238*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorError(TS ts, PetscInt step, PetscReal ptime, Vec u, PetscViewerAndFormat *vf)
1239*d71ae5a4SJacob Faibussowitsch {
124007eaae0cSMatthew G. Knepley   DM        dm;
124107eaae0cSMatthew G. Knepley   PetscDS   ds = NULL;
124207eaae0cSMatthew G. Knepley   PetscInt  Nf = -1, f;
1243d0c080abSJoseph Pusztay   PetscBool flg;
1244d0c080abSJoseph Pusztay 
1245d0c080abSJoseph Pusztay   PetscFunctionBegin;
12469566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
12479566063dSJacob Faibussowitsch   if (dm) PetscCall(DMGetDS(dm, &ds));
12489566063dSJacob Faibussowitsch   if (ds) PetscCall(PetscDSGetNumFields(ds, &Nf));
124907eaae0cSMatthew G. Knepley   if (Nf <= 0) {
125007eaae0cSMatthew G. Knepley     Vec       y;
125107eaae0cSMatthew G. Knepley     PetscReal nrm;
125207eaae0cSMatthew G. Knepley 
12539566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u, &y));
12549566063dSJacob Faibussowitsch     PetscCall(TSComputeSolutionFunction(ts, ptime, y));
12559566063dSJacob Faibussowitsch     PetscCall(VecAXPY(y, -1.0, u));
12569566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer, PETSCVIEWERASCII, &flg));
1257d0c080abSJoseph Pusztay     if (flg) {
12589566063dSJacob Faibussowitsch       PetscCall(VecNorm(y, NORM_2, &nrm));
12599566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vf->viewer, "2-norm of error %g\n", (double)nrm));
1260d0c080abSJoseph Pusztay     }
12619566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer, PETSCVIEWERDRAW, &flg));
12621baa6e33SBarry Smith     if (flg) PetscCall(VecView(y, vf->viewer));
12639566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&y));
126407eaae0cSMatthew G. Knepley   } else {
126507eaae0cSMatthew G. Knepley     PetscErrorCode (**exactFuncs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx);
126607eaae0cSMatthew G. Knepley     void    **ctxs;
126707eaae0cSMatthew G. Knepley     Vec       v;
126807eaae0cSMatthew G. Knepley     PetscReal ferrors[1];
126907eaae0cSMatthew G. Knepley 
12709566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(Nf, &exactFuncs, Nf, &ctxs));
12719566063dSJacob Faibussowitsch     for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(ds, f, &exactFuncs[f], &ctxs[f]));
12729566063dSJacob Faibussowitsch     PetscCall(DMComputeL2FieldDiff(dm, ptime, exactFuncs, ctxs, u, ferrors));
12739566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Timestep: %04d time = %-8.4g \t L_2 Error: [", (int)step, (double)ptime));
127407eaae0cSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
12759566063dSJacob Faibussowitsch       if (f > 0) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ", "));
12769566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%2.3g", (double)ferrors[f]));
127707eaae0cSMatthew G. Knepley     }
12789566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "]\n"));
127907eaae0cSMatthew G. Knepley 
12809566063dSJacob Faibussowitsch     PetscCall(VecViewFromOptions(u, NULL, "-sol_vec_view"));
128107eaae0cSMatthew G. Knepley 
12829566063dSJacob Faibussowitsch     PetscCall(PetscOptionsHasName(NULL, NULL, "-exact_vec_view", &flg));
128307eaae0cSMatthew G. Knepley     if (flg) {
12849566063dSJacob Faibussowitsch       PetscCall(DMGetGlobalVector(dm, &v));
12859566063dSJacob Faibussowitsch       PetscCall(DMProjectFunction(dm, ptime, exactFuncs, ctxs, INSERT_ALL_VALUES, v));
12869566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetName((PetscObject)v, "Exact Solution"));
12879566063dSJacob Faibussowitsch       PetscCall(VecViewFromOptions(v, NULL, "-exact_vec_view"));
12889566063dSJacob Faibussowitsch       PetscCall(DMRestoreGlobalVector(dm, &v));
128907eaae0cSMatthew G. Knepley     }
12909566063dSJacob Faibussowitsch     PetscCall(PetscFree2(exactFuncs, ctxs));
129107eaae0cSMatthew G. Knepley   }
1292d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1293d0c080abSJoseph Pusztay }
1294d0c080abSJoseph Pusztay 
1295*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSNESIterations(TS ts, PetscInt n, PetscReal ptime, Vec v, void *monctx)
1296*d71ae5a4SJacob Faibussowitsch {
1297d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx)monctx;
1298d0c080abSJoseph Pusztay   PetscReal      x   = ptime, y;
1299d0c080abSJoseph Pusztay   PetscInt       its;
1300d0c080abSJoseph Pusztay 
1301d0c080abSJoseph Pusztay   PetscFunctionBegin;
1302d0c080abSJoseph Pusztay   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1303d0c080abSJoseph Pusztay   if (!n) {
1304d0c080abSJoseph Pusztay     PetscDrawAxis axis;
13059566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
13069566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Nonlinear iterations as function of time", "Time", "SNES Iterations"));
13079566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1308d0c080abSJoseph Pusztay     ctx->snes_its = 0;
1309d0c080abSJoseph Pusztay   }
13109566063dSJacob Faibussowitsch   PetscCall(TSGetSNESIterations(ts, &its));
1311d0c080abSJoseph Pusztay   y = its - ctx->snes_its;
13129566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg, &x, &y));
1313d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
13149566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
13159566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1316d0c080abSJoseph Pusztay   }
1317d0c080abSJoseph Pusztay   ctx->snes_its = its;
1318d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1319d0c080abSJoseph Pusztay }
1320d0c080abSJoseph Pusztay 
1321*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGKSPIterations(TS ts, PetscInt n, PetscReal ptime, Vec v, void *monctx)
1322*d71ae5a4SJacob Faibussowitsch {
1323d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx)monctx;
1324d0c080abSJoseph Pusztay   PetscReal      x   = ptime, y;
1325d0c080abSJoseph Pusztay   PetscInt       its;
1326d0c080abSJoseph Pusztay 
1327d0c080abSJoseph Pusztay   PetscFunctionBegin;
1328d0c080abSJoseph Pusztay   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1329d0c080abSJoseph Pusztay   if (!n) {
1330d0c080abSJoseph Pusztay     PetscDrawAxis axis;
13319566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
13329566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Linear iterations as function of time", "Time", "KSP Iterations"));
13339566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1334d0c080abSJoseph Pusztay     ctx->ksp_its = 0;
1335d0c080abSJoseph Pusztay   }
13369566063dSJacob Faibussowitsch   PetscCall(TSGetKSPIterations(ts, &its));
1337d0c080abSJoseph Pusztay   y = its - ctx->ksp_its;
13389566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg, &x, &y));
1339d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
13409566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
13419566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1342d0c080abSJoseph Pusztay   }
1343d0c080abSJoseph Pusztay   ctx->ksp_its = its;
1344d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1345d0c080abSJoseph Pusztay }
1346d0c080abSJoseph Pusztay 
1347d0c080abSJoseph Pusztay /*@C
1348d0c080abSJoseph Pusztay    TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope()
1349d0c080abSJoseph Pusztay 
1350d0c080abSJoseph Pusztay    Collective on TS
1351d0c080abSJoseph Pusztay 
1352d0c080abSJoseph Pusztay    Input Parameters:
1353d0c080abSJoseph Pusztay .  ts  - the ODE solver object
1354d0c080abSJoseph Pusztay 
1355d0c080abSJoseph Pusztay    Output Parameter:
1356d0c080abSJoseph Pusztay .  ctx - the context
1357d0c080abSJoseph Pusztay 
1358d0c080abSJoseph Pusztay    Level: intermediate
1359d0c080abSJoseph Pusztay 
1360db781477SPatrick Sanan .seealso: `TSMonitorLGTimeStep()`, `TSMonitorSet()`, `TSMonitorLGSolution()`, `TSMonitorLGError()`
1361d0c080abSJoseph Pusztay 
1362d0c080abSJoseph Pusztay @*/
1363*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorEnvelopeCtxCreate(TS ts, TSMonitorEnvelopeCtx *ctx)
1364*d71ae5a4SJacob Faibussowitsch {
1365d0c080abSJoseph Pusztay   PetscFunctionBegin;
13669566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
1367d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1368d0c080abSJoseph Pusztay }
1369d0c080abSJoseph Pusztay 
1370d0c080abSJoseph Pusztay /*@C
1371d0c080abSJoseph Pusztay    TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution
1372d0c080abSJoseph Pusztay 
1373d0c080abSJoseph Pusztay    Collective on TS
1374d0c080abSJoseph Pusztay 
1375d0c080abSJoseph Pusztay    Input Parameters:
1376d0c080abSJoseph Pusztay +  ts - the TS context
1377d0c080abSJoseph Pusztay .  step - current time-step
1378d0c080abSJoseph Pusztay .  ptime - current time
1379d0c080abSJoseph Pusztay .  u  - current solution
1380d0c080abSJoseph Pusztay -  dctx - the envelope context
1381d0c080abSJoseph Pusztay 
1382d0c080abSJoseph Pusztay    Options Database:
138367b8a455SSatish Balay .  -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time
1384d0c080abSJoseph Pusztay 
1385d0c080abSJoseph Pusztay    Level: intermediate
1386d0c080abSJoseph Pusztay 
1387d0c080abSJoseph Pusztay    Notes:
13883a61192cSBarry Smith    After a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope
13893a61192cSBarry Smith 
13903a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
13913a61192cSBarry Smith    to be used during the TS integration.
1392d0c080abSJoseph Pusztay 
1393db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxCreate()`
1394d0c080abSJoseph Pusztay @*/
1395*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorEnvelope(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx)
1396*d71ae5a4SJacob Faibussowitsch {
1397d0c080abSJoseph Pusztay   TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx;
1398d0c080abSJoseph Pusztay 
1399d0c080abSJoseph Pusztay   PetscFunctionBegin;
1400d0c080abSJoseph Pusztay   if (!ctx->max) {
14019566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u, &ctx->max));
14029566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u, &ctx->min));
14039566063dSJacob Faibussowitsch     PetscCall(VecCopy(u, ctx->max));
14049566063dSJacob Faibussowitsch     PetscCall(VecCopy(u, ctx->min));
1405d0c080abSJoseph Pusztay   } else {
14069566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMax(ctx->max, u, ctx->max));
14079566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMin(ctx->min, u, ctx->min));
1408d0c080abSJoseph Pusztay   }
1409d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1410d0c080abSJoseph Pusztay }
1411d0c080abSJoseph Pusztay 
1412d0c080abSJoseph Pusztay /*@C
1413d0c080abSJoseph Pusztay    TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution
1414d0c080abSJoseph Pusztay 
1415d0c080abSJoseph Pusztay    Collective on TS
1416d0c080abSJoseph Pusztay 
1417d0c080abSJoseph Pusztay    Input Parameter:
1418d0c080abSJoseph Pusztay .  ts - the TS context
1419d0c080abSJoseph Pusztay 
1420d8d19677SJose E. Roman    Output Parameters:
1421d0c080abSJoseph Pusztay +  max - the maximum values
1422d0c080abSJoseph Pusztay -  min - the minimum values
1423d0c080abSJoseph Pusztay 
1424d0c080abSJoseph Pusztay    Notes:
1425d0c080abSJoseph Pusztay     If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored
1426d0c080abSJoseph Pusztay 
1427d0c080abSJoseph Pusztay    Level: intermediate
1428d0c080abSJoseph Pusztay 
1429db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`
1430d0c080abSJoseph Pusztay @*/
1431*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorEnvelopeGetBounds(TS ts, Vec *max, Vec *min)
1432*d71ae5a4SJacob Faibussowitsch {
1433d0c080abSJoseph Pusztay   PetscInt i;
1434d0c080abSJoseph Pusztay 
1435d0c080abSJoseph Pusztay   PetscFunctionBegin;
1436d0c080abSJoseph Pusztay   if (max) *max = NULL;
1437d0c080abSJoseph Pusztay   if (min) *min = NULL;
1438d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
1439d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorEnvelope) {
1440d0c080abSJoseph Pusztay       TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)ts->monitorcontext[i];
1441d0c080abSJoseph Pusztay       if (max) *max = ctx->max;
1442d0c080abSJoseph Pusztay       if (min) *min = ctx->min;
1443d0c080abSJoseph Pusztay       break;
1444d0c080abSJoseph Pusztay     }
1445d0c080abSJoseph Pusztay   }
1446d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1447d0c080abSJoseph Pusztay }
1448d0c080abSJoseph Pusztay 
1449d0c080abSJoseph Pusztay /*@C
1450d0c080abSJoseph Pusztay    TSMonitorEnvelopeCtxDestroy - Destroys a context that was created  with TSMonitorEnvelopeCtxCreate().
1451d0c080abSJoseph Pusztay 
1452d0c080abSJoseph Pusztay    Collective on TSMonitorEnvelopeCtx
1453d0c080abSJoseph Pusztay 
1454d0c080abSJoseph Pusztay    Input Parameter:
1455d0c080abSJoseph Pusztay .  ctx - the monitor context
1456d0c080abSJoseph Pusztay 
1457d0c080abSJoseph Pusztay    Level: intermediate
1458d0c080abSJoseph Pusztay 
1459db781477SPatrick Sanan .seealso: `TSMonitorLGCtxCreate()`, `TSMonitorSet()`, `TSMonitorLGTimeStep()`
1460d0c080abSJoseph Pusztay @*/
1461*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx)
1462*d71ae5a4SJacob Faibussowitsch {
1463d0c080abSJoseph Pusztay   PetscFunctionBegin;
14649566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ctx)->min));
14659566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ctx)->max));
14669566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
1467d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1468d0c080abSJoseph Pusztay }
1469d0c080abSJoseph Pusztay 
1470d0c080abSJoseph Pusztay /*@C
1471d0c080abSJoseph Pusztay   TSDMSwarmMonitorMoments - Monitors the first three moments of a DMSarm being evolved by the TS
1472d0c080abSJoseph Pusztay 
1473d0c080abSJoseph Pusztay   Not collective
1474d0c080abSJoseph Pusztay 
1475d0c080abSJoseph Pusztay   Input Parameters:
1476d0c080abSJoseph Pusztay + ts   - the TS context
1477d0c080abSJoseph Pusztay . step - current timestep
1478d0c080abSJoseph Pusztay . t    - current time
1479d0c080abSJoseph Pusztay . u    - current solution
1480d0c080abSJoseph Pusztay - ctx  - not used
1481d0c080abSJoseph Pusztay 
1482d0c080abSJoseph Pusztay   Options Database:
148367b8a455SSatish Balay . -ts_dmswarm_monitor_moments - Monitor moments of particle distribution
1484d0c080abSJoseph Pusztay 
1485d0c080abSJoseph Pusztay   Level: intermediate
1486d0c080abSJoseph Pusztay 
1487d0c080abSJoseph Pusztay   Notes:
1488d0c080abSJoseph Pusztay   This requires a DMSwarm be attached to the TS.
1489d0c080abSJoseph Pusztay 
14903a61192cSBarry Smith   This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
14913a61192cSBarry Smith   to be used during the TS integration.
14923a61192cSBarry Smith 
1493db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `DMSWARM`
1494d0c080abSJoseph Pusztay @*/
1495*d71ae5a4SJacob Faibussowitsch PetscErrorCode TSDMSwarmMonitorMoments(TS ts, PetscInt step, PetscReal t, Vec U, PetscViewerAndFormat *vf)
1496*d71ae5a4SJacob Faibussowitsch {
1497d0c080abSJoseph Pusztay   DM                 sw;
1498d0c080abSJoseph Pusztay   const PetscScalar *u;
1499d0c080abSJoseph Pusztay   PetscReal          m = 1.0, totE = 0., totMom[3] = {0., 0., 0.};
1500d0c080abSJoseph Pusztay   PetscInt           dim, d, Np, p;
1501d0c080abSJoseph Pusztay   MPI_Comm           comm;
1502d0c080abSJoseph Pusztay 
1503d0c080abSJoseph Pusztay   PetscFunctionBeginUser;
15049566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &sw));
1505d0c080abSJoseph Pusztay   if (!sw || step % ts->monitorFrequency != 0) PetscFunctionReturn(0);
15069566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)ts, &comm));
15079566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(sw, &dim));
15089566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(U, &Np));
1509d0c080abSJoseph Pusztay   Np /= dim;
15109566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U, &u));
1511d0c080abSJoseph Pusztay   for (p = 0; p < Np; ++p) {
1512d0c080abSJoseph Pusztay     for (d = 0; d < dim; ++d) {
1513d0c080abSJoseph Pusztay       totE += PetscRealPart(u[p * dim + d] * u[p * dim + d]);
1514d0c080abSJoseph Pusztay       totMom[d] += PetscRealPart(u[p * dim + d]);
1515d0c080abSJoseph Pusztay     }
1516d0c080abSJoseph Pusztay   }
15179566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U, &u));
1518d0c080abSJoseph Pusztay   for (d = 0; d < dim; ++d) totMom[d] *= m;
1519d0c080abSJoseph Pusztay   totE *= 0.5 * m;
152063a3b9bcSJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "Step %4" PetscInt_FMT " Total Energy: %10.8lf", step, (double)totE));
152163a3b9bcSJacob Faibussowitsch   for (d = 0; d < dim; ++d) PetscCall(PetscPrintf(comm, "    Total Momentum %c: %10.8lf", (char)('x' + d), (double)totMom[d]));
15229566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "\n"));
1523d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1524d0c080abSJoseph Pusztay }
1525