xref: /petsc/src/ts/interface/ts.c (revision 8cbdbec6f8317ddf7886f91eb9c6bd083b543c50)
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);
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);
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);
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);
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);
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);
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);
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__ "TSGetKSP"
1729 /*@
1730    TSGetKSP - Returns the KSP (linear solver) associated with
1731    a TS (timestepper) context.
1732 
1733    Not Collective, but KSP is parallel if TS is parallel
1734 
1735    Input Parameter:
1736 .  ts - the TS context obtained from TSCreate()
1737 
1738    Output Parameter:
1739 .  ksp - the nonlinear solver context
1740 
1741    Notes:
1742    The user can then directly manipulate the KSP context to set various
1743    options, etc.  Likewise, the user can then extract and manipulate the
1744    KSP and PC contexts as well.
1745 
1746    TSGetKSP() does not work for integrators that do not use KSP;
1747    in this case TSGetKSP() returns PETSC_NULL in ksp.
1748 
1749    Level: beginner
1750 
1751 .keywords: timestep, get, KSP
1752 @*/
1753 PetscErrorCode  TSGetKSP(TS ts,KSP *ksp)
1754 {
1755   PetscErrorCode ierr;
1756   SNES           snes;
1757 
1758   PetscFunctionBegin;
1759   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1760   PetscValidPointer(ksp,2);
1761   if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first");
1762   if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()");
1763   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1764   ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr);
1765   PetscFunctionReturn(0);
1766 }
1767 
1768 /* ----------- Routines to set solver parameters ---------- */
1769 
1770 #undef __FUNCT__
1771 #define __FUNCT__ "TSGetDuration"
1772 /*@
1773    TSGetDuration - Gets the maximum number of timesteps to use and
1774    maximum time for iteration.
1775 
1776    Not Collective
1777 
1778    Input Parameters:
1779 +  ts       - the TS context obtained from TSCreate()
1780 .  maxsteps - maximum number of iterations to use, or PETSC_NULL
1781 -  maxtime  - final time to iterate to, or PETSC_NULL
1782 
1783    Level: intermediate
1784 
1785 .keywords: TS, timestep, get, maximum, iterations, time
1786 @*/
1787 PetscErrorCode  TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
1788 {
1789   PetscFunctionBegin;
1790   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1791   if (maxsteps) {
1792     PetscValidIntPointer(maxsteps,2);
1793     *maxsteps = ts->max_steps;
1794   }
1795   if (maxtime) {
1796     PetscValidScalarPointer(maxtime,3);
1797     *maxtime  = ts->max_time;
1798   }
1799   PetscFunctionReturn(0);
1800 }
1801 
1802 #undef __FUNCT__
1803 #define __FUNCT__ "TSSetDuration"
1804 /*@
1805    TSSetDuration - Sets the maximum number of timesteps to use and
1806    maximum time for iteration.
1807 
1808    Logically Collective on TS
1809 
1810    Input Parameters:
1811 +  ts - the TS context obtained from TSCreate()
1812 .  maxsteps - maximum number of iterations to use
1813 -  maxtime - final time to iterate to
1814 
1815    Options Database Keys:
1816 .  -ts_max_steps <maxsteps> - Sets maxsteps
1817 .  -ts_final_time <maxtime> - Sets maxtime
1818 
1819    Notes:
1820    The default maximum number of iterations is 5000. Default time is 5.0
1821 
1822    Level: intermediate
1823 
1824 .keywords: TS, timestep, set, maximum, iterations
1825 
1826 .seealso: TSSetExactFinalTime()
1827 @*/
1828 PetscErrorCode  TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime)
1829 {
1830   PetscFunctionBegin;
1831   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1832   PetscValidLogicalCollectiveInt(ts,maxsteps,2);
1833   PetscValidLogicalCollectiveReal(ts,maxtime,2);
1834   if (maxsteps >= 0) ts->max_steps = maxsteps;
1835   if (maxtime != PETSC_DEFAULT) ts->max_time  = maxtime;
1836   PetscFunctionReturn(0);
1837 }
1838 
1839 #undef __FUNCT__
1840 #define __FUNCT__ "TSSetSolution"
1841 /*@
1842    TSSetSolution - Sets the initial solution vector
1843    for use by the TS routines.
1844 
1845    Logically Collective on TS and Vec
1846 
1847    Input Parameters:
1848 +  ts - the TS context obtained from TSCreate()
1849 -  u - the solution vector
1850 
1851    Level: beginner
1852 
1853 .keywords: TS, timestep, set, solution, initial conditions
1854 @*/
1855 PetscErrorCode  TSSetSolution(TS ts,Vec u)
1856 {
1857   PetscErrorCode ierr;
1858   DM             dm;
1859 
1860   PetscFunctionBegin;
1861   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1862   PetscValidHeaderSpecific(u,VEC_CLASSID,2);
1863   ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr);
1864   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
1865   ts->vec_sol = u;
1866   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1867   ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr);
1868   PetscFunctionReturn(0);
1869 }
1870 
1871 #undef __FUNCT__
1872 #define __FUNCT__ "TSSetPreStep"
1873 /*@C
1874   TSSetPreStep - Sets the general-purpose function
1875   called once at the beginning of each time step.
1876 
1877   Logically Collective on TS
1878 
1879   Input Parameters:
1880 + ts   - The TS context obtained from TSCreate()
1881 - func - The function
1882 
1883   Calling sequence of func:
1884 . func (TS ts);
1885 
1886   Level: intermediate
1887 
1888   Note:
1889   If a step is rejected, TSStep() will call this routine again before each attempt.
1890   The last completed time step number can be queried using TSGetTimeStepNumber(), the
1891   size of the step being attempted can be obtained using TSGetTimeStep().
1892 
1893 .keywords: TS, timestep
1894 .seealso: TSSetPreStage(), TSSetPostStep(), TSStep()
1895 @*/
1896 PetscErrorCode  TSSetPreStep(TS ts, PetscErrorCode (*func)(TS))
1897 {
1898   PetscFunctionBegin;
1899   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1900   ts->ops->prestep = func;
1901   PetscFunctionReturn(0);
1902 }
1903 
1904 #undef __FUNCT__
1905 #define __FUNCT__ "TSPreStep"
1906 /*@
1907   TSPreStep - Runs the user-defined pre-step function.
1908 
1909   Collective on TS
1910 
1911   Input Parameters:
1912 . ts   - The TS context obtained from TSCreate()
1913 
1914   Notes:
1915   TSPreStep() is typically used within time stepping implementations,
1916   so most users would not generally call this routine themselves.
1917 
1918   Level: developer
1919 
1920 .keywords: TS, timestep
1921 .seealso: TSSetPreStep(), TSPreStage(), TSPostStep()
1922 @*/
1923 PetscErrorCode  TSPreStep(TS ts)
1924 {
1925   PetscErrorCode ierr;
1926 
1927   PetscFunctionBegin;
1928   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1929   if (ts->ops->prestep) {
1930     PetscStackPush("TS PreStep function");
1931     ierr = (*ts->ops->prestep)(ts);CHKERRQ(ierr);
1932     PetscStackPop;
1933   }
1934   PetscFunctionReturn(0);
1935 }
1936 
1937 #undef __FUNCT__
1938 #define __FUNCT__ "TSSetPreStage"
1939 /*@C
1940   TSSetPreStage - Sets the general-purpose function
1941   called once at the beginning of each stage.
1942 
1943   Logically Collective on TS
1944 
1945   Input Parameters:
1946 + ts   - The TS context obtained from TSCreate()
1947 - func - The function
1948 
1949   Calling sequence of func:
1950 . PetscErrorCode func(TS ts, PetscReal stagetime);
1951 
1952   Level: intermediate
1953 
1954   Note:
1955   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
1956   The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being
1957   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
1958 
1959 .keywords: TS, timestep
1960 .seealso: TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
1961 @*/
1962 PetscErrorCode  TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal))
1963 {
1964   PetscFunctionBegin;
1965   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1966   ts->ops->prestage = func;
1967   PetscFunctionReturn(0);
1968 }
1969 
1970 #undef __FUNCT__
1971 #define __FUNCT__ "TSPreStage"
1972 /*@
1973   TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage()
1974 
1975   Collective on TS
1976 
1977   Input Parameters:
1978 . ts   - The TS context obtained from TSCreate()
1979 
1980   Notes:
1981   TSPreStage() is typically used within time stepping implementations,
1982   most users would not generally call this routine themselves.
1983 
1984   Level: developer
1985 
1986 .keywords: TS, timestep
1987 .seealso: TSSetPreStep(), TSPreStep(), TSPostStep()
1988 @*/
1989 PetscErrorCode  TSPreStage(TS ts, PetscReal stagetime)
1990 {
1991   PetscErrorCode ierr;
1992 
1993   PetscFunctionBegin;
1994   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1995   if (ts->ops->prestage) {
1996     PetscStackPush("TS PreStage function");
1997     ierr = (*ts->ops->prestage)(ts,stagetime);CHKERRQ(ierr);
1998     PetscStackPop;
1999   }
2000   PetscFunctionReturn(0);
2001 }
2002 
2003 #undef __FUNCT__
2004 #define __FUNCT__ "TSSetPostStep"
2005 /*@C
2006   TSSetPostStep - Sets the general-purpose function
2007   called once at the end of each time step.
2008 
2009   Logically Collective on TS
2010 
2011   Input Parameters:
2012 + ts   - The TS context obtained from TSCreate()
2013 - func - The function
2014 
2015   Calling sequence of func:
2016 $ func (TS ts);
2017 
2018   Level: intermediate
2019 
2020 .keywords: TS, timestep
2021 .seealso: TSSetPreStep(), TSSetPreStage(), TSGetTimeStep(), TSGetTimeStepNumber(), TSGetTime()
2022 @*/
2023 PetscErrorCode  TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
2024 {
2025   PetscFunctionBegin;
2026   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2027   ts->ops->poststep = func;
2028   PetscFunctionReturn(0);
2029 }
2030 
2031 #undef __FUNCT__
2032 #define __FUNCT__ "TSPostStep"
2033 /*@
2034   TSPostStep - Runs the user-defined post-step function.
2035 
2036   Collective on TS
2037 
2038   Input Parameters:
2039 . ts   - The TS context obtained from TSCreate()
2040 
2041   Notes:
2042   TSPostStep() is typically used within time stepping implementations,
2043   so most users would not generally call this routine themselves.
2044 
2045   Level: developer
2046 
2047 .keywords: TS, timestep
2048 @*/
2049 PetscErrorCode  TSPostStep(TS ts)
2050 {
2051   PetscErrorCode ierr;
2052 
2053   PetscFunctionBegin;
2054   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2055   if (ts->ops->poststep) {
2056     PetscStackPush("TS PostStep function");
2057     ierr = (*ts->ops->poststep)(ts);CHKERRQ(ierr);
2058     PetscStackPop;
2059   }
2060   PetscFunctionReturn(0);
2061 }
2062 
2063 /* ------------ Routines to set performance monitoring options ----------- */
2064 
2065 #undef __FUNCT__
2066 #define __FUNCT__ "TSMonitorSet"
2067 /*@C
2068    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
2069    timestep to display the iteration's  progress.
2070 
2071    Logically Collective on TS
2072 
2073    Input Parameters:
2074 +  ts - the TS context obtained from TSCreate()
2075 .  monitor - monitoring routine
2076 .  mctx - [optional] user-defined context for private data for the
2077              monitor routine (use PETSC_NULL if no context is desired)
2078 -  monitordestroy - [optional] routine that frees monitor context
2079           (may be PETSC_NULL)
2080 
2081    Calling sequence of monitor:
2082 $    int monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
2083 
2084 +    ts - the TS context
2085 .    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
2086                                been interpolated to)
2087 .    time - current time
2088 .    u - current iterate
2089 -    mctx - [optional] monitoring context
2090 
2091    Notes:
2092    This routine adds an additional monitor to the list of monitors that
2093    already has been loaded.
2094 
2095    Fortran notes: Only a single monitor function can be set for each TS object
2096 
2097    Level: intermediate
2098 
2099 .keywords: TS, timestep, set, monitor
2100 
2101 .seealso: TSMonitorDefault(), TSMonitorCancel()
2102 @*/
2103 PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**))
2104 {
2105   PetscFunctionBegin;
2106   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2107   if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2108   ts->monitor[ts->numbermonitors]           = monitor;
2109   ts->monitordestroy[ts->numbermonitors]    = mdestroy;
2110   ts->monitorcontext[ts->numbermonitors++]  = (void*)mctx;
2111   PetscFunctionReturn(0);
2112 }
2113 
2114 #undef __FUNCT__
2115 #define __FUNCT__ "TSMonitorCancel"
2116 /*@C
2117    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
2118 
2119    Logically Collective on TS
2120 
2121    Input Parameters:
2122 .  ts - the TS context obtained from TSCreate()
2123 
2124    Notes:
2125    There is no way to remove a single, specific monitor.
2126 
2127    Level: intermediate
2128 
2129 .keywords: TS, timestep, set, monitor
2130 
2131 .seealso: TSMonitorDefault(), TSMonitorSet()
2132 @*/
2133 PetscErrorCode  TSMonitorCancel(TS ts)
2134 {
2135   PetscErrorCode ierr;
2136   PetscInt       i;
2137 
2138   PetscFunctionBegin;
2139   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2140   for (i=0; i<ts->numbermonitors; i++) {
2141     if (ts->monitordestroy[i]) {
2142       ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr);
2143     }
2144   }
2145   ts->numbermonitors = 0;
2146   PetscFunctionReturn(0);
2147 }
2148 
2149 #undef __FUNCT__
2150 #define __FUNCT__ "TSMonitorDefault"
2151 /*@
2152    TSMonitorDefault - Sets the Default monitor
2153 
2154    Level: intermediate
2155 
2156 .keywords: TS, set, monitor
2157 
2158 .seealso: TSMonitorDefault(), TSMonitorSet()
2159 @*/
2160 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *dummy)
2161 {
2162   PetscErrorCode ierr;
2163   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)ts)->comm);
2164 
2165   PetscFunctionBegin;
2166   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
2167   ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g\n",step,(double)ts->time_step,(double)ptime);CHKERRQ(ierr);
2168   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
2169   PetscFunctionReturn(0);
2170 }
2171 
2172 #undef __FUNCT__
2173 #define __FUNCT__ "TSSetRetainStages"
2174 /*@
2175    TSSetRetainStages - Request that all stages in the upcoming step be stored so that interpolation will be available.
2176 
2177    Logically Collective on TS
2178 
2179    Input Argument:
2180 .  ts - time stepping context
2181 
2182    Output Argument:
2183 .  flg - PETSC_TRUE or PETSC_FALSE
2184 
2185    Level: intermediate
2186 
2187 .keywords: TS, set
2188 
2189 .seealso: TSInterpolate(), TSSetPostStep()
2190 @*/
2191 PetscErrorCode TSSetRetainStages(TS ts,PetscBool flg)
2192 {
2193   PetscFunctionBegin;
2194   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2195   ts->retain_stages = flg;
2196   PetscFunctionReturn(0);
2197 }
2198 
2199 #undef __FUNCT__
2200 #define __FUNCT__ "TSInterpolate"
2201 /*@
2202    TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval
2203 
2204    Collective on TS
2205 
2206    Input Argument:
2207 +  ts - time stepping context
2208 -  t - time to interpolate to
2209 
2210    Output Argument:
2211 .  U - state at given time
2212 
2213    Notes:
2214    The user should call TSSetRetainStages() before taking a step in which interpolation will be requested.
2215 
2216    Level: intermediate
2217 
2218    Developer Notes:
2219    TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints.
2220 
2221 .keywords: TS, set
2222 
2223 .seealso: TSSetRetainStages(), TSSetPostStep()
2224 @*/
2225 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U)
2226 {
2227   PetscErrorCode ierr;
2228 
2229   PetscFunctionBegin;
2230   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2231   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);
2232   if (!ts->ops->interpolate) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name);
2233   ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr);
2234   PetscFunctionReturn(0);
2235 }
2236 
2237 #undef __FUNCT__
2238 #define __FUNCT__ "TSStep"
2239 /*@
2240    TSStep - Steps one time step
2241 
2242    Collective on TS
2243 
2244    Input Parameter:
2245 .  ts - the TS context obtained from TSCreate()
2246 
2247    Level: intermediate
2248 
2249    Notes:
2250    The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may
2251    be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages.
2252 
2253    This may over-step the final time provided in TSSetDuration() depending on the time-step used. TSSolve() interpolates to exactly the
2254    time provided in TSSetDuration(). One can use TSInterpolate() to determine an interpolated solution within the final timestep.
2255 
2256 .keywords: TS, timestep, solve
2257 
2258 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate()
2259 @*/
2260 PetscErrorCode  TSStep(TS ts)
2261 {
2262   PetscReal      ptime_prev;
2263   PetscErrorCode ierr;
2264 
2265   PetscFunctionBegin;
2266   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2267   ierr = TSSetUp(ts);CHKERRQ(ierr);
2268 
2269   ts->reason = TS_CONVERGED_ITERATING;
2270 
2271   ptime_prev = ts->ptime;
2272   ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr);
2273   ierr = (*ts->ops->step)(ts);CHKERRQ(ierr);
2274   ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr);
2275   ts->time_step_prev = ts->ptime - ptime_prev;
2276 
2277   if (ts->reason < 0) {
2278     if (ts->errorifstepfailed) {
2279       if (ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) {
2280         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]);
2281       } else SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]);
2282     }
2283   } else if (!ts->reason) {
2284     if (ts->steps >= ts->max_steps)
2285       ts->reason = TS_CONVERGED_ITS;
2286     else if (ts->ptime >= ts->max_time)
2287       ts->reason = TS_CONVERGED_TIME;
2288   }
2289 
2290   PetscFunctionReturn(0);
2291 }
2292 
2293 #undef __FUNCT__
2294 #define __FUNCT__ "TSEvaluateStep"
2295 /*@
2296    TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy.
2297 
2298    Collective on TS
2299 
2300    Input Arguments:
2301 +  ts - time stepping context
2302 .  order - desired order of accuracy
2303 -  done - whether the step was evaluated at this order (pass PETSC_NULL to generate an error if not available)
2304 
2305    Output Arguments:
2306 .  U - state at the end of the current step
2307 
2308    Level: advanced
2309 
2310    Notes:
2311    This function cannot be called until all stages have been evaluated.
2312    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.
2313 
2314 .seealso: TSStep(), TSAdapt
2315 @*/
2316 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done)
2317 {
2318   PetscErrorCode ierr;
2319 
2320   PetscFunctionBegin;
2321   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2322   PetscValidType(ts,1);
2323   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
2324   if (!ts->ops->evaluatestep) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name);
2325   ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr);
2326   PetscFunctionReturn(0);
2327 }
2328 
2329 #undef __FUNCT__
2330 #define __FUNCT__ "TSSolve"
2331 /*@
2332    TSSolve - Steps the requested number of timesteps.
2333 
2334    Collective on TS
2335 
2336    Input Parameter:
2337 +  ts - the TS context obtained from TSCreate()
2338 -  u - the solution vector  (can be null if TSSetSolution() was used, otherwise must contain the initial conditions)
2339 
2340    Level: beginner
2341 
2342    Notes:
2343    The final time returned by this function may be different from the time of the internally
2344    held state accessible by TSGetSolution() and TSGetTime() because the method may have
2345    stepped over the final time.
2346 
2347 .keywords: TS, timestep, solve
2348 
2349 .seealso: TSCreate(), TSSetSolution(), TSStep()
2350 @*/
2351 PetscErrorCode TSSolve(TS ts,Vec u)
2352 {
2353   PetscBool         flg;
2354   PetscViewer       viewer;
2355   PetscErrorCode    ierr;
2356   PetscViewerFormat format;
2357 
2358   PetscFunctionBegin;
2359   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2360   if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2);
2361   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 */
2362     if (!ts->vec_sol || u == ts->vec_sol) {
2363       Vec y;
2364       ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
2365       ierr = TSSetSolution(ts,y);CHKERRQ(ierr);
2366       ierr = VecDestroy(&y);CHKERRQ(ierr); /* grant ownership */
2367     }
2368     if (u) {
2369       ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr);
2370     }
2371   } else {
2372     if (u) {
2373       ierr = TSSetSolution(ts,u);CHKERRQ(ierr);
2374     }
2375   }
2376   ierr = TSSetUp(ts);CHKERRQ(ierr);
2377   /* reset time step and iteration counters */
2378   ts->steps = 0;
2379   ts->ksp_its = 0;
2380   ts->snes_its = 0;
2381   ts->num_snes_failures = 0;
2382   ts->reject = 0;
2383   ts->reason = TS_CONVERGED_ITERATING;
2384 
2385   if (ts->ops->solve) {         /* This private interface is transitional and should be removed when all implementations are updated. */
2386     ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr);
2387     ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);
2388     ts->solvetime = ts->ptime;
2389   } else {
2390     /* steps the requested number of timesteps. */
2391     ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
2392     if (ts->steps >= ts->max_steps)
2393       ts->reason = TS_CONVERGED_ITS;
2394     else if (ts->ptime >= ts->max_time)
2395       ts->reason = TS_CONVERGED_TIME;
2396     while (!ts->reason) {
2397       ierr = TSStep(ts);CHKERRQ(ierr);
2398       ierr = TSPostStep(ts);CHKERRQ(ierr);
2399       ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
2400     }
2401     if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) {
2402       ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr);
2403       ts->solvetime = ts->max_time;
2404     } else {
2405       if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);}
2406       ts->solvetime = ts->ptime;
2407     }
2408   }
2409   ierr = TSMonitor(ts,-1,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
2410   ierr = PetscOptionsGetViewer(((PetscObject)ts)->comm,((PetscObject)ts)->prefix,"-ts_view",&viewer,&format,&flg);CHKERRQ(ierr);
2411   if (flg && !PetscPreLoadingOn) {
2412     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
2413     ierr = TSView(ts,viewer);CHKERRQ(ierr);
2414     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
2415     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
2416   }
2417   PetscFunctionReturn(0);
2418 }
2419 
2420 #undef __FUNCT__
2421 #define __FUNCT__ "TSMonitor"
2422 /*@
2423    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()
2424 
2425    Collective on TS
2426 
2427    Input Parameters:
2428 +  ts - time stepping context obtained from TSCreate()
2429 .  step - step number that has just completed
2430 .  ptime - model time of the state
2431 -  u - state at the current model time
2432 
2433    Notes:
2434    TSMonitor() is typically used within the time stepping implementations.
2435    Users might call this function when using the TSStep() interface instead of TSSolve().
2436 
2437    Level: advanced
2438 
2439 .keywords: TS, timestep
2440 @*/
2441 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u)
2442 {
2443   PetscErrorCode ierr;
2444   PetscInt       i,n = ts->numbermonitors;
2445 
2446   PetscFunctionBegin;
2447   for (i=0; i<n; i++) {
2448     ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr);
2449   }
2450   PetscFunctionReturn(0);
2451 }
2452 
2453 /* ------------------------------------------------------------------------*/
2454 struct _n_TSMonitorLGCtx {
2455   PetscDrawLG lg;
2456   PetscInt    howoften;  /* when > 0 uses step % howoften, when negative only final solution plotted */
2457   PetscInt    ksp_its,snes_its;
2458 };
2459 
2460 
2461 #undef __FUNCT__
2462 #define __FUNCT__ "TSMonitorLGCtxCreate"
2463 /*@C
2464    TSMonitorLGCtxCreate - Creates a line graph context for use with
2465    TS to monitor the solution process graphically in various ways
2466 
2467    Collective on TS
2468 
2469    Input Parameters:
2470 +  host - the X display to open, or null for the local machine
2471 .  label - the title to put in the title bar
2472 .  x, y - the screen coordinates of the upper left coordinate of the window
2473 .  m, n - the screen width and height in pixels
2474 -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
2475 
2476    Output Parameter:
2477 .  ctx - the context
2478 
2479    Options Database Key:
2480 +  -ts_monitor_lg_timestep - automatically sets line graph monitor
2481 .  -ts_monitor_lg_solution -
2482 .  -ts_monitor_lg_error -
2483 .  -ts_monitor_lg_ksp_iterations -
2484 .  -ts_monitor_lg_snes_iterations -
2485 -  -lg_indicate_data_points <true,false> - indicate the data points (at each time step) on the plot; default is true
2486 
2487    Notes:
2488    Use TSMonitorLGCtxDestroy() to destroy.
2489 
2490    Level: intermediate
2491 
2492 .keywords: TS, monitor, line graph, residual, seealso
2493 
2494 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError()
2495 
2496 @*/
2497 PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
2498 {
2499   PetscDraw      win;
2500   PetscErrorCode ierr;
2501   PetscBool      flg = PETSC_TRUE;
2502 
2503   PetscFunctionBegin;
2504   ierr = PetscNew(struct _n_TSMonitorLGCtx,ctx);CHKERRQ(ierr);
2505   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&win);CHKERRQ(ierr);
2506   ierr = PetscDrawSetFromOptions(win);CHKERRQ(ierr);
2507   ierr = PetscDrawLGCreate(win,1,&(*ctx)->lg);CHKERRQ(ierr);
2508   ierr = PetscOptionsGetBool(PETSC_NULL,"-lg_indicate_data_points",&flg,PETSC_NULL);CHKERRQ(ierr);
2509   if (flg) {
2510     ierr = PetscDrawLGIndicateDataPoints((*ctx)->lg);CHKERRQ(ierr);
2511   }
2512   ierr = PetscLogObjectParent((*ctx)->lg,win);CHKERRQ(ierr);
2513   (*ctx)->howoften = howoften;
2514   PetscFunctionReturn(0);
2515 }
2516 
2517 #undef __FUNCT__
2518 #define __FUNCT__ "TSMonitorLGTimeStep"
2519 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
2520 {
2521   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
2522   PetscReal      x = ptime,y;
2523   PetscErrorCode ierr;
2524 
2525   PetscFunctionBegin;
2526   if (!n) {
2527     PetscDrawAxis  axis;
2528     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
2529     ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time","Time step");CHKERRQ(ierr);
2530     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
2531   }
2532   ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr);
2533   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
2534   if (((ctx->howoften > 0) && (!(n % ctx->howoften))) || ((ctx->howoften == -1) && (n == -1))){
2535     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
2536   }
2537   PetscFunctionReturn(0);
2538 }
2539 
2540 #undef __FUNCT__
2541 #define __FUNCT__ "TSMonitorLGCtxDestroy"
2542 /*@C
2543    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
2544    with TSMonitorLGCtxCreate().
2545 
2546    Collective on TSMonitorLGCtx
2547 
2548    Input Parameter:
2549 .  ctx - the monitor context
2550 
2551    Level: intermediate
2552 
2553 .keywords: TS, monitor, line graph, destroy
2554 
2555 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep();
2556 @*/
2557 PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
2558 {
2559   PetscDraw      draw;
2560   PetscErrorCode ierr;
2561 
2562   PetscFunctionBegin;
2563   ierr = PetscDrawLGGetDraw((*ctx)->lg,&draw);CHKERRQ(ierr);
2564   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
2565   ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr);
2566   ierr = PetscFree(*ctx);CHKERRQ(ierr);
2567   PetscFunctionReturn(0);
2568 }
2569 
2570 #undef __FUNCT__
2571 #define __FUNCT__ "TSGetTime"
2572 /*@
2573    TSGetTime - Gets the time of the most recently completed step.
2574 
2575    Not Collective
2576 
2577    Input Parameter:
2578 .  ts - the TS context obtained from TSCreate()
2579 
2580    Output Parameter:
2581 .  t  - the current time
2582 
2583    Level: beginner
2584 
2585    Note:
2586    When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(),
2587    TSSetPreStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated.
2588 
2589 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
2590 
2591 .keywords: TS, get, time
2592 @*/
2593 PetscErrorCode  TSGetTime(TS ts,PetscReal* t)
2594 {
2595   PetscFunctionBegin;
2596   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2597   PetscValidRealPointer(t,2);
2598   *t = ts->ptime;
2599   PetscFunctionReturn(0);
2600 }
2601 
2602 #undef __FUNCT__
2603 #define __FUNCT__ "TSSetTime"
2604 /*@
2605    TSSetTime - Allows one to reset the time.
2606 
2607    Logically Collective on TS
2608 
2609    Input Parameters:
2610 +  ts - the TS context obtained from TSCreate()
2611 -  time - the time
2612 
2613    Level: intermediate
2614 
2615 .seealso: TSGetTime(), TSSetDuration()
2616 
2617 .keywords: TS, set, time
2618 @*/
2619 PetscErrorCode  TSSetTime(TS ts, PetscReal t)
2620 {
2621   PetscFunctionBegin;
2622   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2623   PetscValidLogicalCollectiveReal(ts,t,2);
2624   ts->ptime = t;
2625   PetscFunctionReturn(0);
2626 }
2627 
2628 #undef __FUNCT__
2629 #define __FUNCT__ "TSSetOptionsPrefix"
2630 /*@C
2631    TSSetOptionsPrefix - Sets the prefix used for searching for all
2632    TS options in the database.
2633 
2634    Logically Collective on TS
2635 
2636    Input Parameter:
2637 +  ts     - The TS context
2638 -  prefix - The prefix to prepend to all option names
2639 
2640    Notes:
2641    A hyphen (-) must NOT be given at the beginning of the prefix name.
2642    The first character of all runtime options is AUTOMATICALLY the
2643    hyphen.
2644 
2645    Level: advanced
2646 
2647 .keywords: TS, set, options, prefix, database
2648 
2649 .seealso: TSSetFromOptions()
2650 
2651 @*/
2652 PetscErrorCode  TSSetOptionsPrefix(TS ts,const char prefix[])
2653 {
2654   PetscErrorCode ierr;
2655   SNES           snes;
2656 
2657   PetscFunctionBegin;
2658   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2659   ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2660   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2661   ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr);
2662   PetscFunctionReturn(0);
2663 }
2664 
2665 
2666 #undef __FUNCT__
2667 #define __FUNCT__ "TSAppendOptionsPrefix"
2668 /*@C
2669    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
2670    TS options in the database.
2671 
2672    Logically Collective on TS
2673 
2674    Input Parameter:
2675 +  ts     - The TS context
2676 -  prefix - The prefix to prepend to all option names
2677 
2678    Notes:
2679    A hyphen (-) must NOT be given at the beginning of the prefix name.
2680    The first character of all runtime options is AUTOMATICALLY the
2681    hyphen.
2682 
2683    Level: advanced
2684 
2685 .keywords: TS, append, options, prefix, database
2686 
2687 .seealso: TSGetOptionsPrefix()
2688 
2689 @*/
2690 PetscErrorCode  TSAppendOptionsPrefix(TS ts,const char prefix[])
2691 {
2692   PetscErrorCode ierr;
2693   SNES           snes;
2694 
2695   PetscFunctionBegin;
2696   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2697   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2698   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2699   ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr);
2700   PetscFunctionReturn(0);
2701 }
2702 
2703 #undef __FUNCT__
2704 #define __FUNCT__ "TSGetOptionsPrefix"
2705 /*@C
2706    TSGetOptionsPrefix - Sets the prefix used for searching for all
2707    TS options in the database.
2708 
2709    Not Collective
2710 
2711    Input Parameter:
2712 .  ts - The TS context
2713 
2714    Output Parameter:
2715 .  prefix - A pointer to the prefix string used
2716 
2717    Notes: On the fortran side, the user should pass in a string 'prifix' of
2718    sufficient length to hold the prefix.
2719 
2720    Level: intermediate
2721 
2722 .keywords: TS, get, options, prefix, database
2723 
2724 .seealso: TSAppendOptionsPrefix()
2725 @*/
2726 PetscErrorCode  TSGetOptionsPrefix(TS ts,const char *prefix[])
2727 {
2728   PetscErrorCode ierr;
2729 
2730   PetscFunctionBegin;
2731   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2732   PetscValidPointer(prefix,2);
2733   ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2734   PetscFunctionReturn(0);
2735 }
2736 
2737 #undef __FUNCT__
2738 #define __FUNCT__ "TSGetRHSJacobian"
2739 /*@C
2740    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
2741 
2742    Not Collective, but parallel objects are returned if TS is parallel
2743 
2744    Input Parameter:
2745 .  ts  - The TS context obtained from TSCreate()
2746 
2747    Output Parameters:
2748 +  J   - The Jacobian J of F, where U_t = G(U,t)
2749 .  M   - The preconditioner matrix, usually the same as J
2750 .  func - Function to compute the Jacobian of the RHS
2751 -  ctx - User-defined context for Jacobian evaluation routine
2752 
2753    Notes: You can pass in PETSC_NULL for any return argument you do not need.
2754 
2755    Level: intermediate
2756 
2757 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
2758 
2759 .keywords: TS, timestep, get, matrix, Jacobian
2760 @*/
2761 PetscErrorCode  TSGetRHSJacobian(TS ts,Mat *J,Mat *M,TSRHSJacobian *func,void **ctx)
2762 {
2763   PetscErrorCode ierr;
2764   SNES           snes;
2765   DM             dm;
2766 
2767   PetscFunctionBegin;
2768   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2769   ierr = SNESGetJacobian(snes,J,M,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2770   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2771   ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr);
2772   PetscFunctionReturn(0);
2773 }
2774 
2775 #undef __FUNCT__
2776 #define __FUNCT__ "TSGetIJacobian"
2777 /*@C
2778    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
2779 
2780    Not Collective, but parallel objects are returned if TS is parallel
2781 
2782    Input Parameter:
2783 .  ts  - The TS context obtained from TSCreate()
2784 
2785    Output Parameters:
2786 +  A   - The Jacobian of F(t,U,U_t)
2787 .  B   - The preconditioner matrix, often the same as A
2788 .  f   - The function to compute the matrices
2789 - ctx - User-defined context for Jacobian evaluation routine
2790 
2791    Notes: You can pass in PETSC_NULL for any return argument you do not need.
2792 
2793    Level: advanced
2794 
2795 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
2796 
2797 .keywords: TS, timestep, get, matrix, Jacobian
2798 @*/
2799 PetscErrorCode  TSGetIJacobian(TS ts,Mat *A,Mat *B,TSIJacobian *f,void **ctx)
2800 {
2801   PetscErrorCode ierr;
2802   SNES           snes;
2803   DM             dm;
2804 
2805   PetscFunctionBegin;
2806   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2807   ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
2808   ierr = SNESGetJacobian(snes,A,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2809   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2810   ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr);
2811   PetscFunctionReturn(0);
2812 }
2813 
2814 struct _n_TSMonitorDrawCtx {
2815   PetscViewer viewer;
2816   Vec         initialsolution;
2817   PetscBool   showinitial;
2818   PetscInt    howoften;  /* when > 0 uses step % howoften, when negative only final solution plotted */
2819 };
2820 
2821 #undef __FUNCT__
2822 #define __FUNCT__ "TSMonitorDrawSolution"
2823 /*@C
2824    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
2825    VecView() for the solution at each timestep
2826 
2827    Collective on TS
2828 
2829    Input Parameters:
2830 +  ts - the TS context
2831 .  step - current time-step
2832 .  ptime - current time
2833 -  dummy - either a viewer or PETSC_NULL
2834 
2835    Options Database:
2836 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
2837 
2838    Notes: the initial solution and current solution are not displayed with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
2839        will look bad
2840 
2841    Level: intermediate
2842 
2843 .keywords: TS,  vector, monitor, view
2844 
2845 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
2846 @*/
2847 PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
2848 {
2849   PetscErrorCode   ierr;
2850   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
2851 
2852   PetscFunctionBegin;
2853   if (!step && ictx->showinitial) {
2854     if (!ictx->initialsolution) {
2855       ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr);
2856     }
2857     ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr);
2858   }
2859   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften)) && (step > -1)) || ((ictx->howoften == -1) && (step == -1)))) PetscFunctionReturn(0);
2860 
2861   if (ictx->showinitial) {
2862     PetscReal pause;
2863     ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr);
2864     ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr);
2865     ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr);
2866     ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr);
2867     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr);
2868   }
2869   ierr = VecView(u,ictx->viewer);CHKERRQ(ierr);
2870   if (ictx->showinitial) {
2871     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr);
2872   }
2873   PetscFunctionReturn(0);
2874 }
2875 
2876 
2877 #undef __FUNCT__
2878 #define __FUNCT__ "TSMonitorDrawCtxDestroy"
2879 /*@C
2880    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
2881 
2882    Collective on TS
2883 
2884    Input Parameters:
2885 .    ctx - the monitor context
2886 
2887    Level: intermediate
2888 
2889 .keywords: TS,  vector, monitor, view
2890 
2891 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError()
2892 @*/
2893 PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
2894 {
2895   PetscErrorCode       ierr;
2896 
2897   PetscFunctionBegin;
2898   ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr);
2899   ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr);
2900   ierr = PetscFree(*ictx);CHKERRQ(ierr);
2901   PetscFunctionReturn(0);
2902 }
2903 
2904 #undef __FUNCT__
2905 #define __FUNCT__ "TSMonitorDrawCtxCreate"
2906 /*@C
2907    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
2908 
2909    Collective on TS
2910 
2911    Input Parameter:
2912 .    ts - time-step context
2913 
2914    Output Patameter:
2915 .    ctx - the monitor context
2916 
2917    Options Database:
2918 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
2919 
2920    Level: intermediate
2921 
2922 .keywords: TS,  vector, monitor, view
2923 
2924 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx()
2925 @*/
2926 PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
2927 {
2928   PetscErrorCode   ierr;
2929 
2930   PetscFunctionBegin;
2931   ierr = PetscNew(struct _n_TSMonitorDrawCtx,ctx);CHKERRQ(ierr);
2932   ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr);
2933   (*ctx)->showinitial = PETSC_FALSE;
2934   (*ctx)->howoften    = howoften;
2935   ierr = PetscOptionsGetBool(PETSC_NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,PETSC_NULL);CHKERRQ(ierr);
2936   PetscFunctionReturn(0);
2937 }
2938 
2939 #undef __FUNCT__
2940 #define __FUNCT__ "TSMonitorDrawError"
2941 /*@C
2942    TSMonitorDrawError - Monitors progress of the TS solvers by calling
2943    VecView() for the error at each timestep
2944 
2945    Collective on TS
2946 
2947    Input Parameters:
2948 +  ts - the TS context
2949 .  step - current time-step
2950 .  ptime - current time
2951 -  dummy - either a viewer or PETSC_NULL
2952 
2953    Level: intermediate
2954 
2955 .keywords: TS,  vector, monitor, view
2956 
2957 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
2958 @*/
2959 PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
2960 {
2961   PetscErrorCode   ierr;
2962   TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy;
2963   PetscViewer      viewer = ctx->viewer;
2964   Vec              work;
2965 
2966   PetscFunctionBegin;
2967   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1)))) PetscFunctionReturn(0);
2968   ierr = VecDuplicate(u,&work);CHKERRQ(ierr);
2969   ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr);
2970   ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr);
2971   ierr = VecView(work,viewer);CHKERRQ(ierr);
2972   ierr = VecDestroy(&work);CHKERRQ(ierr);
2973   PetscFunctionReturn(0);
2974 }
2975 
2976 #include <petsc-private/dmimpl.h>
2977 #undef __FUNCT__
2978 #define __FUNCT__ "TSSetDM"
2979 /*@
2980    TSSetDM - Sets the DM that may be used by some preconditioners
2981 
2982    Logically Collective on TS and DM
2983 
2984    Input Parameters:
2985 +  ts - the preconditioner context
2986 -  dm - the dm
2987 
2988    Level: intermediate
2989 
2990 
2991 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM()
2992 @*/
2993 PetscErrorCode  TSSetDM(TS ts,DM dm)
2994 {
2995   PetscErrorCode ierr;
2996   SNES           snes;
2997   DMTS           tsdm;
2998 
2999   PetscFunctionBegin;
3000   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3001   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
3002   if (ts->dm) {               /* Move the DMTS context over to the new DM unless the new DM already has one */
3003     if (ts->dm->dmts && !dm->dmts) {
3004       ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr);
3005       ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr);
3006       if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */
3007         tsdm->originaldm = dm;
3008       }
3009     }
3010     ierr = DMDestroy(&ts->dm);CHKERRQ(ierr);
3011   }
3012   ts->dm = dm;
3013   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3014   ierr = SNESSetDM(snes,dm);CHKERRQ(ierr);
3015   PetscFunctionReturn(0);
3016 }
3017 
3018 #undef __FUNCT__
3019 #define __FUNCT__ "TSGetDM"
3020 /*@
3021    TSGetDM - Gets the DM that may be used by some preconditioners
3022 
3023    Not Collective
3024 
3025    Input Parameter:
3026 . ts - the preconditioner context
3027 
3028    Output Parameter:
3029 .  dm - the dm
3030 
3031    Level: intermediate
3032 
3033 
3034 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM()
3035 @*/
3036 PetscErrorCode  TSGetDM(TS ts,DM *dm)
3037 {
3038   PetscErrorCode ierr;
3039 
3040   PetscFunctionBegin;
3041   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3042   if (!ts->dm) {
3043     ierr = DMShellCreate(((PetscObject)ts)->comm,&ts->dm);CHKERRQ(ierr);
3044     if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
3045   }
3046   *dm = ts->dm;
3047   PetscFunctionReturn(0);
3048 }
3049 
3050 #undef __FUNCT__
3051 #define __FUNCT__ "SNESTSFormFunction"
3052 /*@
3053    SNESTSFormFunction - Function to evaluate nonlinear residual
3054 
3055    Logically Collective on SNES
3056 
3057    Input Parameter:
3058 + snes - nonlinear solver
3059 . U - the current state at which to evaluate the residual
3060 - ctx - user context, must be a TS
3061 
3062    Output Parameter:
3063 . F - the nonlinear residual
3064 
3065    Notes:
3066    This function is not normally called by users and is automatically registered with the SNES used by TS.
3067    It is most frequently passed to MatFDColoringSetFunction().
3068 
3069    Level: advanced
3070 
3071 .seealso: SNESSetFunction(), MatFDColoringSetFunction()
3072 @*/
3073 PetscErrorCode  SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx)
3074 {
3075   TS             ts = (TS)ctx;
3076   PetscErrorCode ierr;
3077 
3078   PetscFunctionBegin;
3079   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3080   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
3081   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
3082   PetscValidHeaderSpecific(ts,TS_CLASSID,4);
3083   ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr);
3084   PetscFunctionReturn(0);
3085 }
3086 
3087 #undef __FUNCT__
3088 #define __FUNCT__ "SNESTSFormJacobian"
3089 /*@
3090    SNESTSFormJacobian - Function to evaluate the Jacobian
3091 
3092    Collective on SNES
3093 
3094    Input Parameter:
3095 + snes - nonlinear solver
3096 . U - the current state at which to evaluate the residual
3097 - ctx - user context, must be a TS
3098 
3099    Output Parameter:
3100 + A - the Jacobian
3101 . B - the preconditioning matrix (may be the same as A)
3102 - flag - indicates any structure change in the matrix
3103 
3104    Notes:
3105    This function is not normally called by users and is automatically registered with the SNES used by TS.
3106 
3107    Level: developer
3108 
3109 .seealso: SNESSetJacobian()
3110 @*/
3111 PetscErrorCode  SNESTSFormJacobian(SNES snes,Vec U,Mat *A,Mat *B,MatStructure *flag,void *ctx)
3112 {
3113   TS             ts = (TS)ctx;
3114   PetscErrorCode ierr;
3115 
3116   PetscFunctionBegin;
3117   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3118   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
3119   PetscValidPointer(A,3);
3120   PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
3121   PetscValidPointer(B,4);
3122   PetscValidHeaderSpecific(*B,MAT_CLASSID,4);
3123   PetscValidPointer(flag,5);
3124   PetscValidHeaderSpecific(ts,TS_CLASSID,6);
3125   ierr = (ts->ops->snesjacobian)(snes,U,A,B,flag,ts);CHKERRQ(ierr);
3126   PetscFunctionReturn(0);
3127 }
3128 
3129 #undef __FUNCT__
3130 #define __FUNCT__ "TSComputeRHSFunctionLinear"
3131 /*@C
3132    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only
3133 
3134    Collective on TS
3135 
3136    Input Arguments:
3137 +  ts - time stepping context
3138 .  t - time at which to evaluate
3139 .  U - state at which to evaluate
3140 -  ctx - context
3141 
3142    Output Arguments:
3143 .  F - right hand side
3144 
3145    Level: intermediate
3146 
3147    Notes:
3148    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
3149    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().
3150 
3151 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
3152 @*/
3153 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx)
3154 {
3155   PetscErrorCode ierr;
3156   Mat            Arhs,Brhs;
3157   MatStructure   flg2;
3158 
3159   PetscFunctionBegin;
3160   ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
3161   ierr = TSComputeRHSJacobian(ts,t,U,&Arhs,&Brhs,&flg2);CHKERRQ(ierr);
3162   ierr = MatMult(Arhs,U,F);CHKERRQ(ierr);
3163   PetscFunctionReturn(0);
3164 }
3165 
3166 #undef __FUNCT__
3167 #define __FUNCT__ "TSComputeRHSJacobianConstant"
3168 /*@C
3169    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
3170 
3171    Collective on TS
3172 
3173    Input Arguments:
3174 +  ts - time stepping context
3175 .  t - time at which to evaluate
3176 .  U - state at which to evaluate
3177 -  ctx - context
3178 
3179    Output Arguments:
3180 +  A - pointer to operator
3181 .  B - pointer to preconditioning matrix
3182 -  flg - matrix structure flag
3183 
3184    Level: intermediate
3185 
3186    Notes:
3187    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.
3188 
3189 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear()
3190 @*/
3191 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat *A,Mat *B,MatStructure *flg,void *ctx)
3192 {
3193   PetscFunctionBegin;
3194   *flg = SAME_PRECONDITIONER;
3195   PetscFunctionReturn(0);
3196 }
3197 
3198 #undef __FUNCT__
3199 #define __FUNCT__ "TSComputeIFunctionLinear"
3200 /*@C
3201    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
3202 
3203    Collective on TS
3204 
3205    Input Arguments:
3206 +  ts - time stepping context
3207 .  t - time at which to evaluate
3208 .  U - state at which to evaluate
3209 .  Udot - time derivative of state vector
3210 -  ctx - context
3211 
3212    Output Arguments:
3213 .  F - left hand side
3214 
3215    Level: intermediate
3216 
3217    Notes:
3218    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
3219    user is required to write their own TSComputeIFunction.
3220    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
3221    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().
3222 
3223 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant()
3224 @*/
3225 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx)
3226 {
3227   PetscErrorCode ierr;
3228   Mat            A,B;
3229   MatStructure   flg2;
3230 
3231   PetscFunctionBegin;
3232   ierr = TSGetIJacobian(ts,&A,&B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
3233   ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,&A,&B,&flg2,PETSC_TRUE);CHKERRQ(ierr);
3234   ierr = MatMult(A,Udot,F);CHKERRQ(ierr);
3235   PetscFunctionReturn(0);
3236 }
3237 
3238 #undef __FUNCT__
3239 #define __FUNCT__ "TSComputeIJacobianConstant"
3240 /*@C
3241    TSComputeIJacobianConstant - Reuses a Jacobian that is time-independent.
3242 
3243    Collective on TS
3244 
3245    Input Arguments:
3246 +  ts - time stepping context
3247 .  t - time at which to evaluate
3248 .  U - state at which to evaluate
3249 .  Udot - time derivative of state vector
3250 .  shift - shift to apply
3251 -  ctx - context
3252 
3253    Output Arguments:
3254 +  A - pointer to operator
3255 .  B - pointer to preconditioning matrix
3256 -  flg - matrix structure flag
3257 
3258    Level: intermediate
3259 
3260    Notes:
3261    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.
3262 
3263 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear()
3264 @*/
3265 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,void *ctx)
3266 {
3267   PetscFunctionBegin;
3268   *flg = SAME_PRECONDITIONER;
3269   PetscFunctionReturn(0);
3270 }
3271 
3272 #undef __FUNCT__
3273 #define __FUNCT__ "TSGetConvergedReason"
3274 /*@
3275    TSGetConvergedReason - Gets the reason the TS iteration was stopped.
3276 
3277    Not Collective
3278 
3279    Input Parameter:
3280 .  ts - the TS context
3281 
3282    Output Parameter:
3283 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
3284             manual pages for the individual convergence tests for complete lists
3285 
3286    Level: beginner
3287 
3288    Notes:
3289    Can only be called after the call to TSSolve() is complete.
3290 
3291 .keywords: TS, nonlinear, set, convergence, test
3292 
3293 .seealso: TSSetConvergenceTest(), TSConvergedReason
3294 @*/
3295 PetscErrorCode  TSGetConvergedReason(TS ts,TSConvergedReason *reason)
3296 {
3297   PetscFunctionBegin;
3298   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3299   PetscValidPointer(reason,2);
3300   *reason = ts->reason;
3301   PetscFunctionReturn(0);
3302 }
3303 
3304 #undef __FUNCT__
3305 #define __FUNCT__ "TSSetConvergedReason"
3306 /*@
3307    TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve.
3308 
3309    Not Collective
3310 
3311    Input Parameter:
3312 +  ts - the TS context
3313 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
3314             manual pages for the individual convergence tests for complete lists
3315 
3316    Level: advanced
3317 
3318    Notes:
3319    Can only be called during TSSolve() is active.
3320 
3321 .keywords: TS, nonlinear, set, convergence, test
3322 
3323 .seealso: TSConvergedReason
3324 @*/
3325 PetscErrorCode  TSSetConvergedReason(TS ts,TSConvergedReason reason)
3326 {
3327   PetscFunctionBegin;
3328   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3329   ts->reason = reason;
3330   PetscFunctionReturn(0);
3331 }
3332 
3333 #undef __FUNCT__
3334 #define __FUNCT__ "TSGetSolveTime"
3335 /*@
3336    TSGetSolveTime - Gets the time after a call to TSSolve()
3337 
3338    Not Collective
3339 
3340    Input Parameter:
3341 .  ts - the TS context
3342 
3343    Output Parameter:
3344 .  ftime - the final time. This time should correspond to the final time set with TSSetDuration()
3345 
3346    Level: beginner
3347 
3348    Notes:
3349    Can only be called after the call to TSSolve() is complete.
3350 
3351 .keywords: TS, nonlinear, set, convergence, test
3352 
3353 .seealso: TSSetConvergenceTest(), TSConvergedReason
3354 @*/
3355 PetscErrorCode  TSGetSolveTime(TS ts,PetscReal *ftime)
3356 {
3357   PetscFunctionBegin;
3358   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3359   PetscValidPointer(ftime,2);
3360   *ftime = ts->solvetime;
3361   PetscFunctionReturn(0);
3362 }
3363 
3364 #undef __FUNCT__
3365 #define __FUNCT__ "TSGetSNESIterations"
3366 /*@
3367    TSGetSNESIterations - Gets the total number of nonlinear iterations
3368    used by the time integrator.
3369 
3370    Not Collective
3371 
3372    Input Parameter:
3373 .  ts - TS context
3374 
3375    Output Parameter:
3376 .  nits - number of nonlinear iterations
3377 
3378    Notes:
3379    This counter is reset to zero for each successive call to TSSolve().
3380 
3381    Level: intermediate
3382 
3383 .keywords: TS, get, number, nonlinear, iterations
3384 
3385 .seealso:  TSGetKSPIterations()
3386 @*/
3387 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits)
3388 {
3389   PetscFunctionBegin;
3390   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3391   PetscValidIntPointer(nits,2);
3392   *nits = ts->snes_its;
3393   PetscFunctionReturn(0);
3394 }
3395 
3396 #undef __FUNCT__
3397 #define __FUNCT__ "TSGetKSPIterations"
3398 /*@
3399    TSGetKSPIterations - Gets the total number of linear iterations
3400    used by the time integrator.
3401 
3402    Not Collective
3403 
3404    Input Parameter:
3405 .  ts - TS context
3406 
3407    Output Parameter:
3408 .  lits - number of linear iterations
3409 
3410    Notes:
3411    This counter is reset to zero for each successive call to TSSolve().
3412 
3413    Level: intermediate
3414 
3415 .keywords: TS, get, number, linear, iterations
3416 
3417 .seealso:  TSGetSNESIterations(), SNESGetKSPIterations()
3418 @*/
3419 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits)
3420 {
3421   PetscFunctionBegin;
3422   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3423   PetscValidIntPointer(lits,2);
3424   *lits = ts->ksp_its;
3425   PetscFunctionReturn(0);
3426 }
3427 
3428 #undef __FUNCT__
3429 #define __FUNCT__ "TSGetStepRejections"
3430 /*@
3431    TSGetStepRejections - Gets the total number of rejected steps.
3432 
3433    Not Collective
3434 
3435    Input Parameter:
3436 .  ts - TS context
3437 
3438    Output Parameter:
3439 .  rejects - number of steps rejected
3440 
3441    Notes:
3442    This counter is reset to zero for each successive call to TSSolve().
3443 
3444    Level: intermediate
3445 
3446 .keywords: TS, get, number
3447 
3448 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails()
3449 @*/
3450 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects)
3451 {
3452   PetscFunctionBegin;
3453   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3454   PetscValidIntPointer(rejects,2);
3455   *rejects = ts->reject;
3456   PetscFunctionReturn(0);
3457 }
3458 
3459 #undef __FUNCT__
3460 #define __FUNCT__ "TSGetSNESFailures"
3461 /*@
3462    TSGetSNESFailures - Gets the total number of failed SNES solves
3463 
3464    Not Collective
3465 
3466    Input Parameter:
3467 .  ts - TS context
3468 
3469    Output Parameter:
3470 .  fails - number of failed nonlinear solves
3471 
3472    Notes:
3473    This counter is reset to zero for each successive call to TSSolve().
3474 
3475    Level: intermediate
3476 
3477 .keywords: TS, get, number
3478 
3479 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures()
3480 @*/
3481 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails)
3482 {
3483   PetscFunctionBegin;
3484   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3485   PetscValidIntPointer(fails,2);
3486   *fails = ts->num_snes_failures;
3487   PetscFunctionReturn(0);
3488 }
3489 
3490 #undef __FUNCT__
3491 #define __FUNCT__ "TSSetMaxStepRejections"
3492 /*@
3493    TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails
3494 
3495    Not Collective
3496 
3497    Input Parameter:
3498 +  ts - TS context
3499 -  rejects - maximum number of rejected steps, pass -1 for unlimited
3500 
3501    Notes:
3502    The counter is reset to zero for each step
3503 
3504    Options Database Key:
3505  .  -ts_max_reject - Maximum number of step rejections before a step fails
3506 
3507    Level: intermediate
3508 
3509 .keywords: TS, set, maximum, number
3510 
3511 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
3512 @*/
3513 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects)
3514 {
3515   PetscFunctionBegin;
3516   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3517   ts->max_reject = rejects;
3518   PetscFunctionReturn(0);
3519 }
3520 
3521 #undef __FUNCT__
3522 #define __FUNCT__ "TSSetMaxSNESFailures"
3523 /*@
3524    TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves
3525 
3526    Not Collective
3527 
3528    Input Parameter:
3529 +  ts - TS context
3530 -  fails - maximum number of failed nonlinear solves, pass -1 for unlimited
3531 
3532    Notes:
3533    The counter is reset to zero for each successive call to TSSolve().
3534 
3535    Options Database Key:
3536  .  -ts_max_snes_failures - Maximum number of nonlinear solve failures
3537 
3538    Level: intermediate
3539 
3540 .keywords: TS, set, maximum, number
3541 
3542 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason()
3543 @*/
3544 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails)
3545 {
3546   PetscFunctionBegin;
3547   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3548   ts->max_snes_failures = fails;
3549   PetscFunctionReturn(0);
3550 }
3551 
3552 #undef __FUNCT__
3553 #define __FUNCT__ "TSSetErrorIfStepFails()"
3554 /*@
3555    TSSetErrorIfStepFails - Error if no step succeeds
3556 
3557    Not Collective
3558 
3559    Input Parameter:
3560 +  ts - TS context
3561 -  err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure
3562 
3563    Options Database Key:
3564  .  -ts_error_if_step_fails - Error if no step succeeds
3565 
3566    Level: intermediate
3567 
3568 .keywords: TS, set, error
3569 
3570 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
3571 @*/
3572 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err)
3573 {
3574   PetscFunctionBegin;
3575   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3576   ts->errorifstepfailed = err;
3577   PetscFunctionReturn(0);
3578 }
3579 
3580 #undef __FUNCT__
3581 #define __FUNCT__ "TSMonitorSolutionBinary"
3582 /*@C
3583    TSMonitorSolutionBinary - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file
3584 
3585    Collective on TS
3586 
3587    Input Parameters:
3588 +  ts - the TS context
3589 .  step - current time-step
3590 .  ptime - current time
3591 .  u - current state
3592 -  viewer - binary viewer
3593 
3594    Level: intermediate
3595 
3596 .keywords: TS,  vector, monitor, view
3597 
3598 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3599 @*/
3600 PetscErrorCode  TSMonitorSolutionBinary(TS ts,PetscInt step,PetscReal ptime,Vec u,void *viewer)
3601 {
3602   PetscErrorCode ierr;
3603   PetscViewer    v = (PetscViewer)viewer;
3604 
3605   PetscFunctionBegin;
3606   ierr = VecView(u,v);CHKERRQ(ierr);
3607   PetscFunctionReturn(0);
3608 }
3609 
3610 #undef __FUNCT__
3611 #define __FUNCT__ "TSMonitorSolutionVTK"
3612 /*@C
3613    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
3614 
3615    Collective on TS
3616 
3617    Input Parameters:
3618 +  ts - the TS context
3619 .  step - current time-step
3620 .  ptime - current time
3621 .  u - current state
3622 -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
3623 
3624    Level: intermediate
3625 
3626    Notes:
3627    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.
3628    These are named according to the file name template.
3629 
3630    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().
3631 
3632 .keywords: TS,  vector, monitor, view
3633 
3634 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3635 @*/
3636 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
3637 {
3638   PetscErrorCode ierr;
3639   char           filename[PETSC_MAX_PATH_LEN];
3640   PetscViewer    viewer;
3641 
3642   PetscFunctionBegin;
3643   ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr);
3644   ierr = PetscViewerVTKOpen(((PetscObject)ts)->comm,filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr);
3645   ierr = VecView(u,viewer);CHKERRQ(ierr);
3646   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3647   PetscFunctionReturn(0);
3648 }
3649 
3650 #undef __FUNCT__
3651 #define __FUNCT__ "TSMonitorSolutionVTKDestroy"
3652 /*@C
3653    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
3654 
3655    Collective on TS
3656 
3657    Input Parameters:
3658 .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
3659 
3660    Level: intermediate
3661 
3662    Note:
3663    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
3664 
3665 .keywords: TS,  vector, monitor, view
3666 
3667 .seealso: TSMonitorSet(), TSMonitorSolutionVTK()
3668 @*/
3669 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
3670 {
3671   PetscErrorCode ierr;
3672 
3673   PetscFunctionBegin;
3674   ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr);
3675   PetscFunctionReturn(0);
3676 }
3677 
3678 #undef __FUNCT__
3679 #define __FUNCT__ "TSGetTSAdapt"
3680 /*@
3681    TSGetTSAdapt - Get the adaptive controller context for the current method
3682 
3683    Collective on TS if controller has not been created yet
3684 
3685    Input Arguments:
3686 .  ts - time stepping context
3687 
3688    Output Arguments:
3689 .  adapt - adaptive controller
3690 
3691    Level: intermediate
3692 
3693 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose()
3694 @*/
3695 PetscErrorCode TSGetTSAdapt(TS ts,TSAdapt *adapt)
3696 {
3697   PetscErrorCode ierr;
3698 
3699   PetscFunctionBegin;
3700   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3701   PetscValidPointer(adapt,2);
3702   if (!ts->adapt) {
3703     ierr = TSAdaptCreate(((PetscObject)ts)->comm,&ts->adapt);CHKERRQ(ierr);
3704     ierr = PetscLogObjectParent(ts,ts->adapt);CHKERRQ(ierr);
3705     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr);
3706   }
3707   *adapt = ts->adapt;
3708   PetscFunctionReturn(0);
3709 }
3710 
3711 #undef __FUNCT__
3712 #define __FUNCT__ "TSSetTolerances"
3713 /*@
3714    TSSetTolerances - Set tolerances for local truncation error when using adaptive controller
3715 
3716    Logically Collective
3717 
3718    Input Arguments:
3719 +  ts - time integration context
3720 .  atol - scalar absolute tolerances, PETSC_DECIDE to leave current value
3721 .  vatol - vector of absolute tolerances or PETSC_NULL, used in preference to atol if present
3722 .  rtol - scalar relative tolerances, PETSC_DECIDE to leave current value
3723 -  vrtol - vector of relative tolerances or PETSC_NULL, used in preference to atol if present
3724 
3725    Level: beginner
3726 
3727 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances()
3728 @*/
3729 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol)
3730 {
3731   PetscErrorCode ierr;
3732 
3733   PetscFunctionBegin;
3734   if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol;
3735   if (vatol) {
3736     ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr);
3737     ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
3738     ts->vatol = vatol;
3739   }
3740   if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol;
3741   if (vrtol) {
3742     ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr);
3743     ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
3744     ts->vrtol = vrtol;
3745   }
3746   PetscFunctionReturn(0);
3747 }
3748 
3749 #undef __FUNCT__
3750 #define __FUNCT__ "TSGetTolerances"
3751 /*@
3752    TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
3753 
3754    Logically Collective
3755 
3756    Input Arguments:
3757 .  ts - time integration context
3758 
3759    Output Arguments:
3760 +  atol - scalar absolute tolerances, PETSC_NULL to ignore
3761 .  vatol - vector of absolute tolerances, PETSC_NULL to ignore
3762 .  rtol - scalar relative tolerances, PETSC_NULL to ignore
3763 -  vrtol - vector of relative tolerances, PETSC_NULL to ignore
3764 
3765    Level: beginner
3766 
3767 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances()
3768 @*/
3769 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol)
3770 {
3771   PetscFunctionBegin;
3772   if (atol)  *atol  = ts->atol;
3773   if (vatol) *vatol = ts->vatol;
3774   if (rtol)  *rtol  = ts->rtol;
3775   if (vrtol) *vrtol = ts->vrtol;
3776   PetscFunctionReturn(0);
3777 }
3778 
3779 #undef __FUNCT__
3780 #define __FUNCT__ "TSErrorNormWRMS"
3781 /*@
3782    TSErrorNormWRMS - compute a weighted norm of the difference between a vector and the current state
3783 
3784    Collective on TS
3785 
3786    Input Arguments:
3787 +  ts - time stepping context
3788 -  Y - state vector to be compared to ts->vec_sol
3789 
3790    Output Arguments:
3791 .  norm - weighted norm, a value of 1.0 is considered small
3792 
3793    Level: developer
3794 
3795 .seealso: TSSetTolerances()
3796 @*/
3797 PetscErrorCode TSErrorNormWRMS(TS ts,Vec Y,PetscReal *norm)
3798 {
3799   PetscErrorCode    ierr;
3800   PetscInt          i,n,N;
3801   const PetscScalar *u,*y;
3802   Vec               U;
3803   PetscReal         sum,gsum;
3804 
3805   PetscFunctionBegin;
3806   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3807   PetscValidHeaderSpecific(Y,VEC_CLASSID,2);
3808   PetscValidPointer(norm,3);
3809   U = ts->vec_sol;
3810   PetscCheckSameTypeAndComm(U,1,Y,2);
3811   if (U == Y) SETERRQ(((PetscObject)U)->comm,PETSC_ERR_ARG_IDN,"Y cannot be the TS solution vector");
3812 
3813   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
3814   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
3815   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
3816   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
3817   sum = 0.;
3818   if (ts->vatol && ts->vrtol) {
3819     const PetscScalar *atol,*rtol;
3820     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
3821     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
3822     for (i=0; i<n; i++) {
3823       PetscReal tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
3824       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
3825     }
3826     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
3827     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
3828   } else if (ts->vatol) {       /* vector atol, scalar rtol */
3829     const PetscScalar *atol;
3830     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
3831     for (i=0; i<n; i++) {
3832       PetscReal tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
3833       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
3834     }
3835     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
3836   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
3837     const PetscScalar *rtol;
3838     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
3839     for (i=0; i<n; i++) {
3840       PetscReal tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
3841       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
3842     }
3843     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
3844   } else {                      /* scalar atol, scalar rtol */
3845     for (i=0; i<n; i++) {
3846       PetscReal tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
3847       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
3848     }
3849   }
3850   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
3851   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
3852 
3853   ierr = MPI_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,((PetscObject)ts)->comm);CHKERRQ(ierr);
3854   *norm = PetscSqrtReal(gsum / N);
3855   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
3856   PetscFunctionReturn(0);
3857 }
3858 
3859 #undef __FUNCT__
3860 #define __FUNCT__ "TSSetCFLTimeLocal"
3861 /*@
3862    TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
3863 
3864    Logically Collective on TS
3865 
3866    Input Arguments:
3867 +  ts - time stepping context
3868 -  cfltime - maximum stable time step if using forward Euler (value can be different on each process)
3869 
3870    Note:
3871    After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
3872 
3873    Level: intermediate
3874 
3875 .seealso: TSGetCFLTime(), TSADAPTCFL
3876 @*/
3877 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime)
3878 {
3879   PetscFunctionBegin;
3880   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3881   ts->cfltime_local = cfltime;
3882   ts->cfltime = -1.;
3883   PetscFunctionReturn(0);
3884 }
3885 
3886 #undef __FUNCT__
3887 #define __FUNCT__ "TSGetCFLTime"
3888 /*@
3889    TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
3890 
3891    Collective on TS
3892 
3893    Input Arguments:
3894 .  ts - time stepping context
3895 
3896    Output Arguments:
3897 .  cfltime - maximum stable time step for forward Euler
3898 
3899    Level: advanced
3900 
3901 .seealso: TSSetCFLTimeLocal()
3902 @*/
3903 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime)
3904 {
3905   PetscErrorCode ierr;
3906 
3907   PetscFunctionBegin;
3908   if (ts->cfltime < 0) {
3909     ierr = MPI_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,((PetscObject)ts)->comm);CHKERRQ(ierr);
3910   }
3911   *cfltime = ts->cfltime;
3912   PetscFunctionReturn(0);
3913 }
3914 
3915 #undef __FUNCT__
3916 #define __FUNCT__ "TSVISetVariableBounds"
3917 /*@
3918    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
3919 
3920    Input Parameters:
3921 .  ts   - the TS context.
3922 .  xl   - lower bound.
3923 .  xu   - upper bound.
3924 
3925    Notes:
3926    If this routine is not called then the lower and upper bounds are set to
3927    SNES_VI_NINF and SNES_VI_INF respectively during SNESSetUp().
3928 
3929    Level: advanced
3930 
3931 @*/
3932 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
3933 {
3934   PetscErrorCode ierr;
3935   SNES           snes;
3936 
3937   PetscFunctionBegin;
3938   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3939   ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr);
3940   PetscFunctionReturn(0);
3941 }
3942 
3943 #if defined(PETSC_HAVE_MATLAB_ENGINE)
3944 #include <mex.h>
3945 
3946 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext;
3947 
3948 #undef __FUNCT__
3949 #define __FUNCT__ "TSComputeFunction_Matlab"
3950 /*
3951    TSComputeFunction_Matlab - Calls the function that has been set with
3952                          TSSetFunctionMatlab().
3953 
3954    Collective on TS
3955 
3956    Input Parameters:
3957 +  snes - the TS context
3958 -  u - input vector
3959 
3960    Output Parameter:
3961 .  y - function vector, as set by TSSetFunction()
3962 
3963    Notes:
3964    TSComputeFunction() is typically used within nonlinear solvers
3965    implementations, so most users would not generally call this routine
3966    themselves.
3967 
3968    Level: developer
3969 
3970 .keywords: TS, nonlinear, compute, function
3971 
3972 .seealso: TSSetFunction(), TSGetFunction()
3973 */
3974 PetscErrorCode  TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx)
3975 {
3976   PetscErrorCode   ierr;
3977   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
3978   int              nlhs = 1,nrhs = 7;
3979   mxArray          *plhs[1],*prhs[7];
3980   long long int    lx = 0,lxdot = 0,ly = 0,ls = 0;
3981 
3982   PetscFunctionBegin;
3983   PetscValidHeaderSpecific(snes,TS_CLASSID,1);
3984   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
3985   PetscValidHeaderSpecific(udot,VEC_CLASSID,4);
3986   PetscValidHeaderSpecific(y,VEC_CLASSID,5);
3987   PetscCheckSameComm(snes,1,u,3);
3988   PetscCheckSameComm(snes,1,y,5);
3989 
3990   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
3991   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
3992   ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr);
3993   ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr);
3994   prhs[0] =  mxCreateDoubleScalar((double)ls);
3995   prhs[1] =  mxCreateDoubleScalar(time);
3996   prhs[2] =  mxCreateDoubleScalar((double)lx);
3997   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
3998   prhs[4] =  mxCreateDoubleScalar((double)ly);
3999   prhs[5] =  mxCreateString(sctx->funcname);
4000   prhs[6] =  sctx->ctx;
4001   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr);
4002   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4003   mxDestroyArray(prhs[0]);
4004   mxDestroyArray(prhs[1]);
4005   mxDestroyArray(prhs[2]);
4006   mxDestroyArray(prhs[3]);
4007   mxDestroyArray(prhs[4]);
4008   mxDestroyArray(prhs[5]);
4009   mxDestroyArray(plhs[0]);
4010   PetscFunctionReturn(0);
4011 }
4012 
4013 
4014 #undef __FUNCT__
4015 #define __FUNCT__ "TSSetFunctionMatlab"
4016 /*
4017    TSSetFunctionMatlab - Sets the function evaluation routine and function
4018    vector for use by the TS routines in solving ODEs
4019    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
4020 
4021    Logically Collective on TS
4022 
4023    Input Parameters:
4024 +  ts - the TS context
4025 -  func - function evaluation routine
4026 
4027    Calling sequence of func:
4028 $    func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx);
4029 
4030    Level: beginner
4031 
4032 .keywords: TS, nonlinear, set, function
4033 
4034 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
4035 */
4036 PetscErrorCode  TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx)
4037 {
4038   PetscErrorCode  ierr;
4039   TSMatlabContext *sctx;
4040 
4041   PetscFunctionBegin;
4042   /* currently sctx is memory bleed */
4043   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
4044   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4045   /*
4046      This should work, but it doesn't
4047   sctx->ctx = ctx;
4048   mexMakeArrayPersistent(sctx->ctx);
4049   */
4050   sctx->ctx = mxDuplicateArray(ctx);
4051   ierr = TSSetIFunction(ts,PETSC_NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr);
4052   PetscFunctionReturn(0);
4053 }
4054 
4055 #undef __FUNCT__
4056 #define __FUNCT__ "TSComputeJacobian_Matlab"
4057 /*
4058    TSComputeJacobian_Matlab - Calls the function that has been set with
4059                          TSSetJacobianMatlab().
4060 
4061    Collective on TS
4062 
4063    Input Parameters:
4064 +  ts - the TS context
4065 .  u - input vector
4066 .  A, B - the matrices
4067 -  ctx - user context
4068 
4069    Output Parameter:
4070 .  flag - structure of the matrix
4071 
4072    Level: developer
4073 
4074 .keywords: TS, nonlinear, compute, function
4075 
4076 .seealso: TSSetFunction(), TSGetFunction()
4077 @*/
4078 PetscErrorCode  TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flag, void *ctx)
4079 {
4080   PetscErrorCode  ierr;
4081   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
4082   int             nlhs = 2,nrhs = 9;
4083   mxArray         *plhs[2],*prhs[9];
4084   long long int   lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0;
4085 
4086   PetscFunctionBegin;
4087   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4088   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
4089 
4090   /* call Matlab function in ctx with arguments u and y */
4091 
4092   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
4093   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
4094   ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr);
4095   ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr);
4096   ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr);
4097   prhs[0] =  mxCreateDoubleScalar((double)ls);
4098   prhs[1] =  mxCreateDoubleScalar((double)time);
4099   prhs[2] =  mxCreateDoubleScalar((double)lx);
4100   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
4101   prhs[4] =  mxCreateDoubleScalar((double)shift);
4102   prhs[5] =  mxCreateDoubleScalar((double)lA);
4103   prhs[6] =  mxCreateDoubleScalar((double)lB);
4104   prhs[7] =  mxCreateString(sctx->funcname);
4105   prhs[8] =  sctx->ctx;
4106   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr);
4107   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4108   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
4109   mxDestroyArray(prhs[0]);
4110   mxDestroyArray(prhs[1]);
4111   mxDestroyArray(prhs[2]);
4112   mxDestroyArray(prhs[3]);
4113   mxDestroyArray(prhs[4]);
4114   mxDestroyArray(prhs[5]);
4115   mxDestroyArray(prhs[6]);
4116   mxDestroyArray(prhs[7]);
4117   mxDestroyArray(plhs[0]);
4118   mxDestroyArray(plhs[1]);
4119   PetscFunctionReturn(0);
4120 }
4121 
4122 
4123 #undef __FUNCT__
4124 #define __FUNCT__ "TSSetJacobianMatlab"
4125 /*
4126    TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
4127    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
4128 
4129    Logically Collective on TS
4130 
4131    Input Parameters:
4132 +  ts - the TS context
4133 .  A,B - Jacobian matrices
4134 .  func - function evaluation routine
4135 -  ctx - user context
4136 
4137    Calling sequence of func:
4138 $    flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx);
4139 
4140 
4141    Level: developer
4142 
4143 .keywords: TS, nonlinear, set, function
4144 
4145 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
4146 */
4147 PetscErrorCode  TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx)
4148 {
4149   PetscErrorCode    ierr;
4150   TSMatlabContext *sctx;
4151 
4152   PetscFunctionBegin;
4153   /* currently sctx is memory bleed */
4154   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
4155   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4156   /*
4157      This should work, but it doesn't
4158   sctx->ctx = ctx;
4159   mexMakeArrayPersistent(sctx->ctx);
4160   */
4161   sctx->ctx = mxDuplicateArray(ctx);
4162   ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
4163   PetscFunctionReturn(0);
4164 }
4165 
4166 #undef __FUNCT__
4167 #define __FUNCT__ "TSMonitor_Matlab"
4168 /*
4169    TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab().
4170 
4171    Collective on TS
4172 
4173 .seealso: TSSetFunction(), TSGetFunction()
4174 @*/
4175 PetscErrorCode  TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx)
4176 {
4177   PetscErrorCode  ierr;
4178   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
4179   int             nlhs = 1,nrhs = 6;
4180   mxArray         *plhs[1],*prhs[6];
4181   long long int   lx = 0,ls = 0;
4182 
4183   PetscFunctionBegin;
4184   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4185   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
4186 
4187   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
4188   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
4189   prhs[0] =  mxCreateDoubleScalar((double)ls);
4190   prhs[1] =  mxCreateDoubleScalar((double)it);
4191   prhs[2] =  mxCreateDoubleScalar((double)time);
4192   prhs[3] =  mxCreateDoubleScalar((double)lx);
4193   prhs[4] =  mxCreateString(sctx->funcname);
4194   prhs[5] =  sctx->ctx;
4195   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr);
4196   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4197   mxDestroyArray(prhs[0]);
4198   mxDestroyArray(prhs[1]);
4199   mxDestroyArray(prhs[2]);
4200   mxDestroyArray(prhs[3]);
4201   mxDestroyArray(prhs[4]);
4202   mxDestroyArray(plhs[0]);
4203   PetscFunctionReturn(0);
4204 }
4205 
4206 
4207 #undef __FUNCT__
4208 #define __FUNCT__ "TSMonitorSetMatlab"
4209 /*
4210    TSMonitorSetMatlab - Sets the monitor function from Matlab
4211 
4212    Level: developer
4213 
4214 .keywords: TS, nonlinear, set, function
4215 
4216 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
4217 */
4218 PetscErrorCode  TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx)
4219 {
4220   PetscErrorCode    ierr;
4221   TSMatlabContext *sctx;
4222 
4223   PetscFunctionBegin;
4224   /* currently sctx is memory bleed */
4225   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
4226   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4227   /*
4228      This should work, but it doesn't
4229   sctx->ctx = ctx;
4230   mexMakeArrayPersistent(sctx->ctx);
4231   */
4232   sctx->ctx = mxDuplicateArray(ctx);
4233   ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4234   PetscFunctionReturn(0);
4235 }
4236 #endif
4237 
4238 
4239 
4240 #undef __FUNCT__
4241 #define __FUNCT__ "TSMonitorLGSolution"
4242 /*@C
4243    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
4244        in a time based line graph
4245 
4246    Collective on TS
4247 
4248    Input Parameters:
4249 +  ts - the TS context
4250 .  step - current time-step
4251 .  ptime - current time
4252 -  lg - a line graph object
4253 
4254    Level: intermediate
4255 
4256     Notes: each process in a parallel run displays its component solutions in a separate window
4257 
4258 .keywords: TS,  vector, monitor, view
4259 
4260 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4261 @*/
4262 PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4263 {
4264   PetscErrorCode    ierr;
4265   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
4266   const PetscScalar *yy;
4267   PetscInt          dim;
4268 
4269   PetscFunctionBegin;
4270   if (!step) {
4271     PetscDrawAxis  axis;
4272     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4273     ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr);
4274     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
4275     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
4276     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4277   }
4278   ierr = VecGetArrayRead(u,&yy);CHKERRQ(ierr);
4279 #if defined(PETSC_USE_COMPLEX)
4280   {
4281     PetscReal *yreal;
4282     PetscInt i,n;
4283     ierr = VecGetLocalSize(u,&n);CHKERRQ(ierr);
4284     ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr);
4285     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
4286     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
4287     ierr = PetscFree(yreal);CHKERRQ(ierr);
4288   }
4289 #else
4290   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
4291 #endif
4292   ierr = VecRestoreArrayRead(u,&yy);CHKERRQ(ierr);
4293   if (((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1))){
4294     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4295   }
4296   PetscFunctionReturn(0);
4297 }
4298 
4299 #undef __FUNCT__
4300 #define __FUNCT__ "TSMonitorLGError"
4301 /*@C
4302    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector
4303        in a time based line graph
4304 
4305    Collective on TS
4306 
4307    Input Parameters:
4308 +  ts - the TS context
4309 .  step - current time-step
4310 .  ptime - current time
4311 -  lg - a line graph object
4312 
4313    Level: intermediate
4314 
4315    Notes:
4316    Only for sequential solves.
4317 
4318    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
4319 
4320    Options Database Keys:
4321 .  -ts_monitor_lg_error - create a graphical monitor of error history
4322 
4323 .keywords: TS,  vector, monitor, view
4324 
4325 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
4326 @*/
4327 PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4328 {
4329   PetscErrorCode    ierr;
4330   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
4331   const PetscScalar *yy;
4332   Vec               y;
4333   PetscInt          dim;
4334 
4335   PetscFunctionBegin;
4336   if (!step) {
4337     PetscDrawAxis  axis;
4338     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4339     ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr);
4340     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
4341     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
4342     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4343   }
4344   ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
4345   ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr);
4346   ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr);
4347   ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr);
4348 #if defined(PETSC_USE_COMPLEX)
4349   {
4350     PetscReal *yreal;
4351     PetscInt  i,n;
4352     ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr);
4353     ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr);
4354     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
4355     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
4356     ierr = PetscFree(yreal);CHKERRQ(ierr);
4357   }
4358 #else
4359   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
4360 #endif
4361   ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr);
4362   ierr = VecDestroy(&y);CHKERRQ(ierr);
4363   if (((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1))){
4364     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4365   }
4366   PetscFunctionReturn(0);
4367 }
4368 
4369 #undef __FUNCT__
4370 #define __FUNCT__ "TSMonitorLGSNESIterations"
4371 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
4372 {
4373   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
4374   PetscReal      x = ptime,y;
4375   PetscErrorCode ierr;
4376   PetscInt       its;
4377 
4378   PetscFunctionBegin;
4379   if (!n) {
4380     PetscDrawAxis  axis;
4381     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4382     ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr);
4383     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4384     ctx->snes_its  = 0;
4385   }
4386   ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr);
4387   y    = its - ctx->snes_its;
4388   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
4389   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))){
4390     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4391   }
4392   ctx->snes_its = its;
4393   PetscFunctionReturn(0);
4394 }
4395 
4396 #undef __FUNCT__
4397 #define __FUNCT__ "TSMonitorLGKSPIterations"
4398 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
4399 {
4400   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
4401   PetscReal      x = ptime,y;
4402   PetscErrorCode ierr;
4403   PetscInt       its;
4404 
4405   PetscFunctionBegin;
4406   if (!n) {
4407     PetscDrawAxis  axis;
4408     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4409     ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr);
4410     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4411     ctx->ksp_its = 0;
4412   }
4413   ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr);
4414   y    = its - ctx->ksp_its;
4415   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
4416   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))){
4417     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4418   }
4419   ctx->ksp_its = its;
4420   PetscFunctionReturn(0);
4421 }
4422 
4423 #undef __FUNCT__
4424 #define __FUNCT__ "TSComputeLinearStability"
4425 /*@
4426    TSComputeLinearStability - computes the linear stability function at a point
4427 
4428    Collective on TS and Vec
4429 
4430    Input Parameters:
4431 +  ts - the TS context
4432 -  xr,xi - real and imaginary part of input arguments
4433 
4434    Output Parameters:
4435 .  yr,yi - real and imaginary part of function value
4436 
4437    Level: developer
4438 
4439 .keywords: TS, compute
4440 
4441 .seealso: TSSetRHSFunction(), TSComputeIFunction()
4442 @*/
4443 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi)
4444 {
4445   PetscErrorCode ierr;
4446 
4447   PetscFunctionBegin;
4448   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4449   if (!ts->ops->linearstability) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_SUP,"Linearized stability function not provided for this method");
4450   ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr);
4451   PetscFunctionReturn(0);
4452 }
4453