xref: /petsc/src/ts/interface/tsmon.c (revision c2e3fba1fe1cda7e6350bbca19c4ed35ce95940a)
1d0c080abSJoseph Pusztay #include <petsc/private/tsimpl.h>        /*I "petscts.h"  I*/
2d0c080abSJoseph Pusztay #include <petscdm.h>
307eaae0cSMatthew G. Knepley #include <petscds.h>
4ab43fcacSJoe Pusztay #include <petscdmswarm.h>
5d0c080abSJoseph Pusztay #include <petscdraw.h>
6d0c080abSJoseph Pusztay 
7d0c080abSJoseph Pusztay /*@C
8d0c080abSJoseph Pusztay    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()
9d0c080abSJoseph Pusztay 
10d0c080abSJoseph Pusztay    Collective on TS
11d0c080abSJoseph Pusztay 
12d0c080abSJoseph Pusztay    Input Parameters:
13d0c080abSJoseph Pusztay +  ts - time stepping context obtained from TSCreate()
14d0c080abSJoseph Pusztay .  step - step number that has just completed
15d0c080abSJoseph Pusztay .  ptime - model time of the state
16d0c080abSJoseph Pusztay -  u - state at the current model time
17d0c080abSJoseph Pusztay 
18d0c080abSJoseph Pusztay    Notes:
19d0c080abSJoseph Pusztay    TSMonitor() is typically used automatically within the time stepping implementations.
20d0c080abSJoseph Pusztay    Users would almost never call this routine directly.
21d0c080abSJoseph Pusztay 
22d0c080abSJoseph Pusztay    A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions
23d0c080abSJoseph Pusztay 
24d0c080abSJoseph Pusztay    Level: developer
25d0c080abSJoseph Pusztay 
26d0c080abSJoseph Pusztay @*/
27d0c080abSJoseph Pusztay PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u)
28d0c080abSJoseph Pusztay {
29d0c080abSJoseph Pusztay   DM             dm;
30d0c080abSJoseph Pusztay   PetscInt       i,n = ts->numbermonitors;
31d0c080abSJoseph Pusztay 
32d0c080abSJoseph Pusztay   PetscFunctionBegin;
33d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
34d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
35d0c080abSJoseph Pusztay 
369566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
379566063dSJacob Faibussowitsch   PetscCall(DMSetOutputSequenceNumber(dm,step,ptime));
38d0c080abSJoseph Pusztay 
399566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(u));
40d0c080abSJoseph Pusztay   for (i=0; i<n; i++) {
419566063dSJacob Faibussowitsch     PetscCall((*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]));
42d0c080abSJoseph Pusztay   }
439566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(u));
44d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
45d0c080abSJoseph Pusztay }
46d0c080abSJoseph Pusztay 
47d0c080abSJoseph Pusztay /*@C
48d0c080abSJoseph Pusztay    TSMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
49d0c080abSJoseph Pusztay 
50d0c080abSJoseph Pusztay    Collective on TS
51d0c080abSJoseph Pusztay 
52d0c080abSJoseph Pusztay    Input Parameters:
53d0c080abSJoseph Pusztay +  ts - TS object you wish to monitor
54d0c080abSJoseph Pusztay .  name - the monitor type one is seeking
55d0c080abSJoseph Pusztay .  help - message indicating what monitoring is done
56d0c080abSJoseph Pusztay .  manual - manual page for the monitor
57d0c080abSJoseph Pusztay .  monitor - the monitor function
58d0c080abSJoseph Pusztay -  monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the TS or PetscViewer objects
59d0c080abSJoseph Pusztay 
60d0c080abSJoseph Pusztay    Level: developer
61d0c080abSJoseph Pusztay 
62db781477SPatrick Sanan .seealso: `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
63db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
64db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
65db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
66*c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
67db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
68db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
69d0c080abSJoseph Pusztay @*/
70d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorSetFromOptions(TS ts,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(TS,PetscViewerAndFormat*))
71d0c080abSJoseph Pusztay {
72d0c080abSJoseph Pusztay   PetscViewer       viewer;
73d0c080abSJoseph Pusztay   PetscViewerFormat format;
74d0c080abSJoseph Pusztay   PetscBool         flg;
75d0c080abSJoseph Pusztay 
76d0c080abSJoseph Pusztay   PetscFunctionBegin;
779566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts),((PetscObject) ts)->options,((PetscObject)ts)->prefix,name,&viewer,&format,&flg));
78d0c080abSJoseph Pusztay   if (flg) {
79d0c080abSJoseph Pusztay     PetscViewerAndFormat *vf;
809566063dSJacob Faibussowitsch     PetscCall(PetscViewerAndFormatCreate(viewer,format,&vf));
819566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject)viewer));
82d0c080abSJoseph Pusztay     if (monitorsetup) {
839566063dSJacob Faibussowitsch       PetscCall((*monitorsetup)(ts,vf));
84d0c080abSJoseph Pusztay     }
859566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts,(PetscErrorCode (*)(TS,PetscInt,PetscReal,Vec,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy));
86d0c080abSJoseph Pusztay   }
87d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
88d0c080abSJoseph Pusztay }
89d0c080abSJoseph Pusztay 
90d0c080abSJoseph Pusztay /*@C
91d0c080abSJoseph Pusztay    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
92d0c080abSJoseph Pusztay    timestep to display the iteration's  progress.
93d0c080abSJoseph Pusztay 
94d0c080abSJoseph Pusztay    Logically Collective on TS
95d0c080abSJoseph Pusztay 
96d0c080abSJoseph Pusztay    Input Parameters:
97d0c080abSJoseph Pusztay +  ts - the TS context obtained from TSCreate()
98d0c080abSJoseph Pusztay .  monitor - monitoring routine
99d0c080abSJoseph Pusztay .  mctx - [optional] user-defined context for private data for the
100d0c080abSJoseph Pusztay              monitor routine (use NULL if no context is desired)
101d0c080abSJoseph Pusztay -  monitordestroy - [optional] routine that frees monitor context
102d0c080abSJoseph Pusztay           (may be NULL)
103d0c080abSJoseph Pusztay 
104d0c080abSJoseph Pusztay    Calling sequence of monitor:
105d0c080abSJoseph Pusztay $    PetscErrorCode monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
106d0c080abSJoseph Pusztay 
107d0c080abSJoseph Pusztay +    ts - the TS context
108d0c080abSJoseph 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)
109d0c080abSJoseph Pusztay .    time - current time
110d0c080abSJoseph Pusztay .    u - current iterate
111d0c080abSJoseph Pusztay -    mctx - [optional] monitoring context
112d0c080abSJoseph Pusztay 
113d0c080abSJoseph Pusztay    Notes:
114d0c080abSJoseph Pusztay    This routine adds an additional monitor to the list of monitors that
115d0c080abSJoseph Pusztay    already has been loaded.
116d0c080abSJoseph Pusztay 
117d0c080abSJoseph Pusztay    Fortran Notes:
118d0c080abSJoseph Pusztay     Only a single monitor function can be set for each TS object
119d0c080abSJoseph Pusztay 
120d0c080abSJoseph Pusztay    Level: intermediate
121d0c080abSJoseph Pusztay 
122db781477SPatrick Sanan .seealso: `TSMonitorDefault()`, `TSMonitorCancel()`
123d0c080abSJoseph Pusztay @*/
124d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**))
125d0c080abSJoseph Pusztay {
126d0c080abSJoseph Pusztay   PetscInt       i;
127d0c080abSJoseph Pusztay   PetscBool      identical;
128d0c080abSJoseph Pusztay 
129d0c080abSJoseph Pusztay   PetscFunctionBegin;
130d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
131d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors;i++) {
1329566063dSJacob Faibussowitsch     PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical));
133d0c080abSJoseph Pusztay     if (identical) PetscFunctionReturn(0);
134d0c080abSJoseph Pusztay   }
1353c633725SBarry Smith   PetscCheck(ts->numbermonitors < MAXTSMONITORS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
136d0c080abSJoseph Pusztay   ts->monitor[ts->numbermonitors]          = monitor;
137d0c080abSJoseph Pusztay   ts->monitordestroy[ts->numbermonitors]   = mdestroy;
138d0c080abSJoseph Pusztay   ts->monitorcontext[ts->numbermonitors++] = (void*)mctx;
139d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
140d0c080abSJoseph Pusztay }
141d0c080abSJoseph Pusztay 
142d0c080abSJoseph Pusztay /*@C
143d0c080abSJoseph Pusztay    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
144d0c080abSJoseph Pusztay 
145d0c080abSJoseph Pusztay    Logically Collective on TS
146d0c080abSJoseph Pusztay 
147d0c080abSJoseph Pusztay    Input Parameters:
148d0c080abSJoseph Pusztay .  ts - the TS context obtained from TSCreate()
149d0c080abSJoseph Pusztay 
150d0c080abSJoseph Pusztay    Notes:
151d0c080abSJoseph Pusztay    There is no way to remove a single, specific monitor.
152d0c080abSJoseph Pusztay 
153d0c080abSJoseph Pusztay    Level: intermediate
154d0c080abSJoseph Pusztay 
155db781477SPatrick Sanan .seealso: `TSMonitorDefault()`, `TSMonitorSet()`
156d0c080abSJoseph Pusztay @*/
157d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorCancel(TS ts)
158d0c080abSJoseph Pusztay {
159d0c080abSJoseph Pusztay   PetscInt       i;
160d0c080abSJoseph Pusztay 
161d0c080abSJoseph Pusztay   PetscFunctionBegin;
162d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
163d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
164d0c080abSJoseph Pusztay     if (ts->monitordestroy[i]) {
1659566063dSJacob Faibussowitsch       PetscCall((*ts->monitordestroy[i])(&ts->monitorcontext[i]));
166d0c080abSJoseph Pusztay     }
167d0c080abSJoseph Pusztay   }
168d0c080abSJoseph Pusztay   ts->numbermonitors = 0;
169d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
170d0c080abSJoseph Pusztay }
171d0c080abSJoseph Pusztay 
172d0c080abSJoseph Pusztay /*@C
173d0c080abSJoseph Pusztay    TSMonitorDefault - The Default monitor, prints the timestep and time for each step
174d0c080abSJoseph Pusztay 
175d0c080abSJoseph Pusztay    Level: intermediate
176d0c080abSJoseph Pusztay 
177db781477SPatrick Sanan .seealso: `TSMonitorSet()`
178d0c080abSJoseph Pusztay @*/
179d0c080abSJoseph Pusztay PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf)
180d0c080abSJoseph Pusztay {
181d0c080abSJoseph Pusztay   PetscViewer    viewer =  vf->viewer;
182d0c080abSJoseph Pusztay   PetscBool      iascii,ibinary;
183d0c080abSJoseph Pusztay 
184d0c080abSJoseph Pusztay   PetscFunctionBegin;
185064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,5);
1869566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
1879566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary));
1889566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,vf->format));
189d0c080abSJoseph Pusztay   if (iascii) {
1909566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel));
191d0c080abSJoseph Pusztay     if (step == -1) { /* this indicates it is an interpolated solution */
19263a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %" PetscInt_FMT " and %" PetscInt_FMT "\n",(double)ptime,ts->steps-1,ts->steps));
193d0c080abSJoseph Pusztay     } else {
19463a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT " TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n"));
195d0c080abSJoseph Pusztay     }
1969566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel));
197d0c080abSJoseph Pusztay   } else if (ibinary) {
198d0c080abSJoseph Pusztay     PetscMPIInt rank;
1999566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank));
200d0c080abSJoseph Pusztay     if (!rank) {
201d0c080abSJoseph Pusztay       PetscBool skipHeader;
202d0c080abSJoseph Pusztay       PetscInt  classid = REAL_FILE_CLASSID;
203d0c080abSJoseph Pusztay 
2049566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryGetSkipHeader(viewer,&skipHeader));
205d0c080abSJoseph Pusztay       if (!skipHeader) {
2069566063dSJacob Faibussowitsch          PetscCall(PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT));
207d0c080abSJoseph Pusztay        }
2089566063dSJacob Faibussowitsch       PetscCall(PetscRealView(1,&ptime,viewer));
209d0c080abSJoseph Pusztay     } else {
2109566063dSJacob Faibussowitsch       PetscCall(PetscRealView(0,&ptime,viewer));
211d0c080abSJoseph Pusztay     }
212d0c080abSJoseph Pusztay   }
2139566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
214d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
215d0c080abSJoseph Pusztay }
216d0c080abSJoseph Pusztay 
217d0c080abSJoseph Pusztay /*@C
218d0c080abSJoseph Pusztay    TSMonitorExtreme - Prints the extreme values of the solution at each timestep
219d0c080abSJoseph Pusztay 
220d0c080abSJoseph Pusztay    Level: intermediate
221d0c080abSJoseph Pusztay 
222db781477SPatrick Sanan .seealso: `TSMonitorSet()`
223d0c080abSJoseph Pusztay @*/
224d0c080abSJoseph Pusztay PetscErrorCode TSMonitorExtreme(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf)
225d0c080abSJoseph Pusztay {
226d0c080abSJoseph Pusztay   PetscViewer    viewer =  vf->viewer;
227d0c080abSJoseph Pusztay   PetscBool      iascii;
228d0c080abSJoseph Pusztay   PetscReal      max,min;
229d0c080abSJoseph Pusztay 
230d0c080abSJoseph Pusztay   PetscFunctionBegin;
231064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,5);
2329566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
2339566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,vf->format));
234d0c080abSJoseph Pusztay   if (iascii) {
2359566063dSJacob Faibussowitsch     PetscCall(VecMax(v,NULL,&max));
2369566063dSJacob Faibussowitsch     PetscCall(VecMin(v,NULL,&min));
2379566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel));
23863a3b9bcSJacob 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));
2399566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel));
240d0c080abSJoseph Pusztay   }
2419566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
242d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
243d0c080abSJoseph Pusztay }
244d0c080abSJoseph Pusztay 
245d0c080abSJoseph Pusztay /*@C
246d0c080abSJoseph Pusztay    TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with
247d0c080abSJoseph Pusztay    TS to monitor the solution process graphically in various ways
248d0c080abSJoseph Pusztay 
249d0c080abSJoseph Pusztay    Collective on TS
250d0c080abSJoseph Pusztay 
251d0c080abSJoseph Pusztay    Input Parameters:
252d0c080abSJoseph Pusztay +  host - the X display to open, or null for the local machine
253d0c080abSJoseph Pusztay .  label - the title to put in the title bar
254d0c080abSJoseph Pusztay .  x, y - the screen coordinates of the upper left coordinate of the window
255d0c080abSJoseph Pusztay .  m, n - the screen width and height in pixels
256d0c080abSJoseph Pusztay -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
257d0c080abSJoseph Pusztay 
258d0c080abSJoseph Pusztay    Output Parameter:
259d0c080abSJoseph Pusztay .  ctx - the context
260d0c080abSJoseph Pusztay 
261d0c080abSJoseph Pusztay    Options Database Key:
262d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep - automatically sets line graph monitor
263d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep_log - automatically sets line graph monitor
264d0c080abSJoseph Pusztay .  -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables())
265d0c080abSJoseph Pusztay .  -ts_monitor_lg_error -  monitor the error
266d0c080abSJoseph Pusztay .  -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep
267d0c080abSJoseph Pusztay .  -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep
268d0c080abSJoseph Pusztay -  -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true
269d0c080abSJoseph Pusztay 
270d0c080abSJoseph Pusztay    Notes:
271d0c080abSJoseph Pusztay    Use TSMonitorLGCtxDestroy() to destroy.
272d0c080abSJoseph Pusztay 
273d0c080abSJoseph Pusztay    One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform()
274d0c080abSJoseph Pusztay 
275d0c080abSJoseph Pusztay    Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the
276d0c080abSJoseph Pusztay    first argument (if that TS object does not have a TSMonitorLGCtx associated with it the function call is ignored) and the second takes a TSMonitorLGCtx object
277d0c080abSJoseph Pusztay    as the first argument.
278d0c080abSJoseph Pusztay 
279d0c080abSJoseph Pusztay    One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames()
280d0c080abSJoseph Pusztay 
281d0c080abSJoseph Pusztay    Level: intermediate
282d0c080abSJoseph Pusztay 
283db781477SPatrick Sanan .seealso: `TSMonitorLGTimeStep()`, `TSMonitorSet()`, `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorDefault()`, `VecView()`,
284db781477SPatrick Sanan           `TSMonitorLGCtxCreate()`, `TSMonitorLGCtxSetVariableNames()`, `TSMonitorLGCtxGetVariableNames()`,
285db781477SPatrick Sanan           `TSMonitorLGSetVariableNames()`, `TSMonitorLGGetVariableNames()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetDisplayVariables()`,
286db781477SPatrick Sanan           `TSMonitorLGCtxSetTransform()`, `TSMonitorLGSetTransform()`, `TSMonitorLGError()`, `TSMonitorLGSNESIterations()`, `TSMonitorLGKSPIterations()`,
287db781477SPatrick Sanan           `TSMonitorEnvelopeCtxCreate()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxDestroy()`, `TSMonitorEnvelop()`
288d0c080abSJoseph Pusztay 
289d0c080abSJoseph Pusztay @*/
290d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
291d0c080abSJoseph Pusztay {
292d0c080abSJoseph Pusztay   PetscDraw      draw;
293d0c080abSJoseph Pusztay 
294d0c080abSJoseph Pusztay   PetscFunctionBegin;
2959566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
2969566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm,host,label,x,y,m,n,&draw));
2979566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetFromOptions(draw));
2989566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGCreate(draw,1,&(*ctx)->lg));
2999566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGSetFromOptions((*ctx)->lg));
3009566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw));
301d0c080abSJoseph Pusztay   (*ctx)->howoften = howoften;
302d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
303d0c080abSJoseph Pusztay }
304d0c080abSJoseph Pusztay 
305d0c080abSJoseph Pusztay PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx)
306d0c080abSJoseph Pusztay {
307d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
308d0c080abSJoseph Pusztay   PetscReal      x   = ptime,y;
309d0c080abSJoseph Pusztay 
310d0c080abSJoseph Pusztay   PetscFunctionBegin;
311d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */
312d0c080abSJoseph Pusztay   if (!step) {
313d0c080abSJoseph Pusztay     PetscDrawAxis axis;
314d0c080abSJoseph Pusztay     const char *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step";
3159566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
3169566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time",ylabel));
3179566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
318d0c080abSJoseph Pusztay   }
3199566063dSJacob Faibussowitsch   PetscCall(TSGetTimeStep(ts,&y));
320d0c080abSJoseph Pusztay   if (ctx->semilogy) y = PetscLog10Real(y);
3219566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg,&x,&y));
322d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
3239566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
3249566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
325d0c080abSJoseph Pusztay   }
326d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
327d0c080abSJoseph Pusztay }
328d0c080abSJoseph Pusztay 
329d0c080abSJoseph Pusztay /*@C
330d0c080abSJoseph Pusztay    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
331d0c080abSJoseph Pusztay    with TSMonitorLGCtxCreate().
332d0c080abSJoseph Pusztay 
333d0c080abSJoseph Pusztay    Collective on TSMonitorLGCtx
334d0c080abSJoseph Pusztay 
335d0c080abSJoseph Pusztay    Input Parameter:
336d0c080abSJoseph Pusztay .  ctx - the monitor context
337d0c080abSJoseph Pusztay 
338d0c080abSJoseph Pusztay    Level: intermediate
339d0c080abSJoseph Pusztay 
340db781477SPatrick Sanan .seealso: `TSMonitorLGCtxCreate()`, `TSMonitorSet()`, `TSMonitorLGTimeStep();`
341d0c080abSJoseph Pusztay @*/
342d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
343d0c080abSJoseph Pusztay {
344d0c080abSJoseph Pusztay   PetscFunctionBegin;
345d0c080abSJoseph Pusztay   if ((*ctx)->transformdestroy) {
3469566063dSJacob Faibussowitsch     PetscCall(((*ctx)->transformdestroy)((*ctx)->transformctx));
347d0c080abSJoseph Pusztay   }
3489566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGDestroy(&(*ctx)->lg));
3499566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&(*ctx)->names));
3509566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&(*ctx)->displaynames));
3519566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ctx)->displayvariables));
3529566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ctx)->displayvalues));
3539566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
354d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
355d0c080abSJoseph Pusztay }
356d0c080abSJoseph Pusztay 
357d7462660SMatthew Knepley /* Creates a TS Monitor SPCtx for use with DMSwarm particle visualizations */
358d7462660SMatthew Knepley PetscErrorCode TSMonitorSPCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,PetscInt retain,PetscBool phase,TSMonitorSPCtx *ctx)
359d0c080abSJoseph Pusztay {
360d0c080abSJoseph Pusztay   PetscDraw      draw;
361d0c080abSJoseph Pusztay 
362d0c080abSJoseph Pusztay   PetscFunctionBegin;
3639566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
3649566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm,host,label,x,y,m,n,&draw));
3659566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetFromOptions(draw));
3669566063dSJacob Faibussowitsch   PetscCall(PetscDrawSPCreate(draw,1,&(*ctx)->sp));
3679566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw));
368d0c080abSJoseph Pusztay   (*ctx)->howoften = howoften;
369d7462660SMatthew Knepley   (*ctx)->retain   = retain;
370d7462660SMatthew Knepley   (*ctx)->phase    = phase;
371d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
372d0c080abSJoseph Pusztay }
373d0c080abSJoseph Pusztay 
374d0c080abSJoseph Pusztay /*
375d0c080abSJoseph Pusztay   Destroys a TSMonitorSPCtx that was created with TSMonitorSPCtxCreate
376d0c080abSJoseph Pusztay */
377d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSPCtxDestroy(TSMonitorSPCtx *ctx)
378d0c080abSJoseph Pusztay {
379d0c080abSJoseph Pusztay   PetscFunctionBegin;
380d0c080abSJoseph Pusztay 
3819566063dSJacob Faibussowitsch   PetscCall(PetscDrawSPDestroy(&(*ctx)->sp));
3829566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
383d0c080abSJoseph Pusztay 
384d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
385d0c080abSJoseph Pusztay 
386d0c080abSJoseph Pusztay }
387d0c080abSJoseph Pusztay 
388d0c080abSJoseph Pusztay /*@C
389d0c080abSJoseph Pusztay    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
390d0c080abSJoseph Pusztay    VecView() for the solution at each timestep
391d0c080abSJoseph Pusztay 
392d0c080abSJoseph Pusztay    Collective on TS
393d0c080abSJoseph Pusztay 
394d0c080abSJoseph Pusztay    Input Parameters:
395d0c080abSJoseph Pusztay +  ts - the TS context
396d0c080abSJoseph Pusztay .  step - current time-step
397d0c080abSJoseph Pusztay .  ptime - current time
398d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
399d0c080abSJoseph Pusztay 
400d0c080abSJoseph Pusztay    Options Database:
401d0c080abSJoseph Pusztay .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
402d0c080abSJoseph Pusztay 
403d0c080abSJoseph Pusztay    Notes:
404d0c080abSJoseph Pusztay     the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
405d0c080abSJoseph Pusztay        will look bad
406d0c080abSJoseph Pusztay 
407d0c080abSJoseph Pusztay    Level: intermediate
408d0c080abSJoseph Pusztay 
409db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
410d0c080abSJoseph Pusztay @*/
411d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
412d0c080abSJoseph Pusztay {
413d0c080abSJoseph Pusztay   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
414d0c080abSJoseph Pusztay   PetscDraw        draw;
415d0c080abSJoseph Pusztay 
416d0c080abSJoseph Pusztay   PetscFunctionBegin;
417d0c080abSJoseph Pusztay   if (!step && ictx->showinitial) {
418d0c080abSJoseph Pusztay     if (!ictx->initialsolution) {
4199566063dSJacob Faibussowitsch       PetscCall(VecDuplicate(u,&ictx->initialsolution));
420d0c080abSJoseph Pusztay     }
4219566063dSJacob Faibussowitsch     PetscCall(VecCopy(u,ictx->initialsolution));
422d0c080abSJoseph Pusztay   }
423d0c080abSJoseph Pusztay   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
424d0c080abSJoseph Pusztay 
425d0c080abSJoseph Pusztay   if (ictx->showinitial) {
426d0c080abSJoseph Pusztay     PetscReal pause;
4279566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetPause(ictx->viewer,&pause));
4289566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetPause(ictx->viewer,0.0));
4299566063dSJacob Faibussowitsch     PetscCall(VecView(ictx->initialsolution,ictx->viewer));
4309566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetPause(ictx->viewer,pause));
4319566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE));
432d0c080abSJoseph Pusztay   }
4339566063dSJacob Faibussowitsch   PetscCall(VecView(u,ictx->viewer));
434d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
435d0c080abSJoseph Pusztay     PetscReal xl,yl,xr,yr,h;
436d0c080abSJoseph Pusztay     char      time[32];
437d0c080abSJoseph Pusztay 
4389566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(ictx->viewer,0,&draw));
4399566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime));
4409566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr));
441d0c080abSJoseph Pusztay     h    = yl + .95*(yr - yl);
4429566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time));
4439566063dSJacob Faibussowitsch     PetscCall(PetscDrawFlush(draw));
444d0c080abSJoseph Pusztay   }
445d0c080abSJoseph Pusztay 
446d0c080abSJoseph Pusztay   if (ictx->showinitial) {
4479566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE));
448d0c080abSJoseph Pusztay   }
449d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
450d0c080abSJoseph Pusztay }
451d0c080abSJoseph Pusztay 
452d0c080abSJoseph Pusztay /*@C
453d0c080abSJoseph Pusztay    TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram
454d0c080abSJoseph Pusztay 
455d0c080abSJoseph Pusztay    Collective on TS
456d0c080abSJoseph Pusztay 
457d0c080abSJoseph Pusztay    Input Parameters:
458d0c080abSJoseph Pusztay +  ts - the TS context
459d0c080abSJoseph Pusztay .  step - current time-step
460d0c080abSJoseph Pusztay .  ptime - current time
461d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
462d0c080abSJoseph Pusztay 
463d0c080abSJoseph Pusztay    Level: intermediate
464d0c080abSJoseph Pusztay 
465db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
466d0c080abSJoseph Pusztay @*/
467d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
468d0c080abSJoseph Pusztay {
469d0c080abSJoseph Pusztay   TSMonitorDrawCtx  ictx = (TSMonitorDrawCtx)dummy;
470d0c080abSJoseph Pusztay   PetscDraw         draw;
471d0c080abSJoseph Pusztay   PetscDrawAxis     axis;
472d0c080abSJoseph Pusztay   PetscInt          n;
473d0c080abSJoseph Pusztay   PetscMPIInt       size;
474d0c080abSJoseph Pusztay   PetscReal         U0,U1,xl,yl,xr,yr,h;
475d0c080abSJoseph Pusztay   char              time[32];
476d0c080abSJoseph Pusztay   const PetscScalar *U;
477d0c080abSJoseph Pusztay 
478d0c080abSJoseph Pusztay   PetscFunctionBegin;
4799566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size));
4803c633725SBarry Smith   PetscCheck(size == 1,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs");
4819566063dSJacob Faibussowitsch   PetscCall(VecGetSize(u,&n));
4823c633725SBarry Smith   PetscCheck(n == 2,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns");
483d0c080abSJoseph Pusztay 
4849566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(ictx->viewer,0,&draw));
4859566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis));
4869566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr));
487d0c080abSJoseph Pusztay   if (!step) {
4889566063dSJacob Faibussowitsch     PetscCall(PetscDrawClear(draw));
4899566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisDraw(axis));
490d0c080abSJoseph Pusztay   }
491d0c080abSJoseph Pusztay 
4929566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(u,&U));
493d0c080abSJoseph Pusztay   U0 = PetscRealPart(U[0]);
494d0c080abSJoseph Pusztay   U1 = PetscRealPart(U[1]);
4959566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(u,&U));
496d0c080abSJoseph Pusztay   if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0);
497d0c080abSJoseph Pusztay 
498d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
4999566063dSJacob Faibussowitsch   PetscCall(PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK));
500d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
5019566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr));
5029566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime));
503d0c080abSJoseph Pusztay     h    = yl + .95*(yr - yl);
5049566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time));
505d0c080abSJoseph Pusztay   }
506d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
5079566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
5089566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
5099566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
510d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
511d0c080abSJoseph Pusztay }
512d0c080abSJoseph Pusztay 
513d0c080abSJoseph Pusztay /*@C
514d0c080abSJoseph Pusztay    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
515d0c080abSJoseph Pusztay 
516d0c080abSJoseph Pusztay    Collective on TS
517d0c080abSJoseph Pusztay 
518d0c080abSJoseph Pusztay    Input Parameters:
519d0c080abSJoseph Pusztay .    ctx - the monitor context
520d0c080abSJoseph Pusztay 
521d0c080abSJoseph Pusztay    Level: intermediate
522d0c080abSJoseph Pusztay 
523db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawSolution()`, `TSMonitorDrawError()`
524d0c080abSJoseph Pusztay @*/
525d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
526d0c080abSJoseph Pusztay {
527d0c080abSJoseph Pusztay   PetscFunctionBegin;
5289566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&(*ictx)->viewer));
5299566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ictx)->initialsolution));
5309566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ictx));
531d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
532d0c080abSJoseph Pusztay }
533d0c080abSJoseph Pusztay 
534d0c080abSJoseph Pusztay /*@C
535d0c080abSJoseph Pusztay    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
536d0c080abSJoseph Pusztay 
537d0c080abSJoseph Pusztay    Collective on TS
538d0c080abSJoseph Pusztay 
539d0c080abSJoseph Pusztay    Input Parameter:
540d0c080abSJoseph Pusztay .    ts - time-step context
541d0c080abSJoseph Pusztay 
542d0c080abSJoseph Pusztay    Output Patameter:
543d0c080abSJoseph Pusztay .    ctx - the monitor context
544d0c080abSJoseph Pusztay 
545d0c080abSJoseph Pusztay    Options Database:
546d0c080abSJoseph Pusztay .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
547d0c080abSJoseph Pusztay 
548d0c080abSJoseph Pusztay    Level: intermediate
549d0c080abSJoseph Pusztay 
550db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawCtx()`
551d0c080abSJoseph Pusztay @*/
552d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
553d0c080abSJoseph Pusztay {
554d0c080abSJoseph Pusztay   PetscFunctionBegin;
5559566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
5569566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer));
5579566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetFromOptions((*ctx)->viewer));
558d0c080abSJoseph Pusztay 
559d0c080abSJoseph Pusztay   (*ctx)->howoften    = howoften;
560d0c080abSJoseph Pusztay   (*ctx)->showinitial = PETSC_FALSE;
5619566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL));
562d0c080abSJoseph Pusztay 
563d0c080abSJoseph Pusztay   (*ctx)->showtimestepandtime = PETSC_FALSE;
5649566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL));
565d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
566d0c080abSJoseph Pusztay }
567d0c080abSJoseph Pusztay 
568d0c080abSJoseph Pusztay /*@C
569d0c080abSJoseph Pusztay    TSMonitorDrawSolutionFunction - Monitors progress of the TS solvers by calling
570d0c080abSJoseph Pusztay    VecView() for the solution provided by TSSetSolutionFunction() at each timestep
571d0c080abSJoseph Pusztay 
572d0c080abSJoseph Pusztay    Collective on TS
573d0c080abSJoseph Pusztay 
574d0c080abSJoseph Pusztay    Input Parameters:
575d0c080abSJoseph Pusztay +  ts - the TS context
576d0c080abSJoseph Pusztay .  step - current time-step
577d0c080abSJoseph Pusztay .  ptime - current time
578d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
579d0c080abSJoseph Pusztay 
580d0c080abSJoseph Pusztay    Options Database:
581d0c080abSJoseph Pusztay .  -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
582d0c080abSJoseph Pusztay 
583d0c080abSJoseph Pusztay    Level: intermediate
584d0c080abSJoseph Pusztay 
585db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
586d0c080abSJoseph Pusztay @*/
587d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawSolutionFunction(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
588d0c080abSJoseph Pusztay {
589d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
590d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
591d0c080abSJoseph Pusztay   Vec              work;
592d0c080abSJoseph Pusztay 
593d0c080abSJoseph Pusztay   PetscFunctionBegin;
594d0c080abSJoseph Pusztay   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
5959566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u,&work));
5969566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts,ptime,work));
5979566063dSJacob Faibussowitsch   PetscCall(VecView(work,viewer));
5989566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work));
599d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
600d0c080abSJoseph Pusztay }
601d0c080abSJoseph Pusztay 
602d0c080abSJoseph Pusztay /*@C
603d0c080abSJoseph Pusztay    TSMonitorDrawError - Monitors progress of the TS solvers by calling
604d0c080abSJoseph Pusztay    VecView() for the error at each timestep
605d0c080abSJoseph Pusztay 
606d0c080abSJoseph Pusztay    Collective on TS
607d0c080abSJoseph Pusztay 
608d0c080abSJoseph Pusztay    Input Parameters:
609d0c080abSJoseph Pusztay +  ts - the TS context
610d0c080abSJoseph Pusztay .  step - current time-step
611d0c080abSJoseph Pusztay .  ptime - current time
612d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
613d0c080abSJoseph Pusztay 
614d0c080abSJoseph Pusztay    Options Database:
615d0c080abSJoseph Pusztay .  -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
616d0c080abSJoseph Pusztay 
617d0c080abSJoseph Pusztay    Level: intermediate
618d0c080abSJoseph Pusztay 
619db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
620d0c080abSJoseph Pusztay @*/
621d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
622d0c080abSJoseph Pusztay {
623d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
624d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
625d0c080abSJoseph Pusztay   Vec              work;
626d0c080abSJoseph Pusztay 
627d0c080abSJoseph Pusztay   PetscFunctionBegin;
628d0c080abSJoseph Pusztay   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
6299566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u,&work));
6309566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts,ptime,work));
6319566063dSJacob Faibussowitsch   PetscCall(VecAXPY(work,-1.0,u));
6329566063dSJacob Faibussowitsch   PetscCall(VecView(work,viewer));
6339566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work));
634d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
635d0c080abSJoseph Pusztay }
636d0c080abSJoseph Pusztay 
637d0c080abSJoseph Pusztay /*@C
638d0c080abSJoseph Pusztay    TSMonitorSolution - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file or a PetscDraw object
639d0c080abSJoseph Pusztay 
640d0c080abSJoseph Pusztay    Collective on TS
641d0c080abSJoseph Pusztay 
642d0c080abSJoseph Pusztay    Input Parameters:
643d0c080abSJoseph Pusztay +  ts - the TS context
644d0c080abSJoseph Pusztay .  step - current time-step
645d0c080abSJoseph Pusztay .  ptime - current time
646d0c080abSJoseph Pusztay .  u - current state
647d0c080abSJoseph Pusztay -  vf - viewer and its format
648d0c080abSJoseph Pusztay 
649d0c080abSJoseph Pusztay    Level: intermediate
650d0c080abSJoseph Pusztay 
651db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
652d0c080abSJoseph Pusztay @*/
653d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
654d0c080abSJoseph Pusztay {
655d0c080abSJoseph Pusztay   PetscFunctionBegin;
6569566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(vf->viewer,vf->format));
6579566063dSJacob Faibussowitsch   PetscCall(VecView(u,vf->viewer));
6589566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(vf->viewer));
659d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
660d0c080abSJoseph Pusztay }
661d0c080abSJoseph Pusztay 
662d0c080abSJoseph Pusztay /*@C
663d0c080abSJoseph Pusztay    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
664d0c080abSJoseph Pusztay 
665d0c080abSJoseph Pusztay    Collective on TS
666d0c080abSJoseph Pusztay 
667d0c080abSJoseph Pusztay    Input Parameters:
668d0c080abSJoseph Pusztay +  ts - the TS context
669d0c080abSJoseph Pusztay .  step - current time-step
670d0c080abSJoseph Pusztay .  ptime - current time
671d0c080abSJoseph Pusztay .  u - current state
67263a3b9bcSJacob Faibussowitsch -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03" PetscInt_FMT ")
673d0c080abSJoseph Pusztay 
674d0c080abSJoseph Pusztay    Level: intermediate
675d0c080abSJoseph Pusztay 
676d0c080abSJoseph Pusztay    Notes:
677d0c080abSJoseph Pusztay    The VTK format does not allow writing multiple time steps in the same file, therefore a different file will be written for each time step.
678d0c080abSJoseph Pusztay    These are named according to the file name template.
679d0c080abSJoseph Pusztay 
680d0c080abSJoseph Pusztay    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().
681d0c080abSJoseph Pusztay 
682db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
683d0c080abSJoseph Pusztay @*/
684d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
685d0c080abSJoseph Pusztay {
686d0c080abSJoseph Pusztay   char           filename[PETSC_MAX_PATH_LEN];
687d0c080abSJoseph Pusztay   PetscViewer    viewer;
688d0c080abSJoseph Pusztay 
689d0c080abSJoseph Pusztay   PetscFunctionBegin;
690d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
6919566063dSJacob Faibussowitsch   PetscCall(PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step));
6929566063dSJacob Faibussowitsch   PetscCall(PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer));
6939566063dSJacob Faibussowitsch   PetscCall(VecView(u,viewer));
6949566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&viewer));
695d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
696d0c080abSJoseph Pusztay }
697d0c080abSJoseph Pusztay 
698d0c080abSJoseph Pusztay /*@C
699d0c080abSJoseph Pusztay    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
700d0c080abSJoseph Pusztay 
701d0c080abSJoseph Pusztay    Collective on TS
702d0c080abSJoseph Pusztay 
703d0c080abSJoseph Pusztay    Input Parameters:
70463a3b9bcSJacob Faibussowitsch .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03" PetscInt_FMT ")
705d0c080abSJoseph Pusztay 
706d0c080abSJoseph Pusztay    Level: intermediate
707d0c080abSJoseph Pusztay 
708d0c080abSJoseph Pusztay    Note:
709d0c080abSJoseph Pusztay    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
710d0c080abSJoseph Pusztay 
711db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorSolutionVTK()`
712d0c080abSJoseph Pusztay @*/
713d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
714d0c080abSJoseph Pusztay {
715d0c080abSJoseph Pusztay   PetscFunctionBegin;
7169566063dSJacob Faibussowitsch   PetscCall(PetscFree(*(char**)filenametemplate));
717d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
718d0c080abSJoseph Pusztay }
719d0c080abSJoseph Pusztay 
720d0c080abSJoseph Pusztay /*@C
721d0c080abSJoseph Pusztay    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
722d0c080abSJoseph Pusztay        in a time based line graph
723d0c080abSJoseph Pusztay 
724d0c080abSJoseph Pusztay    Collective on TS
725d0c080abSJoseph Pusztay 
726d0c080abSJoseph Pusztay    Input Parameters:
727d0c080abSJoseph Pusztay +  ts - the TS context
728d0c080abSJoseph Pusztay .  step - current time-step
729d0c080abSJoseph Pusztay .  ptime - current time
730d0c080abSJoseph Pusztay .  u - current solution
731d0c080abSJoseph Pusztay -  dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate()
732d0c080abSJoseph Pusztay 
733d0c080abSJoseph Pusztay    Options Database:
73467b8a455SSatish Balay .   -ts_monitor_lg_solution_variables - enable monitor of lg solution variables
735d0c080abSJoseph Pusztay 
736d0c080abSJoseph Pusztay    Level: intermediate
737d0c080abSJoseph Pusztay 
738d0c080abSJoseph Pusztay    Notes:
739d0c080abSJoseph Pusztay     Each process in a parallel run displays its component solutions in a separate window
740d0c080abSJoseph Pusztay 
741db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGCtxCreate()`, `TSMonitorLGCtxSetVariableNames()`, `TSMonitorLGCtxGetVariableNames()`,
742db781477SPatrick Sanan           `TSMonitorLGSetVariableNames()`, `TSMonitorLGGetVariableNames()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetDisplayVariables()`,
743db781477SPatrick Sanan           `TSMonitorLGCtxSetTransform()`, `TSMonitorLGSetTransform()`, `TSMonitorLGError()`, `TSMonitorLGSNESIterations()`, `TSMonitorLGKSPIterations()`,
744db781477SPatrick Sanan           `TSMonitorEnvelopeCtxCreate()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxDestroy()`, `TSMonitorEnvelop()`
745d0c080abSJoseph Pusztay @*/
746d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
747d0c080abSJoseph Pusztay {
748d0c080abSJoseph Pusztay   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dctx;
749d0c080abSJoseph Pusztay   const PetscScalar *yy;
750d0c080abSJoseph Pusztay   Vec               v;
751d0c080abSJoseph Pusztay 
752d0c080abSJoseph Pusztay   PetscFunctionBegin;
753d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
754d0c080abSJoseph Pusztay   if (!step) {
755d0c080abSJoseph Pusztay     PetscDrawAxis axis;
756d0c080abSJoseph Pusztay     PetscInt      dim;
7579566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
7589566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution"));
759d0c080abSJoseph Pusztay     if (!ctx->names) {
760d0c080abSJoseph Pusztay       PetscBool flg;
761d0c080abSJoseph Pusztay       /* user provides names of variables to plot but no names has been set so assume names are integer values */
7629566063dSJacob Faibussowitsch       PetscCall(PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg));
763d0c080abSJoseph Pusztay       if (flg) {
764d0c080abSJoseph Pusztay         PetscInt i,n;
765d0c080abSJoseph Pusztay         char     **names;
7669566063dSJacob Faibussowitsch         PetscCall(VecGetSize(u,&n));
7679566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(n+1,&names));
768d0c080abSJoseph Pusztay         for (i=0; i<n; i++) {
7699566063dSJacob Faibussowitsch           PetscCall(PetscMalloc1(5,&names[i]));
77063a3b9bcSJacob Faibussowitsch           PetscCall(PetscSNPrintf(names[i],5,"%" PetscInt_FMT,i));
771d0c080abSJoseph Pusztay         }
772d0c080abSJoseph Pusztay         names[n] = NULL;
773d0c080abSJoseph Pusztay         ctx->names = names;
774d0c080abSJoseph Pusztay       }
775d0c080abSJoseph Pusztay     }
776d0c080abSJoseph Pusztay     if (ctx->names && !ctx->displaynames) {
777d0c080abSJoseph Pusztay       char      **displaynames;
778d0c080abSJoseph Pusztay       PetscBool flg;
7799566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u,&dim));
7809566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(dim+1,&displaynames));
7819566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg));
782d0c080abSJoseph Pusztay       if (flg) {
7839566063dSJacob Faibussowitsch         PetscCall(TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames));
784d0c080abSJoseph Pusztay       }
7859566063dSJacob Faibussowitsch       PetscCall(PetscStrArrayDestroy(&displaynames));
786d0c080abSJoseph Pusztay     }
787d0c080abSJoseph Pusztay     if (ctx->displaynames) {
7889566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables));
7899566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames));
790d0c080abSJoseph Pusztay     } else if (ctx->names) {
7919566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u,&dim));
7929566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg,dim));
7939566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names));
794d0c080abSJoseph Pusztay     } else {
7959566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u,&dim));
7969566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg,dim));
797d0c080abSJoseph Pusztay     }
7989566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
799d0c080abSJoseph Pusztay   }
800d0c080abSJoseph Pusztay 
801d0c080abSJoseph Pusztay   if (!ctx->transform) v = u;
8029566063dSJacob Faibussowitsch   else PetscCall((*ctx->transform)(ctx->transformctx,u,&v));
8039566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(v,&yy));
804d0c080abSJoseph Pusztay   if (ctx->displaynames) {
805d0c080abSJoseph Pusztay     PetscInt i;
806d0c080abSJoseph Pusztay     for (i=0; i<ctx->ndisplayvariables; i++)
807d0c080abSJoseph Pusztay       ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]);
8089566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues));
809d0c080abSJoseph Pusztay   } else {
810d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
811d0c080abSJoseph Pusztay     PetscInt  i,n;
812d0c080abSJoseph Pusztay     PetscReal *yreal;
8139566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(v,&n));
8149566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&yreal));
815d0c080abSJoseph Pusztay     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
8169566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal));
8179566063dSJacob Faibussowitsch     PetscCall(PetscFree(yreal));
818d0c080abSJoseph Pusztay #else
8199566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy));
820d0c080abSJoseph Pusztay #endif
821d0c080abSJoseph Pusztay   }
8229566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(v,&yy));
8239566063dSJacob Faibussowitsch   if (ctx->transform) PetscCall(VecDestroy(&v));
824d0c080abSJoseph Pusztay 
825d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
8269566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
8279566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
828d0c080abSJoseph Pusztay   }
829d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
830d0c080abSJoseph Pusztay }
831d0c080abSJoseph Pusztay 
832d0c080abSJoseph Pusztay /*@C
833d0c080abSJoseph Pusztay    TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
834d0c080abSJoseph Pusztay 
835d0c080abSJoseph Pusztay    Collective on TS
836d0c080abSJoseph Pusztay 
837d0c080abSJoseph Pusztay    Input Parameters:
838d0c080abSJoseph Pusztay +  ts - the TS context
839d0c080abSJoseph Pusztay -  names - the names of the components, final string must be NULL
840d0c080abSJoseph Pusztay 
841d0c080abSJoseph Pusztay    Level: intermediate
842d0c080abSJoseph Pusztay 
843d0c080abSJoseph Pusztay    Notes:
844d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
845d0c080abSJoseph Pusztay 
846db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetVariableNames()`
847d0c080abSJoseph Pusztay @*/
848d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSetVariableNames(TS ts,const char * const *names)
849d0c080abSJoseph Pusztay {
850d0c080abSJoseph Pusztay   PetscInt          i;
851d0c080abSJoseph Pusztay 
852d0c080abSJoseph Pusztay   PetscFunctionBegin;
853d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
854d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
8559566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names));
856d0c080abSJoseph Pusztay       break;
857d0c080abSJoseph Pusztay     }
858d0c080abSJoseph Pusztay   }
859d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
860d0c080abSJoseph Pusztay }
861d0c080abSJoseph Pusztay 
862d0c080abSJoseph Pusztay /*@C
863d0c080abSJoseph Pusztay    TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
864d0c080abSJoseph Pusztay 
865d0c080abSJoseph Pusztay    Collective on TS
866d0c080abSJoseph Pusztay 
867d0c080abSJoseph Pusztay    Input Parameters:
868d0c080abSJoseph Pusztay +  ts - the TS context
869d0c080abSJoseph Pusztay -  names - the names of the components, final string must be NULL
870d0c080abSJoseph Pusztay 
871d0c080abSJoseph Pusztay    Level: intermediate
872d0c080abSJoseph Pusztay 
873db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGSetVariableNames()`
874d0c080abSJoseph Pusztay @*/
875d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names)
876d0c080abSJoseph Pusztay {
877d0c080abSJoseph Pusztay   PetscFunctionBegin;
8789566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&ctx->names));
8799566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(names,&ctx->names));
880d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
881d0c080abSJoseph Pusztay }
882d0c080abSJoseph Pusztay 
883d0c080abSJoseph Pusztay /*@C
884d0c080abSJoseph Pusztay    TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot
885d0c080abSJoseph Pusztay 
886d0c080abSJoseph Pusztay    Collective on TS
887d0c080abSJoseph Pusztay 
888d0c080abSJoseph Pusztay    Input Parameter:
889d0c080abSJoseph Pusztay .  ts - the TS context
890d0c080abSJoseph Pusztay 
891d0c080abSJoseph Pusztay    Output Parameter:
892d0c080abSJoseph Pusztay .  names - the names of the components, final string must be NULL
893d0c080abSJoseph Pusztay 
894d0c080abSJoseph Pusztay    Level: intermediate
895d0c080abSJoseph Pusztay 
896d0c080abSJoseph Pusztay    Notes:
897d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
898d0c080abSJoseph Pusztay 
899db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`
900d0c080abSJoseph Pusztay @*/
901d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGGetVariableNames(TS ts,const char *const **names)
902d0c080abSJoseph Pusztay {
903d0c080abSJoseph Pusztay   PetscInt       i;
904d0c080abSJoseph Pusztay 
905d0c080abSJoseph Pusztay   PetscFunctionBegin;
906d0c080abSJoseph Pusztay   *names = NULL;
907d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
908d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
909d0c080abSJoseph Pusztay       TSMonitorLGCtx  ctx = (TSMonitorLGCtx) ts->monitorcontext[i];
910d0c080abSJoseph Pusztay       *names = (const char *const *)ctx->names;
911d0c080abSJoseph Pusztay       break;
912d0c080abSJoseph Pusztay     }
913d0c080abSJoseph Pusztay   }
914d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
915d0c080abSJoseph Pusztay }
916d0c080abSJoseph Pusztay 
917d0c080abSJoseph Pusztay /*@C
918d0c080abSJoseph Pusztay    TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor
919d0c080abSJoseph Pusztay 
920d0c080abSJoseph Pusztay    Collective on TS
921d0c080abSJoseph Pusztay 
922d0c080abSJoseph Pusztay    Input Parameters:
923d0c080abSJoseph Pusztay +  ctx - the TSMonitorLG context
924d0c080abSJoseph Pusztay -  displaynames - the names of the components, final string must be NULL
925d0c080abSJoseph Pusztay 
926d0c080abSJoseph Pusztay    Level: intermediate
927d0c080abSJoseph Pusztay 
928db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`
929d0c080abSJoseph Pusztay @*/
930d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames)
931d0c080abSJoseph Pusztay {
932d0c080abSJoseph Pusztay   PetscInt          j = 0,k;
933d0c080abSJoseph Pusztay 
934d0c080abSJoseph Pusztay   PetscFunctionBegin;
935d0c080abSJoseph Pusztay   if (!ctx->names) PetscFunctionReturn(0);
9369566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&ctx->displaynames));
9379566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(displaynames,&ctx->displaynames));
938d0c080abSJoseph Pusztay   while (displaynames[j]) j++;
939d0c080abSJoseph Pusztay   ctx->ndisplayvariables = j;
9409566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables));
9419566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues));
942d0c080abSJoseph Pusztay   j = 0;
943d0c080abSJoseph Pusztay   while (displaynames[j]) {
944d0c080abSJoseph Pusztay     k = 0;
945d0c080abSJoseph Pusztay     while (ctx->names[k]) {
946d0c080abSJoseph Pusztay       PetscBool flg;
9479566063dSJacob Faibussowitsch       PetscCall(PetscStrcmp(displaynames[j],ctx->names[k],&flg));
948d0c080abSJoseph Pusztay       if (flg) {
949d0c080abSJoseph Pusztay         ctx->displayvariables[j] = k;
950d0c080abSJoseph Pusztay         break;
951d0c080abSJoseph Pusztay       }
952d0c080abSJoseph Pusztay       k++;
953d0c080abSJoseph Pusztay     }
954d0c080abSJoseph Pusztay     j++;
955d0c080abSJoseph Pusztay   }
956d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
957d0c080abSJoseph Pusztay }
958d0c080abSJoseph Pusztay 
959d0c080abSJoseph Pusztay /*@C
960d0c080abSJoseph Pusztay    TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor
961d0c080abSJoseph Pusztay 
962d0c080abSJoseph Pusztay    Collective on TS
963d0c080abSJoseph Pusztay 
964d0c080abSJoseph Pusztay    Input Parameters:
965d0c080abSJoseph Pusztay +  ts - the TS context
966d0c080abSJoseph Pusztay -  displaynames - the names of the components, final string must be NULL
967d0c080abSJoseph Pusztay 
968d0c080abSJoseph Pusztay    Notes:
969d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
970d0c080abSJoseph Pusztay 
971d0c080abSJoseph Pusztay    Level: intermediate
972d0c080abSJoseph Pusztay 
973db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`
974d0c080abSJoseph Pusztay @*/
975d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames)
976d0c080abSJoseph Pusztay {
977d0c080abSJoseph Pusztay   PetscInt          i;
978d0c080abSJoseph Pusztay 
979d0c080abSJoseph Pusztay   PetscFunctionBegin;
980d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
981d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
9829566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames));
983d0c080abSJoseph Pusztay       break;
984d0c080abSJoseph Pusztay     }
985d0c080abSJoseph Pusztay   }
986d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
987d0c080abSJoseph Pusztay }
988d0c080abSJoseph Pusztay 
989d0c080abSJoseph Pusztay /*@C
990d0c080abSJoseph Pusztay    TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed
991d0c080abSJoseph Pusztay 
992d0c080abSJoseph Pusztay    Collective on TS
993d0c080abSJoseph Pusztay 
994d0c080abSJoseph Pusztay    Input Parameters:
995d0c080abSJoseph Pusztay +  ts - the TS context
996d0c080abSJoseph Pusztay .  transform - the transform function
997d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
998d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
999d0c080abSJoseph Pusztay 
1000d0c080abSJoseph Pusztay    Notes:
1001d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
1002d0c080abSJoseph Pusztay 
1003d0c080abSJoseph Pusztay    Level: intermediate
1004d0c080abSJoseph Pusztay 
1005db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`, `TSMonitorLGCtxSetTransform()`
1006d0c080abSJoseph Pusztay @*/
1007d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
1008d0c080abSJoseph Pusztay {
1009d0c080abSJoseph Pusztay   PetscInt          i;
1010d0c080abSJoseph Pusztay 
1011d0c080abSJoseph Pusztay   PetscFunctionBegin;
1012d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
1013d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
10149566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx));
1015d0c080abSJoseph Pusztay     }
1016d0c080abSJoseph Pusztay   }
1017d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1018d0c080abSJoseph Pusztay }
1019d0c080abSJoseph Pusztay 
1020d0c080abSJoseph Pusztay /*@C
1021d0c080abSJoseph Pusztay    TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed
1022d0c080abSJoseph Pusztay 
1023d0c080abSJoseph Pusztay    Collective on TSLGCtx
1024d0c080abSJoseph Pusztay 
1025d0c080abSJoseph Pusztay    Input Parameters:
1026d0c080abSJoseph Pusztay +  ts - the TS context
1027d0c080abSJoseph Pusztay .  transform - the transform function
1028d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
1029d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
1030d0c080abSJoseph Pusztay 
1031d0c080abSJoseph Pusztay    Level: intermediate
1032d0c080abSJoseph Pusztay 
1033db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`, `TSMonitorLGSetTransform()`
1034d0c080abSJoseph Pusztay @*/
1035d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
1036d0c080abSJoseph Pusztay {
1037d0c080abSJoseph Pusztay   PetscFunctionBegin;
1038d0c080abSJoseph Pusztay   ctx->transform    = transform;
1039d0c080abSJoseph Pusztay   ctx->transformdestroy = destroy;
1040d0c080abSJoseph Pusztay   ctx->transformctx = tctx;
1041d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1042d0c080abSJoseph Pusztay }
1043d0c080abSJoseph Pusztay 
1044d0c080abSJoseph Pusztay /*@C
1045d0c080abSJoseph Pusztay    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error
1046d0c080abSJoseph Pusztay        in a time based line graph
1047d0c080abSJoseph Pusztay 
1048d0c080abSJoseph Pusztay    Collective on TS
1049d0c080abSJoseph Pusztay 
1050d0c080abSJoseph Pusztay    Input Parameters:
1051d0c080abSJoseph Pusztay +  ts - the TS context
1052d0c080abSJoseph Pusztay .  step - current time-step
1053d0c080abSJoseph Pusztay .  ptime - current time
1054d0c080abSJoseph Pusztay .  u - current solution
1055d0c080abSJoseph Pusztay -  dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate()
1056d0c080abSJoseph Pusztay 
1057d0c080abSJoseph Pusztay    Level: intermediate
1058d0c080abSJoseph Pusztay 
1059d0c080abSJoseph Pusztay    Notes:
1060d0c080abSJoseph Pusztay     Each process in a parallel run displays its component errors in a separate window
1061d0c080abSJoseph Pusztay 
1062d0c080abSJoseph Pusztay    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
1063d0c080abSJoseph Pusztay 
1064d0c080abSJoseph Pusztay    Options Database Keys:
1065d0c080abSJoseph Pusztay .  -ts_monitor_lg_error - create a graphical monitor of error history
1066d0c080abSJoseph Pusztay 
1067db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
1068d0c080abSJoseph Pusztay @*/
1069d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
1070d0c080abSJoseph Pusztay {
1071d0c080abSJoseph Pusztay   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
1072d0c080abSJoseph Pusztay   const PetscScalar *yy;
1073d0c080abSJoseph Pusztay   Vec               y;
1074d0c080abSJoseph Pusztay 
1075d0c080abSJoseph Pusztay   PetscFunctionBegin;
1076d0c080abSJoseph Pusztay   if (!step) {
1077d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1078d0c080abSJoseph Pusztay     PetscInt      dim;
10799566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
10809566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Error"));
10819566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(u,&dim));
10829566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSetDimension(ctx->lg,dim));
10839566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1084d0c080abSJoseph Pusztay   }
10859566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u,&y));
10869566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts,ptime,y));
10879566063dSJacob Faibussowitsch   PetscCall(VecAXPY(y,-1.0,u));
10889566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(y,&yy));
1089d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
1090d0c080abSJoseph Pusztay   {
1091d0c080abSJoseph Pusztay     PetscReal *yreal;
1092d0c080abSJoseph Pusztay     PetscInt  i,n;
10939566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(y,&n));
10949566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&yreal));
1095d0c080abSJoseph Pusztay     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
10969566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal));
10979566063dSJacob Faibussowitsch     PetscCall(PetscFree(yreal));
1098d0c080abSJoseph Pusztay   }
1099d0c080abSJoseph Pusztay #else
11009566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy));
1101d0c080abSJoseph Pusztay #endif
11029566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(y,&yy));
11039566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&y));
1104d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
11059566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
11069566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1107d0c080abSJoseph Pusztay   }
1108d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1109d0c080abSJoseph Pusztay }
1110d0c080abSJoseph Pusztay 
1111d0c080abSJoseph Pusztay /*@C
1112d0c080abSJoseph Pusztay    TSMonitorSPSwarmSolution - Graphically displays phase plots of DMSwarm particles on a scatter plot
1113d0c080abSJoseph Pusztay 
1114d0c080abSJoseph Pusztay    Input Parameters:
1115d0c080abSJoseph Pusztay +  ts - the TS context
1116d0c080abSJoseph Pusztay .  step - current time-step
1117d0c080abSJoseph Pusztay .  ptime - current time
1118d0c080abSJoseph Pusztay .  u - current solution
1119d0c080abSJoseph Pusztay -  dctx - the TSMonitorSPCtx object that contains all the options for the monitoring, this is created with TSMonitorSPCtxCreate()
1120d0c080abSJoseph Pusztay 
1121d0c080abSJoseph Pusztay    Options Database:
1122d7462660SMatthew Knepley + -ts_monitor_sp_swarm <n>          - Monitor the solution every n steps, or -1 for plotting only the final solution
1123d7462660SMatthew Knepley . -ts_monitor_sp_swarm_retain <n>   - Retain n old points so we can see the history, or -1 for all points
1124d7462660SMatthew Knepley - -ts_monitor_sp_swarm_phase <bool> - Plot in phase space, as opposed to coordinate space
1125d0c080abSJoseph Pusztay 
1126d0c080abSJoseph Pusztay    Level: intermediate
1127d0c080abSJoseph Pusztay 
1128db781477SPatrick Sanan .seealso: `TSMonitoSet()`
1129d0c080abSJoseph Pusztay @*/
1130d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSPSwarmSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx)
1131d0c080abSJoseph Pusztay {
1132d0c080abSJoseph Pusztay   TSMonitorSPCtx     ctx = (TSMonitorSPCtx) dctx;
1133f98b2f00SMatthew G. Knepley   PetscDraw          draw;
1134d7462660SMatthew Knepley   DM                 dm, cdm;
1135d0c080abSJoseph Pusztay   const PetscScalar *yy;
1136d0c080abSJoseph Pusztay   PetscInt           Np, p, dim = 2;
1137d0c080abSJoseph Pusztay 
1138d0c080abSJoseph Pusztay   PetscFunctionBegin;
1139d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1140d0c080abSJoseph Pusztay   if (!step) {
1141d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1142ab43fcacSJoe Pusztay     PetscReal     dmboxlower[2], dmboxupper[2];
1143f98b2f00SMatthew G. Knepley 
11449566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &dm));
11459566063dSJacob Faibussowitsch     PetscCall(DMGetDimension(dm, &dim));
11463c633725SBarry Smith     PetscCheck(dim == 2, PETSC_COMM_SELF, PETSC_ERR_SUP, "Monitor only supports two dimensional fields");
11479566063dSJacob Faibussowitsch     PetscCall(DMSwarmGetCellDM(dm, &cdm));
11489566063dSJacob Faibussowitsch     PetscCall(DMGetBoundingBox(cdm, dmboxlower, dmboxupper));
11499566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(u, &Np));
1150d7462660SMatthew Knepley     Np /= dim*2;
11519566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPGetAxis(ctx->sp,&axis));
11528c87cf4dSdanfinn     if (ctx->phase) {
11539566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(axis,"Particles","X","V"));
11549566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], -5, 5));
11558c87cf4dSdanfinn     } else {
11569566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(axis,"Particles","X","Y"));
11579566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], dmboxlower[1], dmboxupper[1]));
11588c87cf4dSdanfinn     }
11599566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetHoldLimits(axis, PETSC_TRUE));
11609566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPReset(ctx->sp));
1161d0c080abSJoseph Pusztay   }
11629566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(u, &Np));
1163d7462660SMatthew Knepley   Np /= dim*2;
1164d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
11659566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPGetDraw(ctx->sp, &draw));
1166d7462660SMatthew Knepley     if ((ctx->retain == 0) || (ctx->retain > 0 && !(step % ctx->retain))) {
11679566063dSJacob Faibussowitsch       PetscCall(PetscDrawClear(draw));
1168d7462660SMatthew Knepley     }
11699566063dSJacob Faibussowitsch     PetscCall(PetscDrawFlush(draw));
11709566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPReset(ctx->sp));
1171f98b2f00SMatthew G. Knepley     PetscCall(VecGetArrayRead(u, &yy));
1172f98b2f00SMatthew G. Knepley     for (p = 0; p < Np; ++p) {
1173f98b2f00SMatthew G. Knepley       PetscReal x, y;
1174f98b2f00SMatthew G. Knepley 
1175f98b2f00SMatthew G. Knepley       if (ctx->phase) {
1176f98b2f00SMatthew G. Knepley         x = PetscRealPart(yy[p*dim*2]);
1177f98b2f00SMatthew G. Knepley         y = PetscRealPart(yy[p*dim*2 + dim]);
1178f98b2f00SMatthew G. Knepley       } else {
1179f98b2f00SMatthew G. Knepley         x = PetscRealPart(yy[p*dim*2]);
1180f98b2f00SMatthew G. Knepley         y = PetscRealPart(yy[p*dim*2 + 1]);
1181f98b2f00SMatthew G. Knepley       }
1182f98b2f00SMatthew G. Knepley       PetscCall(PetscDrawSPAddPoint(ctx->sp, &x, &y));
1183f98b2f00SMatthew G. Knepley     }
1184f98b2f00SMatthew G. Knepley     PetscCall(VecRestoreArrayRead(u, &yy));
11859566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPDraw(ctx->sp, PETSC_FALSE));
11869566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPSave(ctx->sp));
1187d0c080abSJoseph Pusztay   }
1188d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1189d0c080abSJoseph Pusztay }
1190d0c080abSJoseph Pusztay 
1191d0c080abSJoseph Pusztay /*@C
1192d0c080abSJoseph Pusztay    TSMonitorError - Monitors progress of the TS solvers by printing the 2 norm of the error at each timestep
1193d0c080abSJoseph Pusztay 
1194d0c080abSJoseph Pusztay    Collective on TS
1195d0c080abSJoseph Pusztay 
1196d0c080abSJoseph Pusztay    Input Parameters:
1197d0c080abSJoseph Pusztay +  ts - the TS context
1198d0c080abSJoseph Pusztay .  step - current time-step
1199d0c080abSJoseph Pusztay .  ptime - current time
1200d0c080abSJoseph Pusztay .  u - current solution
1201d0c080abSJoseph Pusztay -  dctx - unused context
1202d0c080abSJoseph Pusztay 
1203d0c080abSJoseph Pusztay    Level: intermediate
1204d0c080abSJoseph Pusztay 
1205d0c080abSJoseph Pusztay    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
1206d0c080abSJoseph Pusztay 
1207d0c080abSJoseph Pusztay    Options Database Keys:
1208d0c080abSJoseph Pusztay .  -ts_monitor_error - create a graphical monitor of error history
1209d0c080abSJoseph Pusztay 
1210db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
1211d0c080abSJoseph Pusztay @*/
1212d0c080abSJoseph Pusztay PetscErrorCode TSMonitorError(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
1213d0c080abSJoseph Pusztay {
121407eaae0cSMatthew G. Knepley   DM             dm;
121507eaae0cSMatthew G. Knepley   PetscDS        ds = NULL;
121607eaae0cSMatthew G. Knepley   PetscInt       Nf = -1, f;
1217d0c080abSJoseph Pusztay   PetscBool      flg;
1218d0c080abSJoseph Pusztay 
1219d0c080abSJoseph Pusztay   PetscFunctionBegin;
12209566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
12219566063dSJacob Faibussowitsch   if (dm) PetscCall(DMGetDS(dm, &ds));
12229566063dSJacob Faibussowitsch   if (ds) PetscCall(PetscDSGetNumFields(ds, &Nf));
122307eaae0cSMatthew G. Knepley   if (Nf <= 0) {
122407eaae0cSMatthew G. Knepley     Vec       y;
122507eaae0cSMatthew G. Knepley     PetscReal nrm;
122607eaae0cSMatthew G. Knepley 
12279566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u,&y));
12289566063dSJacob Faibussowitsch     PetscCall(TSComputeSolutionFunction(ts,ptime,y));
12299566063dSJacob Faibussowitsch     PetscCall(VecAXPY(y,-1.0,u));
12309566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERASCII,&flg));
1231d0c080abSJoseph Pusztay     if (flg) {
12329566063dSJacob Faibussowitsch       PetscCall(VecNorm(y,NORM_2,&nrm));
12339566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vf->viewer,"2-norm of error %g\n",(double)nrm));
1234d0c080abSJoseph Pusztay     }
12359566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERDRAW,&flg));
1236d0c080abSJoseph Pusztay     if (flg) {
12379566063dSJacob Faibussowitsch       PetscCall(VecView(y,vf->viewer));
1238d0c080abSJoseph Pusztay     }
12399566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&y));
124007eaae0cSMatthew G. Knepley   } else {
124107eaae0cSMatthew G. Knepley     PetscErrorCode (**exactFuncs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx);
124207eaae0cSMatthew G. Knepley     void            **ctxs;
124307eaae0cSMatthew G. Knepley     Vec               v;
124407eaae0cSMatthew G. Knepley     PetscReal         ferrors[1];
124507eaae0cSMatthew G. Knepley 
12469566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(Nf, &exactFuncs, Nf, &ctxs));
12479566063dSJacob Faibussowitsch     for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(ds, f, &exactFuncs[f], &ctxs[f]));
12489566063dSJacob Faibussowitsch     PetscCall(DMComputeL2FieldDiff(dm, ptime, exactFuncs, ctxs, u, ferrors));
12499566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Timestep: %04d time = %-8.4g \t L_2 Error: [", (int) step, (double) ptime));
125007eaae0cSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
12519566063dSJacob Faibussowitsch       if (f > 0) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ", "));
12529566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%2.3g", (double) ferrors[f]));
125307eaae0cSMatthew G. Knepley     }
12549566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "]\n"));
125507eaae0cSMatthew G. Knepley 
12569566063dSJacob Faibussowitsch     PetscCall(VecViewFromOptions(u, NULL, "-sol_vec_view"));
125707eaae0cSMatthew G. Knepley 
12589566063dSJacob Faibussowitsch     PetscCall(PetscOptionsHasName(NULL, NULL, "-exact_vec_view", &flg));
125907eaae0cSMatthew G. Knepley     if (flg) {
12609566063dSJacob Faibussowitsch       PetscCall(DMGetGlobalVector(dm, &v));
12619566063dSJacob Faibussowitsch       PetscCall(DMProjectFunction(dm, ptime, exactFuncs, ctxs, INSERT_ALL_VALUES, v));
12629566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetName((PetscObject) v, "Exact Solution"));
12639566063dSJacob Faibussowitsch       PetscCall(VecViewFromOptions(v, NULL, "-exact_vec_view"));
12649566063dSJacob Faibussowitsch       PetscCall(DMRestoreGlobalVector(dm, &v));
126507eaae0cSMatthew G. Knepley     }
12669566063dSJacob Faibussowitsch     PetscCall(PetscFree2(exactFuncs, ctxs));
126707eaae0cSMatthew G. Knepley   }
1268d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1269d0c080abSJoseph Pusztay }
1270d0c080abSJoseph Pusztay 
1271d0c080abSJoseph Pusztay PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
1272d0c080abSJoseph Pusztay {
1273d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
1274d0c080abSJoseph Pusztay   PetscReal      x   = ptime,y;
1275d0c080abSJoseph Pusztay   PetscInt       its;
1276d0c080abSJoseph Pusztay 
1277d0c080abSJoseph Pusztay   PetscFunctionBegin;
1278d0c080abSJoseph Pusztay   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1279d0c080abSJoseph Pusztay   if (!n) {
1280d0c080abSJoseph Pusztay     PetscDrawAxis axis;
12819566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
12829566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations"));
12839566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1284d0c080abSJoseph Pusztay     ctx->snes_its = 0;
1285d0c080abSJoseph Pusztay   }
12869566063dSJacob Faibussowitsch   PetscCall(TSGetSNESIterations(ts,&its));
1287d0c080abSJoseph Pusztay   y    = its - ctx->snes_its;
12889566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg,&x,&y));
1289d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
12909566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
12919566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1292d0c080abSJoseph Pusztay   }
1293d0c080abSJoseph Pusztay   ctx->snes_its = its;
1294d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1295d0c080abSJoseph Pusztay }
1296d0c080abSJoseph Pusztay 
1297d0c080abSJoseph Pusztay PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
1298d0c080abSJoseph Pusztay {
1299d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
1300d0c080abSJoseph Pusztay   PetscReal      x   = ptime,y;
1301d0c080abSJoseph Pusztay   PetscInt       its;
1302d0c080abSJoseph Pusztay 
1303d0c080abSJoseph Pusztay   PetscFunctionBegin;
1304d0c080abSJoseph Pusztay   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1305d0c080abSJoseph Pusztay   if (!n) {
1306d0c080abSJoseph Pusztay     PetscDrawAxis axis;
13079566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
13089566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations"));
13099566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1310d0c080abSJoseph Pusztay     ctx->ksp_its = 0;
1311d0c080abSJoseph Pusztay   }
13129566063dSJacob Faibussowitsch   PetscCall(TSGetKSPIterations(ts,&its));
1313d0c080abSJoseph Pusztay   y    = its - ctx->ksp_its;
13149566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg,&x,&y));
1315d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
13169566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
13179566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1318d0c080abSJoseph Pusztay   }
1319d0c080abSJoseph Pusztay   ctx->ksp_its = its;
1320d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1321d0c080abSJoseph Pusztay }
1322d0c080abSJoseph Pusztay 
1323d0c080abSJoseph Pusztay /*@C
1324d0c080abSJoseph Pusztay    TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope()
1325d0c080abSJoseph Pusztay 
1326d0c080abSJoseph Pusztay    Collective on TS
1327d0c080abSJoseph Pusztay 
1328d0c080abSJoseph Pusztay    Input Parameters:
1329d0c080abSJoseph Pusztay .  ts  - the ODE solver object
1330d0c080abSJoseph Pusztay 
1331d0c080abSJoseph Pusztay    Output Parameter:
1332d0c080abSJoseph Pusztay .  ctx - the context
1333d0c080abSJoseph Pusztay 
1334d0c080abSJoseph Pusztay    Level: intermediate
1335d0c080abSJoseph Pusztay 
1336db781477SPatrick Sanan .seealso: `TSMonitorLGTimeStep()`, `TSMonitorSet()`, `TSMonitorLGSolution()`, `TSMonitorLGError()`
1337d0c080abSJoseph Pusztay 
1338d0c080abSJoseph Pusztay @*/
1339d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx)
1340d0c080abSJoseph Pusztay {
1341d0c080abSJoseph Pusztay   PetscFunctionBegin;
13429566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
1343d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1344d0c080abSJoseph Pusztay }
1345d0c080abSJoseph Pusztay 
1346d0c080abSJoseph Pusztay /*@C
1347d0c080abSJoseph Pusztay    TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution
1348d0c080abSJoseph Pusztay 
1349d0c080abSJoseph Pusztay    Collective on TS
1350d0c080abSJoseph Pusztay 
1351d0c080abSJoseph Pusztay    Input Parameters:
1352d0c080abSJoseph Pusztay +  ts - the TS context
1353d0c080abSJoseph Pusztay .  step - current time-step
1354d0c080abSJoseph Pusztay .  ptime - current time
1355d0c080abSJoseph Pusztay .  u  - current solution
1356d0c080abSJoseph Pusztay -  dctx - the envelope context
1357d0c080abSJoseph Pusztay 
1358d0c080abSJoseph Pusztay    Options Database:
135967b8a455SSatish Balay .  -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time
1360d0c080abSJoseph Pusztay 
1361d0c080abSJoseph Pusztay    Level: intermediate
1362d0c080abSJoseph Pusztay 
1363d0c080abSJoseph Pusztay    Notes:
1364d0c080abSJoseph Pusztay     after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope
1365d0c080abSJoseph Pusztay 
1366db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxCreate()`
1367d0c080abSJoseph Pusztay @*/
1368d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
1369d0c080abSJoseph Pusztay {
1370d0c080abSJoseph Pusztay   TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx;
1371d0c080abSJoseph Pusztay 
1372d0c080abSJoseph Pusztay   PetscFunctionBegin;
1373d0c080abSJoseph Pusztay   if (!ctx->max) {
13749566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u,&ctx->max));
13759566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u,&ctx->min));
13769566063dSJacob Faibussowitsch     PetscCall(VecCopy(u,ctx->max));
13779566063dSJacob Faibussowitsch     PetscCall(VecCopy(u,ctx->min));
1378d0c080abSJoseph Pusztay   } else {
13799566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMax(ctx->max,u,ctx->max));
13809566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMin(ctx->min,u,ctx->min));
1381d0c080abSJoseph Pusztay   }
1382d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1383d0c080abSJoseph Pusztay }
1384d0c080abSJoseph Pusztay 
1385d0c080abSJoseph Pusztay /*@C
1386d0c080abSJoseph Pusztay    TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution
1387d0c080abSJoseph Pusztay 
1388d0c080abSJoseph Pusztay    Collective on TS
1389d0c080abSJoseph Pusztay 
1390d0c080abSJoseph Pusztay    Input Parameter:
1391d0c080abSJoseph Pusztay .  ts - the TS context
1392d0c080abSJoseph Pusztay 
1393d8d19677SJose E. Roman    Output Parameters:
1394d0c080abSJoseph Pusztay +  max - the maximum values
1395d0c080abSJoseph Pusztay -  min - the minimum values
1396d0c080abSJoseph Pusztay 
1397d0c080abSJoseph Pusztay    Notes:
1398d0c080abSJoseph Pusztay     If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored
1399d0c080abSJoseph Pusztay 
1400d0c080abSJoseph Pusztay    Level: intermediate
1401d0c080abSJoseph Pusztay 
1402db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`
1403d0c080abSJoseph Pusztay @*/
1404d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min)
1405d0c080abSJoseph Pusztay {
1406d0c080abSJoseph Pusztay   PetscInt i;
1407d0c080abSJoseph Pusztay 
1408d0c080abSJoseph Pusztay   PetscFunctionBegin;
1409d0c080abSJoseph Pusztay   if (max) *max = NULL;
1410d0c080abSJoseph Pusztay   if (min) *min = NULL;
1411d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
1412d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorEnvelope) {
1413d0c080abSJoseph Pusztay       TSMonitorEnvelopeCtx  ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i];
1414d0c080abSJoseph Pusztay       if (max) *max = ctx->max;
1415d0c080abSJoseph Pusztay       if (min) *min = ctx->min;
1416d0c080abSJoseph Pusztay       break;
1417d0c080abSJoseph Pusztay     }
1418d0c080abSJoseph Pusztay   }
1419d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1420d0c080abSJoseph Pusztay }
1421d0c080abSJoseph Pusztay 
1422d0c080abSJoseph Pusztay /*@C
1423d0c080abSJoseph Pusztay    TSMonitorEnvelopeCtxDestroy - Destroys a context that was created  with TSMonitorEnvelopeCtxCreate().
1424d0c080abSJoseph Pusztay 
1425d0c080abSJoseph Pusztay    Collective on TSMonitorEnvelopeCtx
1426d0c080abSJoseph Pusztay 
1427d0c080abSJoseph Pusztay    Input Parameter:
1428d0c080abSJoseph Pusztay .  ctx - the monitor context
1429d0c080abSJoseph Pusztay 
1430d0c080abSJoseph Pusztay    Level: intermediate
1431d0c080abSJoseph Pusztay 
1432db781477SPatrick Sanan .seealso: `TSMonitorLGCtxCreate()`, `TSMonitorSet()`, `TSMonitorLGTimeStep()`
1433d0c080abSJoseph Pusztay @*/
1434d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx)
1435d0c080abSJoseph Pusztay {
1436d0c080abSJoseph Pusztay   PetscFunctionBegin;
14379566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ctx)->min));
14389566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ctx)->max));
14399566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
1440d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1441d0c080abSJoseph Pusztay }
1442d0c080abSJoseph Pusztay 
1443d0c080abSJoseph Pusztay /*@C
1444d0c080abSJoseph Pusztay   TSDMSwarmMonitorMoments - Monitors the first three moments of a DMSarm being evolved by the TS
1445d0c080abSJoseph Pusztay 
1446d0c080abSJoseph Pusztay   Not collective
1447d0c080abSJoseph Pusztay 
1448d0c080abSJoseph Pusztay   Input Parameters:
1449d0c080abSJoseph Pusztay + ts   - the TS context
1450d0c080abSJoseph Pusztay . step - current timestep
1451d0c080abSJoseph Pusztay . t    - current time
1452d0c080abSJoseph Pusztay . u    - current solution
1453d0c080abSJoseph Pusztay - ctx  - not used
1454d0c080abSJoseph Pusztay 
1455d0c080abSJoseph Pusztay   Options Database:
145667b8a455SSatish Balay . -ts_dmswarm_monitor_moments - Monitor moments of particle distribution
1457d0c080abSJoseph Pusztay 
1458d0c080abSJoseph Pusztay   Level: intermediate
1459d0c080abSJoseph Pusztay 
1460d0c080abSJoseph Pusztay   Notes:
1461d0c080abSJoseph Pusztay   This requires a DMSwarm be attached to the TS.
1462d0c080abSJoseph Pusztay 
1463db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `DMSWARM`
1464d0c080abSJoseph Pusztay @*/
1465d0c080abSJoseph Pusztay PetscErrorCode TSDMSwarmMonitorMoments(TS ts, PetscInt step, PetscReal t, Vec U, PetscViewerAndFormat *vf)
1466d0c080abSJoseph Pusztay {
1467d0c080abSJoseph Pusztay   DM                 sw;
1468d0c080abSJoseph Pusztay   const PetscScalar *u;
1469d0c080abSJoseph Pusztay   PetscReal          m = 1.0, totE = 0., totMom[3] = {0., 0., 0.};
1470d0c080abSJoseph Pusztay   PetscInt           dim, d, Np, p;
1471d0c080abSJoseph Pusztay   MPI_Comm           comm;
1472d0c080abSJoseph Pusztay 
1473d0c080abSJoseph Pusztay   PetscFunctionBeginUser;
14749566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &sw));
1475d0c080abSJoseph Pusztay   if (!sw || step%ts->monitorFrequency != 0) PetscFunctionReturn(0);
14769566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject) ts, &comm));
14779566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(sw, &dim));
14789566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(U, &Np));
1479d0c080abSJoseph Pusztay   Np  /= dim;
14809566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U, &u));
1481d0c080abSJoseph Pusztay   for (p = 0; p < Np; ++p) {
1482d0c080abSJoseph Pusztay     for (d = 0; d < dim; ++d) {
1483d0c080abSJoseph Pusztay       totE      += PetscRealPart(u[p*dim+d]*u[p*dim+d]);
1484d0c080abSJoseph Pusztay       totMom[d] += PetscRealPart(u[p*dim+d]);
1485d0c080abSJoseph Pusztay     }
1486d0c080abSJoseph Pusztay   }
14879566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U, &u));
1488d0c080abSJoseph Pusztay   for (d = 0; d < dim; ++d) totMom[d] *= m;
1489d0c080abSJoseph Pusztay   totE *= 0.5*m;
149063a3b9bcSJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "Step %4" PetscInt_FMT " Total Energy: %10.8lf", step, (double) totE));
149163a3b9bcSJacob Faibussowitsch   for (d = 0; d < dim; ++d) PetscCall(PetscPrintf(comm, "    Total Momentum %c: %10.8lf", (char)('x'+d), (double) totMom[d]));
14929566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "\n"));
1493d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1494d0c080abSJoseph Pusztay }
1495