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