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