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