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