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