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