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