xref: /petsc/src/ts/interface/ts.c (revision 942e334039a1a47ff909c032afdf0581bd880e9f)
1 
2 #include <petsc-private/tsimpl.h>        /*I "petscts.h"  I*/
3 #include <petscdmshell.h>
4 
5 /* Logging support */
6 PetscClassId  TS_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 #undef __FUNCT__
2922 #define __FUNCT__ "TSSetDM"
2923 /*@
2924    TSSetDM - Sets the DM that may be used by some preconditioners
2925 
2926    Logically Collective on TS and DM
2927 
2928    Input Parameters:
2929 +  ts - the preconditioner context
2930 -  dm - the dm
2931 
2932    Level: intermediate
2933 
2934 
2935 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM()
2936 @*/
2937 PetscErrorCode  TSSetDM(TS ts,DM dm)
2938 {
2939   PetscErrorCode ierr;
2940   SNES           snes;
2941   DMTS           tsdm;
2942 
2943   PetscFunctionBegin;
2944   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2945   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
2946   if (ts->dm) {               /* Move the DMTS context over to the new DM unless the new DM already has one */
2947     PetscContainer oldcontainer,container;
2948     ierr = PetscObjectQuery((PetscObject)ts->dm,"DMTS",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
2949     ierr = PetscObjectQuery((PetscObject)dm,"DMTS",(PetscObject*)&container);CHKERRQ(ierr);
2950     if (oldcontainer && !container) {
2951       ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr);
2952       ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr);
2953       if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */
2954         tsdm->originaldm = dm;
2955       }
2956     }
2957     ierr = DMDestroy(&ts->dm);CHKERRQ(ierr);
2958   }
2959   ts->dm = dm;
2960   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2961   ierr = SNESSetDM(snes,dm);CHKERRQ(ierr);
2962   PetscFunctionReturn(0);
2963 }
2964 
2965 #undef __FUNCT__
2966 #define __FUNCT__ "TSGetDM"
2967 /*@
2968    TSGetDM - Gets the DM that may be used by some preconditioners
2969 
2970    Not Collective
2971 
2972    Input Parameter:
2973 . ts - the preconditioner context
2974 
2975    Output Parameter:
2976 .  dm - the dm
2977 
2978    Level: intermediate
2979 
2980 
2981 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM()
2982 @*/
2983 PetscErrorCode  TSGetDM(TS ts,DM *dm)
2984 {
2985   PetscErrorCode ierr;
2986 
2987   PetscFunctionBegin;
2988   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2989   if (!ts->dm) {
2990     ierr = DMShellCreate(((PetscObject)ts)->comm,&ts->dm);CHKERRQ(ierr);
2991     if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
2992   }
2993   *dm = ts->dm;
2994   PetscFunctionReturn(0);
2995 }
2996 
2997 #undef __FUNCT__
2998 #define __FUNCT__ "SNESTSFormFunction"
2999 /*@
3000    SNESTSFormFunction - Function to evaluate nonlinear residual
3001 
3002    Logically Collective on SNES
3003 
3004    Input Parameter:
3005 + snes - nonlinear solver
3006 . U - the current state at which to evaluate the residual
3007 - ctx - user context, must be a TS
3008 
3009    Output Parameter:
3010 . F - the nonlinear residual
3011 
3012    Notes:
3013    This function is not normally called by users and is automatically registered with the SNES used by TS.
3014    It is most frequently passed to MatFDColoringSetFunction().
3015 
3016    Level: advanced
3017 
3018 .seealso: SNESSetFunction(), MatFDColoringSetFunction()
3019 @*/
3020 PetscErrorCode  SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx)
3021 {
3022   TS             ts = (TS)ctx;
3023   PetscErrorCode ierr;
3024 
3025   PetscFunctionBegin;
3026   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3027   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
3028   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
3029   PetscValidHeaderSpecific(ts,TS_CLASSID,4);
3030   ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr);
3031   PetscFunctionReturn(0);
3032 }
3033 
3034 #undef __FUNCT__
3035 #define __FUNCT__ "SNESTSFormJacobian"
3036 /*@
3037    SNESTSFormJacobian - Function to evaluate the Jacobian
3038 
3039    Collective on SNES
3040 
3041    Input Parameter:
3042 + snes - nonlinear solver
3043 . U - the current state at which to evaluate the residual
3044 - ctx - user context, must be a TS
3045 
3046    Output Parameter:
3047 + A - the Jacobian
3048 . B - the preconditioning matrix (may be the same as A)
3049 - flag - indicates any structure change in the matrix
3050 
3051    Notes:
3052    This function is not normally called by users and is automatically registered with the SNES used by TS.
3053 
3054    Level: developer
3055 
3056 .seealso: SNESSetJacobian()
3057 @*/
3058 PetscErrorCode  SNESTSFormJacobian(SNES snes,Vec U,Mat *A,Mat *B,MatStructure *flag,void *ctx)
3059 {
3060   TS             ts = (TS)ctx;
3061   PetscErrorCode ierr;
3062 
3063   PetscFunctionBegin;
3064   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3065   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
3066   PetscValidPointer(A,3);
3067   PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
3068   PetscValidPointer(B,4);
3069   PetscValidHeaderSpecific(*B,MAT_CLASSID,4);
3070   PetscValidPointer(flag,5);
3071   PetscValidHeaderSpecific(ts,TS_CLASSID,6);
3072   ierr = (ts->ops->snesjacobian)(snes,U,A,B,flag,ts);CHKERRQ(ierr);
3073   PetscFunctionReturn(0);
3074 }
3075 
3076 #undef __FUNCT__
3077 #define __FUNCT__ "TSComputeRHSFunctionLinear"
3078 /*@C
3079    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only
3080 
3081    Collective on TS
3082 
3083    Input Arguments:
3084 +  ts - time stepping context
3085 .  t - time at which to evaluate
3086 .  U - state at which to evaluate
3087 -  ctx - context
3088 
3089    Output Arguments:
3090 .  F - right hand side
3091 
3092    Level: intermediate
3093 
3094    Notes:
3095    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
3096    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().
3097 
3098 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
3099 @*/
3100 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx)
3101 {
3102   PetscErrorCode ierr;
3103   Mat            Arhs,Brhs;
3104   MatStructure   flg2;
3105 
3106   PetscFunctionBegin;
3107   ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
3108   ierr = TSComputeRHSJacobian(ts,t,U,&Arhs,&Brhs,&flg2);CHKERRQ(ierr);
3109   ierr = MatMult(Arhs,U,F);CHKERRQ(ierr);
3110   PetscFunctionReturn(0);
3111 }
3112 
3113 #undef __FUNCT__
3114 #define __FUNCT__ "TSComputeRHSJacobianConstant"
3115 /*@C
3116    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
3117 
3118    Collective on TS
3119 
3120    Input Arguments:
3121 +  ts - time stepping context
3122 .  t - time at which to evaluate
3123 .  U - state at which to evaluate
3124 -  ctx - context
3125 
3126    Output Arguments:
3127 +  A - pointer to operator
3128 .  B - pointer to preconditioning matrix
3129 -  flg - matrix structure flag
3130 
3131    Level: intermediate
3132 
3133    Notes:
3134    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.
3135 
3136 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear()
3137 @*/
3138 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat *A,Mat *B,MatStructure *flg,void *ctx)
3139 {
3140   PetscFunctionBegin;
3141   *flg = SAME_PRECONDITIONER;
3142   PetscFunctionReturn(0);
3143 }
3144 
3145 #undef __FUNCT__
3146 #define __FUNCT__ "TSComputeIFunctionLinear"
3147 /*@C
3148    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
3149 
3150    Collective on TS
3151 
3152    Input Arguments:
3153 +  ts - time stepping context
3154 .  t - time at which to evaluate
3155 .  U - state at which to evaluate
3156 .  Udot - time derivative of state vector
3157 -  ctx - context
3158 
3159    Output Arguments:
3160 .  F - left hand side
3161 
3162    Level: intermediate
3163 
3164    Notes:
3165    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
3166    user is required to write their own TSComputeIFunction.
3167    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
3168    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().
3169 
3170 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant()
3171 @*/
3172 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx)
3173 {
3174   PetscErrorCode ierr;
3175   Mat            A,B;
3176   MatStructure   flg2;
3177 
3178   PetscFunctionBegin;
3179   ierr = TSGetIJacobian(ts,&A,&B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
3180   ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,&A,&B,&flg2,PETSC_TRUE);CHKERRQ(ierr);
3181   ierr = MatMult(A,Udot,F);CHKERRQ(ierr);
3182   PetscFunctionReturn(0);
3183 }
3184 
3185 #undef __FUNCT__
3186 #define __FUNCT__ "TSComputeIJacobianConstant"
3187 /*@C
3188    TSComputeIJacobianConstant - Reuses a Jacobian that is time-independent.
3189 
3190    Collective on TS
3191 
3192    Input Arguments:
3193 +  ts - time stepping context
3194 .  t - time at which to evaluate
3195 .  U - state at which to evaluate
3196 .  Udot - time derivative of state vector
3197 .  shift - shift to apply
3198 -  ctx - context
3199 
3200    Output Arguments:
3201 +  A - pointer to operator
3202 .  B - pointer to preconditioning matrix
3203 -  flg - matrix structure flag
3204 
3205    Level: intermediate
3206 
3207    Notes:
3208    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.
3209 
3210 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear()
3211 @*/
3212 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,void *ctx)
3213 {
3214   PetscFunctionBegin;
3215   *flg = SAME_PRECONDITIONER;
3216   PetscFunctionReturn(0);
3217 }
3218 
3219 #undef __FUNCT__
3220 #define __FUNCT__ "TSGetConvergedReason"
3221 /*@
3222    TSGetConvergedReason - Gets the reason the TS iteration was stopped.
3223 
3224    Not Collective
3225 
3226    Input Parameter:
3227 .  ts - the TS context
3228 
3229    Output Parameter:
3230 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
3231             manual pages for the individual convergence tests for complete lists
3232 
3233    Level: beginner
3234 
3235    Notes:
3236    Can only be called after the call to TSSolve() is complete.
3237 
3238 .keywords: TS, nonlinear, set, convergence, test
3239 
3240 .seealso: TSSetConvergenceTest(), TSConvergedReason
3241 @*/
3242 PetscErrorCode  TSGetConvergedReason(TS ts,TSConvergedReason *reason)
3243 {
3244   PetscFunctionBegin;
3245   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3246   PetscValidPointer(reason,2);
3247   *reason = ts->reason;
3248   PetscFunctionReturn(0);
3249 }
3250 
3251 #undef __FUNCT__
3252 #define __FUNCT__ "TSGetSolveTime"
3253 /*@
3254    TSGetSolveTime - Gets the time after a call to TSSolve()
3255 
3256    Not Collective
3257 
3258    Input Parameter:
3259 .  ts - the TS context
3260 
3261    Output Parameter:
3262 .  ftime - the final time. This time should correspond to the final time set with TSSetDuration()
3263 
3264    Level: beginner
3265 
3266    Notes:
3267    Can only be called after the call to TSSolve() is complete.
3268 
3269 .keywords: TS, nonlinear, set, convergence, test
3270 
3271 .seealso: TSSetConvergenceTest(), TSConvergedReason
3272 @*/
3273 PetscErrorCode  TSGetSolveTime(TS ts,PetscReal *ftime)
3274 {
3275   PetscFunctionBegin;
3276   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3277   PetscValidPointer(ftime,2);
3278   *ftime = ts->solvetime;
3279   PetscFunctionReturn(0);
3280 }
3281 
3282 #undef __FUNCT__
3283 #define __FUNCT__ "TSGetSNESIterations"
3284 /*@
3285    TSGetSNESIterations - Gets the total number of nonlinear iterations
3286    used by the time integrator.
3287 
3288    Not Collective
3289 
3290    Input Parameter:
3291 .  ts - TS context
3292 
3293    Output Parameter:
3294 .  nits - number of nonlinear iterations
3295 
3296    Notes:
3297    This counter is reset to zero for each successive call to TSSolve().
3298 
3299    Level: intermediate
3300 
3301 .keywords: TS, get, number, nonlinear, iterations
3302 
3303 .seealso:  TSGetKSPIterations()
3304 @*/
3305 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits)
3306 {
3307   PetscFunctionBegin;
3308   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3309   PetscValidIntPointer(nits,2);
3310   *nits = ts->snes_its;
3311   PetscFunctionReturn(0);
3312 }
3313 
3314 #undef __FUNCT__
3315 #define __FUNCT__ "TSGetKSPIterations"
3316 /*@
3317    TSGetKSPIterations - Gets the total number of linear iterations
3318    used by the time integrator.
3319 
3320    Not Collective
3321 
3322    Input Parameter:
3323 .  ts - TS context
3324 
3325    Output Parameter:
3326 .  lits - number of linear iterations
3327 
3328    Notes:
3329    This counter is reset to zero for each successive call to TSSolve().
3330 
3331    Level: intermediate
3332 
3333 .keywords: TS, get, number, linear, iterations
3334 
3335 .seealso:  TSGetSNESIterations(), SNESGetKSPIterations()
3336 @*/
3337 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits)
3338 {
3339   PetscFunctionBegin;
3340   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3341   PetscValidIntPointer(lits,2);
3342   *lits = ts->ksp_its;
3343   PetscFunctionReturn(0);
3344 }
3345 
3346 #undef __FUNCT__
3347 #define __FUNCT__ "TSGetStepRejections"
3348 /*@
3349    TSGetStepRejections - Gets the total number of rejected steps.
3350 
3351    Not Collective
3352 
3353    Input Parameter:
3354 .  ts - TS context
3355 
3356    Output Parameter:
3357 .  rejects - number of steps rejected
3358 
3359    Notes:
3360    This counter is reset to zero for each successive call to TSSolve().
3361 
3362    Level: intermediate
3363 
3364 .keywords: TS, get, number
3365 
3366 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails()
3367 @*/
3368 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects)
3369 {
3370   PetscFunctionBegin;
3371   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3372   PetscValidIntPointer(rejects,2);
3373   *rejects = ts->reject;
3374   PetscFunctionReturn(0);
3375 }
3376 
3377 #undef __FUNCT__
3378 #define __FUNCT__ "TSGetSNESFailures"
3379 /*@
3380    TSGetSNESFailures - Gets the total number of failed SNES solves
3381 
3382    Not Collective
3383 
3384    Input Parameter:
3385 .  ts - TS context
3386 
3387    Output Parameter:
3388 .  fails - number of failed nonlinear solves
3389 
3390    Notes:
3391    This counter is reset to zero for each successive call to TSSolve().
3392 
3393    Level: intermediate
3394 
3395 .keywords: TS, get, number
3396 
3397 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures()
3398 @*/
3399 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails)
3400 {
3401   PetscFunctionBegin;
3402   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3403   PetscValidIntPointer(fails,2);
3404   *fails = ts->num_snes_failures;
3405   PetscFunctionReturn(0);
3406 }
3407 
3408 #undef __FUNCT__
3409 #define __FUNCT__ "TSSetMaxStepRejections"
3410 /*@
3411    TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails
3412 
3413    Not Collective
3414 
3415    Input Parameter:
3416 +  ts - TS context
3417 -  rejects - maximum number of rejected steps, pass -1 for unlimited
3418 
3419    Notes:
3420    The counter is reset to zero for each step
3421 
3422    Options Database Key:
3423  .  -ts_max_reject - Maximum number of step rejections before a step fails
3424 
3425    Level: intermediate
3426 
3427 .keywords: TS, set, maximum, number
3428 
3429 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
3430 @*/
3431 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects)
3432 {
3433   PetscFunctionBegin;
3434   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3435   ts->max_reject = rejects;
3436   PetscFunctionReturn(0);
3437 }
3438 
3439 #undef __FUNCT__
3440 #define __FUNCT__ "TSSetMaxSNESFailures"
3441 /*@
3442    TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves
3443 
3444    Not Collective
3445 
3446    Input Parameter:
3447 +  ts - TS context
3448 -  fails - maximum number of failed nonlinear solves, pass -1 for unlimited
3449 
3450    Notes:
3451    The counter is reset to zero for each successive call to TSSolve().
3452 
3453    Options Database Key:
3454  .  -ts_max_snes_failures - Maximum number of nonlinear solve failures
3455 
3456    Level: intermediate
3457 
3458 .keywords: TS, set, maximum, number
3459 
3460 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason()
3461 @*/
3462 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails)
3463 {
3464   PetscFunctionBegin;
3465   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3466   ts->max_snes_failures = fails;
3467   PetscFunctionReturn(0);
3468 }
3469 
3470 #undef __FUNCT__
3471 #define __FUNCT__ "TSSetErrorIfStepFails()"
3472 /*@
3473    TSSetErrorIfStepFails - Error if no step succeeds
3474 
3475    Not Collective
3476 
3477    Input Parameter:
3478 +  ts - TS context
3479 -  err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure
3480 
3481    Options Database Key:
3482  .  -ts_error_if_step_fails - Error if no step succeeds
3483 
3484    Level: intermediate
3485 
3486 .keywords: TS, set, error
3487 
3488 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
3489 @*/
3490 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err)
3491 {
3492   PetscFunctionBegin;
3493   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3494   ts->errorifstepfailed = err;
3495   PetscFunctionReturn(0);
3496 }
3497 
3498 #undef __FUNCT__
3499 #define __FUNCT__ "TSMonitorSolutionBinary"
3500 /*@C
3501    TSMonitorSolutionBinary - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file
3502 
3503    Collective on TS
3504 
3505    Input Parameters:
3506 +  ts - the TS context
3507 .  step - current time-step
3508 .  ptime - current time
3509 .  u - current state
3510 -  viewer - binary viewer
3511 
3512    Level: intermediate
3513 
3514 .keywords: TS,  vector, monitor, view
3515 
3516 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3517 @*/
3518 PetscErrorCode  TSMonitorSolutionBinary(TS ts,PetscInt step,PetscReal ptime,Vec u,void *viewer)
3519 {
3520   PetscErrorCode ierr;
3521   PetscViewer    v = (PetscViewer)viewer;
3522 
3523   PetscFunctionBegin;
3524   ierr = VecView(u,v);CHKERRQ(ierr);
3525   PetscFunctionReturn(0);
3526 }
3527 
3528 #undef __FUNCT__
3529 #define __FUNCT__ "TSMonitorSolutionVTK"
3530 /*@C
3531    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
3532 
3533    Collective on TS
3534 
3535    Input Parameters:
3536 +  ts - the TS context
3537 .  step - current time-step
3538 .  ptime - current time
3539 .  u - current state
3540 -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
3541 
3542    Level: intermediate
3543 
3544    Notes:
3545    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.
3546    These are named according to the file name template.
3547 
3548    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().
3549 
3550 .keywords: TS,  vector, monitor, view
3551 
3552 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3553 @*/
3554 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
3555 {
3556   PetscErrorCode ierr;
3557   char           filename[PETSC_MAX_PATH_LEN];
3558   PetscViewer    viewer;
3559 
3560   PetscFunctionBegin;
3561   ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr);
3562   ierr = PetscViewerVTKOpen(((PetscObject)ts)->comm,filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr);
3563   ierr = VecView(u,viewer);CHKERRQ(ierr);
3564   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3565   PetscFunctionReturn(0);
3566 }
3567 
3568 #undef __FUNCT__
3569 #define __FUNCT__ "TSMonitorSolutionVTKDestroy"
3570 /*@C
3571    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
3572 
3573    Collective on TS
3574 
3575    Input Parameters:
3576 .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
3577 
3578    Level: intermediate
3579 
3580    Note:
3581    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
3582 
3583 .keywords: TS,  vector, monitor, view
3584 
3585 .seealso: TSMonitorSet(), TSMonitorSolutionVTK()
3586 @*/
3587 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
3588 {
3589   PetscErrorCode ierr;
3590 
3591   PetscFunctionBegin;
3592   ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr);
3593   PetscFunctionReturn(0);
3594 }
3595 
3596 #undef __FUNCT__
3597 #define __FUNCT__ "TSGetAdapt"
3598 /*@
3599    TSGetAdapt - Get the adaptive controller context for the current method
3600 
3601    Collective on TS if controller has not been created yet
3602 
3603    Input Arguments:
3604 .  ts - time stepping context
3605 
3606    Output Arguments:
3607 .  adapt - adaptive controller
3608 
3609    Level: intermediate
3610 
3611 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose()
3612 @*/
3613 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt)
3614 {
3615   PetscErrorCode ierr;
3616 
3617   PetscFunctionBegin;
3618   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3619   PetscValidPointer(adapt,2);
3620   if (!ts->adapt) {
3621     ierr = TSAdaptCreate(((PetscObject)ts)->comm,&ts->adapt);CHKERRQ(ierr);
3622     ierr = PetscLogObjectParent(ts,ts->adapt);CHKERRQ(ierr);
3623     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr);
3624   }
3625   *adapt = ts->adapt;
3626   PetscFunctionReturn(0);
3627 }
3628 
3629 #undef __FUNCT__
3630 #define __FUNCT__ "TSSetTolerances"
3631 /*@
3632    TSSetTolerances - Set tolerances for local truncation error when using adaptive controller
3633 
3634    Logically Collective
3635 
3636    Input Arguments:
3637 +  ts - time integration context
3638 .  atol - scalar absolute tolerances, PETSC_DECIDE to leave current value
3639 .  vatol - vector of absolute tolerances or PETSC_NULL, used in preference to atol if present
3640 .  rtol - scalar relative tolerances, PETSC_DECIDE to leave current value
3641 -  vrtol - vector of relative tolerances or PETSC_NULL, used in preference to atol if present
3642 
3643    Level: beginner
3644 
3645 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances()
3646 @*/
3647 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol)
3648 {
3649   PetscErrorCode ierr;
3650 
3651   PetscFunctionBegin;
3652   if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol;
3653   if (vatol) {
3654     ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr);
3655     ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
3656     ts->vatol = vatol;
3657   }
3658   if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol;
3659   if (vrtol) {
3660     ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr);
3661     ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
3662     ts->vrtol = vrtol;
3663   }
3664   PetscFunctionReturn(0);
3665 }
3666 
3667 #undef __FUNCT__
3668 #define __FUNCT__ "TSGetTolerances"
3669 /*@
3670    TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
3671 
3672    Logically Collective
3673 
3674    Input Arguments:
3675 .  ts - time integration context
3676 
3677    Output Arguments:
3678 +  atol - scalar absolute tolerances, PETSC_NULL to ignore
3679 .  vatol - vector of absolute tolerances, PETSC_NULL to ignore
3680 .  rtol - scalar relative tolerances, PETSC_NULL to ignore
3681 -  vrtol - vector of relative tolerances, PETSC_NULL to ignore
3682 
3683    Level: beginner
3684 
3685 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances()
3686 @*/
3687 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol)
3688 {
3689   PetscFunctionBegin;
3690   if (atol)  *atol  = ts->atol;
3691   if (vatol) *vatol = ts->vatol;
3692   if (rtol)  *rtol  = ts->rtol;
3693   if (vrtol) *vrtol = ts->vrtol;
3694   PetscFunctionReturn(0);
3695 }
3696 
3697 #undef __FUNCT__
3698 #define __FUNCT__ "TSErrorNormWRMS"
3699 /*@
3700    TSErrorNormWRMS - compute a weighted norm of the difference between a vector and the current state
3701 
3702    Collective on TS
3703 
3704    Input Arguments:
3705 +  ts - time stepping context
3706 -  Y - state vector to be compared to ts->vec_sol
3707 
3708    Output Arguments:
3709 .  norm - weighted norm, a value of 1.0 is considered small
3710 
3711    Level: developer
3712 
3713 .seealso: TSSetTolerances()
3714 @*/
3715 PetscErrorCode TSErrorNormWRMS(TS ts,Vec Y,PetscReal *norm)
3716 {
3717   PetscErrorCode    ierr;
3718   PetscInt          i,n,N;
3719   const PetscScalar *u,*y;
3720   Vec               U;
3721   PetscReal         sum,gsum;
3722 
3723   PetscFunctionBegin;
3724   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3725   PetscValidHeaderSpecific(Y,VEC_CLASSID,2);
3726   PetscValidPointer(norm,3);
3727   U = ts->vec_sol;
3728   PetscCheckSameTypeAndComm(U,1,Y,2);
3729   if (U == Y) SETERRQ(((PetscObject)U)->comm,PETSC_ERR_ARG_IDN,"Y cannot be the TS solution vector");
3730 
3731   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
3732   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
3733   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
3734   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
3735   sum = 0.;
3736   if (ts->vatol && ts->vrtol) {
3737     const PetscScalar *atol,*rtol;
3738     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
3739     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
3740     for (i=0; i<n; i++) {
3741       PetscReal tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
3742       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
3743     }
3744     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
3745     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
3746   } else if (ts->vatol) {       /* vector atol, scalar rtol */
3747     const PetscScalar *atol;
3748     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
3749     for (i=0; i<n; i++) {
3750       PetscReal tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
3751       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
3752     }
3753     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
3754   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
3755     const PetscScalar *rtol;
3756     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
3757     for (i=0; i<n; i++) {
3758       PetscReal tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
3759       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
3760     }
3761     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
3762   } else {                      /* scalar atol, scalar rtol */
3763     for (i=0; i<n; i++) {
3764       PetscReal tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
3765       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
3766     }
3767   }
3768   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
3769   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
3770 
3771   ierr = MPI_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,((PetscObject)ts)->comm);CHKERRQ(ierr);
3772   *norm = PetscSqrtReal(gsum / N);
3773   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
3774   PetscFunctionReturn(0);
3775 }
3776 
3777 #undef __FUNCT__
3778 #define __FUNCT__ "TSSetCFLTimeLocal"
3779 /*@
3780    TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
3781 
3782    Logically Collective on TS
3783 
3784    Input Arguments:
3785 +  ts - time stepping context
3786 -  cfltime - maximum stable time step if using forward Euler (value can be different on each process)
3787 
3788    Note:
3789    After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
3790 
3791    Level: intermediate
3792 
3793 .seealso: TSGetCFLTime(), TSADAPTCFL
3794 @*/
3795 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime)
3796 {
3797   PetscFunctionBegin;
3798   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3799   ts->cfltime_local = cfltime;
3800   ts->cfltime = -1.;
3801   PetscFunctionReturn(0);
3802 }
3803 
3804 #undef __FUNCT__
3805 #define __FUNCT__ "TSGetCFLTime"
3806 /*@
3807    TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
3808 
3809    Collective on TS
3810 
3811    Input Arguments:
3812 .  ts - time stepping context
3813 
3814    Output Arguments:
3815 .  cfltime - maximum stable time step for forward Euler
3816 
3817    Level: advanced
3818 
3819 .seealso: TSSetCFLTimeLocal()
3820 @*/
3821 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime)
3822 {
3823   PetscErrorCode ierr;
3824 
3825   PetscFunctionBegin;
3826   if (ts->cfltime < 0) {
3827     ierr = MPI_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,((PetscObject)ts)->comm);CHKERRQ(ierr);
3828   }
3829   *cfltime = ts->cfltime;
3830   PetscFunctionReturn(0);
3831 }
3832 
3833 #undef __FUNCT__
3834 #define __FUNCT__ "TSVISetVariableBounds"
3835 /*@
3836    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
3837 
3838    Input Parameters:
3839 .  ts   - the TS context.
3840 .  xl   - lower bound.
3841 .  xu   - upper bound.
3842 
3843    Notes:
3844    If this routine is not called then the lower and upper bounds are set to
3845    SNES_VI_NINF and SNES_VI_INF respectively during SNESSetUp().
3846 
3847    Level: advanced
3848 
3849 @*/
3850 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
3851 {
3852   PetscErrorCode ierr;
3853   SNES           snes;
3854 
3855   PetscFunctionBegin;
3856   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3857   ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr);
3858   PetscFunctionReturn(0);
3859 }
3860 
3861 #if defined(PETSC_HAVE_MATLAB_ENGINE)
3862 #include <mex.h>
3863 
3864 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext;
3865 
3866 #undef __FUNCT__
3867 #define __FUNCT__ "TSComputeFunction_Matlab"
3868 /*
3869    TSComputeFunction_Matlab - Calls the function that has been set with
3870                          TSSetFunctionMatlab().
3871 
3872    Collective on TS
3873 
3874    Input Parameters:
3875 +  snes - the TS context
3876 -  u - input vector
3877 
3878    Output Parameter:
3879 .  y - function vector, as set by TSSetFunction()
3880 
3881    Notes:
3882    TSComputeFunction() is typically used within nonlinear solvers
3883    implementations, so most users would not generally call this routine
3884    themselves.
3885 
3886    Level: developer
3887 
3888 .keywords: TS, nonlinear, compute, function
3889 
3890 .seealso: TSSetFunction(), TSGetFunction()
3891 */
3892 PetscErrorCode  TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx)
3893 {
3894   PetscErrorCode   ierr;
3895   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
3896   int              nlhs = 1,nrhs = 7;
3897   mxArray          *plhs[1],*prhs[7];
3898   long long int    lx = 0,lxdot = 0,ly = 0,ls = 0;
3899 
3900   PetscFunctionBegin;
3901   PetscValidHeaderSpecific(snes,TS_CLASSID,1);
3902   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
3903   PetscValidHeaderSpecific(udot,VEC_CLASSID,4);
3904   PetscValidHeaderSpecific(y,VEC_CLASSID,5);
3905   PetscCheckSameComm(snes,1,u,3);
3906   PetscCheckSameComm(snes,1,y,5);
3907 
3908   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
3909   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
3910   ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr);
3911   ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr);
3912   prhs[0] =  mxCreateDoubleScalar((double)ls);
3913   prhs[1] =  mxCreateDoubleScalar(time);
3914   prhs[2] =  mxCreateDoubleScalar((double)lx);
3915   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
3916   prhs[4] =  mxCreateDoubleScalar((double)ly);
3917   prhs[5] =  mxCreateString(sctx->funcname);
3918   prhs[6] =  sctx->ctx;
3919   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr);
3920   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
3921   mxDestroyArray(prhs[0]);
3922   mxDestroyArray(prhs[1]);
3923   mxDestroyArray(prhs[2]);
3924   mxDestroyArray(prhs[3]);
3925   mxDestroyArray(prhs[4]);
3926   mxDestroyArray(prhs[5]);
3927   mxDestroyArray(plhs[0]);
3928   PetscFunctionReturn(0);
3929 }
3930 
3931 
3932 #undef __FUNCT__
3933 #define __FUNCT__ "TSSetFunctionMatlab"
3934 /*
3935    TSSetFunctionMatlab - Sets the function evaluation routine and function
3936    vector for use by the TS routines in solving ODEs
3937    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
3938 
3939    Logically Collective on TS
3940 
3941    Input Parameters:
3942 +  ts - the TS context
3943 -  func - function evaluation routine
3944 
3945    Calling sequence of func:
3946 $    func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx);
3947 
3948    Level: beginner
3949 
3950 .keywords: TS, nonlinear, set, function
3951 
3952 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
3953 */
3954 PetscErrorCode  TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx)
3955 {
3956   PetscErrorCode  ierr;
3957   TSMatlabContext *sctx;
3958 
3959   PetscFunctionBegin;
3960   /* currently sctx is memory bleed */
3961   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
3962   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
3963   /*
3964      This should work, but it doesn't
3965   sctx->ctx = ctx;
3966   mexMakeArrayPersistent(sctx->ctx);
3967   */
3968   sctx->ctx = mxDuplicateArray(ctx);
3969   ierr = TSSetIFunction(ts,PETSC_NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr);
3970   PetscFunctionReturn(0);
3971 }
3972 
3973 #undef __FUNCT__
3974 #define __FUNCT__ "TSComputeJacobian_Matlab"
3975 /*
3976    TSComputeJacobian_Matlab - Calls the function that has been set with
3977                          TSSetJacobianMatlab().
3978 
3979    Collective on TS
3980 
3981    Input Parameters:
3982 +  ts - the TS context
3983 .  u - input vector
3984 .  A, B - the matrices
3985 -  ctx - user context
3986 
3987    Output Parameter:
3988 .  flag - structure of the matrix
3989 
3990    Level: developer
3991 
3992 .keywords: TS, nonlinear, compute, function
3993 
3994 .seealso: TSSetFunction(), TSGetFunction()
3995 @*/
3996 PetscErrorCode  TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flag, void *ctx)
3997 {
3998   PetscErrorCode  ierr;
3999   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
4000   int             nlhs = 2,nrhs = 9;
4001   mxArray         *plhs[2],*prhs[9];
4002   long long int   lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0;
4003 
4004   PetscFunctionBegin;
4005   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4006   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
4007 
4008   /* call Matlab function in ctx with arguments u and y */
4009 
4010   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
4011   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
4012   ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr);
4013   ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr);
4014   ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr);
4015   prhs[0] =  mxCreateDoubleScalar((double)ls);
4016   prhs[1] =  mxCreateDoubleScalar((double)time);
4017   prhs[2] =  mxCreateDoubleScalar((double)lx);
4018   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
4019   prhs[4] =  mxCreateDoubleScalar((double)shift);
4020   prhs[5] =  mxCreateDoubleScalar((double)lA);
4021   prhs[6] =  mxCreateDoubleScalar((double)lB);
4022   prhs[7] =  mxCreateString(sctx->funcname);
4023   prhs[8] =  sctx->ctx;
4024   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr);
4025   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4026   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
4027   mxDestroyArray(prhs[0]);
4028   mxDestroyArray(prhs[1]);
4029   mxDestroyArray(prhs[2]);
4030   mxDestroyArray(prhs[3]);
4031   mxDestroyArray(prhs[4]);
4032   mxDestroyArray(prhs[5]);
4033   mxDestroyArray(prhs[6]);
4034   mxDestroyArray(prhs[7]);
4035   mxDestroyArray(plhs[0]);
4036   mxDestroyArray(plhs[1]);
4037   PetscFunctionReturn(0);
4038 }
4039 
4040 
4041 #undef __FUNCT__
4042 #define __FUNCT__ "TSSetJacobianMatlab"
4043 /*
4044    TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
4045    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
4046 
4047    Logically Collective on TS
4048 
4049    Input Parameters:
4050 +  ts - the TS context
4051 .  A,B - Jacobian matrices
4052 .  func - function evaluation routine
4053 -  ctx - user context
4054 
4055    Calling sequence of func:
4056 $    flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx);
4057 
4058 
4059    Level: developer
4060 
4061 .keywords: TS, nonlinear, set, function
4062 
4063 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
4064 */
4065 PetscErrorCode  TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx)
4066 {
4067   PetscErrorCode    ierr;
4068   TSMatlabContext *sctx;
4069 
4070   PetscFunctionBegin;
4071   /* currently sctx is memory bleed */
4072   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
4073   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4074   /*
4075      This should work, but it doesn't
4076   sctx->ctx = ctx;
4077   mexMakeArrayPersistent(sctx->ctx);
4078   */
4079   sctx->ctx = mxDuplicateArray(ctx);
4080   ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
4081   PetscFunctionReturn(0);
4082 }
4083 
4084 #undef __FUNCT__
4085 #define __FUNCT__ "TSMonitor_Matlab"
4086 /*
4087    TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab().
4088 
4089    Collective on TS
4090 
4091 .seealso: TSSetFunction(), TSGetFunction()
4092 @*/
4093 PetscErrorCode  TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx)
4094 {
4095   PetscErrorCode  ierr;
4096   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
4097   int             nlhs = 1,nrhs = 6;
4098   mxArray         *plhs[1],*prhs[6];
4099   long long int   lx = 0,ls = 0;
4100 
4101   PetscFunctionBegin;
4102   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4103   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
4104 
4105   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
4106   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
4107   prhs[0] =  mxCreateDoubleScalar((double)ls);
4108   prhs[1] =  mxCreateDoubleScalar((double)it);
4109   prhs[2] =  mxCreateDoubleScalar((double)time);
4110   prhs[3] =  mxCreateDoubleScalar((double)lx);
4111   prhs[4] =  mxCreateString(sctx->funcname);
4112   prhs[5] =  sctx->ctx;
4113   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr);
4114   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4115   mxDestroyArray(prhs[0]);
4116   mxDestroyArray(prhs[1]);
4117   mxDestroyArray(prhs[2]);
4118   mxDestroyArray(prhs[3]);
4119   mxDestroyArray(prhs[4]);
4120   mxDestroyArray(plhs[0]);
4121   PetscFunctionReturn(0);
4122 }
4123 
4124 
4125 #undef __FUNCT__
4126 #define __FUNCT__ "TSMonitorSetMatlab"
4127 /*
4128    TSMonitorSetMatlab - Sets the monitor function from Matlab
4129 
4130    Level: developer
4131 
4132 .keywords: TS, nonlinear, set, function
4133 
4134 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
4135 */
4136 PetscErrorCode  TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx)
4137 {
4138   PetscErrorCode    ierr;
4139   TSMatlabContext *sctx;
4140 
4141   PetscFunctionBegin;
4142   /* currently sctx is memory bleed */
4143   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
4144   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4145   /*
4146      This should work, but it doesn't
4147   sctx->ctx = ctx;
4148   mexMakeArrayPersistent(sctx->ctx);
4149   */
4150   sctx->ctx = mxDuplicateArray(ctx);
4151   ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4152   PetscFunctionReturn(0);
4153 }
4154 #endif
4155 
4156 
4157 
4158 #undef __FUNCT__
4159 #define __FUNCT__ "TSMonitorLGSolution"
4160 /*@C
4161    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
4162        in a time based line graph
4163 
4164    Collective on TS
4165 
4166    Input Parameters:
4167 +  ts - the TS context
4168 .  step - current time-step
4169 .  ptime - current time
4170 -  lg - a line graph object
4171 
4172    Level: intermediate
4173 
4174     Notes: each process in a parallel run displays its component solutions in a separate window
4175 
4176 .keywords: TS,  vector, monitor, view
4177 
4178 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4179 @*/
4180 PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4181 {
4182   PetscErrorCode    ierr;
4183   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
4184   const PetscScalar *yy;
4185   PetscInt          dim;
4186 
4187   PetscFunctionBegin;
4188   if (!step) {
4189     PetscDrawAxis  axis;
4190     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4191     ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr);
4192     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
4193     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
4194     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4195   }
4196   ierr = VecGetArrayRead(u,&yy);CHKERRQ(ierr);
4197 #if defined(PETSC_USE_COMPLEX)
4198   {
4199     PetscReal *yreal;
4200     PetscInt i,n;
4201     ierr = VecGetLocalSize(u,&n);CHKERRQ(ierr);
4202     ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr);
4203     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
4204     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
4205     ierr = PetscFree(yreal);CHKERRQ(ierr);
4206   }
4207 #else
4208   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
4209 #endif
4210   ierr = VecRestoreArrayRead(u,&yy);CHKERRQ(ierr);
4211   if (((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1))){
4212     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4213   }
4214   PetscFunctionReturn(0);
4215 }
4216 
4217 #undef __FUNCT__
4218 #define __FUNCT__ "TSMonitorLGError"
4219 /*@C
4220    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector
4221        in a time based line graph
4222 
4223    Collective on TS
4224 
4225    Input Parameters:
4226 +  ts - the TS context
4227 .  step - current time-step
4228 .  ptime - current time
4229 -  lg - a line graph object
4230 
4231    Level: intermediate
4232 
4233    Notes:
4234    Only for sequential solves.
4235 
4236    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
4237 
4238    Options Database Keys:
4239 .  -ts_monitor_lg_error - create a graphical monitor of error history
4240 
4241 .keywords: TS,  vector, monitor, view
4242 
4243 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
4244 @*/
4245 PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4246 {
4247   PetscErrorCode    ierr;
4248   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
4249   const PetscScalar *yy;
4250   Vec               y;
4251   PetscInt          dim;
4252 
4253   PetscFunctionBegin;
4254   if (!step) {
4255     PetscDrawAxis  axis;
4256     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4257     ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr);
4258     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
4259     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
4260     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4261   }
4262   ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
4263   ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr);
4264   ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr);
4265   ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr);
4266 #if defined(PETSC_USE_COMPLEX)
4267   {
4268     PetscReal *yreal;
4269     PetscInt  i,n;
4270     ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr);
4271     ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr);
4272     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
4273     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
4274     ierr = PetscFree(yreal);CHKERRQ(ierr);
4275   }
4276 #else
4277   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
4278 #endif
4279   ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr);
4280   ierr = VecDestroy(&y);CHKERRQ(ierr);
4281   if (((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1))){
4282     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4283   }
4284   PetscFunctionReturn(0);
4285 }
4286 
4287 #undef __FUNCT__
4288 #define __FUNCT__ "TSMonitorLGSNESIterations"
4289 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
4290 {
4291   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
4292   PetscReal      x = ptime,y;
4293   PetscErrorCode ierr;
4294   PetscInt       its;
4295 
4296   PetscFunctionBegin;
4297   if (!n) {
4298     PetscDrawAxis  axis;
4299     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4300     ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr);
4301     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4302     ctx->snes_its  = 0;
4303   }
4304   ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr);
4305   y    = its - ctx->snes_its;
4306   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
4307   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))){
4308     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4309   }
4310   ctx->snes_its = its;
4311   PetscFunctionReturn(0);
4312 }
4313 
4314 #undef __FUNCT__
4315 #define __FUNCT__ "TSMonitorLGKSPIterations"
4316 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
4317 {
4318   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
4319   PetscReal      x = ptime,y;
4320   PetscErrorCode ierr;
4321   PetscInt       its;
4322 
4323   PetscFunctionBegin;
4324   if (!n) {
4325     PetscDrawAxis  axis;
4326     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4327     ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr);
4328     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4329     ctx->ksp_its = 0;
4330   }
4331   ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr);
4332   y    = its - ctx->ksp_its;
4333   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
4334   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))){
4335     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4336   }
4337   ctx->ksp_its = its;
4338   PetscFunctionReturn(0);
4339 }
4340 
4341 #undef __FUNCT__
4342 #define __FUNCT__ "TSComputeLinearStability"
4343 /*@
4344    TSComputeLinearStability - computes the linear stability function at a point
4345 
4346    Collective on TS and Vec
4347 
4348    Input Parameters:
4349 +  ts - the TS context
4350 -  xr,xi - real and imaginary part of input arguments
4351 
4352    Output Parameters:
4353 .  yr,yi - real and imaginary part of function value
4354 
4355    Level: developer
4356 
4357 .keywords: TS, compute
4358 
4359 .seealso: TSSetRHSFunction(), TSComputeIFunction()
4360 @*/
4361 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi)
4362 {
4363   PetscErrorCode ierr;
4364 
4365   PetscFunctionBegin;
4366   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4367   if (!ts->ops->linearstability) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_SUP,"Linearized stability function not provided for this method");
4368   ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr);
4369   PetscFunctionReturn(0);
4370 }
4371