xref: /petsc/src/ts/interface/tsmon.c (revision 3a61192c58448b12cde16ea84d8948c8e04fc9e4)
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()`,
66db781477SPatrick 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 
122*3a61192cSBarry Smith .seealso: `TSMonitorDefault()`, `TSMonitorCancel()`, `TSDMSwarmMonitorMoments()`, `TSMonitorExtreme()`,  `TSMonitorDrawSolution()`,
123*3a61192cSBarry Smith           `TSMonitorDrawSolutionPhase()`, `TSMonitorDrawSolutionFunction()`, `TSMonitorDrawError()`, `TSMonitorSolution()`, `TSMonitorSolutionVTK()`,
124*3a61192cSBarry Smith           `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorSPSwarmSolution()`, `TSMonitorError()`, `TSMonitorEnvelope()`, `TSDMSwarmMonitorMoments()`
125d0c080abSJoseph Pusztay @*/
126d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**))
127d0c080abSJoseph Pusztay {
128d0c080abSJoseph Pusztay   PetscInt       i;
129d0c080abSJoseph Pusztay   PetscBool      identical;
130d0c080abSJoseph Pusztay 
131d0c080abSJoseph Pusztay   PetscFunctionBegin;
132d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
133d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors;i++) {
1349566063dSJacob Faibussowitsch     PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical));
135d0c080abSJoseph Pusztay     if (identical) PetscFunctionReturn(0);
136d0c080abSJoseph Pusztay   }
1373c633725SBarry Smith   PetscCheck(ts->numbermonitors < MAXTSMONITORS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
138d0c080abSJoseph Pusztay   ts->monitor[ts->numbermonitors]          = monitor;
139d0c080abSJoseph Pusztay   ts->monitordestroy[ts->numbermonitors]   = mdestroy;
140d0c080abSJoseph Pusztay   ts->monitorcontext[ts->numbermonitors++] = (void*)mctx;
141d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
142d0c080abSJoseph Pusztay }
143d0c080abSJoseph Pusztay 
144d0c080abSJoseph Pusztay /*@C
145d0c080abSJoseph Pusztay    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
146d0c080abSJoseph Pusztay 
147d0c080abSJoseph Pusztay    Logically Collective on TS
148d0c080abSJoseph Pusztay 
149d0c080abSJoseph Pusztay    Input Parameters:
150d0c080abSJoseph Pusztay .  ts - the TS context obtained from TSCreate()
151d0c080abSJoseph Pusztay 
152d0c080abSJoseph Pusztay    Notes:
153d0c080abSJoseph Pusztay    There is no way to remove a single, specific monitor.
154d0c080abSJoseph Pusztay 
155d0c080abSJoseph Pusztay    Level: intermediate
156d0c080abSJoseph Pusztay 
157db781477SPatrick Sanan .seealso: `TSMonitorDefault()`, `TSMonitorSet()`
158d0c080abSJoseph Pusztay @*/
159d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorCancel(TS ts)
160d0c080abSJoseph Pusztay {
161d0c080abSJoseph Pusztay   PetscInt       i;
162d0c080abSJoseph Pusztay 
163d0c080abSJoseph Pusztay   PetscFunctionBegin;
164d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
165d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
166d0c080abSJoseph Pusztay     if (ts->monitordestroy[i]) {
1679566063dSJacob Faibussowitsch       PetscCall((*ts->monitordestroy[i])(&ts->monitorcontext[i]));
168d0c080abSJoseph Pusztay     }
169d0c080abSJoseph Pusztay   }
170d0c080abSJoseph Pusztay   ts->numbermonitors = 0;
171d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
172d0c080abSJoseph Pusztay }
173d0c080abSJoseph Pusztay 
174d0c080abSJoseph Pusztay /*@C
175d0c080abSJoseph Pusztay    TSMonitorDefault - The Default monitor, prints the timestep and time for each step
176d0c080abSJoseph Pusztay 
177*3a61192cSBarry Smith    Options Database:
178*3a61192cSBarry Smith .  -ts_monitor - monitors the time integration
179*3a61192cSBarry Smith 
180*3a61192cSBarry Smith    Notes:
181*3a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
182*3a61192cSBarry Smith    to be used during the TS integration.
183*3a61192cSBarry Smith 
184d0c080abSJoseph Pusztay    Level: intermediate
185d0c080abSJoseph Pusztay 
186*3a61192cSBarry Smith .seealso: `TSMonitorSet()`,  `TSDMSwarmMonitorMoments()`, `TSMonitorExtreme()`,  `TSMonitorDrawSolution()`,
187*3a61192cSBarry Smith           `TSMonitorDrawSolutionPhase()`, `TSMonitorDrawSolutionFunction()`, `TSMonitorDrawError()`, `TSMonitorSolution()`, `TSMonitorSolutionVTK()`,
188*3a61192cSBarry Smith           `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorSPSwarmSolution()`, `TSMonitorError()`, `TSMonitorEnvelope()`, `TSDMSwarmMonitorMoments()`
189d0c080abSJoseph Pusztay @*/
190d0c080abSJoseph Pusztay PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf)
191d0c080abSJoseph Pusztay {
192d0c080abSJoseph Pusztay   PetscViewer    viewer =  vf->viewer;
193d0c080abSJoseph Pusztay   PetscBool      iascii,ibinary;
194d0c080abSJoseph Pusztay 
195d0c080abSJoseph Pusztay   PetscFunctionBegin;
196064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,5);
1979566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
1989566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary));
1999566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,vf->format));
200d0c080abSJoseph Pusztay   if (iascii) {
2019566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel));
202d0c080abSJoseph Pusztay     if (step == -1) { /* this indicates it is an interpolated solution */
20363a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %" PetscInt_FMT " and %" PetscInt_FMT "\n",(double)ptime,ts->steps-1,ts->steps));
204d0c080abSJoseph Pusztay     } else {
20563a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT " TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n"));
206d0c080abSJoseph Pusztay     }
2079566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel));
208d0c080abSJoseph Pusztay   } else if (ibinary) {
209d0c080abSJoseph Pusztay     PetscMPIInt rank;
2109566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank));
211d0c080abSJoseph Pusztay     if (!rank) {
212d0c080abSJoseph Pusztay       PetscBool skipHeader;
213d0c080abSJoseph Pusztay       PetscInt  classid = REAL_FILE_CLASSID;
214d0c080abSJoseph Pusztay 
2159566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryGetSkipHeader(viewer,&skipHeader));
216d0c080abSJoseph Pusztay       if (!skipHeader) {
2179566063dSJacob Faibussowitsch          PetscCall(PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT));
218d0c080abSJoseph Pusztay        }
2199566063dSJacob Faibussowitsch       PetscCall(PetscRealView(1,&ptime,viewer));
220d0c080abSJoseph Pusztay     } else {
2219566063dSJacob Faibussowitsch       PetscCall(PetscRealView(0,&ptime,viewer));
222d0c080abSJoseph Pusztay     }
223d0c080abSJoseph Pusztay   }
2249566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
225d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
226d0c080abSJoseph Pusztay }
227d0c080abSJoseph Pusztay 
228d0c080abSJoseph Pusztay /*@C
229d0c080abSJoseph Pusztay    TSMonitorExtreme - Prints the extreme values of the solution at each timestep
230d0c080abSJoseph Pusztay 
231*3a61192cSBarry Smith    Notes:
232*3a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
233*3a61192cSBarry Smith    to be used during the TS integration.
234*3a61192cSBarry Smith 
235d0c080abSJoseph Pusztay    Level: intermediate
236d0c080abSJoseph Pusztay 
237db781477SPatrick Sanan .seealso: `TSMonitorSet()`
238d0c080abSJoseph Pusztay @*/
239d0c080abSJoseph Pusztay PetscErrorCode TSMonitorExtreme(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf)
240d0c080abSJoseph Pusztay {
241d0c080abSJoseph Pusztay   PetscViewer    viewer =  vf->viewer;
242d0c080abSJoseph Pusztay   PetscBool      iascii;
243d0c080abSJoseph Pusztay   PetscReal      max,min;
244d0c080abSJoseph Pusztay 
245d0c080abSJoseph Pusztay   PetscFunctionBegin;
246064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,5);
2479566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
2489566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,vf->format));
249d0c080abSJoseph Pusztay   if (iascii) {
2509566063dSJacob Faibussowitsch     PetscCall(VecMax(v,NULL,&max));
2519566063dSJacob Faibussowitsch     PetscCall(VecMin(v,NULL,&min));
2529566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel));
25363a3b9bcSJacob 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));
2549566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel));
255d0c080abSJoseph Pusztay   }
2569566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
257d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
258d0c080abSJoseph Pusztay }
259d0c080abSJoseph Pusztay 
260d0c080abSJoseph Pusztay /*@C
261d0c080abSJoseph Pusztay    TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with
262d0c080abSJoseph Pusztay    TS to monitor the solution process graphically in various ways
263d0c080abSJoseph Pusztay 
264d0c080abSJoseph Pusztay    Collective on TS
265d0c080abSJoseph Pusztay 
266d0c080abSJoseph Pusztay    Input Parameters:
267d0c080abSJoseph Pusztay +  host - the X display to open, or null for the local machine
268d0c080abSJoseph Pusztay .  label - the title to put in the title bar
269d0c080abSJoseph Pusztay .  x, y - the screen coordinates of the upper left coordinate of the window
270d0c080abSJoseph Pusztay .  m, n - the screen width and height in pixels
271d0c080abSJoseph Pusztay -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
272d0c080abSJoseph Pusztay 
273d0c080abSJoseph Pusztay    Output Parameter:
274d0c080abSJoseph Pusztay .  ctx - the context
275d0c080abSJoseph Pusztay 
276d0c080abSJoseph Pusztay    Options Database Key:
277d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep - automatically sets line graph monitor
278d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep_log - automatically sets line graph monitor
279d0c080abSJoseph Pusztay .  -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables())
280d0c080abSJoseph Pusztay .  -ts_monitor_lg_error -  monitor the error
281d0c080abSJoseph Pusztay .  -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep
282d0c080abSJoseph Pusztay .  -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep
283d0c080abSJoseph Pusztay -  -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true
284d0c080abSJoseph Pusztay 
285d0c080abSJoseph Pusztay    Notes:
286d0c080abSJoseph Pusztay    Use TSMonitorLGCtxDestroy() to destroy.
287d0c080abSJoseph Pusztay 
288d0c080abSJoseph Pusztay    One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform()
289d0c080abSJoseph Pusztay 
290d0c080abSJoseph 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
291d0c080abSJoseph 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
292d0c080abSJoseph Pusztay    as the first argument.
293d0c080abSJoseph Pusztay 
294d0c080abSJoseph Pusztay    One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames()
295d0c080abSJoseph Pusztay 
296d0c080abSJoseph Pusztay    Level: intermediate
297d0c080abSJoseph Pusztay 
298db781477SPatrick Sanan .seealso: `TSMonitorLGTimeStep()`, `TSMonitorSet()`, `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorDefault()`, `VecView()`,
299db781477SPatrick Sanan           `TSMonitorLGCtxCreate()`, `TSMonitorLGCtxSetVariableNames()`, `TSMonitorLGCtxGetVariableNames()`,
300db781477SPatrick Sanan           `TSMonitorLGSetVariableNames()`, `TSMonitorLGGetVariableNames()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetDisplayVariables()`,
301db781477SPatrick Sanan           `TSMonitorLGCtxSetTransform()`, `TSMonitorLGSetTransform()`, `TSMonitorLGError()`, `TSMonitorLGSNESIterations()`, `TSMonitorLGKSPIterations()`,
302db781477SPatrick Sanan           `TSMonitorEnvelopeCtxCreate()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxDestroy()`, `TSMonitorEnvelop()`
303d0c080abSJoseph Pusztay 
304d0c080abSJoseph Pusztay @*/
305d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
306d0c080abSJoseph Pusztay {
307d0c080abSJoseph Pusztay   PetscDraw      draw;
308d0c080abSJoseph Pusztay 
309d0c080abSJoseph Pusztay   PetscFunctionBegin;
3109566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
3119566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm,host,label,x,y,m,n,&draw));
3129566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetFromOptions(draw));
3139566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGCreate(draw,1,&(*ctx)->lg));
3149566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGSetFromOptions((*ctx)->lg));
3159566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw));
316d0c080abSJoseph Pusztay   (*ctx)->howoften = howoften;
317d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
318d0c080abSJoseph Pusztay }
319d0c080abSJoseph Pusztay 
320d0c080abSJoseph Pusztay PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx)
321d0c080abSJoseph Pusztay {
322d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
323d0c080abSJoseph Pusztay   PetscReal      x   = ptime,y;
324d0c080abSJoseph Pusztay 
325d0c080abSJoseph Pusztay   PetscFunctionBegin;
326d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */
327d0c080abSJoseph Pusztay   if (!step) {
328d0c080abSJoseph Pusztay     PetscDrawAxis axis;
329d0c080abSJoseph Pusztay     const char *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step";
3309566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
3319566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time",ylabel));
3329566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
333d0c080abSJoseph Pusztay   }
3349566063dSJacob Faibussowitsch   PetscCall(TSGetTimeStep(ts,&y));
335d0c080abSJoseph Pusztay   if (ctx->semilogy) y = PetscLog10Real(y);
3369566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg,&x,&y));
337d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
3389566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
3399566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
340d0c080abSJoseph Pusztay   }
341d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
342d0c080abSJoseph Pusztay }
343d0c080abSJoseph Pusztay 
344d0c080abSJoseph Pusztay /*@C
345d0c080abSJoseph Pusztay    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
346d0c080abSJoseph Pusztay    with TSMonitorLGCtxCreate().
347d0c080abSJoseph Pusztay 
348d0c080abSJoseph Pusztay    Collective on TSMonitorLGCtx
349d0c080abSJoseph Pusztay 
350d0c080abSJoseph Pusztay    Input Parameter:
351d0c080abSJoseph Pusztay .  ctx - the monitor context
352d0c080abSJoseph Pusztay 
353d0c080abSJoseph Pusztay    Level: intermediate
354d0c080abSJoseph Pusztay 
355db781477SPatrick Sanan .seealso: `TSMonitorLGCtxCreate()`, `TSMonitorSet()`, `TSMonitorLGTimeStep();`
356d0c080abSJoseph Pusztay @*/
357d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
358d0c080abSJoseph Pusztay {
359d0c080abSJoseph Pusztay   PetscFunctionBegin;
360d0c080abSJoseph Pusztay   if ((*ctx)->transformdestroy) {
3619566063dSJacob Faibussowitsch     PetscCall(((*ctx)->transformdestroy)((*ctx)->transformctx));
362d0c080abSJoseph Pusztay   }
3639566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGDestroy(&(*ctx)->lg));
3649566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&(*ctx)->names));
3659566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&(*ctx)->displaynames));
3669566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ctx)->displayvariables));
3679566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ctx)->displayvalues));
3689566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
369d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
370d0c080abSJoseph Pusztay }
371d0c080abSJoseph Pusztay 
372d7462660SMatthew Knepley /* Creates a TS Monitor SPCtx for use with DMSwarm particle visualizations */
373d7462660SMatthew 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)
374d0c080abSJoseph Pusztay {
375d0c080abSJoseph Pusztay   PetscDraw      draw;
376d0c080abSJoseph Pusztay 
377d0c080abSJoseph Pusztay   PetscFunctionBegin;
3789566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
3799566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm,host,label,x,y,m,n,&draw));
3809566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetFromOptions(draw));
3819566063dSJacob Faibussowitsch   PetscCall(PetscDrawSPCreate(draw,1,&(*ctx)->sp));
3829566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw));
383d0c080abSJoseph Pusztay   (*ctx)->howoften = howoften;
384d7462660SMatthew Knepley   (*ctx)->retain   = retain;
385d7462660SMatthew Knepley   (*ctx)->phase    = phase;
386d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
387d0c080abSJoseph Pusztay }
388d0c080abSJoseph Pusztay 
389d0c080abSJoseph Pusztay /*
390d0c080abSJoseph Pusztay   Destroys a TSMonitorSPCtx that was created with TSMonitorSPCtxCreate
391d0c080abSJoseph Pusztay */
392d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSPCtxDestroy(TSMonitorSPCtx *ctx)
393d0c080abSJoseph Pusztay {
394d0c080abSJoseph Pusztay   PetscFunctionBegin;
395d0c080abSJoseph Pusztay 
3969566063dSJacob Faibussowitsch   PetscCall(PetscDrawSPDestroy(&(*ctx)->sp));
3979566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
398d0c080abSJoseph Pusztay 
399d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
400d0c080abSJoseph Pusztay 
401d0c080abSJoseph Pusztay }
402d0c080abSJoseph Pusztay 
403d0c080abSJoseph Pusztay /*@C
404d0c080abSJoseph Pusztay    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
405d0c080abSJoseph Pusztay    VecView() for the solution at each timestep
406d0c080abSJoseph Pusztay 
407d0c080abSJoseph Pusztay    Collective on TS
408d0c080abSJoseph Pusztay 
409d0c080abSJoseph Pusztay    Input Parameters:
410d0c080abSJoseph Pusztay +  ts - the TS context
411d0c080abSJoseph Pusztay .  step - current time-step
412d0c080abSJoseph Pusztay .  ptime - current time
413d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
414d0c080abSJoseph Pusztay 
415d0c080abSJoseph Pusztay    Options Database:
416d0c080abSJoseph Pusztay .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
417d0c080abSJoseph Pusztay 
418d0c080abSJoseph Pusztay    Notes:
419*3a61192cSBarry Smith    The initial solution and current solution are not displayed with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
420d0c080abSJoseph Pusztay    will look bad
421d0c080abSJoseph Pusztay 
422*3a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
423*3a61192cSBarry Smith    to be used during the TS integration.
424*3a61192cSBarry Smith 
425d0c080abSJoseph Pusztay    Level: intermediate
426d0c080abSJoseph Pusztay 
427db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
428d0c080abSJoseph Pusztay @*/
429d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
430d0c080abSJoseph Pusztay {
431d0c080abSJoseph Pusztay   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
432d0c080abSJoseph Pusztay   PetscDraw        draw;
433d0c080abSJoseph Pusztay 
434d0c080abSJoseph Pusztay   PetscFunctionBegin;
435d0c080abSJoseph Pusztay   if (!step && ictx->showinitial) {
436d0c080abSJoseph Pusztay     if (!ictx->initialsolution) {
4379566063dSJacob Faibussowitsch       PetscCall(VecDuplicate(u,&ictx->initialsolution));
438d0c080abSJoseph Pusztay     }
4399566063dSJacob Faibussowitsch     PetscCall(VecCopy(u,ictx->initialsolution));
440d0c080abSJoseph Pusztay   }
441d0c080abSJoseph Pusztay   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
442d0c080abSJoseph Pusztay 
443d0c080abSJoseph Pusztay   if (ictx->showinitial) {
444d0c080abSJoseph Pusztay     PetscReal pause;
4459566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetPause(ictx->viewer,&pause));
4469566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetPause(ictx->viewer,0.0));
4479566063dSJacob Faibussowitsch     PetscCall(VecView(ictx->initialsolution,ictx->viewer));
4489566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetPause(ictx->viewer,pause));
4499566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE));
450d0c080abSJoseph Pusztay   }
4519566063dSJacob Faibussowitsch   PetscCall(VecView(u,ictx->viewer));
452d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
453d0c080abSJoseph Pusztay     PetscReal xl,yl,xr,yr,h;
454d0c080abSJoseph Pusztay     char      time[32];
455d0c080abSJoseph Pusztay 
4569566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(ictx->viewer,0,&draw));
4579566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime));
4589566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr));
459d0c080abSJoseph Pusztay     h    = yl + .95*(yr - yl);
4609566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time));
4619566063dSJacob Faibussowitsch     PetscCall(PetscDrawFlush(draw));
462d0c080abSJoseph Pusztay   }
463d0c080abSJoseph Pusztay 
464d0c080abSJoseph Pusztay   if (ictx->showinitial) {
4659566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE));
466d0c080abSJoseph Pusztay   }
467d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
468d0c080abSJoseph Pusztay }
469d0c080abSJoseph Pusztay 
470d0c080abSJoseph Pusztay /*@C
471d0c080abSJoseph Pusztay    TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram
472d0c080abSJoseph Pusztay 
473d0c080abSJoseph Pusztay    Collective on TS
474d0c080abSJoseph Pusztay 
475d0c080abSJoseph Pusztay    Input Parameters:
476d0c080abSJoseph Pusztay +  ts - the TS context
477d0c080abSJoseph Pusztay .  step - current time-step
478d0c080abSJoseph Pusztay .  ptime - current time
479d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
480d0c080abSJoseph Pusztay 
481*3a61192cSBarry Smith    Notes:
482*3a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
483*3a61192cSBarry Smith    to be used during the TS integration.
484*3a61192cSBarry Smith 
485d0c080abSJoseph Pusztay    Level: intermediate
486d0c080abSJoseph Pusztay 
487db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
488d0c080abSJoseph Pusztay @*/
489d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
490d0c080abSJoseph Pusztay {
491d0c080abSJoseph Pusztay   TSMonitorDrawCtx  ictx = (TSMonitorDrawCtx)dummy;
492d0c080abSJoseph Pusztay   PetscDraw         draw;
493d0c080abSJoseph Pusztay   PetscDrawAxis     axis;
494d0c080abSJoseph Pusztay   PetscInt          n;
495d0c080abSJoseph Pusztay   PetscMPIInt       size;
496d0c080abSJoseph Pusztay   PetscReal         U0,U1,xl,yl,xr,yr,h;
497d0c080abSJoseph Pusztay   char              time[32];
498d0c080abSJoseph Pusztay   const PetscScalar *U;
499d0c080abSJoseph Pusztay 
500d0c080abSJoseph Pusztay   PetscFunctionBegin;
5019566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size));
5023c633725SBarry Smith   PetscCheck(size == 1,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs");
5039566063dSJacob Faibussowitsch   PetscCall(VecGetSize(u,&n));
5043c633725SBarry Smith   PetscCheck(n == 2,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns");
505d0c080abSJoseph Pusztay 
5069566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(ictx->viewer,0,&draw));
5079566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis));
5089566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr));
509d0c080abSJoseph Pusztay   if (!step) {
5109566063dSJacob Faibussowitsch     PetscCall(PetscDrawClear(draw));
5119566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisDraw(axis));
512d0c080abSJoseph Pusztay   }
513d0c080abSJoseph Pusztay 
5149566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(u,&U));
515d0c080abSJoseph Pusztay   U0 = PetscRealPart(U[0]);
516d0c080abSJoseph Pusztay   U1 = PetscRealPart(U[1]);
5179566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(u,&U));
518d0c080abSJoseph Pusztay   if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0);
519d0c080abSJoseph Pusztay 
520d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
5219566063dSJacob Faibussowitsch   PetscCall(PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK));
522d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
5239566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr));
5249566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime));
525d0c080abSJoseph Pusztay     h    = yl + .95*(yr - yl);
5269566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time));
527d0c080abSJoseph Pusztay   }
528d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
5299566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
5309566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
5319566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
532d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
533d0c080abSJoseph Pusztay }
534d0c080abSJoseph Pusztay 
535d0c080abSJoseph Pusztay /*@C
536d0c080abSJoseph Pusztay    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
537d0c080abSJoseph Pusztay 
538d0c080abSJoseph Pusztay    Collective on TS
539d0c080abSJoseph Pusztay 
540d0c080abSJoseph Pusztay    Input Parameters:
541d0c080abSJoseph Pusztay .    ctx - the monitor context
542d0c080abSJoseph Pusztay 
543d0c080abSJoseph Pusztay    Level: intermediate
544d0c080abSJoseph Pusztay 
545db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawSolution()`, `TSMonitorDrawError()`
546d0c080abSJoseph Pusztay @*/
547d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
548d0c080abSJoseph Pusztay {
549d0c080abSJoseph Pusztay   PetscFunctionBegin;
5509566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&(*ictx)->viewer));
5519566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ictx)->initialsolution));
5529566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ictx));
553d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
554d0c080abSJoseph Pusztay }
555d0c080abSJoseph Pusztay 
556d0c080abSJoseph Pusztay /*@C
557d0c080abSJoseph Pusztay    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
558d0c080abSJoseph Pusztay 
559d0c080abSJoseph Pusztay    Collective on TS
560d0c080abSJoseph Pusztay 
561d0c080abSJoseph Pusztay    Input Parameter:
562d0c080abSJoseph Pusztay .    ts - time-step context
563d0c080abSJoseph Pusztay 
564d0c080abSJoseph Pusztay    Output Patameter:
565d0c080abSJoseph Pusztay .    ctx - the monitor context
566d0c080abSJoseph Pusztay 
567d0c080abSJoseph Pusztay    Options Database:
568d0c080abSJoseph Pusztay .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
569d0c080abSJoseph Pusztay 
570d0c080abSJoseph Pusztay    Level: intermediate
571d0c080abSJoseph Pusztay 
572db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawCtx()`
573d0c080abSJoseph Pusztay @*/
574d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
575d0c080abSJoseph Pusztay {
576d0c080abSJoseph Pusztay   PetscFunctionBegin;
5779566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
5789566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer));
5799566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetFromOptions((*ctx)->viewer));
580d0c080abSJoseph Pusztay 
581d0c080abSJoseph Pusztay   (*ctx)->howoften    = howoften;
582d0c080abSJoseph Pusztay   (*ctx)->showinitial = PETSC_FALSE;
5839566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL));
584d0c080abSJoseph Pusztay 
585d0c080abSJoseph Pusztay   (*ctx)->showtimestepandtime = PETSC_FALSE;
5869566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL));
587d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
588d0c080abSJoseph Pusztay }
589d0c080abSJoseph Pusztay 
590d0c080abSJoseph Pusztay /*@C
591d0c080abSJoseph Pusztay    TSMonitorDrawSolutionFunction - Monitors progress of the TS solvers by calling
592d0c080abSJoseph Pusztay    VecView() for the solution provided by TSSetSolutionFunction() at each timestep
593d0c080abSJoseph Pusztay 
594d0c080abSJoseph Pusztay    Collective on TS
595d0c080abSJoseph Pusztay 
596d0c080abSJoseph Pusztay    Input Parameters:
597d0c080abSJoseph Pusztay +  ts - the TS context
598d0c080abSJoseph Pusztay .  step - current time-step
599d0c080abSJoseph Pusztay .  ptime - current time
600d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
601d0c080abSJoseph Pusztay 
602d0c080abSJoseph Pusztay    Options Database:
603d0c080abSJoseph Pusztay .  -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
604d0c080abSJoseph Pusztay 
605*3a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
606*3a61192cSBarry Smith    to be used during the TS integration.
607*3a61192cSBarry Smith 
608d0c080abSJoseph Pusztay    Level: intermediate
609d0c080abSJoseph Pusztay 
610db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
611d0c080abSJoseph Pusztay @*/
612d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawSolutionFunction(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
613d0c080abSJoseph Pusztay {
614d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
615d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
616d0c080abSJoseph Pusztay   Vec              work;
617d0c080abSJoseph Pusztay 
618d0c080abSJoseph Pusztay   PetscFunctionBegin;
619d0c080abSJoseph Pusztay   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
6209566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u,&work));
6219566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts,ptime,work));
6229566063dSJacob Faibussowitsch   PetscCall(VecView(work,viewer));
6239566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work));
624d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
625d0c080abSJoseph Pusztay }
626d0c080abSJoseph Pusztay 
627d0c080abSJoseph Pusztay /*@C
628d0c080abSJoseph Pusztay    TSMonitorDrawError - Monitors progress of the TS solvers by calling
629d0c080abSJoseph Pusztay    VecView() for the error at each timestep
630d0c080abSJoseph Pusztay 
631d0c080abSJoseph Pusztay    Collective on TS
632d0c080abSJoseph Pusztay 
633d0c080abSJoseph Pusztay    Input Parameters:
634d0c080abSJoseph Pusztay +  ts - the TS context
635d0c080abSJoseph Pusztay .  step - current time-step
636d0c080abSJoseph Pusztay .  ptime - current time
637d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
638d0c080abSJoseph Pusztay 
639d0c080abSJoseph Pusztay    Options Database:
640d0c080abSJoseph Pusztay .  -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
641d0c080abSJoseph Pusztay 
642*3a61192cSBarry Smith    Notes:
643*3a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
644*3a61192cSBarry Smith    to be used during the TS integration.
645*3a61192cSBarry Smith 
646d0c080abSJoseph Pusztay    Level: intermediate
647d0c080abSJoseph Pusztay 
648db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
649d0c080abSJoseph Pusztay @*/
650d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
651d0c080abSJoseph Pusztay {
652d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
653d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
654d0c080abSJoseph Pusztay   Vec              work;
655d0c080abSJoseph Pusztay 
656d0c080abSJoseph Pusztay   PetscFunctionBegin;
657d0c080abSJoseph Pusztay   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
6589566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u,&work));
6599566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts,ptime,work));
6609566063dSJacob Faibussowitsch   PetscCall(VecAXPY(work,-1.0,u));
6619566063dSJacob Faibussowitsch   PetscCall(VecView(work,viewer));
6629566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work));
663d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
664d0c080abSJoseph Pusztay }
665d0c080abSJoseph Pusztay 
666d0c080abSJoseph Pusztay /*@C
667d0c080abSJoseph 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
668d0c080abSJoseph Pusztay 
669d0c080abSJoseph Pusztay    Collective on TS
670d0c080abSJoseph Pusztay 
671d0c080abSJoseph Pusztay    Input Parameters:
672d0c080abSJoseph Pusztay +  ts - the TS context
673d0c080abSJoseph Pusztay .  step - current time-step
674d0c080abSJoseph Pusztay .  ptime - current time
675d0c080abSJoseph Pusztay .  u - current state
676d0c080abSJoseph Pusztay -  vf - viewer and its format
677d0c080abSJoseph Pusztay 
678*3a61192cSBarry Smith    Notes:
679*3a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
680*3a61192cSBarry Smith    to be used during the TS integration.
681*3a61192cSBarry Smith 
682d0c080abSJoseph Pusztay    Level: intermediate
683d0c080abSJoseph Pusztay 
684db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
685d0c080abSJoseph Pusztay @*/
686d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
687d0c080abSJoseph Pusztay {
688d0c080abSJoseph Pusztay   PetscFunctionBegin;
6899566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(vf->viewer,vf->format));
6909566063dSJacob Faibussowitsch   PetscCall(VecView(u,vf->viewer));
6919566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(vf->viewer));
692d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
693d0c080abSJoseph Pusztay }
694d0c080abSJoseph Pusztay 
695d0c080abSJoseph Pusztay /*@C
696d0c080abSJoseph Pusztay    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
697d0c080abSJoseph Pusztay 
698d0c080abSJoseph Pusztay    Collective on TS
699d0c080abSJoseph Pusztay 
700d0c080abSJoseph Pusztay    Input Parameters:
701d0c080abSJoseph Pusztay +  ts - the TS context
702d0c080abSJoseph Pusztay .  step - current time-step
703d0c080abSJoseph Pusztay .  ptime - current time
704d0c080abSJoseph Pusztay .  u - current state
70563a3b9bcSJacob Faibussowitsch -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03" PetscInt_FMT ")
706d0c080abSJoseph Pusztay 
707d0c080abSJoseph Pusztay    Level: intermediate
708d0c080abSJoseph Pusztay 
709d0c080abSJoseph Pusztay    Notes:
710d0c080abSJoseph 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.
711d0c080abSJoseph Pusztay    These are named according to the file name template.
712d0c080abSJoseph Pusztay 
713*3a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
714*3a61192cSBarry Smith    to be used during the TS integration.
715d0c080abSJoseph Pusztay 
716db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
717d0c080abSJoseph Pusztay @*/
718d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
719d0c080abSJoseph Pusztay {
720d0c080abSJoseph Pusztay   char           filename[PETSC_MAX_PATH_LEN];
721d0c080abSJoseph Pusztay   PetscViewer    viewer;
722d0c080abSJoseph Pusztay 
723d0c080abSJoseph Pusztay   PetscFunctionBegin;
724d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
7259566063dSJacob Faibussowitsch   PetscCall(PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step));
7269566063dSJacob Faibussowitsch   PetscCall(PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer));
7279566063dSJacob Faibussowitsch   PetscCall(VecView(u,viewer));
7289566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&viewer));
729d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
730d0c080abSJoseph Pusztay }
731d0c080abSJoseph Pusztay 
732d0c080abSJoseph Pusztay /*@C
733d0c080abSJoseph Pusztay    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
734d0c080abSJoseph Pusztay 
735d0c080abSJoseph Pusztay    Collective on TS
736d0c080abSJoseph Pusztay 
737d0c080abSJoseph Pusztay    Input Parameters:
73863a3b9bcSJacob Faibussowitsch .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03" PetscInt_FMT ")
739d0c080abSJoseph Pusztay 
740d0c080abSJoseph Pusztay    Level: intermediate
741d0c080abSJoseph Pusztay 
742d0c080abSJoseph Pusztay    Note:
743d0c080abSJoseph Pusztay    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
744d0c080abSJoseph Pusztay 
745db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorSolutionVTK()`
746d0c080abSJoseph Pusztay @*/
747d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
748d0c080abSJoseph Pusztay {
749d0c080abSJoseph Pusztay   PetscFunctionBegin;
7509566063dSJacob Faibussowitsch   PetscCall(PetscFree(*(char**)filenametemplate));
751d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
752d0c080abSJoseph Pusztay }
753d0c080abSJoseph Pusztay 
754d0c080abSJoseph Pusztay /*@C
755d0c080abSJoseph Pusztay    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
756d0c080abSJoseph Pusztay        in a time based line graph
757d0c080abSJoseph Pusztay 
758d0c080abSJoseph Pusztay    Collective on TS
759d0c080abSJoseph Pusztay 
760d0c080abSJoseph Pusztay    Input Parameters:
761d0c080abSJoseph Pusztay +  ts - the TS context
762d0c080abSJoseph Pusztay .  step - current time-step
763d0c080abSJoseph Pusztay .  ptime - current time
764d0c080abSJoseph Pusztay .  u - current solution
765d0c080abSJoseph Pusztay -  dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate()
766d0c080abSJoseph Pusztay 
767d0c080abSJoseph Pusztay    Options Database:
76867b8a455SSatish Balay .   -ts_monitor_lg_solution_variables - enable monitor of lg solution variables
769d0c080abSJoseph Pusztay 
770d0c080abSJoseph Pusztay    Level: intermediate
771d0c080abSJoseph Pusztay 
772d0c080abSJoseph Pusztay    Notes:
773d0c080abSJoseph Pusztay    Each process in a parallel run displays its component solutions in a separate window
774d0c080abSJoseph Pusztay 
775*3a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
776*3a61192cSBarry Smith    to be used during the TS integration.
777*3a61192cSBarry Smith 
778db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGCtxCreate()`, `TSMonitorLGCtxSetVariableNames()`, `TSMonitorLGCtxGetVariableNames()`,
779db781477SPatrick Sanan           `TSMonitorLGSetVariableNames()`, `TSMonitorLGGetVariableNames()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetDisplayVariables()`,
780db781477SPatrick Sanan           `TSMonitorLGCtxSetTransform()`, `TSMonitorLGSetTransform()`, `TSMonitorLGError()`, `TSMonitorLGSNESIterations()`, `TSMonitorLGKSPIterations()`,
781db781477SPatrick Sanan           `TSMonitorEnvelopeCtxCreate()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxDestroy()`, `TSMonitorEnvelop()`
782d0c080abSJoseph Pusztay @*/
783d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
784d0c080abSJoseph Pusztay {
785d0c080abSJoseph Pusztay   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dctx;
786d0c080abSJoseph Pusztay   const PetscScalar *yy;
787d0c080abSJoseph Pusztay   Vec               v;
788d0c080abSJoseph Pusztay 
789d0c080abSJoseph Pusztay   PetscFunctionBegin;
790d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
791d0c080abSJoseph Pusztay   if (!step) {
792d0c080abSJoseph Pusztay     PetscDrawAxis axis;
793d0c080abSJoseph Pusztay     PetscInt      dim;
7949566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
7959566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution"));
796d0c080abSJoseph Pusztay     if (!ctx->names) {
797d0c080abSJoseph Pusztay       PetscBool flg;
798d0c080abSJoseph Pusztay       /* user provides names of variables to plot but no names has been set so assume names are integer values */
7999566063dSJacob Faibussowitsch       PetscCall(PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg));
800d0c080abSJoseph Pusztay       if (flg) {
801d0c080abSJoseph Pusztay         PetscInt i,n;
802d0c080abSJoseph Pusztay         char     **names;
8039566063dSJacob Faibussowitsch         PetscCall(VecGetSize(u,&n));
8049566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(n+1,&names));
805d0c080abSJoseph Pusztay         for (i=0; i<n; i++) {
8069566063dSJacob Faibussowitsch           PetscCall(PetscMalloc1(5,&names[i]));
80763a3b9bcSJacob Faibussowitsch           PetscCall(PetscSNPrintf(names[i],5,"%" PetscInt_FMT,i));
808d0c080abSJoseph Pusztay         }
809d0c080abSJoseph Pusztay         names[n] = NULL;
810d0c080abSJoseph Pusztay         ctx->names = names;
811d0c080abSJoseph Pusztay       }
812d0c080abSJoseph Pusztay     }
813d0c080abSJoseph Pusztay     if (ctx->names && !ctx->displaynames) {
814d0c080abSJoseph Pusztay       char      **displaynames;
815d0c080abSJoseph Pusztay       PetscBool flg;
8169566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u,&dim));
8179566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(dim+1,&displaynames));
8189566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg));
819d0c080abSJoseph Pusztay       if (flg) {
8209566063dSJacob Faibussowitsch         PetscCall(TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames));
821d0c080abSJoseph Pusztay       }
8229566063dSJacob Faibussowitsch       PetscCall(PetscStrArrayDestroy(&displaynames));
823d0c080abSJoseph Pusztay     }
824d0c080abSJoseph Pusztay     if (ctx->displaynames) {
8259566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables));
8269566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames));
827d0c080abSJoseph Pusztay     } else if (ctx->names) {
8289566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u,&dim));
8299566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg,dim));
8309566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names));
831d0c080abSJoseph Pusztay     } else {
8329566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u,&dim));
8339566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg,dim));
834d0c080abSJoseph Pusztay     }
8359566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
836d0c080abSJoseph Pusztay   }
837d0c080abSJoseph Pusztay 
838d0c080abSJoseph Pusztay   if (!ctx->transform) v = u;
8399566063dSJacob Faibussowitsch   else PetscCall((*ctx->transform)(ctx->transformctx,u,&v));
8409566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(v,&yy));
841d0c080abSJoseph Pusztay   if (ctx->displaynames) {
842d0c080abSJoseph Pusztay     PetscInt i;
843d0c080abSJoseph Pusztay     for (i=0; i<ctx->ndisplayvariables; i++)
844d0c080abSJoseph Pusztay       ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]);
8459566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues));
846d0c080abSJoseph Pusztay   } else {
847d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
848d0c080abSJoseph Pusztay     PetscInt  i,n;
849d0c080abSJoseph Pusztay     PetscReal *yreal;
8509566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(v,&n));
8519566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&yreal));
852d0c080abSJoseph Pusztay     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
8539566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal));
8549566063dSJacob Faibussowitsch     PetscCall(PetscFree(yreal));
855d0c080abSJoseph Pusztay #else
8569566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy));
857d0c080abSJoseph Pusztay #endif
858d0c080abSJoseph Pusztay   }
8599566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(v,&yy));
8609566063dSJacob Faibussowitsch   if (ctx->transform) PetscCall(VecDestroy(&v));
861d0c080abSJoseph Pusztay 
862d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
8639566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
8649566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
865d0c080abSJoseph Pusztay   }
866d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
867d0c080abSJoseph Pusztay }
868d0c080abSJoseph Pusztay 
869d0c080abSJoseph Pusztay /*@C
870d0c080abSJoseph Pusztay    TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
871d0c080abSJoseph Pusztay 
872d0c080abSJoseph Pusztay    Collective on TS
873d0c080abSJoseph Pusztay 
874d0c080abSJoseph Pusztay    Input Parameters:
875d0c080abSJoseph Pusztay +  ts - the TS context
876d0c080abSJoseph Pusztay -  names - the names of the components, final string must be NULL
877d0c080abSJoseph Pusztay 
878d0c080abSJoseph Pusztay    Level: intermediate
879d0c080abSJoseph Pusztay 
880d0c080abSJoseph Pusztay    Notes:
881d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
882d0c080abSJoseph Pusztay 
883db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetVariableNames()`
884d0c080abSJoseph Pusztay @*/
885d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSetVariableNames(TS ts,const char * const *names)
886d0c080abSJoseph Pusztay {
887d0c080abSJoseph Pusztay   PetscInt          i;
888d0c080abSJoseph Pusztay 
889d0c080abSJoseph Pusztay   PetscFunctionBegin;
890d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
891d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
8929566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names));
893d0c080abSJoseph Pusztay       break;
894d0c080abSJoseph Pusztay     }
895d0c080abSJoseph Pusztay   }
896d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
897d0c080abSJoseph Pusztay }
898d0c080abSJoseph Pusztay 
899d0c080abSJoseph Pusztay /*@C
900d0c080abSJoseph Pusztay    TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
901d0c080abSJoseph Pusztay 
902d0c080abSJoseph Pusztay    Collective on TS
903d0c080abSJoseph Pusztay 
904d0c080abSJoseph Pusztay    Input Parameters:
905d0c080abSJoseph Pusztay +  ts - the TS context
906d0c080abSJoseph Pusztay -  names - the names of the components, final string must be NULL
907d0c080abSJoseph Pusztay 
908d0c080abSJoseph Pusztay    Level: intermediate
909d0c080abSJoseph Pusztay 
910db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGSetVariableNames()`
911d0c080abSJoseph Pusztay @*/
912d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names)
913d0c080abSJoseph Pusztay {
914d0c080abSJoseph Pusztay   PetscFunctionBegin;
9159566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&ctx->names));
9169566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(names,&ctx->names));
917d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
918d0c080abSJoseph Pusztay }
919d0c080abSJoseph Pusztay 
920d0c080abSJoseph Pusztay /*@C
921d0c080abSJoseph Pusztay    TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot
922d0c080abSJoseph Pusztay 
923d0c080abSJoseph Pusztay    Collective on TS
924d0c080abSJoseph Pusztay 
925d0c080abSJoseph Pusztay    Input Parameter:
926d0c080abSJoseph Pusztay .  ts - the TS context
927d0c080abSJoseph Pusztay 
928d0c080abSJoseph Pusztay    Output Parameter:
929d0c080abSJoseph Pusztay .  names - the names of the components, final string must be NULL
930d0c080abSJoseph Pusztay 
931d0c080abSJoseph Pusztay    Level: intermediate
932d0c080abSJoseph Pusztay 
933d0c080abSJoseph Pusztay    Notes:
934d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
935d0c080abSJoseph Pusztay 
936db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`
937d0c080abSJoseph Pusztay @*/
938d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGGetVariableNames(TS ts,const char *const **names)
939d0c080abSJoseph Pusztay {
940d0c080abSJoseph Pusztay   PetscInt       i;
941d0c080abSJoseph Pusztay 
942d0c080abSJoseph Pusztay   PetscFunctionBegin;
943d0c080abSJoseph Pusztay   *names = NULL;
944d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
945d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
946d0c080abSJoseph Pusztay       TSMonitorLGCtx  ctx = (TSMonitorLGCtx) ts->monitorcontext[i];
947d0c080abSJoseph Pusztay       *names = (const char *const *)ctx->names;
948d0c080abSJoseph Pusztay       break;
949d0c080abSJoseph Pusztay     }
950d0c080abSJoseph Pusztay   }
951d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
952d0c080abSJoseph Pusztay }
953d0c080abSJoseph Pusztay 
954d0c080abSJoseph Pusztay /*@C
955d0c080abSJoseph Pusztay    TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor
956d0c080abSJoseph Pusztay 
957d0c080abSJoseph Pusztay    Collective on TS
958d0c080abSJoseph Pusztay 
959d0c080abSJoseph Pusztay    Input Parameters:
960d0c080abSJoseph Pusztay +  ctx - the TSMonitorLG context
961d0c080abSJoseph Pusztay -  displaynames - the names of the components, final string must be NULL
962d0c080abSJoseph Pusztay 
963d0c080abSJoseph Pusztay    Level: intermediate
964d0c080abSJoseph Pusztay 
965db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`
966d0c080abSJoseph Pusztay @*/
967d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames)
968d0c080abSJoseph Pusztay {
969d0c080abSJoseph Pusztay   PetscInt          j = 0,k;
970d0c080abSJoseph Pusztay 
971d0c080abSJoseph Pusztay   PetscFunctionBegin;
972d0c080abSJoseph Pusztay   if (!ctx->names) PetscFunctionReturn(0);
9739566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&ctx->displaynames));
9749566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(displaynames,&ctx->displaynames));
975d0c080abSJoseph Pusztay   while (displaynames[j]) j++;
976d0c080abSJoseph Pusztay   ctx->ndisplayvariables = j;
9779566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables));
9789566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues));
979d0c080abSJoseph Pusztay   j = 0;
980d0c080abSJoseph Pusztay   while (displaynames[j]) {
981d0c080abSJoseph Pusztay     k = 0;
982d0c080abSJoseph Pusztay     while (ctx->names[k]) {
983d0c080abSJoseph Pusztay       PetscBool flg;
9849566063dSJacob Faibussowitsch       PetscCall(PetscStrcmp(displaynames[j],ctx->names[k],&flg));
985d0c080abSJoseph Pusztay       if (flg) {
986d0c080abSJoseph Pusztay         ctx->displayvariables[j] = k;
987d0c080abSJoseph Pusztay         break;
988d0c080abSJoseph Pusztay       }
989d0c080abSJoseph Pusztay       k++;
990d0c080abSJoseph Pusztay     }
991d0c080abSJoseph Pusztay     j++;
992d0c080abSJoseph Pusztay   }
993d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
994d0c080abSJoseph Pusztay }
995d0c080abSJoseph Pusztay 
996d0c080abSJoseph Pusztay /*@C
997d0c080abSJoseph Pusztay    TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor
998d0c080abSJoseph Pusztay 
999d0c080abSJoseph Pusztay    Collective on TS
1000d0c080abSJoseph Pusztay 
1001d0c080abSJoseph Pusztay    Input Parameters:
1002d0c080abSJoseph Pusztay +  ts - the TS context
1003d0c080abSJoseph Pusztay -  displaynames - the names of the components, final string must be NULL
1004d0c080abSJoseph Pusztay 
1005d0c080abSJoseph Pusztay    Notes:
1006d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
1007d0c080abSJoseph Pusztay 
1008d0c080abSJoseph Pusztay    Level: intermediate
1009d0c080abSJoseph Pusztay 
1010db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`
1011d0c080abSJoseph Pusztay @*/
1012d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames)
1013d0c080abSJoseph Pusztay {
1014d0c080abSJoseph Pusztay   PetscInt          i;
1015d0c080abSJoseph Pusztay 
1016d0c080abSJoseph Pusztay   PetscFunctionBegin;
1017d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
1018d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
10199566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames));
1020d0c080abSJoseph Pusztay       break;
1021d0c080abSJoseph Pusztay     }
1022d0c080abSJoseph Pusztay   }
1023d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1024d0c080abSJoseph Pusztay }
1025d0c080abSJoseph Pusztay 
1026d0c080abSJoseph Pusztay /*@C
1027d0c080abSJoseph Pusztay    TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed
1028d0c080abSJoseph Pusztay 
1029d0c080abSJoseph Pusztay    Collective on TS
1030d0c080abSJoseph Pusztay 
1031d0c080abSJoseph Pusztay    Input Parameters:
1032d0c080abSJoseph Pusztay +  ts - the TS context
1033d0c080abSJoseph Pusztay .  transform - the transform function
1034d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
1035d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
1036d0c080abSJoseph Pusztay 
1037d0c080abSJoseph Pusztay    Notes:
1038d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
1039d0c080abSJoseph Pusztay 
1040d0c080abSJoseph Pusztay    Level: intermediate
1041d0c080abSJoseph Pusztay 
1042db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`, `TSMonitorLGCtxSetTransform()`
1043d0c080abSJoseph Pusztay @*/
1044d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
1045d0c080abSJoseph Pusztay {
1046d0c080abSJoseph Pusztay   PetscInt          i;
1047d0c080abSJoseph Pusztay 
1048d0c080abSJoseph Pusztay   PetscFunctionBegin;
1049d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
1050d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
10519566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx));
1052d0c080abSJoseph Pusztay     }
1053d0c080abSJoseph Pusztay   }
1054d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1055d0c080abSJoseph Pusztay }
1056d0c080abSJoseph Pusztay 
1057d0c080abSJoseph Pusztay /*@C
1058d0c080abSJoseph Pusztay    TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed
1059d0c080abSJoseph Pusztay 
1060d0c080abSJoseph Pusztay    Collective on TSLGCtx
1061d0c080abSJoseph Pusztay 
1062d0c080abSJoseph Pusztay    Input Parameters:
1063d0c080abSJoseph Pusztay +  ts - the TS context
1064d0c080abSJoseph Pusztay .  transform - the transform function
1065d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
1066d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
1067d0c080abSJoseph Pusztay 
1068d0c080abSJoseph Pusztay    Level: intermediate
1069d0c080abSJoseph Pusztay 
1070db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`, `TSMonitorLGSetTransform()`
1071d0c080abSJoseph Pusztay @*/
1072d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
1073d0c080abSJoseph Pusztay {
1074d0c080abSJoseph Pusztay   PetscFunctionBegin;
1075d0c080abSJoseph Pusztay   ctx->transform    = transform;
1076d0c080abSJoseph Pusztay   ctx->transformdestroy = destroy;
1077d0c080abSJoseph Pusztay   ctx->transformctx = tctx;
1078d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1079d0c080abSJoseph Pusztay }
1080d0c080abSJoseph Pusztay 
1081d0c080abSJoseph Pusztay /*@C
1082d0c080abSJoseph Pusztay    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error
1083d0c080abSJoseph Pusztay        in a time based line graph
1084d0c080abSJoseph Pusztay 
1085d0c080abSJoseph Pusztay    Collective on TS
1086d0c080abSJoseph Pusztay 
1087d0c080abSJoseph Pusztay    Input Parameters:
1088d0c080abSJoseph Pusztay +  ts - the TS context
1089d0c080abSJoseph Pusztay .  step - current time-step
1090d0c080abSJoseph Pusztay .  ptime - current time
1091d0c080abSJoseph Pusztay .  u - current solution
1092d0c080abSJoseph Pusztay -  dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate()
1093d0c080abSJoseph Pusztay 
1094*3a61192cSBarry Smith    Options Database Keys:
1095*3a61192cSBarry Smith .  -ts_monitor_lg_error - create a graphical monitor of error history
1096*3a61192cSBarry Smith 
1097d0c080abSJoseph Pusztay    Level: intermediate
1098d0c080abSJoseph Pusztay 
1099d0c080abSJoseph Pusztay    Notes:
1100d0c080abSJoseph Pusztay     Each process in a parallel run displays its component errors in a separate window
1101d0c080abSJoseph Pusztay 
1102d0c080abSJoseph Pusztay    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
1103d0c080abSJoseph Pusztay 
1104*3a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
1105*3a61192cSBarry Smith    to be used during the TS integration.
1106d0c080abSJoseph Pusztay 
1107db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
1108d0c080abSJoseph Pusztay @*/
1109d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
1110d0c080abSJoseph Pusztay {
1111d0c080abSJoseph Pusztay   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
1112d0c080abSJoseph Pusztay   const PetscScalar *yy;
1113d0c080abSJoseph Pusztay   Vec               y;
1114d0c080abSJoseph Pusztay 
1115d0c080abSJoseph Pusztay   PetscFunctionBegin;
1116d0c080abSJoseph Pusztay   if (!step) {
1117d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1118d0c080abSJoseph Pusztay     PetscInt      dim;
11199566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
11209566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Error"));
11219566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(u,&dim));
11229566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSetDimension(ctx->lg,dim));
11239566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1124d0c080abSJoseph Pusztay   }
11259566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u,&y));
11269566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts,ptime,y));
11279566063dSJacob Faibussowitsch   PetscCall(VecAXPY(y,-1.0,u));
11289566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(y,&yy));
1129d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
1130d0c080abSJoseph Pusztay   {
1131d0c080abSJoseph Pusztay     PetscReal *yreal;
1132d0c080abSJoseph Pusztay     PetscInt  i,n;
11339566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(y,&n));
11349566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&yreal));
1135d0c080abSJoseph Pusztay     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
11369566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal));
11379566063dSJacob Faibussowitsch     PetscCall(PetscFree(yreal));
1138d0c080abSJoseph Pusztay   }
1139d0c080abSJoseph Pusztay #else
11409566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy));
1141d0c080abSJoseph Pusztay #endif
11429566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(y,&yy));
11439566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&y));
1144d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
11459566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
11469566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1147d0c080abSJoseph Pusztay   }
1148d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1149d0c080abSJoseph Pusztay }
1150d0c080abSJoseph Pusztay 
1151d0c080abSJoseph Pusztay /*@C
1152d0c080abSJoseph Pusztay    TSMonitorSPSwarmSolution - Graphically displays phase plots of DMSwarm particles on a scatter plot
1153d0c080abSJoseph Pusztay 
1154d0c080abSJoseph Pusztay    Input Parameters:
1155d0c080abSJoseph Pusztay +  ts - the TS context
1156d0c080abSJoseph Pusztay .  step - current time-step
1157d0c080abSJoseph Pusztay .  ptime - current time
1158d0c080abSJoseph Pusztay .  u - current solution
1159d0c080abSJoseph Pusztay -  dctx - the TSMonitorSPCtx object that contains all the options for the monitoring, this is created with TSMonitorSPCtxCreate()
1160d0c080abSJoseph Pusztay 
1161d0c080abSJoseph Pusztay    Options Database:
1162d7462660SMatthew Knepley + -ts_monitor_sp_swarm <n>          - Monitor the solution every n steps, or -1 for plotting only the final solution
1163d7462660SMatthew Knepley . -ts_monitor_sp_swarm_retain <n>   - Retain n old points so we can see the history, or -1 for all points
1164d7462660SMatthew Knepley - -ts_monitor_sp_swarm_phase <bool> - Plot in phase space, as opposed to coordinate space
1165d0c080abSJoseph Pusztay 
1166d0c080abSJoseph Pusztay    Level: intermediate
1167d0c080abSJoseph Pusztay 
1168*3a61192cSBarry Smith    Notes:
1169*3a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
1170*3a61192cSBarry Smith    to be used during the TS integration.
1171*3a61192cSBarry Smith 
1172db781477SPatrick Sanan .seealso: `TSMonitoSet()`
1173d0c080abSJoseph Pusztay @*/
1174d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSPSwarmSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx)
1175d0c080abSJoseph Pusztay {
1176d0c080abSJoseph Pusztay   TSMonitorSPCtx     ctx = (TSMonitorSPCtx) dctx;
1177f98b2f00SMatthew G. Knepley   PetscDraw          draw;
1178d7462660SMatthew Knepley   DM                 dm, cdm;
1179d0c080abSJoseph Pusztay   const PetscScalar *yy;
1180d0c080abSJoseph Pusztay   PetscInt           Np, p, dim = 2;
1181d0c080abSJoseph Pusztay 
1182d0c080abSJoseph Pusztay   PetscFunctionBegin;
1183d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1184d0c080abSJoseph Pusztay   if (!step) {
1185d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1186ab43fcacSJoe Pusztay     PetscReal     dmboxlower[2], dmboxupper[2];
1187f98b2f00SMatthew G. Knepley 
11889566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &dm));
11899566063dSJacob Faibussowitsch     PetscCall(DMGetDimension(dm, &dim));
11903c633725SBarry Smith     PetscCheck(dim == 2, PETSC_COMM_SELF, PETSC_ERR_SUP, "Monitor only supports two dimensional fields");
11919566063dSJacob Faibussowitsch     PetscCall(DMSwarmGetCellDM(dm, &cdm));
11929566063dSJacob Faibussowitsch     PetscCall(DMGetBoundingBox(cdm, dmboxlower, dmboxupper));
11939566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(u, &Np));
1194d7462660SMatthew Knepley     Np /= dim*2;
11959566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPGetAxis(ctx->sp,&axis));
11968c87cf4dSdanfinn     if (ctx->phase) {
11979566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(axis,"Particles","X","V"));
11989566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], -5, 5));
11998c87cf4dSdanfinn     } else {
12009566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(axis,"Particles","X","Y"));
12019566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], dmboxlower[1], dmboxupper[1]));
12028c87cf4dSdanfinn     }
12039566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetHoldLimits(axis, PETSC_TRUE));
12049566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPReset(ctx->sp));
1205d0c080abSJoseph Pusztay   }
12069566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(u, &Np));
1207d7462660SMatthew Knepley   Np /= dim*2;
1208d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
12099566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPGetDraw(ctx->sp, &draw));
1210d7462660SMatthew Knepley     if ((ctx->retain == 0) || (ctx->retain > 0 && !(step % ctx->retain))) {
12119566063dSJacob Faibussowitsch       PetscCall(PetscDrawClear(draw));
1212d7462660SMatthew Knepley     }
12139566063dSJacob Faibussowitsch     PetscCall(PetscDrawFlush(draw));
12149566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPReset(ctx->sp));
1215f98b2f00SMatthew G. Knepley     PetscCall(VecGetArrayRead(u, &yy));
1216f98b2f00SMatthew G. Knepley     for (p = 0; p < Np; ++p) {
1217f98b2f00SMatthew G. Knepley       PetscReal x, y;
1218f98b2f00SMatthew G. Knepley 
1219f98b2f00SMatthew G. Knepley       if (ctx->phase) {
1220f98b2f00SMatthew G. Knepley         x = PetscRealPart(yy[p*dim*2]);
1221f98b2f00SMatthew G. Knepley         y = PetscRealPart(yy[p*dim*2 + dim]);
1222f98b2f00SMatthew G. Knepley       } else {
1223f98b2f00SMatthew G. Knepley         x = PetscRealPart(yy[p*dim*2]);
1224f98b2f00SMatthew G. Knepley         y = PetscRealPart(yy[p*dim*2 + 1]);
1225f98b2f00SMatthew G. Knepley       }
1226f98b2f00SMatthew G. Knepley       PetscCall(PetscDrawSPAddPoint(ctx->sp, &x, &y));
1227f98b2f00SMatthew G. Knepley     }
1228f98b2f00SMatthew G. Knepley     PetscCall(VecRestoreArrayRead(u, &yy));
12299566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPDraw(ctx->sp, PETSC_FALSE));
12309566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPSave(ctx->sp));
1231d0c080abSJoseph Pusztay   }
1232d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1233d0c080abSJoseph Pusztay }
1234d0c080abSJoseph Pusztay 
1235d0c080abSJoseph Pusztay /*@C
1236d0c080abSJoseph Pusztay    TSMonitorError - Monitors progress of the TS solvers by printing the 2 norm of the error at each timestep
1237d0c080abSJoseph Pusztay 
1238d0c080abSJoseph Pusztay    Collective on TS
1239d0c080abSJoseph Pusztay 
1240d0c080abSJoseph Pusztay    Input Parameters:
1241d0c080abSJoseph Pusztay +  ts - the TS context
1242d0c080abSJoseph Pusztay .  step - current time-step
1243d0c080abSJoseph Pusztay .  ptime - current time
1244d0c080abSJoseph Pusztay .  u - current solution
1245d0c080abSJoseph Pusztay -  dctx - unused context
1246d0c080abSJoseph Pusztay 
1247d0c080abSJoseph Pusztay    Level: intermediate
1248d0c080abSJoseph Pusztay 
1249*3a61192cSBarry Smith    Notes:
1250*3a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
1251*3a61192cSBarry Smith    to be used during the TS integration.
1252*3a61192cSBarry Smith 
1253d0c080abSJoseph Pusztay    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
1254d0c080abSJoseph Pusztay 
1255d0c080abSJoseph Pusztay    Options Database Keys:
1256d0c080abSJoseph Pusztay .  -ts_monitor_error - create a graphical monitor of error history
1257d0c080abSJoseph Pusztay 
1258db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
1259d0c080abSJoseph Pusztay @*/
1260d0c080abSJoseph Pusztay PetscErrorCode TSMonitorError(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
1261d0c080abSJoseph Pusztay {
126207eaae0cSMatthew G. Knepley   DM             dm;
126307eaae0cSMatthew G. Knepley   PetscDS        ds = NULL;
126407eaae0cSMatthew G. Knepley   PetscInt       Nf = -1, f;
1265d0c080abSJoseph Pusztay   PetscBool      flg;
1266d0c080abSJoseph Pusztay 
1267d0c080abSJoseph Pusztay   PetscFunctionBegin;
12689566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
12699566063dSJacob Faibussowitsch   if (dm) PetscCall(DMGetDS(dm, &ds));
12709566063dSJacob Faibussowitsch   if (ds) PetscCall(PetscDSGetNumFields(ds, &Nf));
127107eaae0cSMatthew G. Knepley   if (Nf <= 0) {
127207eaae0cSMatthew G. Knepley     Vec       y;
127307eaae0cSMatthew G. Knepley     PetscReal nrm;
127407eaae0cSMatthew G. Knepley 
12759566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u,&y));
12769566063dSJacob Faibussowitsch     PetscCall(TSComputeSolutionFunction(ts,ptime,y));
12779566063dSJacob Faibussowitsch     PetscCall(VecAXPY(y,-1.0,u));
12789566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERASCII,&flg));
1279d0c080abSJoseph Pusztay     if (flg) {
12809566063dSJacob Faibussowitsch       PetscCall(VecNorm(y,NORM_2,&nrm));
12819566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vf->viewer,"2-norm of error %g\n",(double)nrm));
1282d0c080abSJoseph Pusztay     }
12839566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERDRAW,&flg));
1284d0c080abSJoseph Pusztay     if (flg) {
12859566063dSJacob Faibussowitsch       PetscCall(VecView(y,vf->viewer));
1286d0c080abSJoseph Pusztay     }
12879566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&y));
128807eaae0cSMatthew G. Knepley   } else {
128907eaae0cSMatthew G. Knepley     PetscErrorCode (**exactFuncs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx);
129007eaae0cSMatthew G. Knepley     void            **ctxs;
129107eaae0cSMatthew G. Knepley     Vec               v;
129207eaae0cSMatthew G. Knepley     PetscReal         ferrors[1];
129307eaae0cSMatthew G. Knepley 
12949566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(Nf, &exactFuncs, Nf, &ctxs));
12959566063dSJacob Faibussowitsch     for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(ds, f, &exactFuncs[f], &ctxs[f]));
12969566063dSJacob Faibussowitsch     PetscCall(DMComputeL2FieldDiff(dm, ptime, exactFuncs, ctxs, u, ferrors));
12979566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Timestep: %04d time = %-8.4g \t L_2 Error: [", (int) step, (double) ptime));
129807eaae0cSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
12999566063dSJacob Faibussowitsch       if (f > 0) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ", "));
13009566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%2.3g", (double) ferrors[f]));
130107eaae0cSMatthew G. Knepley     }
13029566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "]\n"));
130307eaae0cSMatthew G. Knepley 
13049566063dSJacob Faibussowitsch     PetscCall(VecViewFromOptions(u, NULL, "-sol_vec_view"));
130507eaae0cSMatthew G. Knepley 
13069566063dSJacob Faibussowitsch     PetscCall(PetscOptionsHasName(NULL, NULL, "-exact_vec_view", &flg));
130707eaae0cSMatthew G. Knepley     if (flg) {
13089566063dSJacob Faibussowitsch       PetscCall(DMGetGlobalVector(dm, &v));
13099566063dSJacob Faibussowitsch       PetscCall(DMProjectFunction(dm, ptime, exactFuncs, ctxs, INSERT_ALL_VALUES, v));
13109566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetName((PetscObject) v, "Exact Solution"));
13119566063dSJacob Faibussowitsch       PetscCall(VecViewFromOptions(v, NULL, "-exact_vec_view"));
13129566063dSJacob Faibussowitsch       PetscCall(DMRestoreGlobalVector(dm, &v));
131307eaae0cSMatthew G. Knepley     }
13149566063dSJacob Faibussowitsch     PetscCall(PetscFree2(exactFuncs, ctxs));
131507eaae0cSMatthew G. Knepley   }
1316d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1317d0c080abSJoseph Pusztay }
1318d0c080abSJoseph Pusztay 
1319d0c080abSJoseph Pusztay PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
1320d0c080abSJoseph Pusztay {
1321d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
1322d0c080abSJoseph Pusztay   PetscReal      x   = ptime,y;
1323d0c080abSJoseph Pusztay   PetscInt       its;
1324d0c080abSJoseph Pusztay 
1325d0c080abSJoseph Pusztay   PetscFunctionBegin;
1326d0c080abSJoseph Pusztay   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1327d0c080abSJoseph Pusztay   if (!n) {
1328d0c080abSJoseph Pusztay     PetscDrawAxis axis;
13299566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
13309566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations"));
13319566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1332d0c080abSJoseph Pusztay     ctx->snes_its = 0;
1333d0c080abSJoseph Pusztay   }
13349566063dSJacob Faibussowitsch   PetscCall(TSGetSNESIterations(ts,&its));
1335d0c080abSJoseph Pusztay   y    = its - ctx->snes_its;
13369566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg,&x,&y));
1337d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
13389566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
13399566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1340d0c080abSJoseph Pusztay   }
1341d0c080abSJoseph Pusztay   ctx->snes_its = its;
1342d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1343d0c080abSJoseph Pusztay }
1344d0c080abSJoseph Pusztay 
1345d0c080abSJoseph Pusztay PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
1346d0c080abSJoseph Pusztay {
1347d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
1348d0c080abSJoseph Pusztay   PetscReal      x   = ptime,y;
1349d0c080abSJoseph Pusztay   PetscInt       its;
1350d0c080abSJoseph Pusztay 
1351d0c080abSJoseph Pusztay   PetscFunctionBegin;
1352d0c080abSJoseph Pusztay   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1353d0c080abSJoseph Pusztay   if (!n) {
1354d0c080abSJoseph Pusztay     PetscDrawAxis axis;
13559566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
13569566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations"));
13579566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1358d0c080abSJoseph Pusztay     ctx->ksp_its = 0;
1359d0c080abSJoseph Pusztay   }
13609566063dSJacob Faibussowitsch   PetscCall(TSGetKSPIterations(ts,&its));
1361d0c080abSJoseph Pusztay   y    = its - ctx->ksp_its;
13629566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg,&x,&y));
1363d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
13649566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
13659566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1366d0c080abSJoseph Pusztay   }
1367d0c080abSJoseph Pusztay   ctx->ksp_its = its;
1368d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1369d0c080abSJoseph Pusztay }
1370d0c080abSJoseph Pusztay 
1371d0c080abSJoseph Pusztay /*@C
1372d0c080abSJoseph Pusztay    TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope()
1373d0c080abSJoseph Pusztay 
1374d0c080abSJoseph Pusztay    Collective on TS
1375d0c080abSJoseph Pusztay 
1376d0c080abSJoseph Pusztay    Input Parameters:
1377d0c080abSJoseph Pusztay .  ts  - the ODE solver object
1378d0c080abSJoseph Pusztay 
1379d0c080abSJoseph Pusztay    Output Parameter:
1380d0c080abSJoseph Pusztay .  ctx - the context
1381d0c080abSJoseph Pusztay 
1382d0c080abSJoseph Pusztay    Level: intermediate
1383d0c080abSJoseph Pusztay 
1384db781477SPatrick Sanan .seealso: `TSMonitorLGTimeStep()`, `TSMonitorSet()`, `TSMonitorLGSolution()`, `TSMonitorLGError()`
1385d0c080abSJoseph Pusztay 
1386d0c080abSJoseph Pusztay @*/
1387d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx)
1388d0c080abSJoseph Pusztay {
1389d0c080abSJoseph Pusztay   PetscFunctionBegin;
13909566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
1391d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1392d0c080abSJoseph Pusztay }
1393d0c080abSJoseph Pusztay 
1394d0c080abSJoseph Pusztay /*@C
1395d0c080abSJoseph Pusztay    TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution
1396d0c080abSJoseph Pusztay 
1397d0c080abSJoseph Pusztay    Collective on TS
1398d0c080abSJoseph Pusztay 
1399d0c080abSJoseph Pusztay    Input Parameters:
1400d0c080abSJoseph Pusztay +  ts - the TS context
1401d0c080abSJoseph Pusztay .  step - current time-step
1402d0c080abSJoseph Pusztay .  ptime - current time
1403d0c080abSJoseph Pusztay .  u  - current solution
1404d0c080abSJoseph Pusztay -  dctx - the envelope context
1405d0c080abSJoseph Pusztay 
1406d0c080abSJoseph Pusztay    Options Database:
140767b8a455SSatish Balay .  -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time
1408d0c080abSJoseph Pusztay 
1409d0c080abSJoseph Pusztay    Level: intermediate
1410d0c080abSJoseph Pusztay 
1411d0c080abSJoseph Pusztay    Notes:
1412*3a61192cSBarry Smith    After a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope
1413*3a61192cSBarry Smith 
1414*3a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
1415*3a61192cSBarry Smith    to be used during the TS integration.
1416d0c080abSJoseph Pusztay 
1417db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxCreate()`
1418d0c080abSJoseph Pusztay @*/
1419d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
1420d0c080abSJoseph Pusztay {
1421d0c080abSJoseph Pusztay   TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx;
1422d0c080abSJoseph Pusztay 
1423d0c080abSJoseph Pusztay   PetscFunctionBegin;
1424d0c080abSJoseph Pusztay   if (!ctx->max) {
14259566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u,&ctx->max));
14269566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u,&ctx->min));
14279566063dSJacob Faibussowitsch     PetscCall(VecCopy(u,ctx->max));
14289566063dSJacob Faibussowitsch     PetscCall(VecCopy(u,ctx->min));
1429d0c080abSJoseph Pusztay   } else {
14309566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMax(ctx->max,u,ctx->max));
14319566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMin(ctx->min,u,ctx->min));
1432d0c080abSJoseph Pusztay   }
1433d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1434d0c080abSJoseph Pusztay }
1435d0c080abSJoseph Pusztay 
1436d0c080abSJoseph Pusztay /*@C
1437d0c080abSJoseph Pusztay    TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution
1438d0c080abSJoseph Pusztay 
1439d0c080abSJoseph Pusztay    Collective on TS
1440d0c080abSJoseph Pusztay 
1441d0c080abSJoseph Pusztay    Input Parameter:
1442d0c080abSJoseph Pusztay .  ts - the TS context
1443d0c080abSJoseph Pusztay 
1444d8d19677SJose E. Roman    Output Parameters:
1445d0c080abSJoseph Pusztay +  max - the maximum values
1446d0c080abSJoseph Pusztay -  min - the minimum values
1447d0c080abSJoseph Pusztay 
1448d0c080abSJoseph Pusztay    Notes:
1449d0c080abSJoseph Pusztay     If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored
1450d0c080abSJoseph Pusztay 
1451d0c080abSJoseph Pusztay    Level: intermediate
1452d0c080abSJoseph Pusztay 
1453db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`
1454d0c080abSJoseph Pusztay @*/
1455d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min)
1456d0c080abSJoseph Pusztay {
1457d0c080abSJoseph Pusztay   PetscInt i;
1458d0c080abSJoseph Pusztay 
1459d0c080abSJoseph Pusztay   PetscFunctionBegin;
1460d0c080abSJoseph Pusztay   if (max) *max = NULL;
1461d0c080abSJoseph Pusztay   if (min) *min = NULL;
1462d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
1463d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorEnvelope) {
1464d0c080abSJoseph Pusztay       TSMonitorEnvelopeCtx  ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i];
1465d0c080abSJoseph Pusztay       if (max) *max = ctx->max;
1466d0c080abSJoseph Pusztay       if (min) *min = ctx->min;
1467d0c080abSJoseph Pusztay       break;
1468d0c080abSJoseph Pusztay     }
1469d0c080abSJoseph Pusztay   }
1470d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1471d0c080abSJoseph Pusztay }
1472d0c080abSJoseph Pusztay 
1473d0c080abSJoseph Pusztay /*@C
1474d0c080abSJoseph Pusztay    TSMonitorEnvelopeCtxDestroy - Destroys a context that was created  with TSMonitorEnvelopeCtxCreate().
1475d0c080abSJoseph Pusztay 
1476d0c080abSJoseph Pusztay    Collective on TSMonitorEnvelopeCtx
1477d0c080abSJoseph Pusztay 
1478d0c080abSJoseph Pusztay    Input Parameter:
1479d0c080abSJoseph Pusztay .  ctx - the monitor context
1480d0c080abSJoseph Pusztay 
1481d0c080abSJoseph Pusztay    Level: intermediate
1482d0c080abSJoseph Pusztay 
1483db781477SPatrick Sanan .seealso: `TSMonitorLGCtxCreate()`, `TSMonitorSet()`, `TSMonitorLGTimeStep()`
1484d0c080abSJoseph Pusztay @*/
1485d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx)
1486d0c080abSJoseph Pusztay {
1487d0c080abSJoseph Pusztay   PetscFunctionBegin;
14889566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ctx)->min));
14899566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ctx)->max));
14909566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
1491d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1492d0c080abSJoseph Pusztay }
1493d0c080abSJoseph Pusztay 
1494d0c080abSJoseph Pusztay /*@C
1495d0c080abSJoseph Pusztay   TSDMSwarmMonitorMoments - Monitors the first three moments of a DMSarm being evolved by the TS
1496d0c080abSJoseph Pusztay 
1497d0c080abSJoseph Pusztay   Not collective
1498d0c080abSJoseph Pusztay 
1499d0c080abSJoseph Pusztay   Input Parameters:
1500d0c080abSJoseph Pusztay + ts   - the TS context
1501d0c080abSJoseph Pusztay . step - current timestep
1502d0c080abSJoseph Pusztay . t    - current time
1503d0c080abSJoseph Pusztay . u    - current solution
1504d0c080abSJoseph Pusztay - ctx  - not used
1505d0c080abSJoseph Pusztay 
1506d0c080abSJoseph Pusztay   Options Database:
150767b8a455SSatish Balay . -ts_dmswarm_monitor_moments - Monitor moments of particle distribution
1508d0c080abSJoseph Pusztay 
1509d0c080abSJoseph Pusztay   Level: intermediate
1510d0c080abSJoseph Pusztay 
1511d0c080abSJoseph Pusztay   Notes:
1512d0c080abSJoseph Pusztay   This requires a DMSwarm be attached to the TS.
1513d0c080abSJoseph Pusztay 
1514*3a61192cSBarry Smith   This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
1515*3a61192cSBarry Smith   to be used during the TS integration.
1516*3a61192cSBarry Smith 
1517db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `DMSWARM`
1518d0c080abSJoseph Pusztay @*/
1519d0c080abSJoseph Pusztay PetscErrorCode TSDMSwarmMonitorMoments(TS ts, PetscInt step, PetscReal t, Vec U, PetscViewerAndFormat *vf)
1520d0c080abSJoseph Pusztay {
1521d0c080abSJoseph Pusztay   DM                 sw;
1522d0c080abSJoseph Pusztay   const PetscScalar *u;
1523d0c080abSJoseph Pusztay   PetscReal          m = 1.0, totE = 0., totMom[3] = {0., 0., 0.};
1524d0c080abSJoseph Pusztay   PetscInt           dim, d, Np, p;
1525d0c080abSJoseph Pusztay   MPI_Comm           comm;
1526d0c080abSJoseph Pusztay 
1527d0c080abSJoseph Pusztay   PetscFunctionBeginUser;
15289566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &sw));
1529d0c080abSJoseph Pusztay   if (!sw || step%ts->monitorFrequency != 0) PetscFunctionReturn(0);
15309566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject) ts, &comm));
15319566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(sw, &dim));
15329566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(U, &Np));
1533d0c080abSJoseph Pusztay   Np  /= dim;
15349566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U, &u));
1535d0c080abSJoseph Pusztay   for (p = 0; p < Np; ++p) {
1536d0c080abSJoseph Pusztay     for (d = 0; d < dim; ++d) {
1537d0c080abSJoseph Pusztay       totE      += PetscRealPart(u[p*dim+d]*u[p*dim+d]);
1538d0c080abSJoseph Pusztay       totMom[d] += PetscRealPart(u[p*dim+d]);
1539d0c080abSJoseph Pusztay     }
1540d0c080abSJoseph Pusztay   }
15419566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U, &u));
1542d0c080abSJoseph Pusztay   for (d = 0; d < dim; ++d) totMom[d] *= m;
1543d0c080abSJoseph Pusztay   totE *= 0.5*m;
154463a3b9bcSJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "Step %4" PetscInt_FMT " Total Energy: %10.8lf", step, (double) totE));
154563a3b9bcSJacob Faibussowitsch   for (d = 0; d < dim; ++d) PetscCall(PetscPrintf(comm, "    Total Momentum %c: %10.8lf", (char)('x'+d), (double) totMom[d]));
15469566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "\n"));
1547d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1548d0c080abSJoseph Pusztay }
1549