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