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