xref: /petsc/src/ts/interface/tsmon.c (revision d8d19677bbccf95218448bee62e6b87f4513e133)
1d0c080abSJoseph Pusztay #include <petsc/private/tsimpl.h>        /*I "petscts.h"  I*/
2d0c080abSJoseph Pusztay #include <petscdm.h>
3d0c080abSJoseph Pusztay #include <petscdraw.h>
4d0c080abSJoseph Pusztay 
5d0c080abSJoseph Pusztay /*@C
6d0c080abSJoseph Pusztay    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()
7d0c080abSJoseph Pusztay 
8d0c080abSJoseph Pusztay    Collective on TS
9d0c080abSJoseph Pusztay 
10d0c080abSJoseph Pusztay    Input Parameters:
11d0c080abSJoseph Pusztay +  ts - time stepping context obtained from TSCreate()
12d0c080abSJoseph Pusztay .  step - step number that has just completed
13d0c080abSJoseph Pusztay .  ptime - model time of the state
14d0c080abSJoseph Pusztay -  u - state at the current model time
15d0c080abSJoseph Pusztay 
16d0c080abSJoseph Pusztay    Notes:
17d0c080abSJoseph Pusztay    TSMonitor() is typically used automatically within the time stepping implementations.
18d0c080abSJoseph Pusztay    Users would almost never call this routine directly.
19d0c080abSJoseph Pusztay 
20d0c080abSJoseph Pusztay    A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions
21d0c080abSJoseph Pusztay 
22d0c080abSJoseph Pusztay    Level: developer
23d0c080abSJoseph Pusztay 
24d0c080abSJoseph Pusztay @*/
25d0c080abSJoseph Pusztay PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u)
26d0c080abSJoseph Pusztay {
27d0c080abSJoseph Pusztay   DM             dm;
28d0c080abSJoseph Pusztay   PetscInt       i,n = ts->numbermonitors;
29d0c080abSJoseph Pusztay   PetscErrorCode ierr;
30d0c080abSJoseph Pusztay 
31d0c080abSJoseph Pusztay   PetscFunctionBegin;
32d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
33d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
34d0c080abSJoseph Pusztay 
35d0c080abSJoseph Pusztay   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
36d0c080abSJoseph Pusztay   ierr = DMSetOutputSequenceNumber(dm,step,ptime);CHKERRQ(ierr);
37d0c080abSJoseph Pusztay 
38d0c080abSJoseph Pusztay   ierr = VecLockReadPush(u);CHKERRQ(ierr);
39d0c080abSJoseph Pusztay   for (i=0; i<n; i++) {
40d0c080abSJoseph Pusztay     ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr);
41d0c080abSJoseph Pusztay   }
42d0c080abSJoseph Pusztay   ierr = VecLockReadPop(u);CHKERRQ(ierr);
43d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
44d0c080abSJoseph Pusztay }
45d0c080abSJoseph Pusztay 
46d0c080abSJoseph Pusztay /*@C
47d0c080abSJoseph Pusztay    TSMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
48d0c080abSJoseph Pusztay 
49d0c080abSJoseph Pusztay    Collective on TS
50d0c080abSJoseph Pusztay 
51d0c080abSJoseph Pusztay    Input Parameters:
52d0c080abSJoseph Pusztay +  ts - TS object you wish to monitor
53d0c080abSJoseph Pusztay .  name - the monitor type one is seeking
54d0c080abSJoseph Pusztay .  help - message indicating what monitoring is done
55d0c080abSJoseph Pusztay .  manual - manual page for the monitor
56d0c080abSJoseph Pusztay .  monitor - the monitor function
57d0c080abSJoseph 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
58d0c080abSJoseph Pusztay 
59d0c080abSJoseph Pusztay    Level: developer
60d0c080abSJoseph Pusztay 
61d0c080abSJoseph Pusztay .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
62d0c080abSJoseph Pusztay           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
63d0c080abSJoseph Pusztay           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
64d0c080abSJoseph Pusztay           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
65d0c080abSJoseph Pusztay           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
66d0c080abSJoseph Pusztay           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
67d0c080abSJoseph Pusztay           PetscOptionsFList(), PetscOptionsEList()
68d0c080abSJoseph Pusztay @*/
69d0c080abSJoseph 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*))
70d0c080abSJoseph Pusztay {
71d0c080abSJoseph Pusztay   PetscErrorCode    ierr;
72d0c080abSJoseph Pusztay   PetscViewer       viewer;
73d0c080abSJoseph Pusztay   PetscViewerFormat format;
74d0c080abSJoseph Pusztay   PetscBool         flg;
75d0c080abSJoseph Pusztay 
76d0c080abSJoseph Pusztay   PetscFunctionBegin;
77d0c080abSJoseph Pusztay   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts),((PetscObject) ts)->options,((PetscObject)ts)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr);
78d0c080abSJoseph Pusztay   if (flg) {
79d0c080abSJoseph Pusztay     PetscViewerAndFormat *vf;
80d0c080abSJoseph Pusztay     ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr);
81d0c080abSJoseph Pusztay     ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr);
82d0c080abSJoseph Pusztay     if (monitorsetup) {
83d0c080abSJoseph Pusztay       ierr = (*monitorsetup)(ts,vf);CHKERRQ(ierr);
84d0c080abSJoseph Pusztay     }
85d0c080abSJoseph Pusztay     ierr = TSMonitorSet(ts,(PetscErrorCode (*)(TS,PetscInt,PetscReal,Vec,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr);
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   PetscErrorCode ierr;
127d0c080abSJoseph Pusztay   PetscInt       i;
128d0c080abSJoseph Pusztay   PetscBool      identical;
129d0c080abSJoseph Pusztay 
130d0c080abSJoseph Pusztay   PetscFunctionBegin;
131d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
132d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors;i++) {
133d0c080abSJoseph Pusztay     ierr = PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical);CHKERRQ(ierr);
134d0c080abSJoseph Pusztay     if (identical) PetscFunctionReturn(0);
135d0c080abSJoseph Pusztay   }
136d0c080abSJoseph Pusztay   if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
137d0c080abSJoseph Pusztay   ts->monitor[ts->numbermonitors]          = monitor;
138d0c080abSJoseph Pusztay   ts->monitordestroy[ts->numbermonitors]   = mdestroy;
139d0c080abSJoseph Pusztay   ts->monitorcontext[ts->numbermonitors++] = (void*)mctx;
140d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
141d0c080abSJoseph Pusztay }
142d0c080abSJoseph Pusztay 
143d0c080abSJoseph Pusztay /*@C
144d0c080abSJoseph Pusztay    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
145d0c080abSJoseph Pusztay 
146d0c080abSJoseph Pusztay    Logically Collective on TS
147d0c080abSJoseph Pusztay 
148d0c080abSJoseph Pusztay    Input Parameters:
149d0c080abSJoseph Pusztay .  ts - the TS context obtained from TSCreate()
150d0c080abSJoseph Pusztay 
151d0c080abSJoseph Pusztay    Notes:
152d0c080abSJoseph Pusztay    There is no way to remove a single, specific monitor.
153d0c080abSJoseph Pusztay 
154d0c080abSJoseph Pusztay    Level: intermediate
155d0c080abSJoseph Pusztay 
156d0c080abSJoseph Pusztay .seealso: TSMonitorDefault(), TSMonitorSet()
157d0c080abSJoseph Pusztay @*/
158d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorCancel(TS ts)
159d0c080abSJoseph Pusztay {
160d0c080abSJoseph Pusztay   PetscErrorCode ierr;
161d0c080abSJoseph Pusztay   PetscInt       i;
162d0c080abSJoseph Pusztay 
163d0c080abSJoseph Pusztay   PetscFunctionBegin;
164d0c080abSJoseph Pusztay   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
165d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
166d0c080abSJoseph Pusztay     if (ts->monitordestroy[i]) {
167d0c080abSJoseph Pusztay       ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr);
168d0c080abSJoseph Pusztay     }
169d0c080abSJoseph Pusztay   }
170d0c080abSJoseph Pusztay   ts->numbermonitors = 0;
171d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
172d0c080abSJoseph Pusztay }
173d0c080abSJoseph Pusztay 
174d0c080abSJoseph Pusztay /*@C
175d0c080abSJoseph Pusztay    TSMonitorDefault - The Default monitor, prints the timestep and time for each step
176d0c080abSJoseph Pusztay 
177d0c080abSJoseph Pusztay    Level: intermediate
178d0c080abSJoseph Pusztay 
179d0c080abSJoseph Pusztay .seealso:  TSMonitorSet()
180d0c080abSJoseph Pusztay @*/
181d0c080abSJoseph Pusztay PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf)
182d0c080abSJoseph Pusztay {
183d0c080abSJoseph Pusztay   PetscErrorCode ierr;
184d0c080abSJoseph Pusztay   PetscViewer    viewer =  vf->viewer;
185d0c080abSJoseph Pusztay   PetscBool      iascii,ibinary;
186d0c080abSJoseph Pusztay 
187d0c080abSJoseph Pusztay   PetscFunctionBegin;
188064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,5);
189d0c080abSJoseph Pusztay   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
190d0c080abSJoseph Pusztay   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
191d0c080abSJoseph Pusztay   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
192d0c080abSJoseph Pusztay   if (iascii) {
193d0c080abSJoseph Pusztay     ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
194d0c080abSJoseph Pusztay     if (step == -1) { /* this indicates it is an interpolated solution */
195d0c080abSJoseph Pusztay       ierr = PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %D and %D\n",(double)ptime,ts->steps-1,ts->steps);CHKERRQ(ierr);
196d0c080abSJoseph Pusztay     } else {
197d0c080abSJoseph Pusztay       ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr);
198d0c080abSJoseph Pusztay     }
199d0c080abSJoseph Pusztay     ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
200d0c080abSJoseph Pusztay   } else if (ibinary) {
201d0c080abSJoseph Pusztay     PetscMPIInt rank;
202d0c080abSJoseph Pusztay     ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRMPI(ierr);
203d0c080abSJoseph Pusztay     if (!rank) {
204d0c080abSJoseph Pusztay       PetscBool skipHeader;
205d0c080abSJoseph Pusztay       PetscInt  classid = REAL_FILE_CLASSID;
206d0c080abSJoseph Pusztay 
207d0c080abSJoseph Pusztay       ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
208d0c080abSJoseph Pusztay       if (!skipHeader) {
209d0c080abSJoseph Pusztay          ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr);
210d0c080abSJoseph Pusztay        }
211d0c080abSJoseph Pusztay       ierr = PetscRealView(1,&ptime,viewer);CHKERRQ(ierr);
212d0c080abSJoseph Pusztay     } else {
213d0c080abSJoseph Pusztay       ierr = PetscRealView(0,&ptime,viewer);CHKERRQ(ierr);
214d0c080abSJoseph Pusztay     }
215d0c080abSJoseph Pusztay   }
216d0c080abSJoseph Pusztay   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
217d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
218d0c080abSJoseph Pusztay }
219d0c080abSJoseph Pusztay 
220d0c080abSJoseph Pusztay /*@C
221d0c080abSJoseph Pusztay    TSMonitorExtreme - Prints the extreme values of the solution at each timestep
222d0c080abSJoseph Pusztay 
223d0c080abSJoseph Pusztay    Level: intermediate
224d0c080abSJoseph Pusztay 
225d0c080abSJoseph Pusztay .seealso:  TSMonitorSet()
226d0c080abSJoseph Pusztay @*/
227d0c080abSJoseph Pusztay PetscErrorCode TSMonitorExtreme(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf)
228d0c080abSJoseph Pusztay {
229d0c080abSJoseph Pusztay   PetscErrorCode ierr;
230d0c080abSJoseph Pusztay   PetscViewer    viewer =  vf->viewer;
231d0c080abSJoseph Pusztay   PetscBool      iascii;
232d0c080abSJoseph Pusztay   PetscReal      max,min;
233d0c080abSJoseph Pusztay 
234d0c080abSJoseph Pusztay   PetscFunctionBegin;
235064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,5);
236d0c080abSJoseph Pusztay   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
237d0c080abSJoseph Pusztay   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
238d0c080abSJoseph Pusztay   if (iascii) {
239d0c080abSJoseph Pusztay     ierr = VecMax(v,NULL,&max);CHKERRQ(ierr);
240d0c080abSJoseph Pusztay     ierr = VecMin(v,NULL,&min);CHKERRQ(ierr);
241d0c080abSJoseph Pusztay     ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
242d0c080abSJoseph Pusztay     ierr = 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);CHKERRQ(ierr);
243d0c080abSJoseph Pusztay     ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
244d0c080abSJoseph Pusztay   }
245d0c080abSJoseph Pusztay   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
246d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
247d0c080abSJoseph Pusztay }
248d0c080abSJoseph Pusztay 
249d0c080abSJoseph Pusztay /*@C
250d0c080abSJoseph Pusztay    TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with
251d0c080abSJoseph Pusztay    TS to monitor the solution process graphically in various ways
252d0c080abSJoseph Pusztay 
253d0c080abSJoseph Pusztay    Collective on TS
254d0c080abSJoseph Pusztay 
255d0c080abSJoseph Pusztay    Input Parameters:
256d0c080abSJoseph Pusztay +  host - the X display to open, or null for the local machine
257d0c080abSJoseph Pusztay .  label - the title to put in the title bar
258d0c080abSJoseph Pusztay .  x, y - the screen coordinates of the upper left coordinate of the window
259d0c080abSJoseph Pusztay .  m, n - the screen width and height in pixels
260d0c080abSJoseph Pusztay -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
261d0c080abSJoseph Pusztay 
262d0c080abSJoseph Pusztay    Output Parameter:
263d0c080abSJoseph Pusztay .  ctx - the context
264d0c080abSJoseph Pusztay 
265d0c080abSJoseph Pusztay    Options Database Key:
266d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep - automatically sets line graph monitor
267d0c080abSJoseph Pusztay +  -ts_monitor_lg_timestep_log - automatically sets line graph monitor
268d0c080abSJoseph Pusztay .  -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables())
269d0c080abSJoseph Pusztay .  -ts_monitor_lg_error -  monitor the error
270d0c080abSJoseph Pusztay .  -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep
271d0c080abSJoseph Pusztay .  -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep
272d0c080abSJoseph Pusztay -  -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true
273d0c080abSJoseph Pusztay 
274d0c080abSJoseph Pusztay    Notes:
275d0c080abSJoseph Pusztay    Use TSMonitorLGCtxDestroy() to destroy.
276d0c080abSJoseph Pusztay 
277d0c080abSJoseph Pusztay    One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform()
278d0c080abSJoseph Pusztay 
279d0c080abSJoseph 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
280d0c080abSJoseph 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
281d0c080abSJoseph Pusztay    as the first argument.
282d0c080abSJoseph Pusztay 
283d0c080abSJoseph Pusztay    One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames()
284d0c080abSJoseph Pusztay 
285d0c080abSJoseph Pusztay    Level: intermediate
286d0c080abSJoseph Pusztay 
287d0c080abSJoseph Pusztay .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(),
288d0c080abSJoseph Pusztay            TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
289d0c080abSJoseph Pusztay            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
290d0c080abSJoseph Pusztay            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
291d0c080abSJoseph Pusztay            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()
292d0c080abSJoseph Pusztay 
293d0c080abSJoseph Pusztay @*/
294d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
295d0c080abSJoseph Pusztay {
296d0c080abSJoseph Pusztay   PetscDraw      draw;
297d0c080abSJoseph Pusztay   PetscErrorCode ierr;
298d0c080abSJoseph Pusztay 
299d0c080abSJoseph Pusztay   PetscFunctionBegin;
300d0c080abSJoseph Pusztay   ierr = PetscNew(ctx);CHKERRQ(ierr);
301d0c080abSJoseph Pusztay   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr);
302d0c080abSJoseph Pusztay   ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr);
303d0c080abSJoseph Pusztay   ierr = PetscDrawLGCreate(draw,1,&(*ctx)->lg);CHKERRQ(ierr);
304d0c080abSJoseph Pusztay   ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr);
305d0c080abSJoseph Pusztay   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
306d0c080abSJoseph Pusztay   (*ctx)->howoften = howoften;
307d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
308d0c080abSJoseph Pusztay }
309d0c080abSJoseph Pusztay 
310d0c080abSJoseph Pusztay PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx)
311d0c080abSJoseph Pusztay {
312d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
313d0c080abSJoseph Pusztay   PetscReal      x   = ptime,y;
314d0c080abSJoseph Pusztay   PetscErrorCode ierr;
315d0c080abSJoseph Pusztay 
316d0c080abSJoseph Pusztay   PetscFunctionBegin;
317d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */
318d0c080abSJoseph Pusztay   if (!step) {
319d0c080abSJoseph Pusztay     PetscDrawAxis axis;
320d0c080abSJoseph Pusztay     const char *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step";
321d0c080abSJoseph Pusztay     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
322d0c080abSJoseph Pusztay     ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time",ylabel);CHKERRQ(ierr);
323d0c080abSJoseph Pusztay     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
324d0c080abSJoseph Pusztay   }
325d0c080abSJoseph Pusztay   ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr);
326d0c080abSJoseph Pusztay   if (ctx->semilogy) y = PetscLog10Real(y);
327d0c080abSJoseph Pusztay   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
328d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
329d0c080abSJoseph Pusztay     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
330d0c080abSJoseph Pusztay     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
331d0c080abSJoseph Pusztay   }
332d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
333d0c080abSJoseph Pusztay }
334d0c080abSJoseph Pusztay 
335d0c080abSJoseph Pusztay /*@C
336d0c080abSJoseph Pusztay    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
337d0c080abSJoseph Pusztay    with TSMonitorLGCtxCreate().
338d0c080abSJoseph Pusztay 
339d0c080abSJoseph Pusztay    Collective on TSMonitorLGCtx
340d0c080abSJoseph Pusztay 
341d0c080abSJoseph Pusztay    Input Parameter:
342d0c080abSJoseph Pusztay .  ctx - the monitor context
343d0c080abSJoseph Pusztay 
344d0c080abSJoseph Pusztay    Level: intermediate
345d0c080abSJoseph Pusztay 
346d0c080abSJoseph Pusztay .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep();
347d0c080abSJoseph Pusztay @*/
348d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
349d0c080abSJoseph Pusztay {
350d0c080abSJoseph Pusztay   PetscErrorCode ierr;
351d0c080abSJoseph Pusztay 
352d0c080abSJoseph Pusztay   PetscFunctionBegin;
353d0c080abSJoseph Pusztay   if ((*ctx)->transformdestroy) {
354d0c080abSJoseph Pusztay     ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr);
355d0c080abSJoseph Pusztay   }
356d0c080abSJoseph Pusztay   ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr);
357d0c080abSJoseph Pusztay   ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr);
358d0c080abSJoseph Pusztay   ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr);
359d0c080abSJoseph Pusztay   ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr);
360d0c080abSJoseph Pusztay   ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr);
361d0c080abSJoseph Pusztay   ierr = PetscFree(*ctx);CHKERRQ(ierr);
362d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
363d0c080abSJoseph Pusztay }
364d0c080abSJoseph Pusztay 
365d0c080abSJoseph Pusztay /*
366d0c080abSJoseph Pusztay 
367d0c080abSJoseph Pusztay   Creates a TS Monitor SPCtx for use with DM Swarm particle visualizations
368d0c080abSJoseph Pusztay 
369d0c080abSJoseph Pusztay */
370d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSPCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorSPCtx *ctx)
371d0c080abSJoseph Pusztay {
372d0c080abSJoseph Pusztay   PetscDraw      draw;
373d0c080abSJoseph Pusztay   PetscErrorCode ierr;
374d0c080abSJoseph Pusztay 
375d0c080abSJoseph Pusztay   PetscFunctionBegin;
376d0c080abSJoseph Pusztay   ierr = PetscNew(ctx);CHKERRQ(ierr);
377d0c080abSJoseph Pusztay   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr);
378d0c080abSJoseph Pusztay   ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr);
379d0c080abSJoseph Pusztay   ierr = PetscDrawSPCreate(draw,1,&(*ctx)->sp);CHKERRQ(ierr);
380d0c080abSJoseph Pusztay   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
381d0c080abSJoseph Pusztay   (*ctx)->howoften = howoften;
382d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
383d0c080abSJoseph Pusztay 
384d0c080abSJoseph Pusztay }
385d0c080abSJoseph Pusztay 
386d0c080abSJoseph Pusztay /*
387d0c080abSJoseph Pusztay   Destroys a TSMonitorSPCtx that was created with TSMonitorSPCtxCreate
388d0c080abSJoseph Pusztay */
389d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSPCtxDestroy(TSMonitorSPCtx *ctx)
390d0c080abSJoseph Pusztay {
391d0c080abSJoseph Pusztay   PetscErrorCode ierr;
392d0c080abSJoseph Pusztay 
393d0c080abSJoseph Pusztay   PetscFunctionBegin;
394d0c080abSJoseph Pusztay 
395d0c080abSJoseph Pusztay   ierr = PetscDrawSPDestroy(&(*ctx)->sp);CHKERRQ(ierr);
396d0c080abSJoseph Pusztay   ierr = PetscFree(*ctx);CHKERRQ(ierr);
397d0c080abSJoseph Pusztay 
398d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
399d0c080abSJoseph Pusztay 
400d0c080abSJoseph Pusztay }
401d0c080abSJoseph Pusztay 
402d0c080abSJoseph Pusztay /*@C
403d0c080abSJoseph Pusztay    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
404d0c080abSJoseph Pusztay    VecView() for the solution at each timestep
405d0c080abSJoseph Pusztay 
406d0c080abSJoseph Pusztay    Collective on TS
407d0c080abSJoseph Pusztay 
408d0c080abSJoseph Pusztay    Input Parameters:
409d0c080abSJoseph Pusztay +  ts - the TS context
410d0c080abSJoseph Pusztay .  step - current time-step
411d0c080abSJoseph Pusztay .  ptime - current time
412d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
413d0c080abSJoseph Pusztay 
414d0c080abSJoseph Pusztay    Options Database:
415d0c080abSJoseph Pusztay .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
416d0c080abSJoseph Pusztay 
417d0c080abSJoseph Pusztay    Notes:
418d0c080abSJoseph Pusztay     the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
419d0c080abSJoseph Pusztay        will look bad
420d0c080abSJoseph Pusztay 
421d0c080abSJoseph Pusztay    Level: intermediate
422d0c080abSJoseph Pusztay 
423d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
424d0c080abSJoseph Pusztay @*/
425d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
426d0c080abSJoseph Pusztay {
427d0c080abSJoseph Pusztay   PetscErrorCode   ierr;
428d0c080abSJoseph Pusztay   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
429d0c080abSJoseph Pusztay   PetscDraw        draw;
430d0c080abSJoseph Pusztay 
431d0c080abSJoseph Pusztay   PetscFunctionBegin;
432d0c080abSJoseph Pusztay   if (!step && ictx->showinitial) {
433d0c080abSJoseph Pusztay     if (!ictx->initialsolution) {
434d0c080abSJoseph Pusztay       ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr);
435d0c080abSJoseph Pusztay     }
436d0c080abSJoseph Pusztay     ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr);
437d0c080abSJoseph Pusztay   }
438d0c080abSJoseph Pusztay   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
439d0c080abSJoseph Pusztay 
440d0c080abSJoseph Pusztay   if (ictx->showinitial) {
441d0c080abSJoseph Pusztay     PetscReal pause;
442d0c080abSJoseph Pusztay     ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr);
443d0c080abSJoseph Pusztay     ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr);
444d0c080abSJoseph Pusztay     ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr);
445d0c080abSJoseph Pusztay     ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr);
446d0c080abSJoseph Pusztay     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr);
447d0c080abSJoseph Pusztay   }
448d0c080abSJoseph Pusztay   ierr = VecView(u,ictx->viewer);CHKERRQ(ierr);
449d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
450d0c080abSJoseph Pusztay     PetscReal xl,yl,xr,yr,h;
451d0c080abSJoseph Pusztay     char      time[32];
452d0c080abSJoseph Pusztay 
453d0c080abSJoseph Pusztay     ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
454d0c080abSJoseph Pusztay     ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
455d0c080abSJoseph Pusztay     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
456d0c080abSJoseph Pusztay     h    = yl + .95*(yr - yl);
457d0c080abSJoseph Pusztay     ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
458d0c080abSJoseph Pusztay     ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
459d0c080abSJoseph Pusztay   }
460d0c080abSJoseph Pusztay 
461d0c080abSJoseph Pusztay   if (ictx->showinitial) {
462d0c080abSJoseph Pusztay     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr);
463d0c080abSJoseph Pusztay   }
464d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
465d0c080abSJoseph Pusztay }
466d0c080abSJoseph Pusztay 
467d0c080abSJoseph Pusztay /*@C
468d0c080abSJoseph Pusztay    TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram
469d0c080abSJoseph Pusztay 
470d0c080abSJoseph Pusztay    Collective on TS
471d0c080abSJoseph Pusztay 
472d0c080abSJoseph Pusztay    Input Parameters:
473d0c080abSJoseph Pusztay +  ts - the TS context
474d0c080abSJoseph Pusztay .  step - current time-step
475d0c080abSJoseph Pusztay .  ptime - current time
476d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
477d0c080abSJoseph Pusztay 
478d0c080abSJoseph Pusztay    Level: intermediate
479d0c080abSJoseph Pusztay 
480d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
481d0c080abSJoseph Pusztay @*/
482d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
483d0c080abSJoseph Pusztay {
484d0c080abSJoseph Pusztay   PetscErrorCode    ierr;
485d0c080abSJoseph Pusztay   TSMonitorDrawCtx  ictx = (TSMonitorDrawCtx)dummy;
486d0c080abSJoseph Pusztay   PetscDraw         draw;
487d0c080abSJoseph Pusztay   PetscDrawAxis     axis;
488d0c080abSJoseph Pusztay   PetscInt          n;
489d0c080abSJoseph Pusztay   PetscMPIInt       size;
490d0c080abSJoseph Pusztay   PetscReal         U0,U1,xl,yl,xr,yr,h;
491d0c080abSJoseph Pusztay   char              time[32];
492d0c080abSJoseph Pusztay   const PetscScalar *U;
493d0c080abSJoseph Pusztay 
494d0c080abSJoseph Pusztay   PetscFunctionBegin;
495d0c080abSJoseph Pusztay   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size);CHKERRMPI(ierr);
496d0c080abSJoseph Pusztay   if (size != 1) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs");
497d0c080abSJoseph Pusztay   ierr = VecGetSize(u,&n);CHKERRQ(ierr);
498d0c080abSJoseph Pusztay   if (n != 2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns");
499d0c080abSJoseph Pusztay 
500d0c080abSJoseph Pusztay   ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
501d0c080abSJoseph Pusztay   ierr = PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis);CHKERRQ(ierr);
502d0c080abSJoseph Pusztay   ierr = PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr);
503d0c080abSJoseph Pusztay   if (!step) {
504d0c080abSJoseph Pusztay     ierr = PetscDrawClear(draw);CHKERRQ(ierr);
505d0c080abSJoseph Pusztay     ierr = PetscDrawAxisDraw(axis);CHKERRQ(ierr);
506d0c080abSJoseph Pusztay   }
507d0c080abSJoseph Pusztay 
508d0c080abSJoseph Pusztay   ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr);
509d0c080abSJoseph Pusztay   U0 = PetscRealPart(U[0]);
510d0c080abSJoseph Pusztay   U1 = PetscRealPart(U[1]);
511d0c080abSJoseph Pusztay   ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr);
512d0c080abSJoseph Pusztay   if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0);
513d0c080abSJoseph Pusztay 
514d0c080abSJoseph Pusztay   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
515d0c080abSJoseph Pusztay   ierr = PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK);CHKERRQ(ierr);
516d0c080abSJoseph Pusztay   if (ictx->showtimestepandtime) {
517d0c080abSJoseph Pusztay     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
518d0c080abSJoseph Pusztay     ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
519d0c080abSJoseph Pusztay     h    = yl + .95*(yr - yl);
520d0c080abSJoseph Pusztay     ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
521d0c080abSJoseph Pusztay   }
522d0c080abSJoseph Pusztay   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
523d0c080abSJoseph Pusztay   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
524d0c080abSJoseph Pusztay   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
525d0c080abSJoseph Pusztay   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
526d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
527d0c080abSJoseph Pusztay }
528d0c080abSJoseph Pusztay 
529d0c080abSJoseph Pusztay /*@C
530d0c080abSJoseph Pusztay    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
531d0c080abSJoseph Pusztay 
532d0c080abSJoseph Pusztay    Collective on TS
533d0c080abSJoseph Pusztay 
534d0c080abSJoseph Pusztay    Input Parameters:
535d0c080abSJoseph Pusztay .    ctx - the monitor context
536d0c080abSJoseph Pusztay 
537d0c080abSJoseph Pusztay    Level: intermediate
538d0c080abSJoseph Pusztay 
539d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError()
540d0c080abSJoseph Pusztay @*/
541d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
542d0c080abSJoseph Pusztay {
543d0c080abSJoseph Pusztay   PetscErrorCode ierr;
544d0c080abSJoseph Pusztay 
545d0c080abSJoseph Pusztay   PetscFunctionBegin;
546d0c080abSJoseph Pusztay   ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr);
547d0c080abSJoseph Pusztay   ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr);
548d0c080abSJoseph Pusztay   ierr = PetscFree(*ictx);CHKERRQ(ierr);
549d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
550d0c080abSJoseph Pusztay }
551d0c080abSJoseph Pusztay 
552d0c080abSJoseph Pusztay /*@C
553d0c080abSJoseph Pusztay    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
554d0c080abSJoseph Pusztay 
555d0c080abSJoseph Pusztay    Collective on TS
556d0c080abSJoseph Pusztay 
557d0c080abSJoseph Pusztay    Input Parameter:
558d0c080abSJoseph Pusztay .    ts - time-step context
559d0c080abSJoseph Pusztay 
560d0c080abSJoseph Pusztay    Output Patameter:
561d0c080abSJoseph Pusztay .    ctx - the monitor context
562d0c080abSJoseph Pusztay 
563d0c080abSJoseph Pusztay    Options Database:
564d0c080abSJoseph Pusztay .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
565d0c080abSJoseph Pusztay 
566d0c080abSJoseph Pusztay    Level: intermediate
567d0c080abSJoseph Pusztay 
568d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx()
569d0c080abSJoseph Pusztay @*/
570d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
571d0c080abSJoseph Pusztay {
572d0c080abSJoseph Pusztay   PetscErrorCode   ierr;
573d0c080abSJoseph Pusztay 
574d0c080abSJoseph Pusztay   PetscFunctionBegin;
575d0c080abSJoseph Pusztay   ierr = PetscNew(ctx);CHKERRQ(ierr);
576d0c080abSJoseph Pusztay   ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr);
577d0c080abSJoseph Pusztay   ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr);
578d0c080abSJoseph Pusztay 
579d0c080abSJoseph Pusztay   (*ctx)->howoften    = howoften;
580d0c080abSJoseph Pusztay   (*ctx)->showinitial = PETSC_FALSE;
581d0c080abSJoseph Pusztay   ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr);
582d0c080abSJoseph Pusztay 
583d0c080abSJoseph Pusztay   (*ctx)->showtimestepandtime = PETSC_FALSE;
584d0c080abSJoseph Pusztay   ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr);
585d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
586d0c080abSJoseph Pusztay }
587d0c080abSJoseph Pusztay 
588d0c080abSJoseph Pusztay /*@C
589d0c080abSJoseph Pusztay    TSMonitorDrawSolutionFunction - Monitors progress of the TS solvers by calling
590d0c080abSJoseph Pusztay    VecView() for the solution provided by TSSetSolutionFunction() at each timestep
591d0c080abSJoseph Pusztay 
592d0c080abSJoseph Pusztay    Collective on TS
593d0c080abSJoseph Pusztay 
594d0c080abSJoseph Pusztay    Input Parameters:
595d0c080abSJoseph Pusztay +  ts - the TS context
596d0c080abSJoseph Pusztay .  step - current time-step
597d0c080abSJoseph Pusztay .  ptime - current time
598d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
599d0c080abSJoseph Pusztay 
600d0c080abSJoseph Pusztay    Options Database:
601d0c080abSJoseph Pusztay .  -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
602d0c080abSJoseph Pusztay 
603d0c080abSJoseph Pusztay    Level: intermediate
604d0c080abSJoseph Pusztay 
605d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
606d0c080abSJoseph Pusztay @*/
607d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawSolutionFunction(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
608d0c080abSJoseph Pusztay {
609d0c080abSJoseph Pusztay   PetscErrorCode   ierr;
610d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
611d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
612d0c080abSJoseph Pusztay   Vec              work;
613d0c080abSJoseph Pusztay 
614d0c080abSJoseph Pusztay   PetscFunctionBegin;
615d0c080abSJoseph Pusztay   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
616d0c080abSJoseph Pusztay   ierr = VecDuplicate(u,&work);CHKERRQ(ierr);
617d0c080abSJoseph Pusztay   ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr);
618d0c080abSJoseph Pusztay   ierr = VecView(work,viewer);CHKERRQ(ierr);
619d0c080abSJoseph Pusztay   ierr = VecDestroy(&work);CHKERRQ(ierr);
620d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
621d0c080abSJoseph Pusztay }
622d0c080abSJoseph Pusztay 
623d0c080abSJoseph Pusztay /*@C
624d0c080abSJoseph Pusztay    TSMonitorDrawError - Monitors progress of the TS solvers by calling
625d0c080abSJoseph Pusztay    VecView() for the error at each timestep
626d0c080abSJoseph Pusztay 
627d0c080abSJoseph Pusztay    Collective on TS
628d0c080abSJoseph Pusztay 
629d0c080abSJoseph Pusztay    Input Parameters:
630d0c080abSJoseph Pusztay +  ts - the TS context
631d0c080abSJoseph Pusztay .  step - current time-step
632d0c080abSJoseph Pusztay .  ptime - current time
633d0c080abSJoseph Pusztay -  dummy - either a viewer or NULL
634d0c080abSJoseph Pusztay 
635d0c080abSJoseph Pusztay    Options Database:
636d0c080abSJoseph Pusztay .  -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
637d0c080abSJoseph Pusztay 
638d0c080abSJoseph Pusztay    Level: intermediate
639d0c080abSJoseph Pusztay 
640d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
641d0c080abSJoseph Pusztay @*/
642d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
643d0c080abSJoseph Pusztay {
644d0c080abSJoseph Pusztay   PetscErrorCode   ierr;
645d0c080abSJoseph Pusztay   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
646d0c080abSJoseph Pusztay   PetscViewer      viewer = ctx->viewer;
647d0c080abSJoseph Pusztay   Vec              work;
648d0c080abSJoseph Pusztay 
649d0c080abSJoseph Pusztay   PetscFunctionBegin;
650d0c080abSJoseph Pusztay   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
651d0c080abSJoseph Pusztay   ierr = VecDuplicate(u,&work);CHKERRQ(ierr);
652d0c080abSJoseph Pusztay   ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr);
653d0c080abSJoseph Pusztay   ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr);
654d0c080abSJoseph Pusztay   ierr = VecView(work,viewer);CHKERRQ(ierr);
655d0c080abSJoseph Pusztay   ierr = VecDestroy(&work);CHKERRQ(ierr);
656d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
657d0c080abSJoseph Pusztay }
658d0c080abSJoseph Pusztay 
659d0c080abSJoseph Pusztay /*@C
660d0c080abSJoseph 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
661d0c080abSJoseph Pusztay 
662d0c080abSJoseph Pusztay    Collective on TS
663d0c080abSJoseph Pusztay 
664d0c080abSJoseph Pusztay    Input Parameters:
665d0c080abSJoseph Pusztay +  ts - the TS context
666d0c080abSJoseph Pusztay .  step - current time-step
667d0c080abSJoseph Pusztay .  ptime - current time
668d0c080abSJoseph Pusztay .  u - current state
669d0c080abSJoseph Pusztay -  vf - viewer and its format
670d0c080abSJoseph Pusztay 
671d0c080abSJoseph Pusztay    Level: intermediate
672d0c080abSJoseph Pusztay 
673d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
674d0c080abSJoseph Pusztay @*/
675d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
676d0c080abSJoseph Pusztay {
677d0c080abSJoseph Pusztay   PetscErrorCode ierr;
678d0c080abSJoseph Pusztay 
679d0c080abSJoseph Pusztay   PetscFunctionBegin;
680d0c080abSJoseph Pusztay   ierr = PetscViewerPushFormat(vf->viewer,vf->format);CHKERRQ(ierr);
681d0c080abSJoseph Pusztay   ierr = VecView(u,vf->viewer);CHKERRQ(ierr);
682d0c080abSJoseph Pusztay   ierr = PetscViewerPopFormat(vf->viewer);CHKERRQ(ierr);
683d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
684d0c080abSJoseph Pusztay }
685d0c080abSJoseph Pusztay 
686d0c080abSJoseph Pusztay /*@C
687d0c080abSJoseph Pusztay    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
688d0c080abSJoseph Pusztay 
689d0c080abSJoseph Pusztay    Collective on TS
690d0c080abSJoseph Pusztay 
691d0c080abSJoseph Pusztay    Input Parameters:
692d0c080abSJoseph Pusztay +  ts - the TS context
693d0c080abSJoseph Pusztay .  step - current time-step
694d0c080abSJoseph Pusztay .  ptime - current time
695d0c080abSJoseph Pusztay .  u - current state
696d0c080abSJoseph Pusztay -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
697d0c080abSJoseph Pusztay 
698d0c080abSJoseph Pusztay    Level: intermediate
699d0c080abSJoseph Pusztay 
700d0c080abSJoseph Pusztay    Notes:
701d0c080abSJoseph 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.
702d0c080abSJoseph Pusztay    These are named according to the file name template.
703d0c080abSJoseph Pusztay 
704d0c080abSJoseph Pusztay    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().
705d0c080abSJoseph Pusztay 
706d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
707d0c080abSJoseph Pusztay @*/
708d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
709d0c080abSJoseph Pusztay {
710d0c080abSJoseph Pusztay   PetscErrorCode ierr;
711d0c080abSJoseph Pusztay   char           filename[PETSC_MAX_PATH_LEN];
712d0c080abSJoseph Pusztay   PetscViewer    viewer;
713d0c080abSJoseph Pusztay 
714d0c080abSJoseph Pusztay   PetscFunctionBegin;
715d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
716d0c080abSJoseph Pusztay   ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr);
717d0c080abSJoseph Pusztay   ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr);
718d0c080abSJoseph Pusztay   ierr = VecView(u,viewer);CHKERRQ(ierr);
719d0c080abSJoseph Pusztay   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
720d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
721d0c080abSJoseph Pusztay }
722d0c080abSJoseph Pusztay 
723d0c080abSJoseph Pusztay /*@C
724d0c080abSJoseph Pusztay    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
725d0c080abSJoseph Pusztay 
726d0c080abSJoseph Pusztay    Collective on TS
727d0c080abSJoseph Pusztay 
728d0c080abSJoseph Pusztay    Input Parameters:
729d0c080abSJoseph Pusztay .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
730d0c080abSJoseph Pusztay 
731d0c080abSJoseph Pusztay    Level: intermediate
732d0c080abSJoseph Pusztay 
733d0c080abSJoseph Pusztay    Note:
734d0c080abSJoseph Pusztay    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
735d0c080abSJoseph Pusztay 
736d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorSolutionVTK()
737d0c080abSJoseph Pusztay @*/
738d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
739d0c080abSJoseph Pusztay {
740d0c080abSJoseph Pusztay   PetscErrorCode ierr;
741d0c080abSJoseph Pusztay 
742d0c080abSJoseph Pusztay   PetscFunctionBegin;
743d0c080abSJoseph Pusztay   ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr);
744d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
745d0c080abSJoseph Pusztay }
746d0c080abSJoseph Pusztay 
747d0c080abSJoseph Pusztay /*@C
748d0c080abSJoseph Pusztay    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
749d0c080abSJoseph Pusztay        in a time based line graph
750d0c080abSJoseph Pusztay 
751d0c080abSJoseph Pusztay    Collective on TS
752d0c080abSJoseph Pusztay 
753d0c080abSJoseph Pusztay    Input Parameters:
754d0c080abSJoseph Pusztay +  ts - the TS context
755d0c080abSJoseph Pusztay .  step - current time-step
756d0c080abSJoseph Pusztay .  ptime - current time
757d0c080abSJoseph Pusztay .  u - current solution
758d0c080abSJoseph Pusztay -  dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate()
759d0c080abSJoseph Pusztay 
760d0c080abSJoseph Pusztay    Options Database:
761d0c080abSJoseph Pusztay .   -ts_monitor_lg_solution_variables
762d0c080abSJoseph Pusztay 
763d0c080abSJoseph Pusztay    Level: intermediate
764d0c080abSJoseph Pusztay 
765d0c080abSJoseph Pusztay    Notes:
766d0c080abSJoseph Pusztay     Each process in a parallel run displays its component solutions in a separate window
767d0c080abSJoseph Pusztay 
768d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
769d0c080abSJoseph Pusztay            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
770d0c080abSJoseph Pusztay            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
771d0c080abSJoseph Pusztay            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()
772d0c080abSJoseph Pusztay @*/
773d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
774d0c080abSJoseph Pusztay {
775d0c080abSJoseph Pusztay   PetscErrorCode    ierr;
776d0c080abSJoseph Pusztay   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dctx;
777d0c080abSJoseph Pusztay   const PetscScalar *yy;
778d0c080abSJoseph Pusztay   Vec               v;
779d0c080abSJoseph Pusztay 
780d0c080abSJoseph Pusztay   PetscFunctionBegin;
781d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
782d0c080abSJoseph Pusztay   if (!step) {
783d0c080abSJoseph Pusztay     PetscDrawAxis axis;
784d0c080abSJoseph Pusztay     PetscInt      dim;
785d0c080abSJoseph Pusztay     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
786d0c080abSJoseph Pusztay     ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr);
787d0c080abSJoseph Pusztay     if (!ctx->names) {
788d0c080abSJoseph Pusztay       PetscBool flg;
789d0c080abSJoseph Pusztay       /* user provides names of variables to plot but no names has been set so assume names are integer values */
790d0c080abSJoseph Pusztay       ierr = PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg);CHKERRQ(ierr);
791d0c080abSJoseph Pusztay       if (flg) {
792d0c080abSJoseph Pusztay         PetscInt i,n;
793d0c080abSJoseph Pusztay         char     **names;
794d0c080abSJoseph Pusztay         ierr = VecGetSize(u,&n);CHKERRQ(ierr);
795d0c080abSJoseph Pusztay         ierr = PetscMalloc1(n+1,&names);CHKERRQ(ierr);
796d0c080abSJoseph Pusztay         for (i=0; i<n; i++) {
797d0c080abSJoseph Pusztay           ierr = PetscMalloc1(5,&names[i]);CHKERRQ(ierr);
798d0c080abSJoseph Pusztay           ierr = PetscSNPrintf(names[i],5,"%D",i);CHKERRQ(ierr);
799d0c080abSJoseph Pusztay         }
800d0c080abSJoseph Pusztay         names[n] = NULL;
801d0c080abSJoseph Pusztay         ctx->names = names;
802d0c080abSJoseph Pusztay       }
803d0c080abSJoseph Pusztay     }
804d0c080abSJoseph Pusztay     if (ctx->names && !ctx->displaynames) {
805d0c080abSJoseph Pusztay       char      **displaynames;
806d0c080abSJoseph Pusztay       PetscBool flg;
807d0c080abSJoseph Pusztay       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
808d0c080abSJoseph Pusztay       ierr = PetscCalloc1(dim+1,&displaynames);CHKERRQ(ierr);
809d0c080abSJoseph Pusztay       ierr = PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr);
810d0c080abSJoseph Pusztay       if (flg) {
811d0c080abSJoseph Pusztay         ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr);
812d0c080abSJoseph Pusztay       }
813d0c080abSJoseph Pusztay       ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr);
814d0c080abSJoseph Pusztay     }
815d0c080abSJoseph Pusztay     if (ctx->displaynames) {
816d0c080abSJoseph Pusztay       ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr);
817d0c080abSJoseph Pusztay       ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr);
818d0c080abSJoseph Pusztay     } else if (ctx->names) {
819d0c080abSJoseph Pusztay       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
820d0c080abSJoseph Pusztay       ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
821d0c080abSJoseph Pusztay       ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr);
822d0c080abSJoseph Pusztay     } else {
823d0c080abSJoseph Pusztay       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
824d0c080abSJoseph Pusztay       ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
825d0c080abSJoseph Pusztay     }
826d0c080abSJoseph Pusztay     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
827d0c080abSJoseph Pusztay   }
828d0c080abSJoseph Pusztay 
829d0c080abSJoseph Pusztay   if (!ctx->transform) v = u;
830d0c080abSJoseph Pusztay   else {ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);}
831d0c080abSJoseph Pusztay   ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr);
832d0c080abSJoseph Pusztay   if (ctx->displaynames) {
833d0c080abSJoseph Pusztay     PetscInt i;
834d0c080abSJoseph Pusztay     for (i=0; i<ctx->ndisplayvariables; i++)
835d0c080abSJoseph Pusztay       ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]);
836d0c080abSJoseph Pusztay     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr);
837d0c080abSJoseph Pusztay   } else {
838d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
839d0c080abSJoseph Pusztay     PetscInt  i,n;
840d0c080abSJoseph Pusztay     PetscReal *yreal;
841d0c080abSJoseph Pusztay     ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
842d0c080abSJoseph Pusztay     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
843d0c080abSJoseph Pusztay     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
844d0c080abSJoseph Pusztay     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
845d0c080abSJoseph Pusztay     ierr = PetscFree(yreal);CHKERRQ(ierr);
846d0c080abSJoseph Pusztay #else
847d0c080abSJoseph Pusztay     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
848d0c080abSJoseph Pusztay #endif
849d0c080abSJoseph Pusztay   }
850d0c080abSJoseph Pusztay   ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr);
851d0c080abSJoseph Pusztay   if (ctx->transform) {ierr = VecDestroy(&v);CHKERRQ(ierr);}
852d0c080abSJoseph Pusztay 
853d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
854d0c080abSJoseph Pusztay     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
855d0c080abSJoseph Pusztay     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
856d0c080abSJoseph Pusztay   }
857d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
858d0c080abSJoseph Pusztay }
859d0c080abSJoseph Pusztay 
860d0c080abSJoseph Pusztay /*@C
861d0c080abSJoseph Pusztay    TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
862d0c080abSJoseph Pusztay 
863d0c080abSJoseph Pusztay    Collective on TS
864d0c080abSJoseph Pusztay 
865d0c080abSJoseph Pusztay    Input Parameters:
866d0c080abSJoseph Pusztay +  ts - the TS context
867d0c080abSJoseph Pusztay -  names - the names of the components, final string must be NULL
868d0c080abSJoseph Pusztay 
869d0c080abSJoseph Pusztay    Level: intermediate
870d0c080abSJoseph Pusztay 
871d0c080abSJoseph Pusztay    Notes:
872d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
873d0c080abSJoseph Pusztay 
874d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames()
875d0c080abSJoseph Pusztay @*/
876d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSetVariableNames(TS ts,const char * const *names)
877d0c080abSJoseph Pusztay {
878d0c080abSJoseph Pusztay   PetscErrorCode    ierr;
879d0c080abSJoseph Pusztay   PetscInt          i;
880d0c080abSJoseph Pusztay 
881d0c080abSJoseph Pusztay   PetscFunctionBegin;
882d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
883d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
884d0c080abSJoseph Pusztay       ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr);
885d0c080abSJoseph Pusztay       break;
886d0c080abSJoseph Pusztay     }
887d0c080abSJoseph Pusztay   }
888d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
889d0c080abSJoseph Pusztay }
890d0c080abSJoseph Pusztay 
891d0c080abSJoseph Pusztay /*@C
892d0c080abSJoseph Pusztay    TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
893d0c080abSJoseph Pusztay 
894d0c080abSJoseph Pusztay    Collective on TS
895d0c080abSJoseph Pusztay 
896d0c080abSJoseph Pusztay    Input Parameters:
897d0c080abSJoseph Pusztay +  ts - the TS context
898d0c080abSJoseph Pusztay -  names - the names of the components, final string must be NULL
899d0c080abSJoseph Pusztay 
900d0c080abSJoseph Pusztay    Level: intermediate
901d0c080abSJoseph Pusztay 
902d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames()
903d0c080abSJoseph Pusztay @*/
904d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names)
905d0c080abSJoseph Pusztay {
906d0c080abSJoseph Pusztay   PetscErrorCode    ierr;
907d0c080abSJoseph Pusztay 
908d0c080abSJoseph Pusztay   PetscFunctionBegin;
909d0c080abSJoseph Pusztay   ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr);
910d0c080abSJoseph Pusztay   ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr);
911d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
912d0c080abSJoseph Pusztay }
913d0c080abSJoseph Pusztay 
914d0c080abSJoseph Pusztay /*@C
915d0c080abSJoseph Pusztay    TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot
916d0c080abSJoseph Pusztay 
917d0c080abSJoseph Pusztay    Collective on TS
918d0c080abSJoseph Pusztay 
919d0c080abSJoseph Pusztay    Input Parameter:
920d0c080abSJoseph Pusztay .  ts - the TS context
921d0c080abSJoseph Pusztay 
922d0c080abSJoseph Pusztay    Output Parameter:
923d0c080abSJoseph Pusztay .  names - the names of the components, final string must be NULL
924d0c080abSJoseph Pusztay 
925d0c080abSJoseph Pusztay    Level: intermediate
926d0c080abSJoseph Pusztay 
927d0c080abSJoseph Pusztay    Notes:
928d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
929d0c080abSJoseph Pusztay 
930d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
931d0c080abSJoseph Pusztay @*/
932d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGGetVariableNames(TS ts,const char *const **names)
933d0c080abSJoseph Pusztay {
934d0c080abSJoseph Pusztay   PetscInt       i;
935d0c080abSJoseph Pusztay 
936d0c080abSJoseph Pusztay   PetscFunctionBegin;
937d0c080abSJoseph Pusztay   *names = NULL;
938d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
939d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
940d0c080abSJoseph Pusztay       TSMonitorLGCtx  ctx = (TSMonitorLGCtx) ts->monitorcontext[i];
941d0c080abSJoseph Pusztay       *names = (const char *const *)ctx->names;
942d0c080abSJoseph Pusztay       break;
943d0c080abSJoseph Pusztay     }
944d0c080abSJoseph Pusztay   }
945d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
946d0c080abSJoseph Pusztay }
947d0c080abSJoseph Pusztay 
948d0c080abSJoseph Pusztay /*@C
949d0c080abSJoseph Pusztay    TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor
950d0c080abSJoseph Pusztay 
951d0c080abSJoseph Pusztay    Collective on TS
952d0c080abSJoseph Pusztay 
953d0c080abSJoseph Pusztay    Input Parameters:
954d0c080abSJoseph Pusztay +  ctx - the TSMonitorLG context
955d0c080abSJoseph Pusztay -  displaynames - the names of the components, final string must be NULL
956d0c080abSJoseph Pusztay 
957d0c080abSJoseph Pusztay    Level: intermediate
958d0c080abSJoseph Pusztay 
959d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
960d0c080abSJoseph Pusztay @*/
961d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames)
962d0c080abSJoseph Pusztay {
963d0c080abSJoseph Pusztay   PetscInt          j = 0,k;
964d0c080abSJoseph Pusztay   PetscErrorCode    ierr;
965d0c080abSJoseph Pusztay 
966d0c080abSJoseph Pusztay   PetscFunctionBegin;
967d0c080abSJoseph Pusztay   if (!ctx->names) PetscFunctionReturn(0);
968d0c080abSJoseph Pusztay   ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr);
969d0c080abSJoseph Pusztay   ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr);
970d0c080abSJoseph Pusztay   while (displaynames[j]) j++;
971d0c080abSJoseph Pusztay   ctx->ndisplayvariables = j;
972d0c080abSJoseph Pusztay   ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr);
973d0c080abSJoseph Pusztay   ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr);
974d0c080abSJoseph Pusztay   j = 0;
975d0c080abSJoseph Pusztay   while (displaynames[j]) {
976d0c080abSJoseph Pusztay     k = 0;
977d0c080abSJoseph Pusztay     while (ctx->names[k]) {
978d0c080abSJoseph Pusztay       PetscBool flg;
979d0c080abSJoseph Pusztay       ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr);
980d0c080abSJoseph Pusztay       if (flg) {
981d0c080abSJoseph Pusztay         ctx->displayvariables[j] = k;
982d0c080abSJoseph Pusztay         break;
983d0c080abSJoseph Pusztay       }
984d0c080abSJoseph Pusztay       k++;
985d0c080abSJoseph Pusztay     }
986d0c080abSJoseph Pusztay     j++;
987d0c080abSJoseph Pusztay   }
988d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
989d0c080abSJoseph Pusztay }
990d0c080abSJoseph Pusztay 
991d0c080abSJoseph Pusztay /*@C
992d0c080abSJoseph Pusztay    TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor
993d0c080abSJoseph Pusztay 
994d0c080abSJoseph Pusztay    Collective on TS
995d0c080abSJoseph Pusztay 
996d0c080abSJoseph Pusztay    Input Parameters:
997d0c080abSJoseph Pusztay +  ts - the TS context
998d0c080abSJoseph Pusztay -  displaynames - the names of the components, final string must be NULL
999d0c080abSJoseph Pusztay 
1000d0c080abSJoseph Pusztay    Notes:
1001d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
1002d0c080abSJoseph Pusztay 
1003d0c080abSJoseph Pusztay    Level: intermediate
1004d0c080abSJoseph Pusztay 
1005d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
1006d0c080abSJoseph Pusztay @*/
1007d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames)
1008d0c080abSJoseph Pusztay {
1009d0c080abSJoseph Pusztay   PetscInt          i;
1010d0c080abSJoseph Pusztay   PetscErrorCode    ierr;
1011d0c080abSJoseph Pusztay 
1012d0c080abSJoseph Pusztay   PetscFunctionBegin;
1013d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
1014d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
1015d0c080abSJoseph Pusztay       ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr);
1016d0c080abSJoseph Pusztay       break;
1017d0c080abSJoseph Pusztay     }
1018d0c080abSJoseph Pusztay   }
1019d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1020d0c080abSJoseph Pusztay }
1021d0c080abSJoseph Pusztay 
1022d0c080abSJoseph Pusztay /*@C
1023d0c080abSJoseph Pusztay    TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed
1024d0c080abSJoseph Pusztay 
1025d0c080abSJoseph Pusztay    Collective on TS
1026d0c080abSJoseph Pusztay 
1027d0c080abSJoseph Pusztay    Input Parameters:
1028d0c080abSJoseph Pusztay +  ts - the TS context
1029d0c080abSJoseph Pusztay .  transform - the transform function
1030d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
1031d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
1032d0c080abSJoseph Pusztay 
1033d0c080abSJoseph Pusztay    Notes:
1034d0c080abSJoseph Pusztay     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
1035d0c080abSJoseph Pusztay 
1036d0c080abSJoseph Pusztay    Level: intermediate
1037d0c080abSJoseph Pusztay 
1038d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform()
1039d0c080abSJoseph Pusztay @*/
1040d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
1041d0c080abSJoseph Pusztay {
1042d0c080abSJoseph Pusztay   PetscInt          i;
1043d0c080abSJoseph Pusztay   PetscErrorCode    ierr;
1044d0c080abSJoseph Pusztay 
1045d0c080abSJoseph Pusztay   PetscFunctionBegin;
1046d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
1047d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorLGSolution) {
1048d0c080abSJoseph Pusztay       ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr);
1049d0c080abSJoseph Pusztay     }
1050d0c080abSJoseph Pusztay   }
1051d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1052d0c080abSJoseph Pusztay }
1053d0c080abSJoseph Pusztay 
1054d0c080abSJoseph Pusztay /*@C
1055d0c080abSJoseph Pusztay    TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed
1056d0c080abSJoseph Pusztay 
1057d0c080abSJoseph Pusztay    Collective on TSLGCtx
1058d0c080abSJoseph Pusztay 
1059d0c080abSJoseph Pusztay    Input Parameters:
1060d0c080abSJoseph Pusztay +  ts - the TS context
1061d0c080abSJoseph Pusztay .  transform - the transform function
1062d0c080abSJoseph Pusztay .  destroy - function to destroy the optional context
1063d0c080abSJoseph Pusztay -  ctx - optional context used by transform function
1064d0c080abSJoseph Pusztay 
1065d0c080abSJoseph Pusztay    Level: intermediate
1066d0c080abSJoseph Pusztay 
1067d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform()
1068d0c080abSJoseph Pusztay @*/
1069d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
1070d0c080abSJoseph Pusztay {
1071d0c080abSJoseph Pusztay   PetscFunctionBegin;
1072d0c080abSJoseph Pusztay   ctx->transform    = transform;
1073d0c080abSJoseph Pusztay   ctx->transformdestroy = destroy;
1074d0c080abSJoseph Pusztay   ctx->transformctx = tctx;
1075d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1076d0c080abSJoseph Pusztay }
1077d0c080abSJoseph Pusztay 
1078d0c080abSJoseph Pusztay /*@C
1079d0c080abSJoseph Pusztay    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error
1080d0c080abSJoseph Pusztay        in a time based line graph
1081d0c080abSJoseph Pusztay 
1082d0c080abSJoseph Pusztay    Collective on TS
1083d0c080abSJoseph Pusztay 
1084d0c080abSJoseph Pusztay    Input Parameters:
1085d0c080abSJoseph Pusztay +  ts - the TS context
1086d0c080abSJoseph Pusztay .  step - current time-step
1087d0c080abSJoseph Pusztay .  ptime - current time
1088d0c080abSJoseph Pusztay .  u - current solution
1089d0c080abSJoseph Pusztay -  dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate()
1090d0c080abSJoseph Pusztay 
1091d0c080abSJoseph Pusztay    Level: intermediate
1092d0c080abSJoseph Pusztay 
1093d0c080abSJoseph Pusztay    Notes:
1094d0c080abSJoseph Pusztay     Each process in a parallel run displays its component errors in a separate window
1095d0c080abSJoseph Pusztay 
1096d0c080abSJoseph Pusztay    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
1097d0c080abSJoseph Pusztay 
1098d0c080abSJoseph Pusztay    Options Database Keys:
1099d0c080abSJoseph Pusztay .  -ts_monitor_lg_error - create a graphical monitor of error history
1100d0c080abSJoseph Pusztay 
1101d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
1102d0c080abSJoseph Pusztay @*/
1103d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
1104d0c080abSJoseph Pusztay {
1105d0c080abSJoseph Pusztay   PetscErrorCode    ierr;
1106d0c080abSJoseph Pusztay   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
1107d0c080abSJoseph Pusztay   const PetscScalar *yy;
1108d0c080abSJoseph Pusztay   Vec               y;
1109d0c080abSJoseph Pusztay 
1110d0c080abSJoseph Pusztay   PetscFunctionBegin;
1111d0c080abSJoseph Pusztay   if (!step) {
1112d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1113d0c080abSJoseph Pusztay     PetscInt      dim;
1114d0c080abSJoseph Pusztay     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
1115d0c080abSJoseph Pusztay     ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Error");CHKERRQ(ierr);
1116d0c080abSJoseph Pusztay     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
1117d0c080abSJoseph Pusztay     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
1118d0c080abSJoseph Pusztay     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
1119d0c080abSJoseph Pusztay   }
1120d0c080abSJoseph Pusztay   ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
1121d0c080abSJoseph Pusztay   ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr);
1122d0c080abSJoseph Pusztay   ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr);
1123d0c080abSJoseph Pusztay   ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr);
1124d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX)
1125d0c080abSJoseph Pusztay   {
1126d0c080abSJoseph Pusztay     PetscReal *yreal;
1127d0c080abSJoseph Pusztay     PetscInt  i,n;
1128d0c080abSJoseph Pusztay     ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr);
1129d0c080abSJoseph Pusztay     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
1130d0c080abSJoseph Pusztay     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
1131d0c080abSJoseph Pusztay     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
1132d0c080abSJoseph Pusztay     ierr = PetscFree(yreal);CHKERRQ(ierr);
1133d0c080abSJoseph Pusztay   }
1134d0c080abSJoseph Pusztay #else
1135d0c080abSJoseph Pusztay   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
1136d0c080abSJoseph Pusztay #endif
1137d0c080abSJoseph Pusztay   ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr);
1138d0c080abSJoseph Pusztay   ierr = VecDestroy(&y);CHKERRQ(ierr);
1139d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
1140d0c080abSJoseph Pusztay     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
1141d0c080abSJoseph Pusztay     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
1142d0c080abSJoseph Pusztay   }
1143d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1144d0c080abSJoseph Pusztay }
1145d0c080abSJoseph Pusztay 
1146d0c080abSJoseph Pusztay /*@C
1147d0c080abSJoseph Pusztay    TSMonitorSPSwarmSolution - Graphically displays phase plots of DMSwarm particles on a scatter plot
1148d0c080abSJoseph Pusztay 
1149d0c080abSJoseph Pusztay    Input Parameters:
1150d0c080abSJoseph Pusztay +  ts - the TS context
1151d0c080abSJoseph Pusztay .  step - current time-step
1152d0c080abSJoseph Pusztay .  ptime - current time
1153d0c080abSJoseph Pusztay .  u - current solution
1154d0c080abSJoseph Pusztay -  dctx - the TSMonitorSPCtx object that contains all the options for the monitoring, this is created with TSMonitorSPCtxCreate()
1155d0c080abSJoseph Pusztay 
1156d0c080abSJoseph Pusztay    Options Database:
1157d0c080abSJoseph Pusztay .   -ts_monitor_sp_swarm
1158d0c080abSJoseph Pusztay 
1159d0c080abSJoseph Pusztay    Level: intermediate
1160d0c080abSJoseph Pusztay 
1161d0c080abSJoseph Pusztay @*/
1162d0c080abSJoseph Pusztay PetscErrorCode TSMonitorSPSwarmSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
1163d0c080abSJoseph Pusztay {
1164d0c080abSJoseph Pusztay   PetscErrorCode    ierr;
1165d0c080abSJoseph Pusztay   TSMonitorSPCtx    ctx = (TSMonitorSPCtx)dctx;
1166d0c080abSJoseph Pusztay   const PetscScalar *yy;
1167d0c080abSJoseph Pusztay   PetscReal       *y,*x;
1168d0c080abSJoseph Pusztay   PetscInt          Np, p, dim=2;
1169d0c080abSJoseph Pusztay   DM                dm;
1170d0c080abSJoseph Pusztay 
1171d0c080abSJoseph Pusztay   PetscFunctionBegin;
1172d0c080abSJoseph Pusztay   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1173d0c080abSJoseph Pusztay   if (!step) {
1174d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1175d0c080abSJoseph Pusztay     ierr = PetscDrawSPGetAxis(ctx->sp,&axis);CHKERRQ(ierr);
1176d0c080abSJoseph Pusztay     ierr = PetscDrawAxisSetLabels(axis,"Particles","X","Y");CHKERRQ(ierr);
1177d0c080abSJoseph Pusztay     ierr = PetscDrawAxisSetLimits(axis, -5, 5, -5, 5);CHKERRQ(ierr);
1178d0c080abSJoseph Pusztay     ierr = PetscDrawAxisSetHoldLimits(axis, PETSC_TRUE);CHKERRQ(ierr);
1179d0c080abSJoseph Pusztay     ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
1180d8185827SBarry Smith     ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
11812758c9b9SBarry Smith     if (dim!=2) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Dimensions improper for monitor arguments! Current support: two dimensions.");
1182d0c080abSJoseph Pusztay     ierr = VecGetLocalSize(u, &Np);CHKERRQ(ierr);
1183d0c080abSJoseph Pusztay     Np /= 2*dim;
1184d0c080abSJoseph Pusztay     ierr = PetscDrawSPSetDimension(ctx->sp, Np);CHKERRQ(ierr);
1185d0c080abSJoseph Pusztay     ierr = PetscDrawSPReset(ctx->sp);CHKERRQ(ierr);
1186d0c080abSJoseph Pusztay   }
1187d0c080abSJoseph Pusztay   ierr = VecGetLocalSize(u, &Np);CHKERRQ(ierr);
1188d0c080abSJoseph Pusztay   Np /= 2*dim;
1189d0c080abSJoseph Pusztay   ierr = VecGetArrayRead(u,&yy);CHKERRQ(ierr);
1190d0c080abSJoseph Pusztay   ierr = PetscMalloc2(Np, &x, Np, &y);CHKERRQ(ierr);
1191d0c080abSJoseph Pusztay   /* get points from solution vector */
1192d0c080abSJoseph Pusztay   for (p=0; p<Np; ++p) {
1193d0c080abSJoseph Pusztay     x[p] = PetscRealPart(yy[2*dim*p]);
1194d0c080abSJoseph Pusztay     y[p] = PetscRealPart(yy[2*dim*p+1]);
1195d0c080abSJoseph Pusztay   }
1196d0c080abSJoseph Pusztay   ierr = VecRestoreArrayRead(u,&yy);CHKERRQ(ierr);
1197d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
1198d0c080abSJoseph Pusztay     ierr = PetscDrawSPAddPoint(ctx->sp,x,y);CHKERRQ(ierr);
1199d0c080abSJoseph Pusztay     ierr = PetscDrawSPDraw(ctx->sp,PETSC_FALSE);CHKERRQ(ierr);
1200d0c080abSJoseph Pusztay     ierr = PetscDrawSPSave(ctx->sp);CHKERRQ(ierr);
1201d0c080abSJoseph Pusztay   }
1202d0c080abSJoseph Pusztay   ierr = PetscFree2(x, y);CHKERRQ(ierr);
1203d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1204d0c080abSJoseph Pusztay }
1205d0c080abSJoseph Pusztay 
1206d0c080abSJoseph Pusztay /*@C
1207d0c080abSJoseph Pusztay    TSMonitorError - Monitors progress of the TS solvers by printing the 2 norm of the error at each timestep
1208d0c080abSJoseph Pusztay 
1209d0c080abSJoseph Pusztay    Collective on TS
1210d0c080abSJoseph Pusztay 
1211d0c080abSJoseph Pusztay    Input Parameters:
1212d0c080abSJoseph Pusztay +  ts - the TS context
1213d0c080abSJoseph Pusztay .  step - current time-step
1214d0c080abSJoseph Pusztay .  ptime - current time
1215d0c080abSJoseph Pusztay .  u - current solution
1216d0c080abSJoseph Pusztay -  dctx - unused context
1217d0c080abSJoseph Pusztay 
1218d0c080abSJoseph Pusztay    Level: intermediate
1219d0c080abSJoseph Pusztay 
1220d0c080abSJoseph Pusztay    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
1221d0c080abSJoseph Pusztay 
1222d0c080abSJoseph Pusztay    Options Database Keys:
1223d0c080abSJoseph Pusztay .  -ts_monitor_error - create a graphical monitor of error history
1224d0c080abSJoseph Pusztay 
1225d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
1226d0c080abSJoseph Pusztay @*/
1227d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorError(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
1228d0c080abSJoseph Pusztay {
1229d0c080abSJoseph Pusztay   PetscErrorCode    ierr;
1230d0c080abSJoseph Pusztay   Vec               y;
1231d0c080abSJoseph Pusztay   PetscReal         nrm;
1232d0c080abSJoseph Pusztay   PetscBool         flg;
1233d0c080abSJoseph Pusztay 
1234d0c080abSJoseph Pusztay   PetscFunctionBegin;
1235d0c080abSJoseph Pusztay   ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
1236d0c080abSJoseph Pusztay   ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr);
1237d0c080abSJoseph Pusztay   ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr);
1238d0c080abSJoseph Pusztay   ierr = PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERASCII,&flg);CHKERRQ(ierr);
1239d0c080abSJoseph Pusztay   if (flg) {
1240d0c080abSJoseph Pusztay     ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
1241d0c080abSJoseph Pusztay     ierr = PetscViewerASCIIPrintf(vf->viewer,"2-norm of error %g\n",(double)nrm);CHKERRQ(ierr);
1242d0c080abSJoseph Pusztay   }
1243d0c080abSJoseph Pusztay   ierr = PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERDRAW,&flg);CHKERRQ(ierr);
1244d0c080abSJoseph Pusztay   if (flg) {
1245d0c080abSJoseph Pusztay     ierr = VecView(y,vf->viewer);CHKERRQ(ierr);
1246d0c080abSJoseph Pusztay   }
1247d0c080abSJoseph Pusztay   ierr = VecDestroy(&y);CHKERRQ(ierr);
1248d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1249d0c080abSJoseph Pusztay }
1250d0c080abSJoseph Pusztay 
1251d0c080abSJoseph Pusztay PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
1252d0c080abSJoseph Pusztay {
1253d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
1254d0c080abSJoseph Pusztay   PetscReal      x   = ptime,y;
1255d0c080abSJoseph Pusztay   PetscErrorCode ierr;
1256d0c080abSJoseph Pusztay   PetscInt       its;
1257d0c080abSJoseph Pusztay 
1258d0c080abSJoseph Pusztay   PetscFunctionBegin;
1259d0c080abSJoseph Pusztay   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1260d0c080abSJoseph Pusztay   if (!n) {
1261d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1262d0c080abSJoseph Pusztay     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
1263d0c080abSJoseph Pusztay     ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr);
1264d0c080abSJoseph Pusztay     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
1265d0c080abSJoseph Pusztay     ctx->snes_its = 0;
1266d0c080abSJoseph Pusztay   }
1267d0c080abSJoseph Pusztay   ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr);
1268d0c080abSJoseph Pusztay   y    = its - ctx->snes_its;
1269d0c080abSJoseph Pusztay   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
1270d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
1271d0c080abSJoseph Pusztay     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
1272d0c080abSJoseph Pusztay     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
1273d0c080abSJoseph Pusztay   }
1274d0c080abSJoseph Pusztay   ctx->snes_its = its;
1275d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1276d0c080abSJoseph Pusztay }
1277d0c080abSJoseph Pusztay 
1278d0c080abSJoseph Pusztay PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
1279d0c080abSJoseph Pusztay {
1280d0c080abSJoseph Pusztay   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
1281d0c080abSJoseph Pusztay   PetscReal      x   = ptime,y;
1282d0c080abSJoseph Pusztay   PetscErrorCode ierr;
1283d0c080abSJoseph Pusztay   PetscInt       its;
1284d0c080abSJoseph Pusztay 
1285d0c080abSJoseph Pusztay   PetscFunctionBegin;
1286d0c080abSJoseph Pusztay   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
1287d0c080abSJoseph Pusztay   if (!n) {
1288d0c080abSJoseph Pusztay     PetscDrawAxis axis;
1289d0c080abSJoseph Pusztay     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
1290d0c080abSJoseph Pusztay     ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr);
1291d0c080abSJoseph Pusztay     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
1292d0c080abSJoseph Pusztay     ctx->ksp_its = 0;
1293d0c080abSJoseph Pusztay   }
1294d0c080abSJoseph Pusztay   ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr);
1295d0c080abSJoseph Pusztay   y    = its - ctx->ksp_its;
1296d0c080abSJoseph Pusztay   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
1297d0c080abSJoseph Pusztay   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
1298d0c080abSJoseph Pusztay     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
1299d0c080abSJoseph Pusztay     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
1300d0c080abSJoseph Pusztay   }
1301d0c080abSJoseph Pusztay   ctx->ksp_its = its;
1302d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1303d0c080abSJoseph Pusztay }
1304d0c080abSJoseph Pusztay 
1305d0c080abSJoseph Pusztay /*@C
1306d0c080abSJoseph Pusztay    TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope()
1307d0c080abSJoseph Pusztay 
1308d0c080abSJoseph Pusztay    Collective on TS
1309d0c080abSJoseph Pusztay 
1310d0c080abSJoseph Pusztay    Input Parameters:
1311d0c080abSJoseph Pusztay .  ts  - the ODE solver object
1312d0c080abSJoseph Pusztay 
1313d0c080abSJoseph Pusztay    Output Parameter:
1314d0c080abSJoseph Pusztay .  ctx - the context
1315d0c080abSJoseph Pusztay 
1316d0c080abSJoseph Pusztay    Level: intermediate
1317d0c080abSJoseph Pusztay 
1318d0c080abSJoseph Pusztay .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError()
1319d0c080abSJoseph Pusztay 
1320d0c080abSJoseph Pusztay @*/
1321d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx)
1322d0c080abSJoseph Pusztay {
1323d0c080abSJoseph Pusztay   PetscErrorCode ierr;
1324d0c080abSJoseph Pusztay 
1325d0c080abSJoseph Pusztay   PetscFunctionBegin;
1326d0c080abSJoseph Pusztay   ierr = PetscNew(ctx);CHKERRQ(ierr);
1327d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1328d0c080abSJoseph Pusztay }
1329d0c080abSJoseph Pusztay 
1330d0c080abSJoseph Pusztay /*@C
1331d0c080abSJoseph Pusztay    TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution
1332d0c080abSJoseph Pusztay 
1333d0c080abSJoseph Pusztay    Collective on TS
1334d0c080abSJoseph Pusztay 
1335d0c080abSJoseph Pusztay    Input Parameters:
1336d0c080abSJoseph Pusztay +  ts - the TS context
1337d0c080abSJoseph Pusztay .  step - current time-step
1338d0c080abSJoseph Pusztay .  ptime - current time
1339d0c080abSJoseph Pusztay .  u  - current solution
1340d0c080abSJoseph Pusztay -  dctx - the envelope context
1341d0c080abSJoseph Pusztay 
1342d0c080abSJoseph Pusztay    Options Database:
1343d0c080abSJoseph Pusztay .  -ts_monitor_envelope
1344d0c080abSJoseph Pusztay 
1345d0c080abSJoseph Pusztay    Level: intermediate
1346d0c080abSJoseph Pusztay 
1347d0c080abSJoseph Pusztay    Notes:
1348d0c080abSJoseph Pusztay     after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope
1349d0c080abSJoseph Pusztay 
1350d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate()
1351d0c080abSJoseph Pusztay @*/
1352d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
1353d0c080abSJoseph Pusztay {
1354d0c080abSJoseph Pusztay   PetscErrorCode       ierr;
1355d0c080abSJoseph Pusztay   TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx;
1356d0c080abSJoseph Pusztay 
1357d0c080abSJoseph Pusztay   PetscFunctionBegin;
1358d0c080abSJoseph Pusztay   if (!ctx->max) {
1359d0c080abSJoseph Pusztay     ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr);
1360d0c080abSJoseph Pusztay     ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr);
1361d0c080abSJoseph Pusztay     ierr = VecCopy(u,ctx->max);CHKERRQ(ierr);
1362d0c080abSJoseph Pusztay     ierr = VecCopy(u,ctx->min);CHKERRQ(ierr);
1363d0c080abSJoseph Pusztay   } else {
1364d0c080abSJoseph Pusztay     ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr);
1365d0c080abSJoseph Pusztay     ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr);
1366d0c080abSJoseph Pusztay   }
1367d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1368d0c080abSJoseph Pusztay }
1369d0c080abSJoseph Pusztay 
1370d0c080abSJoseph Pusztay /*@C
1371d0c080abSJoseph Pusztay    TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution
1372d0c080abSJoseph Pusztay 
1373d0c080abSJoseph Pusztay    Collective on TS
1374d0c080abSJoseph Pusztay 
1375d0c080abSJoseph Pusztay    Input Parameter:
1376d0c080abSJoseph Pusztay .  ts - the TS context
1377d0c080abSJoseph Pusztay 
1378*d8d19677SJose E. Roman    Output Parameters:
1379d0c080abSJoseph Pusztay +  max - the maximum values
1380d0c080abSJoseph Pusztay -  min - the minimum values
1381d0c080abSJoseph Pusztay 
1382d0c080abSJoseph Pusztay    Notes:
1383d0c080abSJoseph Pusztay     If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored
1384d0c080abSJoseph Pusztay 
1385d0c080abSJoseph Pusztay    Level: intermediate
1386d0c080abSJoseph Pusztay 
1387d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
1388d0c080abSJoseph Pusztay @*/
1389d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min)
1390d0c080abSJoseph Pusztay {
1391d0c080abSJoseph Pusztay   PetscInt i;
1392d0c080abSJoseph Pusztay 
1393d0c080abSJoseph Pusztay   PetscFunctionBegin;
1394d0c080abSJoseph Pusztay   if (max) *max = NULL;
1395d0c080abSJoseph Pusztay   if (min) *min = NULL;
1396d0c080abSJoseph Pusztay   for (i=0; i<ts->numbermonitors; i++) {
1397d0c080abSJoseph Pusztay     if (ts->monitor[i] == TSMonitorEnvelope) {
1398d0c080abSJoseph Pusztay       TSMonitorEnvelopeCtx  ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i];
1399d0c080abSJoseph Pusztay       if (max) *max = ctx->max;
1400d0c080abSJoseph Pusztay       if (min) *min = ctx->min;
1401d0c080abSJoseph Pusztay       break;
1402d0c080abSJoseph Pusztay     }
1403d0c080abSJoseph Pusztay   }
1404d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1405d0c080abSJoseph Pusztay }
1406d0c080abSJoseph Pusztay 
1407d0c080abSJoseph Pusztay /*@C
1408d0c080abSJoseph Pusztay    TSMonitorEnvelopeCtxDestroy - Destroys a context that was created  with TSMonitorEnvelopeCtxCreate().
1409d0c080abSJoseph Pusztay 
1410d0c080abSJoseph Pusztay    Collective on TSMonitorEnvelopeCtx
1411d0c080abSJoseph Pusztay 
1412d0c080abSJoseph Pusztay    Input Parameter:
1413d0c080abSJoseph Pusztay .  ctx - the monitor context
1414d0c080abSJoseph Pusztay 
1415d0c080abSJoseph Pusztay    Level: intermediate
1416d0c080abSJoseph Pusztay 
1417d0c080abSJoseph Pusztay .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep()
1418d0c080abSJoseph Pusztay @*/
1419d0c080abSJoseph Pusztay PetscErrorCode  TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx)
1420d0c080abSJoseph Pusztay {
1421d0c080abSJoseph Pusztay   PetscErrorCode ierr;
1422d0c080abSJoseph Pusztay 
1423d0c080abSJoseph Pusztay   PetscFunctionBegin;
1424d0c080abSJoseph Pusztay   ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr);
1425d0c080abSJoseph Pusztay   ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr);
1426d0c080abSJoseph Pusztay   ierr = PetscFree(*ctx);CHKERRQ(ierr);
1427d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1428d0c080abSJoseph Pusztay }
1429d0c080abSJoseph Pusztay 
1430d0c080abSJoseph Pusztay /*@C
1431d0c080abSJoseph Pusztay   TSDMSwarmMonitorMoments - Monitors the first three moments of a DMSarm being evolved by the TS
1432d0c080abSJoseph Pusztay 
1433d0c080abSJoseph Pusztay   Not collective
1434d0c080abSJoseph Pusztay 
1435d0c080abSJoseph Pusztay   Input Parameters:
1436d0c080abSJoseph Pusztay + ts   - the TS context
1437d0c080abSJoseph Pusztay . step - current timestep
1438d0c080abSJoseph Pusztay . t    - current time
1439d0c080abSJoseph Pusztay . u    - current solution
1440d0c080abSJoseph Pusztay - ctx  - not used
1441d0c080abSJoseph Pusztay 
1442d0c080abSJoseph Pusztay   Options Database:
1443d0c080abSJoseph Pusztay . -ts_dmswarm_monitor_moments
1444d0c080abSJoseph Pusztay 
1445d0c080abSJoseph Pusztay   Level: intermediate
1446d0c080abSJoseph Pusztay 
1447d0c080abSJoseph Pusztay   Notes:
1448d0c080abSJoseph Pusztay   This requires a DMSwarm be attached to the TS.
1449d0c080abSJoseph Pusztay 
1450d0c080abSJoseph Pusztay .seealso: TSMonitorSet(), TSMonitorDefault(), DMSWARM
1451d0c080abSJoseph Pusztay @*/
1452d0c080abSJoseph Pusztay PetscErrorCode TSDMSwarmMonitorMoments(TS ts, PetscInt step, PetscReal t, Vec U, PetscViewerAndFormat *vf)
1453d0c080abSJoseph Pusztay {
1454d0c080abSJoseph Pusztay   DM                 sw;
1455d0c080abSJoseph Pusztay   const PetscScalar *u;
1456d0c080abSJoseph Pusztay   PetscReal          m = 1.0, totE = 0., totMom[3] = {0., 0., 0.};
1457d0c080abSJoseph Pusztay   PetscInt           dim, d, Np, p;
1458d0c080abSJoseph Pusztay   MPI_Comm           comm;
1459d0c080abSJoseph Pusztay   PetscErrorCode     ierr;
1460d0c080abSJoseph Pusztay 
1461d0c080abSJoseph Pusztay   PetscFunctionBeginUser;
1462d0c080abSJoseph Pusztay   ierr = TSGetDM(ts, &sw);CHKERRQ(ierr);
1463d0c080abSJoseph Pusztay   if (!sw || step%ts->monitorFrequency != 0) PetscFunctionReturn(0);
1464d0c080abSJoseph Pusztay   ierr = PetscObjectGetComm((PetscObject) ts, &comm);CHKERRQ(ierr);
1465d0c080abSJoseph Pusztay   ierr = DMGetDimension(sw, &dim);CHKERRQ(ierr);
1466d0c080abSJoseph Pusztay   ierr = VecGetLocalSize(U, &Np);CHKERRQ(ierr);
1467d0c080abSJoseph Pusztay   Np  /= dim;
1468d0c080abSJoseph Pusztay   ierr = VecGetArrayRead(U, &u);CHKERRQ(ierr);
1469d0c080abSJoseph Pusztay   for (p = 0; p < Np; ++p) {
1470d0c080abSJoseph Pusztay     for (d = 0; d < dim; ++d) {
1471d0c080abSJoseph Pusztay       totE      += PetscRealPart(u[p*dim+d]*u[p*dim+d]);
1472d0c080abSJoseph Pusztay       totMom[d] += PetscRealPart(u[p*dim+d]);
1473d0c080abSJoseph Pusztay     }
1474d0c080abSJoseph Pusztay   }
1475d0c080abSJoseph Pusztay   ierr = VecRestoreArrayRead(U, &u);CHKERRQ(ierr);
1476d0c080abSJoseph Pusztay   for (d = 0; d < dim; ++d) totMom[d] *= m;
1477d0c080abSJoseph Pusztay   totE *= 0.5*m;
1478d0c080abSJoseph Pusztay   ierr = PetscPrintf(comm, "Step %4D Total Energy: %10.8lf", step, (double) totE);CHKERRQ(ierr);
1479d0c080abSJoseph Pusztay   for (d = 0; d < dim; ++d) {ierr = PetscPrintf(comm, "    Total Momentum %c: %10.8lf", 'x'+d, (double) totMom[d]);CHKERRQ(ierr);}
1480d0c080abSJoseph Pusztay   ierr = PetscPrintf(comm, "\n");CHKERRQ(ierr);
1481d0c080abSJoseph Pusztay   PetscFunctionReturn(0);
1482d0c080abSJoseph Pusztay }
1483