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