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