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