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