xref: /petsc/src/ts/interface/ts.c (revision 2a34c10ce821da49e32a0f08e4bd95dc44083eea)
1 
2 #include <petsc-private/tsimpl.h>        /*I "petscts.h"  I*/
3 #include <petscdmshell.h>
4 
5 /* Logging support */
6 PetscClassId  TS_CLASSID, DMTS_CLASSID;
7 PetscLogEvent  TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval;
8 
9 #undef __FUNCT__
10 #define __FUNCT__ "TSSetTypeFromOptions"
11 /*
12   TSSetTypeFromOptions - Sets the type of ts from user options.
13 
14   Collective on TS
15 
16   Input Parameter:
17 . ts - The ts
18 
19   Level: intermediate
20 
21 .keywords: TS, set, options, database, type
22 .seealso: TSSetFromOptions(), TSSetType()
23 */
24 static PetscErrorCode TSSetTypeFromOptions(TS ts)
25 {
26   PetscBool      opt;
27   const char     *defaultType;
28   char           typeName[256];
29   PetscErrorCode ierr;
30 
31   PetscFunctionBegin;
32   if (((PetscObject)ts)->type_name) {
33     defaultType = ((PetscObject)ts)->type_name;
34   } else {
35     defaultType = TSEULER;
36   }
37 
38   if (!TSRegisterAllCalled) {ierr = TSRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
39   ierr = PetscOptionsList("-ts_type", "TS method"," TSSetType", TSList, defaultType, typeName, 256, &opt);CHKERRQ(ierr);
40   if (opt) {
41     ierr = TSSetType(ts, typeName);CHKERRQ(ierr);
42   } else {
43     ierr = TSSetType(ts, defaultType);CHKERRQ(ierr);
44   }
45   PetscFunctionReturn(0);
46 }
47 
48 #undef __FUNCT__
49 #define __FUNCT__ "TSSetFromOptions"
50 /*@
51    TSSetFromOptions - Sets various TS parameters from user options.
52 
53    Collective on TS
54 
55    Input Parameter:
56 .  ts - the TS context obtained from TSCreate()
57 
58    Options Database Keys:
59 +  -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSGL, TSSSP
60 .  -ts_max_steps maxsteps - maximum number of time-steps to take
61 .  -ts_final_time time - maximum time to compute to
62 .  -ts_dt dt - initial time step
63 .  -ts_monitor - print information at each timestep
64 .  -ts_monitor_lg_timestep - Monitor timestep size graphically
65 .  -ts_monitor_lg_solution - Monitor solution graphically
66 .  -ts_monitor_lg_error - Monitor error graphically
67 .  -ts_monitor_lg_snes_iterations - Monitor number nonlinear iterations for each timestep graphically
68 .  -ts_monitor_lg_ksp_iterations - Monitor number nonlinear iterations for each timestep graphically
69 .  -ts_monitor_sp_eig - Monitor eigenvalues of linearized operator graphically
70 .  -ts_monitor_draw_solution - Monitor solution graphically
71 .  -ts_monitor_draw_solution - Monitor solution graphically
72 .  -ts_monitor_draw_error - Monitor error graphically
73 .  -ts_monitor_draw_solution_binary <filename> - Save each solution to a binary file
74 -  -ts_monitor_draw_solution_vtk <filename.vts> - Save each time step to a binary file, use filename-%%03D.vts
75 
76    Level: beginner
77 
78 .keywords: TS, timestep, set, options, database
79 
80 .seealso: TSGetType()
81 @*/
82 PetscErrorCode  TSSetFromOptions(TS ts)
83 {
84   PetscBool      opt,flg;
85   PetscErrorCode ierr;
86   PetscViewer    monviewer;
87   char           monfilename[PETSC_MAX_PATH_LEN];
88   SNES           snes;
89   TSAdapt        adapt;
90   PetscReal      time_step;
91 
92   PetscFunctionBegin;
93   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
94   ierr = PetscObjectOptionsBegin((PetscObject)ts);CHKERRQ(ierr);
95     /* Handle TS type options */
96     ierr = TSSetTypeFromOptions(ts);CHKERRQ(ierr);
97 
98     /* Handle generic TS options */
99     ierr = PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetDuration",ts->max_steps,&ts->max_steps,PETSC_NULL);CHKERRQ(ierr);
100     ierr = PetscOptionsReal("-ts_final_time","Time to run to","TSSetDuration",ts->max_time,&ts->max_time,PETSC_NULL);CHKERRQ(ierr);
101     ierr = PetscOptionsReal("-ts_init_time","Initial time","TSSetTime",ts->ptime,&ts->ptime,PETSC_NULL);CHKERRQ(ierr);
102     ierr = PetscOptionsReal("-ts_dt","Initial time step","TSSetTimeStep",ts->time_step,&time_step,&flg);CHKERRQ(ierr);
103     if (flg) {
104       ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr);
105     }
106     opt = ts->exact_final_time == PETSC_DECIDE ? PETSC_FALSE : (PetscBool)ts->exact_final_time;
107     ierr = PetscOptionsBool("-ts_exact_final_time","Interpolate output to stop exactly at the final time","TSSetExactFinalTime",opt,&opt,&flg);CHKERRQ(ierr);
108     if (flg) {ierr = TSSetExactFinalTime(ts,opt);CHKERRQ(ierr);}
109     ierr = PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","TSSetMaxSNESFailures",ts->max_snes_failures,&ts->max_snes_failures,PETSC_NULL);CHKERRQ(ierr);
110     ierr = PetscOptionsInt("-ts_max_reject","Maximum number of step rejections before step fails","TSSetMaxStepRejections",ts->max_reject,&ts->max_reject,PETSC_NULL);CHKERRQ(ierr);
111     ierr = PetscOptionsBool("-ts_error_if_step_fails","Error if no step succeeds","TSSetErrorIfStepFails",ts->errorifstepfailed,&ts->errorifstepfailed,PETSC_NULL);CHKERRQ(ierr);
112     ierr = PetscOptionsReal("-ts_rtol","Relative tolerance for local truncation error","TSSetTolerances",ts->rtol,&ts->rtol,PETSC_NULL);CHKERRQ(ierr);
113     ierr = PetscOptionsReal("-ts_atol","Absolute tolerance for local truncation error","TSSetTolerances",ts->atol,&ts->atol,PETSC_NULL);CHKERRQ(ierr);
114 
115     /* Monitor options */
116     ierr = PetscOptionsString("-ts_monitor","Monitor timestep size","TSMonitorDefault","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
117     if (flg) {
118       ierr = PetscViewerASCIIOpen(((PetscObject)ts)->comm,monfilename,&monviewer);CHKERRQ(ierr);
119       ierr = TSMonitorSet(ts,TSMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
120     }
121     ierr = PetscOptionsString("-ts_monitor_python","Use Python function","TSMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
122     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ts,monfilename);CHKERRQ(ierr);}
123 
124     ierr = PetscOptionsName("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",&opt);CHKERRQ(ierr);
125     if (opt) {
126       TSMonitorLGCtx ctx;
127       PetscInt       howoften = 1;
128 
129       ierr = PetscOptionsInt("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",howoften,&howoften,PETSC_NULL);CHKERRQ(ierr);
130       ierr = TSMonitorLGCtxCreate(((PetscObject)ts)->comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr);
131       ierr = TSMonitorSet(ts,TSMonitorLGTimeStep,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
132     }
133     ierr = PetscOptionsName("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",&opt);CHKERRQ(ierr);
134     if (opt) {
135       TSMonitorLGCtx ctx;
136       PetscInt       howoften = 1;
137 
138       ierr = PetscOptionsInt("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",howoften,&howoften,PETSC_NULL);CHKERRQ(ierr);
139       ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);
140       ierr = TSMonitorSet(ts,TSMonitorLGSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
141     }
142     ierr = PetscOptionsName("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",&opt);CHKERRQ(ierr);
143     if (opt) {
144       TSMonitorLGCtx ctx;
145       PetscInt       howoften = 1;
146 
147       ierr = PetscOptionsInt("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",howoften,&howoften,PETSC_NULL);CHKERRQ(ierr);
148       ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);
149       ierr = TSMonitorSet(ts,TSMonitorLGError,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
150     }
151     ierr = PetscOptionsName("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",&opt);CHKERRQ(ierr);
152     if (opt) {
153       TSMonitorLGCtx ctx;
154       PetscInt       howoften = 1;
155 
156       ierr = PetscOptionsInt("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",howoften,&howoften,PETSC_NULL);CHKERRQ(ierr);
157       ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);
158       ierr = TSMonitorSet(ts,TSMonitorLGSNESIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
159     }
160     ierr = PetscOptionsName("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",&opt);CHKERRQ(ierr);
161     if (opt) {
162       TSMonitorLGCtx ctx;
163       PetscInt       howoften = 1;
164 
165       ierr = PetscOptionsInt("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",howoften,&howoften,PETSC_NULL);CHKERRQ(ierr);
166       ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);
167       ierr = TSMonitorSet(ts,TSMonitorLGKSPIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
168     }
169     ierr = PetscOptionsName("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",&opt);CHKERRQ(ierr);
170     if (opt) {
171       TSMonitorSPEigCtx ctx;
172       PetscInt          howoften = 1;
173 
174       ierr = PetscOptionsInt("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",howoften,&howoften,PETSC_NULL);CHKERRQ(ierr);
175       ierr = TSMonitorSPEigCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);
176       ierr = TSMonitorSet(ts,TSMonitorSPEig,ctx,(PetscErrorCode (*)(void**))TSMonitorSPEigCtxDestroy);CHKERRQ(ierr);
177     }
178     opt  = PETSC_FALSE;
179     ierr = PetscOptionsName("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",&opt);CHKERRQ(ierr);
180     if (opt) {
181       TSMonitorDrawCtx ctx;
182       PetscInt         howoften = 1;
183 
184       ierr = PetscOptionsInt("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",howoften,&howoften,PETSC_NULL);CHKERRQ(ierr);
185       ierr = TSMonitorDrawCtxCreate(((PetscObject)ts)->comm,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);
186       ierr = TSMonitorSet(ts,TSMonitorDrawSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr);
187     }
188     opt  = PETSC_FALSE;
189     ierr = PetscOptionsName("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",&opt);CHKERRQ(ierr);
190     if (opt) {
191       TSMonitorDrawCtx ctx;
192       PetscInt         howoften = 1;
193 
194       ierr = PetscOptionsInt("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",howoften,&howoften,PETSC_NULL);CHKERRQ(ierr);
195       ierr = TSMonitorDrawCtxCreate(((PetscObject)ts)->comm,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);
196       ierr = TSMonitorSet(ts,TSMonitorDrawError,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr);
197     }
198     opt  = PETSC_FALSE;
199     ierr = PetscOptionsString("-ts_monitor_draw_solution_binary","Save each solution to a binary file","TSMonitorSolutionBinary",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
200     if (flg) {
201       PetscViewer ctx;
202       if (monfilename[0]) {
203         ierr = PetscViewerBinaryOpen(((PetscObject)ts)->comm,monfilename,FILE_MODE_WRITE,&ctx);CHKERRQ(ierr);
204       } else {
205         ctx = PETSC_VIEWER_BINARY_(((PetscObject)ts)->comm);
206       }
207       ierr = TSMonitorSet(ts,TSMonitorSolutionBinary,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
208     }
209     opt  = PETSC_FALSE;
210     ierr = PetscOptionsString("-ts_monitor_draw_solution_vtk","Save each time step to a binary file, use filename-%%03D.vts","TSMonitorSolutionVTK",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
211     if (flg) {
212       const char *ptr,*ptr2;
213       char *filetemplate;
214       if (!monfilename[0]) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"-ts_monitor_draw_solution_vtk requires a file template, e.g. filename-%%03D.vts");
215       /* Do some cursory validation of the input. */
216       ierr = PetscStrstr(monfilename,"%",(char**)&ptr);CHKERRQ(ierr);
217       if (!ptr) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"-ts_monitor_draw_solution_vtk requires a file template, e.g. filename-%%03D.vts");
218       for (ptr++ ; ptr && *ptr; ptr++) {
219         ierr = PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);CHKERRQ(ierr);
220         if (!ptr2 && (*ptr < '0' || '9' < *ptr)) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Invalid file template argument to -ts_monitor_draw_solution_vtk, should look like filename-%%03D.vts");
221         if (ptr2) break;
222       }
223       ierr = PetscStrallocpy(monfilename,&filetemplate);CHKERRQ(ierr);
224       ierr = TSMonitorSet(ts,TSMonitorSolutionVTK,filetemplate,(PetscErrorCode (*)(void**))TSMonitorSolutionVTKDestroy);CHKERRQ(ierr);
225     }
226 
227     ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr);
228     ierr = TSAdaptSetFromOptions(adapt);CHKERRQ(ierr);
229 
230     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
231     if (ts->problem_type == TS_LINEAR) {ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);}
232 
233     /* Handle specific TS options */
234     if (ts->ops->setfromoptions) {
235       ierr = (*ts->ops->setfromoptions)(ts);CHKERRQ(ierr);
236     }
237 
238     /* process any options handlers added with PetscObjectAddOptionsHandler() */
239     ierr = PetscObjectProcessOptionsHandlers((PetscObject)ts);CHKERRQ(ierr);
240   ierr = PetscOptionsEnd();CHKERRQ(ierr);
241   PetscFunctionReturn(0);
242 }
243 
244 #undef __FUNCT__
245 #undef __FUNCT__
246 #define __FUNCT__ "TSComputeRHSJacobian"
247 /*@
248    TSComputeRHSJacobian - Computes the Jacobian matrix that has been
249       set with TSSetRHSJacobian().
250 
251    Collective on TS and Vec
252 
253    Input Parameters:
254 +  ts - the TS context
255 .  t - current timestep
256 -  U - input vector
257 
258    Output Parameters:
259 +  A - Jacobian matrix
260 .  B - optional preconditioning matrix
261 -  flag - flag indicating matrix structure
262 
263    Notes:
264    Most users should not need to explicitly call this routine, as it
265    is used internally within the nonlinear solvers.
266 
267    See KSPSetOperators() for important information about setting the
268    flag parameter.
269 
270    Level: developer
271 
272 .keywords: SNES, compute, Jacobian, matrix
273 
274 .seealso:  TSSetRHSJacobian(), KSPSetOperators()
275 @*/
276 PetscErrorCode  TSComputeRHSJacobian(TS ts,PetscReal t,Vec U,Mat *A,Mat *B,MatStructure *flg)
277 {
278   PetscErrorCode ierr;
279   PetscInt       Ustate;
280   DM             dm;
281   DMTS           tsdm;
282   TSRHSJacobian  rhsjacobianfunc;
283   void           *ctx;
284   TSIJacobian    ijacobianfunc;
285 
286   PetscFunctionBegin;
287   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
288   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
289   PetscCheckSameComm(ts,1,U,3);
290   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
291   ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr);
292   ierr = DMTSGetRHSJacobian(dm,&rhsjacobianfunc,&ctx);CHKERRQ(ierr);
293   ierr = DMTSGetIJacobian(dm,&ijacobianfunc,PETSC_NULL);CHKERRQ(ierr);
294   ierr = PetscObjectStateQuery((PetscObject)U,&Ustate);CHKERRQ(ierr);
295   if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.X == U && ts->rhsjacobian.Xstate == Ustate))) {
296     *flg = ts->rhsjacobian.mstructure;
297     PetscFunctionReturn(0);
298   }
299 
300   if (!rhsjacobianfunc && !ijacobianfunc) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()");
301 
302   if (rhsjacobianfunc) {
303     ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr);
304     *flg = DIFFERENT_NONZERO_PATTERN;
305     PetscStackPush("TS user Jacobian function");
306     ierr = (*rhsjacobianfunc)(ts,t,U,A,B,flg,ctx);CHKERRQ(ierr);
307     PetscStackPop;
308     ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr);
309     /* make sure user returned a correct Jacobian and preconditioner */
310     PetscValidHeaderSpecific(*A,MAT_CLASSID,4);
311     PetscValidHeaderSpecific(*B,MAT_CLASSID,5);
312   } else {
313     ierr = MatZeroEntries(*A);CHKERRQ(ierr);
314     if (*A != *B) {ierr = MatZeroEntries(*B);CHKERRQ(ierr);}
315     *flg = SAME_NONZERO_PATTERN;
316   }
317   ts->rhsjacobian.time = t;
318   ts->rhsjacobian.X = U;
319   ierr = PetscObjectStateQuery((PetscObject)U,&ts->rhsjacobian.Xstate);CHKERRQ(ierr);
320   ts->rhsjacobian.mstructure = *flg;
321   PetscFunctionReturn(0);
322 }
323 
324 #undef __FUNCT__
325 #define __FUNCT__ "TSComputeRHSFunction"
326 /*@
327    TSComputeRHSFunction - Evaluates the right-hand-side function.
328 
329    Collective on TS and Vec
330 
331    Input Parameters:
332 +  ts - the TS context
333 .  t - current time
334 -  U - state vector
335 
336    Output Parameter:
337 .  y - right hand side
338 
339    Note:
340    Most users should not need to explicitly call this routine, as it
341    is used internally within the nonlinear solvers.
342 
343    Level: developer
344 
345 .keywords: TS, compute
346 
347 .seealso: TSSetRHSFunction(), TSComputeIFunction()
348 @*/
349 PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec U,Vec y)
350 {
351   PetscErrorCode ierr;
352   TSRHSFunction  rhsfunction;
353   TSIFunction    ifunction;
354   void           *ctx;
355   DM             dm;
356 
357   PetscFunctionBegin;
358   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
359   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
360   PetscValidHeaderSpecific(y,VEC_CLASSID,4);
361   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
362   ierr = DMTSGetRHSFunction(dm,&rhsfunction,&ctx);CHKERRQ(ierr);
363   ierr = DMTSGetIFunction(dm,&ifunction,PETSC_NULL);CHKERRQ(ierr);
364 
365   if (!rhsfunction && !ifunction) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()");
366 
367   ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr);
368   if (rhsfunction) {
369     PetscStackPush("TS user right-hand-side function");
370     ierr = (*rhsfunction)(ts,t,U,y,ctx);CHKERRQ(ierr);
371     PetscStackPop;
372   } else {
373     ierr = VecZeroEntries(y);CHKERRQ(ierr);
374   }
375 
376   ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr);
377   PetscFunctionReturn(0);
378 }
379 
380 #undef __FUNCT__
381 #define __FUNCT__ "TSComputeSolutionFunction"
382 /*@
383    TSComputeSolutionFunction - Evaluates the solution function.
384 
385    Collective on TS and Vec
386 
387    Input Parameters:
388 +  ts - the TS context
389 -  t - current time
390 
391    Output Parameter:
392 .  U - the solution
393 
394    Note:
395    Most users should not need to explicitly call this routine, as it
396    is used internally within the nonlinear solvers.
397 
398    Level: developer
399 
400 .keywords: TS, compute
401 
402 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction()
403 @*/
404 PetscErrorCode TSComputeSolutionFunction(TS ts,PetscReal t,Vec U)
405 {
406   PetscErrorCode     ierr;
407   TSSolutionFunction solutionfunction;
408   void               *ctx;
409   DM                 dm;
410 
411   PetscFunctionBegin;
412   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
413   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
414   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
415   ierr = DMTSGetSolutionFunction(dm,&solutionfunction,&ctx);CHKERRQ(ierr);
416 
417   if (solutionfunction) {
418     PetscStackPush("TS user right-hand-side function");
419     ierr = (*solutionfunction)(ts,t,U,ctx);CHKERRQ(ierr);
420     PetscStackPop;
421   }
422   PetscFunctionReturn(0);
423 }
424 
425 #undef __FUNCT__
426 #define __FUNCT__ "TSGetRHSVec_Private"
427 static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs)
428 {
429   Vec            F;
430   PetscErrorCode ierr;
431 
432   PetscFunctionBegin;
433   *Frhs = PETSC_NULL;
434   ierr = TSGetIFunction(ts,&F,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
435   if (!ts->Frhs) {
436     ierr = VecDuplicate(F,&ts->Frhs);CHKERRQ(ierr);
437   }
438   *Frhs = ts->Frhs;
439   PetscFunctionReturn(0);
440 }
441 
442 #undef __FUNCT__
443 #define __FUNCT__ "TSGetRHSMats_Private"
444 static PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs)
445 {
446   Mat            A,B;
447   PetscErrorCode ierr;
448 
449   PetscFunctionBegin;
450   ierr = TSGetIJacobian(ts,&A,&B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
451   if (Arhs) {
452     if (!ts->Arhs) {
453       ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs);CHKERRQ(ierr);
454     }
455     *Arhs = ts->Arhs;
456   }
457   if (Brhs) {
458     if (!ts->Brhs) {
459       ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs);CHKERRQ(ierr);
460     }
461     *Brhs = ts->Brhs;
462   }
463   PetscFunctionReturn(0);
464 }
465 
466 #undef __FUNCT__
467 #define __FUNCT__ "TSComputeIFunction"
468 /*@
469    TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,U,Udot)=0
470 
471    Collective on TS and Vec
472 
473    Input Parameters:
474 +  ts - the TS context
475 .  t - current time
476 .  U - state vector
477 .  Udot - time derivative of state vector
478 -  imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate
479 
480    Output Parameter:
481 .  Y - right hand side
482 
483    Note:
484    Most users should not need to explicitly call this routine, as it
485    is used internally within the nonlinear solvers.
486 
487    If the user did did not write their equations in implicit form, this
488    function recasts them in implicit form.
489 
490    Level: developer
491 
492 .keywords: TS, compute
493 
494 .seealso: TSSetIFunction(), TSComputeRHSFunction()
495 @*/
496 PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec U,Vec Udot,Vec Y,PetscBool imex)
497 {
498   PetscErrorCode ierr;
499   TSIFunction    ifunction;
500   TSRHSFunction  rhsfunction;
501   void           *ctx;
502   DM             dm;
503 
504   PetscFunctionBegin;
505   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
506   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
507   PetscValidHeaderSpecific(Udot,VEC_CLASSID,4);
508   PetscValidHeaderSpecific(Y,VEC_CLASSID,5);
509 
510   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
511   ierr = DMTSGetIFunction(dm,&ifunction,&ctx);CHKERRQ(ierr);
512   ierr = DMTSGetRHSFunction(dm,&rhsfunction,PETSC_NULL);CHKERRQ(ierr);
513 
514   if (!rhsfunction && !ifunction) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()");
515 
516   ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr);
517   if (ifunction) {
518     PetscStackPush("TS user implicit function");
519     ierr = (*ifunction)(ts,t,U,Udot,Y,ctx);CHKERRQ(ierr);
520     PetscStackPop;
521   }
522   if (imex) {
523     if (!ifunction) {
524       ierr = VecCopy(Udot,Y);CHKERRQ(ierr);
525     }
526   } else if (rhsfunction) {
527     if (ifunction) {
528       Vec Frhs;
529       ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr);
530       ierr = TSComputeRHSFunction(ts,t,U,Frhs);CHKERRQ(ierr);
531       ierr = VecAXPY(Y,-1,Frhs);CHKERRQ(ierr);
532     } else {
533       ierr = TSComputeRHSFunction(ts,t,U,Y);CHKERRQ(ierr);
534       ierr = VecAYPX(Y,-1,Udot);CHKERRQ(ierr);
535     }
536   }
537   ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr);
538   PetscFunctionReturn(0);
539 }
540 
541 #undef __FUNCT__
542 #define __FUNCT__ "TSComputeIJacobian"
543 /*@
544    TSComputeIJacobian - Evaluates the Jacobian of the DAE
545 
546    Collective on TS and Vec
547 
548    Input
549       Input Parameters:
550 +  ts - the TS context
551 .  t - current timestep
552 .  U - state vector
553 .  Udot - time derivative of state vector
554 .  shift - shift to apply, see note below
555 -  imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate
556 
557    Output Parameters:
558 +  A - Jacobian matrix
559 .  B - optional preconditioning matrix
560 -  flag - flag indicating matrix structure
561 
562    Notes:
563    If F(t,U,Udot)=0 is the DAE, the required Jacobian is
564 
565    dF/dU + shift*dF/dUdot
566 
567    Most users should not need to explicitly call this routine, as it
568    is used internally within the nonlinear solvers.
569 
570    Level: developer
571 
572 .keywords: TS, compute, Jacobian, matrix
573 
574 .seealso:  TSSetIJacobian()
575 @*/
576 PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,PetscBool imex)
577 {
578   PetscInt       Ustate, Udotstate;
579   PetscErrorCode ierr;
580   TSIJacobian    ijacobian;
581   TSRHSJacobian  rhsjacobian;
582   DM             dm;
583   void           *ctx;
584 
585   PetscFunctionBegin;
586 
587   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
588   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
589   PetscValidHeaderSpecific(Udot,VEC_CLASSID,4);
590   PetscValidPointer(A,6);
591   PetscValidHeaderSpecific(*A,MAT_CLASSID,6);
592   PetscValidPointer(B,7);
593   PetscValidHeaderSpecific(*B,MAT_CLASSID,7);
594   PetscValidPointer(flg,8);
595 
596   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
597   ierr = DMTSGetIJacobian(dm,&ijacobian,&ctx);CHKERRQ(ierr);
598   ierr = DMTSGetRHSJacobian(dm,&rhsjacobian,PETSC_NULL);CHKERRQ(ierr);
599 
600   ierr = PetscObjectStateQuery((PetscObject)U,&Ustate);CHKERRQ(ierr);
601   ierr = PetscObjectStateQuery((PetscObject)Udot,&Udotstate);CHKERRQ(ierr);
602   if (ts->ijacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->ijacobian.X == U && ts->ijacobian.Xstate == Ustate && ts->ijacobian.Xdot == Udot && ts->ijacobian.Xdotstate == Udotstate && ts->ijacobian.imex == imex))) {
603     *flg = ts->ijacobian.mstructure;
604     ierr = MatScale(*A, shift / ts->ijacobian.shift);CHKERRQ(ierr);
605     PetscFunctionReturn(0);
606   }
607 
608   if (!rhsjacobian && !ijacobian) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()");
609 
610   *flg = SAME_NONZERO_PATTERN;  /* In case we're solving a linear problem in which case it wouldn't get initialized below. */
611   ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr);
612   if (ijacobian) {
613     *flg = DIFFERENT_NONZERO_PATTERN;
614     PetscStackPush("TS user implicit Jacobian");
615     ierr = (*ijacobian)(ts,t,U,Udot,shift,A,B,flg,ctx);CHKERRQ(ierr);
616     PetscStackPop;
617     /* make sure user returned a correct Jacobian and preconditioner */
618     PetscValidHeaderSpecific(*A,MAT_CLASSID,4);
619     PetscValidHeaderSpecific(*B,MAT_CLASSID,5);
620   }
621   if (imex) {
622     if (!ijacobian) {  /* system was written as Udot = G(t,U) */
623       ierr = MatZeroEntries(*A);CHKERRQ(ierr);
624       ierr = MatShift(*A,shift);CHKERRQ(ierr);
625       if (*A != *B) {
626         ierr = MatZeroEntries(*B);CHKERRQ(ierr);
627         ierr = MatShift(*B,shift);CHKERRQ(ierr);
628       }
629       *flg = SAME_PRECONDITIONER;
630     }
631   } else {
632     if (!ijacobian) {
633       ierr = TSComputeRHSJacobian(ts,t,U,A,B,flg);CHKERRQ(ierr);
634       ierr = MatScale(*A,-1);CHKERRQ(ierr);
635       ierr = MatShift(*A,shift);CHKERRQ(ierr);
636       if (*A != *B) {
637         ierr = MatScale(*B,-1);CHKERRQ(ierr);
638         ierr = MatShift(*B,shift);CHKERRQ(ierr);
639       }
640     } else if (rhsjacobian) {
641       Mat Arhs,Brhs;
642       MatStructure axpy,flg2 = DIFFERENT_NONZERO_PATTERN;
643       ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
644       ierr = TSComputeRHSJacobian(ts,t,U,&Arhs,&Brhs,&flg2);CHKERRQ(ierr);
645       axpy = (*flg == flg2) ? SAME_NONZERO_PATTERN : DIFFERENT_NONZERO_PATTERN;
646       ierr = MatAXPY(*A,-1,Arhs,axpy);CHKERRQ(ierr);
647       if (*A != *B) {
648         ierr = MatAXPY(*B,-1,Brhs,axpy);CHKERRQ(ierr);
649       }
650       *flg = PetscMin(*flg,flg2);
651     }
652   }
653 
654   ts->ijacobian.time = t;
655   ts->ijacobian.X = U;
656   ts->ijacobian.Xdot = Udot;
657   ierr = PetscObjectStateQuery((PetscObject)U,&ts->ijacobian.Xstate);CHKERRQ(ierr);
658   ierr = PetscObjectStateQuery((PetscObject)Udot,&ts->ijacobian.Xdotstate);CHKERRQ(ierr);
659   ts->ijacobian.shift = shift;
660   ts->ijacobian.imex = imex;
661   ts->ijacobian.mstructure = *flg;
662   ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr);
663   PetscFunctionReturn(0);
664 }
665 
666 #undef __FUNCT__
667 #define __FUNCT__ "TSSetRHSFunction"
668 /*@C
669     TSSetRHSFunction - Sets the routine for evaluating the function,
670     where U_t = G(t,u).
671 
672     Logically Collective on TS
673 
674     Input Parameters:
675 +   ts - the TS context obtained from TSCreate()
676 .   r - vector to put the computed right hand side (or PETSC_NULL to have it created)
677 .   f - routine for evaluating the right-hand-side function
678 -   ctx - [optional] user-defined context for private data for the
679           function evaluation routine (may be PETSC_NULL)
680 
681     Calling sequence of func:
682 $     func (TS ts,PetscReal t,Vec u,Vec F,void *ctx);
683 
684 +   t - current timestep
685 .   u - input vector
686 .   F - function vector
687 -   ctx - [optional] user-defined function context
688 
689     Level: beginner
690 
691 .keywords: TS, timestep, set, right-hand-side, function
692 
693 .seealso: TSSetRHSJacobian(), TSSetIJacobian()
694 @*/
695 PetscErrorCode  TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx)
696 {
697   PetscErrorCode ierr;
698   SNES           snes;
699   Vec            ralloc = PETSC_NULL;
700   DM             dm;
701 
702   PetscFunctionBegin;
703   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
704   if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2);
705 
706   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
707   ierr = DMTSSetRHSFunction(dm,f,ctx);CHKERRQ(ierr);
708   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
709   if (!r && !ts->dm && ts->vec_sol) {
710     ierr = VecDuplicate(ts->vec_sol,&ralloc);CHKERRQ(ierr);
711     r = ralloc;
712   }
713   ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr);
714   ierr = VecDestroy(&ralloc);CHKERRQ(ierr);
715   PetscFunctionReturn(0);
716 }
717 
718 #undef __FUNCT__
719 #define __FUNCT__ "TSSetSolutionFunction"
720 /*@C
721     TSSetSolutionFunction - Provide a function that computes the solution of the ODE or DAE
722 
723     Logically Collective on TS
724 
725     Input Parameters:
726 +   ts - the TS context obtained from TSCreate()
727 .   f - routine for evaluating the solution
728 -   ctx - [optional] user-defined context for private data for the
729           function evaluation routine (may be PETSC_NULL)
730 
731     Calling sequence of func:
732 $     func (TS ts,PetscReal t,Vec u,void *ctx);
733 
734 +   t - current timestep
735 .   u - output vector
736 -   ctx - [optional] user-defined function context
737 
738     Notes:
739     This routine is used for testing accuracy of time integration schemes when you already know the solution.
740     If analytic solutions are not known for your system, consider using the Method of Manufactured Solutions to
741     create closed-form solutions with non-physical forcing terms.
742 
743     For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history.
744 
745     Level: beginner
746 
747 .keywords: TS, timestep, set, right-hand-side, function
748 
749 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction()
750 @*/
751 PetscErrorCode  TSSetSolutionFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx)
752 {
753   PetscErrorCode ierr;
754   DM             dm;
755 
756   PetscFunctionBegin;
757   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
758   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
759   ierr = DMTSSetSolutionFunction(dm,f,ctx);CHKERRQ(ierr);
760   PetscFunctionReturn(0);
761 }
762 
763 #undef __FUNCT__
764 #define __FUNCT__ "TSSetRHSJacobian"
765 /*@C
766    TSSetRHSJacobian - Sets the function to compute the Jacobian of F,
767    where U_t = G(U,t), as well as the location to store the matrix.
768 
769    Logically Collective on TS
770 
771    Input Parameters:
772 +  ts  - the TS context obtained from TSCreate()
773 .  A   - Jacobian matrix
774 .  B   - preconditioner matrix (usually same as A)
775 .  f   - the Jacobian evaluation routine
776 -  ctx - [optional] user-defined context for private data for the
777          Jacobian evaluation routine (may be PETSC_NULL)
778 
779    Calling sequence of func:
780 $     func (TS ts,PetscReal t,Vec u,Mat *A,Mat *B,MatStructure *flag,void *ctx);
781 
782 +  t - current timestep
783 .  u - input vector
784 .  A - matrix A, where U_t = A(t)u
785 .  B - preconditioner matrix, usually the same as A
786 .  flag - flag indicating information about the preconditioner matrix
787           structure (same as flag in KSPSetOperators())
788 -  ctx - [optional] user-defined context for matrix evaluation routine
789 
790    Notes:
791    See KSPSetOperators() for important information about setting the flag
792    output parameter in the routine func().  Be sure to read this information!
793 
794    The routine func() takes Mat * as the matrix arguments rather than Mat.
795    This allows the matrix evaluation routine to replace A and/or B with a
796    completely new matrix structure (not just different matrix elements)
797    when appropriate, for instance, if the nonzero structure is changing
798    throughout the global iterations.
799 
800    Level: beginner
801 
802 .keywords: TS, timestep, set, right-hand-side, Jacobian
803 
804 .seealso: SNESDefaultComputeJacobianColor(), TSSetRHSFunction()
805 
806 @*/
807 PetscErrorCode  TSSetRHSJacobian(TS ts,Mat A,Mat B,TSRHSJacobian f,void *ctx)
808 {
809   PetscErrorCode ierr;
810   SNES           snes;
811   DM             dm;
812   TSIJacobian    ijacobian;
813 
814   PetscFunctionBegin;
815   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
816   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
817   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
818   if (A) PetscCheckSameComm(ts,1,A,2);
819   if (B) PetscCheckSameComm(ts,1,B,3);
820 
821   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
822   ierr = DMTSSetRHSJacobian(dm,f,ctx);CHKERRQ(ierr);
823   ierr = DMTSGetIJacobian(dm,&ijacobian,PETSC_NULL);CHKERRQ(ierr);
824 
825   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
826   if (!ijacobian) {
827     ierr = SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);CHKERRQ(ierr);
828   }
829   if (A) {
830     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
831     ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr);
832     ts->Arhs = A;
833   }
834   if (B) {
835     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
836     ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr);
837     ts->Brhs = B;
838   }
839   PetscFunctionReturn(0);
840 }
841 
842 
843 #undef __FUNCT__
844 #define __FUNCT__ "TSSetIFunction"
845 /*@C
846    TSSetIFunction - Set the function to compute F(t,U,U_t) where F() = 0 is the DAE to be solved.
847 
848    Logically Collective on TS
849 
850    Input Parameters:
851 +  ts  - the TS context obtained from TSCreate()
852 .  r   - vector to hold the residual (or PETSC_NULL to have it created internally)
853 .  f   - the function evaluation routine
854 -  ctx - user-defined context for private data for the function evaluation routine (may be PETSC_NULL)
855 
856    Calling sequence of f:
857 $  f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx);
858 
859 +  t   - time at step/stage being solved
860 .  u   - state vector
861 .  u_t - time derivative of state vector
862 .  F   - function vector
863 -  ctx - [optional] user-defined context for matrix evaluation routine
864 
865    Important:
866    The user MUST call either this routine, TSSetRHSFunction().  This routine must be used when not solving an ODE, for example a DAE.
867 
868    Level: beginner
869 
870 .keywords: TS, timestep, set, DAE, Jacobian
871 
872 .seealso: TSSetRHSJacobian(), TSSetRHSFunction(), TSSetIJacobian()
873 @*/
874 PetscErrorCode  TSSetIFunction(TS ts,Vec res,TSIFunction f,void *ctx)
875 {
876   PetscErrorCode ierr;
877   SNES           snes;
878   Vec            resalloc = PETSC_NULL;
879   DM             dm;
880 
881   PetscFunctionBegin;
882   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
883   if (res) PetscValidHeaderSpecific(res,VEC_CLASSID,2);
884 
885   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
886   ierr = DMTSSetIFunction(dm,f,ctx);CHKERRQ(ierr);
887 
888   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
889   if (!res && !ts->dm && ts->vec_sol) {
890     ierr = VecDuplicate(ts->vec_sol,&resalloc);CHKERRQ(ierr);
891     res = resalloc;
892   }
893   ierr = SNESSetFunction(snes,res,SNESTSFormFunction,ts);CHKERRQ(ierr);
894   ierr = VecDestroy(&resalloc);CHKERRQ(ierr);
895 
896   PetscFunctionReturn(0);
897 }
898 
899 #undef __FUNCT__
900 #define __FUNCT__ "TSGetIFunction"
901 /*@C
902    TSGetIFunction - Returns the vector where the implicit residual is stored and the function/contex to compute it.
903 
904    Not Collective
905 
906    Input Parameter:
907 .  ts - the TS context
908 
909    Output Parameter:
910 +  r - vector to hold residual (or PETSC_NULL)
911 .  func - the function to compute residual (or PETSC_NULL)
912 -  ctx - the function context (or PETSC_NULL)
913 
914    Level: advanced
915 
916 .keywords: TS, nonlinear, get, function
917 
918 .seealso: TSSetIFunction(), SNESGetFunction()
919 @*/
920 PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx)
921 {
922   PetscErrorCode ierr;
923   SNES           snes;
924   DM             dm;
925 
926   PetscFunctionBegin;
927   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
928   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
929   ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
930   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
931   ierr = DMTSGetIFunction(dm,func,ctx);CHKERRQ(ierr);
932   PetscFunctionReturn(0);
933 }
934 
935 #undef __FUNCT__
936 #define __FUNCT__ "TSGetRHSFunction"
937 /*@C
938    TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it.
939 
940    Not Collective
941 
942    Input Parameter:
943 .  ts - the TS context
944 
945    Output Parameter:
946 +  r - vector to hold computed right hand side (or PETSC_NULL)
947 .  func - the function to compute right hand side (or PETSC_NULL)
948 -  ctx - the function context (or PETSC_NULL)
949 
950    Level: advanced
951 
952 .keywords: TS, nonlinear, get, function
953 
954 .seealso: TSSetRhsfunction(), SNESGetFunction()
955 @*/
956 PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx)
957 {
958   PetscErrorCode ierr;
959   SNES           snes;
960   DM             dm;
961 
962   PetscFunctionBegin;
963   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
964   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
965   ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
966   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
967   ierr = DMTSGetRHSFunction(dm,func,ctx);CHKERRQ(ierr);
968   PetscFunctionReturn(0);
969 }
970 
971 #undef __FUNCT__
972 #define __FUNCT__ "TSSetIJacobian"
973 /*@C
974    TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function
975         you provided with TSSetIFunction().
976 
977    Logically Collective on TS
978 
979    Input Parameters:
980 +  ts  - the TS context obtained from TSCreate()
981 .  A   - Jacobian matrix
982 .  B   - preconditioning matrix for A (may be same as A)
983 .  f   - the Jacobian evaluation routine
984 -  ctx - user-defined context for private data for the Jacobian evaluation routine (may be PETSC_NULL)
985 
986    Calling sequence of f:
987 $  f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat *A,Mat *B,MatStructure *flag,void *ctx);
988 
989 +  t    - time at step/stage being solved
990 .  U    - state vector
991 .  U_t  - time derivative of state vector
992 .  a    - shift
993 .  A    - Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t
994 .  B    - preconditioning matrix for A, may be same as A
995 .  flag - flag indicating information about the preconditioner matrix
996           structure (same as flag in KSPSetOperators())
997 -  ctx  - [optional] user-defined context for matrix evaluation routine
998 
999    Notes:
1000    The matrices A and B are exactly the matrices that are used by SNES for the nonlinear solve.
1001 
1002    The matrix dF/dU + a*dF/dU_t you provide turns out to be
1003    the Jacobian of F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved.
1004    The time integrator internally approximates U_t by W+a*U where the positive "shift"
1005    a and vector W depend on the integration method, step size, and past states. For example with
1006    the backward Euler method a = 1/dt and W = -a*U(previous timestep) so
1007    W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt
1008 
1009    Level: beginner
1010 
1011 .keywords: TS, timestep, DAE, Jacobian
1012 
1013 .seealso: TSSetIFunction(), TSSetRHSJacobian(), SNESDefaultComputeJacobianColor(), SNESDefaultComputeJacobian()
1014 
1015 @*/
1016 PetscErrorCode  TSSetIJacobian(TS ts,Mat A,Mat B,TSIJacobian f,void *ctx)
1017 {
1018   PetscErrorCode ierr;
1019   SNES           snes;
1020   DM             dm;
1021 
1022   PetscFunctionBegin;
1023   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1024   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
1025   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
1026   if (A) PetscCheckSameComm(ts,1,A,2);
1027   if (B) PetscCheckSameComm(ts,1,B,3);
1028 
1029   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1030   ierr = DMTSSetIJacobian(dm,f,ctx);CHKERRQ(ierr);
1031 
1032   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1033   ierr = SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);CHKERRQ(ierr);
1034   PetscFunctionReturn(0);
1035 }
1036 
1037 #undef __FUNCT__
1038 #define __FUNCT__ "TSLoad"
1039 /*@C
1040   TSLoad - Loads a KSP that has been stored in binary  with KSPView().
1041 
1042   Collective on PetscViewer
1043 
1044   Input Parameters:
1045 + newdm - the newly loaded TS, this needs to have been created with TSCreate() or
1046            some related function before a call to TSLoad().
1047 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen()
1048 
1049    Level: intermediate
1050 
1051   Notes:
1052    The type is determined by the data in the file, any type set into the TS before this call is ignored.
1053 
1054   Notes for advanced users:
1055   Most users should not need to know the details of the binary storage
1056   format, since TSLoad() and TSView() completely hide these details.
1057   But for anyone who's interested, the standard binary matrix storage
1058   format is
1059 .vb
1060      has not yet been determined
1061 .ve
1062 
1063 .seealso: PetscViewerBinaryOpen(), TSView(), MatLoad(), VecLoad()
1064 @*/
1065 PetscErrorCode  TSLoad(TS ts, PetscViewer viewer)
1066 {
1067   PetscErrorCode ierr;
1068   PetscBool      isbinary;
1069   PetscInt       classid;
1070   char           type[256];
1071 
1072   PetscFunctionBegin;
1073   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1074   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1075   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1076   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
1077 
1078   ierr = PetscViewerBinaryRead(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr);
1079   if (classid != TS_FILE_CLASSID) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_ARG_WRONG,"Not TS next in file");
1080   ierr = PetscViewerBinaryRead(viewer,type,256,PETSC_CHAR);CHKERRQ(ierr);
1081   ierr = TSSetType(ts, type);CHKERRQ(ierr);
1082   if (ts->ops->load) {
1083     ierr = (*ts->ops->load)(ts,viewer);CHKERRQ(ierr);
1084   }
1085   ierr = DMCreate(((PetscObject)ts)->comm,&ts->dm);CHKERRQ(ierr);
1086   ierr = DMLoad(ts->dm,viewer);CHKERRQ(ierr);
1087   ierr = DMCreateGlobalVector(ts->dm,&ts->vec_sol);CHKERRQ(ierr);
1088   ierr = VecLoad(ts->vec_sol,viewer);CHKERRQ(ierr);
1089   PetscFunctionReturn(0);
1090 }
1091 
1092 #undef __FUNCT__
1093 #define __FUNCT__ "TSView"
1094 /*@C
1095     TSView - Prints the TS data structure.
1096 
1097     Collective on TS
1098 
1099     Input Parameters:
1100 +   ts - the TS context obtained from TSCreate()
1101 -   viewer - visualization context
1102 
1103     Options Database Key:
1104 .   -ts_view - calls TSView() at end of TSStep()
1105 
1106     Notes:
1107     The available visualization contexts include
1108 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
1109 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
1110          output where only the first processor opens
1111          the file.  All other processors send their
1112          data to the first processor to print.
1113 
1114     The user can open an alternative visualization context with
1115     PetscViewerASCIIOpen() - output to a specified file.
1116 
1117     Level: beginner
1118 
1119 .keywords: TS, timestep, view
1120 
1121 .seealso: PetscViewerASCIIOpen()
1122 @*/
1123 PetscErrorCode  TSView(TS ts,PetscViewer viewer)
1124 {
1125   PetscErrorCode ierr;
1126   TSType         type;
1127   PetscBool      iascii,isstring,isundials,isbinary;
1128 
1129   PetscFunctionBegin;
1130   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1131   if (!viewer) {
1132     ierr = PetscViewerASCIIGetStdout(((PetscObject)ts)->comm,&viewer);CHKERRQ(ierr);
1133   }
1134   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1135   PetscCheckSameComm(ts,1,viewer,2);
1136 
1137   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1138   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
1139   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1140   if (iascii) {
1141     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer,"TS Object");CHKERRQ(ierr);
1142     ierr = PetscViewerASCIIPrintf(viewer,"  maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr);
1143     ierr = PetscViewerASCIIPrintf(viewer,"  maximum time=%G\n",ts->max_time);CHKERRQ(ierr);
1144     if (ts->problem_type == TS_NONLINEAR) {
1145       ierr = PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solver iterations=%D\n",ts->snes_its);CHKERRQ(ierr);
1146       ierr = PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solve failures=%D\n",ts->num_snes_failures);CHKERRQ(ierr);
1147     }
1148     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",ts->ksp_its);CHKERRQ(ierr);
1149     ierr = PetscViewerASCIIPrintf(viewer,"  total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr);
1150     if (ts->ops->view) {
1151       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1152       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1153       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1154     }
1155   } else if (isstring) {
1156     ierr = TSGetType(ts,&type);CHKERRQ(ierr);
1157     ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr);
1158   } else if (isbinary) {
1159     PetscInt         classid = TS_FILE_CLASSID;
1160     MPI_Comm         comm;
1161     PetscMPIInt      rank;
1162     char             type[256];
1163 
1164     ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr);
1165     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
1166     if (!rank) {
1167       ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
1168       ierr = PetscStrncpy(type,((PetscObject)ts)->type_name,256);CHKERRQ(ierr);
1169       ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
1170     }
1171     if (ts->ops->view) {
1172       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1173     }
1174     ierr = DMView(ts->dm,viewer);CHKERRQ(ierr);
1175     ierr = VecView(ts->vec_sol,viewer);CHKERRQ(ierr);
1176   }
1177   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1178   ierr = PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr);
1179   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1180   PetscFunctionReturn(0);
1181 }
1182 
1183 
1184 #undef __FUNCT__
1185 #define __FUNCT__ "TSSetApplicationContext"
1186 /*@
1187    TSSetApplicationContext - Sets an optional user-defined context for
1188    the timesteppers.
1189 
1190    Logically Collective on TS
1191 
1192    Input Parameters:
1193 +  ts - the TS context obtained from TSCreate()
1194 -  usrP - optional user context
1195 
1196    Level: intermediate
1197 
1198 .keywords: TS, timestep, set, application, context
1199 
1200 .seealso: TSGetApplicationContext()
1201 @*/
1202 PetscErrorCode  TSSetApplicationContext(TS ts,void *usrP)
1203 {
1204   PetscFunctionBegin;
1205   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1206   ts->user = usrP;
1207   PetscFunctionReturn(0);
1208 }
1209 
1210 #undef __FUNCT__
1211 #define __FUNCT__ "TSGetApplicationContext"
1212 /*@
1213     TSGetApplicationContext - Gets the user-defined context for the
1214     timestepper.
1215 
1216     Not Collective
1217 
1218     Input Parameter:
1219 .   ts - the TS context obtained from TSCreate()
1220 
1221     Output Parameter:
1222 .   usrP - user context
1223 
1224     Level: intermediate
1225 
1226 .keywords: TS, timestep, get, application, context
1227 
1228 .seealso: TSSetApplicationContext()
1229 @*/
1230 PetscErrorCode  TSGetApplicationContext(TS ts,void *usrP)
1231 {
1232   PetscFunctionBegin;
1233   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1234   *(void**)usrP = ts->user;
1235   PetscFunctionReturn(0);
1236 }
1237 
1238 #undef __FUNCT__
1239 #define __FUNCT__ "TSGetTimeStepNumber"
1240 /*@
1241    TSGetTimeStepNumber - Gets the number of time steps completed.
1242 
1243    Not Collective
1244 
1245    Input Parameter:
1246 .  ts - the TS context obtained from TSCreate()
1247 
1248    Output Parameter:
1249 .  iter - number of steps completed so far
1250 
1251    Level: intermediate
1252 
1253 .keywords: TS, timestep, get, iteration, number
1254 .seealso: TSGetTime(), TSGetTimeStep(), TSSetPreStep(), TSSetPreStage(), TSSetPostStep()
1255 @*/
1256 PetscErrorCode  TSGetTimeStepNumber(TS ts,PetscInt* iter)
1257 {
1258   PetscFunctionBegin;
1259   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1260   PetscValidIntPointer(iter,2);
1261   *iter = ts->steps;
1262   PetscFunctionReturn(0);
1263 }
1264 
1265 #undef __FUNCT__
1266 #define __FUNCT__ "TSSetInitialTimeStep"
1267 /*@
1268    TSSetInitialTimeStep - Sets the initial timestep to be used,
1269    as well as the initial time.
1270 
1271    Logically Collective on TS
1272 
1273    Input Parameters:
1274 +  ts - the TS context obtained from TSCreate()
1275 .  initial_time - the initial time
1276 -  time_step - the size of the timestep
1277 
1278    Level: intermediate
1279 
1280 .seealso: TSSetTimeStep(), TSGetTimeStep()
1281 
1282 .keywords: TS, set, initial, timestep
1283 @*/
1284 PetscErrorCode  TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step)
1285 {
1286   PetscErrorCode ierr;
1287 
1288   PetscFunctionBegin;
1289   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1290   ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr);
1291   ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr);
1292   PetscFunctionReturn(0);
1293 }
1294 
1295 #undef __FUNCT__
1296 #define __FUNCT__ "TSSetTimeStep"
1297 /*@
1298    TSSetTimeStep - Allows one to reset the timestep at any time,
1299    useful for simple pseudo-timestepping codes.
1300 
1301    Logically Collective on TS
1302 
1303    Input Parameters:
1304 +  ts - the TS context obtained from TSCreate()
1305 -  time_step - the size of the timestep
1306 
1307    Level: intermediate
1308 
1309 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
1310 
1311 .keywords: TS, set, timestep
1312 @*/
1313 PetscErrorCode  TSSetTimeStep(TS ts,PetscReal time_step)
1314 {
1315   PetscFunctionBegin;
1316   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1317   PetscValidLogicalCollectiveReal(ts,time_step,2);
1318   ts->time_step = time_step;
1319   ts->time_step_orig = time_step;
1320   PetscFunctionReturn(0);
1321 }
1322 
1323 #undef __FUNCT__
1324 #define __FUNCT__ "TSSetExactFinalTime"
1325 /*@
1326    TSSetExactFinalTime - Determines whether to interpolate solution to the
1327       exact final time requested by the user or just returns it at the final time
1328       it computed.
1329 
1330   Logically Collective on TS
1331 
1332    Input Parameter:
1333 +   ts - the time-step context
1334 -   ft - PETSC_TRUE if interpolates, else PETSC_FALSE
1335 
1336    Level: beginner
1337 
1338 .seealso: TSSetDuration()
1339 @*/
1340 PetscErrorCode  TSSetExactFinalTime(TS ts,PetscBool flg)
1341 {
1342   PetscFunctionBegin;
1343   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1344   PetscValidLogicalCollectiveBool(ts,flg,2);
1345   ts->exact_final_time = flg;
1346   PetscFunctionReturn(0);
1347 }
1348 
1349 #undef __FUNCT__
1350 #define __FUNCT__ "TSGetTimeStep"
1351 /*@
1352    TSGetTimeStep - Gets the current timestep size.
1353 
1354    Not Collective
1355 
1356    Input Parameter:
1357 .  ts - the TS context obtained from TSCreate()
1358 
1359    Output Parameter:
1360 .  dt - the current timestep size
1361 
1362    Level: intermediate
1363 
1364 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
1365 
1366 .keywords: TS, get, timestep
1367 @*/
1368 PetscErrorCode  TSGetTimeStep(TS ts,PetscReal* dt)
1369 {
1370   PetscFunctionBegin;
1371   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1372   PetscValidRealPointer(dt,2);
1373   *dt = ts->time_step;
1374   PetscFunctionReturn(0);
1375 }
1376 
1377 #undef __FUNCT__
1378 #define __FUNCT__ "TSGetSolution"
1379 /*@
1380    TSGetSolution - Returns the solution at the present timestep. It
1381    is valid to call this routine inside the function that you are evaluating
1382    in order to move to the new timestep. This vector not changed until
1383    the solution at the next timestep has been calculated.
1384 
1385    Not Collective, but Vec returned is parallel if TS is parallel
1386 
1387    Input Parameter:
1388 .  ts - the TS context obtained from TSCreate()
1389 
1390    Output Parameter:
1391 .  v - the vector containing the solution
1392 
1393    Level: intermediate
1394 
1395 .seealso: TSGetTimeStep()
1396 
1397 .keywords: TS, timestep, get, solution
1398 @*/
1399 PetscErrorCode  TSGetSolution(TS ts,Vec *v)
1400 {
1401   PetscFunctionBegin;
1402   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1403   PetscValidPointer(v,2);
1404   *v = ts->vec_sol;
1405   PetscFunctionReturn(0);
1406 }
1407 
1408 /* ----- Routines to initialize and destroy a timestepper ---- */
1409 #undef __FUNCT__
1410 #define __FUNCT__ "TSSetProblemType"
1411 /*@
1412   TSSetProblemType - Sets the type of problem to be solved.
1413 
1414   Not collective
1415 
1416   Input Parameters:
1417 + ts   - The TS
1418 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1419 .vb
1420          U_t - A U = 0      (linear)
1421          U_t - A(t) U = 0   (linear)
1422          F(t,U,U_t) = 0     (nonlinear)
1423 .ve
1424 
1425    Level: beginner
1426 
1427 .keywords: TS, problem type
1428 .seealso: TSSetUp(), TSProblemType, TS
1429 @*/
1430 PetscErrorCode  TSSetProblemType(TS ts, TSProblemType type)
1431 {
1432   PetscErrorCode ierr;
1433 
1434   PetscFunctionBegin;
1435   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1436   ts->problem_type = type;
1437   if (type == TS_LINEAR) {
1438     SNES snes;
1439     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1440     ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);
1441   }
1442   PetscFunctionReturn(0);
1443 }
1444 
1445 #undef __FUNCT__
1446 #define __FUNCT__ "TSGetProblemType"
1447 /*@C
1448   TSGetProblemType - Gets the type of problem to be solved.
1449 
1450   Not collective
1451 
1452   Input Parameter:
1453 . ts   - The TS
1454 
1455   Output Parameter:
1456 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1457 .vb
1458          M U_t = A U
1459          M(t) U_t = A(t) U
1460          F(t,U,U_t)
1461 .ve
1462 
1463    Level: beginner
1464 
1465 .keywords: TS, problem type
1466 .seealso: TSSetUp(), TSProblemType, TS
1467 @*/
1468 PetscErrorCode  TSGetProblemType(TS ts, TSProblemType *type)
1469 {
1470   PetscFunctionBegin;
1471   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1472   PetscValidIntPointer(type,2);
1473   *type = ts->problem_type;
1474   PetscFunctionReturn(0);
1475 }
1476 
1477 #undef __FUNCT__
1478 #define __FUNCT__ "TSSetUp"
1479 /*@
1480    TSSetUp - Sets up the internal data structures for the later use
1481    of a timestepper.
1482 
1483    Collective on TS
1484 
1485    Input Parameter:
1486 .  ts - the TS context obtained from TSCreate()
1487 
1488    Notes:
1489    For basic use of the TS solvers the user need not explicitly call
1490    TSSetUp(), since these actions will automatically occur during
1491    the call to TSStep().  However, if one wishes to control this
1492    phase separately, TSSetUp() should be called after TSCreate()
1493    and optional routines of the form TSSetXXX(), but before TSStep().
1494 
1495    Level: advanced
1496 
1497 .keywords: TS, timestep, setup
1498 
1499 .seealso: TSCreate(), TSStep(), TSDestroy()
1500 @*/
1501 PetscErrorCode  TSSetUp(TS ts)
1502 {
1503   PetscErrorCode ierr;
1504   DM             dm;
1505   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
1506   PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
1507   TSIJacobian    ijac;
1508   TSRHSJacobian  rhsjac;
1509 
1510   PetscFunctionBegin;
1511   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1512   if (ts->setupcalled) PetscFunctionReturn(0);
1513 
1514   if (!((PetscObject)ts)->type_name) {
1515     ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr);
1516   }
1517   if (ts->exact_final_time == PETSC_DECIDE) ts->exact_final_time = PETSC_FALSE;
1518 
1519   if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first");
1520 
1521   ierr = TSGetAdapt(ts,&ts->adapt);CHKERRQ(ierr);
1522 
1523   if (ts->ops->setup) {
1524     ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr);
1525   }
1526 
1527   /* in the case where we've set a DMTSFunction or what have you, we need the default SNESFunction
1528    to be set right but can't do it elsewhere due to the overreliance on ctx=ts.
1529    */
1530   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1531   ierr = DMSNESGetFunction(dm,&func,PETSC_NULL);CHKERRQ(ierr);
1532   if (!func) {
1533     ierr =DMSNESSetFunction(dm,SNESTSFormFunction,ts);CHKERRQ(ierr);
1534   }
1535   /* if the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it.
1536      Otherwise, the SNES will use coloring internally to form the Jacobian.
1537    */
1538   ierr = DMSNESGetJacobian(dm,&jac,PETSC_NULL);CHKERRQ(ierr);
1539   ierr = DMTSGetIJacobian(dm,&ijac,PETSC_NULL);CHKERRQ(ierr);
1540   ierr = DMTSGetRHSJacobian(dm,&rhsjac,PETSC_NULL);CHKERRQ(ierr);
1541   if (!jac && (ijac || rhsjac)) {
1542     ierr = DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);CHKERRQ(ierr);
1543   }
1544   ts->setupcalled = PETSC_TRUE;
1545   PetscFunctionReturn(0);
1546 }
1547 
1548 #undef __FUNCT__
1549 #define __FUNCT__ "TSReset"
1550 /*@
1551    TSReset - Resets a TS context and removes any allocated Vecs and Mats.
1552 
1553    Collective on TS
1554 
1555    Input Parameter:
1556 .  ts - the TS context obtained from TSCreate()
1557 
1558    Level: beginner
1559 
1560 .keywords: TS, timestep, reset
1561 
1562 .seealso: TSCreate(), TSSetup(), TSDestroy()
1563 @*/
1564 PetscErrorCode  TSReset(TS ts)
1565 {
1566   PetscErrorCode ierr;
1567 
1568   PetscFunctionBegin;
1569   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1570   if (ts->ops->reset) {
1571     ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr);
1572   }
1573   if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);}
1574   ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr);
1575   ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr);
1576   ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr);
1577   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
1578   ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
1579   ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
1580   ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr);
1581   ts->setupcalled = PETSC_FALSE;
1582   PetscFunctionReturn(0);
1583 }
1584 
1585 #undef __FUNCT__
1586 #define __FUNCT__ "TSDestroy"
1587 /*@
1588    TSDestroy - Destroys the timestepper context that was created
1589    with TSCreate().
1590 
1591    Collective on TS
1592 
1593    Input Parameter:
1594 .  ts - the TS context obtained from TSCreate()
1595 
1596    Level: beginner
1597 
1598 .keywords: TS, timestepper, destroy
1599 
1600 .seealso: TSCreate(), TSSetUp(), TSSolve()
1601 @*/
1602 PetscErrorCode  TSDestroy(TS *ts)
1603 {
1604   PetscErrorCode ierr;
1605 
1606   PetscFunctionBegin;
1607   if (!*ts) PetscFunctionReturn(0);
1608   PetscValidHeaderSpecific((*ts),TS_CLASSID,1);
1609   if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);}
1610 
1611   ierr = TSReset((*ts));CHKERRQ(ierr);
1612 
1613   /* if memory was published with AMS then destroy it */
1614   ierr = PetscObjectDepublish((*ts));CHKERRQ(ierr);
1615   if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);}
1616 
1617   ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr);
1618   ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr);
1619   ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr);
1620   ierr = TSMonitorCancel((*ts));CHKERRQ(ierr);
1621 
1622   ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr);
1623   PetscFunctionReturn(0);
1624 }
1625 
1626 #undef __FUNCT__
1627 #define __FUNCT__ "TSGetSNES"
1628 /*@
1629    TSGetSNES - Returns the SNES (nonlinear solver) associated with
1630    a TS (timestepper) context. Valid only for nonlinear problems.
1631 
1632    Not Collective, but SNES is parallel if TS is parallel
1633 
1634    Input Parameter:
1635 .  ts - the TS context obtained from TSCreate()
1636 
1637    Output Parameter:
1638 .  snes - the nonlinear solver context
1639 
1640    Notes:
1641    The user can then directly manipulate the SNES context to set various
1642    options, etc.  Likewise, the user can then extract and manipulate the
1643    KSP, KSP, and PC contexts as well.
1644 
1645    TSGetSNES() does not work for integrators that do not use SNES; in
1646    this case TSGetSNES() returns PETSC_NULL in snes.
1647 
1648    Level: beginner
1649 
1650 .keywords: timestep, get, SNES
1651 @*/
1652 PetscErrorCode  TSGetSNES(TS ts,SNES *snes)
1653 {
1654   PetscErrorCode ierr;
1655 
1656   PetscFunctionBegin;
1657   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1658   PetscValidPointer(snes,2);
1659   if (!ts->snes) {
1660     ierr = SNESCreate(((PetscObject)ts)->comm,&ts->snes);CHKERRQ(ierr);
1661     ierr = SNESSetFunction(ts->snes,PETSC_NULL,SNESTSFormFunction,ts);CHKERRQ(ierr);
1662     ierr = PetscLogObjectParent(ts,ts->snes);CHKERRQ(ierr);
1663     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr);
1664     if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
1665     if (ts->problem_type == TS_LINEAR) {
1666       ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr);
1667     }
1668   }
1669   *snes = ts->snes;
1670   PetscFunctionReturn(0);
1671 }
1672 
1673 #undef __FUNCT__
1674 #define __FUNCT__ "TSGetKSP"
1675 /*@
1676    TSGetKSP - Returns the KSP (linear solver) associated with
1677    a TS (timestepper) context.
1678 
1679    Not Collective, but KSP is parallel if TS is parallel
1680 
1681    Input Parameter:
1682 .  ts - the TS context obtained from TSCreate()
1683 
1684    Output Parameter:
1685 .  ksp - the nonlinear solver context
1686 
1687    Notes:
1688    The user can then directly manipulate the KSP context to set various
1689    options, etc.  Likewise, the user can then extract and manipulate the
1690    KSP and PC contexts as well.
1691 
1692    TSGetKSP() does not work for integrators that do not use KSP;
1693    in this case TSGetKSP() returns PETSC_NULL in ksp.
1694 
1695    Level: beginner
1696 
1697 .keywords: timestep, get, KSP
1698 @*/
1699 PetscErrorCode  TSGetKSP(TS ts,KSP *ksp)
1700 {
1701   PetscErrorCode ierr;
1702   SNES           snes;
1703 
1704   PetscFunctionBegin;
1705   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1706   PetscValidPointer(ksp,2);
1707   if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first");
1708   if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()");
1709   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1710   ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr);
1711   PetscFunctionReturn(0);
1712 }
1713 
1714 /* ----------- Routines to set solver parameters ---------- */
1715 
1716 #undef __FUNCT__
1717 #define __FUNCT__ "TSGetDuration"
1718 /*@
1719    TSGetDuration - Gets the maximum number of timesteps to use and
1720    maximum time for iteration.
1721 
1722    Not Collective
1723 
1724    Input Parameters:
1725 +  ts       - the TS context obtained from TSCreate()
1726 .  maxsteps - maximum number of iterations to use, or PETSC_NULL
1727 -  maxtime  - final time to iterate to, or PETSC_NULL
1728 
1729    Level: intermediate
1730 
1731 .keywords: TS, timestep, get, maximum, iterations, time
1732 @*/
1733 PetscErrorCode  TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
1734 {
1735   PetscFunctionBegin;
1736   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1737   if (maxsteps) {
1738     PetscValidIntPointer(maxsteps,2);
1739     *maxsteps = ts->max_steps;
1740   }
1741   if (maxtime) {
1742     PetscValidScalarPointer(maxtime,3);
1743     *maxtime  = ts->max_time;
1744   }
1745   PetscFunctionReturn(0);
1746 }
1747 
1748 #undef __FUNCT__
1749 #define __FUNCT__ "TSSetDuration"
1750 /*@
1751    TSSetDuration - Sets the maximum number of timesteps to use and
1752    maximum time for iteration.
1753 
1754    Logically Collective on TS
1755 
1756    Input Parameters:
1757 +  ts - the TS context obtained from TSCreate()
1758 .  maxsteps - maximum number of iterations to use
1759 -  maxtime - final time to iterate to
1760 
1761    Options Database Keys:
1762 .  -ts_max_steps <maxsteps> - Sets maxsteps
1763 .  -ts_final_time <maxtime> - Sets maxtime
1764 
1765    Notes:
1766    The default maximum number of iterations is 5000. Default time is 5.0
1767 
1768    Level: intermediate
1769 
1770 .keywords: TS, timestep, set, maximum, iterations
1771 
1772 .seealso: TSSetExactFinalTime()
1773 @*/
1774 PetscErrorCode  TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime)
1775 {
1776   PetscFunctionBegin;
1777   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1778   PetscValidLogicalCollectiveInt(ts,maxsteps,2);
1779   PetscValidLogicalCollectiveReal(ts,maxtime,2);
1780   if (maxsteps >= 0) ts->max_steps = maxsteps;
1781   if (maxtime != PETSC_DEFAULT) ts->max_time  = maxtime;
1782   PetscFunctionReturn(0);
1783 }
1784 
1785 #undef __FUNCT__
1786 #define __FUNCT__ "TSSetSolution"
1787 /*@
1788    TSSetSolution - Sets the initial solution vector
1789    for use by the TS routines.
1790 
1791    Logically Collective on TS and Vec
1792 
1793    Input Parameters:
1794 +  ts - the TS context obtained from TSCreate()
1795 -  u - the solution vector
1796 
1797    Level: beginner
1798 
1799 .keywords: TS, timestep, set, solution, initial conditions
1800 @*/
1801 PetscErrorCode  TSSetSolution(TS ts,Vec u)
1802 {
1803   PetscErrorCode ierr;
1804   DM             dm;
1805 
1806   PetscFunctionBegin;
1807   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1808   PetscValidHeaderSpecific(u,VEC_CLASSID,2);
1809   ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr);
1810   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
1811   ts->vec_sol = u;
1812   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1813   ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr);
1814   PetscFunctionReturn(0);
1815 }
1816 
1817 #undef __FUNCT__
1818 #define __FUNCT__ "TSSetPreStep"
1819 /*@C
1820   TSSetPreStep - Sets the general-purpose function
1821   called once at the beginning of each time step.
1822 
1823   Logically Collective on TS
1824 
1825   Input Parameters:
1826 + ts   - The TS context obtained from TSCreate()
1827 - func - The function
1828 
1829   Calling sequence of func:
1830 . func (TS ts);
1831 
1832   Level: intermediate
1833 
1834   Note:
1835   If a step is rejected, TSStep() will call this routine again before each attempt.
1836   The last completed time step number can be queried using TSGetTimeStepNumber(), the
1837   size of the step being attempted can be obtained using TSGetTimeStep().
1838 
1839 .keywords: TS, timestep
1840 .seealso: TSSetPreStage(), TSSetPostStep(), TSStep()
1841 @*/
1842 PetscErrorCode  TSSetPreStep(TS ts, PetscErrorCode (*func)(TS))
1843 {
1844   PetscFunctionBegin;
1845   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1846   ts->ops->prestep = func;
1847   PetscFunctionReturn(0);
1848 }
1849 
1850 #undef __FUNCT__
1851 #define __FUNCT__ "TSPreStep"
1852 /*@
1853   TSPreStep - Runs the user-defined pre-step function.
1854 
1855   Collective on TS
1856 
1857   Input Parameters:
1858 . ts   - The TS context obtained from TSCreate()
1859 
1860   Notes:
1861   TSPreStep() is typically used within time stepping implementations,
1862   so most users would not generally call this routine themselves.
1863 
1864   Level: developer
1865 
1866 .keywords: TS, timestep
1867 .seealso: TSSetPreStep(), TSPreStage(), TSPostStep()
1868 @*/
1869 PetscErrorCode  TSPreStep(TS ts)
1870 {
1871   PetscErrorCode ierr;
1872 
1873   PetscFunctionBegin;
1874   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1875   if (ts->ops->prestep) {
1876     PetscStackPush("TS PreStep function");
1877     ierr = (*ts->ops->prestep)(ts);CHKERRQ(ierr);
1878     PetscStackPop;
1879   }
1880   PetscFunctionReturn(0);
1881 }
1882 
1883 #undef __FUNCT__
1884 #define __FUNCT__ "TSSetPreStage"
1885 /*@C
1886   TSSetPreStage - Sets the general-purpose function
1887   called once at the beginning of each stage.
1888 
1889   Logically Collective on TS
1890 
1891   Input Parameters:
1892 + ts   - The TS context obtained from TSCreate()
1893 - func - The function
1894 
1895   Calling sequence of func:
1896 . PetscErrorCode func(TS ts, PetscReal stagetime);
1897 
1898   Level: intermediate
1899 
1900   Note:
1901   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
1902   The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being
1903   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
1904 
1905 .keywords: TS, timestep
1906 .seealso: TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
1907 @*/
1908 PetscErrorCode  TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal))
1909 {
1910   PetscFunctionBegin;
1911   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1912   ts->ops->prestage = func;
1913   PetscFunctionReturn(0);
1914 }
1915 
1916 #undef __FUNCT__
1917 #define __FUNCT__ "TSPreStage"
1918 /*@
1919   TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage()
1920 
1921   Collective on TS
1922 
1923   Input Parameters:
1924 . ts   - The TS context obtained from TSCreate()
1925 
1926   Notes:
1927   TSPreStage() is typically used within time stepping implementations,
1928   most users would not generally call this routine themselves.
1929 
1930   Level: developer
1931 
1932 .keywords: TS, timestep
1933 .seealso: TSSetPreStep(), TSPreStep(), TSPostStep()
1934 @*/
1935 PetscErrorCode  TSPreStage(TS ts, PetscReal stagetime)
1936 {
1937   PetscErrorCode ierr;
1938 
1939   PetscFunctionBegin;
1940   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1941   if (ts->ops->prestage) {
1942     PetscStackPush("TS PreStage function");
1943     ierr = (*ts->ops->prestage)(ts,stagetime);CHKERRQ(ierr);
1944     PetscStackPop;
1945   }
1946   PetscFunctionReturn(0);
1947 }
1948 
1949 #undef __FUNCT__
1950 #define __FUNCT__ "TSSetPostStep"
1951 /*@C
1952   TSSetPostStep - Sets the general-purpose function
1953   called once at the end of each time step.
1954 
1955   Logically Collective on TS
1956 
1957   Input Parameters:
1958 + ts   - The TS context obtained from TSCreate()
1959 - func - The function
1960 
1961   Calling sequence of func:
1962 $ func (TS ts);
1963 
1964   Level: intermediate
1965 
1966 .keywords: TS, timestep
1967 .seealso: TSSetPreStep(), TSSetPreStage(), TSGetTimeStep(), TSGetTimeStepNumber(), TSGetTime()
1968 @*/
1969 PetscErrorCode  TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
1970 {
1971   PetscFunctionBegin;
1972   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1973   ts->ops->poststep = func;
1974   PetscFunctionReturn(0);
1975 }
1976 
1977 #undef __FUNCT__
1978 #define __FUNCT__ "TSPostStep"
1979 /*@
1980   TSPostStep - Runs the user-defined post-step function.
1981 
1982   Collective on TS
1983 
1984   Input Parameters:
1985 . ts   - The TS context obtained from TSCreate()
1986 
1987   Notes:
1988   TSPostStep() is typically used within time stepping implementations,
1989   so most users would not generally call this routine themselves.
1990 
1991   Level: developer
1992 
1993 .keywords: TS, timestep
1994 @*/
1995 PetscErrorCode  TSPostStep(TS ts)
1996 {
1997   PetscErrorCode ierr;
1998 
1999   PetscFunctionBegin;
2000   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2001   if (ts->ops->poststep) {
2002     PetscStackPush("TS PostStep function");
2003     ierr = (*ts->ops->poststep)(ts);CHKERRQ(ierr);
2004     PetscStackPop;
2005   }
2006   PetscFunctionReturn(0);
2007 }
2008 
2009 /* ------------ Routines to set performance monitoring options ----------- */
2010 
2011 #undef __FUNCT__
2012 #define __FUNCT__ "TSMonitorSet"
2013 /*@C
2014    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
2015    timestep to display the iteration's  progress.
2016 
2017    Logically Collective on TS
2018 
2019    Input Parameters:
2020 +  ts - the TS context obtained from TSCreate()
2021 .  monitor - monitoring routine
2022 .  mctx - [optional] user-defined context for private data for the
2023              monitor routine (use PETSC_NULL if no context is desired)
2024 -  monitordestroy - [optional] routine that frees monitor context
2025           (may be PETSC_NULL)
2026 
2027    Calling sequence of monitor:
2028 $    int monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
2029 
2030 +    ts - the TS context
2031 .    steps - iteration number (after the final time step the monitor routine is called with a step of -1, this is at the final time which may have
2032                                been interpolated to)
2033 .    time - current time
2034 .    u - current iterate
2035 -    mctx - [optional] monitoring context
2036 
2037    Notes:
2038    This routine adds an additional monitor to the list of monitors that
2039    already has been loaded.
2040 
2041    Fortran notes: Only a single monitor function can be set for each TS object
2042 
2043    Level: intermediate
2044 
2045 .keywords: TS, timestep, set, monitor
2046 
2047 .seealso: TSMonitorDefault(), TSMonitorCancel()
2048 @*/
2049 PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**))
2050 {
2051   PetscFunctionBegin;
2052   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2053   if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2054   ts->monitor[ts->numbermonitors]           = monitor;
2055   ts->monitordestroy[ts->numbermonitors]    = mdestroy;
2056   ts->monitorcontext[ts->numbermonitors++]  = (void*)mctx;
2057   PetscFunctionReturn(0);
2058 }
2059 
2060 #undef __FUNCT__
2061 #define __FUNCT__ "TSMonitorCancel"
2062 /*@C
2063    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
2064 
2065    Logically Collective on TS
2066 
2067    Input Parameters:
2068 .  ts - the TS context obtained from TSCreate()
2069 
2070    Notes:
2071    There is no way to remove a single, specific monitor.
2072 
2073    Level: intermediate
2074 
2075 .keywords: TS, timestep, set, monitor
2076 
2077 .seealso: TSMonitorDefault(), TSMonitorSet()
2078 @*/
2079 PetscErrorCode  TSMonitorCancel(TS ts)
2080 {
2081   PetscErrorCode ierr;
2082   PetscInt       i;
2083 
2084   PetscFunctionBegin;
2085   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2086   for (i=0; i<ts->numbermonitors; i++) {
2087     if (ts->monitordestroy[i]) {
2088       ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr);
2089     }
2090   }
2091   ts->numbermonitors = 0;
2092   PetscFunctionReturn(0);
2093 }
2094 
2095 #undef __FUNCT__
2096 #define __FUNCT__ "TSMonitorDefault"
2097 /*@
2098    TSMonitorDefault - Sets the Default monitor
2099 
2100    Level: intermediate
2101 
2102 .keywords: TS, set, monitor
2103 
2104 .seealso: TSMonitorDefault(), TSMonitorSet()
2105 @*/
2106 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *dummy)
2107 {
2108   PetscErrorCode ierr;
2109   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)ts)->comm);
2110 
2111   PetscFunctionBegin;
2112   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
2113   ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g\n",step,(double)ts->time_step,(double)ptime);CHKERRQ(ierr);
2114   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
2115   PetscFunctionReturn(0);
2116 }
2117 
2118 #undef __FUNCT__
2119 #define __FUNCT__ "TSSetRetainStages"
2120 /*@
2121    TSSetRetainStages - Request that all stages in the upcoming step be stored so that interpolation will be available.
2122 
2123    Logically Collective on TS
2124 
2125    Input Argument:
2126 .  ts - time stepping context
2127 
2128    Output Argument:
2129 .  flg - PETSC_TRUE or PETSC_FALSE
2130 
2131    Level: intermediate
2132 
2133 .keywords: TS, set
2134 
2135 .seealso: TSInterpolate(), TSSetPostStep()
2136 @*/
2137 PetscErrorCode TSSetRetainStages(TS ts,PetscBool flg)
2138 {
2139   PetscFunctionBegin;
2140   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2141   ts->retain_stages = flg;
2142   PetscFunctionReturn(0);
2143 }
2144 
2145 #undef __FUNCT__
2146 #define __FUNCT__ "TSInterpolate"
2147 /*@
2148    TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval
2149 
2150    Collective on TS
2151 
2152    Input Argument:
2153 +  ts - time stepping context
2154 -  t - time to interpolate to
2155 
2156    Output Argument:
2157 .  U - state at given time
2158 
2159    Notes:
2160    The user should call TSSetRetainStages() before taking a step in which interpolation will be requested.
2161 
2162    Level: intermediate
2163 
2164    Developer Notes:
2165    TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints.
2166 
2167 .keywords: TS, set
2168 
2169 .seealso: TSSetRetainStages(), TSSetPostStep()
2170 @*/
2171 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U)
2172 {
2173   PetscErrorCode ierr;
2174 
2175   PetscFunctionBegin;
2176   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2177   if (t < ts->ptime - ts->time_step_prev || t > ts->ptime) SETERRQ3(((PetscObject)ts)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Requested time %G not in last time steps [%G,%G]",t,ts->ptime-ts->time_step_prev,ts->ptime);
2178   if (!ts->ops->interpolate) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name);
2179   ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr);
2180   PetscFunctionReturn(0);
2181 }
2182 
2183 #undef __FUNCT__
2184 #define __FUNCT__ "TSStep"
2185 /*@
2186    TSStep - Steps one time step
2187 
2188    Collective on TS
2189 
2190    Input Parameter:
2191 .  ts - the TS context obtained from TSCreate()
2192 
2193    Level: intermediate
2194 
2195    Notes:
2196    The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may
2197    be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages.
2198 
2199    This may over-step the final time provided in TSSetDuration() depending on the time-step used. TSSolve() interpolates to exactly the
2200    time provided in TSSetDuration(). One can use TSInterpolate() to determine an interpolated solution within the final timestep.
2201 
2202 .keywords: TS, timestep, solve
2203 
2204 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate()
2205 @*/
2206 PetscErrorCode  TSStep(TS ts)
2207 {
2208   PetscReal      ptime_prev;
2209   PetscErrorCode ierr;
2210 
2211   PetscFunctionBegin;
2212   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2213   ierr = TSSetUp(ts);CHKERRQ(ierr);
2214 
2215   ts->reason = TS_CONVERGED_ITERATING;
2216 
2217   ptime_prev = ts->ptime;
2218   ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr);
2219   ierr = (*ts->ops->step)(ts);CHKERRQ(ierr);
2220   ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr);
2221   ts->time_step_prev = ts->ptime - ptime_prev;
2222 
2223   if (ts->reason < 0) {
2224     if (ts->errorifstepfailed) {
2225       if (ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) {
2226         SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s, increase -ts_max_snes_failures or make negative to attempt recovery",TSConvergedReasons[ts->reason]);
2227       } else SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]);
2228     }
2229   } else if (!ts->reason) {
2230     if (ts->steps >= ts->max_steps)
2231       ts->reason = TS_CONVERGED_ITS;
2232     else if (ts->ptime >= ts->max_time)
2233       ts->reason = TS_CONVERGED_TIME;
2234   }
2235 
2236   PetscFunctionReturn(0);
2237 }
2238 
2239 #undef __FUNCT__
2240 #define __FUNCT__ "TSEvaluateStep"
2241 /*@
2242    TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy.
2243 
2244    Collective on TS
2245 
2246    Input Arguments:
2247 +  ts - time stepping context
2248 .  order - desired order of accuracy
2249 -  done - whether the step was evaluated at this order (pass PETSC_NULL to generate an error if not available)
2250 
2251    Output Arguments:
2252 .  U - state at the end of the current step
2253 
2254    Level: advanced
2255 
2256    Notes:
2257    This function cannot be called until all stages have been evaluated.
2258    It is normally called by adaptive controllers before a step has been accepted and may also be called by the user after TSStep() has returned.
2259 
2260 .seealso: TSStep(), TSAdapt
2261 @*/
2262 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done)
2263 {
2264   PetscErrorCode ierr;
2265 
2266   PetscFunctionBegin;
2267   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2268   PetscValidType(ts,1);
2269   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
2270   if (!ts->ops->evaluatestep) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name);
2271   ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr);
2272   PetscFunctionReturn(0);
2273 }
2274 
2275 #undef __FUNCT__
2276 #define __FUNCT__ "TSSolve"
2277 /*@
2278    TSSolve - Steps the requested number of timesteps.
2279 
2280    Collective on TS
2281 
2282    Input Parameter:
2283 +  ts - the TS context obtained from TSCreate()
2284 -  u - the solution vector  (can be null if TSSetSolution() was used, otherwise must contain the initial conditions)
2285 
2286    Level: beginner
2287 
2288    Notes:
2289    The final time returned by this function may be different from the time of the internally
2290    held state accessible by TSGetSolution() and TSGetTime() because the method may have
2291    stepped over the final time.
2292 
2293 .keywords: TS, timestep, solve
2294 
2295 .seealso: TSCreate(), TSSetSolution(), TSStep()
2296 @*/
2297 PetscErrorCode TSSolve(TS ts,Vec u)
2298 {
2299   PetscBool      flg;
2300   char           filename[PETSC_MAX_PATH_LEN];
2301   PetscViewer    viewer;
2302   PetscErrorCode ierr;
2303 
2304   PetscFunctionBegin;
2305   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2306   if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2);
2307   if (ts->exact_final_time) {   /* Need ts->vec_sol to be distinct so it is not overwritten when we interpolate at the end */
2308     if (!ts->vec_sol || u == ts->vec_sol) {
2309       Vec y;
2310       ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
2311       ierr = TSSetSolution(ts,y);CHKERRQ(ierr);
2312       ierr = VecDestroy(&y);CHKERRQ(ierr); /* grant ownership */
2313     }
2314     if (u) {
2315       ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr);
2316     }
2317   } else {
2318     if (u) {
2319       ierr = TSSetSolution(ts,u);CHKERRQ(ierr);
2320     }
2321   }
2322   ierr = TSSetUp(ts);CHKERRQ(ierr);
2323   /* reset time step and iteration counters */
2324   ts->steps = 0;
2325   ts->ksp_its = 0;
2326   ts->snes_its = 0;
2327   ts->num_snes_failures = 0;
2328   ts->reject = 0;
2329   ts->reason = TS_CONVERGED_ITERATING;
2330 
2331   if (ts->ops->solve) {         /* This private interface is transitional and should be removed when all implementations are updated. */
2332     ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr);
2333     ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);
2334     ts->solvetime = ts->ptime;
2335   } else {
2336     /* steps the requested number of timesteps. */
2337     ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
2338     if (ts->steps >= ts->max_steps)
2339       ts->reason = TS_CONVERGED_ITS;
2340     else if (ts->ptime >= ts->max_time)
2341       ts->reason = TS_CONVERGED_TIME;
2342     while (!ts->reason) {
2343       ierr = TSStep(ts);CHKERRQ(ierr);
2344       ierr = TSPostStep(ts);CHKERRQ(ierr);
2345       ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
2346     }
2347     if (ts->exact_final_time && ts->ptime > ts->max_time) {
2348       ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr);
2349       ts->solvetime = ts->max_time;
2350     } else {
2351       ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);
2352       ts->solvetime = ts->ptime;
2353     }
2354   }
2355   ierr = TSMonitor(ts,-1,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
2356   ierr = PetscOptionsGetString(((PetscObject)ts)->prefix,"-ts_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
2357   if (flg && !PetscPreLoadingOn) {
2358     ierr = PetscViewerASCIIOpen(((PetscObject)ts)->comm,filename,&viewer);CHKERRQ(ierr);
2359     ierr = TSView(ts,viewer);CHKERRQ(ierr);
2360     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
2361   }
2362   PetscFunctionReturn(0);
2363 }
2364 
2365 #undef __FUNCT__
2366 #define __FUNCT__ "TSMonitor"
2367 /*@
2368    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()
2369 
2370    Collective on TS
2371 
2372    Input Parameters:
2373 +  ts - time stepping context obtained from TSCreate()
2374 .  step - step number that has just completed
2375 .  ptime - model time of the state
2376 -  u - state at the current model time
2377 
2378    Notes:
2379    TSMonitor() is typically used within the time stepping implementations.
2380    Users might call this function when using the TSStep() interface instead of TSSolve().
2381 
2382    Level: advanced
2383 
2384 .keywords: TS, timestep
2385 @*/
2386 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u)
2387 {
2388   PetscErrorCode ierr;
2389   PetscInt       i,n = ts->numbermonitors;
2390 
2391   PetscFunctionBegin;
2392   for (i=0; i<n; i++) {
2393     ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr);
2394   }
2395   PetscFunctionReturn(0);
2396 }
2397 
2398 /* ------------------------------------------------------------------------*/
2399 struct _n_TSMonitorLGCtx {
2400   PetscDrawLG lg;
2401   PetscInt    howoften;  /* when > 0 uses step % howoften, when negative only final solution plotted */
2402   PetscInt    ksp_its,snes_its;
2403 };
2404 
2405 
2406 #undef __FUNCT__
2407 #define __FUNCT__ "TSMonitorLGCtxCreate"
2408 /*@C
2409    TSMonitorLGCtxCreate - Creates a line graph context for use with
2410    TS to monitor the solution process graphically in various ways
2411 
2412    Collective on TS
2413 
2414    Input Parameters:
2415 +  host - the X display to open, or null for the local machine
2416 .  label - the title to put in the title bar
2417 .  x, y - the screen coordinates of the upper left coordinate of the window
2418 .  m, n - the screen width and height in pixels
2419 -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
2420 
2421    Output Parameter:
2422 .  ctx - the context
2423 
2424    Options Database Key:
2425 +  -ts_monitor_lg_timestep - automatically sets line graph monitor
2426 .  -ts_monitor_lg_solution -
2427 .  -ts_monitor_lg_error -
2428 .  -ts_monitor_lg_ksp_iterations -
2429 .  -ts_monitor_lg_snes_iterations -
2430 -  -lg_indicate_data_points <true,false> - indicate the data points (at each time step) on the plot; default is true
2431 
2432    Notes:
2433    Use TSMonitorLGCtxDestroy() to destroy.
2434 
2435    Level: intermediate
2436 
2437 .keywords: TS, monitor, line graph, residual, seealso
2438 
2439 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError()
2440 
2441 @*/
2442 PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
2443 {
2444   PetscDraw      win;
2445   PetscErrorCode ierr;
2446   PetscBool      flg = PETSC_TRUE;
2447 
2448   PetscFunctionBegin;
2449   ierr = PetscNew(struct _n_TSMonitorLGCtx,ctx);CHKERRQ(ierr);
2450   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&win);CHKERRQ(ierr);
2451   ierr = PetscDrawSetFromOptions(win);CHKERRQ(ierr);
2452   ierr = PetscDrawLGCreate(win,1,&(*ctx)->lg);CHKERRQ(ierr);
2453   ierr = PetscOptionsGetBool(PETSC_NULL,"-lg_indicate_data_points",&flg,PETSC_NULL);CHKERRQ(ierr);
2454   if (flg) {
2455     ierr = PetscDrawLGIndicateDataPoints((*ctx)->lg);CHKERRQ(ierr);
2456   }
2457   ierr = PetscLogObjectParent((*ctx)->lg,win);CHKERRQ(ierr);
2458   (*ctx)->howoften = howoften;
2459   PetscFunctionReturn(0);
2460 }
2461 
2462 #undef __FUNCT__
2463 #define __FUNCT__ "TSMonitorLGTimeStep"
2464 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
2465 {
2466   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
2467   PetscReal      x = ptime,y;
2468   PetscErrorCode ierr;
2469 
2470   PetscFunctionBegin;
2471   if (!n) {
2472     PetscDrawAxis  axis;
2473     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
2474     ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time","Time step");CHKERRQ(ierr);
2475     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
2476   }
2477   ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr);
2478   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
2479   if (((ctx->howoften > 0) && (!(n % ctx->howoften))) || ((ctx->howoften == -1) && (n == -1))){
2480     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
2481   }
2482   PetscFunctionReturn(0);
2483 }
2484 
2485 #undef __FUNCT__
2486 #define __FUNCT__ "TSMonitorLGCtxDestroy"
2487 /*@C
2488    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
2489    with TSMonitorLGCtxCreate().
2490 
2491    Collective on TSMonitorLGCtx
2492 
2493    Input Parameter:
2494 .  ctx - the monitor context
2495 
2496    Level: intermediate
2497 
2498 .keywords: TS, monitor, line graph, destroy
2499 
2500 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep();
2501 @*/
2502 PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
2503 {
2504   PetscDraw      draw;
2505   PetscErrorCode ierr;
2506 
2507   PetscFunctionBegin;
2508   ierr = PetscDrawLGGetDraw((*ctx)->lg,&draw);CHKERRQ(ierr);
2509   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
2510   ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr);
2511   ierr = PetscFree(*ctx);CHKERRQ(ierr);
2512   PetscFunctionReturn(0);
2513 }
2514 
2515 #undef __FUNCT__
2516 #define __FUNCT__ "TSGetTime"
2517 /*@
2518    TSGetTime - Gets the time of the most recently completed step.
2519 
2520    Not Collective
2521 
2522    Input Parameter:
2523 .  ts - the TS context obtained from TSCreate()
2524 
2525    Output Parameter:
2526 .  t  - the current time
2527 
2528    Level: beginner
2529 
2530    Note:
2531    When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(),
2532    TSSetPreStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated.
2533 
2534 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
2535 
2536 .keywords: TS, get, time
2537 @*/
2538 PetscErrorCode  TSGetTime(TS ts,PetscReal* t)
2539 {
2540   PetscFunctionBegin;
2541   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2542   PetscValidRealPointer(t,2);
2543   *t = ts->ptime;
2544   PetscFunctionReturn(0);
2545 }
2546 
2547 #undef __FUNCT__
2548 #define __FUNCT__ "TSSetTime"
2549 /*@
2550    TSSetTime - Allows one to reset the time.
2551 
2552    Logically Collective on TS
2553 
2554    Input Parameters:
2555 +  ts - the TS context obtained from TSCreate()
2556 -  time - the time
2557 
2558    Level: intermediate
2559 
2560 .seealso: TSGetTime(), TSSetDuration()
2561 
2562 .keywords: TS, set, time
2563 @*/
2564 PetscErrorCode  TSSetTime(TS ts, PetscReal t)
2565 {
2566   PetscFunctionBegin;
2567   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2568   PetscValidLogicalCollectiveReal(ts,t,2);
2569   ts->ptime = t;
2570   PetscFunctionReturn(0);
2571 }
2572 
2573 #undef __FUNCT__
2574 #define __FUNCT__ "TSSetOptionsPrefix"
2575 /*@C
2576    TSSetOptionsPrefix - Sets the prefix used for searching for all
2577    TS options in the database.
2578 
2579    Logically Collective on TS
2580 
2581    Input Parameter:
2582 +  ts     - The TS context
2583 -  prefix - The prefix to prepend to all option names
2584 
2585    Notes:
2586    A hyphen (-) must NOT be given at the beginning of the prefix name.
2587    The first character of all runtime options is AUTOMATICALLY the
2588    hyphen.
2589 
2590    Level: advanced
2591 
2592 .keywords: TS, set, options, prefix, database
2593 
2594 .seealso: TSSetFromOptions()
2595 
2596 @*/
2597 PetscErrorCode  TSSetOptionsPrefix(TS ts,const char prefix[])
2598 {
2599   PetscErrorCode ierr;
2600   SNES           snes;
2601 
2602   PetscFunctionBegin;
2603   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2604   ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2605   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2606   ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr);
2607   PetscFunctionReturn(0);
2608 }
2609 
2610 
2611 #undef __FUNCT__
2612 #define __FUNCT__ "TSAppendOptionsPrefix"
2613 /*@C
2614    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
2615    TS options in the database.
2616 
2617    Logically Collective on TS
2618 
2619    Input Parameter:
2620 +  ts     - The TS context
2621 -  prefix - The prefix to prepend to all option names
2622 
2623    Notes:
2624    A hyphen (-) must NOT be given at the beginning of the prefix name.
2625    The first character of all runtime options is AUTOMATICALLY the
2626    hyphen.
2627 
2628    Level: advanced
2629 
2630 .keywords: TS, append, options, prefix, database
2631 
2632 .seealso: TSGetOptionsPrefix()
2633 
2634 @*/
2635 PetscErrorCode  TSAppendOptionsPrefix(TS ts,const char prefix[])
2636 {
2637   PetscErrorCode ierr;
2638   SNES           snes;
2639 
2640   PetscFunctionBegin;
2641   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2642   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2643   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2644   ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr);
2645   PetscFunctionReturn(0);
2646 }
2647 
2648 #undef __FUNCT__
2649 #define __FUNCT__ "TSGetOptionsPrefix"
2650 /*@C
2651    TSGetOptionsPrefix - Sets the prefix used for searching for all
2652    TS options in the database.
2653 
2654    Not Collective
2655 
2656    Input Parameter:
2657 .  ts - The TS context
2658 
2659    Output Parameter:
2660 .  prefix - A pointer to the prefix string used
2661 
2662    Notes: On the fortran side, the user should pass in a string 'prifix' of
2663    sufficient length to hold the prefix.
2664 
2665    Level: intermediate
2666 
2667 .keywords: TS, get, options, prefix, database
2668 
2669 .seealso: TSAppendOptionsPrefix()
2670 @*/
2671 PetscErrorCode  TSGetOptionsPrefix(TS ts,const char *prefix[])
2672 {
2673   PetscErrorCode ierr;
2674 
2675   PetscFunctionBegin;
2676   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2677   PetscValidPointer(prefix,2);
2678   ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2679   PetscFunctionReturn(0);
2680 }
2681 
2682 #undef __FUNCT__
2683 #define __FUNCT__ "TSGetRHSJacobian"
2684 /*@C
2685    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
2686 
2687    Not Collective, but parallel objects are returned if TS is parallel
2688 
2689    Input Parameter:
2690 .  ts  - The TS context obtained from TSCreate()
2691 
2692    Output Parameters:
2693 +  J   - The Jacobian J of F, where U_t = G(U,t)
2694 .  M   - The preconditioner matrix, usually the same as J
2695 .  func - Function to compute the Jacobian of the RHS
2696 -  ctx - User-defined context for Jacobian evaluation routine
2697 
2698    Notes: You can pass in PETSC_NULL for any return argument you do not need.
2699 
2700    Level: intermediate
2701 
2702 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
2703 
2704 .keywords: TS, timestep, get, matrix, Jacobian
2705 @*/
2706 PetscErrorCode  TSGetRHSJacobian(TS ts,Mat *J,Mat *M,TSRHSJacobian *func,void **ctx)
2707 {
2708   PetscErrorCode ierr;
2709   SNES           snes;
2710   DM             dm;
2711 
2712   PetscFunctionBegin;
2713   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2714   ierr = SNESGetJacobian(snes,J,M,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2715   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2716   ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr);
2717   PetscFunctionReturn(0);
2718 }
2719 
2720 #undef __FUNCT__
2721 #define __FUNCT__ "TSGetIJacobian"
2722 /*@C
2723    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
2724 
2725    Not Collective, but parallel objects are returned if TS is parallel
2726 
2727    Input Parameter:
2728 .  ts  - The TS context obtained from TSCreate()
2729 
2730    Output Parameters:
2731 +  A   - The Jacobian of F(t,U,U_t)
2732 .  B   - The preconditioner matrix, often the same as A
2733 .  f   - The function to compute the matrices
2734 - ctx - User-defined context for Jacobian evaluation routine
2735 
2736    Notes: You can pass in PETSC_NULL for any return argument you do not need.
2737 
2738    Level: advanced
2739 
2740 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
2741 
2742 .keywords: TS, timestep, get, matrix, Jacobian
2743 @*/
2744 PetscErrorCode  TSGetIJacobian(TS ts,Mat *A,Mat *B,TSIJacobian *f,void **ctx)
2745 {
2746   PetscErrorCode ierr;
2747   SNES           snes;
2748   DM             dm;
2749 
2750   PetscFunctionBegin;
2751   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2752   ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
2753   ierr = SNESGetJacobian(snes,A,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2754   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2755   ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr);
2756   PetscFunctionReturn(0);
2757 }
2758 
2759 struct _n_TSMonitorDrawCtx {
2760   PetscViewer viewer;
2761   Vec         initialsolution;
2762   PetscBool   showinitial;
2763   PetscInt    howoften;  /* when > 0 uses step % howoften, when negative only final solution plotted */
2764 };
2765 
2766 #undef __FUNCT__
2767 #define __FUNCT__ "TSMonitorDrawSolution"
2768 /*@C
2769    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
2770    VecView() for the solution at each timestep
2771 
2772    Collective on TS
2773 
2774    Input Parameters:
2775 +  ts - the TS context
2776 .  step - current time-step
2777 .  ptime - current time
2778 -  dummy - either a viewer or PETSC_NULL
2779 
2780    Options Database:
2781 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
2782 
2783    Notes: the initial solution and current solution are not displayed with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
2784        will look bad
2785 
2786    Level: intermediate
2787 
2788 .keywords: TS,  vector, monitor, view
2789 
2790 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
2791 @*/
2792 PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
2793 {
2794   PetscErrorCode   ierr;
2795   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
2796 
2797   PetscFunctionBegin;
2798   if (!step && ictx->showinitial) {
2799     if (!ictx->initialsolution) {
2800       ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr);
2801     }
2802     ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr);
2803   }
2804   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften)) && (step > -1)) || ((ictx->howoften == -1) && (step == -1)))) PetscFunctionReturn(0);
2805 
2806   if (ictx->showinitial) {
2807     PetscReal pause;
2808     ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr);
2809     ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr);
2810     ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr);
2811     ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr);
2812     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr);
2813   }
2814   ierr = VecView(u,ictx->viewer);CHKERRQ(ierr);
2815   if (ictx->showinitial) {
2816     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr);
2817   }
2818   PetscFunctionReturn(0);
2819 }
2820 
2821 
2822 #undef __FUNCT__
2823 #define __FUNCT__ "TSMonitorDrawCtxDestroy"
2824 /*@C
2825    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
2826 
2827    Collective on TS
2828 
2829    Input Parameters:
2830 .    ctx - the monitor context
2831 
2832    Level: intermediate
2833 
2834 .keywords: TS,  vector, monitor, view
2835 
2836 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError()
2837 @*/
2838 PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
2839 {
2840   PetscErrorCode       ierr;
2841 
2842   PetscFunctionBegin;
2843   ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr);
2844   ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr);
2845   ierr = PetscFree(*ictx);CHKERRQ(ierr);
2846   PetscFunctionReturn(0);
2847 }
2848 
2849 #undef __FUNCT__
2850 #define __FUNCT__ "TSMonitorDrawCtxCreate"
2851 /*@C
2852    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
2853 
2854    Collective on TS
2855 
2856    Input Parameter:
2857 .    ts - time-step context
2858 
2859    Output Patameter:
2860 .    ctx - the monitor context
2861 
2862    Options Database:
2863 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
2864 
2865    Level: intermediate
2866 
2867 .keywords: TS,  vector, monitor, view
2868 
2869 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx()
2870 @*/
2871 PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
2872 {
2873   PetscErrorCode   ierr;
2874 
2875   PetscFunctionBegin;
2876   ierr = PetscNew(struct _n_TSMonitorDrawCtx,ctx);CHKERRQ(ierr);
2877   ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr);
2878   (*ctx)->showinitial = PETSC_FALSE;
2879   (*ctx)->howoften    = howoften;
2880   ierr = PetscOptionsGetBool(PETSC_NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,PETSC_NULL);CHKERRQ(ierr);
2881   PetscFunctionReturn(0);
2882 }
2883 
2884 #undef __FUNCT__
2885 #define __FUNCT__ "TSMonitorDrawError"
2886 /*@C
2887    TSMonitorDrawError - Monitors progress of the TS solvers by calling
2888    VecView() for the error at each timestep
2889 
2890    Collective on TS
2891 
2892    Input Parameters:
2893 +  ts - the TS context
2894 .  step - current time-step
2895 .  ptime - current time
2896 -  dummy - either a viewer or PETSC_NULL
2897 
2898    Level: intermediate
2899 
2900 .keywords: TS,  vector, monitor, view
2901 
2902 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
2903 @*/
2904 PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
2905 {
2906   PetscErrorCode   ierr;
2907   TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy;
2908   PetscViewer      viewer = ctx->viewer;
2909   Vec              work;
2910 
2911   PetscFunctionBegin;
2912   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1)))) PetscFunctionReturn(0);
2913   ierr = VecDuplicate(u,&work);CHKERRQ(ierr);
2914   ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr);
2915   ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr);
2916   ierr = VecView(work,viewer);CHKERRQ(ierr);
2917   ierr = VecDestroy(&work);CHKERRQ(ierr);
2918   PetscFunctionReturn(0);
2919 }
2920 
2921 #include <petsc-private/dmimpl.h>
2922 #undef __FUNCT__
2923 #define __FUNCT__ "TSSetDM"
2924 /*@
2925    TSSetDM - Sets the DM that may be used by some preconditioners
2926 
2927    Logically Collective on TS and DM
2928 
2929    Input Parameters:
2930 +  ts - the preconditioner context
2931 -  dm - the dm
2932 
2933    Level: intermediate
2934 
2935 
2936 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM()
2937 @*/
2938 PetscErrorCode  TSSetDM(TS ts,DM dm)
2939 {
2940   PetscErrorCode ierr;
2941   SNES           snes;
2942   DMTS           tsdm;
2943 
2944   PetscFunctionBegin;
2945   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2946   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
2947   if (ts->dm) {               /* Move the DMTS context over to the new DM unless the new DM already has one */
2948     if (ts->dm->dmts && !dm->dmts) {
2949       ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr);
2950       ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr);
2951       if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */
2952         tsdm->originaldm = dm;
2953       }
2954     }
2955     ierr = DMDestroy(&ts->dm);CHKERRQ(ierr);
2956   }
2957   ts->dm = dm;
2958   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2959   ierr = SNESSetDM(snes,dm);CHKERRQ(ierr);
2960   PetscFunctionReturn(0);
2961 }
2962 
2963 #undef __FUNCT__
2964 #define __FUNCT__ "TSGetDM"
2965 /*@
2966    TSGetDM - Gets the DM that may be used by some preconditioners
2967 
2968    Not Collective
2969 
2970    Input Parameter:
2971 . ts - the preconditioner context
2972 
2973    Output Parameter:
2974 .  dm - the dm
2975 
2976    Level: intermediate
2977 
2978 
2979 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM()
2980 @*/
2981 PetscErrorCode  TSGetDM(TS ts,DM *dm)
2982 {
2983   PetscErrorCode ierr;
2984 
2985   PetscFunctionBegin;
2986   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2987   if (!ts->dm) {
2988     ierr = DMShellCreate(((PetscObject)ts)->comm,&ts->dm);CHKERRQ(ierr);
2989     if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
2990   }
2991   *dm = ts->dm;
2992   PetscFunctionReturn(0);
2993 }
2994 
2995 #undef __FUNCT__
2996 #define __FUNCT__ "SNESTSFormFunction"
2997 /*@
2998    SNESTSFormFunction - Function to evaluate nonlinear residual
2999 
3000    Logically Collective on SNES
3001 
3002    Input Parameter:
3003 + snes - nonlinear solver
3004 . U - the current state at which to evaluate the residual
3005 - ctx - user context, must be a TS
3006 
3007    Output Parameter:
3008 . F - the nonlinear residual
3009 
3010    Notes:
3011    This function is not normally called by users and is automatically registered with the SNES used by TS.
3012    It is most frequently passed to MatFDColoringSetFunction().
3013 
3014    Level: advanced
3015 
3016 .seealso: SNESSetFunction(), MatFDColoringSetFunction()
3017 @*/
3018 PetscErrorCode  SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx)
3019 {
3020   TS             ts = (TS)ctx;
3021   PetscErrorCode ierr;
3022 
3023   PetscFunctionBegin;
3024   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3025   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
3026   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
3027   PetscValidHeaderSpecific(ts,TS_CLASSID,4);
3028   ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr);
3029   PetscFunctionReturn(0);
3030 }
3031 
3032 #undef __FUNCT__
3033 #define __FUNCT__ "SNESTSFormJacobian"
3034 /*@
3035    SNESTSFormJacobian - Function to evaluate the Jacobian
3036 
3037    Collective on SNES
3038 
3039    Input Parameter:
3040 + snes - nonlinear solver
3041 . U - the current state at which to evaluate the residual
3042 - ctx - user context, must be a TS
3043 
3044    Output Parameter:
3045 + A - the Jacobian
3046 . B - the preconditioning matrix (may be the same as A)
3047 - flag - indicates any structure change in the matrix
3048 
3049    Notes:
3050    This function is not normally called by users and is automatically registered with the SNES used by TS.
3051 
3052    Level: developer
3053 
3054 .seealso: SNESSetJacobian()
3055 @*/
3056 PetscErrorCode  SNESTSFormJacobian(SNES snes,Vec U,Mat *A,Mat *B,MatStructure *flag,void *ctx)
3057 {
3058   TS             ts = (TS)ctx;
3059   PetscErrorCode ierr;
3060 
3061   PetscFunctionBegin;
3062   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3063   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
3064   PetscValidPointer(A,3);
3065   PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
3066   PetscValidPointer(B,4);
3067   PetscValidHeaderSpecific(*B,MAT_CLASSID,4);
3068   PetscValidPointer(flag,5);
3069   PetscValidHeaderSpecific(ts,TS_CLASSID,6);
3070   ierr = (ts->ops->snesjacobian)(snes,U,A,B,flag,ts);CHKERRQ(ierr);
3071   PetscFunctionReturn(0);
3072 }
3073 
3074 #undef __FUNCT__
3075 #define __FUNCT__ "TSComputeRHSFunctionLinear"
3076 /*@C
3077    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only
3078 
3079    Collective on TS
3080 
3081    Input Arguments:
3082 +  ts - time stepping context
3083 .  t - time at which to evaluate
3084 .  U - state at which to evaluate
3085 -  ctx - context
3086 
3087    Output Arguments:
3088 .  F - right hand side
3089 
3090    Level: intermediate
3091 
3092    Notes:
3093    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
3094    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().
3095 
3096 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
3097 @*/
3098 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx)
3099 {
3100   PetscErrorCode ierr;
3101   Mat            Arhs,Brhs;
3102   MatStructure   flg2;
3103 
3104   PetscFunctionBegin;
3105   ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
3106   ierr = TSComputeRHSJacobian(ts,t,U,&Arhs,&Brhs,&flg2);CHKERRQ(ierr);
3107   ierr = MatMult(Arhs,U,F);CHKERRQ(ierr);
3108   PetscFunctionReturn(0);
3109 }
3110 
3111 #undef __FUNCT__
3112 #define __FUNCT__ "TSComputeRHSJacobianConstant"
3113 /*@C
3114    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
3115 
3116    Collective on TS
3117 
3118    Input Arguments:
3119 +  ts - time stepping context
3120 .  t - time at which to evaluate
3121 .  U - state at which to evaluate
3122 -  ctx - context
3123 
3124    Output Arguments:
3125 +  A - pointer to operator
3126 .  B - pointer to preconditioning matrix
3127 -  flg - matrix structure flag
3128 
3129    Level: intermediate
3130 
3131    Notes:
3132    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.
3133 
3134 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear()
3135 @*/
3136 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat *A,Mat *B,MatStructure *flg,void *ctx)
3137 {
3138   PetscFunctionBegin;
3139   *flg = SAME_PRECONDITIONER;
3140   PetscFunctionReturn(0);
3141 }
3142 
3143 #undef __FUNCT__
3144 #define __FUNCT__ "TSComputeIFunctionLinear"
3145 /*@C
3146    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
3147 
3148    Collective on TS
3149 
3150    Input Arguments:
3151 +  ts - time stepping context
3152 .  t - time at which to evaluate
3153 .  U - state at which to evaluate
3154 .  Udot - time derivative of state vector
3155 -  ctx - context
3156 
3157    Output Arguments:
3158 .  F - left hand side
3159 
3160    Level: intermediate
3161 
3162    Notes:
3163    The assumption here is that the left hand side is of the form A*Udot (and not A*Udot + B*U). For other cases, the
3164    user is required to write their own TSComputeIFunction.
3165    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
3166    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().
3167 
3168 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant()
3169 @*/
3170 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx)
3171 {
3172   PetscErrorCode ierr;
3173   Mat            A,B;
3174   MatStructure   flg2;
3175 
3176   PetscFunctionBegin;
3177   ierr = TSGetIJacobian(ts,&A,&B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
3178   ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,&A,&B,&flg2,PETSC_TRUE);CHKERRQ(ierr);
3179   ierr = MatMult(A,Udot,F);CHKERRQ(ierr);
3180   PetscFunctionReturn(0);
3181 }
3182 
3183 #undef __FUNCT__
3184 #define __FUNCT__ "TSComputeIJacobianConstant"
3185 /*@C
3186    TSComputeIJacobianConstant - Reuses a Jacobian that is time-independent.
3187 
3188    Collective on TS
3189 
3190    Input Arguments:
3191 +  ts - time stepping context
3192 .  t - time at which to evaluate
3193 .  U - state at which to evaluate
3194 .  Udot - time derivative of state vector
3195 .  shift - shift to apply
3196 -  ctx - context
3197 
3198    Output Arguments:
3199 +  A - pointer to operator
3200 .  B - pointer to preconditioning matrix
3201 -  flg - matrix structure flag
3202 
3203    Level: intermediate
3204 
3205    Notes:
3206    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.
3207 
3208 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear()
3209 @*/
3210 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,void *ctx)
3211 {
3212   PetscFunctionBegin;
3213   *flg = SAME_PRECONDITIONER;
3214   PetscFunctionReturn(0);
3215 }
3216 
3217 #undef __FUNCT__
3218 #define __FUNCT__ "TSGetConvergedReason"
3219 /*@
3220    TSGetConvergedReason - Gets the reason the TS iteration was stopped.
3221 
3222    Not Collective
3223 
3224    Input Parameter:
3225 .  ts - the TS context
3226 
3227    Output Parameter:
3228 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
3229             manual pages for the individual convergence tests for complete lists
3230 
3231    Level: beginner
3232 
3233    Notes:
3234    Can only be called after the call to TSSolve() is complete.
3235 
3236 .keywords: TS, nonlinear, set, convergence, test
3237 
3238 .seealso: TSSetConvergenceTest(), TSConvergedReason
3239 @*/
3240 PetscErrorCode  TSGetConvergedReason(TS ts,TSConvergedReason *reason)
3241 {
3242   PetscFunctionBegin;
3243   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3244   PetscValidPointer(reason,2);
3245   *reason = ts->reason;
3246   PetscFunctionReturn(0);
3247 }
3248 
3249 #undef __FUNCT__
3250 #define __FUNCT__ "TSGetSolveTime"
3251 /*@
3252    TSGetSolveTime - Gets the time after a call to TSSolve()
3253 
3254    Not Collective
3255 
3256    Input Parameter:
3257 .  ts - the TS context
3258 
3259    Output Parameter:
3260 .  ftime - the final time. This time should correspond to the final time set with TSSetDuration()
3261 
3262    Level: beginner
3263 
3264    Notes:
3265    Can only be called after the call to TSSolve() is complete.
3266 
3267 .keywords: TS, nonlinear, set, convergence, test
3268 
3269 .seealso: TSSetConvergenceTest(), TSConvergedReason
3270 @*/
3271 PetscErrorCode  TSGetSolveTime(TS ts,PetscReal *ftime)
3272 {
3273   PetscFunctionBegin;
3274   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3275   PetscValidPointer(ftime,2);
3276   *ftime = ts->solvetime;
3277   PetscFunctionReturn(0);
3278 }
3279 
3280 #undef __FUNCT__
3281 #define __FUNCT__ "TSGetSNESIterations"
3282 /*@
3283    TSGetSNESIterations - Gets the total number of nonlinear iterations
3284    used by the time integrator.
3285 
3286    Not Collective
3287 
3288    Input Parameter:
3289 .  ts - TS context
3290 
3291    Output Parameter:
3292 .  nits - number of nonlinear iterations
3293 
3294    Notes:
3295    This counter is reset to zero for each successive call to TSSolve().
3296 
3297    Level: intermediate
3298 
3299 .keywords: TS, get, number, nonlinear, iterations
3300 
3301 .seealso:  TSGetKSPIterations()
3302 @*/
3303 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits)
3304 {
3305   PetscFunctionBegin;
3306   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3307   PetscValidIntPointer(nits,2);
3308   *nits = ts->snes_its;
3309   PetscFunctionReturn(0);
3310 }
3311 
3312 #undef __FUNCT__
3313 #define __FUNCT__ "TSGetKSPIterations"
3314 /*@
3315    TSGetKSPIterations - Gets the total number of linear iterations
3316    used by the time integrator.
3317 
3318    Not Collective
3319 
3320    Input Parameter:
3321 .  ts - TS context
3322 
3323    Output Parameter:
3324 .  lits - number of linear iterations
3325 
3326    Notes:
3327    This counter is reset to zero for each successive call to TSSolve().
3328 
3329    Level: intermediate
3330 
3331 .keywords: TS, get, number, linear, iterations
3332 
3333 .seealso:  TSGetSNESIterations(), SNESGetKSPIterations()
3334 @*/
3335 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits)
3336 {
3337   PetscFunctionBegin;
3338   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3339   PetscValidIntPointer(lits,2);
3340   *lits = ts->ksp_its;
3341   PetscFunctionReturn(0);
3342 }
3343 
3344 #undef __FUNCT__
3345 #define __FUNCT__ "TSGetStepRejections"
3346 /*@
3347    TSGetStepRejections - Gets the total number of rejected steps.
3348 
3349    Not Collective
3350 
3351    Input Parameter:
3352 .  ts - TS context
3353 
3354    Output Parameter:
3355 .  rejects - number of steps rejected
3356 
3357    Notes:
3358    This counter is reset to zero for each successive call to TSSolve().
3359 
3360    Level: intermediate
3361 
3362 .keywords: TS, get, number
3363 
3364 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails()
3365 @*/
3366 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects)
3367 {
3368   PetscFunctionBegin;
3369   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3370   PetscValidIntPointer(rejects,2);
3371   *rejects = ts->reject;
3372   PetscFunctionReturn(0);
3373 }
3374 
3375 #undef __FUNCT__
3376 #define __FUNCT__ "TSGetSNESFailures"
3377 /*@
3378    TSGetSNESFailures - Gets the total number of failed SNES solves
3379 
3380    Not Collective
3381 
3382    Input Parameter:
3383 .  ts - TS context
3384 
3385    Output Parameter:
3386 .  fails - number of failed nonlinear solves
3387 
3388    Notes:
3389    This counter is reset to zero for each successive call to TSSolve().
3390 
3391    Level: intermediate
3392 
3393 .keywords: TS, get, number
3394 
3395 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures()
3396 @*/
3397 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails)
3398 {
3399   PetscFunctionBegin;
3400   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3401   PetscValidIntPointer(fails,2);
3402   *fails = ts->num_snes_failures;
3403   PetscFunctionReturn(0);
3404 }
3405 
3406 #undef __FUNCT__
3407 #define __FUNCT__ "TSSetMaxStepRejections"
3408 /*@
3409    TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails
3410 
3411    Not Collective
3412 
3413    Input Parameter:
3414 +  ts - TS context
3415 -  rejects - maximum number of rejected steps, pass -1 for unlimited
3416 
3417    Notes:
3418    The counter is reset to zero for each step
3419 
3420    Options Database Key:
3421  .  -ts_max_reject - Maximum number of step rejections before a step fails
3422 
3423    Level: intermediate
3424 
3425 .keywords: TS, set, maximum, number
3426 
3427 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
3428 @*/
3429 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects)
3430 {
3431   PetscFunctionBegin;
3432   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3433   ts->max_reject = rejects;
3434   PetscFunctionReturn(0);
3435 }
3436 
3437 #undef __FUNCT__
3438 #define __FUNCT__ "TSSetMaxSNESFailures"
3439 /*@
3440    TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves
3441 
3442    Not Collective
3443 
3444    Input Parameter:
3445 +  ts - TS context
3446 -  fails - maximum number of failed nonlinear solves, pass -1 for unlimited
3447 
3448    Notes:
3449    The counter is reset to zero for each successive call to TSSolve().
3450 
3451    Options Database Key:
3452  .  -ts_max_snes_failures - Maximum number of nonlinear solve failures
3453 
3454    Level: intermediate
3455 
3456 .keywords: TS, set, maximum, number
3457 
3458 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason()
3459 @*/
3460 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails)
3461 {
3462   PetscFunctionBegin;
3463   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3464   ts->max_snes_failures = fails;
3465   PetscFunctionReturn(0);
3466 }
3467 
3468 #undef __FUNCT__
3469 #define __FUNCT__ "TSSetErrorIfStepFails()"
3470 /*@
3471    TSSetErrorIfStepFails - Error if no step succeeds
3472 
3473    Not Collective
3474 
3475    Input Parameter:
3476 +  ts - TS context
3477 -  err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure
3478 
3479    Options Database Key:
3480  .  -ts_error_if_step_fails - Error if no step succeeds
3481 
3482    Level: intermediate
3483 
3484 .keywords: TS, set, error
3485 
3486 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
3487 @*/
3488 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err)
3489 {
3490   PetscFunctionBegin;
3491   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3492   ts->errorifstepfailed = err;
3493   PetscFunctionReturn(0);
3494 }
3495 
3496 #undef __FUNCT__
3497 #define __FUNCT__ "TSMonitorSolutionBinary"
3498 /*@C
3499    TSMonitorSolutionBinary - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file
3500 
3501    Collective on TS
3502 
3503    Input Parameters:
3504 +  ts - the TS context
3505 .  step - current time-step
3506 .  ptime - current time
3507 .  u - current state
3508 -  viewer - binary viewer
3509 
3510    Level: intermediate
3511 
3512 .keywords: TS,  vector, monitor, view
3513 
3514 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3515 @*/
3516 PetscErrorCode  TSMonitorSolutionBinary(TS ts,PetscInt step,PetscReal ptime,Vec u,void *viewer)
3517 {
3518   PetscErrorCode ierr;
3519   PetscViewer    v = (PetscViewer)viewer;
3520 
3521   PetscFunctionBegin;
3522   ierr = VecView(u,v);CHKERRQ(ierr);
3523   PetscFunctionReturn(0);
3524 }
3525 
3526 #undef __FUNCT__
3527 #define __FUNCT__ "TSMonitorSolutionVTK"
3528 /*@C
3529    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
3530 
3531    Collective on TS
3532 
3533    Input Parameters:
3534 +  ts - the TS context
3535 .  step - current time-step
3536 .  ptime - current time
3537 .  u - current state
3538 -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
3539 
3540    Level: intermediate
3541 
3542    Notes:
3543    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.
3544    These are named according to the file name template.
3545 
3546    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().
3547 
3548 .keywords: TS,  vector, monitor, view
3549 
3550 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3551 @*/
3552 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
3553 {
3554   PetscErrorCode ierr;
3555   char           filename[PETSC_MAX_PATH_LEN];
3556   PetscViewer    viewer;
3557 
3558   PetscFunctionBegin;
3559   ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr);
3560   ierr = PetscViewerVTKOpen(((PetscObject)ts)->comm,filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr);
3561   ierr = VecView(u,viewer);CHKERRQ(ierr);
3562   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3563   PetscFunctionReturn(0);
3564 }
3565 
3566 #undef __FUNCT__
3567 #define __FUNCT__ "TSMonitorSolutionVTKDestroy"
3568 /*@C
3569    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
3570 
3571    Collective on TS
3572 
3573    Input Parameters:
3574 .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
3575 
3576    Level: intermediate
3577 
3578    Note:
3579    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
3580 
3581 .keywords: TS,  vector, monitor, view
3582 
3583 .seealso: TSMonitorSet(), TSMonitorSolutionVTK()
3584 @*/
3585 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
3586 {
3587   PetscErrorCode ierr;
3588 
3589   PetscFunctionBegin;
3590   ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr);
3591   PetscFunctionReturn(0);
3592 }
3593 
3594 #undef __FUNCT__
3595 #define __FUNCT__ "TSGetAdapt"
3596 /*@
3597    TSGetAdapt - Get the adaptive controller context for the current method
3598 
3599    Collective on TS if controller has not been created yet
3600 
3601    Input Arguments:
3602 .  ts - time stepping context
3603 
3604    Output Arguments:
3605 .  adapt - adaptive controller
3606 
3607    Level: intermediate
3608 
3609 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose()
3610 @*/
3611 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt)
3612 {
3613   PetscErrorCode ierr;
3614 
3615   PetscFunctionBegin;
3616   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3617   PetscValidPointer(adapt,2);
3618   if (!ts->adapt) {
3619     ierr = TSAdaptCreate(((PetscObject)ts)->comm,&ts->adapt);CHKERRQ(ierr);
3620     ierr = PetscLogObjectParent(ts,ts->adapt);CHKERRQ(ierr);
3621     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr);
3622   }
3623   *adapt = ts->adapt;
3624   PetscFunctionReturn(0);
3625 }
3626 
3627 #undef __FUNCT__
3628 #define __FUNCT__ "TSSetTolerances"
3629 /*@
3630    TSSetTolerances - Set tolerances for local truncation error when using adaptive controller
3631 
3632    Logically Collective
3633 
3634    Input Arguments:
3635 +  ts - time integration context
3636 .  atol - scalar absolute tolerances, PETSC_DECIDE to leave current value
3637 .  vatol - vector of absolute tolerances or PETSC_NULL, used in preference to atol if present
3638 .  rtol - scalar relative tolerances, PETSC_DECIDE to leave current value
3639 -  vrtol - vector of relative tolerances or PETSC_NULL, used in preference to atol if present
3640 
3641    Level: beginner
3642 
3643 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances()
3644 @*/
3645 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol)
3646 {
3647   PetscErrorCode ierr;
3648 
3649   PetscFunctionBegin;
3650   if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol;
3651   if (vatol) {
3652     ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr);
3653     ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
3654     ts->vatol = vatol;
3655   }
3656   if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol;
3657   if (vrtol) {
3658     ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr);
3659     ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
3660     ts->vrtol = vrtol;
3661   }
3662   PetscFunctionReturn(0);
3663 }
3664 
3665 #undef __FUNCT__
3666 #define __FUNCT__ "TSGetTolerances"
3667 /*@
3668    TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
3669 
3670    Logically Collective
3671 
3672    Input Arguments:
3673 .  ts - time integration context
3674 
3675    Output Arguments:
3676 +  atol - scalar absolute tolerances, PETSC_NULL to ignore
3677 .  vatol - vector of absolute tolerances, PETSC_NULL to ignore
3678 .  rtol - scalar relative tolerances, PETSC_NULL to ignore
3679 -  vrtol - vector of relative tolerances, PETSC_NULL to ignore
3680 
3681    Level: beginner
3682 
3683 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances()
3684 @*/
3685 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol)
3686 {
3687   PetscFunctionBegin;
3688   if (atol)  *atol  = ts->atol;
3689   if (vatol) *vatol = ts->vatol;
3690   if (rtol)  *rtol  = ts->rtol;
3691   if (vrtol) *vrtol = ts->vrtol;
3692   PetscFunctionReturn(0);
3693 }
3694 
3695 #undef __FUNCT__
3696 #define __FUNCT__ "TSErrorNormWRMS"
3697 /*@
3698    TSErrorNormWRMS - compute a weighted norm of the difference between a vector and the current state
3699 
3700    Collective on TS
3701 
3702    Input Arguments:
3703 +  ts - time stepping context
3704 -  Y - state vector to be compared to ts->vec_sol
3705 
3706    Output Arguments:
3707 .  norm - weighted norm, a value of 1.0 is considered small
3708 
3709    Level: developer
3710 
3711 .seealso: TSSetTolerances()
3712 @*/
3713 PetscErrorCode TSErrorNormWRMS(TS ts,Vec Y,PetscReal *norm)
3714 {
3715   PetscErrorCode    ierr;
3716   PetscInt          i,n,N;
3717   const PetscScalar *u,*y;
3718   Vec               U;
3719   PetscReal         sum,gsum;
3720 
3721   PetscFunctionBegin;
3722   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3723   PetscValidHeaderSpecific(Y,VEC_CLASSID,2);
3724   PetscValidPointer(norm,3);
3725   U = ts->vec_sol;
3726   PetscCheckSameTypeAndComm(U,1,Y,2);
3727   if (U == Y) SETERRQ(((PetscObject)U)->comm,PETSC_ERR_ARG_IDN,"Y cannot be the TS solution vector");
3728 
3729   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
3730   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
3731   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
3732   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
3733   sum = 0.;
3734   if (ts->vatol && ts->vrtol) {
3735     const PetscScalar *atol,*rtol;
3736     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
3737     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
3738     for (i=0; i<n; i++) {
3739       PetscReal tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
3740       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
3741     }
3742     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
3743     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
3744   } else if (ts->vatol) {       /* vector atol, scalar rtol */
3745     const PetscScalar *atol;
3746     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
3747     for (i=0; i<n; i++) {
3748       PetscReal tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
3749       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
3750     }
3751     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
3752   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
3753     const PetscScalar *rtol;
3754     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
3755     for (i=0; i<n; i++) {
3756       PetscReal tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
3757       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
3758     }
3759     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
3760   } else {                      /* scalar atol, scalar rtol */
3761     for (i=0; i<n; i++) {
3762       PetscReal tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
3763       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
3764     }
3765   }
3766   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
3767   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
3768 
3769   ierr = MPI_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,((PetscObject)ts)->comm);CHKERRQ(ierr);
3770   *norm = PetscSqrtReal(gsum / N);
3771   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
3772   PetscFunctionReturn(0);
3773 }
3774 
3775 #undef __FUNCT__
3776 #define __FUNCT__ "TSSetCFLTimeLocal"
3777 /*@
3778    TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
3779 
3780    Logically Collective on TS
3781 
3782    Input Arguments:
3783 +  ts - time stepping context
3784 -  cfltime - maximum stable time step if using forward Euler (value can be different on each process)
3785 
3786    Note:
3787    After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
3788 
3789    Level: intermediate
3790 
3791 .seealso: TSGetCFLTime(), TSADAPTCFL
3792 @*/
3793 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime)
3794 {
3795   PetscFunctionBegin;
3796   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3797   ts->cfltime_local = cfltime;
3798   ts->cfltime = -1.;
3799   PetscFunctionReturn(0);
3800 }
3801 
3802 #undef __FUNCT__
3803 #define __FUNCT__ "TSGetCFLTime"
3804 /*@
3805    TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
3806 
3807    Collective on TS
3808 
3809    Input Arguments:
3810 .  ts - time stepping context
3811 
3812    Output Arguments:
3813 .  cfltime - maximum stable time step for forward Euler
3814 
3815    Level: advanced
3816 
3817 .seealso: TSSetCFLTimeLocal()
3818 @*/
3819 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime)
3820 {
3821   PetscErrorCode ierr;
3822 
3823   PetscFunctionBegin;
3824   if (ts->cfltime < 0) {
3825     ierr = MPI_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,((PetscObject)ts)->comm);CHKERRQ(ierr);
3826   }
3827   *cfltime = ts->cfltime;
3828   PetscFunctionReturn(0);
3829 }
3830 
3831 #undef __FUNCT__
3832 #define __FUNCT__ "TSVISetVariableBounds"
3833 /*@
3834    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
3835 
3836    Input Parameters:
3837 .  ts   - the TS context.
3838 .  xl   - lower bound.
3839 .  xu   - upper bound.
3840 
3841    Notes:
3842    If this routine is not called then the lower and upper bounds are set to
3843    SNES_VI_NINF and SNES_VI_INF respectively during SNESSetUp().
3844 
3845    Level: advanced
3846 
3847 @*/
3848 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
3849 {
3850   PetscErrorCode ierr;
3851   SNES           snes;
3852 
3853   PetscFunctionBegin;
3854   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3855   ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr);
3856   PetscFunctionReturn(0);
3857 }
3858 
3859 #if defined(PETSC_HAVE_MATLAB_ENGINE)
3860 #include <mex.h>
3861 
3862 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext;
3863 
3864 #undef __FUNCT__
3865 #define __FUNCT__ "TSComputeFunction_Matlab"
3866 /*
3867    TSComputeFunction_Matlab - Calls the function that has been set with
3868                          TSSetFunctionMatlab().
3869 
3870    Collective on TS
3871 
3872    Input Parameters:
3873 +  snes - the TS context
3874 -  u - input vector
3875 
3876    Output Parameter:
3877 .  y - function vector, as set by TSSetFunction()
3878 
3879    Notes:
3880    TSComputeFunction() is typically used within nonlinear solvers
3881    implementations, so most users would not generally call this routine
3882    themselves.
3883 
3884    Level: developer
3885 
3886 .keywords: TS, nonlinear, compute, function
3887 
3888 .seealso: TSSetFunction(), TSGetFunction()
3889 */
3890 PetscErrorCode  TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx)
3891 {
3892   PetscErrorCode   ierr;
3893   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
3894   int              nlhs = 1,nrhs = 7;
3895   mxArray          *plhs[1],*prhs[7];
3896   long long int    lx = 0,lxdot = 0,ly = 0,ls = 0;
3897 
3898   PetscFunctionBegin;
3899   PetscValidHeaderSpecific(snes,TS_CLASSID,1);
3900   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
3901   PetscValidHeaderSpecific(udot,VEC_CLASSID,4);
3902   PetscValidHeaderSpecific(y,VEC_CLASSID,5);
3903   PetscCheckSameComm(snes,1,u,3);
3904   PetscCheckSameComm(snes,1,y,5);
3905 
3906   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
3907   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
3908   ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr);
3909   ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr);
3910   prhs[0] =  mxCreateDoubleScalar((double)ls);
3911   prhs[1] =  mxCreateDoubleScalar(time);
3912   prhs[2] =  mxCreateDoubleScalar((double)lx);
3913   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
3914   prhs[4] =  mxCreateDoubleScalar((double)ly);
3915   prhs[5] =  mxCreateString(sctx->funcname);
3916   prhs[6] =  sctx->ctx;
3917   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr);
3918   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
3919   mxDestroyArray(prhs[0]);
3920   mxDestroyArray(prhs[1]);
3921   mxDestroyArray(prhs[2]);
3922   mxDestroyArray(prhs[3]);
3923   mxDestroyArray(prhs[4]);
3924   mxDestroyArray(prhs[5]);
3925   mxDestroyArray(plhs[0]);
3926   PetscFunctionReturn(0);
3927 }
3928 
3929 
3930 #undef __FUNCT__
3931 #define __FUNCT__ "TSSetFunctionMatlab"
3932 /*
3933    TSSetFunctionMatlab - Sets the function evaluation routine and function
3934    vector for use by the TS routines in solving ODEs
3935    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
3936 
3937    Logically Collective on TS
3938 
3939    Input Parameters:
3940 +  ts - the TS context
3941 -  func - function evaluation routine
3942 
3943    Calling sequence of func:
3944 $    func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx);
3945 
3946    Level: beginner
3947 
3948 .keywords: TS, nonlinear, set, function
3949 
3950 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
3951 */
3952 PetscErrorCode  TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx)
3953 {
3954   PetscErrorCode  ierr;
3955   TSMatlabContext *sctx;
3956 
3957   PetscFunctionBegin;
3958   /* currently sctx is memory bleed */
3959   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
3960   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
3961   /*
3962      This should work, but it doesn't
3963   sctx->ctx = ctx;
3964   mexMakeArrayPersistent(sctx->ctx);
3965   */
3966   sctx->ctx = mxDuplicateArray(ctx);
3967   ierr = TSSetIFunction(ts,PETSC_NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr);
3968   PetscFunctionReturn(0);
3969 }
3970 
3971 #undef __FUNCT__
3972 #define __FUNCT__ "TSComputeJacobian_Matlab"
3973 /*
3974    TSComputeJacobian_Matlab - Calls the function that has been set with
3975                          TSSetJacobianMatlab().
3976 
3977    Collective on TS
3978 
3979    Input Parameters:
3980 +  ts - the TS context
3981 .  u - input vector
3982 .  A, B - the matrices
3983 -  ctx - user context
3984 
3985    Output Parameter:
3986 .  flag - structure of the matrix
3987 
3988    Level: developer
3989 
3990 .keywords: TS, nonlinear, compute, function
3991 
3992 .seealso: TSSetFunction(), TSGetFunction()
3993 @*/
3994 PetscErrorCode  TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flag, void *ctx)
3995 {
3996   PetscErrorCode  ierr;
3997   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
3998   int             nlhs = 2,nrhs = 9;
3999   mxArray         *plhs[2],*prhs[9];
4000   long long int   lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0;
4001 
4002   PetscFunctionBegin;
4003   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4004   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
4005 
4006   /* call Matlab function in ctx with arguments u and y */
4007 
4008   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
4009   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
4010   ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr);
4011   ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr);
4012   ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr);
4013   prhs[0] =  mxCreateDoubleScalar((double)ls);
4014   prhs[1] =  mxCreateDoubleScalar((double)time);
4015   prhs[2] =  mxCreateDoubleScalar((double)lx);
4016   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
4017   prhs[4] =  mxCreateDoubleScalar((double)shift);
4018   prhs[5] =  mxCreateDoubleScalar((double)lA);
4019   prhs[6] =  mxCreateDoubleScalar((double)lB);
4020   prhs[7] =  mxCreateString(sctx->funcname);
4021   prhs[8] =  sctx->ctx;
4022   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr);
4023   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4024   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
4025   mxDestroyArray(prhs[0]);
4026   mxDestroyArray(prhs[1]);
4027   mxDestroyArray(prhs[2]);
4028   mxDestroyArray(prhs[3]);
4029   mxDestroyArray(prhs[4]);
4030   mxDestroyArray(prhs[5]);
4031   mxDestroyArray(prhs[6]);
4032   mxDestroyArray(prhs[7]);
4033   mxDestroyArray(plhs[0]);
4034   mxDestroyArray(plhs[1]);
4035   PetscFunctionReturn(0);
4036 }
4037 
4038 
4039 #undef __FUNCT__
4040 #define __FUNCT__ "TSSetJacobianMatlab"
4041 /*
4042    TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
4043    vector for use by the TS routines in solving ODEs from MATLAB. Here the function is a string containing the name of a MATLAB function
4044 
4045    Logically Collective on TS
4046 
4047    Input Parameters:
4048 +  ts - the TS context
4049 .  A,B - Jacobian matrices
4050 .  func - function evaluation routine
4051 -  ctx - user context
4052 
4053    Calling sequence of func:
4054 $    flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx);
4055 
4056 
4057    Level: developer
4058 
4059 .keywords: TS, nonlinear, set, function
4060 
4061 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
4062 */
4063 PetscErrorCode  TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx)
4064 {
4065   PetscErrorCode    ierr;
4066   TSMatlabContext *sctx;
4067 
4068   PetscFunctionBegin;
4069   /* currently sctx is memory bleed */
4070   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
4071   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4072   /*
4073      This should work, but it doesn't
4074   sctx->ctx = ctx;
4075   mexMakeArrayPersistent(sctx->ctx);
4076   */
4077   sctx->ctx = mxDuplicateArray(ctx);
4078   ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
4079   PetscFunctionReturn(0);
4080 }
4081 
4082 #undef __FUNCT__
4083 #define __FUNCT__ "TSMonitor_Matlab"
4084 /*
4085    TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab().
4086 
4087    Collective on TS
4088 
4089 .seealso: TSSetFunction(), TSGetFunction()
4090 @*/
4091 PetscErrorCode  TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx)
4092 {
4093   PetscErrorCode  ierr;
4094   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
4095   int             nlhs = 1,nrhs = 6;
4096   mxArray         *plhs[1],*prhs[6];
4097   long long int   lx = 0,ls = 0;
4098 
4099   PetscFunctionBegin;
4100   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4101   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
4102 
4103   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
4104   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
4105   prhs[0] =  mxCreateDoubleScalar((double)ls);
4106   prhs[1] =  mxCreateDoubleScalar((double)it);
4107   prhs[2] =  mxCreateDoubleScalar((double)time);
4108   prhs[3] =  mxCreateDoubleScalar((double)lx);
4109   prhs[4] =  mxCreateString(sctx->funcname);
4110   prhs[5] =  sctx->ctx;
4111   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr);
4112   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4113   mxDestroyArray(prhs[0]);
4114   mxDestroyArray(prhs[1]);
4115   mxDestroyArray(prhs[2]);
4116   mxDestroyArray(prhs[3]);
4117   mxDestroyArray(prhs[4]);
4118   mxDestroyArray(plhs[0]);
4119   PetscFunctionReturn(0);
4120 }
4121 
4122 
4123 #undef __FUNCT__
4124 #define __FUNCT__ "TSMonitorSetMatlab"
4125 /*
4126    TSMonitorSetMatlab - Sets the monitor function from Matlab
4127 
4128    Level: developer
4129 
4130 .keywords: TS, nonlinear, set, function
4131 
4132 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
4133 */
4134 PetscErrorCode  TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx)
4135 {
4136   PetscErrorCode    ierr;
4137   TSMatlabContext *sctx;
4138 
4139   PetscFunctionBegin;
4140   /* currently sctx is memory bleed */
4141   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
4142   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4143   /*
4144      This should work, but it doesn't
4145   sctx->ctx = ctx;
4146   mexMakeArrayPersistent(sctx->ctx);
4147   */
4148   sctx->ctx = mxDuplicateArray(ctx);
4149   ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4150   PetscFunctionReturn(0);
4151 }
4152 #endif
4153 
4154 
4155 
4156 #undef __FUNCT__
4157 #define __FUNCT__ "TSMonitorLGSolution"
4158 /*@C
4159    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
4160        in a time based line graph
4161 
4162    Collective on TS
4163 
4164    Input Parameters:
4165 +  ts - the TS context
4166 .  step - current time-step
4167 .  ptime - current time
4168 -  lg - a line graph object
4169 
4170    Level: intermediate
4171 
4172     Notes: each process in a parallel run displays its component solutions in a separate window
4173 
4174 .keywords: TS,  vector, monitor, view
4175 
4176 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4177 @*/
4178 PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4179 {
4180   PetscErrorCode    ierr;
4181   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
4182   const PetscScalar *yy;
4183   PetscInt          dim;
4184 
4185   PetscFunctionBegin;
4186   if (!step) {
4187     PetscDrawAxis  axis;
4188     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4189     ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr);
4190     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
4191     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
4192     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4193   }
4194   ierr = VecGetArrayRead(u,&yy);CHKERRQ(ierr);
4195 #if defined(PETSC_USE_COMPLEX)
4196   {
4197     PetscReal *yreal;
4198     PetscInt i,n;
4199     ierr = VecGetLocalSize(u,&n);CHKERRQ(ierr);
4200     ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr);
4201     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
4202     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
4203     ierr = PetscFree(yreal);CHKERRQ(ierr);
4204   }
4205 #else
4206   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
4207 #endif
4208   ierr = VecRestoreArrayRead(u,&yy);CHKERRQ(ierr);
4209   if (((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1))){
4210     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4211   }
4212   PetscFunctionReturn(0);
4213 }
4214 
4215 #undef __FUNCT__
4216 #define __FUNCT__ "TSMonitorLGError"
4217 /*@C
4218    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector
4219        in a time based line graph
4220 
4221    Collective on TS
4222 
4223    Input Parameters:
4224 +  ts - the TS context
4225 .  step - current time-step
4226 .  ptime - current time
4227 -  lg - a line graph object
4228 
4229    Level: intermediate
4230 
4231    Notes:
4232    Only for sequential solves.
4233 
4234    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
4235 
4236    Options Database Keys:
4237 .  -ts_monitor_lg_error - create a graphical monitor of error history
4238 
4239 .keywords: TS,  vector, monitor, view
4240 
4241 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
4242 @*/
4243 PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4244 {
4245   PetscErrorCode    ierr;
4246   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
4247   const PetscScalar *yy;
4248   Vec               y;
4249   PetscInt          dim;
4250 
4251   PetscFunctionBegin;
4252   if (!step) {
4253     PetscDrawAxis  axis;
4254     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4255     ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr);
4256     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
4257     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
4258     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4259   }
4260   ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
4261   ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr);
4262   ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr);
4263   ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr);
4264 #if defined(PETSC_USE_COMPLEX)
4265   {
4266     PetscReal *yreal;
4267     PetscInt  i,n;
4268     ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr);
4269     ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr);
4270     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
4271     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
4272     ierr = PetscFree(yreal);CHKERRQ(ierr);
4273   }
4274 #else
4275   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
4276 #endif
4277   ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr);
4278   ierr = VecDestroy(&y);CHKERRQ(ierr);
4279   if (((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1))){
4280     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4281   }
4282   PetscFunctionReturn(0);
4283 }
4284 
4285 #undef __FUNCT__
4286 #define __FUNCT__ "TSMonitorLGSNESIterations"
4287 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
4288 {
4289   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
4290   PetscReal      x = ptime,y;
4291   PetscErrorCode ierr;
4292   PetscInt       its;
4293 
4294   PetscFunctionBegin;
4295   if (!n) {
4296     PetscDrawAxis  axis;
4297     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4298     ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr);
4299     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4300     ctx->snes_its  = 0;
4301   }
4302   ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr);
4303   y    = its - ctx->snes_its;
4304   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
4305   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))){
4306     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4307   }
4308   ctx->snes_its = its;
4309   PetscFunctionReturn(0);
4310 }
4311 
4312 #undef __FUNCT__
4313 #define __FUNCT__ "TSMonitorLGKSPIterations"
4314 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
4315 {
4316   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
4317   PetscReal      x = ptime,y;
4318   PetscErrorCode ierr;
4319   PetscInt       its;
4320 
4321   PetscFunctionBegin;
4322   if (!n) {
4323     PetscDrawAxis  axis;
4324     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4325     ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr);
4326     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4327     ctx->ksp_its = 0;
4328   }
4329   ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr);
4330   y    = its - ctx->ksp_its;
4331   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
4332   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))){
4333     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4334   }
4335   ctx->ksp_its = its;
4336   PetscFunctionReturn(0);
4337 }
4338 
4339 #undef __FUNCT__
4340 #define __FUNCT__ "TSComputeLinearStability"
4341 /*@
4342    TSComputeLinearStability - computes the linear stability function at a point
4343 
4344    Collective on TS and Vec
4345 
4346    Input Parameters:
4347 +  ts - the TS context
4348 -  xr,xi - real and imaginary part of input arguments
4349 
4350    Output Parameters:
4351 .  yr,yi - real and imaginary part of function value
4352 
4353    Level: developer
4354 
4355 .keywords: TS, compute
4356 
4357 .seealso: TSSetRHSFunction(), TSComputeIFunction()
4358 @*/
4359 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi)
4360 {
4361   PetscErrorCode ierr;
4362 
4363   PetscFunctionBegin;
4364   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4365   if (!ts->ops->linearstability) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_SUP,"Linearized stability function not provided for this method");
4366   ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr);
4367   PetscFunctionReturn(0);
4368 }
4369