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