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