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