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