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