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