xref: /petsc/src/ts/interface/tsmon.c (revision 1cc06b555e92f8ec64db10330b8bbd830e5bc876)
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
8bcf0153eSBarry Smith    TSMonitor - Runs all user-provided monitor routines set using `TSMonitorSet()`
9d0c080abSJoseph Pusztay 
10c3339decSBarry Smith    Collective
11d0c080abSJoseph Pusztay 
12d0c080abSJoseph Pusztay    Input Parameters:
13bcf0153eSBarry Smith +  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 
18bcf0153eSBarry Smith    Level: developer
19bcf0153eSBarry Smith 
20d0c080abSJoseph Pusztay    Notes:
21bcf0153eSBarry Smith    `TSMonitor()` is typically used automatically within the time stepping implementations.
22d0c080abSJoseph Pusztay    Users would almost never call this routine directly.
23d0c080abSJoseph Pusztay 
24d0c080abSJoseph Pusztay    A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions
25d0c080abSJoseph Pusztay 
26bcf0153eSBarry Smith .seealso: `TS`, `TSMonitorSet()`, `TSMonitorSetFromOptions()`
27d0c080abSJoseph Pusztay @*/
28d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitor(TS ts, PetscInt step, PetscReal ptime, Vec u)
29d71ae5a4SJacob Faibussowitsch {
30d0c080abSJoseph Pusztay   DM       dm;
31d0c080abSJoseph Pusztay   PetscInt i, n = ts->numbermonitors;
32d0c080abSJoseph Pusztay 
33d0c080abSJoseph Pusztay   PetscFunctionBegin;
34d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
35d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(u, VEC_CLASSID, 4);
36d0c080abSJoseph Pusztay 
379566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
389566063dSJacob Faibussowitsch   PetscCall(DMSetOutputSequenceNumber(dm, step, ptime));
39d0c080abSJoseph Pusztay 
409566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(u));
4148a46eb9SPierre Jolivet   for (i = 0; i < n; i++) PetscCall((*ts->monitor[i])(ts, step, ptime, u, ts->monitorcontext[i]));
429566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(u));
433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
44d0c080abSJoseph Pusztay }
45d0c080abSJoseph Pusztay 
46d0c080abSJoseph Pusztay /*@C
47d0c080abSJoseph Pusztay    TSMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
48d0c080abSJoseph Pusztay 
49c3339decSBarry Smith    Collective
50d0c080abSJoseph Pusztay 
51d0c080abSJoseph Pusztay    Input Parameters:
52bcf0153eSBarry Smith +  ts - `TS` object you wish to monitor
53d0c080abSJoseph Pusztay .  name - the monitor type one is seeking
54d0c080abSJoseph Pusztay .  help - message indicating what monitoring is done
55d0c080abSJoseph Pusztay .  manual - manual page for the monitor
56d0c080abSJoseph Pusztay .  monitor - the monitor function
57bcf0153eSBarry Smith -  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
58d0c080abSJoseph Pusztay 
59d0c080abSJoseph Pusztay    Level: developer
60d0c080abSJoseph Pusztay 
61*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
62db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
63db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
64db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
65c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
66db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
67db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
68d0c080abSJoseph Pusztay @*/
69d71ae5a4SJacob 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 *))
70d71ae5a4SJacob Faibussowitsch {
71d0c080abSJoseph Pusztay   PetscViewer       viewer;
72d0c080abSJoseph Pusztay   PetscViewerFormat format;
73d0c080abSJoseph Pusztay   PetscBool         flg;
74d0c080abSJoseph Pusztay 
75d0c080abSJoseph Pusztay   PetscFunctionBegin;
769566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts), ((PetscObject)ts)->options, ((PetscObject)ts)->prefix, name, &viewer, &format, &flg));
77d0c080abSJoseph Pusztay   if (flg) {
78d0c080abSJoseph Pusztay     PetscViewerAndFormat *vf;
799812b6beSJed Brown     char                  interval_key[1024];
809566063dSJacob Faibussowitsch     PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf));
819812b6beSJed Brown     PetscCall(PetscSNPrintf(interval_key, sizeof interval_key, "%s_interval", name));
829812b6beSJed Brown     PetscCall(PetscOptionsGetInt(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, interval_key, &vf->view_interval, NULL));
839566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject)viewer));
841baa6e33SBarry Smith     if (monitorsetup) PetscCall((*monitorsetup)(ts, vf));
859566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, (PetscErrorCode(*)(TS, PetscInt, PetscReal, Vec, void *))monitor, vf, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy));
86d0c080abSJoseph Pusztay   }
873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
88d0c080abSJoseph Pusztay }
89d0c080abSJoseph Pusztay 
90d0c080abSJoseph Pusztay /*@C
91d0c080abSJoseph Pusztay    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
92d0c080abSJoseph Pusztay    timestep to display the iteration's  progress.
93d0c080abSJoseph Pusztay 
94c3339decSBarry Smith    Logically Collective
95d0c080abSJoseph Pusztay 
96d0c080abSJoseph Pusztay    Input Parameters:
97bcf0153eSBarry Smith +  ts - the `TS` context obtained from `TSCreate()`
98d0c080abSJoseph Pusztay .  monitor - monitoring routine
99195e9b02SBarry Smith .  mctx - [optional] user-defined context for private data for the monitor routine (use `NULL` if no context is desired)
100195e9b02SBarry Smith -  monitordestroy - [optional] routine that frees monitor context (may be `NULL`)
101d0c080abSJoseph Pusztay 
10220f4b53cSBarry Smith    Calling sequence of `monitor`:
103d0c080abSJoseph Pusztay $    PetscErrorCode monitor(TS ts, PetscInt steps, PetscReal time, Vec u, void *mctx)
10420f4b53cSBarry Smith +    ts - the `TS` context
105d0c080abSJoseph 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)
106d0c080abSJoseph Pusztay .    time - current time
107d0c080abSJoseph Pusztay .    u - current iterate
108d0c080abSJoseph Pusztay -    mctx - [optional] monitoring context
109d0c080abSJoseph Pusztay 
110bcf0153eSBarry Smith    Level: intermediate
111bcf0153eSBarry Smith 
112bcf0153eSBarry Smith    Note:
113195e9b02SBarry Smith    This routine adds an additional monitor to the list of monitors that already has been loaded.
114d0c080abSJoseph Pusztay 
115bcf0153eSBarry Smith    Fortran Note:
116bcf0153eSBarry Smith    Only a single monitor function can be set for each `TS` object
117d0c080abSJoseph Pusztay 
118*1cc06b55SBarry Smith .seealso: [](ch_ts), `TSMonitorDefault()`, `TSMonitorCancel()`, `TSDMSwarmMonitorMoments()`, `TSMonitorExtreme()`, `TSMonitorDrawSolution()`,
1193a61192cSBarry Smith           `TSMonitorDrawSolutionPhase()`, `TSMonitorDrawSolutionFunction()`, `TSMonitorDrawError()`, `TSMonitorSolution()`, `TSMonitorSolutionVTK()`,
1203a61192cSBarry Smith           `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorSPSwarmSolution()`, `TSMonitorError()`, `TSMonitorEnvelope()`, `TSDMSwarmMonitorMoments()`
121d0c080abSJoseph Pusztay @*/
122d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSet(TS ts, PetscErrorCode (*monitor)(TS, PetscInt, PetscReal, Vec, void *), void *mctx, PetscErrorCode (*mdestroy)(void **))
123d71ae5a4SJacob 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));
1313ba16761SJacob Faibussowitsch     if (identical) PetscFunctionReturn(PETSC_SUCCESS);
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;
1373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
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 
143c3339decSBarry Smith    Logically Collective
144d0c080abSJoseph Pusztay 
1452fe279fdSBarry Smith    Input Parameter:
146bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
147d0c080abSJoseph Pusztay 
148d0c080abSJoseph Pusztay    Level: intermediate
149d0c080abSJoseph Pusztay 
150bcf0153eSBarry Smith    Note:
151bcf0153eSBarry Smith    There is no way to remove a single, specific monitor.
152bcf0153eSBarry Smith 
153*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorDefault()`, `TSMonitorSet()`
154d0c080abSJoseph Pusztay @*/
155d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorCancel(TS ts)
156d71ae5a4SJacob 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;
1653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
166d0c080abSJoseph Pusztay }
167d0c080abSJoseph Pusztay 
168d0c080abSJoseph Pusztay /*@C
169195e9b02SBarry Smith    TSMonitorDefault - The default monitor, prints the timestep and time for each step
170d0c080abSJoseph Pusztay 
171bcf0153eSBarry Smith    Options Database Key:
1723a61192cSBarry Smith .  -ts_monitor - monitors the time integration
1733a61192cSBarry Smith 
174d0c080abSJoseph Pusztay    Level: intermediate
175d0c080abSJoseph Pusztay 
176bcf0153eSBarry Smith    Notes:
177bcf0153eSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
178bcf0153eSBarry Smith    to be used during the `TS` integration.
179bcf0153eSBarry Smith 
180*1cc06b55SBarry Smith .seealso: [](ch_ts), `TSMonitorSet()`, `TSDMSwarmMonitorMoments()`, `TSMonitorExtreme()`, `TSMonitorDrawSolution()`,
1813a61192cSBarry Smith           `TSMonitorDrawSolutionPhase()`, `TSMonitorDrawSolutionFunction()`, `TSMonitorDrawError()`, `TSMonitorSolution()`, `TSMonitorSolutionVTK()`,
1823a61192cSBarry Smith           `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorSPSwarmSolution()`, `TSMonitorError()`, `TSMonitorEnvelope()`, `TSDMSwarmMonitorMoments()`
183d0c080abSJoseph Pusztay @*/
184d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDefault(TS ts, PetscInt step, PetscReal ptime, Vec v, PetscViewerAndFormat *vf)
185d71ae5a4SJacob 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));
2173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
218d0c080abSJoseph Pusztay }
219d0c080abSJoseph Pusztay 
220d0c080abSJoseph Pusztay /*@C
221d0c080abSJoseph Pusztay    TSMonitorExtreme - Prints the extreme values of the solution at each timestep
222d0c080abSJoseph Pusztay 
223bcf0153eSBarry Smith    Level: intermediate
224bcf0153eSBarry Smith 
225195e9b02SBarry Smith    Note:
2263a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
227195e9b02SBarry Smith    to be used during the `TS` integration.
2283a61192cSBarry Smith 
229*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`
230d0c080abSJoseph Pusztay @*/
231d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorExtreme(TS ts, PetscInt step, PetscReal ptime, Vec v, PetscViewerAndFormat *vf)
232d71ae5a4SJacob 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));
2493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
250d0c080abSJoseph Pusztay }
251d0c080abSJoseph Pusztay 
252d0c080abSJoseph Pusztay /*@C
253bcf0153eSBarry Smith    TSMonitorLGCtxCreate - Creates a `TSMonitorLGCtx` context for use with
254bcf0153eSBarry Smith    `TS` to monitor the solution process graphically in various ways
255d0c080abSJoseph Pusztay 
256c3339decSBarry Smith    Collective
257d0c080abSJoseph Pusztay 
258d0c080abSJoseph Pusztay    Input Parameters:
259195e9b02SBarry Smith +  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 
268bcf0153eSBarry Smith    Options Database Keys:
269d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep - automatically sets line graph monitor
270d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep_log - automatically sets line graph monitor
271bcf0153eSBarry Smith .  -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
273bcf0153eSBarry Smith .  -ts_monitor_lg_ksp_iterations - monitor the number of `KSP` iterations needed for each timestep
274bcf0153eSBarry Smith .  -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    Level: intermediate
278d0c080abSJoseph Pusztay 
279bcf0153eSBarry Smith    Notes:
280bcf0153eSBarry Smith    Pass the context and `TSMonitorLGCtxDestroy()` to `TSMonitorSet()` to have the context destroyed when no longer needed.
281bcf0153eSBarry Smith 
282bcf0153eSBarry Smith    One can provide a function that transforms the solution before plotting it with `TSMonitorLGCtxSetTransform()` or `TSMonitorLGSetTransform()`
283bcf0153eSBarry Smith 
284bcf0153eSBarry Smith    Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a `TS` object as the
285bcf0153eSBarry Smith    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
286bcf0153eSBarry Smith    as the first argument.
287bcf0153eSBarry Smith 
288bcf0153eSBarry Smith    One can control the names displayed for each solution or error variable with `TSMonitorLGCtxSetVariableNames()` or `TSMonitorLGSetVariableNames()`
289bcf0153eSBarry Smith 
290*1cc06b55SBarry Smith .seealso: [](ch_ts), `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 @*/
296d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, TSMonitorLGCtx *ctx)
297d71ae5a4SJacob Faibussowitsch {
298d0c080abSJoseph Pusztay   PetscDraw draw;
299d0c080abSJoseph Pusztay 
300d0c080abSJoseph Pusztay   PetscFunctionBegin;
3019566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
3029566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm, host, label, x, y, m, n, &draw));
3039566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetFromOptions(draw));
3049566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGCreate(draw, 1, &(*ctx)->lg));
3059566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGSetFromOptions((*ctx)->lg));
3069566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw));
307d0c080abSJoseph Pusztay   (*ctx)->howoften = howoften;
3083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
309d0c080abSJoseph Pusztay }
310d0c080abSJoseph Pusztay 
311d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGTimeStep(TS ts, PetscInt step, PetscReal ptime, Vec v, void *monctx)
312d71ae5a4SJacob Faibussowitsch {
313d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx)monctx;
314d0c080abSJoseph Pusztay   PetscReal      x   = ptime, y;
315d0c080abSJoseph Pusztay 
316d0c080abSJoseph Pusztay   PetscFunctionBegin;
3173ba16761SJacob Faibussowitsch   if (step < 0) PetscFunctionReturn(PETSC_SUCCESS); /* -1 indicates an interpolated solution */
318d0c080abSJoseph Pusztay   if (!step) {
319d0c080abSJoseph Pusztay     PetscDrawAxis axis;
320d0c080abSJoseph Pusztay     const char   *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step";
3219566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
3229566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Timestep as function of time", "Time", ylabel));
3239566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
324d0c080abSJoseph Pusztay   }
3259566063dSJacob Faibussowitsch   PetscCall(TSGetTimeStep(ts, &y));
326d0c080abSJoseph Pusztay   if (ctx->semilogy) y = PetscLog10Real(y);
3279566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg, &x, &y));
328d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
3299566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
3309566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
331d0c080abSJoseph Pusztay   }
3323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
333d0c080abSJoseph Pusztay }
334d0c080abSJoseph Pusztay 
335d0c080abSJoseph Pusztay /*@C
336195e9b02SBarry Smith    TSMonitorLGCtxDestroy - Destroys a line graph context that was created with `TSMonitorLGCtxCreate()`.
337d0c080abSJoseph Pusztay 
338c3339decSBarry Smith    Collective
339d0c080abSJoseph Pusztay 
340d0c080abSJoseph Pusztay    Input Parameter:
341d0c080abSJoseph Pusztay .  ctx - the monitor context
342d0c080abSJoseph Pusztay 
343d0c080abSJoseph Pusztay    Level: intermediate
344d0c080abSJoseph Pusztay 
345bcf0153eSBarry Smith    Note:
346bcf0153eSBarry Smith    Pass to `TSMonitorSet()` along with the context and `TSMonitorLGTimeStep()`
347bcf0153eSBarry Smith 
348*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorLGCtxCreate()`, `TSMonitorSet()`, `TSMonitorLGTimeStep();`
349d0c080abSJoseph Pusztay @*/
350d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
351d71ae5a4SJacob Faibussowitsch {
352d0c080abSJoseph Pusztay   PetscFunctionBegin;
35348a46eb9SPierre Jolivet   if ((*ctx)->transformdestroy) PetscCall(((*ctx)->transformdestroy)((*ctx)->transformctx));
3549566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGDestroy(&(*ctx)->lg));
3559566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&(*ctx)->names));
3569566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&(*ctx)->displaynames));
3579566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ctx)->displayvariables));
3589566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ctx)->displayvalues));
3599566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
3603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
361d0c080abSJoseph Pusztay }
362d0c080abSJoseph Pusztay 
363d7462660SMatthew Knepley /* Creates a TSMonitorSPCtx for use with DMSwarm particle visualizations */
36460e16b1bSMatthew G. Knepley 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, PetscBool multispecies, TSMonitorSPCtx *ctx)
365d71ae5a4SJacob Faibussowitsch {
366d0c080abSJoseph Pusztay   PetscDraw draw;
367d0c080abSJoseph Pusztay 
368d0c080abSJoseph Pusztay   PetscFunctionBegin;
3699566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
3709566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm, host, label, x, y, m, n, &draw));
3719566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetFromOptions(draw));
3729566063dSJacob Faibussowitsch   PetscCall(PetscDrawSPCreate(draw, 1, &(*ctx)->sp));
3739566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw));
374d0c080abSJoseph Pusztay   (*ctx)->howoften     = howoften;
375d7462660SMatthew Knepley   (*ctx)->retain       = retain;
376d7462660SMatthew Knepley   (*ctx)->phase        = phase;
37760e16b1bSMatthew G. Knepley   (*ctx)->multispecies = multispecies;
3783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
379d0c080abSJoseph Pusztay }
380d0c080abSJoseph Pusztay 
38160e16b1bSMatthew G. Knepley /* Destroys a TSMonitorSPCtx that was created with TSMonitorSPCtxCreate */
382d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSPCtxDestroy(TSMonitorSPCtx *ctx)
383d71ae5a4SJacob Faibussowitsch {
384d0c080abSJoseph Pusztay   PetscFunctionBegin;
385d0c080abSJoseph Pusztay 
3869566063dSJacob Faibussowitsch   PetscCall(PetscDrawSPDestroy(&(*ctx)->sp));
3879566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
38860e16b1bSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
38960e16b1bSMatthew G. Knepley }
390d0c080abSJoseph Pusztay 
39160e16b1bSMatthew G. Knepley /* Creates a TSMonitorHGCtx for use with DMSwarm particle visualizations */
39260e16b1bSMatthew G. Knepley PetscErrorCode TSMonitorHGCtxCreate(MPI_Comm comm, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, PetscInt Ns, PetscInt Nb, PetscBool velocity, TSMonitorHGCtx *ctx)
39360e16b1bSMatthew G. Knepley {
39460e16b1bSMatthew G. Knepley   PetscDraw draw;
39560e16b1bSMatthew G. Knepley   PetscInt  s;
39660e16b1bSMatthew G. Knepley 
39760e16b1bSMatthew G. Knepley   PetscFunctionBegin;
39860e16b1bSMatthew G. Knepley   PetscCall(PetscNew(ctx));
39960e16b1bSMatthew G. Knepley   PetscCall(PetscMalloc1(Ns, &(*ctx)->hg));
40060e16b1bSMatthew G. Knepley   for (s = 0; s < Ns; ++s) {
40160e16b1bSMatthew G. Knepley     PetscCall(PetscDrawCreate(comm, host, label, x + s * m, y, m, n, &draw));
40260e16b1bSMatthew G. Knepley     PetscCall(PetscDrawSetFromOptions(draw));
40360e16b1bSMatthew G. Knepley     PetscCall(PetscDrawHGCreate(draw, Nb, &(*ctx)->hg[s]));
40460e16b1bSMatthew G. Knepley     PetscCall(PetscDrawHGCalcStats((*ctx)->hg[s], PETSC_TRUE));
40560e16b1bSMatthew G. Knepley     PetscCall(PetscDrawDestroy(&draw));
40660e16b1bSMatthew G. Knepley   }
40760e16b1bSMatthew G. Knepley   (*ctx)->howoften = howoften;
40860e16b1bSMatthew G. Knepley   (*ctx)->Ns       = Ns;
40960e16b1bSMatthew G. Knepley   (*ctx)->velocity = velocity;
41060e16b1bSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
41160e16b1bSMatthew G. Knepley }
41260e16b1bSMatthew G. Knepley 
41360e16b1bSMatthew G. Knepley /* Destroys a TSMonitorHGCtx that was created with TSMonitorHGCtxCreate */
41460e16b1bSMatthew G. Knepley PetscErrorCode TSMonitorHGCtxDestroy(TSMonitorHGCtx *ctx)
41560e16b1bSMatthew G. Knepley {
41660e16b1bSMatthew G. Knepley   PetscInt s;
41760e16b1bSMatthew G. Knepley 
41860e16b1bSMatthew G. Knepley   PetscFunctionBegin;
41960e16b1bSMatthew G. Knepley   for (s = 0; s < (*ctx)->Ns; ++s) PetscCall(PetscDrawHGDestroy(&(*ctx)->hg[s]));
42060e16b1bSMatthew G. Knepley   PetscCall(PetscFree((*ctx)->hg));
42160e16b1bSMatthew G. Knepley   PetscCall(PetscFree(*ctx));
4223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
423d0c080abSJoseph Pusztay }
424d0c080abSJoseph Pusztay 
425d0c080abSJoseph Pusztay /*@C
426bcf0153eSBarry Smith    TSMonitorDrawSolution - Monitors progress of the `TS` solvers by calling
427bcf0153eSBarry Smith    `VecView()` for the solution at each timestep
428d0c080abSJoseph Pusztay 
429c3339decSBarry Smith    Collective
430d0c080abSJoseph Pusztay 
431d0c080abSJoseph Pusztay    Input Parameters:
432bcf0153eSBarry Smith +  ts - the `TS` context
433d0c080abSJoseph Pusztay .  step - current time-step
434d0c080abSJoseph Pusztay .  ptime - current time
435195e9b02SBarry Smith -  dummy - either a viewer or `NULL`
436d0c080abSJoseph Pusztay 
437bcf0153eSBarry Smith    Options Database Keys:
438bcf0153eSBarry Smith +   -ts_monitor_draw_solution - draw the solution at each time-step
439bcf0153eSBarry Smith -   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
440bcf0153eSBarry Smith 
441bcf0153eSBarry Smith    Level: intermediate
442d0c080abSJoseph Pusztay 
443d0c080abSJoseph Pusztay    Notes:
444195e9b02SBarry Smith    The initial solution and current solution are not displayed with a common axis scaling so generally the option `-ts_monitor_draw_solution_initial`
445d0c080abSJoseph Pusztay    will look bad
446d0c080abSJoseph Pusztay 
447bcf0153eSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, as well as the context created with
448bcf0153eSBarry Smith    `TSMonitorDrawCtxCreate()` and the function `TSMonitorDrawCtxDestroy()` to cause the monitor to be used during the `TS` integration.
4493a61192cSBarry Smith 
450*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawCtxCreate()`, `TSMonitorDrawCtxDestroy()`
451d0c080abSJoseph Pusztay @*/
452d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy)
453d71ae5a4SJacob Faibussowitsch {
454d0c080abSJoseph Pusztay   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
455d0c080abSJoseph Pusztay   PetscDraw        draw;
456d0c080abSJoseph Pusztay 
457d0c080abSJoseph Pusztay   PetscFunctionBegin;
458d0c080abSJoseph Pusztay   if (!step && ictx->showinitial) {
45948a46eb9SPierre Jolivet     if (!ictx->initialsolution) PetscCall(VecDuplicate(u, &ictx->initialsolution));
4609566063dSJacob Faibussowitsch     PetscCall(VecCopy(u, ictx->initialsolution));
461d0c080abSJoseph Pusztay   }
4623ba16761SJacob Faibussowitsch   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(PETSC_SUCCESS);
463d0c080abSJoseph Pusztay 
464d0c080abSJoseph Pusztay   if (ictx->showinitial) {
465d0c080abSJoseph Pusztay     PetscReal pause;
4669566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetPause(ictx->viewer, &pause));
4679566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetPause(ictx->viewer, 0.0));
4689566063dSJacob Faibussowitsch     PetscCall(VecView(ictx->initialsolution, ictx->viewer));
4699566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetPause(ictx->viewer, pause));
4709566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetHold(ictx->viewer, PETSC_TRUE));
471d0c080abSJoseph Pusztay   }
4729566063dSJacob Faibussowitsch   PetscCall(VecView(u, ictx->viewer));
473d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
474d0c080abSJoseph Pusztay     PetscReal xl, yl, xr, yr, h;
475d0c080abSJoseph Pusztay     char      time[32];
476d0c080abSJoseph Pusztay 
4779566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(ictx->viewer, 0, &draw));
4789566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(time, 32, "Timestep %d Time %g", (int)step, (double)ptime));
4799566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
480d0c080abSJoseph Pusztay     h = yl + .95 * (yr - yl);
4819566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw, .5 * (xl + xr), h, PETSC_DRAW_BLACK, time));
4829566063dSJacob Faibussowitsch     PetscCall(PetscDrawFlush(draw));
483d0c080abSJoseph Pusztay   }
484d0c080abSJoseph Pusztay 
4851baa6e33SBarry Smith   if (ictx->showinitial) PetscCall(PetscViewerDrawSetHold(ictx->viewer, PETSC_FALSE));
4863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
487d0c080abSJoseph Pusztay }
488d0c080abSJoseph Pusztay 
489d0c080abSJoseph Pusztay /*@C
490bcf0153eSBarry Smith    TSMonitorDrawSolutionPhase - Monitors progress of the `TS` solvers by plotting the solution as a phase diagram
491d0c080abSJoseph Pusztay 
492c3339decSBarry Smith    Collective
493d0c080abSJoseph Pusztay 
494d0c080abSJoseph Pusztay    Input Parameters:
495bcf0153eSBarry Smith +  ts - the `TS` context
496d0c080abSJoseph Pusztay .  step - current time-step
497d0c080abSJoseph Pusztay .  ptime - current time
498195e9b02SBarry Smith -  dummy - either a viewer or `NULL`
499d0c080abSJoseph Pusztay 
500d0c080abSJoseph Pusztay    Level: intermediate
501d0c080abSJoseph Pusztay 
502bcf0153eSBarry Smith    Notes:
503bcf0153eSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
504bcf0153eSBarry Smith    to be used during the `TS` integration.
505bcf0153eSBarry Smith 
506*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
507d0c080abSJoseph Pusztay @*/
508d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawSolutionPhase(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy)
509d71ae5a4SJacob Faibussowitsch {
510d0c080abSJoseph Pusztay   TSMonitorDrawCtx   ictx = (TSMonitorDrawCtx)dummy;
511d0c080abSJoseph Pusztay   PetscDraw          draw;
512d0c080abSJoseph Pusztay   PetscDrawAxis      axis;
513d0c080abSJoseph Pusztay   PetscInt           n;
514d0c080abSJoseph Pusztay   PetscMPIInt        size;
515d0c080abSJoseph Pusztay   PetscReal          U0, U1, xl, yl, xr, yr, h;
516d0c080abSJoseph Pusztay   char               time[32];
517d0c080abSJoseph Pusztay   const PetscScalar *U;
518d0c080abSJoseph Pusztay 
519d0c080abSJoseph Pusztay   PetscFunctionBegin;
5209566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)ts), &size));
5213c633725SBarry Smith   PetscCheck(size == 1, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Only allowed for sequential runs");
5229566063dSJacob Faibussowitsch   PetscCall(VecGetSize(u, &n));
5233c633725SBarry Smith   PetscCheck(n == 2, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Only for ODEs with two unknowns");
524d0c080abSJoseph Pusztay 
5259566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(ictx->viewer, 0, &draw));
5269566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDrawAxis(ictx->viewer, 0, &axis));
5279566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisGetLimits(axis, &xl, &xr, &yl, &yr));
528d0c080abSJoseph Pusztay   if (!step) {
5299566063dSJacob Faibussowitsch     PetscCall(PetscDrawClear(draw));
5309566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisDraw(axis));
531d0c080abSJoseph Pusztay   }
532d0c080abSJoseph Pusztay 
5339566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(u, &U));
534d0c080abSJoseph Pusztay   U0 = PetscRealPart(U[0]);
535d0c080abSJoseph Pusztay   U1 = PetscRealPart(U[1]);
5369566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(u, &U));
5373ba16761SJacob Faibussowitsch   if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(PETSC_SUCCESS);
538d0c080abSJoseph Pusztay 
539d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
5409566063dSJacob Faibussowitsch   PetscCall(PetscDrawPoint(draw, U0, U1, PETSC_DRAW_BLACK));
541d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
5429566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
5439566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(time, 32, "Timestep %d Time %g", (int)step, (double)ptime));
544d0c080abSJoseph Pusztay     h = yl + .95 * (yr - yl);
5459566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw, .5 * (xl + xr), h, PETSC_DRAW_BLACK, time));
546d0c080abSJoseph Pusztay   }
547d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
5489566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
5499566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
5509566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
5513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
552d0c080abSJoseph Pusztay }
553d0c080abSJoseph Pusztay 
554d0c080abSJoseph Pusztay /*@C
555bcf0153eSBarry Smith    TSMonitorDrawCtxDestroy - Destroys the monitor context for `TSMonitorDrawSolution()`
556d0c080abSJoseph Pusztay 
557c3339decSBarry Smith    Collective
558d0c080abSJoseph Pusztay 
5592fe279fdSBarry Smith    Input Parameter:
560d0c080abSJoseph Pusztay .    ctx - the monitor context
561d0c080abSJoseph Pusztay 
562d0c080abSJoseph Pusztay    Level: intermediate
563d0c080abSJoseph Pusztay 
564*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawSolution()`, `TSMonitorDrawError()`, `TSMonitorDrawCtx`
565d0c080abSJoseph Pusztay @*/
566d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
567d71ae5a4SJacob Faibussowitsch {
568d0c080abSJoseph Pusztay   PetscFunctionBegin;
5699566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&(*ictx)->viewer));
5709566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ictx)->initialsolution));
5719566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ictx));
5723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
573d0c080abSJoseph Pusztay }
574d0c080abSJoseph Pusztay 
575d0c080abSJoseph Pusztay /*@C
576bcf0153eSBarry Smith    TSMonitorDrawCtxCreate - Creates the monitor context for `TSMonitorDrawCtx`
577d0c080abSJoseph Pusztay 
578c3339decSBarry Smith    Collective
579d0c080abSJoseph Pusztay 
580d0c080abSJoseph Pusztay    Input Parameter:
581d0c080abSJoseph Pusztay .    ts - time-step context
582d0c080abSJoseph Pusztay 
583d5b43468SJose E. Roman    Output Parameter:
584d0c080abSJoseph Pusztay .    ctx - the monitor context
585d0c080abSJoseph Pusztay 
586bcf0153eSBarry Smith    Options Database Keys:
587bcf0153eSBarry Smith +   -ts_monitor_draw_solution - draw the solution at each time-step
588bcf0153eSBarry Smith -   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
589d0c080abSJoseph Pusztay 
590d0c080abSJoseph Pusztay    Level: intermediate
591d0c080abSJoseph Pusztay 
592bcf0153eSBarry Smith    Note:
593bcf0153eSBarry Smith    The context created by this function, `PetscMonitorDrawSolution()`, and `TSMonitorDrawCtxDestroy()` should be passed together to `TSMonitorSet()`.
594bcf0153eSBarry Smith 
595*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorDrawCtxDestroy()`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawCtx`, `PetscMonitorDrawSolution()`
596d0c080abSJoseph Pusztay @*/
597d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, TSMonitorDrawCtx *ctx)
598d71ae5a4SJacob Faibussowitsch {
599d0c080abSJoseph Pusztay   PetscFunctionBegin;
6009566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
6019566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawOpen(comm, host, label, x, y, m, n, &(*ctx)->viewer));
6029566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetFromOptions((*ctx)->viewer));
603d0c080abSJoseph Pusztay 
604d0c080abSJoseph Pusztay   (*ctx)->howoften    = howoften;
605d0c080abSJoseph Pusztay   (*ctx)->showinitial = PETSC_FALSE;
6069566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-ts_monitor_draw_solution_initial", &(*ctx)->showinitial, NULL));
607d0c080abSJoseph Pusztay 
608d0c080abSJoseph Pusztay   (*ctx)->showtimestepandtime = PETSC_FALSE;
6099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-ts_monitor_draw_solution_show_time", &(*ctx)->showtimestepandtime, NULL));
6103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
611d0c080abSJoseph Pusztay }
612d0c080abSJoseph Pusztay 
613d0c080abSJoseph Pusztay /*@C
614bcf0153eSBarry Smith    TSMonitorDrawSolutionFunction - Monitors progress of the `TS` solvers by calling
615bcf0153eSBarry Smith    `VecView()` for the solution provided by `TSSetSolutionFunction()` at each timestep
616d0c080abSJoseph Pusztay 
617c3339decSBarry Smith    Collective
618d0c080abSJoseph Pusztay 
619d0c080abSJoseph Pusztay    Input Parameters:
620bcf0153eSBarry Smith +  ts - the `TS` context
621d0c080abSJoseph Pusztay .  step - current time-step
622d0c080abSJoseph Pusztay .  ptime - current time
623195e9b02SBarry Smith -  dummy - either a viewer or `NULL`
624d0c080abSJoseph Pusztay 
625bcf0153eSBarry Smith    Options Database Key:
626bcf0153eSBarry Smith .  -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided `TSSetSolutionFunction()`
6273a61192cSBarry Smith 
628d0c080abSJoseph Pusztay    Level: intermediate
629d0c080abSJoseph Pusztay 
630bcf0153eSBarry Smith    Note:
631bcf0153eSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
632bcf0153eSBarry Smith    to be used during the `TS` integration.
633bcf0153eSBarry Smith 
634*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
635d0c080abSJoseph Pusztay @*/
636d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawSolutionFunction(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy)
637d71ae5a4SJacob Faibussowitsch {
638d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
639d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
640d0c080abSJoseph Pusztay   Vec              work;
641d0c080abSJoseph Pusztay 
642d0c080abSJoseph Pusztay   PetscFunctionBegin;
6433ba16761SJacob Faibussowitsch   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(PETSC_SUCCESS);
6449566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u, &work));
6459566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts, ptime, work));
6469566063dSJacob Faibussowitsch   PetscCall(VecView(work, viewer));
6479566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work));
6483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
649d0c080abSJoseph Pusztay }
650d0c080abSJoseph Pusztay 
651d0c080abSJoseph Pusztay /*@C
652bcf0153eSBarry Smith    TSMonitorDrawError - Monitors progress of the `TS` solvers by calling
653bcf0153eSBarry Smith    `VecView()` for the error at each timestep
654d0c080abSJoseph Pusztay 
655c3339decSBarry Smith    Collective
656d0c080abSJoseph Pusztay 
657d0c080abSJoseph Pusztay    Input Parameters:
658bcf0153eSBarry Smith +  ts - the `TS` context
659d0c080abSJoseph Pusztay .  step - current time-step
660d0c080abSJoseph Pusztay .  ptime - current time
661195e9b02SBarry Smith -  dummy - either a viewer or `NULL`
662d0c080abSJoseph Pusztay 
663bcf0153eSBarry Smith    Options Database Key:
664bcf0153eSBarry Smith .  -ts_monitor_draw_error - Monitor error graphically, requires user to have provided `TSSetSolutionFunction()`
6653a61192cSBarry Smith 
666d0c080abSJoseph Pusztay    Level: intermediate
667d0c080abSJoseph Pusztay 
668bcf0153eSBarry Smith    Notes:
669bcf0153eSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
670bcf0153eSBarry Smith    to be used during the `TS` integration.
671bcf0153eSBarry Smith 
672*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
673d0c080abSJoseph Pusztay @*/
674d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawError(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy)
675d71ae5a4SJacob Faibussowitsch {
676d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
677d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
678d0c080abSJoseph Pusztay   Vec              work;
679d0c080abSJoseph Pusztay 
680d0c080abSJoseph Pusztay   PetscFunctionBegin;
6813ba16761SJacob Faibussowitsch   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(PETSC_SUCCESS);
6829566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u, &work));
6839566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts, ptime, work));
6849566063dSJacob Faibussowitsch   PetscCall(VecAXPY(work, -1.0, u));
6859566063dSJacob Faibussowitsch   PetscCall(VecView(work, viewer));
6869566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work));
6873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
688d0c080abSJoseph Pusztay }
689d0c080abSJoseph Pusztay 
690d0c080abSJoseph Pusztay /*@C
691195e9b02SBarry Smith    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
692d0c080abSJoseph Pusztay 
693c3339decSBarry Smith    Collective
694d0c080abSJoseph Pusztay 
695d0c080abSJoseph Pusztay    Input Parameters:
696bcf0153eSBarry Smith +  ts - the `TS` context
697d0c080abSJoseph Pusztay .  step - current time-step
698d0c080abSJoseph Pusztay .  ptime - current time
699d0c080abSJoseph Pusztay .  u - current state
700d0c080abSJoseph Pusztay -  vf - viewer and its format
701d0c080abSJoseph Pusztay 
702d0c080abSJoseph Pusztay    Level: intermediate
703d0c080abSJoseph Pusztay 
704bcf0153eSBarry Smith    Notes:
705bcf0153eSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
706bcf0153eSBarry Smith    to be used during the `TS` integration.
707bcf0153eSBarry Smith 
708*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
709d0c080abSJoseph Pusztay @*/
710d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, PetscViewerAndFormat *vf)
711d71ae5a4SJacob Faibussowitsch {
712d0c080abSJoseph Pusztay   PetscFunctionBegin;
7133ba16761SJacob Faibussowitsch   if (vf->view_interval > 0 && !ts->reason && step % vf->view_interval != 0) PetscFunctionReturn(PETSC_SUCCESS);
7149566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(vf->viewer, vf->format));
7159566063dSJacob Faibussowitsch   PetscCall(VecView(u, vf->viewer));
7169566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(vf->viewer));
7173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
718d0c080abSJoseph Pusztay }
719d0c080abSJoseph Pusztay 
720d0c080abSJoseph Pusztay /*@C
721bcf0153eSBarry Smith    TSMonitorSolutionVTK - Monitors progress of the `TS` solvers by `VecView()` for the solution at each timestep.
722d0c080abSJoseph Pusztay 
723c3339decSBarry Smith    Collective
724d0c080abSJoseph Pusztay 
725d0c080abSJoseph Pusztay    Input Parameters:
726bcf0153eSBarry Smith +  ts - the `TS` context
727d0c080abSJoseph Pusztay .  step - current time-step
728d0c080abSJoseph Pusztay .  ptime - current time
729d0c080abSJoseph Pusztay .  u - current state
73063a3b9bcSJacob Faibussowitsch -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03" PetscInt_FMT ")
731d0c080abSJoseph Pusztay 
732d0c080abSJoseph Pusztay    Level: intermediate
733d0c080abSJoseph Pusztay 
734d0c080abSJoseph Pusztay    Notes:
735d0c080abSJoseph 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.
736d0c080abSJoseph Pusztay    These are named according to the file name template.
737d0c080abSJoseph Pusztay 
7383a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
739bcf0153eSBarry Smith    to be used during the `TS` integration.
740d0c080abSJoseph Pusztay 
741*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
742d0c080abSJoseph Pusztay @*/
743d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSolutionVTK(TS ts, PetscInt step, PetscReal ptime, Vec u, void *filenametemplate)
744d71ae5a4SJacob Faibussowitsch {
745d0c080abSJoseph Pusztay   char        filename[PETSC_MAX_PATH_LEN];
746d0c080abSJoseph Pusztay   PetscViewer viewer;
747d0c080abSJoseph Pusztay 
748d0c080abSJoseph Pusztay   PetscFunctionBegin;
7493ba16761SJacob Faibussowitsch   if (step < 0) PetscFunctionReturn(PETSC_SUCCESS); /* -1 indicates interpolated solution */
7509566063dSJacob Faibussowitsch   PetscCall(PetscSNPrintf(filename, sizeof(filename), (const char *)filenametemplate, step));
7519566063dSJacob Faibussowitsch   PetscCall(PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts), filename, FILE_MODE_WRITE, &viewer));
7529566063dSJacob Faibussowitsch   PetscCall(VecView(u, viewer));
7539566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&viewer));
7543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
755d0c080abSJoseph Pusztay }
756d0c080abSJoseph Pusztay 
757d0c080abSJoseph Pusztay /*@C
758bcf0153eSBarry Smith    TSMonitorSolutionVTKDestroy - Destroy filename template string created for use with `TSMonitorSolutionVTK()`
759d0c080abSJoseph Pusztay 
760bcf0153eSBarry Smith    Not Collective
761d0c080abSJoseph Pusztay 
7622fe279fdSBarry Smith    Input Parameter:
76363a3b9bcSJacob Faibussowitsch .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03" PetscInt_FMT ")
764d0c080abSJoseph Pusztay 
765d0c080abSJoseph Pusztay    Level: intermediate
766d0c080abSJoseph Pusztay 
767d0c080abSJoseph Pusztay    Note:
768bcf0153eSBarry Smith    This function is normally passed to `TSMonitorSet()` along with `TSMonitorSolutionVTK()`.
769d0c080abSJoseph Pusztay 
770*1cc06b55SBarry Smith .seealso: [](ch_ts), `TSMonitorSet()`, `TSMonitorSolutionVTK()`
771d0c080abSJoseph Pusztay @*/
772d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
773d71ae5a4SJacob Faibussowitsch {
774d0c080abSJoseph Pusztay   PetscFunctionBegin;
7759566063dSJacob Faibussowitsch   PetscCall(PetscFree(*(char **)filenametemplate));
7763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
777d0c080abSJoseph Pusztay }
778d0c080abSJoseph Pusztay 
779d0c080abSJoseph Pusztay /*@C
780bcf0153eSBarry Smith    TSMonitorLGSolution - Monitors progress of the `TS` solvers by plotting each component of the solution vector
781d0c080abSJoseph Pusztay        in a time based line graph
782d0c080abSJoseph Pusztay 
783c3339decSBarry Smith    Collective
784d0c080abSJoseph Pusztay 
785d0c080abSJoseph Pusztay    Input Parameters:
786bcf0153eSBarry Smith +  ts - the `TS` context
787d0c080abSJoseph Pusztay .  step - current time-step
788d0c080abSJoseph Pusztay .  ptime - current time
789d0c080abSJoseph Pusztay .  u - current solution
790bcf0153eSBarry Smith -  dctx - the `TSMonitorLGCtx` object that contains all the options for the monitoring, this is created with `TSMonitorLGCtxCreate()`
791d0c080abSJoseph Pusztay 
792bcf0153eSBarry Smith    Options Database Key:
79367b8a455SSatish Balay .   -ts_monitor_lg_solution_variables - enable monitor of lg solution variables
794d0c080abSJoseph Pusztay 
795d0c080abSJoseph Pusztay    Level: intermediate
796d0c080abSJoseph Pusztay 
797d0c080abSJoseph Pusztay    Notes:
798d0c080abSJoseph Pusztay    Each process in a parallel run displays its component solutions in a separate window
799d0c080abSJoseph Pusztay 
8003a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
801bcf0153eSBarry Smith    to be used during the `TS` integration.
8023a61192cSBarry Smith 
803*1cc06b55SBarry Smith .seealso: [](ch_ts), `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGCtxCreate()`, `TSMonitorLGCtxSetVariableNames()`, `TSMonitorLGCtxGetVariableNames()`,
804db781477SPatrick Sanan           `TSMonitorLGSetVariableNames()`, `TSMonitorLGGetVariableNames()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetDisplayVariables()`,
805db781477SPatrick Sanan           `TSMonitorLGCtxSetTransform()`, `TSMonitorLGSetTransform()`, `TSMonitorLGError()`, `TSMonitorLGSNESIterations()`, `TSMonitorLGKSPIterations()`,
806db781477SPatrick Sanan           `TSMonitorEnvelopeCtxCreate()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxDestroy()`, `TSMonitorEnvelop()`
807d0c080abSJoseph Pusztay @*/
808d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx)
809d71ae5a4SJacob Faibussowitsch {
810d0c080abSJoseph Pusztay   TSMonitorLGCtx     ctx = (TSMonitorLGCtx)dctx;
811d0c080abSJoseph Pusztay   const PetscScalar *yy;
812d0c080abSJoseph Pusztay   Vec                v;
813d0c080abSJoseph Pusztay 
814d0c080abSJoseph Pusztay   PetscFunctionBegin;
8153ba16761SJacob Faibussowitsch   if (step < 0) PetscFunctionReturn(PETSC_SUCCESS); /* -1 indicates interpolated solution */
816d0c080abSJoseph Pusztay   if (!step) {
817d0c080abSJoseph Pusztay     PetscDrawAxis axis;
818d0c080abSJoseph Pusztay     PetscInt      dim;
8199566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
8209566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Solution as function of time", "Time", "Solution"));
821d0c080abSJoseph Pusztay     if (!ctx->names) {
822d0c080abSJoseph Pusztay       PetscBool flg;
823d0c080abSJoseph Pusztay       /* user provides names of variables to plot but no names has been set so assume names are integer values */
8249566063dSJacob Faibussowitsch       PetscCall(PetscOptionsHasName(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_monitor_lg_solution_variables", &flg));
825d0c080abSJoseph Pusztay       if (flg) {
826d0c080abSJoseph Pusztay         PetscInt i, n;
827d0c080abSJoseph Pusztay         char   **names;
8289566063dSJacob Faibussowitsch         PetscCall(VecGetSize(u, &n));
8299566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(n + 1, &names));
830d0c080abSJoseph Pusztay         for (i = 0; i < n; i++) {
8319566063dSJacob Faibussowitsch           PetscCall(PetscMalloc1(5, &names[i]));
83263a3b9bcSJacob Faibussowitsch           PetscCall(PetscSNPrintf(names[i], 5, "%" PetscInt_FMT, i));
833d0c080abSJoseph Pusztay         }
834d0c080abSJoseph Pusztay         names[n]   = NULL;
835d0c080abSJoseph Pusztay         ctx->names = names;
836d0c080abSJoseph Pusztay       }
837d0c080abSJoseph Pusztay     }
838d0c080abSJoseph Pusztay     if (ctx->names && !ctx->displaynames) {
839d0c080abSJoseph Pusztay       char    **displaynames;
840d0c080abSJoseph Pusztay       PetscBool flg;
8419566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u, &dim));
8429566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(dim + 1, &displaynames));
8439566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetStringArray(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_monitor_lg_solution_variables", displaynames, &dim, &flg));
8441baa6e33SBarry Smith       if (flg) PetscCall(TSMonitorLGCtxSetDisplayVariables(ctx, (const char *const *)displaynames));
8459566063dSJacob Faibussowitsch       PetscCall(PetscStrArrayDestroy(&displaynames));
846d0c080abSJoseph Pusztay     }
847d0c080abSJoseph Pusztay     if (ctx->displaynames) {
8489566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg, ctx->ndisplayvariables));
8499566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetLegend(ctx->lg, (const char *const *)ctx->displaynames));
850d0c080abSJoseph Pusztay     } else if (ctx->names) {
8519566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u, &dim));
8529566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg, dim));
8539566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetLegend(ctx->lg, (const char *const *)ctx->names));
854d0c080abSJoseph Pusztay     } else {
8559566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u, &dim));
8569566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg, dim));
857d0c080abSJoseph Pusztay     }
8589566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
859d0c080abSJoseph Pusztay   }
860d0c080abSJoseph Pusztay 
861d0c080abSJoseph Pusztay   if (!ctx->transform) v = u;
8629566063dSJacob Faibussowitsch   else PetscCall((*ctx->transform)(ctx->transformctx, u, &v));
8639566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(v, &yy));
864d0c080abSJoseph Pusztay   if (ctx->displaynames) {
865d0c080abSJoseph Pusztay     PetscInt i;
8669371c9d4SSatish Balay     for (i = 0; i < ctx->ndisplayvariables; i++) ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]);
8679566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, ctx->displayvalues));
868d0c080abSJoseph Pusztay   } else {
869d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
870d0c080abSJoseph Pusztay     PetscInt   i, n;
871d0c080abSJoseph Pusztay     PetscReal *yreal;
8729566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(v, &n));
8739566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &yreal));
874d0c080abSJoseph Pusztay     for (i = 0; i < n; i++) yreal[i] = PetscRealPart(yy[i]);
8759566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yreal));
8769566063dSJacob Faibussowitsch     PetscCall(PetscFree(yreal));
877d0c080abSJoseph Pusztay #else
8789566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yy));
879d0c080abSJoseph Pusztay #endif
880d0c080abSJoseph Pusztay   }
8819566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(v, &yy));
8829566063dSJacob Faibussowitsch   if (ctx->transform) PetscCall(VecDestroy(&v));
883d0c080abSJoseph Pusztay 
884d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
8859566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
8869566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
887d0c080abSJoseph Pusztay   }
8883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
889d0c080abSJoseph Pusztay }
890d0c080abSJoseph Pusztay 
891d0c080abSJoseph Pusztay /*@C
892d0c080abSJoseph Pusztay    TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
893d0c080abSJoseph Pusztay 
894c3339decSBarry Smith    Collective
895d0c080abSJoseph Pusztay 
896d0c080abSJoseph Pusztay    Input Parameters:
897bcf0153eSBarry Smith +  ts - the `TS` context
898195e9b02SBarry Smith -  names - the names of the components, final string must be `NULL`
899d0c080abSJoseph Pusztay 
900d0c080abSJoseph Pusztay    Level: intermediate
901d0c080abSJoseph Pusztay 
902d0c080abSJoseph Pusztay    Notes:
903bcf0153eSBarry Smith     If the `TS` object does not have a `TSMonitorLGCtx` associated with it then this function is ignored
904d0c080abSJoseph Pusztay 
905*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetVariableNames()`
906d0c080abSJoseph Pusztay @*/
907d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSetVariableNames(TS ts, const char *const *names)
908d71ae5a4SJacob Faibussowitsch {
909d0c080abSJoseph Pusztay   PetscInt i;
910d0c080abSJoseph Pusztay 
911d0c080abSJoseph Pusztay   PetscFunctionBegin;
912d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
913d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
9149566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i], names));
915d0c080abSJoseph Pusztay       break;
916d0c080abSJoseph Pusztay     }
917d0c080abSJoseph Pusztay   }
9183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
919d0c080abSJoseph Pusztay }
920d0c080abSJoseph Pusztay 
921d0c080abSJoseph Pusztay /*@C
922d0c080abSJoseph Pusztay    TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
923d0c080abSJoseph Pusztay 
924c3339decSBarry Smith    Collective
925d0c080abSJoseph Pusztay 
926d0c080abSJoseph Pusztay    Input Parameters:
927bcf0153eSBarry Smith +  ts - the `TS` context
928195e9b02SBarry Smith -  names - the names of the components, final string must be `NULL`
929d0c080abSJoseph Pusztay 
930d0c080abSJoseph Pusztay    Level: intermediate
931d0c080abSJoseph Pusztay 
932*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGSetVariableNames()`
933d0c080abSJoseph Pusztay @*/
934d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx, const char *const *names)
935d71ae5a4SJacob Faibussowitsch {
936d0c080abSJoseph Pusztay   PetscFunctionBegin;
9379566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&ctx->names));
9389566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(names, &ctx->names));
9393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
940d0c080abSJoseph Pusztay }
941d0c080abSJoseph Pusztay 
942d0c080abSJoseph Pusztay /*@C
943d0c080abSJoseph Pusztay    TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot
944d0c080abSJoseph Pusztay 
945c3339decSBarry Smith    Collective
946d0c080abSJoseph Pusztay 
947d0c080abSJoseph Pusztay    Input Parameter:
948bcf0153eSBarry Smith .  ts - the `TS` context
949d0c080abSJoseph Pusztay 
950d0c080abSJoseph Pusztay    Output Parameter:
951195e9b02SBarry Smith .  names - the names of the components, final string must be `NULL`
952d0c080abSJoseph Pusztay 
953d0c080abSJoseph Pusztay    Level: intermediate
954d0c080abSJoseph Pusztay 
955bcf0153eSBarry Smith    Note:
956bcf0153eSBarry Smith     If the `TS` object does not have a `TSMonitorLGCtx` associated with it then this function is ignored
957d0c080abSJoseph Pusztay 
958*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`
959d0c080abSJoseph Pusztay @*/
960d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGGetVariableNames(TS ts, const char *const **names)
961d71ae5a4SJacob Faibussowitsch {
962d0c080abSJoseph Pusztay   PetscInt i;
963d0c080abSJoseph Pusztay 
964d0c080abSJoseph Pusztay   PetscFunctionBegin;
965d0c080abSJoseph Pusztay   *names = NULL;
966d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
967d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
968d0c080abSJoseph Pusztay       TSMonitorLGCtx ctx = (TSMonitorLGCtx)ts->monitorcontext[i];
969d0c080abSJoseph Pusztay       *names             = (const char *const *)ctx->names;
970d0c080abSJoseph Pusztay       break;
971d0c080abSJoseph Pusztay     }
972d0c080abSJoseph Pusztay   }
9733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
974d0c080abSJoseph Pusztay }
975d0c080abSJoseph Pusztay 
976d0c080abSJoseph Pusztay /*@C
977d0c080abSJoseph Pusztay    TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor
978d0c080abSJoseph Pusztay 
979c3339decSBarry Smith    Collective
980d0c080abSJoseph Pusztay 
981d0c080abSJoseph Pusztay    Input Parameters:
982bcf0153eSBarry Smith +  ctx - the `TSMonitorLG` context
983195e9b02SBarry Smith -  displaynames - the names of the components, final string must be `NULL`
984d0c080abSJoseph Pusztay 
985d0c080abSJoseph Pusztay    Level: intermediate
986d0c080abSJoseph Pusztay 
987*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`
988d0c080abSJoseph Pusztay @*/
989d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx, const char *const *displaynames)
990d71ae5a4SJacob Faibussowitsch {
991d0c080abSJoseph Pusztay   PetscInt j = 0, k;
992d0c080abSJoseph Pusztay 
993d0c080abSJoseph Pusztay   PetscFunctionBegin;
9943ba16761SJacob Faibussowitsch   if (!ctx->names) PetscFunctionReturn(PETSC_SUCCESS);
9959566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&ctx->displaynames));
9969566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(displaynames, &ctx->displaynames));
997d0c080abSJoseph Pusztay   while (displaynames[j]) j++;
998d0c080abSJoseph Pusztay   ctx->ndisplayvariables = j;
9999566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx->ndisplayvariables, &ctx->displayvariables));
10009566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx->ndisplayvariables, &ctx->displayvalues));
1001d0c080abSJoseph Pusztay   j = 0;
1002d0c080abSJoseph Pusztay   while (displaynames[j]) {
1003d0c080abSJoseph Pusztay     k = 0;
1004d0c080abSJoseph Pusztay     while (ctx->names[k]) {
1005d0c080abSJoseph Pusztay       PetscBool flg;
10069566063dSJacob Faibussowitsch       PetscCall(PetscStrcmp(displaynames[j], ctx->names[k], &flg));
1007d0c080abSJoseph Pusztay       if (flg) {
1008d0c080abSJoseph Pusztay         ctx->displayvariables[j] = k;
1009d0c080abSJoseph Pusztay         break;
1010d0c080abSJoseph Pusztay       }
1011d0c080abSJoseph Pusztay       k++;
1012d0c080abSJoseph Pusztay     }
1013d0c080abSJoseph Pusztay     j++;
1014d0c080abSJoseph Pusztay   }
10153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1016d0c080abSJoseph Pusztay }
1017d0c080abSJoseph Pusztay 
1018d0c080abSJoseph Pusztay /*@C
1019d0c080abSJoseph Pusztay    TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor
1020d0c080abSJoseph Pusztay 
1021c3339decSBarry Smith    Collective
1022d0c080abSJoseph Pusztay 
1023d0c080abSJoseph Pusztay    Input Parameters:
1024bcf0153eSBarry Smith +  ts - the `TS` context
1025195e9b02SBarry Smith -  displaynames - the names of the components, final string must be `NULL`
1026d0c080abSJoseph Pusztay 
1027d0c080abSJoseph Pusztay    Level: intermediate
1028d0c080abSJoseph Pusztay 
1029bcf0153eSBarry Smith    Note:
1030bcf0153eSBarry Smith     If the `TS` object does not have a `TSMonitorLGCtx` associated with it then this function is ignored
1031bcf0153eSBarry Smith 
1032*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`
1033d0c080abSJoseph Pusztay @*/
1034d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSetDisplayVariables(TS ts, const char *const *displaynames)
1035d71ae5a4SJacob Faibussowitsch {
1036d0c080abSJoseph Pusztay   PetscInt i;
1037d0c080abSJoseph Pusztay 
1038d0c080abSJoseph Pusztay   PetscFunctionBegin;
1039d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
1040d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
10419566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i], displaynames));
1042d0c080abSJoseph Pusztay       break;
1043d0c080abSJoseph Pusztay     }
1044d0c080abSJoseph Pusztay   }
10453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1046d0c080abSJoseph Pusztay }
1047d0c080abSJoseph Pusztay 
1048d0c080abSJoseph Pusztay /*@C
1049d0c080abSJoseph Pusztay    TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed
1050d0c080abSJoseph Pusztay 
1051c3339decSBarry Smith    Collective
1052d0c080abSJoseph Pusztay 
1053d0c080abSJoseph Pusztay    Input Parameters:
1054bcf0153eSBarry Smith +  ts - the `TS` context
1055d0c080abSJoseph Pusztay .  transform - the transform function
1056d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
1057d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
1058d0c080abSJoseph Pusztay 
1059d0c080abSJoseph Pusztay    Level: intermediate
1060d0c080abSJoseph Pusztay 
1061bcf0153eSBarry Smith    Note:
1062bcf0153eSBarry Smith     If the `TS` object does not have a `TSMonitorLGCtx` associated with it then this function is ignored
1063bcf0153eSBarry Smith 
1064*1cc06b55SBarry Smith .seealso: [](ch_ts), `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`, `TSMonitorLGCtxSetTransform()`
1065d0c080abSJoseph Pusztay @*/
1066d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSetTransform(TS ts, PetscErrorCode (*transform)(void *, Vec, Vec *), PetscErrorCode (*destroy)(void *), void *tctx)
1067d71ae5a4SJacob Faibussowitsch {
1068d0c080abSJoseph Pusztay   PetscInt i;
1069d0c080abSJoseph Pusztay 
1070d0c080abSJoseph Pusztay   PetscFunctionBegin;
1071d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
107248a46eb9SPierre Jolivet     if (ts->monitor[i] == TSMonitorLGSolution) PetscCall(TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i], transform, destroy, tctx));
1073d0c080abSJoseph Pusztay   }
10743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1075d0c080abSJoseph Pusztay }
1076d0c080abSJoseph Pusztay 
1077d0c080abSJoseph Pusztay /*@C
1078d0c080abSJoseph Pusztay    TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed
1079d0c080abSJoseph Pusztay 
1080c3339decSBarry Smith    Collective
1081d0c080abSJoseph Pusztay 
1082d0c080abSJoseph Pusztay    Input Parameters:
1083bcf0153eSBarry Smith +  ts - the `TS` context
1084d0c080abSJoseph Pusztay .  transform - the transform function
1085d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
1086d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
1087d0c080abSJoseph Pusztay 
1088d0c080abSJoseph Pusztay    Level: intermediate
1089d0c080abSJoseph Pusztay 
1090*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`, `TSMonitorLGSetTransform()`
1091d0c080abSJoseph Pusztay @*/
1092d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx, PetscErrorCode (*transform)(void *, Vec, Vec *), PetscErrorCode (*destroy)(void *), void *tctx)
1093d71ae5a4SJacob Faibussowitsch {
1094d0c080abSJoseph Pusztay   PetscFunctionBegin;
1095d0c080abSJoseph Pusztay   ctx->transform        = transform;
1096d0c080abSJoseph Pusztay   ctx->transformdestroy = destroy;
1097d0c080abSJoseph Pusztay   ctx->transformctx     = tctx;
10983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1099d0c080abSJoseph Pusztay }
1100d0c080abSJoseph Pusztay 
1101d0c080abSJoseph Pusztay /*@C
1102bcf0153eSBarry Smith    TSMonitorLGError - Monitors progress of the `TS` solvers by plotting each component of the error
1103d0c080abSJoseph Pusztay        in a time based line graph
1104d0c080abSJoseph Pusztay 
1105c3339decSBarry Smith    Collective
1106d0c080abSJoseph Pusztay 
1107d0c080abSJoseph Pusztay    Input Parameters:
1108bcf0153eSBarry Smith +  ts - the `TS` context
1109d0c080abSJoseph Pusztay .  step - current time-step
1110d0c080abSJoseph Pusztay .  ptime - current time
1111d0c080abSJoseph Pusztay .  u - current solution
1112bcf0153eSBarry Smith -  dctx - `TSMonitorLGCtx` object created with `TSMonitorLGCtxCreate()`
1113d0c080abSJoseph Pusztay 
1114bcf0153eSBarry Smith    Options Database Key:
11153a61192cSBarry Smith .  -ts_monitor_lg_error - create a graphical monitor of error history
11163a61192cSBarry Smith 
1117d0c080abSJoseph Pusztay    Level: intermediate
1118d0c080abSJoseph Pusztay 
1119d0c080abSJoseph Pusztay    Notes:
1120d0c080abSJoseph Pusztay     Each process in a parallel run displays its component errors in a separate window
1121d0c080abSJoseph Pusztay 
1122bcf0153eSBarry Smith    The user must provide the solution using `TSSetSolutionFunction()` to use this monitor.
1123d0c080abSJoseph Pusztay 
11243a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
11253a61192cSBarry Smith    to be used during the TS integration.
1126d0c080abSJoseph Pusztay 
1127*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
1128d0c080abSJoseph Pusztay @*/
1129d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGError(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy)
1130d71ae5a4SJacob Faibussowitsch {
1131d0c080abSJoseph Pusztay   TSMonitorLGCtx     ctx = (TSMonitorLGCtx)dummy;
1132d0c080abSJoseph Pusztay   const PetscScalar *yy;
1133d0c080abSJoseph Pusztay   Vec                y;
1134d0c080abSJoseph Pusztay 
1135d0c080abSJoseph Pusztay   PetscFunctionBegin;
1136d0c080abSJoseph Pusztay   if (!step) {
1137d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1138d0c080abSJoseph Pusztay     PetscInt      dim;
11399566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
11409566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Error in solution as function of time", "Time", "Error"));
11419566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(u, &dim));
11429566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSetDimension(ctx->lg, dim));
11439566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1144d0c080abSJoseph Pusztay   }
11459566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u, &y));
11469566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts, ptime, y));
11479566063dSJacob Faibussowitsch   PetscCall(VecAXPY(y, -1.0, u));
11489566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(y, &yy));
1149d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
1150d0c080abSJoseph Pusztay   {
1151d0c080abSJoseph Pusztay     PetscReal *yreal;
1152d0c080abSJoseph Pusztay     PetscInt   i, n;
11539566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(y, &n));
11549566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &yreal));
1155d0c080abSJoseph Pusztay     for (i = 0; i < n; i++) yreal[i] = PetscRealPart(yy[i]);
11569566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yreal));
11579566063dSJacob Faibussowitsch     PetscCall(PetscFree(yreal));
1158d0c080abSJoseph Pusztay   }
1159d0c080abSJoseph Pusztay #else
11609566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yy));
1161d0c080abSJoseph Pusztay #endif
11629566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(y, &yy));
11639566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&y));
1164d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
11659566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
11669566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1167d0c080abSJoseph Pusztay   }
11683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1169d0c080abSJoseph Pusztay }
1170d0c080abSJoseph Pusztay 
1171d0c080abSJoseph Pusztay /*@C
1172bcf0153eSBarry Smith    TSMonitorSPSwarmSolution - Graphically displays phase plots of `DMSWARM` particles on a scatter plot
1173d0c080abSJoseph Pusztay 
1174d0c080abSJoseph Pusztay    Input Parameters:
1175bcf0153eSBarry Smith +  ts - the `TS` context
1176d0c080abSJoseph Pusztay .  step - current time-step
1177d0c080abSJoseph Pusztay .  ptime - current time
1178d0c080abSJoseph Pusztay .  u - current solution
1179bcf0153eSBarry Smith -  dctx - the `TSMonitorSPCtx` object that contains all the options for the monitoring, this is created with `TSMonitorSPCtxCreate()`
1180d0c080abSJoseph Pusztay 
1181bcf0153eSBarry Smith    Options Database Keys:
1182d7462660SMatthew Knepley + -ts_monitor_sp_swarm <n>                  - Monitor the solution every n steps, or -1 for plotting only the final solution
1183d7462660SMatthew Knepley . -ts_monitor_sp_swarm_retain <n>           - Retain n old points so we can see the history, or -1 for all points
118420f4b53cSBarry Smith . -ts_monitor_sp_swarm_multi_species <bool> - Color each species differently
1185d7462660SMatthew Knepley - -ts_monitor_sp_swarm_phase <bool>         - Plot in phase space, as opposed to coordinate space
1186d0c080abSJoseph Pusztay 
1187d0c080abSJoseph Pusztay    Level: intermediate
1188d0c080abSJoseph Pusztay 
11893a61192cSBarry Smith    Notes:
11903a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
1191bcf0153eSBarry Smith    to be used during the `TS` integration.
11923a61192cSBarry Smith 
1193*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitoSet()`, `DMSWARM`, `TSMonitorSPCtxCreate()`
1194d0c080abSJoseph Pusztay @*/
1195d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSPSwarmSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx)
1196d71ae5a4SJacob Faibussowitsch {
1197d0c080abSJoseph Pusztay   TSMonitorSPCtx     ctx = (TSMonitorSPCtx)dctx;
1198f98b2f00SMatthew G. Knepley   PetscDraw          draw;
1199d7462660SMatthew Knepley   DM                 dm, cdm;
1200d0c080abSJoseph Pusztay   const PetscScalar *yy;
120160e16b1bSMatthew G. Knepley   PetscInt           Np, p, dim = 2, *species;
120260e16b1bSMatthew G. Knepley   PetscReal          species_color;
1203d0c080abSJoseph Pusztay 
1204d0c080abSJoseph Pusztay   PetscFunctionBegin;
12053ba16761SJacob Faibussowitsch   if (step < 0) PetscFunctionReturn(PETSC_SUCCESS); /* -1 indicates interpolated solution */
120660e16b1bSMatthew G. Knepley   PetscCall(TSGetDM(ts, &dm));
1207d0c080abSJoseph Pusztay   if (!step) {
1208d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1209ab43fcacSJoe Pusztay     PetscReal     dmboxlower[2], dmboxupper[2];
1210f98b2f00SMatthew G. Knepley 
12119566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &dm));
12129566063dSJacob Faibussowitsch     PetscCall(DMGetDimension(dm, &dim));
12133c633725SBarry Smith     PetscCheck(dim == 2, PETSC_COMM_SELF, PETSC_ERR_SUP, "Monitor only supports two dimensional fields");
12149566063dSJacob Faibussowitsch     PetscCall(DMSwarmGetCellDM(dm, &cdm));
12159566063dSJacob Faibussowitsch     PetscCall(DMGetBoundingBox(cdm, dmboxlower, dmboxupper));
12169566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(u, &Np));
1217d7462660SMatthew Knepley     Np /= dim * 2;
12189566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPGetAxis(ctx->sp, &axis));
12198c87cf4dSdanfinn     if (ctx->phase) {
12209566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(axis, "Particles", "X", "V"));
122160e16b1bSMatthew G. Knepley       PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], -10, 10));
12228c87cf4dSdanfinn     } else {
12239566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(axis, "Particles", "X", "Y"));
12249566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], dmboxlower[1], dmboxupper[1]));
12258c87cf4dSdanfinn     }
12269566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetHoldLimits(axis, PETSC_TRUE));
12279566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPReset(ctx->sp));
1228d0c080abSJoseph Pusztay   }
122960e16b1bSMatthew G. Knepley   if (ctx->multispecies) PetscCall(DMSwarmGetField(dm, "species", NULL, NULL, (void **)&species));
12309566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(u, &Np));
1231d7462660SMatthew Knepley   Np /= dim * 2;
1232d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
12339566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPGetDraw(ctx->sp, &draw));
123448a46eb9SPierre Jolivet     if ((ctx->retain == 0) || (ctx->retain > 0 && !(step % ctx->retain))) PetscCall(PetscDrawClear(draw));
12359566063dSJacob Faibussowitsch     PetscCall(PetscDrawFlush(draw));
12369566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPReset(ctx->sp));
1237f98b2f00SMatthew G. Knepley     PetscCall(VecGetArrayRead(u, &yy));
1238f98b2f00SMatthew G. Knepley     for (p = 0; p < Np; ++p) {
1239f98b2f00SMatthew G. Knepley       PetscReal x, y;
1240f98b2f00SMatthew G. Knepley 
1241f98b2f00SMatthew G. Knepley       if (ctx->phase) {
1242f98b2f00SMatthew G. Knepley         x = PetscRealPart(yy[p * dim * 2]);
1243f98b2f00SMatthew G. Knepley         y = PetscRealPart(yy[p * dim * 2 + dim]);
1244f98b2f00SMatthew G. Knepley       } else {
1245f98b2f00SMatthew G. Knepley         x = PetscRealPart(yy[p * dim * 2]);
1246f98b2f00SMatthew G. Knepley         y = PetscRealPart(yy[p * dim * 2 + 1]);
1247f98b2f00SMatthew G. Knepley       }
124860e16b1bSMatthew G. Knepley       if (ctx->multispecies) {
124960e16b1bSMatthew G. Knepley         species_color = species[p] + 2;
125060e16b1bSMatthew G. Knepley         PetscCall(PetscDrawSPAddPointColorized(ctx->sp, &x, &y, &species_color));
125160e16b1bSMatthew G. Knepley       } else {
125260e16b1bSMatthew G. Knepley         PetscCall(PetscDrawSPAddPoint(ctx->sp, &x, &y));
125360e16b1bSMatthew G. Knepley       }
1254f98b2f00SMatthew G. Knepley       PetscCall(PetscDrawSPAddPoint(ctx->sp, &x, &y));
1255f98b2f00SMatthew G. Knepley     }
1256f98b2f00SMatthew G. Knepley     PetscCall(VecRestoreArrayRead(u, &yy));
12579566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPDraw(ctx->sp, PETSC_FALSE));
12589566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPSave(ctx->sp));
125960e16b1bSMatthew G. Knepley     if (ctx->multispecies) PetscCall(DMSwarmRestoreField(dm, "species", NULL, NULL, (void **)&species));
126060e16b1bSMatthew G. Knepley   }
126160e16b1bSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
126260e16b1bSMatthew G. Knepley }
126360e16b1bSMatthew G. Knepley 
126460e16b1bSMatthew G. Knepley /*@C
126520f4b53cSBarry Smith    TSMonitorHGSwarmSolution - Graphically displays histograms of `DMSWARM` particles
126660e16b1bSMatthew G. Knepley 
126760e16b1bSMatthew G. Knepley    Input Parameters:
126820f4b53cSBarry Smith +  ts - the `TS` context
126960e16b1bSMatthew G. Knepley .  step - current time-step
127060e16b1bSMatthew G. Knepley .  ptime - current time
127160e16b1bSMatthew G. Knepley .  u - current solution
127220f4b53cSBarry Smith -  dctx - the `TSMonitorSPCtx` object that contains all the options for the monitoring, this is created with `TSMonitorHGCtxCreate()`
127360e16b1bSMatthew G. Knepley 
127420f4b53cSBarry Smith    Options Database Keys:
127560e16b1bSMatthew G. Knepley + -ts_monitor_hg_swarm <n>             - Monitor the solution every n steps, or -1 for plotting only the final solution
127660e16b1bSMatthew G. Knepley . -ts_monitor_hg_swarm_species <num>   - Number of species to histogram
127760e16b1bSMatthew G. Knepley . -ts_monitor_hg_swarm_bins <num>      - Number of histogram bins
127860e16b1bSMatthew G. Knepley - -ts_monitor_hg_swarm_velocity <bool> - Plot in velocity space, as opposed to coordinate space
127960e16b1bSMatthew G. Knepley 
128060e16b1bSMatthew G. Knepley    Level: intermediate
128160e16b1bSMatthew G. Knepley 
128220f4b53cSBarry Smith    Note:
128360e16b1bSMatthew G. Knepley    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
128460e16b1bSMatthew G. Knepley    to be used during the `TS` integration.
128560e16b1bSMatthew G. Knepley 
128660e16b1bSMatthew G. Knepley .seealso: `TSMonitoSet()`
128760e16b1bSMatthew G. Knepley @*/
128860e16b1bSMatthew G. Knepley PetscErrorCode TSMonitorHGSwarmSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx)
128960e16b1bSMatthew G. Knepley {
129060e16b1bSMatthew G. Knepley   TSMonitorHGCtx     ctx = (TSMonitorHGCtx)dctx;
129160e16b1bSMatthew G. Knepley   PetscDraw          draw;
129260e16b1bSMatthew G. Knepley   DM                 sw;
129360e16b1bSMatthew G. Knepley   const PetscScalar *yy;
129460e16b1bSMatthew G. Knepley   PetscInt          *species;
129560e16b1bSMatthew G. Knepley   PetscInt           dim, d = 0, Np, p, Ns, s;
129660e16b1bSMatthew G. Knepley 
129760e16b1bSMatthew G. Knepley   PetscFunctionBegin;
129860e16b1bSMatthew G. Knepley   if (step < 0) PetscFunctionReturn(PETSC_SUCCESS); /* -1 indicates interpolated solution */
129960e16b1bSMatthew G. Knepley   PetscCall(TSGetDM(ts, &sw));
130060e16b1bSMatthew G. Knepley   PetscCall(DMGetDimension(sw, &dim));
130160e16b1bSMatthew G. Knepley   PetscCall(DMSwarmGetNumSpecies(sw, &Ns));
130260e16b1bSMatthew G. Knepley   Ns = PetscMin(Ns, ctx->Ns);
130360e16b1bSMatthew G. Knepley   PetscCall(VecGetLocalSize(u, &Np));
130460e16b1bSMatthew G. Knepley   Np /= dim * 2;
130560e16b1bSMatthew G. Knepley   if (!step) {
130660e16b1bSMatthew G. Knepley     PetscDrawAxis axis;
130760e16b1bSMatthew G. Knepley     char          title[PETSC_MAX_PATH_LEN];
130860e16b1bSMatthew G. Knepley 
130960e16b1bSMatthew G. Knepley     for (s = 0; s < Ns; ++s) {
131060e16b1bSMatthew G. Knepley       PetscCall(PetscDrawHGGetAxis(ctx->hg[s], &axis));
131160e16b1bSMatthew G. Knepley       PetscCall(PetscSNPrintf(title, PETSC_MAX_PATH_LEN, "Species %" PetscInt_FMT, s));
131260e16b1bSMatthew G. Knepley       if (ctx->velocity) PetscCall(PetscDrawAxisSetLabels(axis, title, "V", "N"));
131360e16b1bSMatthew G. Knepley       else PetscCall(PetscDrawAxisSetLabels(axis, title, "X", "N"));
131460e16b1bSMatthew G. Knepley     }
131560e16b1bSMatthew G. Knepley   }
131660e16b1bSMatthew G. Knepley   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
131760e16b1bSMatthew G. Knepley     PetscCall(DMSwarmGetField(sw, "species", NULL, NULL, (void **)&species));
131860e16b1bSMatthew G. Knepley     for (s = 0; s < Ns; ++s) {
131960e16b1bSMatthew G. Knepley       PetscCall(PetscDrawHGReset(ctx->hg[s]));
132060e16b1bSMatthew G. Knepley       PetscCall(PetscDrawHGGetDraw(ctx->hg[s], &draw));
132160e16b1bSMatthew G. Knepley       PetscCall(PetscDrawClear(draw));
132260e16b1bSMatthew G. Knepley       PetscCall(PetscDrawFlush(draw));
132360e16b1bSMatthew G. Knepley     }
132460e16b1bSMatthew G. Knepley     PetscCall(VecGetArrayRead(u, &yy));
132560e16b1bSMatthew G. Knepley     for (p = 0; p < Np; ++p) {
132660e16b1bSMatthew G. Knepley       const PetscInt s = species[p] < Ns ? species[p] : 0;
132760e16b1bSMatthew G. Knepley       PetscReal      v;
132860e16b1bSMatthew G. Knepley 
132960e16b1bSMatthew G. Knepley       if (ctx->velocity) v = PetscRealPart(yy[p * dim * 2 + d + dim]);
133060e16b1bSMatthew G. Knepley       else v = PetscRealPart(yy[p * dim * 2 + d]);
133160e16b1bSMatthew G. Knepley       PetscCall(PetscDrawHGAddValue(ctx->hg[s], v));
133260e16b1bSMatthew G. Knepley     }
133360e16b1bSMatthew G. Knepley     PetscCall(VecRestoreArrayRead(u, &yy));
133460e16b1bSMatthew G. Knepley     for (s = 0; s < Ns; ++s) {
133560e16b1bSMatthew G. Knepley       PetscCall(PetscDrawHGDraw(ctx->hg[s]));
133660e16b1bSMatthew G. Knepley       PetscCall(PetscDrawHGSave(ctx->hg[s]));
133760e16b1bSMatthew G. Knepley     }
133860e16b1bSMatthew G. Knepley     PetscCall(DMSwarmRestoreField(sw, "species", NULL, NULL, (void **)&species));
1339d0c080abSJoseph Pusztay   }
13403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1341d0c080abSJoseph Pusztay }
1342d0c080abSJoseph Pusztay 
1343d0c080abSJoseph Pusztay /*@C
1344bcf0153eSBarry Smith    TSMonitorError - Monitors progress of the `TS` solvers by printing the 2 norm of the error at each timestep
1345d0c080abSJoseph Pusztay 
1346c3339decSBarry Smith    Collective
1347d0c080abSJoseph Pusztay 
1348d0c080abSJoseph Pusztay    Input Parameters:
1349bcf0153eSBarry Smith +  ts - the `TS` context
1350d0c080abSJoseph Pusztay .  step - current time-step
1351d0c080abSJoseph Pusztay .  ptime - current time
1352d0c080abSJoseph Pusztay .  u - current solution
1353d0c080abSJoseph Pusztay -  dctx - unused context
1354d0c080abSJoseph Pusztay 
1355bcf0153eSBarry Smith    Options Database Key:
1356bcf0153eSBarry Smith .  -ts_monitor_error - create a graphical monitor of error history
1357bcf0153eSBarry Smith 
1358d0c080abSJoseph Pusztay    Level: intermediate
1359d0c080abSJoseph Pusztay 
13603a61192cSBarry Smith    Notes:
13613a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
1362bcf0153eSBarry Smith    to be used during the `TS` integration.
13633a61192cSBarry Smith 
1364bcf0153eSBarry Smith    The user must provide the solution using `TSSetSolutionFunction()` to use this monitor.
1365d0c080abSJoseph Pusztay 
1366*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
1367d0c080abSJoseph Pusztay @*/
1368d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorError(TS ts, PetscInt step, PetscReal ptime, Vec u, PetscViewerAndFormat *vf)
1369d71ae5a4SJacob Faibussowitsch {
137007eaae0cSMatthew G. Knepley   DM        dm;
137107eaae0cSMatthew G. Knepley   PetscDS   ds = NULL;
137207eaae0cSMatthew G. Knepley   PetscInt  Nf = -1, f;
1373d0c080abSJoseph Pusztay   PetscBool flg;
1374d0c080abSJoseph Pusztay 
1375d0c080abSJoseph Pusztay   PetscFunctionBegin;
13769566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
13779566063dSJacob Faibussowitsch   if (dm) PetscCall(DMGetDS(dm, &ds));
13789566063dSJacob Faibussowitsch   if (ds) PetscCall(PetscDSGetNumFields(ds, &Nf));
137907eaae0cSMatthew G. Knepley   if (Nf <= 0) {
138007eaae0cSMatthew G. Knepley     Vec       y;
138107eaae0cSMatthew G. Knepley     PetscReal nrm;
138207eaae0cSMatthew G. Knepley 
13839566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u, &y));
13849566063dSJacob Faibussowitsch     PetscCall(TSComputeSolutionFunction(ts, ptime, y));
13859566063dSJacob Faibussowitsch     PetscCall(VecAXPY(y, -1.0, u));
13869566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer, PETSCVIEWERASCII, &flg));
1387d0c080abSJoseph Pusztay     if (flg) {
13889566063dSJacob Faibussowitsch       PetscCall(VecNorm(y, NORM_2, &nrm));
13899566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vf->viewer, "2-norm of error %g\n", (double)nrm));
1390d0c080abSJoseph Pusztay     }
13919566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer, PETSCVIEWERDRAW, &flg));
13921baa6e33SBarry Smith     if (flg) PetscCall(VecView(y, vf->viewer));
13939566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&y));
139407eaae0cSMatthew G. Knepley   } else {
139507eaae0cSMatthew G. Knepley     PetscErrorCode (**exactFuncs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx);
139607eaae0cSMatthew G. Knepley     void    **ctxs;
139707eaae0cSMatthew G. Knepley     Vec       v;
139807eaae0cSMatthew G. Knepley     PetscReal ferrors[1];
139907eaae0cSMatthew G. Knepley 
14009566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(Nf, &exactFuncs, Nf, &ctxs));
14019566063dSJacob Faibussowitsch     for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(ds, f, &exactFuncs[f], &ctxs[f]));
14029566063dSJacob Faibussowitsch     PetscCall(DMComputeL2FieldDiff(dm, ptime, exactFuncs, ctxs, u, ferrors));
14039566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Timestep: %04d time = %-8.4g \t L_2 Error: [", (int)step, (double)ptime));
140407eaae0cSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
14059566063dSJacob Faibussowitsch       if (f > 0) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ", "));
14069566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%2.3g", (double)ferrors[f]));
140707eaae0cSMatthew G. Knepley     }
14089566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "]\n"));
140907eaae0cSMatthew G. Knepley 
14109566063dSJacob Faibussowitsch     PetscCall(VecViewFromOptions(u, NULL, "-sol_vec_view"));
141107eaae0cSMatthew G. Knepley 
14129566063dSJacob Faibussowitsch     PetscCall(PetscOptionsHasName(NULL, NULL, "-exact_vec_view", &flg));
141307eaae0cSMatthew G. Knepley     if (flg) {
14149566063dSJacob Faibussowitsch       PetscCall(DMGetGlobalVector(dm, &v));
14159566063dSJacob Faibussowitsch       PetscCall(DMProjectFunction(dm, ptime, exactFuncs, ctxs, INSERT_ALL_VALUES, v));
14169566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetName((PetscObject)v, "Exact Solution"));
14179566063dSJacob Faibussowitsch       PetscCall(VecViewFromOptions(v, NULL, "-exact_vec_view"));
14189566063dSJacob Faibussowitsch       PetscCall(DMRestoreGlobalVector(dm, &v));
141907eaae0cSMatthew G. Knepley     }
14209566063dSJacob Faibussowitsch     PetscCall(PetscFree2(exactFuncs, ctxs));
142107eaae0cSMatthew G. Knepley   }
14223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1423d0c080abSJoseph Pusztay }
1424d0c080abSJoseph Pusztay 
1425d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSNESIterations(TS ts, PetscInt n, PetscReal ptime, Vec v, void *monctx)
1426d71ae5a4SJacob Faibussowitsch {
1427d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx)monctx;
1428d0c080abSJoseph Pusztay   PetscReal      x   = ptime, y;
1429d0c080abSJoseph Pusztay   PetscInt       its;
1430d0c080abSJoseph Pusztay 
1431d0c080abSJoseph Pusztay   PetscFunctionBegin;
14323ba16761SJacob Faibussowitsch   if (n < 0) PetscFunctionReturn(PETSC_SUCCESS); /* -1 indicates interpolated solution */
1433d0c080abSJoseph Pusztay   if (!n) {
1434d0c080abSJoseph Pusztay     PetscDrawAxis axis;
14359566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
14369566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Nonlinear iterations as function of time", "Time", "SNES Iterations"));
14379566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1438d0c080abSJoseph Pusztay     ctx->snes_its = 0;
1439d0c080abSJoseph Pusztay   }
14409566063dSJacob Faibussowitsch   PetscCall(TSGetSNESIterations(ts, &its));
1441d0c080abSJoseph Pusztay   y = its - ctx->snes_its;
14429566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg, &x, &y));
1443d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
14449566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
14459566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1446d0c080abSJoseph Pusztay   }
1447d0c080abSJoseph Pusztay   ctx->snes_its = its;
14483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1449d0c080abSJoseph Pusztay }
1450d0c080abSJoseph Pusztay 
1451d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGKSPIterations(TS ts, PetscInt n, PetscReal ptime, Vec v, void *monctx)
1452d71ae5a4SJacob Faibussowitsch {
1453d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx)monctx;
1454d0c080abSJoseph Pusztay   PetscReal      x   = ptime, y;
1455d0c080abSJoseph Pusztay   PetscInt       its;
1456d0c080abSJoseph Pusztay 
1457d0c080abSJoseph Pusztay   PetscFunctionBegin;
14583ba16761SJacob Faibussowitsch   if (n < 0) PetscFunctionReturn(PETSC_SUCCESS); /* -1 indicates interpolated solution */
1459d0c080abSJoseph Pusztay   if (!n) {
1460d0c080abSJoseph Pusztay     PetscDrawAxis axis;
14619566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
14629566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Linear iterations as function of time", "Time", "KSP Iterations"));
14639566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1464d0c080abSJoseph Pusztay     ctx->ksp_its = 0;
1465d0c080abSJoseph Pusztay   }
14669566063dSJacob Faibussowitsch   PetscCall(TSGetKSPIterations(ts, &its));
1467d0c080abSJoseph Pusztay   y = its - ctx->ksp_its;
14689566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg, &x, &y));
1469d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
14709566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
14719566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1472d0c080abSJoseph Pusztay   }
1473d0c080abSJoseph Pusztay   ctx->ksp_its = its;
14743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1475d0c080abSJoseph Pusztay }
1476d0c080abSJoseph Pusztay 
1477d0c080abSJoseph Pusztay /*@C
1478bcf0153eSBarry Smith    TSMonitorEnvelopeCtxCreate - Creates a context for use with `TSMonitorEnvelope()`
1479d0c080abSJoseph Pusztay 
1480c3339decSBarry Smith    Collective
1481d0c080abSJoseph Pusztay 
14822fe279fdSBarry Smith    Input Parameter:
1483bcf0153eSBarry Smith .  ts  - the `TS` solver object
1484d0c080abSJoseph Pusztay 
1485d0c080abSJoseph Pusztay    Output Parameter:
1486d0c080abSJoseph Pusztay .  ctx - the context
1487d0c080abSJoseph Pusztay 
1488d0c080abSJoseph Pusztay    Level: intermediate
1489d0c080abSJoseph Pusztay 
1490*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorLGTimeStep()`, `TSMonitorSet()`, `TSMonitorLGSolution()`, `TSMonitorLGError()`
1491d0c080abSJoseph Pusztay @*/
1492d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorEnvelopeCtxCreate(TS ts, TSMonitorEnvelopeCtx *ctx)
1493d71ae5a4SJacob Faibussowitsch {
1494d0c080abSJoseph Pusztay   PetscFunctionBegin;
14959566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
14963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1497d0c080abSJoseph Pusztay }
1498d0c080abSJoseph Pusztay 
1499d0c080abSJoseph Pusztay /*@C
1500d0c080abSJoseph Pusztay    TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution
1501d0c080abSJoseph Pusztay 
1502c3339decSBarry Smith    Collective
1503d0c080abSJoseph Pusztay 
1504d0c080abSJoseph Pusztay    Input Parameters:
1505195e9b02SBarry Smith +  ts - the `TS` context
1506d0c080abSJoseph Pusztay .  step - current time-step
1507d0c080abSJoseph Pusztay .  ptime - current time
1508d0c080abSJoseph Pusztay .  u  - current solution
1509d0c080abSJoseph Pusztay -  dctx - the envelope context
1510d0c080abSJoseph Pusztay 
1511bcf0153eSBarry Smith    Options Database Key:
151267b8a455SSatish Balay .  -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time
1513d0c080abSJoseph Pusztay 
1514d0c080abSJoseph Pusztay    Level: intermediate
1515d0c080abSJoseph Pusztay 
1516d0c080abSJoseph Pusztay    Notes:
1517bcf0153eSBarry Smith    After a solve you can use `TSMonitorEnvelopeGetBounds()` to access the envelope
15183a61192cSBarry Smith 
15193a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
1520bcf0153eSBarry Smith    to be used during the `TS` integration.
1521d0c080abSJoseph Pusztay 
1522*1cc06b55SBarry Smith .seealso: [](ch_ts), `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxCreate()`
1523d0c080abSJoseph Pusztay @*/
1524d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorEnvelope(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx)
1525d71ae5a4SJacob Faibussowitsch {
1526d0c080abSJoseph Pusztay   TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx;
1527d0c080abSJoseph Pusztay 
1528d0c080abSJoseph Pusztay   PetscFunctionBegin;
1529d0c080abSJoseph Pusztay   if (!ctx->max) {
15309566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u, &ctx->max));
15319566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u, &ctx->min));
15329566063dSJacob Faibussowitsch     PetscCall(VecCopy(u, ctx->max));
15339566063dSJacob Faibussowitsch     PetscCall(VecCopy(u, ctx->min));
1534d0c080abSJoseph Pusztay   } else {
15359566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMax(ctx->max, u, ctx->max));
15369566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMin(ctx->min, u, ctx->min));
1537d0c080abSJoseph Pusztay   }
15383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1539d0c080abSJoseph Pusztay }
1540d0c080abSJoseph Pusztay 
1541d0c080abSJoseph Pusztay /*@C
1542d0c080abSJoseph Pusztay    TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution
1543d0c080abSJoseph Pusztay 
1544c3339decSBarry Smith    Collective
1545d0c080abSJoseph Pusztay 
1546d0c080abSJoseph Pusztay    Input Parameter:
1547bcf0153eSBarry Smith .  ts - the `TS` context
1548d0c080abSJoseph Pusztay 
1549d8d19677SJose E. Roman    Output Parameters:
1550d0c080abSJoseph Pusztay +  max - the maximum values
1551d0c080abSJoseph Pusztay -  min - the minimum values
1552d0c080abSJoseph Pusztay 
1553195e9b02SBarry Smith    Level: intermediate
1554195e9b02SBarry Smith 
1555d0c080abSJoseph Pusztay    Notes:
1556bcf0153eSBarry Smith     If the `TS` does not have a `TSMonitorEnvelopeCtx` associated with it then this function is ignored
1557d0c080abSJoseph Pusztay 
1558*1cc06b55SBarry Smith .seealso: [](ch_ts), `TSMonitorEnvelopeCtx`, `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`
1559d0c080abSJoseph Pusztay @*/
1560d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorEnvelopeGetBounds(TS ts, Vec *max, Vec *min)
1561d71ae5a4SJacob Faibussowitsch {
1562d0c080abSJoseph Pusztay   PetscInt i;
1563d0c080abSJoseph Pusztay 
1564d0c080abSJoseph Pusztay   PetscFunctionBegin;
1565d0c080abSJoseph Pusztay   if (max) *max = NULL;
1566d0c080abSJoseph Pusztay   if (min) *min = NULL;
1567d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
1568d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorEnvelope) {
1569d0c080abSJoseph Pusztay       TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)ts->monitorcontext[i];
1570d0c080abSJoseph Pusztay       if (max) *max = ctx->max;
1571d0c080abSJoseph Pusztay       if (min) *min = ctx->min;
1572d0c080abSJoseph Pusztay       break;
1573d0c080abSJoseph Pusztay     }
1574d0c080abSJoseph Pusztay   }
15753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1576d0c080abSJoseph Pusztay }
1577d0c080abSJoseph Pusztay 
1578d0c080abSJoseph Pusztay /*@C
1579bcf0153eSBarry Smith    TSMonitorEnvelopeCtxDestroy - Destroys a context that was created  with `TSMonitorEnvelopeCtxCreate()`.
1580d0c080abSJoseph Pusztay 
1581c3339decSBarry Smith    Collective
1582d0c080abSJoseph Pusztay 
1583d0c080abSJoseph Pusztay    Input Parameter:
1584d0c080abSJoseph Pusztay .  ctx - the monitor context
1585d0c080abSJoseph Pusztay 
1586d0c080abSJoseph Pusztay    Level: intermediate
1587d0c080abSJoseph Pusztay 
1588*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorLGCtxCreate()`, `TSMonitorSet()`, `TSMonitorLGTimeStep()`
1589d0c080abSJoseph Pusztay @*/
1590d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx)
1591d71ae5a4SJacob Faibussowitsch {
1592d0c080abSJoseph Pusztay   PetscFunctionBegin;
15939566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ctx)->min));
15949566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ctx)->max));
15959566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
15963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1597d0c080abSJoseph Pusztay }
1598d0c080abSJoseph Pusztay 
1599d0c080abSJoseph Pusztay /*@C
1600bcf0153eSBarry Smith   TSDMSwarmMonitorMoments - Monitors the first three moments of a `DMSWARM` being evolved by the `TS`
1601d0c080abSJoseph Pusztay 
160220f4b53cSBarry Smith   Not Collective
1603d0c080abSJoseph Pusztay 
1604d0c080abSJoseph Pusztay   Input Parameters:
1605bcf0153eSBarry Smith + ts   - the `TS` context
1606d0c080abSJoseph Pusztay . step - current timestep
1607d0c080abSJoseph Pusztay . t    - current time
1608d0c080abSJoseph Pusztay . u    - current solution
1609d0c080abSJoseph Pusztay - ctx  - not used
1610d0c080abSJoseph Pusztay 
1611bcf0153eSBarry Smith   Options Database Key:
161267b8a455SSatish Balay . -ts_dmswarm_monitor_moments - Monitor moments of particle distribution
1613d0c080abSJoseph Pusztay 
1614d0c080abSJoseph Pusztay   Level: intermediate
1615d0c080abSJoseph Pusztay 
1616d0c080abSJoseph Pusztay   Notes:
1617bcf0153eSBarry Smith   This requires a `DMSWARM` be attached to the `TS`.
1618d0c080abSJoseph Pusztay 
16193a61192cSBarry Smith   This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
16203a61192cSBarry Smith   to be used during the TS integration.
16213a61192cSBarry Smith 
1622*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `DMSWARM`
1623d0c080abSJoseph Pusztay @*/
1624d71ae5a4SJacob Faibussowitsch PetscErrorCode TSDMSwarmMonitorMoments(TS ts, PetscInt step, PetscReal t, Vec U, PetscViewerAndFormat *vf)
1625d71ae5a4SJacob Faibussowitsch {
1626d0c080abSJoseph Pusztay   DM                 sw;
1627d0c080abSJoseph Pusztay   const PetscScalar *u;
1628d0c080abSJoseph Pusztay   PetscReal          m = 1.0, totE = 0., totMom[3] = {0., 0., 0.};
1629d0c080abSJoseph Pusztay   PetscInt           dim, d, Np, p;
1630d0c080abSJoseph Pusztay   MPI_Comm           comm;
1631d0c080abSJoseph Pusztay 
1632d0c080abSJoseph Pusztay   PetscFunctionBeginUser;
16339566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &sw));
16343ba16761SJacob Faibussowitsch   if (!sw || step % ts->monitorFrequency != 0) PetscFunctionReturn(PETSC_SUCCESS);
16359566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)ts, &comm));
16369566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(sw, &dim));
16379566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(U, &Np));
1638d0c080abSJoseph Pusztay   Np /= dim;
16399566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U, &u));
1640d0c080abSJoseph Pusztay   for (p = 0; p < Np; ++p) {
1641d0c080abSJoseph Pusztay     for (d = 0; d < dim; ++d) {
1642d0c080abSJoseph Pusztay       totE += PetscRealPart(u[p * dim + d] * u[p * dim + d]);
1643d0c080abSJoseph Pusztay       totMom[d] += PetscRealPart(u[p * dim + d]);
1644d0c080abSJoseph Pusztay     }
1645d0c080abSJoseph Pusztay   }
16469566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U, &u));
1647d0c080abSJoseph Pusztay   for (d = 0; d < dim; ++d) totMom[d] *= m;
1648d0c080abSJoseph Pusztay   totE *= 0.5 * m;
164963a3b9bcSJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "Step %4" PetscInt_FMT " Total Energy: %10.8lf", step, (double)totE));
165063a3b9bcSJacob Faibussowitsch   for (d = 0; d < dim; ++d) PetscCall(PetscPrintf(comm, "    Total Momentum %c: %10.8lf", (char)('x' + d), (double)totMom[d]));
16519566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "\n"));
16523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1653d0c080abSJoseph Pusztay }
1654