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