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