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