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