xref: /petsc/src/ts/interface/tsmon.c (revision d5b43468fb8780a8feea140ccd6fa3e6a50411cc)
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 
10bcf0153eSBarry Smith    Collective on ts
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));
43d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
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 
49bcf0153eSBarry Smith    Collective on ts
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 
61bcf0153eSBarry Smith .seealso: [](chapter_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;
799566063dSJacob Faibussowitsch     PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf));
809566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject)viewer));
811baa6e33SBarry Smith     if (monitorsetup) PetscCall((*monitorsetup)(ts, vf));
829566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, (PetscErrorCode(*)(TS, PetscInt, PetscReal, Vec, void *))monitor, vf, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy));
83d0c080abSJoseph Pusztay   }
84d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
85d0c080abSJoseph Pusztay }
86d0c080abSJoseph Pusztay 
87d0c080abSJoseph Pusztay /*@C
88d0c080abSJoseph Pusztay    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
89d0c080abSJoseph Pusztay    timestep to display the iteration's  progress.
90d0c080abSJoseph Pusztay 
91bcf0153eSBarry Smith    Logically Collective on ts
92d0c080abSJoseph Pusztay 
93d0c080abSJoseph Pusztay    Input Parameters:
94bcf0153eSBarry Smith +  ts - the `TS` context obtained from `TSCreate()`
95d0c080abSJoseph Pusztay .  monitor - monitoring routine
96d0c080abSJoseph Pusztay .  mctx - [optional] user-defined context for private data for the
97d0c080abSJoseph Pusztay              monitor routine (use NULL if no context is desired)
98d0c080abSJoseph Pusztay -  monitordestroy - [optional] routine that frees monitor context
99d0c080abSJoseph Pusztay           (may be NULL)
100d0c080abSJoseph Pusztay 
101d0c080abSJoseph Pusztay    Calling sequence of monitor:
102d0c080abSJoseph Pusztay $    PetscErrorCode monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
103d0c080abSJoseph Pusztay 
104d0c080abSJoseph Pusztay +    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:
113d0c080abSJoseph Pusztay    This routine adds an additional monitor to the list of monitors that
114d0c080abSJoseph Pusztay    already has been loaded.
115d0c080abSJoseph Pusztay 
116bcf0153eSBarry Smith    Fortran Note:
117bcf0153eSBarry Smith     Only a single monitor function can be set for each `TS` object
118d0c080abSJoseph Pusztay 
119bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSMonitorDefault()`, `TSMonitorCancel()`, `TSDMSwarmMonitorMoments()`, `TSMonitorExtreme()`, `TSMonitorDrawSolution()`,
1203a61192cSBarry Smith           `TSMonitorDrawSolutionPhase()`, `TSMonitorDrawSolutionFunction()`, `TSMonitorDrawError()`, `TSMonitorSolution()`, `TSMonitorSolutionVTK()`,
1213a61192cSBarry Smith           `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorSPSwarmSolution()`, `TSMonitorError()`, `TSMonitorEnvelope()`, `TSDMSwarmMonitorMoments()`
122d0c080abSJoseph Pusztay @*/
123d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSet(TS ts, PetscErrorCode (*monitor)(TS, PetscInt, PetscReal, Vec, void *), void *mctx, PetscErrorCode (*mdestroy)(void **))
124d71ae5a4SJacob Faibussowitsch {
125d0c080abSJoseph Pusztay   PetscInt  i;
126d0c080abSJoseph Pusztay   PetscBool identical;
127d0c080abSJoseph Pusztay 
128d0c080abSJoseph Pusztay   PetscFunctionBegin;
129d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
130d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
1319566063dSJacob Faibussowitsch     PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))monitor, mctx, mdestroy, (PetscErrorCode(*)(void))ts->monitor[i], ts->monitorcontext[i], ts->monitordestroy[i], &identical));
132d0c080abSJoseph Pusztay     if (identical) PetscFunctionReturn(0);
133d0c080abSJoseph Pusztay   }
1343c633725SBarry Smith   PetscCheck(ts->numbermonitors < MAXTSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set");
135d0c080abSJoseph Pusztay   ts->monitor[ts->numbermonitors]          = monitor;
136d0c080abSJoseph Pusztay   ts->monitordestroy[ts->numbermonitors]   = mdestroy;
137d0c080abSJoseph Pusztay   ts->monitorcontext[ts->numbermonitors++] = (void *)mctx;
138d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
139d0c080abSJoseph Pusztay }
140d0c080abSJoseph Pusztay 
141d0c080abSJoseph Pusztay /*@C
142d0c080abSJoseph Pusztay    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
143d0c080abSJoseph Pusztay 
144bcf0153eSBarry Smith    Logically Collective on ts
145d0c080abSJoseph Pusztay 
146d0c080abSJoseph Pusztay    Input Parameters:
147bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
148d0c080abSJoseph Pusztay 
149d0c080abSJoseph Pusztay    Level: intermediate
150d0c080abSJoseph Pusztay 
151bcf0153eSBarry Smith    Note:
152bcf0153eSBarry Smith    There is no way to remove a single, specific monitor.
153bcf0153eSBarry Smith 
154bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorDefault()`, `TSMonitorSet()`
155d0c080abSJoseph Pusztay @*/
156d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorCancel(TS ts)
157d71ae5a4SJacob Faibussowitsch {
158d0c080abSJoseph Pusztay   PetscInt i;
159d0c080abSJoseph Pusztay 
160d0c080abSJoseph Pusztay   PetscFunctionBegin;
161d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
162d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
16348a46eb9SPierre Jolivet     if (ts->monitordestroy[i]) PetscCall((*ts->monitordestroy[i])(&ts->monitorcontext[i]));
164d0c080abSJoseph Pusztay   }
165d0c080abSJoseph Pusztay   ts->numbermonitors = 0;
166d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
167d0c080abSJoseph Pusztay }
168d0c080abSJoseph Pusztay 
169d0c080abSJoseph Pusztay /*@C
170d0c080abSJoseph Pusztay    TSMonitorDefault - The Default monitor, prints the timestep and time for each step
171d0c080abSJoseph Pusztay 
172bcf0153eSBarry Smith    Options Database Key:
1733a61192cSBarry Smith .  -ts_monitor - monitors the time integration
1743a61192cSBarry Smith 
175d0c080abSJoseph Pusztay    Level: intermediate
176d0c080abSJoseph Pusztay 
177bcf0153eSBarry Smith    Notes:
178bcf0153eSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
179bcf0153eSBarry Smith    to be used during the `TS` integration.
180bcf0153eSBarry Smith 
181bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSMonitorSet()`, `TSDMSwarmMonitorMoments()`, `TSMonitorExtreme()`, `TSMonitorDrawSolution()`,
1823a61192cSBarry Smith           `TSMonitorDrawSolutionPhase()`, `TSMonitorDrawSolutionFunction()`, `TSMonitorDrawError()`, `TSMonitorSolution()`, `TSMonitorSolutionVTK()`,
1833a61192cSBarry Smith           `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorSPSwarmSolution()`, `TSMonitorError()`, `TSMonitorEnvelope()`, `TSDMSwarmMonitorMoments()`
184d0c080abSJoseph Pusztay @*/
185d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDefault(TS ts, PetscInt step, PetscReal ptime, Vec v, PetscViewerAndFormat *vf)
186d71ae5a4SJacob Faibussowitsch {
187d0c080abSJoseph Pusztay   PetscViewer viewer = vf->viewer;
188d0c080abSJoseph Pusztay   PetscBool   iascii, ibinary;
189d0c080abSJoseph Pusztay 
190d0c080abSJoseph Pusztay   PetscFunctionBegin;
191064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 5);
1929566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
1939566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &ibinary));
1949566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
195d0c080abSJoseph Pusztay   if (iascii) {
1969566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)ts)->tablevel));
197d0c080abSJoseph Pusztay     if (step == -1) { /* this indicates it is an interpolated solution */
19863a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Interpolated solution at time %g between steps %" PetscInt_FMT " and %" PetscInt_FMT "\n", (double)ptime, ts->steps - 1, ts->steps));
199d0c080abSJoseph Pusztay     } else {
20063a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " TS dt %g time %g%s", step, (double)ts->time_step, (double)ptime, ts->steprollback ? " (r)\n" : "\n"));
201d0c080abSJoseph Pusztay     }
2029566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)ts)->tablevel));
203d0c080abSJoseph Pusztay   } else if (ibinary) {
204d0c080abSJoseph Pusztay     PetscMPIInt rank;
2059566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
206c5853193SPierre Jolivet     if (rank == 0) {
207d0c080abSJoseph Pusztay       PetscBool skipHeader;
208d0c080abSJoseph Pusztay       PetscInt  classid = REAL_FILE_CLASSID;
209d0c080abSJoseph Pusztay 
2109566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
21148a46eb9SPierre Jolivet       if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, &classid, 1, PETSC_INT));
2129566063dSJacob Faibussowitsch       PetscCall(PetscRealView(1, &ptime, viewer));
213d0c080abSJoseph Pusztay     } else {
2149566063dSJacob Faibussowitsch       PetscCall(PetscRealView(0, &ptime, viewer));
215d0c080abSJoseph Pusztay     }
216d0c080abSJoseph Pusztay   }
2179566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
218d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
219d0c080abSJoseph Pusztay }
220d0c080abSJoseph Pusztay 
221d0c080abSJoseph Pusztay /*@C
222d0c080abSJoseph Pusztay    TSMonitorExtreme - Prints the extreme values of the solution at each timestep
223d0c080abSJoseph Pusztay 
224bcf0153eSBarry Smith    Level: intermediate
225bcf0153eSBarry Smith 
2263a61192cSBarry Smith    Notes:
2273a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
2283a61192cSBarry Smith    to be used during the TS integration.
2293a61192cSBarry Smith 
230bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorSet()`
231d0c080abSJoseph Pusztay @*/
232d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorExtreme(TS ts, PetscInt step, PetscReal ptime, Vec v, PetscViewerAndFormat *vf)
233d71ae5a4SJacob Faibussowitsch {
234d0c080abSJoseph Pusztay   PetscViewer viewer = vf->viewer;
235d0c080abSJoseph Pusztay   PetscBool   iascii;
236d0c080abSJoseph Pusztay   PetscReal   max, min;
237d0c080abSJoseph Pusztay 
238d0c080abSJoseph Pusztay   PetscFunctionBegin;
239064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 5);
2409566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
2419566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
242d0c080abSJoseph Pusztay   if (iascii) {
2439566063dSJacob Faibussowitsch     PetscCall(VecMax(v, NULL, &max));
2449566063dSJacob Faibussowitsch     PetscCall(VecMin(v, NULL, &min));
2459566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)ts)->tablevel));
24663a3b9bcSJacob 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));
2479566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)ts)->tablevel));
248d0c080abSJoseph Pusztay   }
2499566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
250d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
251d0c080abSJoseph Pusztay }
252d0c080abSJoseph Pusztay 
253d0c080abSJoseph Pusztay /*@C
254bcf0153eSBarry Smith    TSMonitorLGCtxCreate - Creates a `TSMonitorLGCtx` context for use with
255bcf0153eSBarry Smith    `TS` to monitor the solution process graphically in various ways
256d0c080abSJoseph Pusztay 
257bcf0153eSBarry Smith    Collective on ts
258d0c080abSJoseph Pusztay 
259d0c080abSJoseph Pusztay    Input Parameters:
260d0c080abSJoseph Pusztay +  host - the X display to open, or null for the local machine
261d0c080abSJoseph Pusztay .  label - the title to put in the title bar
262d0c080abSJoseph Pusztay .  x, y - the screen coordinates of the upper left coordinate of the window
263d0c080abSJoseph Pusztay .  m, n - the screen width and height in pixels
264d0c080abSJoseph Pusztay -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
265d0c080abSJoseph Pusztay 
266d0c080abSJoseph Pusztay    Output Parameter:
267d0c080abSJoseph Pusztay .  ctx - the context
268d0c080abSJoseph Pusztay 
269bcf0153eSBarry Smith    Options Database Keys:
270d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep - automatically sets line graph monitor
271d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep_log - automatically sets line graph monitor
272bcf0153eSBarry Smith .  -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling `TSMonitorLGSetDisplayVariables()` or `TSMonitorLGCtxSetDisplayVariables()`)
273d0c080abSJoseph Pusztay .  -ts_monitor_lg_error -  monitor the error
274bcf0153eSBarry Smith .  -ts_monitor_lg_ksp_iterations - monitor the number of `KSP` iterations needed for each timestep
275bcf0153eSBarry Smith .  -ts_monitor_lg_snes_iterations - monitor the number of `SNES` iterations needed for each timestep
276d0c080abSJoseph Pusztay -  -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true
277d0c080abSJoseph Pusztay 
278d0c080abSJoseph Pusztay    Level: intermediate
279d0c080abSJoseph Pusztay 
280bcf0153eSBarry Smith    Notes:
281bcf0153eSBarry Smith    Pass the context and `TSMonitorLGCtxDestroy()` to `TSMonitorSet()` to have the context destroyed when no longer needed.
282bcf0153eSBarry Smith 
283bcf0153eSBarry Smith    One can provide a function that transforms the solution before plotting it with `TSMonitorLGCtxSetTransform()` or `TSMonitorLGSetTransform()`
284bcf0153eSBarry Smith 
285bcf0153eSBarry 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
286bcf0153eSBarry 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
287bcf0153eSBarry Smith    as the first argument.
288bcf0153eSBarry Smith 
289bcf0153eSBarry Smith    One can control the names displayed for each solution or error variable with `TSMonitorLGCtxSetVariableNames()` or `TSMonitorLGSetVariableNames()`
290bcf0153eSBarry Smith 
291bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSMonitorLGTimeStep()`, `TSMonitorSet()`, `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorDefault()`, `VecView()`,
292db781477SPatrick Sanan           `TSMonitorLGCtxCreate()`, `TSMonitorLGCtxSetVariableNames()`, `TSMonitorLGCtxGetVariableNames()`,
293db781477SPatrick Sanan           `TSMonitorLGSetVariableNames()`, `TSMonitorLGGetVariableNames()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetDisplayVariables()`,
294db781477SPatrick Sanan           `TSMonitorLGCtxSetTransform()`, `TSMonitorLGSetTransform()`, `TSMonitorLGError()`, `TSMonitorLGSNESIterations()`, `TSMonitorLGKSPIterations()`,
295db781477SPatrick Sanan           `TSMonitorEnvelopeCtxCreate()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxDestroy()`, `TSMonitorEnvelop()`
296d0c080abSJoseph Pusztay @*/
297d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, TSMonitorLGCtx *ctx)
298d71ae5a4SJacob Faibussowitsch {
299d0c080abSJoseph Pusztay   PetscDraw draw;
300d0c080abSJoseph Pusztay 
301d0c080abSJoseph Pusztay   PetscFunctionBegin;
3029566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
3039566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm, host, label, x, y, m, n, &draw));
3049566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetFromOptions(draw));
3059566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGCreate(draw, 1, &(*ctx)->lg));
3069566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGSetFromOptions((*ctx)->lg));
3079566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw));
308d0c080abSJoseph Pusztay   (*ctx)->howoften = howoften;
309d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
310d0c080abSJoseph Pusztay }
311d0c080abSJoseph Pusztay 
312d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGTimeStep(TS ts, PetscInt step, PetscReal ptime, Vec v, void *monctx)
313d71ae5a4SJacob Faibussowitsch {
314d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx)monctx;
315d0c080abSJoseph Pusztay   PetscReal      x   = ptime, y;
316d0c080abSJoseph Pusztay 
317d0c080abSJoseph Pusztay   PetscFunctionBegin;
318d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */
319d0c080abSJoseph Pusztay   if (!step) {
320d0c080abSJoseph Pusztay     PetscDrawAxis axis;
321d0c080abSJoseph Pusztay     const char   *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step";
3229566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
3239566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Timestep as function of time", "Time", ylabel));
3249566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
325d0c080abSJoseph Pusztay   }
3269566063dSJacob Faibussowitsch   PetscCall(TSGetTimeStep(ts, &y));
327d0c080abSJoseph Pusztay   if (ctx->semilogy) y = PetscLog10Real(y);
3289566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg, &x, &y));
329d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
3309566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
3319566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
332d0c080abSJoseph Pusztay   }
333d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
334d0c080abSJoseph Pusztay }
335d0c080abSJoseph Pusztay 
336d0c080abSJoseph Pusztay /*@C
337d0c080abSJoseph Pusztay    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
338bcf0153eSBarry Smith    with `TSMonitorLGCtxCreate()`.
339d0c080abSJoseph Pusztay 
340bcf0153eSBarry Smith    Collective on ctx
341d0c080abSJoseph Pusztay 
342d0c080abSJoseph Pusztay    Input Parameter:
343d0c080abSJoseph Pusztay .  ctx - the monitor context
344d0c080abSJoseph Pusztay 
345d0c080abSJoseph Pusztay    Level: intermediate
346d0c080abSJoseph Pusztay 
347bcf0153eSBarry Smith    Note:
348bcf0153eSBarry Smith    Pass to `TSMonitorSet()` along with the context and `TSMonitorLGTimeStep()`
349bcf0153eSBarry Smith 
350bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorLGCtxCreate()`, `TSMonitorSet()`, `TSMonitorLGTimeStep();`
351d0c080abSJoseph Pusztay @*/
352d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
353d71ae5a4SJacob Faibussowitsch {
354d0c080abSJoseph Pusztay   PetscFunctionBegin;
35548a46eb9SPierre Jolivet   if ((*ctx)->transformdestroy) PetscCall(((*ctx)->transformdestroy)((*ctx)->transformctx));
3569566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGDestroy(&(*ctx)->lg));
3579566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&(*ctx)->names));
3589566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&(*ctx)->displaynames));
3599566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ctx)->displayvariables));
3609566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ctx)->displayvalues));
3619566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
362d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
363d0c080abSJoseph Pusztay }
364d0c080abSJoseph Pusztay 
365d7462660SMatthew Knepley /* Creates a TS Monitor SPCtx for use with DMSwarm particle visualizations */
366d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSPCtxCreate(MPI_Comm comm, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, PetscInt retain, PetscBool phase, TSMonitorSPCtx *ctx)
367d71ae5a4SJacob Faibussowitsch {
368d0c080abSJoseph Pusztay   PetscDraw draw;
369d0c080abSJoseph Pusztay 
370d0c080abSJoseph Pusztay   PetscFunctionBegin;
3719566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
3729566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm, host, label, x, y, m, n, &draw));
3739566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetFromOptions(draw));
3749566063dSJacob Faibussowitsch   PetscCall(PetscDrawSPCreate(draw, 1, &(*ctx)->sp));
3759566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw));
376d0c080abSJoseph Pusztay   (*ctx)->howoften = howoften;
377d7462660SMatthew Knepley   (*ctx)->retain   = retain;
378d7462660SMatthew Knepley   (*ctx)->phase    = phase;
379d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
380d0c080abSJoseph Pusztay }
381d0c080abSJoseph Pusztay 
382d0c080abSJoseph Pusztay /*
383d0c080abSJoseph Pusztay   Destroys a TSMonitorSPCtx that was created with TSMonitorSPCtxCreate
384d0c080abSJoseph Pusztay */
385d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSPCtxDestroy(TSMonitorSPCtx *ctx)
386d71ae5a4SJacob Faibussowitsch {
387d0c080abSJoseph Pusztay   PetscFunctionBegin;
388d0c080abSJoseph Pusztay 
3899566063dSJacob Faibussowitsch   PetscCall(PetscDrawSPDestroy(&(*ctx)->sp));
3909566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
391d0c080abSJoseph Pusztay 
392d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
393d0c080abSJoseph Pusztay }
394d0c080abSJoseph Pusztay 
395d0c080abSJoseph Pusztay /*@C
396bcf0153eSBarry Smith    TSMonitorDrawSolution - Monitors progress of the `TS` solvers by calling
397bcf0153eSBarry Smith    `VecView()` for the solution at each timestep
398d0c080abSJoseph Pusztay 
399bcf0153eSBarry Smith    Collective on ts
400d0c080abSJoseph Pusztay 
401d0c080abSJoseph Pusztay    Input Parameters:
402bcf0153eSBarry Smith +  ts - the `TS` context
403d0c080abSJoseph Pusztay .  step - current time-step
404d0c080abSJoseph Pusztay .  ptime - current time
405d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
406d0c080abSJoseph Pusztay 
407bcf0153eSBarry Smith    Options Database Keys:
408bcf0153eSBarry Smith +   -ts_monitor_draw_solution - draw the solution at each time-step
409bcf0153eSBarry Smith -   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
410bcf0153eSBarry Smith 
411bcf0153eSBarry Smith    Level: intermediate
412d0c080abSJoseph Pusztay 
413d0c080abSJoseph Pusztay    Notes:
4143a61192cSBarry Smith    The initial solution and current solution are not displayed with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
415d0c080abSJoseph Pusztay    will look bad
416d0c080abSJoseph Pusztay 
417bcf0153eSBarry 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
418bcf0153eSBarry Smith    `TSMonitorDrawCtxCreate()` and the function `TSMonitorDrawCtxDestroy()` to cause the monitor to be used during the `TS` integration.
4193a61192cSBarry Smith 
420bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawCtxCreate()`, `TSMonitorDrawCtxDestroy()`
421d0c080abSJoseph Pusztay @*/
422d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy)
423d71ae5a4SJacob Faibussowitsch {
424d0c080abSJoseph Pusztay   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
425d0c080abSJoseph Pusztay   PetscDraw        draw;
426d0c080abSJoseph Pusztay 
427d0c080abSJoseph Pusztay   PetscFunctionBegin;
428d0c080abSJoseph Pusztay   if (!step && ictx->showinitial) {
42948a46eb9SPierre Jolivet     if (!ictx->initialsolution) PetscCall(VecDuplicate(u, &ictx->initialsolution));
4309566063dSJacob Faibussowitsch     PetscCall(VecCopy(u, ictx->initialsolution));
431d0c080abSJoseph Pusztay   }
432d0c080abSJoseph Pusztay   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
433d0c080abSJoseph Pusztay 
434d0c080abSJoseph Pusztay   if (ictx->showinitial) {
435d0c080abSJoseph Pusztay     PetscReal pause;
4369566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetPause(ictx->viewer, &pause));
4379566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetPause(ictx->viewer, 0.0));
4389566063dSJacob Faibussowitsch     PetscCall(VecView(ictx->initialsolution, ictx->viewer));
4399566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetPause(ictx->viewer, pause));
4409566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetHold(ictx->viewer, PETSC_TRUE));
441d0c080abSJoseph Pusztay   }
4429566063dSJacob Faibussowitsch   PetscCall(VecView(u, ictx->viewer));
443d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
444d0c080abSJoseph Pusztay     PetscReal xl, yl, xr, yr, h;
445d0c080abSJoseph Pusztay     char      time[32];
446d0c080abSJoseph Pusztay 
4479566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(ictx->viewer, 0, &draw));
4489566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(time, 32, "Timestep %d Time %g", (int)step, (double)ptime));
4499566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
450d0c080abSJoseph Pusztay     h = yl + .95 * (yr - yl);
4519566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw, .5 * (xl + xr), h, PETSC_DRAW_BLACK, time));
4529566063dSJacob Faibussowitsch     PetscCall(PetscDrawFlush(draw));
453d0c080abSJoseph Pusztay   }
454d0c080abSJoseph Pusztay 
4551baa6e33SBarry Smith   if (ictx->showinitial) PetscCall(PetscViewerDrawSetHold(ictx->viewer, PETSC_FALSE));
456d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
457d0c080abSJoseph Pusztay }
458d0c080abSJoseph Pusztay 
459d0c080abSJoseph Pusztay /*@C
460bcf0153eSBarry Smith    TSMonitorDrawSolutionPhase - Monitors progress of the `TS` solvers by plotting the solution as a phase diagram
461d0c080abSJoseph Pusztay 
462bcf0153eSBarry Smith    Collective on ts
463d0c080abSJoseph Pusztay 
464d0c080abSJoseph Pusztay    Input Parameters:
465bcf0153eSBarry Smith +  ts - the `TS` context
466d0c080abSJoseph Pusztay .  step - current time-step
467d0c080abSJoseph Pusztay .  ptime - current time
468d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
469d0c080abSJoseph Pusztay 
470d0c080abSJoseph Pusztay    Level: intermediate
471d0c080abSJoseph Pusztay 
472bcf0153eSBarry Smith    Notes:
473bcf0153eSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
474bcf0153eSBarry Smith    to be used during the `TS` integration.
475bcf0153eSBarry Smith 
476bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
477d0c080abSJoseph Pusztay @*/
478d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawSolutionPhase(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy)
479d71ae5a4SJacob Faibussowitsch {
480d0c080abSJoseph Pusztay   TSMonitorDrawCtx   ictx = (TSMonitorDrawCtx)dummy;
481d0c080abSJoseph Pusztay   PetscDraw          draw;
482d0c080abSJoseph Pusztay   PetscDrawAxis      axis;
483d0c080abSJoseph Pusztay   PetscInt           n;
484d0c080abSJoseph Pusztay   PetscMPIInt        size;
485d0c080abSJoseph Pusztay   PetscReal          U0, U1, xl, yl, xr, yr, h;
486d0c080abSJoseph Pusztay   char               time[32];
487d0c080abSJoseph Pusztay   const PetscScalar *U;
488d0c080abSJoseph Pusztay 
489d0c080abSJoseph Pusztay   PetscFunctionBegin;
4909566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)ts), &size));
4913c633725SBarry Smith   PetscCheck(size == 1, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Only allowed for sequential runs");
4929566063dSJacob Faibussowitsch   PetscCall(VecGetSize(u, &n));
4933c633725SBarry Smith   PetscCheck(n == 2, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Only for ODEs with two unknowns");
494d0c080abSJoseph Pusztay 
4959566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(ictx->viewer, 0, &draw));
4969566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDrawAxis(ictx->viewer, 0, &axis));
4979566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisGetLimits(axis, &xl, &xr, &yl, &yr));
498d0c080abSJoseph Pusztay   if (!step) {
4999566063dSJacob Faibussowitsch     PetscCall(PetscDrawClear(draw));
5009566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisDraw(axis));
501d0c080abSJoseph Pusztay   }
502d0c080abSJoseph Pusztay 
5039566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(u, &U));
504d0c080abSJoseph Pusztay   U0 = PetscRealPart(U[0]);
505d0c080abSJoseph Pusztay   U1 = PetscRealPart(U[1]);
5069566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(u, &U));
507d0c080abSJoseph Pusztay   if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0);
508d0c080abSJoseph Pusztay 
509d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
5109566063dSJacob Faibussowitsch   PetscCall(PetscDrawPoint(draw, U0, U1, PETSC_DRAW_BLACK));
511d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
5129566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
5139566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(time, 32, "Timestep %d Time %g", (int)step, (double)ptime));
514d0c080abSJoseph Pusztay     h = yl + .95 * (yr - yl);
5159566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw, .5 * (xl + xr), h, PETSC_DRAW_BLACK, time));
516d0c080abSJoseph Pusztay   }
517d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
5189566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
5199566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
5209566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
521d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
522d0c080abSJoseph Pusztay }
523d0c080abSJoseph Pusztay 
524d0c080abSJoseph Pusztay /*@C
525bcf0153eSBarry Smith    TSMonitorDrawCtxDestroy - Destroys the monitor context for `TSMonitorDrawSolution()`
526d0c080abSJoseph Pusztay 
527bcf0153eSBarry Smith    Collective on ts
528d0c080abSJoseph Pusztay 
529d0c080abSJoseph Pusztay    Input Parameters:
530d0c080abSJoseph Pusztay .    ctx - the monitor context
531d0c080abSJoseph Pusztay 
532d0c080abSJoseph Pusztay    Level: intermediate
533d0c080abSJoseph Pusztay 
534bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawSolution()`, `TSMonitorDrawError()`, `TSMonitorDrawCtx`
535d0c080abSJoseph Pusztay @*/
536d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
537d71ae5a4SJacob Faibussowitsch {
538d0c080abSJoseph Pusztay   PetscFunctionBegin;
5399566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&(*ictx)->viewer));
5409566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ictx)->initialsolution));
5419566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ictx));
542d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
543d0c080abSJoseph Pusztay }
544d0c080abSJoseph Pusztay 
545d0c080abSJoseph Pusztay /*@C
546bcf0153eSBarry Smith    TSMonitorDrawCtxCreate - Creates the monitor context for `TSMonitorDrawCtx`
547d0c080abSJoseph Pusztay 
548bcf0153eSBarry Smith    Collective on ts
549d0c080abSJoseph Pusztay 
550d0c080abSJoseph Pusztay    Input Parameter:
551d0c080abSJoseph Pusztay .    ts - time-step context
552d0c080abSJoseph Pusztay 
553*d5b43468SJose E. Roman    Output Parameter:
554d0c080abSJoseph Pusztay .    ctx - the monitor context
555d0c080abSJoseph Pusztay 
556bcf0153eSBarry Smith    Options Database Keys:
557bcf0153eSBarry Smith +   -ts_monitor_draw_solution - draw the solution at each time-step
558bcf0153eSBarry Smith -   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
559d0c080abSJoseph Pusztay 
560d0c080abSJoseph Pusztay    Level: intermediate
561d0c080abSJoseph Pusztay 
562bcf0153eSBarry Smith    Note:
563bcf0153eSBarry Smith    The context created by this function,  `PetscMonitorDrawSolution()`, and `TSMonitorDrawCtxDestroy()` should be passed together to `TSMonitorSet()`.
564bcf0153eSBarry Smith 
565bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorDrawCtxDestroy()`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawCtx`, `PetscMonitorDrawSolution()`
566d0c080abSJoseph Pusztay @*/
567d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, TSMonitorDrawCtx *ctx)
568d71ae5a4SJacob Faibussowitsch {
569d0c080abSJoseph Pusztay   PetscFunctionBegin;
5709566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
5719566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawOpen(comm, host, label, x, y, m, n, &(*ctx)->viewer));
5729566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetFromOptions((*ctx)->viewer));
573d0c080abSJoseph Pusztay 
574d0c080abSJoseph Pusztay   (*ctx)->howoften    = howoften;
575d0c080abSJoseph Pusztay   (*ctx)->showinitial = PETSC_FALSE;
5769566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-ts_monitor_draw_solution_initial", &(*ctx)->showinitial, NULL));
577d0c080abSJoseph Pusztay 
578d0c080abSJoseph Pusztay   (*ctx)->showtimestepandtime = PETSC_FALSE;
5799566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-ts_monitor_draw_solution_show_time", &(*ctx)->showtimestepandtime, NULL));
580d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
581d0c080abSJoseph Pusztay }
582d0c080abSJoseph Pusztay 
583d0c080abSJoseph Pusztay /*@C
584bcf0153eSBarry Smith    TSMonitorDrawSolutionFunction - Monitors progress of the `TS` solvers by calling
585bcf0153eSBarry Smith    `VecView()` for the solution provided by `TSSetSolutionFunction()` at each timestep
586d0c080abSJoseph Pusztay 
587bcf0153eSBarry Smith    Collective on ts
588d0c080abSJoseph Pusztay 
589d0c080abSJoseph Pusztay    Input Parameters:
590bcf0153eSBarry Smith +  ts - the `TS` context
591d0c080abSJoseph Pusztay .  step - current time-step
592d0c080abSJoseph Pusztay .  ptime - current time
593d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
594d0c080abSJoseph Pusztay 
595bcf0153eSBarry Smith    Options Database Key:
596bcf0153eSBarry Smith .  -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided `TSSetSolutionFunction()`
5973a61192cSBarry Smith 
598d0c080abSJoseph Pusztay    Level: intermediate
599d0c080abSJoseph Pusztay 
600bcf0153eSBarry Smith    Note:
601bcf0153eSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
602bcf0153eSBarry Smith    to be used during the `TS` integration.
603bcf0153eSBarry Smith 
604bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
605d0c080abSJoseph Pusztay @*/
606d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawSolutionFunction(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy)
607d71ae5a4SJacob Faibussowitsch {
608d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
609d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
610d0c080abSJoseph Pusztay   Vec              work;
611d0c080abSJoseph Pusztay 
612d0c080abSJoseph Pusztay   PetscFunctionBegin;
613d0c080abSJoseph Pusztay   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
6149566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u, &work));
6159566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts, ptime, work));
6169566063dSJacob Faibussowitsch   PetscCall(VecView(work, viewer));
6179566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work));
618d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
619d0c080abSJoseph Pusztay }
620d0c080abSJoseph Pusztay 
621d0c080abSJoseph Pusztay /*@C
622bcf0153eSBarry Smith    TSMonitorDrawError - Monitors progress of the `TS` solvers by calling
623bcf0153eSBarry Smith    `VecView()` for the error at each timestep
624d0c080abSJoseph Pusztay 
625bcf0153eSBarry Smith    Collective on ts
626d0c080abSJoseph Pusztay 
627d0c080abSJoseph Pusztay    Input Parameters:
628bcf0153eSBarry Smith +  ts - the `TS` context
629d0c080abSJoseph Pusztay .  step - current time-step
630d0c080abSJoseph Pusztay .  ptime - current time
631d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
632d0c080abSJoseph Pusztay 
633bcf0153eSBarry Smith    Options Database Key:
634bcf0153eSBarry Smith .  -ts_monitor_draw_error - Monitor error graphically, requires user to have provided `TSSetSolutionFunction()`
6353a61192cSBarry Smith 
636d0c080abSJoseph Pusztay    Level: intermediate
637d0c080abSJoseph Pusztay 
638bcf0153eSBarry Smith    Notes:
639bcf0153eSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
640bcf0153eSBarry Smith    to be used during the `TS` integration.
641bcf0153eSBarry Smith 
642bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
643d0c080abSJoseph Pusztay @*/
644d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawError(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy)
645d71ae5a4SJacob Faibussowitsch {
646d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
647d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
648d0c080abSJoseph Pusztay   Vec              work;
649d0c080abSJoseph Pusztay 
650d0c080abSJoseph Pusztay   PetscFunctionBegin;
651d0c080abSJoseph Pusztay   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
6529566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u, &work));
6539566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts, ptime, work));
6549566063dSJacob Faibussowitsch   PetscCall(VecAXPY(work, -1.0, u));
6559566063dSJacob Faibussowitsch   PetscCall(VecView(work, viewer));
6569566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work));
657d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
658d0c080abSJoseph Pusztay }
659d0c080abSJoseph Pusztay 
660d0c080abSJoseph Pusztay /*@C
661bcf0153eSBarry 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
662d0c080abSJoseph Pusztay 
663bcf0153eSBarry Smith    Collective on ts
664d0c080abSJoseph Pusztay 
665d0c080abSJoseph Pusztay    Input Parameters:
666bcf0153eSBarry Smith +  ts - the `TS` context
667d0c080abSJoseph Pusztay .  step - current time-step
668d0c080abSJoseph Pusztay .  ptime - current time
669d0c080abSJoseph Pusztay .  u - current state
670d0c080abSJoseph Pusztay -  vf - viewer and its format
671d0c080abSJoseph Pusztay 
672d0c080abSJoseph Pusztay    Level: intermediate
673d0c080abSJoseph Pusztay 
674bcf0153eSBarry Smith    Notes:
675bcf0153eSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
676bcf0153eSBarry Smith    to be used during the `TS` integration.
677bcf0153eSBarry Smith 
678bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
679d0c080abSJoseph Pusztay @*/
680d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, PetscViewerAndFormat *vf)
681d71ae5a4SJacob Faibussowitsch {
682d0c080abSJoseph Pusztay   PetscFunctionBegin;
6839566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(vf->viewer, vf->format));
6849566063dSJacob Faibussowitsch   PetscCall(VecView(u, vf->viewer));
6859566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(vf->viewer));
686d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
687d0c080abSJoseph Pusztay }
688d0c080abSJoseph Pusztay 
689d0c080abSJoseph Pusztay /*@C
690bcf0153eSBarry Smith    TSMonitorSolutionVTK - Monitors progress of the `TS` solvers by `VecView()` for the solution at each timestep.
691d0c080abSJoseph Pusztay 
692bcf0153eSBarry Smith    Collective on ts
693d0c080abSJoseph Pusztay 
694d0c080abSJoseph Pusztay    Input Parameters:
695bcf0153eSBarry Smith +  ts - the `TS` context
696d0c080abSJoseph Pusztay .  step - current time-step
697d0c080abSJoseph Pusztay .  ptime - current time
698d0c080abSJoseph Pusztay .  u - current state
69963a3b9bcSJacob Faibussowitsch -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03" PetscInt_FMT ")
700d0c080abSJoseph Pusztay 
701d0c080abSJoseph Pusztay    Level: intermediate
702d0c080abSJoseph Pusztay 
703d0c080abSJoseph Pusztay    Notes:
704d0c080abSJoseph 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.
705d0c080abSJoseph Pusztay    These are named according to the file name template.
706d0c080abSJoseph Pusztay 
7073a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
708bcf0153eSBarry Smith    to be used during the `TS` integration.
709d0c080abSJoseph Pusztay 
710bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
711d0c080abSJoseph Pusztay @*/
712d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSolutionVTK(TS ts, PetscInt step, PetscReal ptime, Vec u, void *filenametemplate)
713d71ae5a4SJacob Faibussowitsch {
714d0c080abSJoseph Pusztay   char        filename[PETSC_MAX_PATH_LEN];
715d0c080abSJoseph Pusztay   PetscViewer viewer;
716d0c080abSJoseph Pusztay 
717d0c080abSJoseph Pusztay   PetscFunctionBegin;
718d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
7199566063dSJacob Faibussowitsch   PetscCall(PetscSNPrintf(filename, sizeof(filename), (const char *)filenametemplate, step));
7209566063dSJacob Faibussowitsch   PetscCall(PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts), filename, FILE_MODE_WRITE, &viewer));
7219566063dSJacob Faibussowitsch   PetscCall(VecView(u, viewer));
7229566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&viewer));
723d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
724d0c080abSJoseph Pusztay }
725d0c080abSJoseph Pusztay 
726d0c080abSJoseph Pusztay /*@C
727bcf0153eSBarry Smith    TSMonitorSolutionVTKDestroy - Destroy filename template string created for use with `TSMonitorSolutionVTK()`
728d0c080abSJoseph Pusztay 
729bcf0153eSBarry Smith    Not Collective
730d0c080abSJoseph Pusztay 
731d0c080abSJoseph Pusztay    Input Parameters:
73263a3b9bcSJacob Faibussowitsch .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03" PetscInt_FMT ")
733d0c080abSJoseph Pusztay 
734d0c080abSJoseph Pusztay    Level: intermediate
735d0c080abSJoseph Pusztay 
736d0c080abSJoseph Pusztay    Note:
737bcf0153eSBarry Smith    This function is normally passed to `TSMonitorSet()` along with `TSMonitorSolutionVTK()`.
738d0c080abSJoseph Pusztay 
739bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSMonitorSet()`, `TSMonitorSolutionVTK()`
740d0c080abSJoseph Pusztay @*/
741d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
742d71ae5a4SJacob Faibussowitsch {
743d0c080abSJoseph Pusztay   PetscFunctionBegin;
7449566063dSJacob Faibussowitsch   PetscCall(PetscFree(*(char **)filenametemplate));
745d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
746d0c080abSJoseph Pusztay }
747d0c080abSJoseph Pusztay 
748d0c080abSJoseph Pusztay /*@C
749bcf0153eSBarry Smith    TSMonitorLGSolution - Monitors progress of the `TS` solvers by plotting each component of the solution vector
750d0c080abSJoseph Pusztay        in a time based line graph
751d0c080abSJoseph Pusztay 
752bcf0153eSBarry Smith    Collective on ts
753d0c080abSJoseph Pusztay 
754d0c080abSJoseph Pusztay    Input Parameters:
755bcf0153eSBarry Smith +  ts - the `TS` context
756d0c080abSJoseph Pusztay .  step - current time-step
757d0c080abSJoseph Pusztay .  ptime - current time
758d0c080abSJoseph Pusztay .  u - current solution
759bcf0153eSBarry Smith -  dctx - the `TSMonitorLGCtx` object that contains all the options for the monitoring, this is created with `TSMonitorLGCtxCreate()`
760d0c080abSJoseph Pusztay 
761bcf0153eSBarry Smith    Options Database Key:
76267b8a455SSatish Balay .   -ts_monitor_lg_solution_variables - enable monitor of lg solution variables
763d0c080abSJoseph Pusztay 
764d0c080abSJoseph Pusztay    Level: intermediate
765d0c080abSJoseph Pusztay 
766d0c080abSJoseph Pusztay    Notes:
767d0c080abSJoseph Pusztay    Each process in a parallel run displays its component solutions in a separate window
768d0c080abSJoseph Pusztay 
7693a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
770bcf0153eSBarry Smith    to be used during the `TS` integration.
7713a61192cSBarry Smith 
772bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGCtxCreate()`, `TSMonitorLGCtxSetVariableNames()`, `TSMonitorLGCtxGetVariableNames()`,
773db781477SPatrick Sanan           `TSMonitorLGSetVariableNames()`, `TSMonitorLGGetVariableNames()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetDisplayVariables()`,
774db781477SPatrick Sanan           `TSMonitorLGCtxSetTransform()`, `TSMonitorLGSetTransform()`, `TSMonitorLGError()`, `TSMonitorLGSNESIterations()`, `TSMonitorLGKSPIterations()`,
775db781477SPatrick Sanan           `TSMonitorEnvelopeCtxCreate()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxDestroy()`, `TSMonitorEnvelop()`
776d0c080abSJoseph Pusztay @*/
777d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx)
778d71ae5a4SJacob Faibussowitsch {
779d0c080abSJoseph Pusztay   TSMonitorLGCtx     ctx = (TSMonitorLGCtx)dctx;
780d0c080abSJoseph Pusztay   const PetscScalar *yy;
781d0c080abSJoseph Pusztay   Vec                v;
782d0c080abSJoseph Pusztay 
783d0c080abSJoseph Pusztay   PetscFunctionBegin;
784d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
785d0c080abSJoseph Pusztay   if (!step) {
786d0c080abSJoseph Pusztay     PetscDrawAxis axis;
787d0c080abSJoseph Pusztay     PetscInt      dim;
7889566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
7899566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Solution as function of time", "Time", "Solution"));
790d0c080abSJoseph Pusztay     if (!ctx->names) {
791d0c080abSJoseph Pusztay       PetscBool flg;
792d0c080abSJoseph Pusztay       /* user provides names of variables to plot but no names has been set so assume names are integer values */
7939566063dSJacob Faibussowitsch       PetscCall(PetscOptionsHasName(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_monitor_lg_solution_variables", &flg));
794d0c080abSJoseph Pusztay       if (flg) {
795d0c080abSJoseph Pusztay         PetscInt i, n;
796d0c080abSJoseph Pusztay         char   **names;
7979566063dSJacob Faibussowitsch         PetscCall(VecGetSize(u, &n));
7989566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(n + 1, &names));
799d0c080abSJoseph Pusztay         for (i = 0; i < n; i++) {
8009566063dSJacob Faibussowitsch           PetscCall(PetscMalloc1(5, &names[i]));
80163a3b9bcSJacob Faibussowitsch           PetscCall(PetscSNPrintf(names[i], 5, "%" PetscInt_FMT, i));
802d0c080abSJoseph Pusztay         }
803d0c080abSJoseph Pusztay         names[n]   = NULL;
804d0c080abSJoseph Pusztay         ctx->names = names;
805d0c080abSJoseph Pusztay       }
806d0c080abSJoseph Pusztay     }
807d0c080abSJoseph Pusztay     if (ctx->names && !ctx->displaynames) {
808d0c080abSJoseph Pusztay       char    **displaynames;
809d0c080abSJoseph Pusztay       PetscBool flg;
8109566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u, &dim));
8119566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(dim + 1, &displaynames));
8129566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetStringArray(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_monitor_lg_solution_variables", displaynames, &dim, &flg));
8131baa6e33SBarry Smith       if (flg) PetscCall(TSMonitorLGCtxSetDisplayVariables(ctx, (const char *const *)displaynames));
8149566063dSJacob Faibussowitsch       PetscCall(PetscStrArrayDestroy(&displaynames));
815d0c080abSJoseph Pusztay     }
816d0c080abSJoseph Pusztay     if (ctx->displaynames) {
8179566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg, ctx->ndisplayvariables));
8189566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetLegend(ctx->lg, (const char *const *)ctx->displaynames));
819d0c080abSJoseph Pusztay     } else if (ctx->names) {
8209566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u, &dim));
8219566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg, dim));
8229566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetLegend(ctx->lg, (const char *const *)ctx->names));
823d0c080abSJoseph Pusztay     } else {
8249566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u, &dim));
8259566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg, dim));
826d0c080abSJoseph Pusztay     }
8279566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
828d0c080abSJoseph Pusztay   }
829d0c080abSJoseph Pusztay 
830d0c080abSJoseph Pusztay   if (!ctx->transform) v = u;
8319566063dSJacob Faibussowitsch   else PetscCall((*ctx->transform)(ctx->transformctx, u, &v));
8329566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(v, &yy));
833d0c080abSJoseph Pusztay   if (ctx->displaynames) {
834d0c080abSJoseph Pusztay     PetscInt i;
8359371c9d4SSatish Balay     for (i = 0; i < ctx->ndisplayvariables; i++) ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]);
8369566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, ctx->displayvalues));
837d0c080abSJoseph Pusztay   } else {
838d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
839d0c080abSJoseph Pusztay     PetscInt   i, n;
840d0c080abSJoseph Pusztay     PetscReal *yreal;
8419566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(v, &n));
8429566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &yreal));
843d0c080abSJoseph Pusztay     for (i = 0; i < n; i++) yreal[i] = PetscRealPart(yy[i]);
8449566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yreal));
8459566063dSJacob Faibussowitsch     PetscCall(PetscFree(yreal));
846d0c080abSJoseph Pusztay #else
8479566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yy));
848d0c080abSJoseph Pusztay #endif
849d0c080abSJoseph Pusztay   }
8509566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(v, &yy));
8519566063dSJacob Faibussowitsch   if (ctx->transform) PetscCall(VecDestroy(&v));
852d0c080abSJoseph Pusztay 
853d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
8549566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
8559566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
856d0c080abSJoseph Pusztay   }
857d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
858d0c080abSJoseph Pusztay }
859d0c080abSJoseph Pusztay 
860d0c080abSJoseph Pusztay /*@C
861d0c080abSJoseph Pusztay    TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
862d0c080abSJoseph Pusztay 
863bcf0153eSBarry Smith    Collective on ts
864d0c080abSJoseph Pusztay 
865d0c080abSJoseph Pusztay    Input Parameters:
866bcf0153eSBarry Smith +  ts - the `TS` context
867d0c080abSJoseph Pusztay -  names - the names of the components, final string must be NULL
868d0c080abSJoseph Pusztay 
869d0c080abSJoseph Pusztay    Level: intermediate
870d0c080abSJoseph Pusztay 
871d0c080abSJoseph Pusztay    Notes:
872bcf0153eSBarry Smith     If the `TS` object does not have a `TSMonitorLGCtx` associated with it then this function is ignored
873d0c080abSJoseph Pusztay 
874bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetVariableNames()`
875d0c080abSJoseph Pusztay @*/
876d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSetVariableNames(TS ts, const char *const *names)
877d71ae5a4SJacob Faibussowitsch {
878d0c080abSJoseph Pusztay   PetscInt i;
879d0c080abSJoseph Pusztay 
880d0c080abSJoseph Pusztay   PetscFunctionBegin;
881d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
882d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
8839566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i], names));
884d0c080abSJoseph Pusztay       break;
885d0c080abSJoseph Pusztay     }
886d0c080abSJoseph Pusztay   }
887d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
888d0c080abSJoseph Pusztay }
889d0c080abSJoseph Pusztay 
890d0c080abSJoseph Pusztay /*@C
891d0c080abSJoseph Pusztay    TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
892d0c080abSJoseph Pusztay 
893bcf0153eSBarry Smith    Collective on ctx
894d0c080abSJoseph Pusztay 
895d0c080abSJoseph Pusztay    Input Parameters:
896bcf0153eSBarry Smith +  ts - the `TS` context
897d0c080abSJoseph Pusztay -  names - the names of the components, final string must be NULL
898d0c080abSJoseph Pusztay 
899d0c080abSJoseph Pusztay    Level: intermediate
900d0c080abSJoseph Pusztay 
901bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGSetVariableNames()`
902d0c080abSJoseph Pusztay @*/
903d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx, const char *const *names)
904d71ae5a4SJacob Faibussowitsch {
905d0c080abSJoseph Pusztay   PetscFunctionBegin;
9069566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&ctx->names));
9079566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(names, &ctx->names));
908d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
909d0c080abSJoseph Pusztay }
910d0c080abSJoseph Pusztay 
911d0c080abSJoseph Pusztay /*@C
912d0c080abSJoseph Pusztay    TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot
913d0c080abSJoseph Pusztay 
914bcf0153eSBarry Smith    Collective on ts
915d0c080abSJoseph Pusztay 
916d0c080abSJoseph Pusztay    Input Parameter:
917bcf0153eSBarry Smith .  ts - the `TS` context
918d0c080abSJoseph Pusztay 
919d0c080abSJoseph Pusztay    Output Parameter:
920d0c080abSJoseph Pusztay .  names - the names of the components, final string must be NULL
921d0c080abSJoseph Pusztay 
922d0c080abSJoseph Pusztay    Level: intermediate
923d0c080abSJoseph Pusztay 
924bcf0153eSBarry Smith    Note:
925bcf0153eSBarry Smith     If the `TS` object does not have a `TSMonitorLGCtx` associated with it then this function is ignored
926d0c080abSJoseph Pusztay 
927bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`
928d0c080abSJoseph Pusztay @*/
929d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGGetVariableNames(TS ts, const char *const **names)
930d71ae5a4SJacob Faibussowitsch {
931d0c080abSJoseph Pusztay   PetscInt i;
932d0c080abSJoseph Pusztay 
933d0c080abSJoseph Pusztay   PetscFunctionBegin;
934d0c080abSJoseph Pusztay   *names = NULL;
935d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
936d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
937d0c080abSJoseph Pusztay       TSMonitorLGCtx ctx = (TSMonitorLGCtx)ts->monitorcontext[i];
938d0c080abSJoseph Pusztay       *names             = (const char *const *)ctx->names;
939d0c080abSJoseph Pusztay       break;
940d0c080abSJoseph Pusztay     }
941d0c080abSJoseph Pusztay   }
942d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
943d0c080abSJoseph Pusztay }
944d0c080abSJoseph Pusztay 
945d0c080abSJoseph Pusztay /*@C
946d0c080abSJoseph Pusztay    TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor
947d0c080abSJoseph Pusztay 
948bcf0153eSBarry Smith    Collective on ctx
949d0c080abSJoseph Pusztay 
950d0c080abSJoseph Pusztay    Input Parameters:
951bcf0153eSBarry Smith +  ctx - the `TSMonitorLG` context
952d0c080abSJoseph Pusztay -  displaynames - the names of the components, final string must be NULL
953d0c080abSJoseph Pusztay 
954d0c080abSJoseph Pusztay    Level: intermediate
955d0c080abSJoseph Pusztay 
956bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`
957d0c080abSJoseph Pusztay @*/
958d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx, const char *const *displaynames)
959d71ae5a4SJacob Faibussowitsch {
960d0c080abSJoseph Pusztay   PetscInt j = 0, k;
961d0c080abSJoseph Pusztay 
962d0c080abSJoseph Pusztay   PetscFunctionBegin;
963d0c080abSJoseph Pusztay   if (!ctx->names) PetscFunctionReturn(0);
9649566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&ctx->displaynames));
9659566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(displaynames, &ctx->displaynames));
966d0c080abSJoseph Pusztay   while (displaynames[j]) j++;
967d0c080abSJoseph Pusztay   ctx->ndisplayvariables = j;
9689566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx->ndisplayvariables, &ctx->displayvariables));
9699566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx->ndisplayvariables, &ctx->displayvalues));
970d0c080abSJoseph Pusztay   j = 0;
971d0c080abSJoseph Pusztay   while (displaynames[j]) {
972d0c080abSJoseph Pusztay     k = 0;
973d0c080abSJoseph Pusztay     while (ctx->names[k]) {
974d0c080abSJoseph Pusztay       PetscBool flg;
9759566063dSJacob Faibussowitsch       PetscCall(PetscStrcmp(displaynames[j], ctx->names[k], &flg));
976d0c080abSJoseph Pusztay       if (flg) {
977d0c080abSJoseph Pusztay         ctx->displayvariables[j] = k;
978d0c080abSJoseph Pusztay         break;
979d0c080abSJoseph Pusztay       }
980d0c080abSJoseph Pusztay       k++;
981d0c080abSJoseph Pusztay     }
982d0c080abSJoseph Pusztay     j++;
983d0c080abSJoseph Pusztay   }
984d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
985d0c080abSJoseph Pusztay }
986d0c080abSJoseph Pusztay 
987d0c080abSJoseph Pusztay /*@C
988d0c080abSJoseph Pusztay    TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor
989d0c080abSJoseph Pusztay 
990bcf0153eSBarry Smith    Collective on ts
991d0c080abSJoseph Pusztay 
992d0c080abSJoseph Pusztay    Input Parameters:
993bcf0153eSBarry Smith +  ts - the `TS` context
994d0c080abSJoseph Pusztay -  displaynames - the names of the components, final string must be NULL
995d0c080abSJoseph Pusztay 
996d0c080abSJoseph Pusztay    Level: intermediate
997d0c080abSJoseph Pusztay 
998bcf0153eSBarry Smith    Note:
999bcf0153eSBarry Smith     If the `TS` object does not have a `TSMonitorLGCtx` associated with it then this function is ignored
1000bcf0153eSBarry Smith 
1001bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`
1002d0c080abSJoseph Pusztay @*/
1003d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSetDisplayVariables(TS ts, const char *const *displaynames)
1004d71ae5a4SJacob Faibussowitsch {
1005d0c080abSJoseph Pusztay   PetscInt i;
1006d0c080abSJoseph Pusztay 
1007d0c080abSJoseph Pusztay   PetscFunctionBegin;
1008d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
1009d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
10109566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i], displaynames));
1011d0c080abSJoseph Pusztay       break;
1012d0c080abSJoseph Pusztay     }
1013d0c080abSJoseph Pusztay   }
1014d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1015d0c080abSJoseph Pusztay }
1016d0c080abSJoseph Pusztay 
1017d0c080abSJoseph Pusztay /*@C
1018d0c080abSJoseph Pusztay    TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed
1019d0c080abSJoseph Pusztay 
1020bcf0153eSBarry Smith    Collective on ts
1021d0c080abSJoseph Pusztay 
1022d0c080abSJoseph Pusztay    Input Parameters:
1023bcf0153eSBarry Smith +  ts - the `TS` context
1024d0c080abSJoseph Pusztay .  transform - the transform function
1025d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
1026d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
1027d0c080abSJoseph Pusztay 
1028d0c080abSJoseph Pusztay    Level: intermediate
1029d0c080abSJoseph Pusztay 
1030bcf0153eSBarry Smith    Note:
1031bcf0153eSBarry Smith     If the `TS` object does not have a `TSMonitorLGCtx` associated with it then this function is ignored
1032bcf0153eSBarry Smith 
1033bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`, `TSMonitorLGCtxSetTransform()`
1034d0c080abSJoseph Pusztay @*/
1035d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSetTransform(TS ts, PetscErrorCode (*transform)(void *, Vec, Vec *), PetscErrorCode (*destroy)(void *), void *tctx)
1036d71ae5a4SJacob Faibussowitsch {
1037d0c080abSJoseph Pusztay   PetscInt i;
1038d0c080abSJoseph Pusztay 
1039d0c080abSJoseph Pusztay   PetscFunctionBegin;
1040d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
104148a46eb9SPierre Jolivet     if (ts->monitor[i] == TSMonitorLGSolution) PetscCall(TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i], transform, destroy, tctx));
1042d0c080abSJoseph Pusztay   }
1043d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1044d0c080abSJoseph Pusztay }
1045d0c080abSJoseph Pusztay 
1046d0c080abSJoseph Pusztay /*@C
1047d0c080abSJoseph Pusztay    TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed
1048d0c080abSJoseph Pusztay 
1049bcf0153eSBarry Smith    Collective on ctx
1050d0c080abSJoseph Pusztay 
1051d0c080abSJoseph Pusztay    Input Parameters:
1052bcf0153eSBarry Smith +  ts - the `TS` context
1053d0c080abSJoseph Pusztay .  transform - the transform function
1054d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
1055d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
1056d0c080abSJoseph Pusztay 
1057d0c080abSJoseph Pusztay    Level: intermediate
1058d0c080abSJoseph Pusztay 
1059bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`, `TSMonitorLGSetTransform()`
1060d0c080abSJoseph Pusztay @*/
1061d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx, PetscErrorCode (*transform)(void *, Vec, Vec *), PetscErrorCode (*destroy)(void *), void *tctx)
1062d71ae5a4SJacob Faibussowitsch {
1063d0c080abSJoseph Pusztay   PetscFunctionBegin;
1064d0c080abSJoseph Pusztay   ctx->transform        = transform;
1065d0c080abSJoseph Pusztay   ctx->transformdestroy = destroy;
1066d0c080abSJoseph Pusztay   ctx->transformctx     = tctx;
1067d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1068d0c080abSJoseph Pusztay }
1069d0c080abSJoseph Pusztay 
1070d0c080abSJoseph Pusztay /*@C
1071bcf0153eSBarry Smith    TSMonitorLGError - Monitors progress of the `TS` solvers by plotting each component of the error
1072d0c080abSJoseph Pusztay        in a time based line graph
1073d0c080abSJoseph Pusztay 
1074bcf0153eSBarry Smith    Collective on ts
1075d0c080abSJoseph Pusztay 
1076d0c080abSJoseph Pusztay    Input Parameters:
1077bcf0153eSBarry Smith +  ts - the `TS` context
1078d0c080abSJoseph Pusztay .  step - current time-step
1079d0c080abSJoseph Pusztay .  ptime - current time
1080d0c080abSJoseph Pusztay .  u - current solution
1081bcf0153eSBarry Smith -  dctx - `TSMonitorLGCtx` object created with `TSMonitorLGCtxCreate()`
1082d0c080abSJoseph Pusztay 
1083bcf0153eSBarry Smith    Options Database Key:
10843a61192cSBarry Smith .  -ts_monitor_lg_error - create a graphical monitor of error history
10853a61192cSBarry Smith 
1086d0c080abSJoseph Pusztay    Level: intermediate
1087d0c080abSJoseph Pusztay 
1088d0c080abSJoseph Pusztay    Notes:
1089d0c080abSJoseph Pusztay     Each process in a parallel run displays its component errors in a separate window
1090d0c080abSJoseph Pusztay 
1091bcf0153eSBarry Smith    The user must provide the solution using `TSSetSolutionFunction()` to use this monitor.
1092d0c080abSJoseph Pusztay 
10933a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
10943a61192cSBarry Smith    to be used during the TS integration.
1095d0c080abSJoseph Pusztay 
1096bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
1097d0c080abSJoseph Pusztay @*/
1098d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGError(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy)
1099d71ae5a4SJacob Faibussowitsch {
1100d0c080abSJoseph Pusztay   TSMonitorLGCtx     ctx = (TSMonitorLGCtx)dummy;
1101d0c080abSJoseph Pusztay   const PetscScalar *yy;
1102d0c080abSJoseph Pusztay   Vec                y;
1103d0c080abSJoseph Pusztay 
1104d0c080abSJoseph Pusztay   PetscFunctionBegin;
1105d0c080abSJoseph Pusztay   if (!step) {
1106d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1107d0c080abSJoseph Pusztay     PetscInt      dim;
11089566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
11099566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Error in solution as function of time", "Time", "Error"));
11109566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(u, &dim));
11119566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSetDimension(ctx->lg, dim));
11129566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1113d0c080abSJoseph Pusztay   }
11149566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u, &y));
11159566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts, ptime, y));
11169566063dSJacob Faibussowitsch   PetscCall(VecAXPY(y, -1.0, u));
11179566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(y, &yy));
1118d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
1119d0c080abSJoseph Pusztay   {
1120d0c080abSJoseph Pusztay     PetscReal *yreal;
1121d0c080abSJoseph Pusztay     PetscInt   i, n;
11229566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(y, &n));
11239566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &yreal));
1124d0c080abSJoseph Pusztay     for (i = 0; i < n; i++) yreal[i] = PetscRealPart(yy[i]);
11259566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yreal));
11269566063dSJacob Faibussowitsch     PetscCall(PetscFree(yreal));
1127d0c080abSJoseph Pusztay   }
1128d0c080abSJoseph Pusztay #else
11299566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yy));
1130d0c080abSJoseph Pusztay #endif
11319566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(y, &yy));
11329566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&y));
1133d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
11349566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
11359566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1136d0c080abSJoseph Pusztay   }
1137d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1138d0c080abSJoseph Pusztay }
1139d0c080abSJoseph Pusztay 
1140d0c080abSJoseph Pusztay /*@C
1141bcf0153eSBarry Smith    TSMonitorSPSwarmSolution - Graphically displays phase plots of `DMSWARM` particles on a scatter plot
1142d0c080abSJoseph Pusztay 
1143d0c080abSJoseph Pusztay    Input Parameters:
1144bcf0153eSBarry Smith +  ts - the `TS` context
1145d0c080abSJoseph Pusztay .  step - current time-step
1146d0c080abSJoseph Pusztay .  ptime - current time
1147d0c080abSJoseph Pusztay .  u - current solution
1148bcf0153eSBarry Smith -  dctx - the `TSMonitorSPCtx` object that contains all the options for the monitoring, this is created with `TSMonitorSPCtxCreate()`
1149d0c080abSJoseph Pusztay 
1150bcf0153eSBarry Smith    Options Database Keys:
1151d7462660SMatthew Knepley + -ts_monitor_sp_swarm <n>          - Monitor the solution every n steps, or -1 for plotting only the final solution
1152d7462660SMatthew Knepley . -ts_monitor_sp_swarm_retain <n>   - Retain n old points so we can see the history, or -1 for all points
1153d7462660SMatthew Knepley - -ts_monitor_sp_swarm_phase <bool> - Plot in phase space, as opposed to coordinate space
1154d0c080abSJoseph Pusztay 
1155d0c080abSJoseph Pusztay    Level: intermediate
1156d0c080abSJoseph Pusztay 
11573a61192cSBarry Smith    Notes:
11583a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
1159bcf0153eSBarry Smith    to be used during the `TS` integration.
11603a61192cSBarry Smith 
1161bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitoSet()`, `DMSWARM`, `TSMonitorSPCtxCreate()`
1162d0c080abSJoseph Pusztay @*/
1163d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSPSwarmSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx)
1164d71ae5a4SJacob Faibussowitsch {
1165d0c080abSJoseph Pusztay   TSMonitorSPCtx     ctx = (TSMonitorSPCtx)dctx;
1166f98b2f00SMatthew G. Knepley   PetscDraw          draw;
1167d7462660SMatthew Knepley   DM                 dm, cdm;
1168d0c080abSJoseph Pusztay   const PetscScalar *yy;
1169d0c080abSJoseph Pusztay   PetscInt           Np, p, dim = 2;
1170d0c080abSJoseph Pusztay 
1171d0c080abSJoseph Pusztay   PetscFunctionBegin;
1172d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1173d0c080abSJoseph Pusztay   if (!step) {
1174d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1175ab43fcacSJoe Pusztay     PetscReal     dmboxlower[2], dmboxupper[2];
1176f98b2f00SMatthew G. Knepley 
11779566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &dm));
11789566063dSJacob Faibussowitsch     PetscCall(DMGetDimension(dm, &dim));
11793c633725SBarry Smith     PetscCheck(dim == 2, PETSC_COMM_SELF, PETSC_ERR_SUP, "Monitor only supports two dimensional fields");
11809566063dSJacob Faibussowitsch     PetscCall(DMSwarmGetCellDM(dm, &cdm));
11819566063dSJacob Faibussowitsch     PetscCall(DMGetBoundingBox(cdm, dmboxlower, dmboxupper));
11829566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(u, &Np));
1183d7462660SMatthew Knepley     Np /= dim * 2;
11849566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPGetAxis(ctx->sp, &axis));
11858c87cf4dSdanfinn     if (ctx->phase) {
11869566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(axis, "Particles", "X", "V"));
11879566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], -5, 5));
11888c87cf4dSdanfinn     } else {
11899566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(axis, "Particles", "X", "Y"));
11909566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], dmboxlower[1], dmboxupper[1]));
11918c87cf4dSdanfinn     }
11929566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetHoldLimits(axis, PETSC_TRUE));
11939566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPReset(ctx->sp));
1194d0c080abSJoseph Pusztay   }
11959566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(u, &Np));
1196d7462660SMatthew Knepley   Np /= dim * 2;
1197d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
11989566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPGetDraw(ctx->sp, &draw));
119948a46eb9SPierre Jolivet     if ((ctx->retain == 0) || (ctx->retain > 0 && !(step % ctx->retain))) PetscCall(PetscDrawClear(draw));
12009566063dSJacob Faibussowitsch     PetscCall(PetscDrawFlush(draw));
12019566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPReset(ctx->sp));
1202f98b2f00SMatthew G. Knepley     PetscCall(VecGetArrayRead(u, &yy));
1203f98b2f00SMatthew G. Knepley     for (p = 0; p < Np; ++p) {
1204f98b2f00SMatthew G. Knepley       PetscReal x, y;
1205f98b2f00SMatthew G. Knepley 
1206f98b2f00SMatthew G. Knepley       if (ctx->phase) {
1207f98b2f00SMatthew G. Knepley         x = PetscRealPart(yy[p * dim * 2]);
1208f98b2f00SMatthew G. Knepley         y = PetscRealPart(yy[p * dim * 2 + dim]);
1209f98b2f00SMatthew G. Knepley       } else {
1210f98b2f00SMatthew G. Knepley         x = PetscRealPart(yy[p * dim * 2]);
1211f98b2f00SMatthew G. Knepley         y = PetscRealPart(yy[p * dim * 2 + 1]);
1212f98b2f00SMatthew G. Knepley       }
1213f98b2f00SMatthew G. Knepley       PetscCall(PetscDrawSPAddPoint(ctx->sp, &x, &y));
1214f98b2f00SMatthew G. Knepley     }
1215f98b2f00SMatthew G. Knepley     PetscCall(VecRestoreArrayRead(u, &yy));
12169566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPDraw(ctx->sp, PETSC_FALSE));
12179566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPSave(ctx->sp));
1218d0c080abSJoseph Pusztay   }
1219d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1220d0c080abSJoseph Pusztay }
1221d0c080abSJoseph Pusztay 
1222d0c080abSJoseph Pusztay /*@C
1223bcf0153eSBarry Smith    TSMonitorError - Monitors progress of the `TS` solvers by printing the 2 norm of the error at each timestep
1224d0c080abSJoseph Pusztay 
1225bcf0153eSBarry Smith    Collective on ts
1226d0c080abSJoseph Pusztay 
1227d0c080abSJoseph Pusztay    Input Parameters:
1228bcf0153eSBarry Smith +  ts - the `TS` context
1229d0c080abSJoseph Pusztay .  step - current time-step
1230d0c080abSJoseph Pusztay .  ptime - current time
1231d0c080abSJoseph Pusztay .  u - current solution
1232d0c080abSJoseph Pusztay -  dctx - unused context
1233d0c080abSJoseph Pusztay 
1234bcf0153eSBarry Smith    Options Database Key:
1235bcf0153eSBarry Smith .  -ts_monitor_error - create a graphical monitor of error history
1236bcf0153eSBarry Smith 
1237d0c080abSJoseph Pusztay    Level: intermediate
1238d0c080abSJoseph Pusztay 
12393a61192cSBarry Smith    Notes:
12403a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
1241bcf0153eSBarry Smith    to be used during the `TS` integration.
12423a61192cSBarry Smith 
1243bcf0153eSBarry Smith    The user must provide the solution using `TSSetSolutionFunction()` to use this monitor.
1244d0c080abSJoseph Pusztay 
1245bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
1246d0c080abSJoseph Pusztay @*/
1247d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorError(TS ts, PetscInt step, PetscReal ptime, Vec u, PetscViewerAndFormat *vf)
1248d71ae5a4SJacob Faibussowitsch {
124907eaae0cSMatthew G. Knepley   DM        dm;
125007eaae0cSMatthew G. Knepley   PetscDS   ds = NULL;
125107eaae0cSMatthew G. Knepley   PetscInt  Nf = -1, f;
1252d0c080abSJoseph Pusztay   PetscBool flg;
1253d0c080abSJoseph Pusztay 
1254d0c080abSJoseph Pusztay   PetscFunctionBegin;
12559566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
12569566063dSJacob Faibussowitsch   if (dm) PetscCall(DMGetDS(dm, &ds));
12579566063dSJacob Faibussowitsch   if (ds) PetscCall(PetscDSGetNumFields(ds, &Nf));
125807eaae0cSMatthew G. Knepley   if (Nf <= 0) {
125907eaae0cSMatthew G. Knepley     Vec       y;
126007eaae0cSMatthew G. Knepley     PetscReal nrm;
126107eaae0cSMatthew G. Knepley 
12629566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u, &y));
12639566063dSJacob Faibussowitsch     PetscCall(TSComputeSolutionFunction(ts, ptime, y));
12649566063dSJacob Faibussowitsch     PetscCall(VecAXPY(y, -1.0, u));
12659566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer, PETSCVIEWERASCII, &flg));
1266d0c080abSJoseph Pusztay     if (flg) {
12679566063dSJacob Faibussowitsch       PetscCall(VecNorm(y, NORM_2, &nrm));
12689566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vf->viewer, "2-norm of error %g\n", (double)nrm));
1269d0c080abSJoseph Pusztay     }
12709566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer, PETSCVIEWERDRAW, &flg));
12711baa6e33SBarry Smith     if (flg) PetscCall(VecView(y, vf->viewer));
12729566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&y));
127307eaae0cSMatthew G. Knepley   } else {
127407eaae0cSMatthew G. Knepley     PetscErrorCode (**exactFuncs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx);
127507eaae0cSMatthew G. Knepley     void    **ctxs;
127607eaae0cSMatthew G. Knepley     Vec       v;
127707eaae0cSMatthew G. Knepley     PetscReal ferrors[1];
127807eaae0cSMatthew G. Knepley 
12799566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(Nf, &exactFuncs, Nf, &ctxs));
12809566063dSJacob Faibussowitsch     for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(ds, f, &exactFuncs[f], &ctxs[f]));
12819566063dSJacob Faibussowitsch     PetscCall(DMComputeL2FieldDiff(dm, ptime, exactFuncs, ctxs, u, ferrors));
12829566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Timestep: %04d time = %-8.4g \t L_2 Error: [", (int)step, (double)ptime));
128307eaae0cSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
12849566063dSJacob Faibussowitsch       if (f > 0) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ", "));
12859566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%2.3g", (double)ferrors[f]));
128607eaae0cSMatthew G. Knepley     }
12879566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "]\n"));
128807eaae0cSMatthew G. Knepley 
12899566063dSJacob Faibussowitsch     PetscCall(VecViewFromOptions(u, NULL, "-sol_vec_view"));
129007eaae0cSMatthew G. Knepley 
12919566063dSJacob Faibussowitsch     PetscCall(PetscOptionsHasName(NULL, NULL, "-exact_vec_view", &flg));
129207eaae0cSMatthew G. Knepley     if (flg) {
12939566063dSJacob Faibussowitsch       PetscCall(DMGetGlobalVector(dm, &v));
12949566063dSJacob Faibussowitsch       PetscCall(DMProjectFunction(dm, ptime, exactFuncs, ctxs, INSERT_ALL_VALUES, v));
12959566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetName((PetscObject)v, "Exact Solution"));
12969566063dSJacob Faibussowitsch       PetscCall(VecViewFromOptions(v, NULL, "-exact_vec_view"));
12979566063dSJacob Faibussowitsch       PetscCall(DMRestoreGlobalVector(dm, &v));
129807eaae0cSMatthew G. Knepley     }
12999566063dSJacob Faibussowitsch     PetscCall(PetscFree2(exactFuncs, ctxs));
130007eaae0cSMatthew G. Knepley   }
1301d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1302d0c080abSJoseph Pusztay }
1303d0c080abSJoseph Pusztay 
1304d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSNESIterations(TS ts, PetscInt n, PetscReal ptime, Vec v, void *monctx)
1305d71ae5a4SJacob Faibussowitsch {
1306d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx)monctx;
1307d0c080abSJoseph Pusztay   PetscReal      x   = ptime, y;
1308d0c080abSJoseph Pusztay   PetscInt       its;
1309d0c080abSJoseph Pusztay 
1310d0c080abSJoseph Pusztay   PetscFunctionBegin;
1311d0c080abSJoseph Pusztay   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1312d0c080abSJoseph Pusztay   if (!n) {
1313d0c080abSJoseph Pusztay     PetscDrawAxis axis;
13149566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
13159566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Nonlinear iterations as function of time", "Time", "SNES Iterations"));
13169566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1317d0c080abSJoseph Pusztay     ctx->snes_its = 0;
1318d0c080abSJoseph Pusztay   }
13199566063dSJacob Faibussowitsch   PetscCall(TSGetSNESIterations(ts, &its));
1320d0c080abSJoseph Pusztay   y = its - ctx->snes_its;
13219566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg, &x, &y));
1322d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
13239566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
13249566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1325d0c080abSJoseph Pusztay   }
1326d0c080abSJoseph Pusztay   ctx->snes_its = its;
1327d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1328d0c080abSJoseph Pusztay }
1329d0c080abSJoseph Pusztay 
1330d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGKSPIterations(TS ts, PetscInt n, PetscReal ptime, Vec v, void *monctx)
1331d71ae5a4SJacob Faibussowitsch {
1332d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx)monctx;
1333d0c080abSJoseph Pusztay   PetscReal      x   = ptime, y;
1334d0c080abSJoseph Pusztay   PetscInt       its;
1335d0c080abSJoseph Pusztay 
1336d0c080abSJoseph Pusztay   PetscFunctionBegin;
1337d0c080abSJoseph Pusztay   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1338d0c080abSJoseph Pusztay   if (!n) {
1339d0c080abSJoseph Pusztay     PetscDrawAxis axis;
13409566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis));
13419566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Linear iterations as function of time", "Time", "KSP Iterations"));
13429566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1343d0c080abSJoseph Pusztay     ctx->ksp_its = 0;
1344d0c080abSJoseph Pusztay   }
13459566063dSJacob Faibussowitsch   PetscCall(TSGetKSPIterations(ts, &its));
1346d0c080abSJoseph Pusztay   y = its - ctx->ksp_its;
13479566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg, &x, &y));
1348d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
13499566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
13509566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1351d0c080abSJoseph Pusztay   }
1352d0c080abSJoseph Pusztay   ctx->ksp_its = its;
1353d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1354d0c080abSJoseph Pusztay }
1355d0c080abSJoseph Pusztay 
1356d0c080abSJoseph Pusztay /*@C
1357bcf0153eSBarry Smith    TSMonitorEnvelopeCtxCreate - Creates a context for use with `TSMonitorEnvelope()`
1358d0c080abSJoseph Pusztay 
1359bcf0153eSBarry Smith    Collective on ts
1360d0c080abSJoseph Pusztay 
1361d0c080abSJoseph Pusztay    Input Parameters:
1362bcf0153eSBarry Smith .  ts  - the `TS` solver object
1363d0c080abSJoseph Pusztay 
1364d0c080abSJoseph Pusztay    Output Parameter:
1365d0c080abSJoseph Pusztay .  ctx - the context
1366d0c080abSJoseph Pusztay 
1367d0c080abSJoseph Pusztay    Level: intermediate
1368d0c080abSJoseph Pusztay 
1369bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorLGTimeStep()`, `TSMonitorSet()`, `TSMonitorLGSolution()`, `TSMonitorLGError()`
1370d0c080abSJoseph Pusztay @*/
1371d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorEnvelopeCtxCreate(TS ts, TSMonitorEnvelopeCtx *ctx)
1372d71ae5a4SJacob Faibussowitsch {
1373d0c080abSJoseph Pusztay   PetscFunctionBegin;
13749566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
1375d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1376d0c080abSJoseph Pusztay }
1377d0c080abSJoseph Pusztay 
1378d0c080abSJoseph Pusztay /*@C
1379d0c080abSJoseph Pusztay    TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution
1380d0c080abSJoseph Pusztay 
1381bcf0153eSBarry Smith    Collective on ts
1382d0c080abSJoseph Pusztay 
1383d0c080abSJoseph Pusztay    Input Parameters:
1384d0c080abSJoseph Pusztay +  ts - the TS context
1385d0c080abSJoseph Pusztay .  step - current time-step
1386d0c080abSJoseph Pusztay .  ptime - current time
1387d0c080abSJoseph Pusztay .  u  - current solution
1388d0c080abSJoseph Pusztay -  dctx - the envelope context
1389d0c080abSJoseph Pusztay 
1390bcf0153eSBarry Smith    Options Database Key:
139167b8a455SSatish Balay .  -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time
1392d0c080abSJoseph Pusztay 
1393d0c080abSJoseph Pusztay    Level: intermediate
1394d0c080abSJoseph Pusztay 
1395d0c080abSJoseph Pusztay    Notes:
1396bcf0153eSBarry Smith    After a solve you can use `TSMonitorEnvelopeGetBounds()` to access the envelope
13973a61192cSBarry Smith 
13983a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
1399bcf0153eSBarry Smith    to be used during the `TS` integration.
1400d0c080abSJoseph Pusztay 
1401bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxCreate()`
1402d0c080abSJoseph Pusztay @*/
1403d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorEnvelope(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx)
1404d71ae5a4SJacob Faibussowitsch {
1405d0c080abSJoseph Pusztay   TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx;
1406d0c080abSJoseph Pusztay 
1407d0c080abSJoseph Pusztay   PetscFunctionBegin;
1408d0c080abSJoseph Pusztay   if (!ctx->max) {
14099566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u, &ctx->max));
14109566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u, &ctx->min));
14119566063dSJacob Faibussowitsch     PetscCall(VecCopy(u, ctx->max));
14129566063dSJacob Faibussowitsch     PetscCall(VecCopy(u, ctx->min));
1413d0c080abSJoseph Pusztay   } else {
14149566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMax(ctx->max, u, ctx->max));
14159566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMin(ctx->min, u, ctx->min));
1416d0c080abSJoseph Pusztay   }
1417d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1418d0c080abSJoseph Pusztay }
1419d0c080abSJoseph Pusztay 
1420d0c080abSJoseph Pusztay /*@C
1421d0c080abSJoseph Pusztay    TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution
1422d0c080abSJoseph Pusztay 
1423bcf0153eSBarry Smith    Collective on ts
1424d0c080abSJoseph Pusztay 
1425d0c080abSJoseph Pusztay    Input Parameter:
1426bcf0153eSBarry Smith .  ts - the `TS` context
1427d0c080abSJoseph Pusztay 
1428d8d19677SJose E. Roman    Output Parameters:
1429d0c080abSJoseph Pusztay +  max - the maximum values
1430d0c080abSJoseph Pusztay -  min - the minimum values
1431d0c080abSJoseph Pusztay 
1432d0c080abSJoseph Pusztay    Notes:
1433bcf0153eSBarry Smith     If the `TS` does not have a `TSMonitorEnvelopeCtx` associated with it then this function is ignored
1434d0c080abSJoseph Pusztay 
1435d0c080abSJoseph Pusztay    Level: intermediate
1436d0c080abSJoseph Pusztay 
1437bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSMonitorEnvelopeCtx`, `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`
1438d0c080abSJoseph Pusztay @*/
1439d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorEnvelopeGetBounds(TS ts, Vec *max, Vec *min)
1440d71ae5a4SJacob Faibussowitsch {
1441d0c080abSJoseph Pusztay   PetscInt i;
1442d0c080abSJoseph Pusztay 
1443d0c080abSJoseph Pusztay   PetscFunctionBegin;
1444d0c080abSJoseph Pusztay   if (max) *max = NULL;
1445d0c080abSJoseph Pusztay   if (min) *min = NULL;
1446d0c080abSJoseph Pusztay   for (i = 0; i < ts->numbermonitors; i++) {
1447d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorEnvelope) {
1448d0c080abSJoseph Pusztay       TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)ts->monitorcontext[i];
1449d0c080abSJoseph Pusztay       if (max) *max = ctx->max;
1450d0c080abSJoseph Pusztay       if (min) *min = ctx->min;
1451d0c080abSJoseph Pusztay       break;
1452d0c080abSJoseph Pusztay     }
1453d0c080abSJoseph Pusztay   }
1454d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1455d0c080abSJoseph Pusztay }
1456d0c080abSJoseph Pusztay 
1457d0c080abSJoseph Pusztay /*@C
1458bcf0153eSBarry Smith    TSMonitorEnvelopeCtxDestroy - Destroys a context that was created  with `TSMonitorEnvelopeCtxCreate()`.
1459d0c080abSJoseph Pusztay 
1460bcf0153eSBarry Smith    Collective on ctx
1461d0c080abSJoseph Pusztay 
1462d0c080abSJoseph Pusztay    Input Parameter:
1463d0c080abSJoseph Pusztay .  ctx - the monitor context
1464d0c080abSJoseph Pusztay 
1465d0c080abSJoseph Pusztay    Level: intermediate
1466d0c080abSJoseph Pusztay 
1467bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorLGCtxCreate()`, `TSMonitorSet()`, `TSMonitorLGTimeStep()`
1468d0c080abSJoseph Pusztay @*/
1469d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx)
1470d71ae5a4SJacob Faibussowitsch {
1471d0c080abSJoseph Pusztay   PetscFunctionBegin;
14729566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ctx)->min));
14739566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ctx)->max));
14749566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
1475d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1476d0c080abSJoseph Pusztay }
1477d0c080abSJoseph Pusztay 
1478d0c080abSJoseph Pusztay /*@C
1479bcf0153eSBarry Smith   TSDMSwarmMonitorMoments - Monitors the first three moments of a `DMSWARM` being evolved by the `TS`
1480d0c080abSJoseph Pusztay 
1481d0c080abSJoseph Pusztay   Not collective
1482d0c080abSJoseph Pusztay 
1483d0c080abSJoseph Pusztay   Input Parameters:
1484bcf0153eSBarry Smith + ts   - the `TS` context
1485d0c080abSJoseph Pusztay . step - current timestep
1486d0c080abSJoseph Pusztay . t    - current time
1487d0c080abSJoseph Pusztay . u    - current solution
1488d0c080abSJoseph Pusztay - ctx  - not used
1489d0c080abSJoseph Pusztay 
1490bcf0153eSBarry Smith   Options Database Key:
149167b8a455SSatish Balay . -ts_dmswarm_monitor_moments - Monitor moments of particle distribution
1492d0c080abSJoseph Pusztay 
1493d0c080abSJoseph Pusztay   Level: intermediate
1494d0c080abSJoseph Pusztay 
1495d0c080abSJoseph Pusztay   Notes:
1496bcf0153eSBarry Smith   This requires a `DMSWARM` be attached to the `TS`.
1497d0c080abSJoseph Pusztay 
14983a61192cSBarry Smith   This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
14993a61192cSBarry Smith   to be used during the TS integration.
15003a61192cSBarry Smith 
1501bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `DMSWARM`
1502d0c080abSJoseph Pusztay @*/
1503d71ae5a4SJacob Faibussowitsch PetscErrorCode TSDMSwarmMonitorMoments(TS ts, PetscInt step, PetscReal t, Vec U, PetscViewerAndFormat *vf)
1504d71ae5a4SJacob Faibussowitsch {
1505d0c080abSJoseph Pusztay   DM                 sw;
1506d0c080abSJoseph Pusztay   const PetscScalar *u;
1507d0c080abSJoseph Pusztay   PetscReal          m = 1.0, totE = 0., totMom[3] = {0., 0., 0.};
1508d0c080abSJoseph Pusztay   PetscInt           dim, d, Np, p;
1509d0c080abSJoseph Pusztay   MPI_Comm           comm;
1510d0c080abSJoseph Pusztay 
1511d0c080abSJoseph Pusztay   PetscFunctionBeginUser;
15129566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &sw));
1513d0c080abSJoseph Pusztay   if (!sw || step % ts->monitorFrequency != 0) PetscFunctionReturn(0);
15149566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)ts, &comm));
15159566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(sw, &dim));
15169566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(U, &Np));
1517d0c080abSJoseph Pusztay   Np /= dim;
15189566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U, &u));
1519d0c080abSJoseph Pusztay   for (p = 0; p < Np; ++p) {
1520d0c080abSJoseph Pusztay     for (d = 0; d < dim; ++d) {
1521d0c080abSJoseph Pusztay       totE += PetscRealPart(u[p * dim + d] * u[p * dim + d]);
1522d0c080abSJoseph Pusztay       totMom[d] += PetscRealPart(u[p * dim + d]);
1523d0c080abSJoseph Pusztay     }
1524d0c080abSJoseph Pusztay   }
15259566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U, &u));
1526d0c080abSJoseph Pusztay   for (d = 0; d < dim; ++d) totMom[d] *= m;
1527d0c080abSJoseph Pusztay   totE *= 0.5 * m;
152863a3b9bcSJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "Step %4" PetscInt_FMT " Total Energy: %10.8lf", step, (double)totE));
152963a3b9bcSJacob Faibussowitsch   for (d = 0; d < dim; ++d) PetscCall(PetscPrintf(comm, "    Total Momentum %c: %10.8lf", (char)('x' + d), (double)totMom[d]));
15309566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "\n"));
1531d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1532d0c080abSJoseph Pusztay }
1533