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