xref: /petsc/src/ts/interface/tsmon.c (revision 1baa6e3354bfe224b33a0c158f482508792a8a6e)
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()`,
66c2e3fba1SPatrick 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));
82*1baa6e33SBarry Smith     if (monitorsetup) PetscCall((*monitorsetup)(ts,vf));
839566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts,(PetscErrorCode (*)(TS,PetscInt,PetscReal,Vec,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy));
84d0c080abSJoseph Pusztay   }
85d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
86d0c080abSJoseph Pusztay }
87d0c080abSJoseph Pusztay 
88d0c080abSJoseph Pusztay /*@C
89d0c080abSJoseph Pusztay    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
90d0c080abSJoseph Pusztay    timestep to display the iteration's  progress.
91d0c080abSJoseph Pusztay 
92d0c080abSJoseph Pusztay    Logically Collective on TS
93d0c080abSJoseph Pusztay 
94d0c080abSJoseph Pusztay    Input Parameters:
95d0c080abSJoseph Pusztay +  ts - the TS context obtained from TSCreate()
96d0c080abSJoseph Pusztay .  monitor - monitoring routine
97d0c080abSJoseph Pusztay .  mctx - [optional] user-defined context for private data for the
98d0c080abSJoseph Pusztay              monitor routine (use NULL if no context is desired)
99d0c080abSJoseph Pusztay -  monitordestroy - [optional] routine that frees monitor context
100d0c080abSJoseph Pusztay           (may be NULL)
101d0c080abSJoseph Pusztay 
102d0c080abSJoseph Pusztay    Calling sequence of monitor:
103d0c080abSJoseph Pusztay $    PetscErrorCode monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
104d0c080abSJoseph Pusztay 
105d0c080abSJoseph Pusztay +    ts - the TS context
106d0c080abSJoseph 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)
107d0c080abSJoseph Pusztay .    time - current time
108d0c080abSJoseph Pusztay .    u - current iterate
109d0c080abSJoseph Pusztay -    mctx - [optional] monitoring context
110d0c080abSJoseph Pusztay 
111d0c080abSJoseph Pusztay    Notes:
112d0c080abSJoseph Pusztay    This routine adds an additional monitor to the list of monitors that
113d0c080abSJoseph Pusztay    already has been loaded.
114d0c080abSJoseph Pusztay 
115d0c080abSJoseph Pusztay    Fortran Notes:
116d0c080abSJoseph Pusztay     Only a single monitor function can be set for each TS object
117d0c080abSJoseph Pusztay 
118d0c080abSJoseph Pusztay    Level: intermediate
119d0c080abSJoseph Pusztay 
1203a61192cSBarry Smith .seealso: `TSMonitorDefault()`, `TSMonitorCancel()`, `TSDMSwarmMonitorMoments()`, `TSMonitorExtreme()`,  `TSMonitorDrawSolution()`,
1213a61192cSBarry Smith           `TSMonitorDrawSolutionPhase()`, `TSMonitorDrawSolutionFunction()`, `TSMonitorDrawError()`, `TSMonitorSolution()`, `TSMonitorSolutionVTK()`,
1223a61192cSBarry Smith           `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorSPSwarmSolution()`, `TSMonitorError()`, `TSMonitorEnvelope()`, `TSDMSwarmMonitorMoments()`
123d0c080abSJoseph Pusztay @*/
124d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**))
125d0c080abSJoseph Pusztay {
126d0c080abSJoseph Pusztay   PetscInt       i;
127d0c080abSJoseph Pusztay   PetscBool      identical;
128d0c080abSJoseph Pusztay 
129d0c080abSJoseph Pusztay   PetscFunctionBegin;
130d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
131d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors;i++) {
1329566063dSJacob Faibussowitsch     PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical));
133d0c080abSJoseph Pusztay     if (identical) PetscFunctionReturn(0);
134d0c080abSJoseph Pusztay   }
1353c633725SBarry Smith   PetscCheck(ts->numbermonitors < MAXTSMONITORS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
136d0c080abSJoseph Pusztay   ts->monitor[ts->numbermonitors]          = monitor;
137d0c080abSJoseph Pusztay   ts->monitordestroy[ts->numbermonitors]   = mdestroy;
138d0c080abSJoseph Pusztay   ts->monitorcontext[ts->numbermonitors++] = (void*)mctx;
139d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
140d0c080abSJoseph Pusztay }
141d0c080abSJoseph Pusztay 
142d0c080abSJoseph Pusztay /*@C
143d0c080abSJoseph Pusztay    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
144d0c080abSJoseph Pusztay 
145d0c080abSJoseph Pusztay    Logically Collective on TS
146d0c080abSJoseph Pusztay 
147d0c080abSJoseph Pusztay    Input Parameters:
148d0c080abSJoseph Pusztay .  ts - the TS context obtained from TSCreate()
149d0c080abSJoseph Pusztay 
150d0c080abSJoseph Pusztay    Notes:
151d0c080abSJoseph Pusztay    There is no way to remove a single, specific monitor.
152d0c080abSJoseph Pusztay 
153d0c080abSJoseph Pusztay    Level: intermediate
154d0c080abSJoseph Pusztay 
155db781477SPatrick Sanan .seealso: `TSMonitorDefault()`, `TSMonitorSet()`
156d0c080abSJoseph Pusztay @*/
157d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorCancel(TS ts)
158d0c080abSJoseph Pusztay {
159d0c080abSJoseph Pusztay   PetscInt       i;
160d0c080abSJoseph Pusztay 
161d0c080abSJoseph Pusztay   PetscFunctionBegin;
162d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
163d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
164d0c080abSJoseph Pusztay     if (ts->monitordestroy[i]) {
1659566063dSJacob Faibussowitsch       PetscCall((*ts->monitordestroy[i])(&ts->monitorcontext[i]));
166d0c080abSJoseph Pusztay     }
167d0c080abSJoseph Pusztay   }
168d0c080abSJoseph Pusztay   ts->numbermonitors = 0;
169d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
170d0c080abSJoseph Pusztay }
171d0c080abSJoseph Pusztay 
172d0c080abSJoseph Pusztay /*@C
173d0c080abSJoseph Pusztay    TSMonitorDefault - The Default monitor, prints the timestep and time for each step
174d0c080abSJoseph Pusztay 
1753a61192cSBarry Smith    Options Database:
1763a61192cSBarry Smith .  -ts_monitor - monitors the time integration
1773a61192cSBarry Smith 
1783a61192cSBarry Smith    Notes:
1793a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
1803a61192cSBarry Smith    to be used during the TS integration.
1813a61192cSBarry Smith 
182d0c080abSJoseph Pusztay    Level: intermediate
183d0c080abSJoseph Pusztay 
1843a61192cSBarry Smith .seealso: `TSMonitorSet()`,  `TSDMSwarmMonitorMoments()`, `TSMonitorExtreme()`,  `TSMonitorDrawSolution()`,
1853a61192cSBarry Smith           `TSMonitorDrawSolutionPhase()`, `TSMonitorDrawSolutionFunction()`, `TSMonitorDrawError()`, `TSMonitorSolution()`, `TSMonitorSolutionVTK()`,
1863a61192cSBarry Smith           `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorSPSwarmSolution()`, `TSMonitorError()`, `TSMonitorEnvelope()`, `TSDMSwarmMonitorMoments()`
187d0c080abSJoseph Pusztay @*/
188d0c080abSJoseph Pusztay PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf)
189d0c080abSJoseph Pusztay {
190d0c080abSJoseph Pusztay   PetscViewer    viewer =  vf->viewer;
191d0c080abSJoseph Pusztay   PetscBool      iascii,ibinary;
192d0c080abSJoseph Pusztay 
193d0c080abSJoseph Pusztay   PetscFunctionBegin;
194064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,5);
1959566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
1969566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary));
1979566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,vf->format));
198d0c080abSJoseph Pusztay   if (iascii) {
1999566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel));
200d0c080abSJoseph Pusztay     if (step == -1) { /* this indicates it is an interpolated solution */
20163a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %" PetscInt_FMT " and %" PetscInt_FMT "\n",(double)ptime,ts->steps-1,ts->steps));
202d0c080abSJoseph Pusztay     } else {
20363a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT " TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n"));
204d0c080abSJoseph Pusztay     }
2059566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel));
206d0c080abSJoseph Pusztay   } else if (ibinary) {
207d0c080abSJoseph Pusztay     PetscMPIInt rank;
2089566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank));
209c5853193SPierre Jolivet     if (rank == 0) {
210d0c080abSJoseph Pusztay       PetscBool skipHeader;
211d0c080abSJoseph Pusztay       PetscInt  classid = REAL_FILE_CLASSID;
212d0c080abSJoseph Pusztay 
2139566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryGetSkipHeader(viewer,&skipHeader));
214d0c080abSJoseph Pusztay       if (!skipHeader) {
2159566063dSJacob Faibussowitsch          PetscCall(PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT));
216d0c080abSJoseph Pusztay        }
2179566063dSJacob Faibussowitsch       PetscCall(PetscRealView(1,&ptime,viewer));
218d0c080abSJoseph Pusztay     } else {
2199566063dSJacob Faibussowitsch       PetscCall(PetscRealView(0,&ptime,viewer));
220d0c080abSJoseph Pusztay     }
221d0c080abSJoseph Pusztay   }
2229566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
223d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
224d0c080abSJoseph Pusztay }
225d0c080abSJoseph Pusztay 
226d0c080abSJoseph Pusztay /*@C
227d0c080abSJoseph Pusztay    TSMonitorExtreme - Prints the extreme values of the solution at each timestep
228d0c080abSJoseph Pusztay 
2293a61192cSBarry Smith    Notes:
2303a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
2313a61192cSBarry Smith    to be used during the TS integration.
2323a61192cSBarry Smith 
233d0c080abSJoseph Pusztay    Level: intermediate
234d0c080abSJoseph Pusztay 
235db781477SPatrick Sanan .seealso: `TSMonitorSet()`
236d0c080abSJoseph Pusztay @*/
237d0c080abSJoseph Pusztay PetscErrorCode TSMonitorExtreme(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf)
238d0c080abSJoseph Pusztay {
239d0c080abSJoseph Pusztay   PetscViewer    viewer =  vf->viewer;
240d0c080abSJoseph Pusztay   PetscBool      iascii;
241d0c080abSJoseph Pusztay   PetscReal      max,min;
242d0c080abSJoseph Pusztay 
243d0c080abSJoseph Pusztay   PetscFunctionBegin;
244064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,5);
2459566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
2469566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,vf->format));
247d0c080abSJoseph Pusztay   if (iascii) {
2489566063dSJacob Faibussowitsch     PetscCall(VecMax(v,NULL,&max));
2499566063dSJacob Faibussowitsch     PetscCall(VecMin(v,NULL,&min));
2509566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel));
25163a3b9bcSJacob 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));
2529566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel));
253d0c080abSJoseph Pusztay   }
2549566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
255d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
256d0c080abSJoseph Pusztay }
257d0c080abSJoseph Pusztay 
258d0c080abSJoseph Pusztay /*@C
259d0c080abSJoseph Pusztay    TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with
260d0c080abSJoseph Pusztay    TS to monitor the solution process graphically in various ways
261d0c080abSJoseph Pusztay 
262d0c080abSJoseph Pusztay    Collective on TS
263d0c080abSJoseph Pusztay 
264d0c080abSJoseph Pusztay    Input Parameters:
265d0c080abSJoseph Pusztay +  host - the X display to open, or null for the local machine
266d0c080abSJoseph Pusztay .  label - the title to put in the title bar
267d0c080abSJoseph Pusztay .  x, y - the screen coordinates of the upper left coordinate of the window
268d0c080abSJoseph Pusztay .  m, n - the screen width and height in pixels
269d0c080abSJoseph Pusztay -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
270d0c080abSJoseph Pusztay 
271d0c080abSJoseph Pusztay    Output Parameter:
272d0c080abSJoseph Pusztay .  ctx - the context
273d0c080abSJoseph Pusztay 
274d0c080abSJoseph Pusztay    Options Database Key:
275d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep - automatically sets line graph monitor
276d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep_log - automatically sets line graph monitor
277d0c080abSJoseph Pusztay .  -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables())
278d0c080abSJoseph Pusztay .  -ts_monitor_lg_error -  monitor the error
279d0c080abSJoseph Pusztay .  -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep
280d0c080abSJoseph Pusztay .  -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep
281d0c080abSJoseph Pusztay -  -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true
282d0c080abSJoseph Pusztay 
283d0c080abSJoseph Pusztay    Notes:
284d0c080abSJoseph Pusztay    Use TSMonitorLGCtxDestroy() to destroy.
285d0c080abSJoseph Pusztay 
286d0c080abSJoseph Pusztay    One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform()
287d0c080abSJoseph Pusztay 
288d0c080abSJoseph 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
289d0c080abSJoseph 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
290d0c080abSJoseph Pusztay    as the first argument.
291d0c080abSJoseph Pusztay 
292d0c080abSJoseph Pusztay    One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames()
293d0c080abSJoseph Pusztay 
294d0c080abSJoseph Pusztay    Level: intermediate
295d0c080abSJoseph Pusztay 
296db781477SPatrick Sanan .seealso: `TSMonitorLGTimeStep()`, `TSMonitorSet()`, `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorDefault()`, `VecView()`,
297db781477SPatrick Sanan           `TSMonitorLGCtxCreate()`, `TSMonitorLGCtxSetVariableNames()`, `TSMonitorLGCtxGetVariableNames()`,
298db781477SPatrick Sanan           `TSMonitorLGSetVariableNames()`, `TSMonitorLGGetVariableNames()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetDisplayVariables()`,
299db781477SPatrick Sanan           `TSMonitorLGCtxSetTransform()`, `TSMonitorLGSetTransform()`, `TSMonitorLGError()`, `TSMonitorLGSNESIterations()`, `TSMonitorLGKSPIterations()`,
300db781477SPatrick Sanan           `TSMonitorEnvelopeCtxCreate()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxDestroy()`, `TSMonitorEnvelop()`
301d0c080abSJoseph Pusztay 
302d0c080abSJoseph Pusztay @*/
303d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
304d0c080abSJoseph Pusztay {
305d0c080abSJoseph Pusztay   PetscDraw      draw;
306d0c080abSJoseph Pusztay 
307d0c080abSJoseph Pusztay   PetscFunctionBegin;
3089566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
3099566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm,host,label,x,y,m,n,&draw));
3109566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetFromOptions(draw));
3119566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGCreate(draw,1,&(*ctx)->lg));
3129566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGSetFromOptions((*ctx)->lg));
3139566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw));
314d0c080abSJoseph Pusztay   (*ctx)->howoften = howoften;
315d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
316d0c080abSJoseph Pusztay }
317d0c080abSJoseph Pusztay 
318d0c080abSJoseph Pusztay PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx)
319d0c080abSJoseph Pusztay {
320d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
321d0c080abSJoseph Pusztay   PetscReal      x   = ptime,y;
322d0c080abSJoseph Pusztay 
323d0c080abSJoseph Pusztay   PetscFunctionBegin;
324d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */
325d0c080abSJoseph Pusztay   if (!step) {
326d0c080abSJoseph Pusztay     PetscDrawAxis axis;
327d0c080abSJoseph Pusztay     const char *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step";
3289566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
3299566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time",ylabel));
3309566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
331d0c080abSJoseph Pusztay   }
3329566063dSJacob Faibussowitsch   PetscCall(TSGetTimeStep(ts,&y));
333d0c080abSJoseph Pusztay   if (ctx->semilogy) y = PetscLog10Real(y);
3349566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg,&x,&y));
335d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
3369566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
3379566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
338d0c080abSJoseph Pusztay   }
339d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
340d0c080abSJoseph Pusztay }
341d0c080abSJoseph Pusztay 
342d0c080abSJoseph Pusztay /*@C
343d0c080abSJoseph Pusztay    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
344d0c080abSJoseph Pusztay    with TSMonitorLGCtxCreate().
345d0c080abSJoseph Pusztay 
346d0c080abSJoseph Pusztay    Collective on TSMonitorLGCtx
347d0c080abSJoseph Pusztay 
348d0c080abSJoseph Pusztay    Input Parameter:
349d0c080abSJoseph Pusztay .  ctx - the monitor context
350d0c080abSJoseph Pusztay 
351d0c080abSJoseph Pusztay    Level: intermediate
352d0c080abSJoseph Pusztay 
353db781477SPatrick Sanan .seealso: `TSMonitorLGCtxCreate()`, `TSMonitorSet()`, `TSMonitorLGTimeStep();`
354d0c080abSJoseph Pusztay @*/
355d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
356d0c080abSJoseph Pusztay {
357d0c080abSJoseph Pusztay   PetscFunctionBegin;
358d0c080abSJoseph Pusztay   if ((*ctx)->transformdestroy) {
3599566063dSJacob Faibussowitsch     PetscCall(((*ctx)->transformdestroy)((*ctx)->transformctx));
360d0c080abSJoseph Pusztay   }
3619566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGDestroy(&(*ctx)->lg));
3629566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&(*ctx)->names));
3639566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&(*ctx)->displaynames));
3649566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ctx)->displayvariables));
3659566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ctx)->displayvalues));
3669566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
367d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
368d0c080abSJoseph Pusztay }
369d0c080abSJoseph Pusztay 
370d7462660SMatthew Knepley /* Creates a TS Monitor SPCtx for use with DMSwarm particle visualizations */
371d7462660SMatthew 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)
372d0c080abSJoseph Pusztay {
373d0c080abSJoseph Pusztay   PetscDraw      draw;
374d0c080abSJoseph Pusztay 
375d0c080abSJoseph Pusztay   PetscFunctionBegin;
3769566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
3779566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm,host,label,x,y,m,n,&draw));
3789566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetFromOptions(draw));
3799566063dSJacob Faibussowitsch   PetscCall(PetscDrawSPCreate(draw,1,&(*ctx)->sp));
3809566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw));
381d0c080abSJoseph Pusztay   (*ctx)->howoften = howoften;
382d7462660SMatthew Knepley   (*ctx)->retain   = retain;
383d7462660SMatthew Knepley   (*ctx)->phase    = phase;
384d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
385d0c080abSJoseph Pusztay }
386d0c080abSJoseph Pusztay 
387d0c080abSJoseph Pusztay /*
388d0c080abSJoseph Pusztay   Destroys a TSMonitorSPCtx that was created with TSMonitorSPCtxCreate
389d0c080abSJoseph Pusztay */
390d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSPCtxDestroy(TSMonitorSPCtx *ctx)
391d0c080abSJoseph Pusztay {
392d0c080abSJoseph Pusztay   PetscFunctionBegin;
393d0c080abSJoseph Pusztay 
3949566063dSJacob Faibussowitsch   PetscCall(PetscDrawSPDestroy(&(*ctx)->sp));
3959566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
396d0c080abSJoseph Pusztay 
397d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
398d0c080abSJoseph Pusztay 
399d0c080abSJoseph Pusztay }
400d0c080abSJoseph Pusztay 
401d0c080abSJoseph Pusztay /*@C
402d0c080abSJoseph Pusztay    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
403d0c080abSJoseph Pusztay    VecView() for the solution at each timestep
404d0c080abSJoseph Pusztay 
405d0c080abSJoseph Pusztay    Collective on TS
406d0c080abSJoseph Pusztay 
407d0c080abSJoseph Pusztay    Input Parameters:
408d0c080abSJoseph Pusztay +  ts - the TS context
409d0c080abSJoseph Pusztay .  step - current time-step
410d0c080abSJoseph Pusztay .  ptime - current time
411d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
412d0c080abSJoseph Pusztay 
413d0c080abSJoseph Pusztay    Options Database:
414d0c080abSJoseph Pusztay .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
415d0c080abSJoseph Pusztay 
416d0c080abSJoseph Pusztay    Notes:
4173a61192cSBarry Smith    The initial solution and current solution are not displayed with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
418d0c080abSJoseph Pusztay    will look bad
419d0c080abSJoseph Pusztay 
4203a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
4213a61192cSBarry Smith    to be used during the TS integration.
4223a61192cSBarry Smith 
423d0c080abSJoseph Pusztay    Level: intermediate
424d0c080abSJoseph Pusztay 
425db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
426d0c080abSJoseph Pusztay @*/
427d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
428d0c080abSJoseph Pusztay {
429d0c080abSJoseph Pusztay   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
430d0c080abSJoseph Pusztay   PetscDraw        draw;
431d0c080abSJoseph Pusztay 
432d0c080abSJoseph Pusztay   PetscFunctionBegin;
433d0c080abSJoseph Pusztay   if (!step && ictx->showinitial) {
434d0c080abSJoseph Pusztay     if (!ictx->initialsolution) {
4359566063dSJacob Faibussowitsch       PetscCall(VecDuplicate(u,&ictx->initialsolution));
436d0c080abSJoseph Pusztay     }
4379566063dSJacob Faibussowitsch     PetscCall(VecCopy(u,ictx->initialsolution));
438d0c080abSJoseph Pusztay   }
439d0c080abSJoseph Pusztay   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
440d0c080abSJoseph Pusztay 
441d0c080abSJoseph Pusztay   if (ictx->showinitial) {
442d0c080abSJoseph Pusztay     PetscReal pause;
4439566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetPause(ictx->viewer,&pause));
4449566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetPause(ictx->viewer,0.0));
4459566063dSJacob Faibussowitsch     PetscCall(VecView(ictx->initialsolution,ictx->viewer));
4469566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetPause(ictx->viewer,pause));
4479566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE));
448d0c080abSJoseph Pusztay   }
4499566063dSJacob Faibussowitsch   PetscCall(VecView(u,ictx->viewer));
450d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
451d0c080abSJoseph Pusztay     PetscReal xl,yl,xr,yr,h;
452d0c080abSJoseph Pusztay     char      time[32];
453d0c080abSJoseph Pusztay 
4549566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(ictx->viewer,0,&draw));
4559566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime));
4569566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr));
457d0c080abSJoseph Pusztay     h    = yl + .95*(yr - yl);
4589566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time));
4599566063dSJacob Faibussowitsch     PetscCall(PetscDrawFlush(draw));
460d0c080abSJoseph Pusztay   }
461d0c080abSJoseph Pusztay 
462*1baa6e33SBarry Smith   if (ictx->showinitial) PetscCall(PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE));
463d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
464d0c080abSJoseph Pusztay }
465d0c080abSJoseph Pusztay 
466d0c080abSJoseph Pusztay /*@C
467d0c080abSJoseph Pusztay    TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram
468d0c080abSJoseph Pusztay 
469d0c080abSJoseph Pusztay    Collective on TS
470d0c080abSJoseph Pusztay 
471d0c080abSJoseph Pusztay    Input Parameters:
472d0c080abSJoseph Pusztay +  ts - the TS context
473d0c080abSJoseph Pusztay .  step - current time-step
474d0c080abSJoseph Pusztay .  ptime - current time
475d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
476d0c080abSJoseph Pusztay 
4773a61192cSBarry Smith    Notes:
4783a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
4793a61192cSBarry Smith    to be used during the TS integration.
4803a61192cSBarry Smith 
481d0c080abSJoseph Pusztay    Level: intermediate
482d0c080abSJoseph Pusztay 
483db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
484d0c080abSJoseph Pusztay @*/
485d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
486d0c080abSJoseph Pusztay {
487d0c080abSJoseph Pusztay   TSMonitorDrawCtx  ictx = (TSMonitorDrawCtx)dummy;
488d0c080abSJoseph Pusztay   PetscDraw         draw;
489d0c080abSJoseph Pusztay   PetscDrawAxis     axis;
490d0c080abSJoseph Pusztay   PetscInt          n;
491d0c080abSJoseph Pusztay   PetscMPIInt       size;
492d0c080abSJoseph Pusztay   PetscReal         U0,U1,xl,yl,xr,yr,h;
493d0c080abSJoseph Pusztay   char              time[32];
494d0c080abSJoseph Pusztay   const PetscScalar *U;
495d0c080abSJoseph Pusztay 
496d0c080abSJoseph Pusztay   PetscFunctionBegin;
4979566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size));
4983c633725SBarry Smith   PetscCheck(size == 1,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs");
4999566063dSJacob Faibussowitsch   PetscCall(VecGetSize(u,&n));
5003c633725SBarry Smith   PetscCheck(n == 2,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns");
501d0c080abSJoseph Pusztay 
5029566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(ictx->viewer,0,&draw));
5039566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis));
5049566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr));
505d0c080abSJoseph Pusztay   if (!step) {
5069566063dSJacob Faibussowitsch     PetscCall(PetscDrawClear(draw));
5079566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisDraw(axis));
508d0c080abSJoseph Pusztay   }
509d0c080abSJoseph Pusztay 
5109566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(u,&U));
511d0c080abSJoseph Pusztay   U0 = PetscRealPart(U[0]);
512d0c080abSJoseph Pusztay   U1 = PetscRealPart(U[1]);
5139566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(u,&U));
514d0c080abSJoseph Pusztay   if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0);
515d0c080abSJoseph Pusztay 
516d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
5179566063dSJacob Faibussowitsch   PetscCall(PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK));
518d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
5199566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr));
5209566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime));
521d0c080abSJoseph Pusztay     h    = yl + .95*(yr - yl);
5229566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time));
523d0c080abSJoseph Pusztay   }
524d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
5259566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
5269566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
5279566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
528d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
529d0c080abSJoseph Pusztay }
530d0c080abSJoseph Pusztay 
531d0c080abSJoseph Pusztay /*@C
532d0c080abSJoseph Pusztay    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
533d0c080abSJoseph Pusztay 
534d0c080abSJoseph Pusztay    Collective on TS
535d0c080abSJoseph Pusztay 
536d0c080abSJoseph Pusztay    Input Parameters:
537d0c080abSJoseph Pusztay .    ctx - the monitor context
538d0c080abSJoseph Pusztay 
539d0c080abSJoseph Pusztay    Level: intermediate
540d0c080abSJoseph Pusztay 
541db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawSolution()`, `TSMonitorDrawError()`
542d0c080abSJoseph Pusztay @*/
543d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
544d0c080abSJoseph Pusztay {
545d0c080abSJoseph Pusztay   PetscFunctionBegin;
5469566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&(*ictx)->viewer));
5479566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ictx)->initialsolution));
5489566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ictx));
549d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
550d0c080abSJoseph Pusztay }
551d0c080abSJoseph Pusztay 
552d0c080abSJoseph Pusztay /*@C
553d0c080abSJoseph Pusztay    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
554d0c080abSJoseph Pusztay 
555d0c080abSJoseph Pusztay    Collective on TS
556d0c080abSJoseph Pusztay 
557d0c080abSJoseph Pusztay    Input Parameter:
558d0c080abSJoseph Pusztay .    ts - time-step context
559d0c080abSJoseph Pusztay 
560d0c080abSJoseph Pusztay    Output Patameter:
561d0c080abSJoseph Pusztay .    ctx - the monitor context
562d0c080abSJoseph Pusztay 
563d0c080abSJoseph Pusztay    Options Database:
564d0c080abSJoseph Pusztay .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
565d0c080abSJoseph Pusztay 
566d0c080abSJoseph Pusztay    Level: intermediate
567d0c080abSJoseph Pusztay 
568db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawCtx()`
569d0c080abSJoseph Pusztay @*/
570d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
571d0c080abSJoseph Pusztay {
572d0c080abSJoseph Pusztay   PetscFunctionBegin;
5739566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
5749566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer));
5759566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetFromOptions((*ctx)->viewer));
576d0c080abSJoseph Pusztay 
577d0c080abSJoseph Pusztay   (*ctx)->howoften    = howoften;
578d0c080abSJoseph Pusztay   (*ctx)->showinitial = PETSC_FALSE;
5799566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL));
580d0c080abSJoseph Pusztay 
581d0c080abSJoseph Pusztay   (*ctx)->showtimestepandtime = PETSC_FALSE;
5829566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL));
583d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
584d0c080abSJoseph Pusztay }
585d0c080abSJoseph Pusztay 
586d0c080abSJoseph Pusztay /*@C
587d0c080abSJoseph Pusztay    TSMonitorDrawSolutionFunction - Monitors progress of the TS solvers by calling
588d0c080abSJoseph Pusztay    VecView() for the solution provided by TSSetSolutionFunction() at each timestep
589d0c080abSJoseph Pusztay 
590d0c080abSJoseph Pusztay    Collective on TS
591d0c080abSJoseph Pusztay 
592d0c080abSJoseph Pusztay    Input Parameters:
593d0c080abSJoseph Pusztay +  ts - the TS context
594d0c080abSJoseph Pusztay .  step - current time-step
595d0c080abSJoseph Pusztay .  ptime - current time
596d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
597d0c080abSJoseph Pusztay 
598d0c080abSJoseph Pusztay    Options Database:
599d0c080abSJoseph Pusztay .  -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
600d0c080abSJoseph Pusztay 
6013a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
6023a61192cSBarry Smith    to be used during the TS integration.
6033a61192cSBarry Smith 
604d0c080abSJoseph Pusztay    Level: intermediate
605d0c080abSJoseph Pusztay 
606db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
607d0c080abSJoseph Pusztay @*/
608d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawSolutionFunction(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
609d0c080abSJoseph Pusztay {
610d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
611d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
612d0c080abSJoseph Pusztay   Vec              work;
613d0c080abSJoseph Pusztay 
614d0c080abSJoseph Pusztay   PetscFunctionBegin;
615d0c080abSJoseph Pusztay   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
6169566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u,&work));
6179566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts,ptime,work));
6189566063dSJacob Faibussowitsch   PetscCall(VecView(work,viewer));
6199566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work));
620d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
621d0c080abSJoseph Pusztay }
622d0c080abSJoseph Pusztay 
623d0c080abSJoseph Pusztay /*@C
624d0c080abSJoseph Pusztay    TSMonitorDrawError - Monitors progress of the TS solvers by calling
625d0c080abSJoseph Pusztay    VecView() for the error at each timestep
626d0c080abSJoseph Pusztay 
627d0c080abSJoseph Pusztay    Collective on TS
628d0c080abSJoseph Pusztay 
629d0c080abSJoseph Pusztay    Input Parameters:
630d0c080abSJoseph Pusztay +  ts - the TS context
631d0c080abSJoseph Pusztay .  step - current time-step
632d0c080abSJoseph Pusztay .  ptime - current time
633d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
634d0c080abSJoseph Pusztay 
635d0c080abSJoseph Pusztay    Options Database:
636d0c080abSJoseph Pusztay .  -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
637d0c080abSJoseph Pusztay 
6383a61192cSBarry Smith    Notes:
6393a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
6403a61192cSBarry Smith    to be used during the TS integration.
6413a61192cSBarry Smith 
642d0c080abSJoseph Pusztay    Level: intermediate
643d0c080abSJoseph Pusztay 
644db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
645d0c080abSJoseph Pusztay @*/
646d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
647d0c080abSJoseph Pusztay {
648d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
649d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
650d0c080abSJoseph Pusztay   Vec              work;
651d0c080abSJoseph Pusztay 
652d0c080abSJoseph Pusztay   PetscFunctionBegin;
653d0c080abSJoseph Pusztay   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
6549566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u,&work));
6559566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts,ptime,work));
6569566063dSJacob Faibussowitsch   PetscCall(VecAXPY(work,-1.0,u));
6579566063dSJacob Faibussowitsch   PetscCall(VecView(work,viewer));
6589566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work));
659d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
660d0c080abSJoseph Pusztay }
661d0c080abSJoseph Pusztay 
662d0c080abSJoseph Pusztay /*@C
663d0c080abSJoseph 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
664d0c080abSJoseph Pusztay 
665d0c080abSJoseph Pusztay    Collective on TS
666d0c080abSJoseph Pusztay 
667d0c080abSJoseph Pusztay    Input Parameters:
668d0c080abSJoseph Pusztay +  ts - the TS context
669d0c080abSJoseph Pusztay .  step - current time-step
670d0c080abSJoseph Pusztay .  ptime - current time
671d0c080abSJoseph Pusztay .  u - current state
672d0c080abSJoseph Pusztay -  vf - viewer and its format
673d0c080abSJoseph Pusztay 
6743a61192cSBarry Smith    Notes:
6753a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
6763a61192cSBarry Smith    to be used during the TS integration.
6773a61192cSBarry Smith 
678d0c080abSJoseph Pusztay    Level: intermediate
679d0c080abSJoseph Pusztay 
680db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
681d0c080abSJoseph Pusztay @*/
682d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
683d0c080abSJoseph Pusztay {
684d0c080abSJoseph Pusztay   PetscFunctionBegin;
6859566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(vf->viewer,vf->format));
6869566063dSJacob Faibussowitsch   PetscCall(VecView(u,vf->viewer));
6879566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(vf->viewer));
688d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
689d0c080abSJoseph Pusztay }
690d0c080abSJoseph Pusztay 
691d0c080abSJoseph Pusztay /*@C
692d0c080abSJoseph Pusztay    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
693d0c080abSJoseph Pusztay 
694d0c080abSJoseph Pusztay    Collective on TS
695d0c080abSJoseph Pusztay 
696d0c080abSJoseph Pusztay    Input Parameters:
697d0c080abSJoseph Pusztay +  ts - the TS context
698d0c080abSJoseph Pusztay .  step - current time-step
699d0c080abSJoseph Pusztay .  ptime - current time
700d0c080abSJoseph Pusztay .  u - current state
70163a3b9bcSJacob Faibussowitsch -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03" PetscInt_FMT ")
702d0c080abSJoseph Pusztay 
703d0c080abSJoseph Pusztay    Level: intermediate
704d0c080abSJoseph Pusztay 
705d0c080abSJoseph Pusztay    Notes:
706d0c080abSJoseph 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.
707d0c080abSJoseph Pusztay    These are named according to the file name template.
708d0c080abSJoseph Pusztay 
7093a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
7103a61192cSBarry Smith    to be used during the TS integration.
711d0c080abSJoseph Pusztay 
712db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`
713d0c080abSJoseph Pusztay @*/
714d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
715d0c080abSJoseph Pusztay {
716d0c080abSJoseph Pusztay   char           filename[PETSC_MAX_PATH_LEN];
717d0c080abSJoseph Pusztay   PetscViewer    viewer;
718d0c080abSJoseph Pusztay 
719d0c080abSJoseph Pusztay   PetscFunctionBegin;
720d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
7219566063dSJacob Faibussowitsch   PetscCall(PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step));
7229566063dSJacob Faibussowitsch   PetscCall(PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer));
7239566063dSJacob Faibussowitsch   PetscCall(VecView(u,viewer));
7249566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&viewer));
725d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
726d0c080abSJoseph Pusztay }
727d0c080abSJoseph Pusztay 
728d0c080abSJoseph Pusztay /*@C
729d0c080abSJoseph Pusztay    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
730d0c080abSJoseph Pusztay 
731d0c080abSJoseph Pusztay    Collective on TS
732d0c080abSJoseph Pusztay 
733d0c080abSJoseph Pusztay    Input Parameters:
73463a3b9bcSJacob Faibussowitsch .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03" PetscInt_FMT ")
735d0c080abSJoseph Pusztay 
736d0c080abSJoseph Pusztay    Level: intermediate
737d0c080abSJoseph Pusztay 
738d0c080abSJoseph Pusztay    Note:
739d0c080abSJoseph Pusztay    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
740d0c080abSJoseph Pusztay 
741db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorSolutionVTK()`
742d0c080abSJoseph Pusztay @*/
743d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
744d0c080abSJoseph Pusztay {
745d0c080abSJoseph Pusztay   PetscFunctionBegin;
7469566063dSJacob Faibussowitsch   PetscCall(PetscFree(*(char**)filenametemplate));
747d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
748d0c080abSJoseph Pusztay }
749d0c080abSJoseph Pusztay 
750d0c080abSJoseph Pusztay /*@C
751d0c080abSJoseph Pusztay    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
752d0c080abSJoseph Pusztay        in a time based line graph
753d0c080abSJoseph Pusztay 
754d0c080abSJoseph Pusztay    Collective on TS
755d0c080abSJoseph Pusztay 
756d0c080abSJoseph Pusztay    Input Parameters:
757d0c080abSJoseph Pusztay +  ts - the TS context
758d0c080abSJoseph Pusztay .  step - current time-step
759d0c080abSJoseph Pusztay .  ptime - current time
760d0c080abSJoseph Pusztay .  u - current solution
761d0c080abSJoseph Pusztay -  dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate()
762d0c080abSJoseph Pusztay 
763d0c080abSJoseph Pusztay    Options Database:
76467b8a455SSatish Balay .   -ts_monitor_lg_solution_variables - enable monitor of lg solution variables
765d0c080abSJoseph Pusztay 
766d0c080abSJoseph Pusztay    Level: intermediate
767d0c080abSJoseph Pusztay 
768d0c080abSJoseph Pusztay    Notes:
769d0c080abSJoseph Pusztay    Each process in a parallel run displays its component solutions in a separate window
770d0c080abSJoseph Pusztay 
7713a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
7723a61192cSBarry Smith    to be used during the TS integration.
7733a61192cSBarry Smith 
774db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGCtxCreate()`, `TSMonitorLGCtxSetVariableNames()`, `TSMonitorLGCtxGetVariableNames()`,
775db781477SPatrick Sanan           `TSMonitorLGSetVariableNames()`, `TSMonitorLGGetVariableNames()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetDisplayVariables()`,
776db781477SPatrick Sanan           `TSMonitorLGCtxSetTransform()`, `TSMonitorLGSetTransform()`, `TSMonitorLGError()`, `TSMonitorLGSNESIterations()`, `TSMonitorLGKSPIterations()`,
777db781477SPatrick Sanan           `TSMonitorEnvelopeCtxCreate()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxDestroy()`, `TSMonitorEnvelop()`
778d0c080abSJoseph Pusztay @*/
779d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
780d0c080abSJoseph Pusztay {
781d0c080abSJoseph Pusztay   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dctx;
782d0c080abSJoseph Pusztay   const PetscScalar *yy;
783d0c080abSJoseph Pusztay   Vec               v;
784d0c080abSJoseph Pusztay 
785d0c080abSJoseph Pusztay   PetscFunctionBegin;
786d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
787d0c080abSJoseph Pusztay   if (!step) {
788d0c080abSJoseph Pusztay     PetscDrawAxis axis;
789d0c080abSJoseph Pusztay     PetscInt      dim;
7909566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
7919566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution"));
792d0c080abSJoseph Pusztay     if (!ctx->names) {
793d0c080abSJoseph Pusztay       PetscBool flg;
794d0c080abSJoseph Pusztay       /* user provides names of variables to plot but no names has been set so assume names are integer values */
7959566063dSJacob Faibussowitsch       PetscCall(PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg));
796d0c080abSJoseph Pusztay       if (flg) {
797d0c080abSJoseph Pusztay         PetscInt i,n;
798d0c080abSJoseph Pusztay         char     **names;
7999566063dSJacob Faibussowitsch         PetscCall(VecGetSize(u,&n));
8009566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(n+1,&names));
801d0c080abSJoseph Pusztay         for (i=0; i<n; i++) {
8029566063dSJacob Faibussowitsch           PetscCall(PetscMalloc1(5,&names[i]));
80363a3b9bcSJacob Faibussowitsch           PetscCall(PetscSNPrintf(names[i],5,"%" PetscInt_FMT,i));
804d0c080abSJoseph Pusztay         }
805d0c080abSJoseph Pusztay         names[n] = NULL;
806d0c080abSJoseph Pusztay         ctx->names = names;
807d0c080abSJoseph Pusztay       }
808d0c080abSJoseph Pusztay     }
809d0c080abSJoseph Pusztay     if (ctx->names && !ctx->displaynames) {
810d0c080abSJoseph Pusztay       char      **displaynames;
811d0c080abSJoseph Pusztay       PetscBool flg;
8129566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u,&dim));
8139566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(dim+1,&displaynames));
8149566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg));
815*1baa6e33SBarry Smith       if (flg) PetscCall(TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames));
8169566063dSJacob Faibussowitsch       PetscCall(PetscStrArrayDestroy(&displaynames));
817d0c080abSJoseph Pusztay     }
818d0c080abSJoseph Pusztay     if (ctx->displaynames) {
8199566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables));
8209566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames));
821d0c080abSJoseph Pusztay     } else if (ctx->names) {
8229566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u,&dim));
8239566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg,dim));
8249566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names));
825d0c080abSJoseph Pusztay     } else {
8269566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u,&dim));
8279566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg,dim));
828d0c080abSJoseph Pusztay     }
8299566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
830d0c080abSJoseph Pusztay   }
831d0c080abSJoseph Pusztay 
832d0c080abSJoseph Pusztay   if (!ctx->transform) v = u;
8339566063dSJacob Faibussowitsch   else PetscCall((*ctx->transform)(ctx->transformctx,u,&v));
8349566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(v,&yy));
835d0c080abSJoseph Pusztay   if (ctx->displaynames) {
836d0c080abSJoseph Pusztay     PetscInt i;
837d0c080abSJoseph Pusztay     for (i=0; i<ctx->ndisplayvariables; i++)
838d0c080abSJoseph Pusztay       ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]);
8399566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues));
840d0c080abSJoseph Pusztay   } else {
841d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
842d0c080abSJoseph Pusztay     PetscInt  i,n;
843d0c080abSJoseph Pusztay     PetscReal *yreal;
8449566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(v,&n));
8459566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&yreal));
846d0c080abSJoseph Pusztay     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
8479566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal));
8489566063dSJacob Faibussowitsch     PetscCall(PetscFree(yreal));
849d0c080abSJoseph Pusztay #else
8509566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy));
851d0c080abSJoseph Pusztay #endif
852d0c080abSJoseph Pusztay   }
8539566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(v,&yy));
8549566063dSJacob Faibussowitsch   if (ctx->transform) PetscCall(VecDestroy(&v));
855d0c080abSJoseph Pusztay 
856d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
8579566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
8589566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
859d0c080abSJoseph Pusztay   }
860d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
861d0c080abSJoseph Pusztay }
862d0c080abSJoseph Pusztay 
863d0c080abSJoseph Pusztay /*@C
864d0c080abSJoseph Pusztay    TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
865d0c080abSJoseph Pusztay 
866d0c080abSJoseph Pusztay    Collective on TS
867d0c080abSJoseph Pusztay 
868d0c080abSJoseph Pusztay    Input Parameters:
869d0c080abSJoseph Pusztay +  ts - the TS context
870d0c080abSJoseph Pusztay -  names - the names of the components, final string must be NULL
871d0c080abSJoseph Pusztay 
872d0c080abSJoseph Pusztay    Level: intermediate
873d0c080abSJoseph Pusztay 
874d0c080abSJoseph Pusztay    Notes:
875d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
876d0c080abSJoseph Pusztay 
877db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetVariableNames()`
878d0c080abSJoseph Pusztay @*/
879d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSetVariableNames(TS ts,const char * const *names)
880d0c080abSJoseph Pusztay {
881d0c080abSJoseph Pusztay   PetscInt          i;
882d0c080abSJoseph Pusztay 
883d0c080abSJoseph Pusztay   PetscFunctionBegin;
884d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
885d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
8869566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names));
887d0c080abSJoseph Pusztay       break;
888d0c080abSJoseph Pusztay     }
889d0c080abSJoseph Pusztay   }
890d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
891d0c080abSJoseph Pusztay }
892d0c080abSJoseph Pusztay 
893d0c080abSJoseph Pusztay /*@C
894d0c080abSJoseph Pusztay    TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
895d0c080abSJoseph Pusztay 
896d0c080abSJoseph Pusztay    Collective on TS
897d0c080abSJoseph Pusztay 
898d0c080abSJoseph Pusztay    Input Parameters:
899d0c080abSJoseph Pusztay +  ts - the TS context
900d0c080abSJoseph Pusztay -  names - the names of the components, final string must be NULL
901d0c080abSJoseph Pusztay 
902d0c080abSJoseph Pusztay    Level: intermediate
903d0c080abSJoseph Pusztay 
904db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGSetVariableNames()`
905d0c080abSJoseph Pusztay @*/
906d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names)
907d0c080abSJoseph Pusztay {
908d0c080abSJoseph Pusztay   PetscFunctionBegin;
9099566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&ctx->names));
9109566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(names,&ctx->names));
911d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
912d0c080abSJoseph Pusztay }
913d0c080abSJoseph Pusztay 
914d0c080abSJoseph Pusztay /*@C
915d0c080abSJoseph Pusztay    TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot
916d0c080abSJoseph Pusztay 
917d0c080abSJoseph Pusztay    Collective on TS
918d0c080abSJoseph Pusztay 
919d0c080abSJoseph Pusztay    Input Parameter:
920d0c080abSJoseph Pusztay .  ts - the TS context
921d0c080abSJoseph Pusztay 
922d0c080abSJoseph Pusztay    Output Parameter:
923d0c080abSJoseph Pusztay .  names - the names of the components, final string must be NULL
924d0c080abSJoseph Pusztay 
925d0c080abSJoseph Pusztay    Level: intermediate
926d0c080abSJoseph Pusztay 
927d0c080abSJoseph Pusztay    Notes:
928d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
929d0c080abSJoseph Pusztay 
930db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`
931d0c080abSJoseph Pusztay @*/
932d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGGetVariableNames(TS ts,const char *const **names)
933d0c080abSJoseph Pusztay {
934d0c080abSJoseph Pusztay   PetscInt       i;
935d0c080abSJoseph Pusztay 
936d0c080abSJoseph Pusztay   PetscFunctionBegin;
937d0c080abSJoseph Pusztay   *names = NULL;
938d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
939d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
940d0c080abSJoseph Pusztay       TSMonitorLGCtx  ctx = (TSMonitorLGCtx) ts->monitorcontext[i];
941d0c080abSJoseph Pusztay       *names = (const char *const *)ctx->names;
942d0c080abSJoseph Pusztay       break;
943d0c080abSJoseph Pusztay     }
944d0c080abSJoseph Pusztay   }
945d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
946d0c080abSJoseph Pusztay }
947d0c080abSJoseph Pusztay 
948d0c080abSJoseph Pusztay /*@C
949d0c080abSJoseph Pusztay    TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor
950d0c080abSJoseph Pusztay 
951d0c080abSJoseph Pusztay    Collective on TS
952d0c080abSJoseph Pusztay 
953d0c080abSJoseph Pusztay    Input Parameters:
954d0c080abSJoseph Pusztay +  ctx - the TSMonitorLG context
955d0c080abSJoseph Pusztay -  displaynames - the names of the components, final string must be NULL
956d0c080abSJoseph Pusztay 
957d0c080abSJoseph Pusztay    Level: intermediate
958d0c080abSJoseph Pusztay 
959db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`
960d0c080abSJoseph Pusztay @*/
961d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames)
962d0c080abSJoseph Pusztay {
963d0c080abSJoseph Pusztay   PetscInt          j = 0,k;
964d0c080abSJoseph Pusztay 
965d0c080abSJoseph Pusztay   PetscFunctionBegin;
966d0c080abSJoseph Pusztay   if (!ctx->names) PetscFunctionReturn(0);
9679566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&ctx->displaynames));
9689566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(displaynames,&ctx->displaynames));
969d0c080abSJoseph Pusztay   while (displaynames[j]) j++;
970d0c080abSJoseph Pusztay   ctx->ndisplayvariables = j;
9719566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables));
9729566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues));
973d0c080abSJoseph Pusztay   j = 0;
974d0c080abSJoseph Pusztay   while (displaynames[j]) {
975d0c080abSJoseph Pusztay     k = 0;
976d0c080abSJoseph Pusztay     while (ctx->names[k]) {
977d0c080abSJoseph Pusztay       PetscBool flg;
9789566063dSJacob Faibussowitsch       PetscCall(PetscStrcmp(displaynames[j],ctx->names[k],&flg));
979d0c080abSJoseph Pusztay       if (flg) {
980d0c080abSJoseph Pusztay         ctx->displayvariables[j] = k;
981d0c080abSJoseph Pusztay         break;
982d0c080abSJoseph Pusztay       }
983d0c080abSJoseph Pusztay       k++;
984d0c080abSJoseph Pusztay     }
985d0c080abSJoseph Pusztay     j++;
986d0c080abSJoseph Pusztay   }
987d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
988d0c080abSJoseph Pusztay }
989d0c080abSJoseph Pusztay 
990d0c080abSJoseph Pusztay /*@C
991d0c080abSJoseph Pusztay    TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor
992d0c080abSJoseph Pusztay 
993d0c080abSJoseph Pusztay    Collective on TS
994d0c080abSJoseph Pusztay 
995d0c080abSJoseph Pusztay    Input Parameters:
996d0c080abSJoseph Pusztay +  ts - the TS context
997d0c080abSJoseph Pusztay -  displaynames - the names of the components, final string must be NULL
998d0c080abSJoseph Pusztay 
999d0c080abSJoseph Pusztay    Notes:
1000d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
1001d0c080abSJoseph Pusztay 
1002d0c080abSJoseph Pusztay    Level: intermediate
1003d0c080abSJoseph Pusztay 
1004db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`
1005d0c080abSJoseph Pusztay @*/
1006d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames)
1007d0c080abSJoseph Pusztay {
1008d0c080abSJoseph Pusztay   PetscInt          i;
1009d0c080abSJoseph Pusztay 
1010d0c080abSJoseph Pusztay   PetscFunctionBegin;
1011d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
1012d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
10139566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames));
1014d0c080abSJoseph Pusztay       break;
1015d0c080abSJoseph Pusztay     }
1016d0c080abSJoseph Pusztay   }
1017d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1018d0c080abSJoseph Pusztay }
1019d0c080abSJoseph Pusztay 
1020d0c080abSJoseph Pusztay /*@C
1021d0c080abSJoseph Pusztay    TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed
1022d0c080abSJoseph Pusztay 
1023d0c080abSJoseph Pusztay    Collective on TS
1024d0c080abSJoseph Pusztay 
1025d0c080abSJoseph Pusztay    Input Parameters:
1026d0c080abSJoseph Pusztay +  ts - the TS context
1027d0c080abSJoseph Pusztay .  transform - the transform function
1028d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
1029d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
1030d0c080abSJoseph Pusztay 
1031d0c080abSJoseph Pusztay    Notes:
1032d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
1033d0c080abSJoseph Pusztay 
1034d0c080abSJoseph Pusztay    Level: intermediate
1035d0c080abSJoseph Pusztay 
1036db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`, `TSMonitorLGCtxSetTransform()`
1037d0c080abSJoseph Pusztay @*/
1038d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
1039d0c080abSJoseph Pusztay {
1040d0c080abSJoseph Pusztay   PetscInt          i;
1041d0c080abSJoseph Pusztay 
1042d0c080abSJoseph Pusztay   PetscFunctionBegin;
1043d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
1044d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
10459566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx));
1046d0c080abSJoseph Pusztay     }
1047d0c080abSJoseph Pusztay   }
1048d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1049d0c080abSJoseph Pusztay }
1050d0c080abSJoseph Pusztay 
1051d0c080abSJoseph Pusztay /*@C
1052d0c080abSJoseph Pusztay    TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed
1053d0c080abSJoseph Pusztay 
1054d0c080abSJoseph Pusztay    Collective on TSLGCtx
1055d0c080abSJoseph Pusztay 
1056d0c080abSJoseph Pusztay    Input Parameters:
1057d0c080abSJoseph Pusztay +  ts - the TS context
1058d0c080abSJoseph Pusztay .  transform - the transform function
1059d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
1060d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
1061d0c080abSJoseph Pusztay 
1062d0c080abSJoseph Pusztay    Level: intermediate
1063d0c080abSJoseph Pusztay 
1064db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`, `TSMonitorLGSetTransform()`
1065d0c080abSJoseph Pusztay @*/
1066d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
1067d0c080abSJoseph Pusztay {
1068d0c080abSJoseph Pusztay   PetscFunctionBegin;
1069d0c080abSJoseph Pusztay   ctx->transform    = transform;
1070d0c080abSJoseph Pusztay   ctx->transformdestroy = destroy;
1071d0c080abSJoseph Pusztay   ctx->transformctx = tctx;
1072d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1073d0c080abSJoseph Pusztay }
1074d0c080abSJoseph Pusztay 
1075d0c080abSJoseph Pusztay /*@C
1076d0c080abSJoseph Pusztay    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error
1077d0c080abSJoseph Pusztay        in a time based line graph
1078d0c080abSJoseph Pusztay 
1079d0c080abSJoseph Pusztay    Collective on TS
1080d0c080abSJoseph Pusztay 
1081d0c080abSJoseph Pusztay    Input Parameters:
1082d0c080abSJoseph Pusztay +  ts - the TS context
1083d0c080abSJoseph Pusztay .  step - current time-step
1084d0c080abSJoseph Pusztay .  ptime - current time
1085d0c080abSJoseph Pusztay .  u - current solution
1086d0c080abSJoseph Pusztay -  dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate()
1087d0c080abSJoseph Pusztay 
10883a61192cSBarry Smith    Options Database Keys:
10893a61192cSBarry Smith .  -ts_monitor_lg_error - create a graphical monitor of error history
10903a61192cSBarry Smith 
1091d0c080abSJoseph Pusztay    Level: intermediate
1092d0c080abSJoseph Pusztay 
1093d0c080abSJoseph Pusztay    Notes:
1094d0c080abSJoseph Pusztay     Each process in a parallel run displays its component errors in a separate window
1095d0c080abSJoseph Pusztay 
1096d0c080abSJoseph Pusztay    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
1097d0c080abSJoseph Pusztay 
10983a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
10993a61192cSBarry Smith    to be used during the TS integration.
1100d0c080abSJoseph Pusztay 
1101db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
1102d0c080abSJoseph Pusztay @*/
1103d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
1104d0c080abSJoseph Pusztay {
1105d0c080abSJoseph Pusztay   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
1106d0c080abSJoseph Pusztay   const PetscScalar *yy;
1107d0c080abSJoseph Pusztay   Vec               y;
1108d0c080abSJoseph Pusztay 
1109d0c080abSJoseph Pusztay   PetscFunctionBegin;
1110d0c080abSJoseph Pusztay   if (!step) {
1111d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1112d0c080abSJoseph Pusztay     PetscInt      dim;
11139566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
11149566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Error"));
11159566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(u,&dim));
11169566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSetDimension(ctx->lg,dim));
11179566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1118d0c080abSJoseph Pusztay   }
11199566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u,&y));
11209566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts,ptime,y));
11219566063dSJacob Faibussowitsch   PetscCall(VecAXPY(y,-1.0,u));
11229566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(y,&yy));
1123d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
1124d0c080abSJoseph Pusztay   {
1125d0c080abSJoseph Pusztay     PetscReal *yreal;
1126d0c080abSJoseph Pusztay     PetscInt  i,n;
11279566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(y,&n));
11289566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&yreal));
1129d0c080abSJoseph Pusztay     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
11309566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal));
11319566063dSJacob Faibussowitsch     PetscCall(PetscFree(yreal));
1132d0c080abSJoseph Pusztay   }
1133d0c080abSJoseph Pusztay #else
11349566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy));
1135d0c080abSJoseph Pusztay #endif
11369566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(y,&yy));
11379566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&y));
1138d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
11399566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
11409566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1141d0c080abSJoseph Pusztay   }
1142d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1143d0c080abSJoseph Pusztay }
1144d0c080abSJoseph Pusztay 
1145d0c080abSJoseph Pusztay /*@C
1146d0c080abSJoseph Pusztay    TSMonitorSPSwarmSolution - Graphically displays phase plots of DMSwarm particles on a scatter plot
1147d0c080abSJoseph Pusztay 
1148d0c080abSJoseph Pusztay    Input Parameters:
1149d0c080abSJoseph Pusztay +  ts - the TS context
1150d0c080abSJoseph Pusztay .  step - current time-step
1151d0c080abSJoseph Pusztay .  ptime - current time
1152d0c080abSJoseph Pusztay .  u - current solution
1153d0c080abSJoseph Pusztay -  dctx - the TSMonitorSPCtx object that contains all the options for the monitoring, this is created with TSMonitorSPCtxCreate()
1154d0c080abSJoseph Pusztay 
1155d0c080abSJoseph Pusztay    Options Database:
1156d7462660SMatthew Knepley + -ts_monitor_sp_swarm <n>          - Monitor the solution every n steps, or -1 for plotting only the final solution
1157d7462660SMatthew Knepley . -ts_monitor_sp_swarm_retain <n>   - Retain n old points so we can see the history, or -1 for all points
1158d7462660SMatthew Knepley - -ts_monitor_sp_swarm_phase <bool> - Plot in phase space, as opposed to coordinate space
1159d0c080abSJoseph Pusztay 
1160d0c080abSJoseph Pusztay    Level: intermediate
1161d0c080abSJoseph Pusztay 
11623a61192cSBarry Smith    Notes:
11633a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
11643a61192cSBarry Smith    to be used during the TS integration.
11653a61192cSBarry Smith 
1166db781477SPatrick Sanan .seealso: `TSMonitoSet()`
1167d0c080abSJoseph Pusztay @*/
1168d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSPSwarmSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx)
1169d0c080abSJoseph Pusztay {
1170d0c080abSJoseph Pusztay   TSMonitorSPCtx     ctx = (TSMonitorSPCtx) dctx;
1171f98b2f00SMatthew G. Knepley   PetscDraw          draw;
1172d7462660SMatthew Knepley   DM                 dm, cdm;
1173d0c080abSJoseph Pusztay   const PetscScalar *yy;
1174d0c080abSJoseph Pusztay   PetscInt           Np, p, dim = 2;
1175d0c080abSJoseph Pusztay 
1176d0c080abSJoseph Pusztay   PetscFunctionBegin;
1177d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1178d0c080abSJoseph Pusztay   if (!step) {
1179d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1180ab43fcacSJoe Pusztay     PetscReal     dmboxlower[2], dmboxupper[2];
1181f98b2f00SMatthew G. Knepley 
11829566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &dm));
11839566063dSJacob Faibussowitsch     PetscCall(DMGetDimension(dm, &dim));
11843c633725SBarry Smith     PetscCheck(dim == 2, PETSC_COMM_SELF, PETSC_ERR_SUP, "Monitor only supports two dimensional fields");
11859566063dSJacob Faibussowitsch     PetscCall(DMSwarmGetCellDM(dm, &cdm));
11869566063dSJacob Faibussowitsch     PetscCall(DMGetBoundingBox(cdm, dmboxlower, dmboxupper));
11879566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(u, &Np));
1188d7462660SMatthew Knepley     Np /= dim*2;
11899566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPGetAxis(ctx->sp,&axis));
11908c87cf4dSdanfinn     if (ctx->phase) {
11919566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(axis,"Particles","X","V"));
11929566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], -5, 5));
11938c87cf4dSdanfinn     } else {
11949566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(axis,"Particles","X","Y"));
11959566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], dmboxlower[1], dmboxupper[1]));
11968c87cf4dSdanfinn     }
11979566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetHoldLimits(axis, PETSC_TRUE));
11989566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPReset(ctx->sp));
1199d0c080abSJoseph Pusztay   }
12009566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(u, &Np));
1201d7462660SMatthew Knepley   Np /= dim*2;
1202d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
12039566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPGetDraw(ctx->sp, &draw));
1204d7462660SMatthew Knepley     if ((ctx->retain == 0) || (ctx->retain > 0 && !(step % ctx->retain))) {
12059566063dSJacob Faibussowitsch       PetscCall(PetscDrawClear(draw));
1206d7462660SMatthew Knepley     }
12079566063dSJacob Faibussowitsch     PetscCall(PetscDrawFlush(draw));
12089566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPReset(ctx->sp));
1209f98b2f00SMatthew G. Knepley     PetscCall(VecGetArrayRead(u, &yy));
1210f98b2f00SMatthew G. Knepley     for (p = 0; p < Np; ++p) {
1211f98b2f00SMatthew G. Knepley       PetscReal x, y;
1212f98b2f00SMatthew G. Knepley 
1213f98b2f00SMatthew G. Knepley       if (ctx->phase) {
1214f98b2f00SMatthew G. Knepley         x = PetscRealPart(yy[p*dim*2]);
1215f98b2f00SMatthew G. Knepley         y = PetscRealPart(yy[p*dim*2 + dim]);
1216f98b2f00SMatthew G. Knepley       } else {
1217f98b2f00SMatthew G. Knepley         x = PetscRealPart(yy[p*dim*2]);
1218f98b2f00SMatthew G. Knepley         y = PetscRealPart(yy[p*dim*2 + 1]);
1219f98b2f00SMatthew G. Knepley       }
1220f98b2f00SMatthew G. Knepley       PetscCall(PetscDrawSPAddPoint(ctx->sp, &x, &y));
1221f98b2f00SMatthew G. Knepley     }
1222f98b2f00SMatthew G. Knepley     PetscCall(VecRestoreArrayRead(u, &yy));
12239566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPDraw(ctx->sp, PETSC_FALSE));
12249566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPSave(ctx->sp));
1225d0c080abSJoseph Pusztay   }
1226d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1227d0c080abSJoseph Pusztay }
1228d0c080abSJoseph Pusztay 
1229d0c080abSJoseph Pusztay /*@C
1230d0c080abSJoseph Pusztay    TSMonitorError - Monitors progress of the TS solvers by printing the 2 norm of the error at each timestep
1231d0c080abSJoseph Pusztay 
1232d0c080abSJoseph Pusztay    Collective on TS
1233d0c080abSJoseph Pusztay 
1234d0c080abSJoseph Pusztay    Input Parameters:
1235d0c080abSJoseph Pusztay +  ts - the TS context
1236d0c080abSJoseph Pusztay .  step - current time-step
1237d0c080abSJoseph Pusztay .  ptime - current time
1238d0c080abSJoseph Pusztay .  u - current solution
1239d0c080abSJoseph Pusztay -  dctx - unused context
1240d0c080abSJoseph Pusztay 
1241d0c080abSJoseph Pusztay    Level: intermediate
1242d0c080abSJoseph Pusztay 
12433a61192cSBarry Smith    Notes:
12443a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
12453a61192cSBarry Smith    to be used during the TS integration.
12463a61192cSBarry Smith 
1247d0c080abSJoseph Pusztay    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
1248d0c080abSJoseph Pusztay 
1249d0c080abSJoseph Pusztay    Options Database Keys:
1250d0c080abSJoseph Pusztay .  -ts_monitor_error - create a graphical monitor of error history
1251d0c080abSJoseph Pusztay 
1252db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()`
1253d0c080abSJoseph Pusztay @*/
1254d0c080abSJoseph Pusztay PetscErrorCode TSMonitorError(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
1255d0c080abSJoseph Pusztay {
125607eaae0cSMatthew G. Knepley   DM             dm;
125707eaae0cSMatthew G. Knepley   PetscDS        ds = NULL;
125807eaae0cSMatthew G. Knepley   PetscInt       Nf = -1, f;
1259d0c080abSJoseph Pusztay   PetscBool      flg;
1260d0c080abSJoseph Pusztay 
1261d0c080abSJoseph Pusztay   PetscFunctionBegin;
12629566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
12639566063dSJacob Faibussowitsch   if (dm) PetscCall(DMGetDS(dm, &ds));
12649566063dSJacob Faibussowitsch   if (ds) PetscCall(PetscDSGetNumFields(ds, &Nf));
126507eaae0cSMatthew G. Knepley   if (Nf <= 0) {
126607eaae0cSMatthew G. Knepley     Vec       y;
126707eaae0cSMatthew G. Knepley     PetscReal nrm;
126807eaae0cSMatthew G. Knepley 
12699566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u,&y));
12709566063dSJacob Faibussowitsch     PetscCall(TSComputeSolutionFunction(ts,ptime,y));
12719566063dSJacob Faibussowitsch     PetscCall(VecAXPY(y,-1.0,u));
12729566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERASCII,&flg));
1273d0c080abSJoseph Pusztay     if (flg) {
12749566063dSJacob Faibussowitsch       PetscCall(VecNorm(y,NORM_2,&nrm));
12759566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vf->viewer,"2-norm of error %g\n",(double)nrm));
1276d0c080abSJoseph Pusztay     }
12779566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERDRAW,&flg));
1278*1baa6e33SBarry Smith     if (flg) PetscCall(VecView(y,vf->viewer));
12799566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&y));
128007eaae0cSMatthew G. Knepley   } else {
128107eaae0cSMatthew G. Knepley     PetscErrorCode (**exactFuncs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx);
128207eaae0cSMatthew G. Knepley     void            **ctxs;
128307eaae0cSMatthew G. Knepley     Vec               v;
128407eaae0cSMatthew G. Knepley     PetscReal         ferrors[1];
128507eaae0cSMatthew G. Knepley 
12869566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(Nf, &exactFuncs, Nf, &ctxs));
12879566063dSJacob Faibussowitsch     for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(ds, f, &exactFuncs[f], &ctxs[f]));
12889566063dSJacob Faibussowitsch     PetscCall(DMComputeL2FieldDiff(dm, ptime, exactFuncs, ctxs, u, ferrors));
12899566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Timestep: %04d time = %-8.4g \t L_2 Error: [", (int) step, (double) ptime));
129007eaae0cSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
12919566063dSJacob Faibussowitsch       if (f > 0) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ", "));
12929566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%2.3g", (double) ferrors[f]));
129307eaae0cSMatthew G. Knepley     }
12949566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "]\n"));
129507eaae0cSMatthew G. Knepley 
12969566063dSJacob Faibussowitsch     PetscCall(VecViewFromOptions(u, NULL, "-sol_vec_view"));
129707eaae0cSMatthew G. Knepley 
12989566063dSJacob Faibussowitsch     PetscCall(PetscOptionsHasName(NULL, NULL, "-exact_vec_view", &flg));
129907eaae0cSMatthew G. Knepley     if (flg) {
13009566063dSJacob Faibussowitsch       PetscCall(DMGetGlobalVector(dm, &v));
13019566063dSJacob Faibussowitsch       PetscCall(DMProjectFunction(dm, ptime, exactFuncs, ctxs, INSERT_ALL_VALUES, v));
13029566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetName((PetscObject) v, "Exact Solution"));
13039566063dSJacob Faibussowitsch       PetscCall(VecViewFromOptions(v, NULL, "-exact_vec_view"));
13049566063dSJacob Faibussowitsch       PetscCall(DMRestoreGlobalVector(dm, &v));
130507eaae0cSMatthew G. Knepley     }
13069566063dSJacob Faibussowitsch     PetscCall(PetscFree2(exactFuncs, ctxs));
130707eaae0cSMatthew G. Knepley   }
1308d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1309d0c080abSJoseph Pusztay }
1310d0c080abSJoseph Pusztay 
1311d0c080abSJoseph Pusztay PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
1312d0c080abSJoseph Pusztay {
1313d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
1314d0c080abSJoseph Pusztay   PetscReal      x   = ptime,y;
1315d0c080abSJoseph Pusztay   PetscInt       its;
1316d0c080abSJoseph Pusztay 
1317d0c080abSJoseph Pusztay   PetscFunctionBegin;
1318d0c080abSJoseph Pusztay   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1319d0c080abSJoseph Pusztay   if (!n) {
1320d0c080abSJoseph Pusztay     PetscDrawAxis axis;
13219566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
13229566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations"));
13239566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1324d0c080abSJoseph Pusztay     ctx->snes_its = 0;
1325d0c080abSJoseph Pusztay   }
13269566063dSJacob Faibussowitsch   PetscCall(TSGetSNESIterations(ts,&its));
1327d0c080abSJoseph Pusztay   y    = its - ctx->snes_its;
13289566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg,&x,&y));
1329d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
13309566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
13319566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1332d0c080abSJoseph Pusztay   }
1333d0c080abSJoseph Pusztay   ctx->snes_its = its;
1334d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1335d0c080abSJoseph Pusztay }
1336d0c080abSJoseph Pusztay 
1337d0c080abSJoseph Pusztay PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
1338d0c080abSJoseph Pusztay {
1339d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
1340d0c080abSJoseph Pusztay   PetscReal      x   = ptime,y;
1341d0c080abSJoseph Pusztay   PetscInt       its;
1342d0c080abSJoseph Pusztay 
1343d0c080abSJoseph Pusztay   PetscFunctionBegin;
1344d0c080abSJoseph Pusztay   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1345d0c080abSJoseph Pusztay   if (!n) {
1346d0c080abSJoseph Pusztay     PetscDrawAxis axis;
13479566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
13489566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations"));
13499566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1350d0c080abSJoseph Pusztay     ctx->ksp_its = 0;
1351d0c080abSJoseph Pusztay   }
13529566063dSJacob Faibussowitsch   PetscCall(TSGetKSPIterations(ts,&its));
1353d0c080abSJoseph Pusztay   y    = its - ctx->ksp_its;
13549566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg,&x,&y));
1355d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
13569566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
13579566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1358d0c080abSJoseph Pusztay   }
1359d0c080abSJoseph Pusztay   ctx->ksp_its = its;
1360d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1361d0c080abSJoseph Pusztay }
1362d0c080abSJoseph Pusztay 
1363d0c080abSJoseph Pusztay /*@C
1364d0c080abSJoseph Pusztay    TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope()
1365d0c080abSJoseph Pusztay 
1366d0c080abSJoseph Pusztay    Collective on TS
1367d0c080abSJoseph Pusztay 
1368d0c080abSJoseph Pusztay    Input Parameters:
1369d0c080abSJoseph Pusztay .  ts  - the ODE solver object
1370d0c080abSJoseph Pusztay 
1371d0c080abSJoseph Pusztay    Output Parameter:
1372d0c080abSJoseph Pusztay .  ctx - the context
1373d0c080abSJoseph Pusztay 
1374d0c080abSJoseph Pusztay    Level: intermediate
1375d0c080abSJoseph Pusztay 
1376db781477SPatrick Sanan .seealso: `TSMonitorLGTimeStep()`, `TSMonitorSet()`, `TSMonitorLGSolution()`, `TSMonitorLGError()`
1377d0c080abSJoseph Pusztay 
1378d0c080abSJoseph Pusztay @*/
1379d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx)
1380d0c080abSJoseph Pusztay {
1381d0c080abSJoseph Pusztay   PetscFunctionBegin;
13829566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
1383d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1384d0c080abSJoseph Pusztay }
1385d0c080abSJoseph Pusztay 
1386d0c080abSJoseph Pusztay /*@C
1387d0c080abSJoseph Pusztay    TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution
1388d0c080abSJoseph Pusztay 
1389d0c080abSJoseph Pusztay    Collective on TS
1390d0c080abSJoseph Pusztay 
1391d0c080abSJoseph Pusztay    Input Parameters:
1392d0c080abSJoseph Pusztay +  ts - the TS context
1393d0c080abSJoseph Pusztay .  step - current time-step
1394d0c080abSJoseph Pusztay .  ptime - current time
1395d0c080abSJoseph Pusztay .  u  - current solution
1396d0c080abSJoseph Pusztay -  dctx - the envelope context
1397d0c080abSJoseph Pusztay 
1398d0c080abSJoseph Pusztay    Options Database:
139967b8a455SSatish Balay .  -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time
1400d0c080abSJoseph Pusztay 
1401d0c080abSJoseph Pusztay    Level: intermediate
1402d0c080abSJoseph Pusztay 
1403d0c080abSJoseph Pusztay    Notes:
14043a61192cSBarry Smith    After a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope
14053a61192cSBarry Smith 
14063a61192cSBarry Smith    This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
14073a61192cSBarry Smith    to be used during the TS integration.
1408d0c080abSJoseph Pusztay 
1409db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxCreate()`
1410d0c080abSJoseph Pusztay @*/
1411d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
1412d0c080abSJoseph Pusztay {
1413d0c080abSJoseph Pusztay   TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx;
1414d0c080abSJoseph Pusztay 
1415d0c080abSJoseph Pusztay   PetscFunctionBegin;
1416d0c080abSJoseph Pusztay   if (!ctx->max) {
14179566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u,&ctx->max));
14189566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u,&ctx->min));
14199566063dSJacob Faibussowitsch     PetscCall(VecCopy(u,ctx->max));
14209566063dSJacob Faibussowitsch     PetscCall(VecCopy(u,ctx->min));
1421d0c080abSJoseph Pusztay   } else {
14229566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMax(ctx->max,u,ctx->max));
14239566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMin(ctx->min,u,ctx->min));
1424d0c080abSJoseph Pusztay   }
1425d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1426d0c080abSJoseph Pusztay }
1427d0c080abSJoseph Pusztay 
1428d0c080abSJoseph Pusztay /*@C
1429d0c080abSJoseph Pusztay    TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution
1430d0c080abSJoseph Pusztay 
1431d0c080abSJoseph Pusztay    Collective on TS
1432d0c080abSJoseph Pusztay 
1433d0c080abSJoseph Pusztay    Input Parameter:
1434d0c080abSJoseph Pusztay .  ts - the TS context
1435d0c080abSJoseph Pusztay 
1436d8d19677SJose E. Roman    Output Parameters:
1437d0c080abSJoseph Pusztay +  max - the maximum values
1438d0c080abSJoseph Pusztay -  min - the minimum values
1439d0c080abSJoseph Pusztay 
1440d0c080abSJoseph Pusztay    Notes:
1441d0c080abSJoseph Pusztay     If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored
1442d0c080abSJoseph Pusztay 
1443d0c080abSJoseph Pusztay    Level: intermediate
1444d0c080abSJoseph Pusztay 
1445db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`
1446d0c080abSJoseph Pusztay @*/
1447d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min)
1448d0c080abSJoseph Pusztay {
1449d0c080abSJoseph Pusztay   PetscInt i;
1450d0c080abSJoseph Pusztay 
1451d0c080abSJoseph Pusztay   PetscFunctionBegin;
1452d0c080abSJoseph Pusztay   if (max) *max = NULL;
1453d0c080abSJoseph Pusztay   if (min) *min = NULL;
1454d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
1455d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorEnvelope) {
1456d0c080abSJoseph Pusztay       TSMonitorEnvelopeCtx  ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i];
1457d0c080abSJoseph Pusztay       if (max) *max = ctx->max;
1458d0c080abSJoseph Pusztay       if (min) *min = ctx->min;
1459d0c080abSJoseph Pusztay       break;
1460d0c080abSJoseph Pusztay     }
1461d0c080abSJoseph Pusztay   }
1462d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1463d0c080abSJoseph Pusztay }
1464d0c080abSJoseph Pusztay 
1465d0c080abSJoseph Pusztay /*@C
1466d0c080abSJoseph Pusztay    TSMonitorEnvelopeCtxDestroy - Destroys a context that was created  with TSMonitorEnvelopeCtxCreate().
1467d0c080abSJoseph Pusztay 
1468d0c080abSJoseph Pusztay    Collective on TSMonitorEnvelopeCtx
1469d0c080abSJoseph Pusztay 
1470d0c080abSJoseph Pusztay    Input Parameter:
1471d0c080abSJoseph Pusztay .  ctx - the monitor context
1472d0c080abSJoseph Pusztay 
1473d0c080abSJoseph Pusztay    Level: intermediate
1474d0c080abSJoseph Pusztay 
1475db781477SPatrick Sanan .seealso: `TSMonitorLGCtxCreate()`, `TSMonitorSet()`, `TSMonitorLGTimeStep()`
1476d0c080abSJoseph Pusztay @*/
1477d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx)
1478d0c080abSJoseph Pusztay {
1479d0c080abSJoseph Pusztay   PetscFunctionBegin;
14809566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ctx)->min));
14819566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ctx)->max));
14829566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
1483d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1484d0c080abSJoseph Pusztay }
1485d0c080abSJoseph Pusztay 
1486d0c080abSJoseph Pusztay /*@C
1487d0c080abSJoseph Pusztay   TSDMSwarmMonitorMoments - Monitors the first three moments of a DMSarm being evolved by the TS
1488d0c080abSJoseph Pusztay 
1489d0c080abSJoseph Pusztay   Not collective
1490d0c080abSJoseph Pusztay 
1491d0c080abSJoseph Pusztay   Input Parameters:
1492d0c080abSJoseph Pusztay + ts   - the TS context
1493d0c080abSJoseph Pusztay . step - current timestep
1494d0c080abSJoseph Pusztay . t    - current time
1495d0c080abSJoseph Pusztay . u    - current solution
1496d0c080abSJoseph Pusztay - ctx  - not used
1497d0c080abSJoseph Pusztay 
1498d0c080abSJoseph Pusztay   Options Database:
149967b8a455SSatish Balay . -ts_dmswarm_monitor_moments - Monitor moments of particle distribution
1500d0c080abSJoseph Pusztay 
1501d0c080abSJoseph Pusztay   Level: intermediate
1502d0c080abSJoseph Pusztay 
1503d0c080abSJoseph Pusztay   Notes:
1504d0c080abSJoseph Pusztay   This requires a DMSwarm be attached to the TS.
1505d0c080abSJoseph Pusztay 
15063a61192cSBarry Smith   This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor
15073a61192cSBarry Smith   to be used during the TS integration.
15083a61192cSBarry Smith 
1509db781477SPatrick Sanan .seealso: `TSMonitorSet()`, `TSMonitorDefault()`, `DMSWARM`
1510d0c080abSJoseph Pusztay @*/
1511d0c080abSJoseph Pusztay PetscErrorCode TSDMSwarmMonitorMoments(TS ts, PetscInt step, PetscReal t, Vec U, PetscViewerAndFormat *vf)
1512d0c080abSJoseph Pusztay {
1513d0c080abSJoseph Pusztay   DM                 sw;
1514d0c080abSJoseph Pusztay   const PetscScalar *u;
1515d0c080abSJoseph Pusztay   PetscReal          m = 1.0, totE = 0., totMom[3] = {0., 0., 0.};
1516d0c080abSJoseph Pusztay   PetscInt           dim, d, Np, p;
1517d0c080abSJoseph Pusztay   MPI_Comm           comm;
1518d0c080abSJoseph Pusztay 
1519d0c080abSJoseph Pusztay   PetscFunctionBeginUser;
15209566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &sw));
1521d0c080abSJoseph Pusztay   if (!sw || step%ts->monitorFrequency != 0) PetscFunctionReturn(0);
15229566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject) ts, &comm));
15239566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(sw, &dim));
15249566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(U, &Np));
1525d0c080abSJoseph Pusztay   Np  /= dim;
15269566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U, &u));
1527d0c080abSJoseph Pusztay   for (p = 0; p < Np; ++p) {
1528d0c080abSJoseph Pusztay     for (d = 0; d < dim; ++d) {
1529d0c080abSJoseph Pusztay       totE      += PetscRealPart(u[p*dim+d]*u[p*dim+d]);
1530d0c080abSJoseph Pusztay       totMom[d] += PetscRealPart(u[p*dim+d]);
1531d0c080abSJoseph Pusztay     }
1532d0c080abSJoseph Pusztay   }
15339566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U, &u));
1534d0c080abSJoseph Pusztay   for (d = 0; d < dim; ++d) totMom[d] *= m;
1535d0c080abSJoseph Pusztay   totE *= 0.5*m;
153663a3b9bcSJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "Step %4" PetscInt_FMT " Total Energy: %10.8lf", step, (double) totE));
153763a3b9bcSJacob Faibussowitsch   for (d = 0; d < dim; ++d) PetscCall(PetscPrintf(comm, "    Total Momentum %c: %10.8lf", (char)('x'+d), (double) totMom[d]));
15389566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "\n"));
1539d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1540d0c080abSJoseph Pusztay }
1541