xref: /petsc/src/ts/interface/tsmon.c (revision f98b2f000af27288b2e6514cfaab9d6a9f06ed3e)
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 
62d0c080abSJoseph Pusztay .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
63d0c080abSJoseph Pusztay           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
64d0c080abSJoseph Pusztay           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
65d0c080abSJoseph Pusztay           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
66d0c080abSJoseph Pusztay           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
67d0c080abSJoseph Pusztay           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
68d0c080abSJoseph Pusztay           PetscOptionsFList(), PetscOptionsEList()
69d0c080abSJoseph Pusztay @*/
70d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorSetFromOptions(TS ts,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(TS,PetscViewerAndFormat*))
71d0c080abSJoseph Pusztay {
72d0c080abSJoseph Pusztay   PetscViewer       viewer;
73d0c080abSJoseph Pusztay   PetscViewerFormat format;
74d0c080abSJoseph Pusztay   PetscBool         flg;
75d0c080abSJoseph Pusztay 
76d0c080abSJoseph Pusztay   PetscFunctionBegin;
779566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts),((PetscObject) ts)->options,((PetscObject)ts)->prefix,name,&viewer,&format,&flg));
78d0c080abSJoseph Pusztay   if (flg) {
79d0c080abSJoseph Pusztay     PetscViewerAndFormat *vf;
809566063dSJacob Faibussowitsch     PetscCall(PetscViewerAndFormatCreate(viewer,format,&vf));
819566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject)viewer));
82d0c080abSJoseph Pusztay     if (monitorsetup) {
839566063dSJacob Faibussowitsch       PetscCall((*monitorsetup)(ts,vf));
84d0c080abSJoseph Pusztay     }
859566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts,(PetscErrorCode (*)(TS,PetscInt,PetscReal,Vec,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy));
86d0c080abSJoseph Pusztay   }
87d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
88d0c080abSJoseph Pusztay }
89d0c080abSJoseph Pusztay 
90d0c080abSJoseph Pusztay /*@C
91d0c080abSJoseph Pusztay    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
92d0c080abSJoseph Pusztay    timestep to display the iteration's  progress.
93d0c080abSJoseph Pusztay 
94d0c080abSJoseph Pusztay    Logically Collective on TS
95d0c080abSJoseph Pusztay 
96d0c080abSJoseph Pusztay    Input Parameters:
97d0c080abSJoseph Pusztay +  ts - the TS context obtained from TSCreate()
98d0c080abSJoseph Pusztay .  monitor - monitoring routine
99d0c080abSJoseph Pusztay .  mctx - [optional] user-defined context for private data for the
100d0c080abSJoseph Pusztay              monitor routine (use NULL if no context is desired)
101d0c080abSJoseph Pusztay -  monitordestroy - [optional] routine that frees monitor context
102d0c080abSJoseph Pusztay           (may be NULL)
103d0c080abSJoseph Pusztay 
104d0c080abSJoseph Pusztay    Calling sequence of monitor:
105d0c080abSJoseph Pusztay $    PetscErrorCode monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
106d0c080abSJoseph Pusztay 
107d0c080abSJoseph Pusztay +    ts - the TS context
108d0c080abSJoseph Pusztay .    steps - iteration number (after the final time step the monitor routine may be called with a step of -1, this indicates the solution has been interpolated to this time)
109d0c080abSJoseph Pusztay .    time - current time
110d0c080abSJoseph Pusztay .    u - current iterate
111d0c080abSJoseph Pusztay -    mctx - [optional] monitoring context
112d0c080abSJoseph Pusztay 
113d0c080abSJoseph Pusztay    Notes:
114d0c080abSJoseph Pusztay    This routine adds an additional monitor to the list of monitors that
115d0c080abSJoseph Pusztay    already has been loaded.
116d0c080abSJoseph Pusztay 
117d0c080abSJoseph Pusztay    Fortran Notes:
118d0c080abSJoseph Pusztay     Only a single monitor function can be set for each TS object
119d0c080abSJoseph Pusztay 
120d0c080abSJoseph Pusztay    Level: intermediate
121d0c080abSJoseph Pusztay 
122d0c080abSJoseph Pusztay .seealso: TSMonitorDefault(), TSMonitorCancel()
123d0c080abSJoseph Pusztay @*/
124d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**))
125d0c080abSJoseph Pusztay {
126d0c080abSJoseph Pusztay   PetscInt       i;
127d0c080abSJoseph Pusztay   PetscBool      identical;
128d0c080abSJoseph Pusztay 
129d0c080abSJoseph Pusztay   PetscFunctionBegin;
130d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
131d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors;i++) {
1329566063dSJacob Faibussowitsch     PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical));
133d0c080abSJoseph Pusztay     if (identical) PetscFunctionReturn(0);
134d0c080abSJoseph Pusztay   }
1353c633725SBarry Smith   PetscCheck(ts->numbermonitors < MAXTSMONITORS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
136d0c080abSJoseph Pusztay   ts->monitor[ts->numbermonitors]          = monitor;
137d0c080abSJoseph Pusztay   ts->monitordestroy[ts->numbermonitors]   = mdestroy;
138d0c080abSJoseph Pusztay   ts->monitorcontext[ts->numbermonitors++] = (void*)mctx;
139d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
140d0c080abSJoseph Pusztay }
141d0c080abSJoseph Pusztay 
142d0c080abSJoseph Pusztay /*@C
143d0c080abSJoseph Pusztay    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
144d0c080abSJoseph Pusztay 
145d0c080abSJoseph Pusztay    Logically Collective on TS
146d0c080abSJoseph Pusztay 
147d0c080abSJoseph Pusztay    Input Parameters:
148d0c080abSJoseph Pusztay .  ts - the TS context obtained from TSCreate()
149d0c080abSJoseph Pusztay 
150d0c080abSJoseph Pusztay    Notes:
151d0c080abSJoseph Pusztay    There is no way to remove a single, specific monitor.
152d0c080abSJoseph Pusztay 
153d0c080abSJoseph Pusztay    Level: intermediate
154d0c080abSJoseph Pusztay 
155d0c080abSJoseph Pusztay .seealso: TSMonitorDefault(), TSMonitorSet()
156d0c080abSJoseph Pusztay @*/
157d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorCancel(TS ts)
158d0c080abSJoseph Pusztay {
159d0c080abSJoseph Pusztay   PetscInt       i;
160d0c080abSJoseph Pusztay 
161d0c080abSJoseph Pusztay   PetscFunctionBegin;
162d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
163d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
164d0c080abSJoseph Pusztay     if (ts->monitordestroy[i]) {
1659566063dSJacob Faibussowitsch       PetscCall((*ts->monitordestroy[i])(&ts->monitorcontext[i]));
166d0c080abSJoseph Pusztay     }
167d0c080abSJoseph Pusztay   }
168d0c080abSJoseph Pusztay   ts->numbermonitors = 0;
169d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
170d0c080abSJoseph Pusztay }
171d0c080abSJoseph Pusztay 
172d0c080abSJoseph Pusztay /*@C
173d0c080abSJoseph Pusztay    TSMonitorDefault - The Default monitor, prints the timestep and time for each step
174d0c080abSJoseph Pusztay 
175d0c080abSJoseph Pusztay    Level: intermediate
176d0c080abSJoseph Pusztay 
177d0c080abSJoseph Pusztay .seealso:  TSMonitorSet()
178d0c080abSJoseph Pusztay @*/
179d0c080abSJoseph Pusztay PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf)
180d0c080abSJoseph Pusztay {
181d0c080abSJoseph Pusztay   PetscViewer    viewer =  vf->viewer;
182d0c080abSJoseph Pusztay   PetscBool      iascii,ibinary;
183d0c080abSJoseph Pusztay 
184d0c080abSJoseph Pusztay   PetscFunctionBegin;
185064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,5);
1869566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
1879566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary));
1889566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,vf->format));
189d0c080abSJoseph Pusztay   if (iascii) {
1909566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel));
191d0c080abSJoseph Pusztay     if (step == -1) { /* this indicates it is an interpolated solution */
1929566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %D and %D\n",(double)ptime,ts->steps-1,ts->steps));
193d0c080abSJoseph Pusztay     } else {
1949566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n"));
195d0c080abSJoseph Pusztay     }
1969566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel));
197d0c080abSJoseph Pusztay   } else if (ibinary) {
198d0c080abSJoseph Pusztay     PetscMPIInt rank;
1999566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank));
200d0c080abSJoseph Pusztay     if (!rank) {
201d0c080abSJoseph Pusztay       PetscBool skipHeader;
202d0c080abSJoseph Pusztay       PetscInt  classid = REAL_FILE_CLASSID;
203d0c080abSJoseph Pusztay 
2049566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryGetSkipHeader(viewer,&skipHeader));
205d0c080abSJoseph Pusztay       if (!skipHeader) {
2069566063dSJacob Faibussowitsch          PetscCall(PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT));
207d0c080abSJoseph Pusztay        }
2089566063dSJacob Faibussowitsch       PetscCall(PetscRealView(1,&ptime,viewer));
209d0c080abSJoseph Pusztay     } else {
2109566063dSJacob Faibussowitsch       PetscCall(PetscRealView(0,&ptime,viewer));
211d0c080abSJoseph Pusztay     }
212d0c080abSJoseph Pusztay   }
2139566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
214d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
215d0c080abSJoseph Pusztay }
216d0c080abSJoseph Pusztay 
217d0c080abSJoseph Pusztay /*@C
218d0c080abSJoseph Pusztay    TSMonitorExtreme - Prints the extreme values of the solution at each timestep
219d0c080abSJoseph Pusztay 
220d0c080abSJoseph Pusztay    Level: intermediate
221d0c080abSJoseph Pusztay 
222d0c080abSJoseph Pusztay .seealso:  TSMonitorSet()
223d0c080abSJoseph Pusztay @*/
224d0c080abSJoseph Pusztay PetscErrorCode TSMonitorExtreme(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf)
225d0c080abSJoseph Pusztay {
226d0c080abSJoseph Pusztay   PetscViewer    viewer =  vf->viewer;
227d0c080abSJoseph Pusztay   PetscBool      iascii;
228d0c080abSJoseph Pusztay   PetscReal      max,min;
229d0c080abSJoseph Pusztay 
230d0c080abSJoseph Pusztay   PetscFunctionBegin;
231064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,5);
2329566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
2339566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,vf->format));
234d0c080abSJoseph Pusztay   if (iascii) {
2359566063dSJacob Faibussowitsch     PetscCall(VecMax(v,NULL,&max));
2369566063dSJacob Faibussowitsch     PetscCall(VecMin(v,NULL,&min));
2379566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel));
2389566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s max %g min %g\n",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)" : "",(double)max,(double)min));
2399566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel));
240d0c080abSJoseph Pusztay   }
2419566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
242d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
243d0c080abSJoseph Pusztay }
244d0c080abSJoseph Pusztay 
245d0c080abSJoseph Pusztay /*@C
246d0c080abSJoseph Pusztay    TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with
247d0c080abSJoseph Pusztay    TS to monitor the solution process graphically in various ways
248d0c080abSJoseph Pusztay 
249d0c080abSJoseph Pusztay    Collective on TS
250d0c080abSJoseph Pusztay 
251d0c080abSJoseph Pusztay    Input Parameters:
252d0c080abSJoseph Pusztay +  host - the X display to open, or null for the local machine
253d0c080abSJoseph Pusztay .  label - the title to put in the title bar
254d0c080abSJoseph Pusztay .  x, y - the screen coordinates of the upper left coordinate of the window
255d0c080abSJoseph Pusztay .  m, n - the screen width and height in pixels
256d0c080abSJoseph Pusztay -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
257d0c080abSJoseph Pusztay 
258d0c080abSJoseph Pusztay    Output Parameter:
259d0c080abSJoseph Pusztay .  ctx - the context
260d0c080abSJoseph Pusztay 
261d0c080abSJoseph Pusztay    Options Database Key:
262d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep - automatically sets line graph monitor
263d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep_log - automatically sets line graph monitor
264d0c080abSJoseph Pusztay .  -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables())
265d0c080abSJoseph Pusztay .  -ts_monitor_lg_error -  monitor the error
266d0c080abSJoseph Pusztay .  -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep
267d0c080abSJoseph Pusztay .  -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep
268d0c080abSJoseph Pusztay -  -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true
269d0c080abSJoseph Pusztay 
270d0c080abSJoseph Pusztay    Notes:
271d0c080abSJoseph Pusztay    Use TSMonitorLGCtxDestroy() to destroy.
272d0c080abSJoseph Pusztay 
273d0c080abSJoseph Pusztay    One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform()
274d0c080abSJoseph Pusztay 
275d0c080abSJoseph Pusztay    Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the
276d0c080abSJoseph Pusztay    first argument (if that TS object does not have a TSMonitorLGCtx associated with it the function call is ignored) and the second takes a TSMonitorLGCtx object
277d0c080abSJoseph Pusztay    as the first argument.
278d0c080abSJoseph Pusztay 
279d0c080abSJoseph Pusztay    One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames()
280d0c080abSJoseph Pusztay 
281d0c080abSJoseph Pusztay    Level: intermediate
282d0c080abSJoseph Pusztay 
283d0c080abSJoseph Pusztay .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(),
284d0c080abSJoseph Pusztay            TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
285d0c080abSJoseph Pusztay            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
286d0c080abSJoseph Pusztay            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
287d0c080abSJoseph Pusztay            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()
288d0c080abSJoseph Pusztay 
289d0c080abSJoseph Pusztay @*/
290d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
291d0c080abSJoseph Pusztay {
292d0c080abSJoseph Pusztay   PetscDraw      draw;
293d0c080abSJoseph Pusztay 
294d0c080abSJoseph Pusztay   PetscFunctionBegin;
2959566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
2969566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm,host,label,x,y,m,n,&draw));
2979566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetFromOptions(draw));
2989566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGCreate(draw,1,&(*ctx)->lg));
2999566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGSetFromOptions((*ctx)->lg));
3009566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw));
301d0c080abSJoseph Pusztay   (*ctx)->howoften = howoften;
302d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
303d0c080abSJoseph Pusztay }
304d0c080abSJoseph Pusztay 
305d0c080abSJoseph Pusztay PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx)
306d0c080abSJoseph Pusztay {
307d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
308d0c080abSJoseph Pusztay   PetscReal      x   = ptime,y;
309d0c080abSJoseph Pusztay 
310d0c080abSJoseph Pusztay   PetscFunctionBegin;
311d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */
312d0c080abSJoseph Pusztay   if (!step) {
313d0c080abSJoseph Pusztay     PetscDrawAxis axis;
314d0c080abSJoseph Pusztay     const char *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step";
3159566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
3169566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time",ylabel));
3179566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
318d0c080abSJoseph Pusztay   }
3199566063dSJacob Faibussowitsch   PetscCall(TSGetTimeStep(ts,&y));
320d0c080abSJoseph Pusztay   if (ctx->semilogy) y = PetscLog10Real(y);
3219566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg,&x,&y));
322d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
3239566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
3249566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
325d0c080abSJoseph Pusztay   }
326d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
327d0c080abSJoseph Pusztay }
328d0c080abSJoseph Pusztay 
329d0c080abSJoseph Pusztay /*@C
330d0c080abSJoseph Pusztay    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
331d0c080abSJoseph Pusztay    with TSMonitorLGCtxCreate().
332d0c080abSJoseph Pusztay 
333d0c080abSJoseph Pusztay    Collective on TSMonitorLGCtx
334d0c080abSJoseph Pusztay 
335d0c080abSJoseph Pusztay    Input Parameter:
336d0c080abSJoseph Pusztay .  ctx - the monitor context
337d0c080abSJoseph Pusztay 
338d0c080abSJoseph Pusztay    Level: intermediate
339d0c080abSJoseph Pusztay 
340d0c080abSJoseph Pusztay .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep();
341d0c080abSJoseph Pusztay @*/
342d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
343d0c080abSJoseph Pusztay {
344d0c080abSJoseph Pusztay   PetscFunctionBegin;
345d0c080abSJoseph Pusztay   if ((*ctx)->transformdestroy) {
3469566063dSJacob Faibussowitsch     PetscCall(((*ctx)->transformdestroy)((*ctx)->transformctx));
347d0c080abSJoseph Pusztay   }
3489566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGDestroy(&(*ctx)->lg));
3499566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&(*ctx)->names));
3509566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&(*ctx)->displaynames));
3519566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ctx)->displayvariables));
3529566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ctx)->displayvalues));
3539566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
354d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
355d0c080abSJoseph Pusztay }
356d0c080abSJoseph Pusztay 
357d7462660SMatthew Knepley /* Creates a TS Monitor SPCtx for use with DMSwarm particle visualizations */
358d7462660SMatthew Knepley PetscErrorCode TSMonitorSPCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,PetscInt retain,PetscBool phase,TSMonitorSPCtx *ctx)
359d0c080abSJoseph Pusztay {
360d0c080abSJoseph Pusztay   PetscDraw      draw;
361d0c080abSJoseph Pusztay 
362d0c080abSJoseph Pusztay   PetscFunctionBegin;
3639566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
3649566063dSJacob Faibussowitsch   PetscCall(PetscDrawCreate(comm,host,label,x,y,m,n,&draw));
3659566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetFromOptions(draw));
3669566063dSJacob Faibussowitsch   PetscCall(PetscDrawSPCreate(draw,1,&(*ctx)->sp));
3679566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&draw));
368d0c080abSJoseph Pusztay   (*ctx)->howoften = howoften;
369d7462660SMatthew Knepley   (*ctx)->retain   = retain;
370d7462660SMatthew Knepley   (*ctx)->phase    = phase;
371d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
372d0c080abSJoseph Pusztay }
373d0c080abSJoseph Pusztay 
374d0c080abSJoseph Pusztay /*
375d0c080abSJoseph Pusztay   Destroys a TSMonitorSPCtx that was created with TSMonitorSPCtxCreate
376d0c080abSJoseph Pusztay */
377d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSPCtxDestroy(TSMonitorSPCtx *ctx)
378d0c080abSJoseph Pusztay {
379d0c080abSJoseph Pusztay   PetscFunctionBegin;
380d0c080abSJoseph Pusztay 
3819566063dSJacob Faibussowitsch   PetscCall(PetscDrawSPDestroy(&(*ctx)->sp));
3829566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
383d0c080abSJoseph Pusztay 
384d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
385d0c080abSJoseph Pusztay 
386d0c080abSJoseph Pusztay }
387d0c080abSJoseph Pusztay 
388d0c080abSJoseph Pusztay /*@C
389d0c080abSJoseph Pusztay    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
390d0c080abSJoseph Pusztay    VecView() for the solution at each timestep
391d0c080abSJoseph Pusztay 
392d0c080abSJoseph Pusztay    Collective on TS
393d0c080abSJoseph Pusztay 
394d0c080abSJoseph Pusztay    Input Parameters:
395d0c080abSJoseph Pusztay +  ts - the TS context
396d0c080abSJoseph Pusztay .  step - current time-step
397d0c080abSJoseph Pusztay .  ptime - current time
398d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
399d0c080abSJoseph Pusztay 
400d0c080abSJoseph Pusztay    Options Database:
401d0c080abSJoseph Pusztay .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
402d0c080abSJoseph Pusztay 
403d0c080abSJoseph Pusztay    Notes:
404d0c080abSJoseph Pusztay     the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
405d0c080abSJoseph Pusztay        will look bad
406d0c080abSJoseph Pusztay 
407d0c080abSJoseph Pusztay    Level: intermediate
408d0c080abSJoseph Pusztay 
409d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
410d0c080abSJoseph Pusztay @*/
411d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
412d0c080abSJoseph Pusztay {
413d0c080abSJoseph Pusztay   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
414d0c080abSJoseph Pusztay   PetscDraw        draw;
415d0c080abSJoseph Pusztay 
416d0c080abSJoseph Pusztay   PetscFunctionBegin;
417d0c080abSJoseph Pusztay   if (!step && ictx->showinitial) {
418d0c080abSJoseph Pusztay     if (!ictx->initialsolution) {
4199566063dSJacob Faibussowitsch       PetscCall(VecDuplicate(u,&ictx->initialsolution));
420d0c080abSJoseph Pusztay     }
4219566063dSJacob Faibussowitsch     PetscCall(VecCopy(u,ictx->initialsolution));
422d0c080abSJoseph Pusztay   }
423d0c080abSJoseph Pusztay   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
424d0c080abSJoseph Pusztay 
425d0c080abSJoseph Pusztay   if (ictx->showinitial) {
426d0c080abSJoseph Pusztay     PetscReal pause;
4279566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetPause(ictx->viewer,&pause));
4289566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetPause(ictx->viewer,0.0));
4299566063dSJacob Faibussowitsch     PetscCall(VecView(ictx->initialsolution,ictx->viewer));
4309566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetPause(ictx->viewer,pause));
4319566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE));
432d0c080abSJoseph Pusztay   }
4339566063dSJacob Faibussowitsch   PetscCall(VecView(u,ictx->viewer));
434d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
435d0c080abSJoseph Pusztay     PetscReal xl,yl,xr,yr,h;
436d0c080abSJoseph Pusztay     char      time[32];
437d0c080abSJoseph Pusztay 
4389566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(ictx->viewer,0,&draw));
4399566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime));
4409566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr));
441d0c080abSJoseph Pusztay     h    = yl + .95*(yr - yl);
4429566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time));
4439566063dSJacob Faibussowitsch     PetscCall(PetscDrawFlush(draw));
444d0c080abSJoseph Pusztay   }
445d0c080abSJoseph Pusztay 
446d0c080abSJoseph Pusztay   if (ictx->showinitial) {
4479566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE));
448d0c080abSJoseph Pusztay   }
449d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
450d0c080abSJoseph Pusztay }
451d0c080abSJoseph Pusztay 
452d0c080abSJoseph Pusztay /*@C
453d0c080abSJoseph Pusztay    TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram
454d0c080abSJoseph Pusztay 
455d0c080abSJoseph Pusztay    Collective on TS
456d0c080abSJoseph Pusztay 
457d0c080abSJoseph Pusztay    Input Parameters:
458d0c080abSJoseph Pusztay +  ts - the TS context
459d0c080abSJoseph Pusztay .  step - current time-step
460d0c080abSJoseph Pusztay .  ptime - current time
461d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
462d0c080abSJoseph Pusztay 
463d0c080abSJoseph Pusztay    Level: intermediate
464d0c080abSJoseph Pusztay 
465d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
466d0c080abSJoseph Pusztay @*/
467d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
468d0c080abSJoseph Pusztay {
469d0c080abSJoseph Pusztay   TSMonitorDrawCtx  ictx = (TSMonitorDrawCtx)dummy;
470d0c080abSJoseph Pusztay   PetscDraw         draw;
471d0c080abSJoseph Pusztay   PetscDrawAxis     axis;
472d0c080abSJoseph Pusztay   PetscInt          n;
473d0c080abSJoseph Pusztay   PetscMPIInt       size;
474d0c080abSJoseph Pusztay   PetscReal         U0,U1,xl,yl,xr,yr,h;
475d0c080abSJoseph Pusztay   char              time[32];
476d0c080abSJoseph Pusztay   const PetscScalar *U;
4775f80ce2aSJacob Faibussowitsch   PetscErrorCode    ierr;
478d0c080abSJoseph Pusztay 
479d0c080abSJoseph Pusztay   PetscFunctionBegin;
4809566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size));
4813c633725SBarry Smith   PetscCheck(size == 1,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs");
4829566063dSJacob Faibussowitsch   PetscCall(VecGetSize(u,&n));
4833c633725SBarry Smith   PetscCheck(n == 2,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns");
484d0c080abSJoseph Pusztay 
4859566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(ictx->viewer,0,&draw));
4869566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis));
4879566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr));
488d0c080abSJoseph Pusztay   if (!step) {
4899566063dSJacob Faibussowitsch     PetscCall(PetscDrawClear(draw));
4909566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisDraw(axis));
491d0c080abSJoseph Pusztay   }
492d0c080abSJoseph Pusztay 
4939566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(u,&U));
494d0c080abSJoseph Pusztay   U0 = PetscRealPart(U[0]);
495d0c080abSJoseph Pusztay   U1 = PetscRealPart(U[1]);
4969566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(u,&U));
497d0c080abSJoseph Pusztay   if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0);
498d0c080abSJoseph Pusztay 
4999566063dSJacob Faibussowitsch   ierr = PetscDrawCollectiveBegin(draw);PetscCall(ierr);
5009566063dSJacob Faibussowitsch   PetscCall(PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK));
501d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
5029566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr));
5039566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime));
504d0c080abSJoseph Pusztay     h    = yl + .95*(yr - yl);
5059566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time));
506d0c080abSJoseph Pusztay   }
5079566063dSJacob Faibussowitsch   ierr = PetscDrawCollectiveEnd(draw);PetscCall(ierr);
5089566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
5099566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
5109566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
511d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
512d0c080abSJoseph Pusztay }
513d0c080abSJoseph Pusztay 
514d0c080abSJoseph Pusztay /*@C
515d0c080abSJoseph Pusztay    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
516d0c080abSJoseph Pusztay 
517d0c080abSJoseph Pusztay    Collective on TS
518d0c080abSJoseph Pusztay 
519d0c080abSJoseph Pusztay    Input Parameters:
520d0c080abSJoseph Pusztay .    ctx - the monitor context
521d0c080abSJoseph Pusztay 
522d0c080abSJoseph Pusztay    Level: intermediate
523d0c080abSJoseph Pusztay 
524d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError()
525d0c080abSJoseph Pusztay @*/
526d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
527d0c080abSJoseph Pusztay {
528d0c080abSJoseph Pusztay   PetscFunctionBegin;
5299566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&(*ictx)->viewer));
5309566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ictx)->initialsolution));
5319566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ictx));
532d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
533d0c080abSJoseph Pusztay }
534d0c080abSJoseph Pusztay 
535d0c080abSJoseph Pusztay /*@C
536d0c080abSJoseph Pusztay    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
537d0c080abSJoseph Pusztay 
538d0c080abSJoseph Pusztay    Collective on TS
539d0c080abSJoseph Pusztay 
540d0c080abSJoseph Pusztay    Input Parameter:
541d0c080abSJoseph Pusztay .    ts - time-step context
542d0c080abSJoseph Pusztay 
543d0c080abSJoseph Pusztay    Output Patameter:
544d0c080abSJoseph Pusztay .    ctx - the monitor context
545d0c080abSJoseph Pusztay 
546d0c080abSJoseph Pusztay    Options Database:
547d0c080abSJoseph Pusztay .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
548d0c080abSJoseph Pusztay 
549d0c080abSJoseph Pusztay    Level: intermediate
550d0c080abSJoseph Pusztay 
551d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx()
552d0c080abSJoseph Pusztay @*/
553d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
554d0c080abSJoseph Pusztay {
555d0c080abSJoseph Pusztay   PetscFunctionBegin;
5569566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
5579566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer));
5589566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetFromOptions((*ctx)->viewer));
559d0c080abSJoseph Pusztay 
560d0c080abSJoseph Pusztay   (*ctx)->howoften    = howoften;
561d0c080abSJoseph Pusztay   (*ctx)->showinitial = PETSC_FALSE;
5629566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL));
563d0c080abSJoseph Pusztay 
564d0c080abSJoseph Pusztay   (*ctx)->showtimestepandtime = PETSC_FALSE;
5659566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL));
566d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
567d0c080abSJoseph Pusztay }
568d0c080abSJoseph Pusztay 
569d0c080abSJoseph Pusztay /*@C
570d0c080abSJoseph Pusztay    TSMonitorDrawSolutionFunction - Monitors progress of the TS solvers by calling
571d0c080abSJoseph Pusztay    VecView() for the solution provided by TSSetSolutionFunction() at each timestep
572d0c080abSJoseph Pusztay 
573d0c080abSJoseph Pusztay    Collective on TS
574d0c080abSJoseph Pusztay 
575d0c080abSJoseph Pusztay    Input Parameters:
576d0c080abSJoseph Pusztay +  ts - the TS context
577d0c080abSJoseph Pusztay .  step - current time-step
578d0c080abSJoseph Pusztay .  ptime - current time
579d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
580d0c080abSJoseph Pusztay 
581d0c080abSJoseph Pusztay    Options Database:
582d0c080abSJoseph Pusztay .  -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
583d0c080abSJoseph Pusztay 
584d0c080abSJoseph Pusztay    Level: intermediate
585d0c080abSJoseph Pusztay 
586d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
587d0c080abSJoseph Pusztay @*/
588d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawSolutionFunction(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
589d0c080abSJoseph Pusztay {
590d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
591d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
592d0c080abSJoseph Pusztay   Vec              work;
593d0c080abSJoseph Pusztay 
594d0c080abSJoseph Pusztay   PetscFunctionBegin;
595d0c080abSJoseph Pusztay   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
5969566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u,&work));
5979566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts,ptime,work));
5989566063dSJacob Faibussowitsch   PetscCall(VecView(work,viewer));
5999566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work));
600d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
601d0c080abSJoseph Pusztay }
602d0c080abSJoseph Pusztay 
603d0c080abSJoseph Pusztay /*@C
604d0c080abSJoseph Pusztay    TSMonitorDrawError - Monitors progress of the TS solvers by calling
605d0c080abSJoseph Pusztay    VecView() for the error at each timestep
606d0c080abSJoseph Pusztay 
607d0c080abSJoseph Pusztay    Collective on TS
608d0c080abSJoseph Pusztay 
609d0c080abSJoseph Pusztay    Input Parameters:
610d0c080abSJoseph Pusztay +  ts - the TS context
611d0c080abSJoseph Pusztay .  step - current time-step
612d0c080abSJoseph Pusztay .  ptime - current time
613d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
614d0c080abSJoseph Pusztay 
615d0c080abSJoseph Pusztay    Options Database:
616d0c080abSJoseph Pusztay .  -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
617d0c080abSJoseph Pusztay 
618d0c080abSJoseph Pusztay    Level: intermediate
619d0c080abSJoseph Pusztay 
620d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
621d0c080abSJoseph Pusztay @*/
622d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
623d0c080abSJoseph Pusztay {
624d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
625d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
626d0c080abSJoseph Pusztay   Vec              work;
627d0c080abSJoseph Pusztay 
628d0c080abSJoseph Pusztay   PetscFunctionBegin;
629d0c080abSJoseph Pusztay   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
6309566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u,&work));
6319566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts,ptime,work));
6329566063dSJacob Faibussowitsch   PetscCall(VecAXPY(work,-1.0,u));
6339566063dSJacob Faibussowitsch   PetscCall(VecView(work,viewer));
6349566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work));
635d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
636d0c080abSJoseph Pusztay }
637d0c080abSJoseph Pusztay 
638d0c080abSJoseph Pusztay /*@C
639d0c080abSJoseph 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
640d0c080abSJoseph Pusztay 
641d0c080abSJoseph Pusztay    Collective on TS
642d0c080abSJoseph Pusztay 
643d0c080abSJoseph Pusztay    Input Parameters:
644d0c080abSJoseph Pusztay +  ts - the TS context
645d0c080abSJoseph Pusztay .  step - current time-step
646d0c080abSJoseph Pusztay .  ptime - current time
647d0c080abSJoseph Pusztay .  u - current state
648d0c080abSJoseph Pusztay -  vf - viewer and its format
649d0c080abSJoseph Pusztay 
650d0c080abSJoseph Pusztay    Level: intermediate
651d0c080abSJoseph Pusztay 
652d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
653d0c080abSJoseph Pusztay @*/
654d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
655d0c080abSJoseph Pusztay {
656d0c080abSJoseph Pusztay   PetscFunctionBegin;
6579566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(vf->viewer,vf->format));
6589566063dSJacob Faibussowitsch   PetscCall(VecView(u,vf->viewer));
6599566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(vf->viewer));
660d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
661d0c080abSJoseph Pusztay }
662d0c080abSJoseph Pusztay 
663d0c080abSJoseph Pusztay /*@C
664d0c080abSJoseph Pusztay    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
665d0c080abSJoseph Pusztay 
666d0c080abSJoseph Pusztay    Collective on TS
667d0c080abSJoseph Pusztay 
668d0c080abSJoseph Pusztay    Input Parameters:
669d0c080abSJoseph Pusztay +  ts - the TS context
670d0c080abSJoseph Pusztay .  step - current time-step
671d0c080abSJoseph Pusztay .  ptime - current time
672d0c080abSJoseph Pusztay .  u - current state
673d0c080abSJoseph Pusztay -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
674d0c080abSJoseph Pusztay 
675d0c080abSJoseph Pusztay    Level: intermediate
676d0c080abSJoseph Pusztay 
677d0c080abSJoseph Pusztay    Notes:
678d0c080abSJoseph 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.
679d0c080abSJoseph Pusztay    These are named according to the file name template.
680d0c080abSJoseph Pusztay 
681d0c080abSJoseph Pusztay    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().
682d0c080abSJoseph Pusztay 
683d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
684d0c080abSJoseph Pusztay @*/
685d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
686d0c080abSJoseph Pusztay {
687d0c080abSJoseph Pusztay   char           filename[PETSC_MAX_PATH_LEN];
688d0c080abSJoseph Pusztay   PetscViewer    viewer;
689d0c080abSJoseph Pusztay 
690d0c080abSJoseph Pusztay   PetscFunctionBegin;
691d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
6929566063dSJacob Faibussowitsch   PetscCall(PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step));
6939566063dSJacob Faibussowitsch   PetscCall(PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer));
6949566063dSJacob Faibussowitsch   PetscCall(VecView(u,viewer));
6959566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&viewer));
696d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
697d0c080abSJoseph Pusztay }
698d0c080abSJoseph Pusztay 
699d0c080abSJoseph Pusztay /*@C
700d0c080abSJoseph Pusztay    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
701d0c080abSJoseph Pusztay 
702d0c080abSJoseph Pusztay    Collective on TS
703d0c080abSJoseph Pusztay 
704d0c080abSJoseph Pusztay    Input Parameters:
705d0c080abSJoseph Pusztay .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
706d0c080abSJoseph Pusztay 
707d0c080abSJoseph Pusztay    Level: intermediate
708d0c080abSJoseph Pusztay 
709d0c080abSJoseph Pusztay    Note:
710d0c080abSJoseph Pusztay    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
711d0c080abSJoseph Pusztay 
712d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorSolutionVTK()
713d0c080abSJoseph Pusztay @*/
714d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
715d0c080abSJoseph Pusztay {
716d0c080abSJoseph Pusztay   PetscFunctionBegin;
7179566063dSJacob Faibussowitsch   PetscCall(PetscFree(*(char**)filenametemplate));
718d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
719d0c080abSJoseph Pusztay }
720d0c080abSJoseph Pusztay 
721d0c080abSJoseph Pusztay /*@C
722d0c080abSJoseph Pusztay    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
723d0c080abSJoseph Pusztay        in a time based line graph
724d0c080abSJoseph Pusztay 
725d0c080abSJoseph Pusztay    Collective on TS
726d0c080abSJoseph Pusztay 
727d0c080abSJoseph Pusztay    Input Parameters:
728d0c080abSJoseph Pusztay +  ts - the TS context
729d0c080abSJoseph Pusztay .  step - current time-step
730d0c080abSJoseph Pusztay .  ptime - current time
731d0c080abSJoseph Pusztay .  u - current solution
732d0c080abSJoseph Pusztay -  dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate()
733d0c080abSJoseph Pusztay 
734d0c080abSJoseph Pusztay    Options Database:
73567b8a455SSatish Balay .   -ts_monitor_lg_solution_variables - enable monitor of lg solution variables
736d0c080abSJoseph Pusztay 
737d0c080abSJoseph Pusztay    Level: intermediate
738d0c080abSJoseph Pusztay 
739d0c080abSJoseph Pusztay    Notes:
740d0c080abSJoseph Pusztay     Each process in a parallel run displays its component solutions in a separate window
741d0c080abSJoseph Pusztay 
742d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
743d0c080abSJoseph Pusztay            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
744d0c080abSJoseph Pusztay            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
745d0c080abSJoseph Pusztay            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()
746d0c080abSJoseph Pusztay @*/
747d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
748d0c080abSJoseph Pusztay {
749d0c080abSJoseph Pusztay   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dctx;
750d0c080abSJoseph Pusztay   const PetscScalar *yy;
751d0c080abSJoseph Pusztay   Vec               v;
752d0c080abSJoseph Pusztay 
753d0c080abSJoseph Pusztay   PetscFunctionBegin;
754d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
755d0c080abSJoseph Pusztay   if (!step) {
756d0c080abSJoseph Pusztay     PetscDrawAxis axis;
757d0c080abSJoseph Pusztay     PetscInt      dim;
7589566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
7599566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution"));
760d0c080abSJoseph Pusztay     if (!ctx->names) {
761d0c080abSJoseph Pusztay       PetscBool flg;
762d0c080abSJoseph Pusztay       /* user provides names of variables to plot but no names has been set so assume names are integer values */
7639566063dSJacob Faibussowitsch       PetscCall(PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg));
764d0c080abSJoseph Pusztay       if (flg) {
765d0c080abSJoseph Pusztay         PetscInt i,n;
766d0c080abSJoseph Pusztay         char     **names;
7679566063dSJacob Faibussowitsch         PetscCall(VecGetSize(u,&n));
7689566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(n+1,&names));
769d0c080abSJoseph Pusztay         for (i=0; i<n; i++) {
7709566063dSJacob Faibussowitsch           PetscCall(PetscMalloc1(5,&names[i]));
7719566063dSJacob Faibussowitsch           PetscCall(PetscSNPrintf(names[i],5,"%D",i));
772d0c080abSJoseph Pusztay         }
773d0c080abSJoseph Pusztay         names[n] = NULL;
774d0c080abSJoseph Pusztay         ctx->names = names;
775d0c080abSJoseph Pusztay       }
776d0c080abSJoseph Pusztay     }
777d0c080abSJoseph Pusztay     if (ctx->names && !ctx->displaynames) {
778d0c080abSJoseph Pusztay       char      **displaynames;
779d0c080abSJoseph Pusztay       PetscBool flg;
7809566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u,&dim));
7819566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(dim+1,&displaynames));
7829566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg));
783d0c080abSJoseph Pusztay       if (flg) {
7849566063dSJacob Faibussowitsch         PetscCall(TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames));
785d0c080abSJoseph Pusztay       }
7869566063dSJacob Faibussowitsch       PetscCall(PetscStrArrayDestroy(&displaynames));
787d0c080abSJoseph Pusztay     }
788d0c080abSJoseph Pusztay     if (ctx->displaynames) {
7899566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables));
7909566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames));
791d0c080abSJoseph Pusztay     } else if (ctx->names) {
7929566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u,&dim));
7939566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg,dim));
7949566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names));
795d0c080abSJoseph Pusztay     } else {
7969566063dSJacob Faibussowitsch       PetscCall(VecGetLocalSize(u,&dim));
7979566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGSetDimension(ctx->lg,dim));
798d0c080abSJoseph Pusztay     }
7999566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
800d0c080abSJoseph Pusztay   }
801d0c080abSJoseph Pusztay 
802d0c080abSJoseph Pusztay   if (!ctx->transform) v = u;
8039566063dSJacob Faibussowitsch   else PetscCall((*ctx->transform)(ctx->transformctx,u,&v));
8049566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(v,&yy));
805d0c080abSJoseph Pusztay   if (ctx->displaynames) {
806d0c080abSJoseph Pusztay     PetscInt i;
807d0c080abSJoseph Pusztay     for (i=0; i<ctx->ndisplayvariables; i++)
808d0c080abSJoseph Pusztay       ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]);
8099566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues));
810d0c080abSJoseph Pusztay   } else {
811d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
812d0c080abSJoseph Pusztay     PetscInt  i,n;
813d0c080abSJoseph Pusztay     PetscReal *yreal;
8149566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(v,&n));
8159566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&yreal));
816d0c080abSJoseph Pusztay     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
8179566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal));
8189566063dSJacob Faibussowitsch     PetscCall(PetscFree(yreal));
819d0c080abSJoseph Pusztay #else
8209566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy));
821d0c080abSJoseph Pusztay #endif
822d0c080abSJoseph Pusztay   }
8239566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(v,&yy));
8249566063dSJacob Faibussowitsch   if (ctx->transform) PetscCall(VecDestroy(&v));
825d0c080abSJoseph Pusztay 
826d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
8279566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
8289566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
829d0c080abSJoseph Pusztay   }
830d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
831d0c080abSJoseph Pusztay }
832d0c080abSJoseph Pusztay 
833d0c080abSJoseph Pusztay /*@C
834d0c080abSJoseph Pusztay    TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
835d0c080abSJoseph Pusztay 
836d0c080abSJoseph Pusztay    Collective on TS
837d0c080abSJoseph Pusztay 
838d0c080abSJoseph Pusztay    Input Parameters:
839d0c080abSJoseph Pusztay +  ts - the TS context
840d0c080abSJoseph Pusztay -  names - the names of the components, final string must be NULL
841d0c080abSJoseph Pusztay 
842d0c080abSJoseph Pusztay    Level: intermediate
843d0c080abSJoseph Pusztay 
844d0c080abSJoseph Pusztay    Notes:
845d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
846d0c080abSJoseph Pusztay 
847d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames()
848d0c080abSJoseph Pusztay @*/
849d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSetVariableNames(TS ts,const char * const *names)
850d0c080abSJoseph Pusztay {
851d0c080abSJoseph Pusztay   PetscInt          i;
852d0c080abSJoseph Pusztay 
853d0c080abSJoseph Pusztay   PetscFunctionBegin;
854d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
855d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
8569566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names));
857d0c080abSJoseph Pusztay       break;
858d0c080abSJoseph Pusztay     }
859d0c080abSJoseph Pusztay   }
860d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
861d0c080abSJoseph Pusztay }
862d0c080abSJoseph Pusztay 
863d0c080abSJoseph Pusztay /*@C
864d0c080abSJoseph Pusztay    TSMonitorLGCtxSetVariableNames - 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 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames()
875d0c080abSJoseph Pusztay @*/
876d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names)
877d0c080abSJoseph Pusztay {
878d0c080abSJoseph Pusztay   PetscFunctionBegin;
8799566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&ctx->names));
8809566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(names,&ctx->names));
881d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
882d0c080abSJoseph Pusztay }
883d0c080abSJoseph Pusztay 
884d0c080abSJoseph Pusztay /*@C
885d0c080abSJoseph Pusztay    TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot
886d0c080abSJoseph Pusztay 
887d0c080abSJoseph Pusztay    Collective on TS
888d0c080abSJoseph Pusztay 
889d0c080abSJoseph Pusztay    Input Parameter:
890d0c080abSJoseph Pusztay .  ts - the TS context
891d0c080abSJoseph Pusztay 
892d0c080abSJoseph Pusztay    Output Parameter:
893d0c080abSJoseph Pusztay .  names - the names of the components, final string must be NULL
894d0c080abSJoseph Pusztay 
895d0c080abSJoseph Pusztay    Level: intermediate
896d0c080abSJoseph Pusztay 
897d0c080abSJoseph Pusztay    Notes:
898d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
899d0c080abSJoseph Pusztay 
900d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
901d0c080abSJoseph Pusztay @*/
902d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGGetVariableNames(TS ts,const char *const **names)
903d0c080abSJoseph Pusztay {
904d0c080abSJoseph Pusztay   PetscInt       i;
905d0c080abSJoseph Pusztay 
906d0c080abSJoseph Pusztay   PetscFunctionBegin;
907d0c080abSJoseph Pusztay   *names = NULL;
908d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
909d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
910d0c080abSJoseph Pusztay       TSMonitorLGCtx  ctx = (TSMonitorLGCtx) ts->monitorcontext[i];
911d0c080abSJoseph Pusztay       *names = (const char *const *)ctx->names;
912d0c080abSJoseph Pusztay       break;
913d0c080abSJoseph Pusztay     }
914d0c080abSJoseph Pusztay   }
915d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
916d0c080abSJoseph Pusztay }
917d0c080abSJoseph Pusztay 
918d0c080abSJoseph Pusztay /*@C
919d0c080abSJoseph Pusztay    TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor
920d0c080abSJoseph Pusztay 
921d0c080abSJoseph Pusztay    Collective on TS
922d0c080abSJoseph Pusztay 
923d0c080abSJoseph Pusztay    Input Parameters:
924d0c080abSJoseph Pusztay +  ctx - the TSMonitorLG context
925d0c080abSJoseph Pusztay -  displaynames - the names of the components, final string must be NULL
926d0c080abSJoseph Pusztay 
927d0c080abSJoseph Pusztay    Level: intermediate
928d0c080abSJoseph Pusztay 
929d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
930d0c080abSJoseph Pusztay @*/
931d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames)
932d0c080abSJoseph Pusztay {
933d0c080abSJoseph Pusztay   PetscInt          j = 0,k;
934d0c080abSJoseph Pusztay 
935d0c080abSJoseph Pusztay   PetscFunctionBegin;
936d0c080abSJoseph Pusztay   if (!ctx->names) PetscFunctionReturn(0);
9379566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&ctx->displaynames));
9389566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(displaynames,&ctx->displaynames));
939d0c080abSJoseph Pusztay   while (displaynames[j]) j++;
940d0c080abSJoseph Pusztay   ctx->ndisplayvariables = j;
9419566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables));
9429566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues));
943d0c080abSJoseph Pusztay   j = 0;
944d0c080abSJoseph Pusztay   while (displaynames[j]) {
945d0c080abSJoseph Pusztay     k = 0;
946d0c080abSJoseph Pusztay     while (ctx->names[k]) {
947d0c080abSJoseph Pusztay       PetscBool flg;
9489566063dSJacob Faibussowitsch       PetscCall(PetscStrcmp(displaynames[j],ctx->names[k],&flg));
949d0c080abSJoseph Pusztay       if (flg) {
950d0c080abSJoseph Pusztay         ctx->displayvariables[j] = k;
951d0c080abSJoseph Pusztay         break;
952d0c080abSJoseph Pusztay       }
953d0c080abSJoseph Pusztay       k++;
954d0c080abSJoseph Pusztay     }
955d0c080abSJoseph Pusztay     j++;
956d0c080abSJoseph Pusztay   }
957d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
958d0c080abSJoseph Pusztay }
959d0c080abSJoseph Pusztay 
960d0c080abSJoseph Pusztay /*@C
961d0c080abSJoseph Pusztay    TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor
962d0c080abSJoseph Pusztay 
963d0c080abSJoseph Pusztay    Collective on TS
964d0c080abSJoseph Pusztay 
965d0c080abSJoseph Pusztay    Input Parameters:
966d0c080abSJoseph Pusztay +  ts - the TS context
967d0c080abSJoseph Pusztay -  displaynames - the names of the components, final string must be NULL
968d0c080abSJoseph Pusztay 
969d0c080abSJoseph Pusztay    Notes:
970d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
971d0c080abSJoseph Pusztay 
972d0c080abSJoseph Pusztay    Level: intermediate
973d0c080abSJoseph Pusztay 
974d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
975d0c080abSJoseph Pusztay @*/
976d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames)
977d0c080abSJoseph Pusztay {
978d0c080abSJoseph Pusztay   PetscInt          i;
979d0c080abSJoseph Pusztay 
980d0c080abSJoseph Pusztay   PetscFunctionBegin;
981d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
982d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
9839566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames));
984d0c080abSJoseph Pusztay       break;
985d0c080abSJoseph Pusztay     }
986d0c080abSJoseph Pusztay   }
987d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
988d0c080abSJoseph Pusztay }
989d0c080abSJoseph Pusztay 
990d0c080abSJoseph Pusztay /*@C
991d0c080abSJoseph Pusztay    TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed
992d0c080abSJoseph Pusztay 
993d0c080abSJoseph Pusztay    Collective on TS
994d0c080abSJoseph Pusztay 
995d0c080abSJoseph Pusztay    Input Parameters:
996d0c080abSJoseph Pusztay +  ts - the TS context
997d0c080abSJoseph Pusztay .  transform - the transform function
998d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
999d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
1000d0c080abSJoseph Pusztay 
1001d0c080abSJoseph Pusztay    Notes:
1002d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
1003d0c080abSJoseph Pusztay 
1004d0c080abSJoseph Pusztay    Level: intermediate
1005d0c080abSJoseph Pusztay 
1006d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform()
1007d0c080abSJoseph Pusztay @*/
1008d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
1009d0c080abSJoseph Pusztay {
1010d0c080abSJoseph Pusztay   PetscInt          i;
1011d0c080abSJoseph Pusztay 
1012d0c080abSJoseph Pusztay   PetscFunctionBegin;
1013d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
1014d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
10159566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx));
1016d0c080abSJoseph Pusztay     }
1017d0c080abSJoseph Pusztay   }
1018d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1019d0c080abSJoseph Pusztay }
1020d0c080abSJoseph Pusztay 
1021d0c080abSJoseph Pusztay /*@C
1022d0c080abSJoseph Pusztay    TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed
1023d0c080abSJoseph Pusztay 
1024d0c080abSJoseph Pusztay    Collective on TSLGCtx
1025d0c080abSJoseph Pusztay 
1026d0c080abSJoseph Pusztay    Input Parameters:
1027d0c080abSJoseph Pusztay +  ts - the TS context
1028d0c080abSJoseph Pusztay .  transform - the transform function
1029d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
1030d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
1031d0c080abSJoseph Pusztay 
1032d0c080abSJoseph Pusztay    Level: intermediate
1033d0c080abSJoseph Pusztay 
1034d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform()
1035d0c080abSJoseph Pusztay @*/
1036d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
1037d0c080abSJoseph Pusztay {
1038d0c080abSJoseph Pusztay   PetscFunctionBegin;
1039d0c080abSJoseph Pusztay   ctx->transform    = transform;
1040d0c080abSJoseph Pusztay   ctx->transformdestroy = destroy;
1041d0c080abSJoseph Pusztay   ctx->transformctx = tctx;
1042d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1043d0c080abSJoseph Pusztay }
1044d0c080abSJoseph Pusztay 
1045d0c080abSJoseph Pusztay /*@C
1046d0c080abSJoseph Pusztay    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error
1047d0c080abSJoseph Pusztay        in a time based line graph
1048d0c080abSJoseph Pusztay 
1049d0c080abSJoseph Pusztay    Collective on TS
1050d0c080abSJoseph Pusztay 
1051d0c080abSJoseph Pusztay    Input Parameters:
1052d0c080abSJoseph Pusztay +  ts - the TS context
1053d0c080abSJoseph Pusztay .  step - current time-step
1054d0c080abSJoseph Pusztay .  ptime - current time
1055d0c080abSJoseph Pusztay .  u - current solution
1056d0c080abSJoseph Pusztay -  dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate()
1057d0c080abSJoseph Pusztay 
1058d0c080abSJoseph Pusztay    Level: intermediate
1059d0c080abSJoseph Pusztay 
1060d0c080abSJoseph Pusztay    Notes:
1061d0c080abSJoseph Pusztay     Each process in a parallel run displays its component errors in a separate window
1062d0c080abSJoseph Pusztay 
1063d0c080abSJoseph Pusztay    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
1064d0c080abSJoseph Pusztay 
1065d0c080abSJoseph Pusztay    Options Database Keys:
1066d0c080abSJoseph Pusztay .  -ts_monitor_lg_error - create a graphical monitor of error history
1067d0c080abSJoseph Pusztay 
1068d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
1069d0c080abSJoseph Pusztay @*/
1070d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
1071d0c080abSJoseph Pusztay {
1072d0c080abSJoseph Pusztay   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
1073d0c080abSJoseph Pusztay   const PetscScalar *yy;
1074d0c080abSJoseph Pusztay   Vec               y;
1075d0c080abSJoseph Pusztay 
1076d0c080abSJoseph Pusztay   PetscFunctionBegin;
1077d0c080abSJoseph Pusztay   if (!step) {
1078d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1079d0c080abSJoseph Pusztay     PetscInt      dim;
10809566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
10819566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Error"));
10829566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(u,&dim));
10839566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSetDimension(ctx->lg,dim));
10849566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1085d0c080abSJoseph Pusztay   }
10869566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u,&y));
10879566063dSJacob Faibussowitsch   PetscCall(TSComputeSolutionFunction(ts,ptime,y));
10889566063dSJacob Faibussowitsch   PetscCall(VecAXPY(y,-1.0,u));
10899566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(y,&yy));
1090d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
1091d0c080abSJoseph Pusztay   {
1092d0c080abSJoseph Pusztay     PetscReal *yreal;
1093d0c080abSJoseph Pusztay     PetscInt  i,n;
10949566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(y,&n));
10959566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&yreal));
1096d0c080abSJoseph Pusztay     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
10979566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal));
10989566063dSJacob Faibussowitsch     PetscCall(PetscFree(yreal));
1099d0c080abSJoseph Pusztay   }
1100d0c080abSJoseph Pusztay #else
11019566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy));
1102d0c080abSJoseph Pusztay #endif
11039566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(y,&yy));
11049566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&y));
1105d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
11069566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
11079566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1108d0c080abSJoseph Pusztay   }
1109d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1110d0c080abSJoseph Pusztay }
1111d0c080abSJoseph Pusztay 
1112d0c080abSJoseph Pusztay /*@C
1113d0c080abSJoseph Pusztay    TSMonitorSPSwarmSolution - Graphically displays phase plots of DMSwarm particles on a scatter plot
1114d0c080abSJoseph Pusztay 
1115d0c080abSJoseph Pusztay    Input Parameters:
1116d0c080abSJoseph Pusztay +  ts - the TS context
1117d0c080abSJoseph Pusztay .  step - current time-step
1118d0c080abSJoseph Pusztay .  ptime - current time
1119d0c080abSJoseph Pusztay .  u - current solution
1120d0c080abSJoseph Pusztay -  dctx - the TSMonitorSPCtx object that contains all the options for the monitoring, this is created with TSMonitorSPCtxCreate()
1121d0c080abSJoseph Pusztay 
1122d0c080abSJoseph Pusztay    Options Database:
1123d7462660SMatthew Knepley + -ts_monitor_sp_swarm <n>          - Monitor the solution every n steps, or -1 for plotting only the final solution
1124d7462660SMatthew Knepley . -ts_monitor_sp_swarm_retain <n>   - Retain n old points so we can see the history, or -1 for all points
1125d7462660SMatthew Knepley - -ts_monitor_sp_swarm_phase <bool> - Plot in phase space, as opposed to coordinate space
1126d0c080abSJoseph Pusztay 
1127d0c080abSJoseph Pusztay    Level: intermediate
1128d0c080abSJoseph Pusztay 
1129d7462660SMatthew Knepley .seealso: TSMonitoSet()
1130d0c080abSJoseph Pusztay @*/
1131d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSPSwarmSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx)
1132d0c080abSJoseph Pusztay {
1133d0c080abSJoseph Pusztay   TSMonitorSPCtx     ctx = (TSMonitorSPCtx) dctx;
1134*f98b2f00SMatthew G. Knepley   PetscDraw          draw;
1135d7462660SMatthew Knepley   DM                 dm, cdm;
1136d0c080abSJoseph Pusztay   const PetscScalar *yy;
1137d0c080abSJoseph Pusztay   PetscInt           Np, p, dim = 2;
1138d0c080abSJoseph Pusztay 
1139d0c080abSJoseph Pusztay   PetscFunctionBegin;
1140d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1141d0c080abSJoseph Pusztay   if (!step) {
1142d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1143ab43fcacSJoe Pusztay     PetscReal     dmboxlower[2], dmboxupper[2];
1144*f98b2f00SMatthew G. Knepley 
11459566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &dm));
11469566063dSJacob Faibussowitsch     PetscCall(DMGetDimension(dm, &dim));
11473c633725SBarry Smith     PetscCheck(dim == 2, PETSC_COMM_SELF, PETSC_ERR_SUP, "Monitor only supports two dimensional fields");
11489566063dSJacob Faibussowitsch     PetscCall(DMSwarmGetCellDM(dm, &cdm));
11499566063dSJacob Faibussowitsch     PetscCall(DMGetBoundingBox(cdm, dmboxlower, dmboxupper));
11509566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(u, &Np));
1151d7462660SMatthew Knepley     Np /= dim*2;
11529566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPGetAxis(ctx->sp,&axis));
11538c87cf4dSdanfinn     if (ctx->phase) {
11549566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(axis,"Particles","X","V"));
11559566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], -5, 5));
11568c87cf4dSdanfinn     } else {
11579566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(axis,"Particles","X","Y"));
11589566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], dmboxlower[1], dmboxupper[1]));
11598c87cf4dSdanfinn     }
11609566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetHoldLimits(axis, PETSC_TRUE));
11619566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPReset(ctx->sp));
1162d0c080abSJoseph Pusztay   }
11639566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(u, &Np));
1164d7462660SMatthew Knepley   Np /= dim*2;
1165d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
11669566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPGetDraw(ctx->sp, &draw));
1167d7462660SMatthew Knepley     if ((ctx->retain == 0) || (ctx->retain > 0 && !(step % ctx->retain))) {
11689566063dSJacob Faibussowitsch       PetscCall(PetscDrawClear(draw));
1169d7462660SMatthew Knepley     }
11709566063dSJacob Faibussowitsch     PetscCall(PetscDrawFlush(draw));
11719566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPReset(ctx->sp));
1172*f98b2f00SMatthew G. Knepley     PetscCall(VecGetArrayRead(u, &yy));
1173*f98b2f00SMatthew G. Knepley     for (p = 0; p < Np; ++p) {
1174*f98b2f00SMatthew G. Knepley       PetscReal x, y;
1175*f98b2f00SMatthew G. Knepley 
1176*f98b2f00SMatthew G. Knepley       if (ctx->phase) {
1177*f98b2f00SMatthew G. Knepley         x = PetscRealPart(yy[p*dim*2]);
1178*f98b2f00SMatthew G. Knepley         y = PetscRealPart(yy[p*dim*2 + dim]);
1179*f98b2f00SMatthew G. Knepley       } else {
1180*f98b2f00SMatthew G. Knepley         x = PetscRealPart(yy[p*dim*2]);
1181*f98b2f00SMatthew G. Knepley         y = PetscRealPart(yy[p*dim*2 + 1]);
1182*f98b2f00SMatthew G. Knepley       }
1183*f98b2f00SMatthew G. Knepley       PetscCall(PetscDrawSPAddPoint(ctx->sp, &x, &y));
1184*f98b2f00SMatthew G. Knepley     }
1185*f98b2f00SMatthew G. Knepley     PetscCall(VecRestoreArrayRead(u, &yy));
11869566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPDraw(ctx->sp, PETSC_FALSE));
11879566063dSJacob Faibussowitsch     PetscCall(PetscDrawSPSave(ctx->sp));
1188d0c080abSJoseph Pusztay   }
1189d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1190d0c080abSJoseph Pusztay }
1191d0c080abSJoseph Pusztay 
1192d0c080abSJoseph Pusztay /*@C
1193d0c080abSJoseph Pusztay    TSMonitorError - Monitors progress of the TS solvers by printing the 2 norm of the error at each timestep
1194d0c080abSJoseph Pusztay 
1195d0c080abSJoseph Pusztay    Collective on TS
1196d0c080abSJoseph Pusztay 
1197d0c080abSJoseph Pusztay    Input Parameters:
1198d0c080abSJoseph Pusztay +  ts - the TS context
1199d0c080abSJoseph Pusztay .  step - current time-step
1200d0c080abSJoseph Pusztay .  ptime - current time
1201d0c080abSJoseph Pusztay .  u - current solution
1202d0c080abSJoseph Pusztay -  dctx - unused context
1203d0c080abSJoseph Pusztay 
1204d0c080abSJoseph Pusztay    Level: intermediate
1205d0c080abSJoseph Pusztay 
1206d0c080abSJoseph Pusztay    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
1207d0c080abSJoseph Pusztay 
1208d0c080abSJoseph Pusztay    Options Database Keys:
1209d0c080abSJoseph Pusztay .  -ts_monitor_error - create a graphical monitor of error history
1210d0c080abSJoseph Pusztay 
1211d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
1212d0c080abSJoseph Pusztay @*/
1213d0c080abSJoseph Pusztay PetscErrorCode TSMonitorError(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
1214d0c080abSJoseph Pusztay {
121507eaae0cSMatthew G. Knepley   DM             dm;
121607eaae0cSMatthew G. Knepley   PetscDS        ds = NULL;
121707eaae0cSMatthew G. Knepley   PetscInt       Nf = -1, f;
1218d0c080abSJoseph Pusztay   PetscBool      flg;
1219d0c080abSJoseph Pusztay 
1220d0c080abSJoseph Pusztay   PetscFunctionBegin;
12219566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
12229566063dSJacob Faibussowitsch   if (dm) PetscCall(DMGetDS(dm, &ds));
12239566063dSJacob Faibussowitsch   if (ds) PetscCall(PetscDSGetNumFields(ds, &Nf));
122407eaae0cSMatthew G. Knepley   if (Nf <= 0) {
122507eaae0cSMatthew G. Knepley     Vec       y;
122607eaae0cSMatthew G. Knepley     PetscReal nrm;
122707eaae0cSMatthew G. Knepley 
12289566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u,&y));
12299566063dSJacob Faibussowitsch     PetscCall(TSComputeSolutionFunction(ts,ptime,y));
12309566063dSJacob Faibussowitsch     PetscCall(VecAXPY(y,-1.0,u));
12319566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERASCII,&flg));
1232d0c080abSJoseph Pusztay     if (flg) {
12339566063dSJacob Faibussowitsch       PetscCall(VecNorm(y,NORM_2,&nrm));
12349566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vf->viewer,"2-norm of error %g\n",(double)nrm));
1235d0c080abSJoseph Pusztay     }
12369566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERDRAW,&flg));
1237d0c080abSJoseph Pusztay     if (flg) {
12389566063dSJacob Faibussowitsch       PetscCall(VecView(y,vf->viewer));
1239d0c080abSJoseph Pusztay     }
12409566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&y));
124107eaae0cSMatthew G. Knepley   } else {
124207eaae0cSMatthew G. Knepley     PetscErrorCode (**exactFuncs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx);
124307eaae0cSMatthew G. Knepley     void            **ctxs;
124407eaae0cSMatthew G. Knepley     Vec               v;
124507eaae0cSMatthew G. Knepley     PetscReal         ferrors[1];
124607eaae0cSMatthew G. Knepley 
12479566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(Nf, &exactFuncs, Nf, &ctxs));
12489566063dSJacob Faibussowitsch     for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(ds, f, &exactFuncs[f], &ctxs[f]));
12499566063dSJacob Faibussowitsch     PetscCall(DMComputeL2FieldDiff(dm, ptime, exactFuncs, ctxs, u, ferrors));
12509566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Timestep: %04d time = %-8.4g \t L_2 Error: [", (int) step, (double) ptime));
125107eaae0cSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
12529566063dSJacob Faibussowitsch       if (f > 0) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ", "));
12539566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%2.3g", (double) ferrors[f]));
125407eaae0cSMatthew G. Knepley     }
12559566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "]\n"));
125607eaae0cSMatthew G. Knepley 
12579566063dSJacob Faibussowitsch     PetscCall(VecViewFromOptions(u, NULL, "-sol_vec_view"));
125807eaae0cSMatthew G. Knepley 
12599566063dSJacob Faibussowitsch     PetscCall(PetscOptionsHasName(NULL, NULL, "-exact_vec_view", &flg));
126007eaae0cSMatthew G. Knepley     if (flg) {
12619566063dSJacob Faibussowitsch       PetscCall(DMGetGlobalVector(dm, &v));
12629566063dSJacob Faibussowitsch       PetscCall(DMProjectFunction(dm, ptime, exactFuncs, ctxs, INSERT_ALL_VALUES, v));
12639566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetName((PetscObject) v, "Exact Solution"));
12649566063dSJacob Faibussowitsch       PetscCall(VecViewFromOptions(v, NULL, "-exact_vec_view"));
12659566063dSJacob Faibussowitsch       PetscCall(DMRestoreGlobalVector(dm, &v));
126607eaae0cSMatthew G. Knepley     }
12679566063dSJacob Faibussowitsch     PetscCall(PetscFree2(exactFuncs, ctxs));
126807eaae0cSMatthew G. Knepley   }
1269d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1270d0c080abSJoseph Pusztay }
1271d0c080abSJoseph Pusztay 
1272d0c080abSJoseph Pusztay PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
1273d0c080abSJoseph Pusztay {
1274d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
1275d0c080abSJoseph Pusztay   PetscReal      x   = ptime,y;
1276d0c080abSJoseph Pusztay   PetscInt       its;
1277d0c080abSJoseph Pusztay 
1278d0c080abSJoseph Pusztay   PetscFunctionBegin;
1279d0c080abSJoseph Pusztay   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1280d0c080abSJoseph Pusztay   if (!n) {
1281d0c080abSJoseph Pusztay     PetscDrawAxis axis;
12829566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
12839566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations"));
12849566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1285d0c080abSJoseph Pusztay     ctx->snes_its = 0;
1286d0c080abSJoseph Pusztay   }
12879566063dSJacob Faibussowitsch   PetscCall(TSGetSNESIterations(ts,&its));
1288d0c080abSJoseph Pusztay   y    = its - ctx->snes_its;
12899566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg,&x,&y));
1290d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
12919566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
12929566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1293d0c080abSJoseph Pusztay   }
1294d0c080abSJoseph Pusztay   ctx->snes_its = its;
1295d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1296d0c080abSJoseph Pusztay }
1297d0c080abSJoseph Pusztay 
1298d0c080abSJoseph Pusztay PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
1299d0c080abSJoseph Pusztay {
1300d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
1301d0c080abSJoseph Pusztay   PetscReal      x   = ptime,y;
1302d0c080abSJoseph Pusztay   PetscInt       its;
1303d0c080abSJoseph Pusztay 
1304d0c080abSJoseph Pusztay   PetscFunctionBegin;
1305d0c080abSJoseph Pusztay   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1306d0c080abSJoseph Pusztay   if (!n) {
1307d0c080abSJoseph Pusztay     PetscDrawAxis axis;
13089566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGGetAxis(ctx->lg,&axis));
13099566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations"));
13109566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGReset(ctx->lg));
1311d0c080abSJoseph Pusztay     ctx->ksp_its = 0;
1312d0c080abSJoseph Pusztay   }
13139566063dSJacob Faibussowitsch   PetscCall(TSGetKSPIterations(ts,&its));
1314d0c080abSJoseph Pusztay   y    = its - ctx->ksp_its;
13159566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(ctx->lg,&x,&y));
1316d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
13179566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(ctx->lg));
13189566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(ctx->lg));
1319d0c080abSJoseph Pusztay   }
1320d0c080abSJoseph Pusztay   ctx->ksp_its = its;
1321d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1322d0c080abSJoseph Pusztay }
1323d0c080abSJoseph Pusztay 
1324d0c080abSJoseph Pusztay /*@C
1325d0c080abSJoseph Pusztay    TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope()
1326d0c080abSJoseph Pusztay 
1327d0c080abSJoseph Pusztay    Collective on TS
1328d0c080abSJoseph Pusztay 
1329d0c080abSJoseph Pusztay    Input Parameters:
1330d0c080abSJoseph Pusztay .  ts  - the ODE solver object
1331d0c080abSJoseph Pusztay 
1332d0c080abSJoseph Pusztay    Output Parameter:
1333d0c080abSJoseph Pusztay .  ctx - the context
1334d0c080abSJoseph Pusztay 
1335d0c080abSJoseph Pusztay    Level: intermediate
1336d0c080abSJoseph Pusztay 
1337d0c080abSJoseph Pusztay .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError()
1338d0c080abSJoseph Pusztay 
1339d0c080abSJoseph Pusztay @*/
1340d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx)
1341d0c080abSJoseph Pusztay {
1342d0c080abSJoseph Pusztay   PetscFunctionBegin;
13439566063dSJacob Faibussowitsch   PetscCall(PetscNew(ctx));
1344d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1345d0c080abSJoseph Pusztay }
1346d0c080abSJoseph Pusztay 
1347d0c080abSJoseph Pusztay /*@C
1348d0c080abSJoseph Pusztay    TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution
1349d0c080abSJoseph Pusztay 
1350d0c080abSJoseph Pusztay    Collective on TS
1351d0c080abSJoseph Pusztay 
1352d0c080abSJoseph Pusztay    Input Parameters:
1353d0c080abSJoseph Pusztay +  ts - the TS context
1354d0c080abSJoseph Pusztay .  step - current time-step
1355d0c080abSJoseph Pusztay .  ptime - current time
1356d0c080abSJoseph Pusztay .  u  - current solution
1357d0c080abSJoseph Pusztay -  dctx - the envelope context
1358d0c080abSJoseph Pusztay 
1359d0c080abSJoseph Pusztay    Options Database:
136067b8a455SSatish Balay .  -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time
1361d0c080abSJoseph Pusztay 
1362d0c080abSJoseph Pusztay    Level: intermediate
1363d0c080abSJoseph Pusztay 
1364d0c080abSJoseph Pusztay    Notes:
1365d0c080abSJoseph Pusztay     after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope
1366d0c080abSJoseph Pusztay 
1367d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate()
1368d0c080abSJoseph Pusztay @*/
1369d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
1370d0c080abSJoseph Pusztay {
1371d0c080abSJoseph Pusztay   TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx;
1372d0c080abSJoseph Pusztay 
1373d0c080abSJoseph Pusztay   PetscFunctionBegin;
1374d0c080abSJoseph Pusztay   if (!ctx->max) {
13759566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u,&ctx->max));
13769566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(u,&ctx->min));
13779566063dSJacob Faibussowitsch     PetscCall(VecCopy(u,ctx->max));
13789566063dSJacob Faibussowitsch     PetscCall(VecCopy(u,ctx->min));
1379d0c080abSJoseph Pusztay   } else {
13809566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMax(ctx->max,u,ctx->max));
13819566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMin(ctx->min,u,ctx->min));
1382d0c080abSJoseph Pusztay   }
1383d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1384d0c080abSJoseph Pusztay }
1385d0c080abSJoseph Pusztay 
1386d0c080abSJoseph Pusztay /*@C
1387d0c080abSJoseph Pusztay    TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution
1388d0c080abSJoseph Pusztay 
1389d0c080abSJoseph Pusztay    Collective on TS
1390d0c080abSJoseph Pusztay 
1391d0c080abSJoseph Pusztay    Input Parameter:
1392d0c080abSJoseph Pusztay .  ts - the TS context
1393d0c080abSJoseph Pusztay 
1394d8d19677SJose E. Roman    Output Parameters:
1395d0c080abSJoseph Pusztay +  max - the maximum values
1396d0c080abSJoseph Pusztay -  min - the minimum values
1397d0c080abSJoseph Pusztay 
1398d0c080abSJoseph Pusztay    Notes:
1399d0c080abSJoseph Pusztay     If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored
1400d0c080abSJoseph Pusztay 
1401d0c080abSJoseph Pusztay    Level: intermediate
1402d0c080abSJoseph Pusztay 
1403d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
1404d0c080abSJoseph Pusztay @*/
1405d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min)
1406d0c080abSJoseph Pusztay {
1407d0c080abSJoseph Pusztay   PetscInt i;
1408d0c080abSJoseph Pusztay 
1409d0c080abSJoseph Pusztay   PetscFunctionBegin;
1410d0c080abSJoseph Pusztay   if (max) *max = NULL;
1411d0c080abSJoseph Pusztay   if (min) *min = NULL;
1412d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
1413d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorEnvelope) {
1414d0c080abSJoseph Pusztay       TSMonitorEnvelopeCtx  ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i];
1415d0c080abSJoseph Pusztay       if (max) *max = ctx->max;
1416d0c080abSJoseph Pusztay       if (min) *min = ctx->min;
1417d0c080abSJoseph Pusztay       break;
1418d0c080abSJoseph Pusztay     }
1419d0c080abSJoseph Pusztay   }
1420d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1421d0c080abSJoseph Pusztay }
1422d0c080abSJoseph Pusztay 
1423d0c080abSJoseph Pusztay /*@C
1424d0c080abSJoseph Pusztay    TSMonitorEnvelopeCtxDestroy - Destroys a context that was created  with TSMonitorEnvelopeCtxCreate().
1425d0c080abSJoseph Pusztay 
1426d0c080abSJoseph Pusztay    Collective on TSMonitorEnvelopeCtx
1427d0c080abSJoseph Pusztay 
1428d0c080abSJoseph Pusztay    Input Parameter:
1429d0c080abSJoseph Pusztay .  ctx - the monitor context
1430d0c080abSJoseph Pusztay 
1431d0c080abSJoseph Pusztay    Level: intermediate
1432d0c080abSJoseph Pusztay 
1433d0c080abSJoseph Pusztay .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep()
1434d0c080abSJoseph Pusztay @*/
1435d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx)
1436d0c080abSJoseph Pusztay {
1437d0c080abSJoseph Pusztay   PetscFunctionBegin;
14389566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ctx)->min));
14399566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(*ctx)->max));
14409566063dSJacob Faibussowitsch   PetscCall(PetscFree(*ctx));
1441d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1442d0c080abSJoseph Pusztay }
1443d0c080abSJoseph Pusztay 
1444d0c080abSJoseph Pusztay /*@C
1445d0c080abSJoseph Pusztay   TSDMSwarmMonitorMoments - Monitors the first three moments of a DMSarm being evolved by the TS
1446d0c080abSJoseph Pusztay 
1447d0c080abSJoseph Pusztay   Not collective
1448d0c080abSJoseph Pusztay 
1449d0c080abSJoseph Pusztay   Input Parameters:
1450d0c080abSJoseph Pusztay + ts   - the TS context
1451d0c080abSJoseph Pusztay . step - current timestep
1452d0c080abSJoseph Pusztay . t    - current time
1453d0c080abSJoseph Pusztay . u    - current solution
1454d0c080abSJoseph Pusztay - ctx  - not used
1455d0c080abSJoseph Pusztay 
1456d0c080abSJoseph Pusztay   Options Database:
145767b8a455SSatish Balay . -ts_dmswarm_monitor_moments - Monitor moments of particle distribution
1458d0c080abSJoseph Pusztay 
1459d0c080abSJoseph Pusztay   Level: intermediate
1460d0c080abSJoseph Pusztay 
1461d0c080abSJoseph Pusztay   Notes:
1462d0c080abSJoseph Pusztay   This requires a DMSwarm be attached to the TS.
1463d0c080abSJoseph Pusztay 
1464d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), DMSWARM
1465d0c080abSJoseph Pusztay @*/
1466d0c080abSJoseph Pusztay PetscErrorCode TSDMSwarmMonitorMoments(TS ts, PetscInt step, PetscReal t, Vec U, PetscViewerAndFormat *vf)
1467d0c080abSJoseph Pusztay {
1468d0c080abSJoseph Pusztay   DM                 sw;
1469d0c080abSJoseph Pusztay   const PetscScalar *u;
1470d0c080abSJoseph Pusztay   PetscReal          m = 1.0, totE = 0., totMom[3] = {0., 0., 0.};
1471d0c080abSJoseph Pusztay   PetscInt           dim, d, Np, p;
1472d0c080abSJoseph Pusztay   MPI_Comm           comm;
1473d0c080abSJoseph Pusztay 
1474d0c080abSJoseph Pusztay   PetscFunctionBeginUser;
14759566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &sw));
1476d0c080abSJoseph Pusztay   if (!sw || step%ts->monitorFrequency != 0) PetscFunctionReturn(0);
14779566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject) ts, &comm));
14789566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(sw, &dim));
14799566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(U, &Np));
1480d0c080abSJoseph Pusztay   Np  /= dim;
14819566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U, &u));
1482d0c080abSJoseph Pusztay   for (p = 0; p < Np; ++p) {
1483d0c080abSJoseph Pusztay     for (d = 0; d < dim; ++d) {
1484d0c080abSJoseph Pusztay       totE      += PetscRealPart(u[p*dim+d]*u[p*dim+d]);
1485d0c080abSJoseph Pusztay       totMom[d] += PetscRealPart(u[p*dim+d]);
1486d0c080abSJoseph Pusztay     }
1487d0c080abSJoseph Pusztay   }
14889566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U, &u));
1489d0c080abSJoseph Pusztay   for (d = 0; d < dim; ++d) totMom[d] *= m;
1490d0c080abSJoseph Pusztay   totE *= 0.5*m;
14919566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "Step %4D Total Energy: %10.8lf", step, (double) totE));
14929566063dSJacob Faibussowitsch   for (d = 0; d < dim; ++d) PetscCall(PetscPrintf(comm, "    Total Momentum %c: %10.8lf", 'x'+d, (double) totMom[d]));
14939566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "\n"));
1494d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1495d0c080abSJoseph Pusztay }
1496