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