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