xref: /petsc/src/ts/interface/ts.c (revision 5ab264f3a2c5f7b4402bc8da2ae9fefa99c8eabd)
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/lib/petsc/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     PetscInt    tabs;
1995     ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr);
1996     ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)ts)->tablevel);CHKERRQ(ierr);
1997     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer);CHKERRQ(ierr);
1998     if (ts->ops->view) {
1999       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2000       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
2001       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2002     }
2003     if (ts->max_steps < PETSC_MAX_INT) {
2004       ierr = PetscViewerASCIIPrintf(viewer,"  maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr);
2005     }
2006     if (ts->max_time < PETSC_MAX_REAL) {
2007       ierr = PetscViewerASCIIPrintf(viewer,"  maximum time=%g\n",(double)ts->max_time);CHKERRQ(ierr);
2008     }
2009     if (ts->usessnes) {
2010       PetscBool lin;
2011       if (ts->problem_type == TS_NONLINEAR) {
2012         ierr = PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solver iterations=%D\n",ts->snes_its);CHKERRQ(ierr);
2013       }
2014       ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",ts->ksp_its);CHKERRQ(ierr);
2015       ierr = PetscObjectTypeCompare((PetscObject)ts->snes,SNESKSPONLY,&lin);CHKERRQ(ierr);
2016       ierr = PetscViewerASCIIPrintf(viewer,"  total number of %slinear solve failures=%D\n",lin ? "" : "non",ts->num_snes_failures);CHKERRQ(ierr);
2017     }
2018     ierr = PetscViewerASCIIPrintf(viewer,"  total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr);
2019     if (ts->vrtol) {
2020       ierr = PetscViewerASCIIPrintf(viewer,"  using vector of relative error tolerances, ");CHKERRQ(ierr);
2021     } else {
2022       ierr = PetscViewerASCIIPrintf(viewer,"  using relative error tolerance of %g, ",(double)ts->rtol);CHKERRQ(ierr);
2023     }
2024     if (ts->vatol) {
2025       ierr = PetscViewerASCIIPrintf(viewer,"  using vector of absolute error tolerances\n");CHKERRQ(ierr);
2026     } else {
2027       ierr = PetscViewerASCIIPrintf(viewer,"  using absolute error tolerance of %g\n",(double)ts->atol);CHKERRQ(ierr);
2028     }
2029     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2030     ierr = TSAdaptView(ts->adapt,viewer);CHKERRQ(ierr);
2031     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2032     if (ts->snes && ts->usessnes)  {
2033       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2034       ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);
2035       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2036     }
2037     ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr);
2038     ierr = DMTSView(sdm,viewer);CHKERRQ(ierr);
2039     ierr = PetscViewerASCIISetTab(viewer, tabs);CHKERRQ(ierr);
2040   } else if (isstring) {
2041     ierr = TSGetType(ts,&type);CHKERRQ(ierr);
2042     ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr);
2043   } else if (isbinary) {
2044     PetscInt    classid = TS_FILE_CLASSID;
2045     MPI_Comm    comm;
2046     PetscMPIInt rank;
2047     char        type[256];
2048 
2049     ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr);
2050     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
2051     if (!rank) {
2052       ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
2053       ierr = PetscStrncpy(type,((PetscObject)ts)->type_name,256);CHKERRQ(ierr);
2054       ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
2055     }
2056     if (ts->ops->view) {
2057       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
2058     }
2059     if (ts->adapt) {ierr = TSAdaptView(ts->adapt,viewer);CHKERRQ(ierr);}
2060     ierr = DMView(ts->dm,viewer);CHKERRQ(ierr);
2061     ierr = VecView(ts->vec_sol,viewer);CHKERRQ(ierr);
2062     ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr);
2063     ierr = DMTSView(sdm,viewer);CHKERRQ(ierr);
2064   } else if (isdraw) {
2065     PetscDraw draw;
2066     char      str[36];
2067     PetscReal x,y,bottom,h;
2068 
2069     ierr   = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
2070     ierr   = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
2071     ierr   = PetscStrcpy(str,"TS: ");CHKERRQ(ierr);
2072     ierr   = PetscStrcat(str,((PetscObject)ts)->type_name);CHKERRQ(ierr);
2073     ierr   = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLACK,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr);
2074     bottom = y - h;
2075     ierr   = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
2076     if (ts->ops->view) {
2077       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
2078     }
2079     if (ts->adapt) {ierr = TSAdaptView(ts->adapt,viewer);CHKERRQ(ierr);}
2080     if (ts->snes)  {ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);}
2081     ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr);
2082 #if defined(PETSC_HAVE_SAWS)
2083   } else if (issaws) {
2084     PetscMPIInt rank;
2085     const char  *name;
2086 
2087     ierr = PetscObjectGetName((PetscObject)ts,&name);CHKERRQ(ierr);
2088     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
2089     if (!((PetscObject)ts)->amsmem && !rank) {
2090       char       dir[1024];
2091 
2092       ierr = PetscObjectViewSAWs((PetscObject)ts,viewer);CHKERRQ(ierr);
2093       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time_step",name);CHKERRQ(ierr);
2094       PetscStackCallSAWs(SAWs_Register,(dir,&ts->steps,1,SAWs_READ,SAWs_INT));
2095       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time",name);CHKERRQ(ierr);
2096       PetscStackCallSAWs(SAWs_Register,(dir,&ts->ptime,1,SAWs_READ,SAWs_DOUBLE));
2097     }
2098     if (ts->ops->view) {
2099       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
2100     }
2101 #endif
2102   }
2103 
2104   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2105   ierr = PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr);
2106   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2107   PetscFunctionReturn(0);
2108 }
2109 
2110 /*@
2111    TSSetApplicationContext - Sets an optional user-defined context for
2112    the timesteppers.
2113 
2114    Logically Collective on TS
2115 
2116    Input Parameters:
2117 +  ts - the TS context obtained from TSCreate()
2118 -  usrP - optional user context
2119 
2120    Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this
2121     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
2122 
2123    Level: intermediate
2124 
2125 .keywords: TS, timestep, set, application, context
2126 
2127 .seealso: TSGetApplicationContext()
2128 @*/
2129 PetscErrorCode  TSSetApplicationContext(TS ts,void *usrP)
2130 {
2131   PetscFunctionBegin;
2132   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2133   ts->user = usrP;
2134   PetscFunctionReturn(0);
2135 }
2136 
2137 /*@
2138     TSGetApplicationContext - Gets the user-defined context for the
2139     timestepper.
2140 
2141     Not Collective
2142 
2143     Input Parameter:
2144 .   ts - the TS context obtained from TSCreate()
2145 
2146     Output Parameter:
2147 .   usrP - user context
2148 
2149    Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this
2150     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
2151 
2152     Level: intermediate
2153 
2154 .keywords: TS, timestep, get, application, context
2155 
2156 .seealso: TSSetApplicationContext()
2157 @*/
2158 PetscErrorCode  TSGetApplicationContext(TS ts,void *usrP)
2159 {
2160   PetscFunctionBegin;
2161   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2162   *(void**)usrP = ts->user;
2163   PetscFunctionReturn(0);
2164 }
2165 
2166 /*@
2167    TSGetStepNumber - Gets the number of steps completed.
2168 
2169    Not Collective
2170 
2171    Input Parameter:
2172 .  ts - the TS context obtained from TSCreate()
2173 
2174    Output Parameter:
2175 .  steps - number of steps completed so far
2176 
2177    Level: intermediate
2178 
2179 .keywords: TS, timestep, get, iteration, number
2180 .seealso: TSGetTime(), TSGetTimeStep(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSSetPostStep()
2181 @*/
2182 PetscErrorCode TSGetStepNumber(TS ts,PetscInt *steps)
2183 {
2184   PetscFunctionBegin;
2185   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2186   PetscValidIntPointer(steps,2);
2187   *steps = ts->steps;
2188   PetscFunctionReturn(0);
2189 }
2190 
2191 /*@
2192    TSSetStepNumber - Sets the number of steps completed.
2193 
2194    Logically Collective on TS
2195 
2196    Input Parameters:
2197 +  ts - the TS context
2198 -  steps - number of steps completed so far
2199 
2200    Notes:
2201    For most uses of the TS solvers the user need not explicitly call
2202    TSSetStepNumber(), as the step counter is appropriately updated in
2203    TSSolve()/TSStep()/TSRollBack(). Power users may call this routine to
2204    reinitialize timestepping by setting the step counter to zero (and time
2205    to the initial time) to solve a similar problem with different initial
2206    conditions or parameters. Other possible use case is to continue
2207    timestepping from a previously interrupted run in such a way that TS
2208    monitors will be called with a initial nonzero step counter.
2209 
2210    Level: advanced
2211 
2212 .keywords: TS, timestep, set, iteration, number
2213 .seealso: TSGetStepNumber(), TSSetTime(), TSSetTimeStep(), TSSetSolution()
2214 @*/
2215 PetscErrorCode TSSetStepNumber(TS ts,PetscInt steps)
2216 {
2217   PetscFunctionBegin;
2218   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2219   PetscValidLogicalCollectiveInt(ts,steps,2);
2220   if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Step number must be non-negative");
2221   ts->steps = steps;
2222   PetscFunctionReturn(0);
2223 }
2224 
2225 /*@
2226    TSSetTimeStep - Allows one to reset the timestep at any time,
2227    useful for simple pseudo-timestepping codes.
2228 
2229    Logically Collective on TS
2230 
2231    Input Parameters:
2232 +  ts - the TS context obtained from TSCreate()
2233 -  time_step - the size of the timestep
2234 
2235    Level: intermediate
2236 
2237 .seealso: TSGetTimeStep(), TSSetTime()
2238 
2239 .keywords: TS, set, timestep
2240 @*/
2241 PetscErrorCode  TSSetTimeStep(TS ts,PetscReal time_step)
2242 {
2243   PetscFunctionBegin;
2244   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2245   PetscValidLogicalCollectiveReal(ts,time_step,2);
2246   ts->time_step = time_step;
2247   PetscFunctionReturn(0);
2248 }
2249 
2250 /*@
2251    TSSetExactFinalTime - Determines whether to adapt the final time step to
2252      match the exact final time, interpolate solution to the exact final time,
2253      or just return at the final time TS computed.
2254 
2255   Logically Collective on TS
2256 
2257    Input Parameter:
2258 +   ts - the time-step context
2259 -   eftopt - exact final time option
2260 
2261 $  TS_EXACTFINALTIME_STEPOVER    - Don't do anything if final time is exceeded
2262 $  TS_EXACTFINALTIME_INTERPOLATE - Interpolate back to final time
2263 $  TS_EXACTFINALTIME_MATCHSTEP - Adapt final time step to match the final time
2264 
2265    Options Database:
2266 .   -ts_exact_final_time <stepover,interpolate,matchstep> - select the final step at runtime
2267 
2268    Warning: If you use the option TS_EXACTFINALTIME_STEPOVER the solution may be at a very different time
2269     then the final time you selected.
2270 
2271    Level: beginner
2272 
2273 .seealso: TSExactFinalTimeOption, TSGetExactFinalTime()
2274 @*/
2275 PetscErrorCode TSSetExactFinalTime(TS ts,TSExactFinalTimeOption eftopt)
2276 {
2277   PetscFunctionBegin;
2278   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2279   PetscValidLogicalCollectiveEnum(ts,eftopt,2);
2280   ts->exact_final_time = eftopt;
2281   PetscFunctionReturn(0);
2282 }
2283 
2284 /*@
2285    TSGetExactFinalTime - Gets the exact final time option.
2286 
2287    Not Collective
2288 
2289    Input Parameter:
2290 .  ts - the TS context
2291 
2292    Output Parameter:
2293 .  eftopt - exact final time option
2294 
2295    Level: beginner
2296 
2297 .seealso: TSExactFinalTimeOption, TSSetExactFinalTime()
2298 @*/
2299 PetscErrorCode TSGetExactFinalTime(TS ts,TSExactFinalTimeOption *eftopt)
2300 {
2301   PetscFunctionBegin;
2302   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2303   PetscValidPointer(eftopt,2);
2304   *eftopt = ts->exact_final_time;
2305   PetscFunctionReturn(0);
2306 }
2307 
2308 /*@
2309    TSGetTimeStep - Gets the current timestep size.
2310 
2311    Not Collective
2312 
2313    Input Parameter:
2314 .  ts - the TS context obtained from TSCreate()
2315 
2316    Output Parameter:
2317 .  dt - the current timestep size
2318 
2319    Level: intermediate
2320 
2321 .seealso: TSSetTimeStep(), TSGetTime()
2322 
2323 .keywords: TS, get, timestep
2324 @*/
2325 PetscErrorCode  TSGetTimeStep(TS ts,PetscReal *dt)
2326 {
2327   PetscFunctionBegin;
2328   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2329   PetscValidRealPointer(dt,2);
2330   *dt = ts->time_step;
2331   PetscFunctionReturn(0);
2332 }
2333 
2334 /*@
2335    TSGetSolution - Returns the solution at the present timestep. It
2336    is valid to call this routine inside the function that you are evaluating
2337    in order to move to the new timestep. This vector not changed until
2338    the solution at the next timestep has been calculated.
2339 
2340    Not Collective, but Vec returned is parallel if TS is parallel
2341 
2342    Input Parameter:
2343 .  ts - the TS context obtained from TSCreate()
2344 
2345    Output Parameter:
2346 .  v - the vector containing the solution
2347 
2348    Note: If you used TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP); this does not return the solution at the requested
2349    final time. It returns the solution at the next timestep.
2350 
2351    Level: intermediate
2352 
2353 .seealso: TSGetTimeStep(), TSGetTime(), TSGetSolveTime(), TSGetSolutionComponents(), TSSetSolutionFunction()
2354 
2355 .keywords: TS, timestep, get, solution
2356 @*/
2357 PetscErrorCode  TSGetSolution(TS ts,Vec *v)
2358 {
2359   PetscFunctionBegin;
2360   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2361   PetscValidPointer(v,2);
2362   *v = ts->vec_sol;
2363   PetscFunctionReturn(0);
2364 }
2365 
2366 /*@
2367    TSGetSolutionComponents - Returns any solution components at the present
2368    timestep, if available for the time integration method being used.
2369    Solution components are quantities that share the same size and
2370    structure as the solution vector.
2371 
2372    Not Collective, but Vec returned is parallel if TS is parallel
2373 
2374    Parameters :
2375 .  ts - the TS context obtained from TSCreate() (input parameter).
2376 .  n - If v is PETSC_NULL, then the number of solution components is
2377        returned through n, else the n-th solution component is
2378        returned in v.
2379 .  v - the vector containing the n-th solution component
2380        (may be PETSC_NULL to use this function to find out
2381         the number of solutions components).
2382 
2383    Level: advanced
2384 
2385 .seealso: TSGetSolution()
2386 
2387 .keywords: TS, timestep, get, solution
2388 @*/
2389 PetscErrorCode  TSGetSolutionComponents(TS ts,PetscInt *n,Vec *v)
2390 {
2391   PetscErrorCode ierr;
2392 
2393   PetscFunctionBegin;
2394   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2395   if (!ts->ops->getsolutioncomponents) *n = 0;
2396   else {
2397     ierr = (*ts->ops->getsolutioncomponents)(ts,n,v);CHKERRQ(ierr);
2398   }
2399   PetscFunctionReturn(0);
2400 }
2401 
2402 /*@
2403    TSGetAuxSolution - Returns an auxiliary solution at the present
2404    timestep, if available for the time integration method being used.
2405 
2406    Not Collective, but Vec returned is parallel if TS is parallel
2407 
2408    Parameters :
2409 .  ts - the TS context obtained from TSCreate() (input parameter).
2410 .  v - the vector containing the auxiliary solution
2411 
2412    Level: intermediate
2413 
2414 .seealso: TSGetSolution()
2415 
2416 .keywords: TS, timestep, get, solution
2417 @*/
2418 PetscErrorCode  TSGetAuxSolution(TS ts,Vec *v)
2419 {
2420   PetscErrorCode ierr;
2421 
2422   PetscFunctionBegin;
2423   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2424   if (ts->ops->getauxsolution) {
2425     ierr = (*ts->ops->getauxsolution)(ts,v);CHKERRQ(ierr);
2426   } else {
2427     ierr = VecZeroEntries(*v); CHKERRQ(ierr);
2428   }
2429   PetscFunctionReturn(0);
2430 }
2431 
2432 /*@
2433    TSGetTimeError - Returns the estimated error vector, if the chosen
2434    TSType has an error estimation functionality.
2435 
2436    Not Collective, but Vec returned is parallel if TS is parallel
2437 
2438    Note: MUST call after TSSetUp()
2439 
2440    Parameters :
2441 .  ts - the TS context obtained from TSCreate() (input parameter).
2442 .  n - current estimate (n=0) or previous one (n=-1)
2443 .  v - the vector containing the error (same size as the solution).
2444 
2445    Level: intermediate
2446 
2447 .seealso: TSGetSolution(), TSSetTimeError()
2448 
2449 .keywords: TS, timestep, get, error
2450 @*/
2451 PetscErrorCode  TSGetTimeError(TS ts,PetscInt n,Vec *v)
2452 {
2453   PetscErrorCode ierr;
2454 
2455   PetscFunctionBegin;
2456   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2457   if (ts->ops->gettimeerror) {
2458     ierr = (*ts->ops->gettimeerror)(ts,n,v);CHKERRQ(ierr);
2459   } else {
2460     ierr = VecZeroEntries(*v);CHKERRQ(ierr);
2461   }
2462   PetscFunctionReturn(0);
2463 }
2464 
2465 /*@
2466    TSSetTimeError - Sets the estimated error vector, if the chosen
2467    TSType has an error estimation functionality. This can be used
2468    to restart such a time integrator with a given error vector.
2469 
2470    Not Collective, but Vec returned is parallel if TS is parallel
2471 
2472    Parameters :
2473 .  ts - the TS context obtained from TSCreate() (input parameter).
2474 .  v - the vector containing the error (same size as the solution).
2475 
2476    Level: intermediate
2477 
2478 .seealso: TSSetSolution(), TSGetTimeError)
2479 
2480 .keywords: TS, timestep, get, error
2481 @*/
2482 PetscErrorCode  TSSetTimeError(TS ts,Vec v)
2483 {
2484   PetscErrorCode ierr;
2485 
2486   PetscFunctionBegin;
2487   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2488   if (!ts->setupcalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetUp() first");
2489   if (ts->ops->settimeerror) {
2490     ierr = (*ts->ops->settimeerror)(ts,v);CHKERRQ(ierr);
2491   }
2492   PetscFunctionReturn(0);
2493 }
2494 
2495 /*@
2496    TSGetCostGradients - Returns the gradients from the TSAdjointSolve()
2497 
2498    Not Collective, but Vec returned is parallel if TS is parallel
2499 
2500    Input Parameter:
2501 .  ts - the TS context obtained from TSCreate()
2502 
2503    Output Parameter:
2504 +  lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables
2505 -  mu - vectors containing the gradients of the cost functions with respect to the problem parameters
2506 
2507    Level: intermediate
2508 
2509 .seealso: TSGetTimeStep()
2510 
2511 .keywords: TS, timestep, get, sensitivity
2512 @*/
2513 PetscErrorCode  TSGetCostGradients(TS ts,PetscInt *numcost,Vec **lambda,Vec **mu)
2514 {
2515   PetscFunctionBegin;
2516   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2517   if (numcost) *numcost = ts->numcost;
2518   if (lambda)  *lambda  = ts->vecs_sensi;
2519   if (mu)      *mu      = ts->vecs_sensip;
2520   PetscFunctionReturn(0);
2521 }
2522 
2523 /* ----- Routines to initialize and destroy a timestepper ---- */
2524 /*@
2525   TSSetProblemType - Sets the type of problem to be solved.
2526 
2527   Not collective
2528 
2529   Input Parameters:
2530 + ts   - The TS
2531 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
2532 .vb
2533          U_t - A U = 0      (linear)
2534          U_t - A(t) U = 0   (linear)
2535          F(t,U,U_t) = 0     (nonlinear)
2536 .ve
2537 
2538    Level: beginner
2539 
2540 .keywords: TS, problem type
2541 .seealso: TSSetUp(), TSProblemType, TS
2542 @*/
2543 PetscErrorCode  TSSetProblemType(TS ts, TSProblemType type)
2544 {
2545   PetscErrorCode ierr;
2546 
2547   PetscFunctionBegin;
2548   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2549   ts->problem_type = type;
2550   if (type == TS_LINEAR) {
2551     SNES snes;
2552     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2553     ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);
2554   }
2555   PetscFunctionReturn(0);
2556 }
2557 
2558 /*@C
2559   TSGetProblemType - Gets the type of problem to be solved.
2560 
2561   Not collective
2562 
2563   Input Parameter:
2564 . ts   - The TS
2565 
2566   Output Parameter:
2567 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
2568 .vb
2569          M U_t = A U
2570          M(t) U_t = A(t) U
2571          F(t,U,U_t)
2572 .ve
2573 
2574    Level: beginner
2575 
2576 .keywords: TS, problem type
2577 .seealso: TSSetUp(), TSProblemType, TS
2578 @*/
2579 PetscErrorCode  TSGetProblemType(TS ts, TSProblemType *type)
2580 {
2581   PetscFunctionBegin;
2582   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2583   PetscValidIntPointer(type,2);
2584   *type = ts->problem_type;
2585   PetscFunctionReturn(0);
2586 }
2587 
2588 /*@
2589    TSSetUp - Sets up the internal data structures for the later use
2590    of a timestepper.
2591 
2592    Collective on TS
2593 
2594    Input Parameter:
2595 .  ts - the TS context obtained from TSCreate()
2596 
2597    Notes:
2598    For basic use of the TS solvers the user need not explicitly call
2599    TSSetUp(), since these actions will automatically occur during
2600    the call to TSStep() or TSSolve().  However, if one wishes to control this
2601    phase separately, TSSetUp() should be called after TSCreate()
2602    and optional routines of the form TSSetXXX(), but before TSStep() and TSSolve().
2603 
2604    Level: advanced
2605 
2606 .keywords: TS, timestep, setup
2607 
2608 .seealso: TSCreate(), TSStep(), TSDestroy(), TSSolve()
2609 @*/
2610 PetscErrorCode  TSSetUp(TS ts)
2611 {
2612   PetscErrorCode ierr;
2613   DM             dm;
2614   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
2615   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
2616   TSIFunction    ifun;
2617   TSIJacobian    ijac;
2618   TSI2Jacobian   i2jac;
2619   TSRHSJacobian  rhsjac;
2620   PetscBool      isnone;
2621 
2622   PetscFunctionBegin;
2623   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2624   if (ts->setupcalled) PetscFunctionReturn(0);
2625 
2626   if (!((PetscObject)ts)->type_name) {
2627     ierr = TSGetIFunction(ts,NULL,&ifun,NULL);CHKERRQ(ierr);
2628     ierr = TSSetType(ts,ifun ? TSBEULER : TSEULER);CHKERRQ(ierr);
2629   }
2630 
2631   if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first");
2632 
2633   if (ts->rhsjacobian.reuse) {
2634     Mat Amat,Pmat;
2635     SNES snes;
2636     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2637     ierr = SNESGetJacobian(snes,&Amat,&Pmat,NULL,NULL);CHKERRQ(ierr);
2638     /* Matching matrices implies that an IJacobian is NOT set, because if it had been set, the IJacobian's matrix would
2639      * have displaced the RHS matrix */
2640     if (Amat == ts->Arhs) {
2641       /* 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 */
2642       ierr = MatDuplicate(ts->Arhs,MAT_COPY_VALUES,&Amat);CHKERRQ(ierr);
2643       ierr = SNESSetJacobian(snes,Amat,NULL,NULL,NULL);CHKERRQ(ierr);
2644       ierr = MatDestroy(&Amat);CHKERRQ(ierr);
2645     }
2646     if (Pmat == ts->Brhs) {
2647       ierr = MatDuplicate(ts->Brhs,MAT_COPY_VALUES,&Pmat);CHKERRQ(ierr);
2648       ierr = SNESSetJacobian(snes,NULL,Pmat,NULL,NULL);CHKERRQ(ierr);
2649       ierr = MatDestroy(&Pmat);CHKERRQ(ierr);
2650     }
2651   }
2652 
2653   ierr = TSGetAdapt(ts,&ts->adapt);CHKERRQ(ierr);
2654   ierr = TSAdaptSetDefaultType(ts->adapt,ts->default_adapt_type);CHKERRQ(ierr);
2655 
2656   if (ts->ops->setup) {
2657     ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr);
2658   }
2659 
2660   /* Attempt to check/preset a default value for the exact final time option */
2661   ierr = PetscObjectTypeCompare((PetscObject)ts->adapt,TSADAPTNONE,&isnone);CHKERRQ(ierr);
2662   if (!isnone && ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED)
2663     ts->exact_final_time = TS_EXACTFINALTIME_MATCHSTEP;
2664 
2665   /* In the case where we've set a DMTSFunction or what have you, we need the default SNESFunction
2666      to be set right but can't do it elsewhere due to the overreliance on ctx=ts.
2667    */
2668   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2669   ierr = DMSNESGetFunction(dm,&func,NULL);CHKERRQ(ierr);
2670   if (!func) {
2671     ierr = DMSNESSetFunction(dm,SNESTSFormFunction,ts);CHKERRQ(ierr);
2672   }
2673   /* If the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it.
2674      Otherwise, the SNES will use coloring internally to form the Jacobian.
2675    */
2676   ierr = DMSNESGetJacobian(dm,&jac,NULL);CHKERRQ(ierr);
2677   ierr = DMTSGetIJacobian(dm,&ijac,NULL);CHKERRQ(ierr);
2678   ierr = DMTSGetI2Jacobian(dm,&i2jac,NULL);CHKERRQ(ierr);
2679   ierr = DMTSGetRHSJacobian(dm,&rhsjac,NULL);CHKERRQ(ierr);
2680   if (!jac && (ijac || i2jac || rhsjac)) {
2681     ierr = DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);CHKERRQ(ierr);
2682   }
2683 
2684   /* if time integration scheme has a starting method, call it */
2685   if (ts->ops->startingmethod) {
2686     ierr = (*ts->ops->startingmethod)(ts);CHKERRQ(ierr);
2687   }
2688 
2689   ts->setupcalled = PETSC_TRUE;
2690   PetscFunctionReturn(0);
2691 }
2692 
2693 /*@
2694    TSAdjointSetUp - Sets up the internal data structures for the later use
2695    of an adjoint solver
2696 
2697    Collective on TS
2698 
2699    Input Parameter:
2700 .  ts - the TS context obtained from TSCreate()
2701 
2702    Level: advanced
2703 
2704 .keywords: TS, timestep, setup
2705 
2706 .seealso: TSCreate(), TSAdjointStep(), TSSetCostGradients()
2707 @*/
2708 PetscErrorCode  TSAdjointSetUp(TS ts)
2709 {
2710   PetscErrorCode ierr;
2711 
2712   PetscFunctionBegin;
2713   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2714   if (ts->adjointsetupcalled) PetscFunctionReturn(0);
2715   if (!ts->vecs_sensi) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetCostGradients() first");
2716   if (ts->vecs_sensip && !ts->Jacp) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"Must call TSAdjointSetRHSJacobian() first");
2717 
2718   if (ts->vec_costintegral) { /* if there is integral in the cost function */
2719     ierr = VecDuplicateVecs(ts->vecs_sensi[0],ts->numcost,&ts->vecs_drdy);CHKERRQ(ierr);
2720     if (ts->vecs_sensip){
2721       ierr = VecDuplicateVecs(ts->vecs_sensip[0],ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr);
2722     }
2723   }
2724 
2725   if (ts->ops->adjointsetup) {
2726     ierr = (*ts->ops->adjointsetup)(ts);CHKERRQ(ierr);
2727   }
2728   ts->adjointsetupcalled = PETSC_TRUE;
2729   PetscFunctionReturn(0);
2730 }
2731 
2732 /*@
2733    TSReset - Resets a TS context and removes any allocated Vecs and Mats.
2734 
2735    Collective on TS
2736 
2737    Input Parameter:
2738 .  ts - the TS context obtained from TSCreate()
2739 
2740    Level: beginner
2741 
2742 .keywords: TS, timestep, reset
2743 
2744 .seealso: TSCreate(), TSSetup(), TSDestroy()
2745 @*/
2746 PetscErrorCode  TSReset(TS ts)
2747 {
2748   PetscErrorCode ierr;
2749 
2750   PetscFunctionBegin;
2751   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2752 
2753   if (ts->ops->reset) {
2754     ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr);
2755   }
2756   if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);}
2757   if (ts->adapt) {ierr = TSAdaptReset(ts->adapt);CHKERRQ(ierr);}
2758 
2759   ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr);
2760   ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr);
2761   ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr);
2762   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
2763   ierr = VecDestroy(&ts->vec_dot);CHKERRQ(ierr);
2764   ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
2765   ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
2766   ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr);
2767 
2768   ierr = VecDestroyVecs(ts->numcost,&ts->vecs_drdy);CHKERRQ(ierr);
2769   ierr = VecDestroyVecs(ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr);
2770 
2771   ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr);
2772   ierr = VecDestroy(&ts->vec_costintegral);CHKERRQ(ierr);
2773   ierr = VecDestroy(&ts->vec_costintegrand);CHKERRQ(ierr);
2774 
2775   ierr = PetscFree(ts->vecs_fwdsensipacked);CHKERRQ(ierr);
2776 
2777   ts->setupcalled = PETSC_FALSE;
2778   PetscFunctionReturn(0);
2779 }
2780 
2781 /*@
2782    TSDestroy - Destroys the timestepper context that was created
2783    with TSCreate().
2784 
2785    Collective on TS
2786 
2787    Input Parameter:
2788 .  ts - the TS context obtained from TSCreate()
2789 
2790    Level: beginner
2791 
2792 .keywords: TS, timestepper, destroy
2793 
2794 .seealso: TSCreate(), TSSetUp(), TSSolve()
2795 @*/
2796 PetscErrorCode  TSDestroy(TS *ts)
2797 {
2798   PetscErrorCode ierr;
2799 
2800   PetscFunctionBegin;
2801   if (!*ts) PetscFunctionReturn(0);
2802   PetscValidHeaderSpecific((*ts),TS_CLASSID,1);
2803   if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);}
2804 
2805   ierr = TSReset((*ts));CHKERRQ(ierr);
2806 
2807   /* if memory was published with SAWs then destroy it */
2808   ierr = PetscObjectSAWsViewOff((PetscObject)*ts);CHKERRQ(ierr);
2809   if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);}
2810 
2811   ierr = TSTrajectoryDestroy(&(*ts)->trajectory);CHKERRQ(ierr);
2812 
2813   ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr);
2814   ierr = TSEventDestroy(&(*ts)->event);CHKERRQ(ierr);
2815 
2816   ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr);
2817   ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr);
2818   ierr = TSMonitorCancel((*ts));CHKERRQ(ierr);
2819   ierr = TSAdjointMonitorCancel((*ts));CHKERRQ(ierr);
2820 
2821   ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr);
2822   PetscFunctionReturn(0);
2823 }
2824 
2825 /*@
2826    TSGetSNES - Returns the SNES (nonlinear solver) associated with
2827    a TS (timestepper) context. Valid only for nonlinear problems.
2828 
2829    Not Collective, but SNES is parallel if TS is parallel
2830 
2831    Input Parameter:
2832 .  ts - the TS context obtained from TSCreate()
2833 
2834    Output Parameter:
2835 .  snes - the nonlinear solver context
2836 
2837    Notes:
2838    The user can then directly manipulate the SNES context to set various
2839    options, etc.  Likewise, the user can then extract and manipulate the
2840    KSP, KSP, and PC contexts as well.
2841 
2842    TSGetSNES() does not work for integrators that do not use SNES; in
2843    this case TSGetSNES() returns NULL in snes.
2844 
2845    Level: beginner
2846 
2847 .keywords: timestep, get, SNES
2848 @*/
2849 PetscErrorCode  TSGetSNES(TS ts,SNES *snes)
2850 {
2851   PetscErrorCode ierr;
2852 
2853   PetscFunctionBegin;
2854   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2855   PetscValidPointer(snes,2);
2856   if (!ts->snes) {
2857     ierr = SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);CHKERRQ(ierr);
2858     ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr);
2859     ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->snes);CHKERRQ(ierr);
2860     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr);
2861     if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
2862     if (ts->problem_type == TS_LINEAR) {
2863       ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr);
2864     }
2865   }
2866   *snes = ts->snes;
2867   PetscFunctionReturn(0);
2868 }
2869 
2870 /*@
2871    TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context
2872 
2873    Collective
2874 
2875    Input Parameter:
2876 +  ts - the TS context obtained from TSCreate()
2877 -  snes - the nonlinear solver context
2878 
2879    Notes:
2880    Most users should have the TS created by calling TSGetSNES()
2881 
2882    Level: developer
2883 
2884 .keywords: timestep, set, SNES
2885 @*/
2886 PetscErrorCode TSSetSNES(TS ts,SNES snes)
2887 {
2888   PetscErrorCode ierr;
2889   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
2890 
2891   PetscFunctionBegin;
2892   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2893   PetscValidHeaderSpecific(snes,SNES_CLASSID,2);
2894   ierr = PetscObjectReference((PetscObject)snes);CHKERRQ(ierr);
2895   ierr = SNESDestroy(&ts->snes);CHKERRQ(ierr);
2896 
2897   ts->snes = snes;
2898 
2899   ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr);
2900   ierr = SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);CHKERRQ(ierr);
2901   if (func == SNESTSFormJacobian) {
2902     ierr = SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);CHKERRQ(ierr);
2903   }
2904   PetscFunctionReturn(0);
2905 }
2906 
2907 /*@
2908    TSGetKSP - Returns the KSP (linear solver) associated with
2909    a TS (timestepper) context.
2910 
2911    Not Collective, but KSP is parallel if TS is parallel
2912 
2913    Input Parameter:
2914 .  ts - the TS context obtained from TSCreate()
2915 
2916    Output Parameter:
2917 .  ksp - the nonlinear solver context
2918 
2919    Notes:
2920    The user can then directly manipulate the KSP context to set various
2921    options, etc.  Likewise, the user can then extract and manipulate the
2922    KSP and PC contexts as well.
2923 
2924    TSGetKSP() does not work for integrators that do not use KSP;
2925    in this case TSGetKSP() returns NULL in ksp.
2926 
2927    Level: beginner
2928 
2929 .keywords: timestep, get, KSP
2930 @*/
2931 PetscErrorCode  TSGetKSP(TS ts,KSP *ksp)
2932 {
2933   PetscErrorCode ierr;
2934   SNES           snes;
2935 
2936   PetscFunctionBegin;
2937   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2938   PetscValidPointer(ksp,2);
2939   if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first");
2940   if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()");
2941   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2942   ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr);
2943   PetscFunctionReturn(0);
2944 }
2945 
2946 /* ----------- Routines to set solver parameters ---------- */
2947 
2948 /*@
2949    TSSetMaxSteps - Sets the maximum number of steps to use.
2950 
2951    Logically Collective on TS
2952 
2953    Input Parameters:
2954 +  ts - the TS context obtained from TSCreate()
2955 -  maxsteps - maximum number of steps to use
2956 
2957    Options Database Keys:
2958 .  -ts_max_steps <maxsteps> - Sets maxsteps
2959 
2960    Notes:
2961    The default maximum number of steps is 5000
2962 
2963    Level: intermediate
2964 
2965 .keywords: TS, timestep, set, maximum, steps
2966 
2967 .seealso: TSGetMaxSteps(), TSSetMaxTime(), TSSetExactFinalTime()
2968 @*/
2969 PetscErrorCode TSSetMaxSteps(TS ts,PetscInt maxsteps)
2970 {
2971   PetscFunctionBegin;
2972   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2973   PetscValidLogicalCollectiveInt(ts,maxsteps,2);
2974   if (maxsteps < 0 ) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of steps must be non-negative");
2975   ts->max_steps = maxsteps;
2976   PetscFunctionReturn(0);
2977 }
2978 
2979 /*@
2980    TSGetMaxSteps - Gets the maximum number of steps to use.
2981 
2982    Not Collective
2983 
2984    Input Parameters:
2985 .  ts - the TS context obtained from TSCreate()
2986 
2987    Output Parameter:
2988 .  maxsteps - maximum number of steps to use
2989 
2990    Level: advanced
2991 
2992 .keywords: TS, timestep, get, maximum, steps
2993 
2994 .seealso: TSSetMaxSteps(), TSGetMaxTime(), TSSetMaxTime()
2995 @*/
2996 PetscErrorCode TSGetMaxSteps(TS ts,PetscInt *maxsteps)
2997 {
2998   PetscFunctionBegin;
2999   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3000   PetscValidIntPointer(maxsteps,2);
3001   *maxsteps = ts->max_steps;
3002   PetscFunctionReturn(0);
3003 }
3004 
3005 /*@
3006    TSSetMaxTime - Sets the maximum (or final) time for timestepping.
3007 
3008    Logically Collective on TS
3009 
3010    Input Parameters:
3011 +  ts - the TS context obtained from TSCreate()
3012 -  maxtime - final time to step to
3013 
3014    Options Database Keys:
3015 .  -ts_max_time <maxtime> - Sets maxtime
3016 
3017    Notes:
3018    The default maximum time is 5.0
3019 
3020    Level: intermediate
3021 
3022 .keywords: TS, timestep, set, maximum, time
3023 
3024 .seealso: TSGetMaxTime(), TSSetMaxSteps(), TSSetExactFinalTime()
3025 @*/
3026 PetscErrorCode TSSetMaxTime(TS ts,PetscReal maxtime)
3027 {
3028   PetscFunctionBegin;
3029   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3030   PetscValidLogicalCollectiveReal(ts,maxtime,2);
3031   ts->max_time = maxtime;
3032   PetscFunctionReturn(0);
3033 }
3034 
3035 /*@
3036    TSGetMaxTime - Gets the maximum (or final) time for timestepping.
3037 
3038    Not Collective
3039 
3040    Input Parameters:
3041 .  ts - the TS context obtained from TSCreate()
3042 
3043    Output Parameter:
3044 .  maxtime - final time to step to
3045 
3046    Level: advanced
3047 
3048 .keywords: TS, timestep, get, maximum, time
3049 
3050 .seealso: TSSetMaxTime(), TSGetMaxSteps(), TSSetMaxSteps()
3051 @*/
3052 PetscErrorCode TSGetMaxTime(TS ts,PetscReal *maxtime)
3053 {
3054   PetscFunctionBegin;
3055   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3056   PetscValidRealPointer(maxtime,2);
3057   *maxtime = ts->max_time;
3058   PetscFunctionReturn(0);
3059 }
3060 
3061 /*@
3062    TSSetInitialTimeStep - Deprecated, use TSSetTime() and TSSetTimeStep().
3063 
3064    Level: deprecated
3065 
3066 @*/
3067 PetscErrorCode  TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step)
3068 {
3069   PetscErrorCode ierr;
3070   PetscFunctionBegin;
3071   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3072   ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr);
3073   ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr);
3074   PetscFunctionReturn(0);
3075 }
3076 
3077 /*@
3078    TSGetDuration - Deprecated, use TSGetMaxSteps() and TSGetMaxTime().
3079 
3080    Level: deprecated
3081 
3082 @*/
3083 PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
3084 {
3085   PetscFunctionBegin;
3086   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3087   if (maxsteps) {
3088     PetscValidIntPointer(maxsteps,2);
3089     *maxsteps = ts->max_steps;
3090   }
3091   if (maxtime) {
3092     PetscValidScalarPointer(maxtime,3);
3093     *maxtime = ts->max_time;
3094   }
3095   PetscFunctionReturn(0);
3096 }
3097 
3098 /*@
3099    TSSetDuration - Deprecated, use TSSetMaxSteps() and TSSetMaxTime().
3100 
3101    Level: deprecated
3102 
3103 @*/
3104 PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime)
3105 {
3106   PetscFunctionBegin;
3107   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3108   PetscValidLogicalCollectiveInt(ts,maxsteps,2);
3109   PetscValidLogicalCollectiveReal(ts,maxtime,2);
3110   if (maxsteps >= 0) ts->max_steps = maxsteps;
3111   if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime;
3112   PetscFunctionReturn(0);
3113 }
3114 
3115 /*@
3116    TSGetTimeStepNumber - Deprecated, use TSGetStepNumber().
3117 
3118    Level: deprecated
3119 
3120 @*/
3121 PetscErrorCode TSGetTimeStepNumber(TS ts,PetscInt *steps) { return TSGetStepNumber(ts,steps); }
3122 
3123 /*@
3124    TSGetTotalSteps - Deprecated, use TSGetStepNumber().
3125 
3126    Level: deprecated
3127 
3128 @*/
3129 PetscErrorCode TSGetTotalSteps(TS ts,PetscInt *steps) { return TSGetStepNumber(ts,steps); }
3130 
3131 /*@
3132    TSSetSolution - Sets the initial solution vector
3133    for use by the TS routines.
3134 
3135    Logically Collective on TS and Vec
3136 
3137    Input Parameters:
3138 +  ts - the TS context obtained from TSCreate()
3139 -  u - the solution vector
3140 
3141    Level: beginner
3142 
3143 .keywords: TS, timestep, set, solution, initial values
3144 
3145 .seealso: TSSetSolutionFunction(), TSGetSolution(), TSCreate()
3146 @*/
3147 PetscErrorCode  TSSetSolution(TS ts,Vec u)
3148 {
3149   PetscErrorCode ierr;
3150   DM             dm;
3151 
3152   PetscFunctionBegin;
3153   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3154   PetscValidHeaderSpecific(u,VEC_CLASSID,2);
3155   ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr);
3156   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
3157   ts->vec_sol = u;
3158 
3159   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
3160   ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr);
3161   PetscFunctionReturn(0);
3162 }
3163 
3164 /*@
3165    TSAdjointSetSteps - Sets the number of steps the adjoint solver should take backward in time
3166 
3167    Logically Collective on TS
3168 
3169    Input Parameters:
3170 +  ts - the TS context obtained from TSCreate()
3171 .  steps - number of steps to use
3172 
3173    Level: intermediate
3174 
3175    Notes: Normally one does not call this and TSAdjointSolve() integrates back to the original timestep. One can call this
3176           so as to integrate back to less than the original timestep
3177 
3178 .keywords: TS, timestep, set, maximum, iterations
3179 
3180 .seealso: TSSetExactFinalTime()
3181 @*/
3182 PetscErrorCode  TSAdjointSetSteps(TS ts,PetscInt steps)
3183 {
3184   PetscFunctionBegin;
3185   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3186   PetscValidLogicalCollectiveInt(ts,steps,2);
3187   if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back a negative number of steps");
3188   if (steps > ts->steps) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back more than the total number of forward steps");
3189   ts->adjoint_max_steps = steps;
3190   PetscFunctionReturn(0);
3191 }
3192 
3193 /*@
3194    TSSetCostGradients - Sets the initial value of the gradients of the cost function w.r.t. initial values and w.r.t. the problem parameters
3195       for use by the TSAdjoint routines.
3196 
3197    Logically Collective on TS and Vec
3198 
3199    Input Parameters:
3200 +  ts - the TS context obtained from TSCreate()
3201 .  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
3202 -  mu - gradients with respect to the parameters, the number of entries in these vectors is the same as the number of parameters
3203 
3204    Level: beginner
3205 
3206    Notes: the entries in these vectors must be correctly initialized with the values lamda_i = df/dy|finaltime  mu_i = df/dp|finaltime
3207 
3208    After TSAdjointSolve() is called the lamba and the mu contain the computed sensitivities
3209 
3210 .keywords: TS, timestep, set, sensitivity, initial values
3211 @*/
3212 PetscErrorCode  TSSetCostGradients(TS ts,PetscInt numcost,Vec *lambda,Vec *mu)
3213 {
3214   PetscFunctionBegin;
3215   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3216   PetscValidPointer(lambda,2);
3217   ts->vecs_sensi  = lambda;
3218   ts->vecs_sensip = mu;
3219   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");
3220   ts->numcost  = numcost;
3221   PetscFunctionReturn(0);
3222 }
3223 
3224 /*@C
3225   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.
3226 
3227   Logically Collective on TS
3228 
3229   Input Parameters:
3230 + ts   - The TS context obtained from TSCreate()
3231 - func - The function
3232 
3233   Calling sequence of func:
3234 $ func (TS ts,PetscReal t,Vec y,Mat A,void *ctx);
3235 +   t - current timestep
3236 .   y - input vector (current ODE solution)
3237 .   A - output matrix
3238 -   ctx - [optional] user-defined function context
3239 
3240   Level: intermediate
3241 
3242   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
3243 
3244 .keywords: TS, sensitivity
3245 .seealso:
3246 @*/
3247 PetscErrorCode  TSAdjointSetRHSJacobian(TS ts,Mat Amat,PetscErrorCode (*func)(TS,PetscReal,Vec,Mat,void*),void *ctx)
3248 {
3249   PetscErrorCode ierr;
3250 
3251   PetscFunctionBegin;
3252   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3253   PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
3254 
3255   ts->rhsjacobianp    = func;
3256   ts->rhsjacobianpctx = ctx;
3257   if(Amat) {
3258     ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr);
3259     ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr);
3260     ts->Jacp = Amat;
3261   }
3262   PetscFunctionReturn(0);
3263 }
3264 
3265 /*@C
3266   TSAdjointComputeRHSJacobian - Runs the user-defined Jacobian function.
3267 
3268   Collective on TS
3269 
3270   Input Parameters:
3271 . ts   - The TS context obtained from TSCreate()
3272 
3273   Level: developer
3274 
3275 .keywords: TS, sensitivity
3276 .seealso: TSAdjointSetRHSJacobian()
3277 @*/
3278 PetscErrorCode  TSAdjointComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat Amat)
3279 {
3280   PetscErrorCode ierr;
3281 
3282   PetscFunctionBegin;
3283   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3284   PetscValidHeaderSpecific(X,VEC_CLASSID,3);
3285   PetscValidPointer(Amat,4);
3286 
3287   PetscStackPush("TS user JacobianP function for sensitivity analysis");
3288   ierr = (*ts->rhsjacobianp)(ts,t,X,Amat,ts->rhsjacobianpctx); CHKERRQ(ierr);
3289   PetscStackPop;
3290   PetscFunctionReturn(0);
3291 }
3292 
3293 /*@C
3294     TSSetCostIntegrand - Sets the routine for evaluating the integral term in one or more cost functions
3295 
3296     Logically Collective on TS
3297 
3298     Input Parameters:
3299 +   ts - the TS context obtained from TSCreate()
3300 .   numcost - number of gradients to be computed, this is the number of cost functions
3301 .   costintegral - vector that stores the integral values
3302 .   rf - routine for evaluating the integrand function
3303 .   drdyf - function that computes the gradients of the r's with respect to y,NULL if not a function y
3304 .   drdpf - function that computes the gradients of the r's with respect to p, NULL if not a function of p
3305 .   fwd - flag indicating whether to evaluate cost integral in the forward run or the adjoint run
3306 -   ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
3307 
3308     Calling sequence of rf:
3309 $   PetscErrorCode rf(TS ts,PetscReal t,Vec y,Vec f,void *ctx);
3310 
3311     Calling sequence of drdyf:
3312 $   PetscErroCode drdyf(TS ts,PetscReal t,Vec y,Vec *drdy,void *ctx);
3313 
3314     Calling sequence of drdpf:
3315 $   PetscErroCode drdpf(TS ts,PetscReal t,Vec y,Vec *drdp,void *ctx);
3316 
3317     Level: intermediate
3318 
3319     Notes: For optimization there is usually a single cost function (numcost = 1). For sensitivities there may be multiple cost functions
3320 
3321 .keywords: TS, sensitivity analysis, timestep, set, quadrature, function
3322 
3323 .seealso: TSAdjointSetRHSJacobian(),TSGetCostGradients(), TSSetCostGradients()
3324 @*/
3325 PetscErrorCode  TSSetCostIntegrand(TS ts,PetscInt numcost,Vec costintegral,PetscErrorCode (*rf)(TS,PetscReal,Vec,Vec,void*),
3326                                                           PetscErrorCode (*drdyf)(TS,PetscReal,Vec,Vec*,void*),
3327                                                           PetscErrorCode (*drdpf)(TS,PetscReal,Vec,Vec*,void*),
3328                                                           PetscBool fwd,void *ctx)
3329 {
3330   PetscErrorCode ierr;
3331 
3332   PetscFunctionBegin;
3333   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3334   if (costintegral) PetscValidHeaderSpecific(costintegral,VEC_CLASSID,3);
3335   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()");
3336   if (!ts->numcost) ts->numcost=numcost;
3337 
3338   if (costintegral) {
3339     ierr = PetscObjectReference((PetscObject)costintegral);CHKERRQ(ierr);
3340     ierr = VecDestroy(&ts->vec_costintegral);CHKERRQ(ierr);
3341     ts->vec_costintegral = costintegral;
3342   } else {
3343     if (!ts->vec_costintegral) { /* Create a seq vec if user does not provide one */
3344       ierr = VecCreateSeq(PETSC_COMM_SELF,numcost,&ts->vec_costintegral);CHKERRQ(ierr);
3345     } else {
3346       ierr = VecSet(ts->vec_costintegral,0.0);CHKERRQ(ierr);
3347     }
3348   }
3349   if (!ts->vec_costintegrand) {
3350     ierr = VecDuplicate(ts->vec_costintegral,&ts->vec_costintegrand);CHKERRQ(ierr);
3351   } else {
3352     ierr = VecSet(ts->vec_costintegrand,0.0);CHKERRQ(ierr);
3353   }
3354   ts->costintegralfwd  = fwd; /* Evaluate the cost integral in forward run if fwd is true */
3355   ts->costintegrand    = rf;
3356   ts->costintegrandctx = ctx;
3357   ts->drdyfunction     = drdyf;
3358   ts->drdpfunction     = drdpf;
3359   PetscFunctionReturn(0);
3360 }
3361 
3362 /*@
3363    TSGetCostIntegral - Returns the values of the integral term in the cost functions.
3364    It is valid to call the routine after a backward run.
3365 
3366    Not Collective
3367 
3368    Input Parameter:
3369 .  ts - the TS context obtained from TSCreate()
3370 
3371    Output Parameter:
3372 .  v - the vector containing the integrals for each cost function
3373 
3374    Level: intermediate
3375 
3376 .seealso: TSSetCostIntegrand()
3377 
3378 .keywords: TS, sensitivity analysis
3379 @*/
3380 PetscErrorCode  TSGetCostIntegral(TS ts,Vec *v)
3381 {
3382   PetscFunctionBegin;
3383   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3384   PetscValidPointer(v,2);
3385   *v = ts->vec_costintegral;
3386   PetscFunctionReturn(0);
3387 }
3388 
3389 /*@
3390    TSComputeCostIntegrand - Evaluates the integral function in the cost functions.
3391 
3392    Input Parameters:
3393 +  ts - the TS context
3394 .  t - current time
3395 -  y - state vector, i.e. current solution
3396 
3397    Output Parameter:
3398 .  q - vector of size numcost to hold the outputs
3399 
3400    Note:
3401    Most users should not need to explicitly call this routine, as it
3402    is used internally within the sensitivity analysis context.
3403 
3404    Level: developer
3405 
3406 .keywords: TS, compute
3407 
3408 .seealso: TSSetCostIntegrand()
3409 @*/
3410 PetscErrorCode TSComputeCostIntegrand(TS ts,PetscReal t,Vec y,Vec q)
3411 {
3412   PetscErrorCode ierr;
3413 
3414   PetscFunctionBegin;
3415   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3416   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
3417   PetscValidHeaderSpecific(q,VEC_CLASSID,4);
3418 
3419   ierr = PetscLogEventBegin(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr);
3420   if (ts->costintegrand) {
3421     PetscStackPush("TS user integrand in the cost function");
3422     ierr = (*ts->costintegrand)(ts,t,y,q,ts->costintegrandctx);CHKERRQ(ierr);
3423     PetscStackPop;
3424   } else {
3425     ierr = VecZeroEntries(q);CHKERRQ(ierr);
3426   }
3427 
3428   ierr = PetscLogEventEnd(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr);
3429   PetscFunctionReturn(0);
3430 }
3431 
3432 /*@
3433   TSAdjointComputeDRDYFunction - Runs the user-defined DRDY function.
3434 
3435   Collective on TS
3436 
3437   Input Parameters:
3438 . ts   - The TS context obtained from TSCreate()
3439 
3440   Notes:
3441   TSAdjointComputeDRDYFunction() is typically used for sensitivity implementation,
3442   so most users would not generally call this routine themselves.
3443 
3444   Level: developer
3445 
3446 .keywords: TS, sensitivity
3447 .seealso: TSAdjointComputeDRDYFunction()
3448 @*/
3449 PetscErrorCode  TSAdjointComputeDRDYFunction(TS ts,PetscReal t,Vec y,Vec *drdy)
3450 {
3451   PetscErrorCode ierr;
3452 
3453   PetscFunctionBegin;
3454   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3455   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
3456 
3457   PetscStackPush("TS user DRDY function for sensitivity analysis");
3458   ierr = (*ts->drdyfunction)(ts,t,y,drdy,ts->costintegrandctx); CHKERRQ(ierr);
3459   PetscStackPop;
3460   PetscFunctionReturn(0);
3461 }
3462 
3463 /*@
3464   TSAdjointComputeDRDPFunction - Runs the user-defined DRDP function.
3465 
3466   Collective on TS
3467 
3468   Input Parameters:
3469 . ts   - The TS context obtained from TSCreate()
3470 
3471   Notes:
3472   TSDRDPFunction() is typically used for sensitivity implementation,
3473   so most users would not generally call this routine themselves.
3474 
3475   Level: developer
3476 
3477 .keywords: TS, sensitivity
3478 .seealso: TSAdjointSetDRDPFunction()
3479 @*/
3480 PetscErrorCode  TSAdjointComputeDRDPFunction(TS ts,PetscReal t,Vec y,Vec *drdp)
3481 {
3482   PetscErrorCode ierr;
3483 
3484   PetscFunctionBegin;
3485   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3486   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
3487 
3488   PetscStackPush("TS user DRDP function for sensitivity analysis");
3489   ierr = (*ts->drdpfunction)(ts,t,y,drdp,ts->costintegrandctx); CHKERRQ(ierr);
3490   PetscStackPop;
3491   PetscFunctionReturn(0);
3492 }
3493 
3494 /*@C
3495   TSSetPreStep - Sets the general-purpose function
3496   called once at the beginning of each time step.
3497 
3498   Logically Collective on TS
3499 
3500   Input Parameters:
3501 + ts   - The TS context obtained from TSCreate()
3502 - func - The function
3503 
3504   Calling sequence of func:
3505 . func (TS ts);
3506 
3507   Level: intermediate
3508 
3509 .keywords: TS, timestep
3510 .seealso: TSSetPreStage(), TSSetPostStage(), TSSetPostStep(), TSStep(), TSRestartStep()
3511 @*/
3512 PetscErrorCode  TSSetPreStep(TS ts, PetscErrorCode (*func)(TS))
3513 {
3514   PetscFunctionBegin;
3515   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3516   ts->prestep = func;
3517   PetscFunctionReturn(0);
3518 }
3519 
3520 /*@
3521   TSPreStep - Runs the user-defined pre-step function.
3522 
3523   Collective on TS
3524 
3525   Input Parameters:
3526 . ts   - The TS context obtained from TSCreate()
3527 
3528   Notes:
3529   TSPreStep() is typically used within time stepping implementations,
3530   so most users would not generally call this routine themselves.
3531 
3532   Level: developer
3533 
3534 .keywords: TS, timestep
3535 .seealso: TSSetPreStep(), TSPreStage(), TSPostStage(), TSPostStep()
3536 @*/
3537 PetscErrorCode  TSPreStep(TS ts)
3538 {
3539   PetscErrorCode ierr;
3540 
3541   PetscFunctionBegin;
3542   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3543   if (ts->prestep) {
3544     Vec              U;
3545     PetscObjectState sprev,spost;
3546 
3547     ierr = TSGetSolution(ts,&U);CHKERRQ(ierr);
3548     ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr);
3549     PetscStackCallStandard((*ts->prestep),(ts));
3550     ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr);
3551     if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);}
3552   }
3553   PetscFunctionReturn(0);
3554 }
3555 
3556 /*@C
3557   TSSetPreStage - Sets the general-purpose function
3558   called once at the beginning of each stage.
3559 
3560   Logically Collective on TS
3561 
3562   Input Parameters:
3563 + ts   - The TS context obtained from TSCreate()
3564 - func - The function
3565 
3566   Calling sequence of func:
3567 . PetscErrorCode func(TS ts, PetscReal stagetime);
3568 
3569   Level: intermediate
3570 
3571   Note:
3572   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
3573   The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being
3574   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
3575 
3576 .keywords: TS, timestep
3577 .seealso: TSSetPostStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
3578 @*/
3579 PetscErrorCode  TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal))
3580 {
3581   PetscFunctionBegin;
3582   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3583   ts->prestage = func;
3584   PetscFunctionReturn(0);
3585 }
3586 
3587 /*@C
3588   TSSetPostStage - Sets the general-purpose function
3589   called once at the end of each stage.
3590 
3591   Logically Collective on TS
3592 
3593   Input Parameters:
3594 + ts   - The TS context obtained from TSCreate()
3595 - func - The function
3596 
3597   Calling sequence of func:
3598 . PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y);
3599 
3600   Level: intermediate
3601 
3602   Note:
3603   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
3604   The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being
3605   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
3606 
3607 .keywords: TS, timestep
3608 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
3609 @*/
3610 PetscErrorCode  TSSetPostStage(TS ts, PetscErrorCode (*func)(TS,PetscReal,PetscInt,Vec*))
3611 {
3612   PetscFunctionBegin;
3613   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3614   ts->poststage = func;
3615   PetscFunctionReturn(0);
3616 }
3617 
3618 /*@C
3619   TSSetPostEvaluate - Sets the general-purpose function
3620   called once at the end of each step evaluation.
3621 
3622   Logically Collective on TS
3623 
3624   Input Parameters:
3625 + ts   - The TS context obtained from TSCreate()
3626 - func - The function
3627 
3628   Calling sequence of func:
3629 . PetscErrorCode func(TS ts);
3630 
3631   Level: intermediate
3632 
3633   Note:
3634   Semantically, TSSetPostEvaluate() differs from TSSetPostStep() since the function it sets is called before event-handling
3635   thus guaranteeing the same solution (computed by the time-stepper) will be passed to it. On the other hand, TSPostStep()
3636   may be passed a different solution, possibly changed by the event handler. TSPostEvaluate() is called after the next step
3637   solution is evaluated allowing to modify it, if need be. The solution can be obtained with TSGetSolution(), the time step
3638   with TSGetTimeStep(), and the time at the start of the step is available via TSGetTime()
3639 
3640 .keywords: TS, timestep
3641 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
3642 @*/
3643 PetscErrorCode  TSSetPostEvaluate(TS ts, PetscErrorCode (*func)(TS))
3644 {
3645   PetscFunctionBegin;
3646   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3647   ts->postevaluate = func;
3648   PetscFunctionReturn(0);
3649 }
3650 
3651 /*@
3652   TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage()
3653 
3654   Collective on TS
3655 
3656   Input Parameters:
3657 . ts          - The TS context obtained from TSCreate()
3658   stagetime   - The absolute time of the current stage
3659 
3660   Notes:
3661   TSPreStage() is typically used within time stepping implementations,
3662   most users would not generally call this routine themselves.
3663 
3664   Level: developer
3665 
3666 .keywords: TS, timestep
3667 .seealso: TSPostStage(), TSSetPreStep(), TSPreStep(), TSPostStep()
3668 @*/
3669 PetscErrorCode  TSPreStage(TS ts, PetscReal stagetime)
3670 {
3671   PetscErrorCode ierr;
3672 
3673   PetscFunctionBegin;
3674   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3675   if (ts->prestage) {
3676     PetscStackCallStandard((*ts->prestage),(ts,stagetime));
3677   }
3678   PetscFunctionReturn(0);
3679 }
3680 
3681 /*@
3682   TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage()
3683 
3684   Collective on TS
3685 
3686   Input Parameters:
3687 . ts          - The TS context obtained from TSCreate()
3688   stagetime   - The absolute time of the current stage
3689   stageindex  - Stage number
3690   Y           - Array of vectors (of size = total number
3691                 of stages) with the stage solutions
3692 
3693   Notes:
3694   TSPostStage() is typically used within time stepping implementations,
3695   most users would not generally call this routine themselves.
3696 
3697   Level: developer
3698 
3699 .keywords: TS, timestep
3700 .seealso: TSPreStage(), TSSetPreStep(), TSPreStep(), TSPostStep()
3701 @*/
3702 PetscErrorCode  TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y)
3703 {
3704   PetscErrorCode ierr;
3705 
3706   PetscFunctionBegin;
3707   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3708   if (ts->poststage) {
3709     PetscStackCallStandard((*ts->poststage),(ts,stagetime,stageindex,Y));
3710   }
3711   PetscFunctionReturn(0);
3712 }
3713 
3714 /*@
3715   TSPostEvaluate - Runs the user-defined post-evaluate function set using TSSetPostEvaluate()
3716 
3717   Collective on TS
3718 
3719   Input Parameters:
3720 . ts          - The TS context obtained from TSCreate()
3721 
3722   Notes:
3723   TSPostEvaluate() is typically used within time stepping implementations,
3724   most users would not generally call this routine themselves.
3725 
3726   Level: developer
3727 
3728 .keywords: TS, timestep
3729 .seealso: TSSetPostEvaluate(), TSSetPreStep(), TSPreStep(), TSPostStep()
3730 @*/
3731 PetscErrorCode  TSPostEvaluate(TS ts)
3732 {
3733   PetscErrorCode ierr;
3734 
3735   PetscFunctionBegin;
3736   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3737   if (ts->postevaluate) {
3738     Vec              U;
3739     PetscObjectState sprev,spost;
3740 
3741     ierr = TSGetSolution(ts,&U);CHKERRQ(ierr);
3742     ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr);
3743     PetscStackCallStandard((*ts->postevaluate),(ts));
3744     ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr);
3745     if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);}
3746   }
3747   PetscFunctionReturn(0);
3748 }
3749 
3750 /*@C
3751   TSSetPostStep - Sets the general-purpose function
3752   called once at the end of each time step.
3753 
3754   Logically Collective on TS
3755 
3756   Input Parameters:
3757 + ts   - The TS context obtained from TSCreate()
3758 - func - The function
3759 
3760   Calling sequence of func:
3761 $ func (TS ts);
3762 
3763   Notes:
3764   The function set by TSSetPostStep() is called after each successful step. The solution vector X
3765   obtained by TSGetSolution() may be different than that computed at the step end if the event handler
3766   locates an event and TSPostEvent() modifies it. Use TSSetPostEvaluate() if an unmodified solution is needed instead.
3767 
3768   Level: intermediate
3769 
3770 .keywords: TS, timestep
3771 .seealso: TSSetPreStep(), TSSetPreStage(), TSSetPostEvaluate(), TSGetTimeStep(), TSGetStepNumber(), TSGetTime(), TSRestartStep()
3772 @*/
3773 PetscErrorCode  TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
3774 {
3775   PetscFunctionBegin;
3776   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3777   ts->poststep = func;
3778   PetscFunctionReturn(0);
3779 }
3780 
3781 /*@
3782   TSPostStep - Runs the user-defined post-step function.
3783 
3784   Collective on TS
3785 
3786   Input Parameters:
3787 . ts   - The TS context obtained from TSCreate()
3788 
3789   Notes:
3790   TSPostStep() is typically used within time stepping implementations,
3791   so most users would not generally call this routine themselves.
3792 
3793   Level: developer
3794 
3795 .keywords: TS, timestep
3796 @*/
3797 PetscErrorCode  TSPostStep(TS ts)
3798 {
3799   PetscErrorCode ierr;
3800 
3801   PetscFunctionBegin;
3802   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3803   if (ts->poststep) {
3804     Vec              U;
3805     PetscObjectState sprev,spost;
3806 
3807     ierr = TSGetSolution(ts,&U);CHKERRQ(ierr);
3808     ierr = PetscObjectStateGet((PetscObject)U,&sprev);CHKERRQ(ierr);
3809     PetscStackCallStandard((*ts->poststep),(ts));
3810     ierr = PetscObjectStateGet((PetscObject)U,&spost);CHKERRQ(ierr);
3811     if (sprev != spost) {ierr = TSRestartStep(ts);CHKERRQ(ierr);}
3812   }
3813   PetscFunctionReturn(0);
3814 }
3815 
3816 /* ------------ Routines to set performance monitoring options ----------- */
3817 
3818 /*@C
3819    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
3820    timestep to display the iteration's  progress.
3821 
3822    Logically Collective on TS
3823 
3824    Input Parameters:
3825 +  ts - the TS context obtained from TSCreate()
3826 .  monitor - monitoring routine
3827 .  mctx - [optional] user-defined context for private data for the
3828              monitor routine (use NULL if no context is desired)
3829 -  monitordestroy - [optional] routine that frees monitor context
3830           (may be NULL)
3831 
3832    Calling sequence of monitor:
3833 $    PetscErrorCode monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
3834 
3835 +    ts - the TS context
3836 .    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)
3837 .    time - current time
3838 .    u - current iterate
3839 -    mctx - [optional] monitoring context
3840 
3841    Notes:
3842    This routine adds an additional monitor to the list of monitors that
3843    already has been loaded.
3844 
3845    Fortran notes: Only a single monitor function can be set for each TS object
3846 
3847    Level: intermediate
3848 
3849 .keywords: TS, timestep, set, monitor
3850 
3851 .seealso: TSMonitorDefault(), TSMonitorCancel()
3852 @*/
3853 PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**))
3854 {
3855   PetscErrorCode ierr;
3856   PetscInt       i;
3857   PetscBool      identical;
3858 
3859   PetscFunctionBegin;
3860   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3861   for (i=0; i<ts->numbermonitors;i++) {
3862     ierr = PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical);CHKERRQ(ierr);
3863     if (identical) PetscFunctionReturn(0);
3864   }
3865   if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
3866   ts->monitor[ts->numbermonitors]          = monitor;
3867   ts->monitordestroy[ts->numbermonitors]   = mdestroy;
3868   ts->monitorcontext[ts->numbermonitors++] = (void*)mctx;
3869   PetscFunctionReturn(0);
3870 }
3871 
3872 /*@C
3873    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
3874 
3875    Logically Collective on TS
3876 
3877    Input Parameters:
3878 .  ts - the TS context obtained from TSCreate()
3879 
3880    Notes:
3881    There is no way to remove a single, specific monitor.
3882 
3883    Level: intermediate
3884 
3885 .keywords: TS, timestep, set, monitor
3886 
3887 .seealso: TSMonitorDefault(), TSMonitorSet()
3888 @*/
3889 PetscErrorCode  TSMonitorCancel(TS ts)
3890 {
3891   PetscErrorCode ierr;
3892   PetscInt       i;
3893 
3894   PetscFunctionBegin;
3895   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3896   for (i=0; i<ts->numbermonitors; i++) {
3897     if (ts->monitordestroy[i]) {
3898       ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr);
3899     }
3900   }
3901   ts->numbermonitors = 0;
3902   PetscFunctionReturn(0);
3903 }
3904 
3905 /*@C
3906    TSMonitorDefault - The Default monitor, prints the timestep and time for each step
3907 
3908    Level: intermediate
3909 
3910 .keywords: TS, set, monitor
3911 
3912 .seealso:  TSMonitorSet()
3913 @*/
3914 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf)
3915 {
3916   PetscErrorCode ierr;
3917   PetscViewer    viewer =  vf->viewer;
3918   PetscBool      iascii,ibinary;
3919 
3920   PetscFunctionBegin;
3921   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
3922   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
3923   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
3924   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
3925   if (iascii) {
3926     ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
3927     if (step == -1){ /* this indicates it is an interpolated solution */
3928       ierr = PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %D and %D\n",(double)ptime,ts->steps-1,ts->steps);CHKERRQ(ierr);
3929     } else {
3930       ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr);
3931     }
3932     ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
3933   } else if (ibinary) {
3934     PetscMPIInt rank;
3935     ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
3936     if (!rank) {
3937       PetscBool skipHeader;
3938       PetscInt  classid = REAL_FILE_CLASSID;
3939 
3940       ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
3941       if (!skipHeader) {
3942          ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
3943        }
3944       ierr = PetscRealView(1,&ptime,viewer);CHKERRQ(ierr);
3945     } else {
3946       ierr = PetscRealView(0,&ptime,viewer);CHKERRQ(ierr);
3947     }
3948   }
3949   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
3950   PetscFunctionReturn(0);
3951 }
3952 
3953 /*@C
3954    TSAdjointMonitorSet - Sets an ADDITIONAL function that is to be used at every
3955    timestep to display the iteration's  progress.
3956 
3957    Logically Collective on TS
3958 
3959    Input Parameters:
3960 +  ts - the TS context obtained from TSCreate()
3961 .  adjointmonitor - monitoring routine
3962 .  adjointmctx - [optional] user-defined context for private data for the
3963              monitor routine (use NULL if no context is desired)
3964 -  adjointmonitordestroy - [optional] routine that frees monitor context
3965           (may be NULL)
3966 
3967    Calling sequence of monitor:
3968 $    int adjointmonitor(TS ts,PetscInt steps,PetscReal time,Vec u,PetscInt numcost,Vec *lambda, Vec *mu,void *adjointmctx)
3969 
3970 +    ts - the TS context
3971 .    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
3972                                been interpolated to)
3973 .    time - current time
3974 .    u - current iterate
3975 .    numcost - number of cost functionos
3976 .    lambda - sensitivities to initial conditions
3977 .    mu - sensitivities to parameters
3978 -    adjointmctx - [optional] adjoint monitoring context
3979 
3980    Notes:
3981    This routine adds an additional monitor to the list of monitors that
3982    already has been loaded.
3983 
3984    Fortran notes: Only a single monitor function can be set for each TS object
3985 
3986    Level: intermediate
3987 
3988 .keywords: TS, timestep, set, adjoint, monitor
3989 
3990 .seealso: TSAdjointMonitorCancel()
3991 @*/
3992 PetscErrorCode  TSAdjointMonitorSet(TS ts,PetscErrorCode (*adjointmonitor)(TS,PetscInt,PetscReal,Vec,PetscInt,Vec*,Vec*,void*),void *adjointmctx,PetscErrorCode (*adjointmdestroy)(void**))
3993 {
3994   PetscErrorCode ierr;
3995   PetscInt       i;
3996   PetscBool      identical;
3997 
3998   PetscFunctionBegin;
3999   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4000   for (i=0; i<ts->numbermonitors;i++) {
4001     ierr = PetscMonitorCompare((PetscErrorCode (*)(void))adjointmonitor,adjointmctx,adjointmdestroy,(PetscErrorCode (*)(void))ts->adjointmonitor[i],ts->adjointmonitorcontext[i],ts->adjointmonitordestroy[i],&identical);CHKERRQ(ierr);
4002     if (identical) PetscFunctionReturn(0);
4003   }
4004   if (ts->numberadjointmonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many adjoint monitors set");
4005   ts->adjointmonitor[ts->numberadjointmonitors]          = adjointmonitor;
4006   ts->adjointmonitordestroy[ts->numberadjointmonitors]   = adjointmdestroy;
4007   ts->adjointmonitorcontext[ts->numberadjointmonitors++] = (void*)adjointmctx;
4008   PetscFunctionReturn(0);
4009 }
4010 
4011 /*@C
4012    TSAdjointMonitorCancel - Clears all the adjoint monitors that have been set on a time-step object.
4013 
4014    Logically Collective on TS
4015 
4016    Input Parameters:
4017 .  ts - the TS context obtained from TSCreate()
4018 
4019    Notes:
4020    There is no way to remove a single, specific monitor.
4021 
4022    Level: intermediate
4023 
4024 .keywords: TS, timestep, set, adjoint, monitor
4025 
4026 .seealso: TSAdjointMonitorSet()
4027 @*/
4028 PetscErrorCode  TSAdjointMonitorCancel(TS ts)
4029 {
4030   PetscErrorCode ierr;
4031   PetscInt       i;
4032 
4033   PetscFunctionBegin;
4034   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4035   for (i=0; i<ts->numberadjointmonitors; i++) {
4036     if (ts->adjointmonitordestroy[i]) {
4037       ierr = (*ts->adjointmonitordestroy[i])(&ts->adjointmonitorcontext[i]);CHKERRQ(ierr);
4038     }
4039   }
4040   ts->numberadjointmonitors = 0;
4041   PetscFunctionReturn(0);
4042 }
4043 
4044 /*@C
4045    TSAdjointMonitorDefault - the default monitor of adjoint computations
4046 
4047    Level: intermediate
4048 
4049 .keywords: TS, set, monitor
4050 
4051 .seealso: TSAdjointMonitorSet()
4052 @*/
4053 PetscErrorCode TSAdjointMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscInt numcost,Vec *lambda,Vec *mu,PetscViewerAndFormat *vf)
4054 {
4055   PetscErrorCode ierr;
4056   PetscViewer    viewer = vf->viewer;
4057 
4058   PetscFunctionBegin;
4059   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
4060   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
4061   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
4062   ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr);
4063   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
4064   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4065   PetscFunctionReturn(0);
4066 }
4067 
4068 /*@
4069    TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval
4070 
4071    Collective on TS
4072 
4073    Input Argument:
4074 +  ts - time stepping context
4075 -  t - time to interpolate to
4076 
4077    Output Argument:
4078 .  U - state at given time
4079 
4080    Level: intermediate
4081 
4082    Developer Notes:
4083    TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints.
4084 
4085 .keywords: TS, set
4086 
4087 .seealso: TSSetExactFinalTime(), TSSolve()
4088 @*/
4089 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U)
4090 {
4091   PetscErrorCode ierr;
4092 
4093   PetscFunctionBegin;
4094   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4095   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
4096   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);
4097   if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name);
4098   ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr);
4099   PetscFunctionReturn(0);
4100 }
4101 
4102 /*@
4103    TSStep - Steps one time step
4104 
4105    Collective on TS
4106 
4107    Input Parameter:
4108 .  ts - the TS context obtained from TSCreate()
4109 
4110    Level: developer
4111 
4112    Notes:
4113    The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine.
4114 
4115    The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may
4116    be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages.
4117 
4118    This may over-step the final time provided in TSSetMaxTime() depending on the time-step used. TSSolve() interpolates to exactly the
4119    time provided in TSSetMaxTime(). One can use TSInterpolate() to determine an interpolated solution within the final timestep.
4120 
4121 .keywords: TS, timestep, solve
4122 
4123 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate()
4124 @*/
4125 PetscErrorCode  TSStep(TS ts)
4126 {
4127   PetscErrorCode   ierr;
4128   static PetscBool cite = PETSC_FALSE;
4129   PetscReal        ptime;
4130 
4131   PetscFunctionBegin;
4132   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4133   ierr = PetscCitationsRegister("@techreport{tspaper,\n"
4134                                 "  title       = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n"
4135                                 "  author      = {Shrirang Abhyankar and Jed Brown and Emil Constantinescu and Debojyoti Ghosh and Barry F. Smith},\n"
4136                                 "  type        = {Preprint},\n"
4137                                 "  number      = {ANL/MCS-P5061-0114},\n"
4138                                 "  institution = {Argonne National Laboratory},\n"
4139                                 "  year        = {2014}\n}\n",&cite);CHKERRQ(ierr);
4140 
4141   ierr = TSSetUp(ts);CHKERRQ(ierr);
4142   ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr);
4143 
4144   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>");
4145   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()");
4146   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");
4147 
4148   if (!ts->steps) ts->ptime_prev = ts->ptime;
4149   ptime = ts->ptime; ts->ptime_prev_rollback = ts->ptime_prev;
4150   ts->reason = TS_CONVERGED_ITERATING;
4151   if (!ts->ops->step) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name);
4152   ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr);
4153   ierr = (*ts->ops->step)(ts);CHKERRQ(ierr);
4154   ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr);
4155   ts->ptime_prev = ptime;
4156   ts->steps++;
4157   ts->steprollback = PETSC_FALSE;
4158   ts->steprestart  = PETSC_FALSE;
4159 
4160   if (ts->reason < 0) {
4161     if (ts->errorifstepfailed) {
4162       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]);
4163       else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]);
4164     }
4165   } else if (!ts->reason) {
4166     if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS;
4167     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
4168   }
4169   PetscFunctionReturn(0);
4170 }
4171 
4172 /*@
4173    TSAdjointStep - Steps one time step backward in the adjoint run
4174 
4175    Collective on TS
4176 
4177    Input Parameter:
4178 .  ts - the TS context obtained from TSCreate()
4179 
4180    Level: intermediate
4181 
4182 .keywords: TS, adjoint, step
4183 
4184 .seealso: TSAdjointSetUp(), TSAdjointSolve()
4185 @*/
4186 PetscErrorCode  TSAdjointStep(TS ts)
4187 {
4188   DM               dm;
4189   PetscErrorCode   ierr;
4190 
4191   PetscFunctionBegin;
4192   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4193   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4194   ierr = TSAdjointSetUp(ts);CHKERRQ(ierr);
4195 
4196   ierr = VecViewFromOptions(ts->vec_sol,(PetscObject)ts,"-ts_view_solution");CHKERRQ(ierr);
4197 
4198   ts->reason = TS_CONVERGED_ITERATING;
4199   ts->ptime_prev = ts->ptime;
4200   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);
4201   ierr = PetscLogEventBegin(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr);
4202   ierr = (*ts->ops->adjointstep)(ts);CHKERRQ(ierr);
4203   ierr = PetscLogEventEnd(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr);
4204   ts->adjoint_steps++; ts->steps--;
4205 
4206   if (ts->reason < 0) {
4207     if (ts->errorifstepfailed) {
4208       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]);
4209       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]);
4210       else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]);
4211     }
4212   } else if (!ts->reason) {
4213     if (ts->adjoint_steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS;
4214   }
4215   PetscFunctionReturn(0);
4216 }
4217 
4218 /*@
4219    TSEvaluateWLTE - Evaluate the weighted local truncation error norm
4220    at the end of a time step with a given order of accuracy.
4221 
4222    Collective on TS
4223 
4224    Input Arguments:
4225 +  ts - time stepping context
4226 .  wnormtype - norm type, either NORM_2 or NORM_INFINITY
4227 -  order - optional, desired order for the error evaluation or PETSC_DECIDE
4228 
4229    Output Arguments:
4230 +  order - optional, the actual order of the error evaluation
4231 -  wlte - the weighted local truncation error norm
4232 
4233    Level: advanced
4234 
4235    Notes:
4236    If the timestepper cannot evaluate the error in a particular step
4237    (eg. in the first step or restart steps after event handling),
4238    this routine returns wlte=-1.0 .
4239 
4240 .seealso: TSStep(), TSAdapt, TSErrorWeightedNorm()
4241 @*/
4242 PetscErrorCode TSEvaluateWLTE(TS ts,NormType wnormtype,PetscInt *order,PetscReal *wlte)
4243 {
4244   PetscErrorCode ierr;
4245 
4246   PetscFunctionBegin;
4247   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4248   PetscValidType(ts,1);
4249   PetscValidLogicalCollectiveEnum(ts,wnormtype,4);
4250   if (order) PetscValidIntPointer(order,3);
4251   if (order) PetscValidLogicalCollectiveInt(ts,*order,3);
4252   PetscValidRealPointer(wlte,4);
4253   if (wnormtype != NORM_2 && wnormtype != NORM_INFINITY) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
4254   if (!ts->ops->evaluatewlte) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateWLTE not implemented for type '%s'",((PetscObject)ts)->type_name);
4255   ierr = (*ts->ops->evaluatewlte)(ts,wnormtype,order,wlte);CHKERRQ(ierr);
4256   PetscFunctionReturn(0);
4257 }
4258 
4259 /*@
4260    TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy.
4261 
4262    Collective on TS
4263 
4264    Input Arguments:
4265 +  ts - time stepping context
4266 .  order - desired order of accuracy
4267 -  done - whether the step was evaluated at this order (pass NULL to generate an error if not available)
4268 
4269    Output Arguments:
4270 .  U - state at the end of the current step
4271 
4272    Level: advanced
4273 
4274    Notes:
4275    This function cannot be called until all stages have been evaluated.
4276    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.
4277 
4278 .seealso: TSStep(), TSAdapt
4279 @*/
4280 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done)
4281 {
4282   PetscErrorCode ierr;
4283 
4284   PetscFunctionBegin;
4285   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4286   PetscValidType(ts,1);
4287   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
4288   if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name);
4289   ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr);
4290   PetscFunctionReturn(0);
4291 }
4292 
4293 /*@
4294    TSForwardCostIntegral - Evaluate the cost integral in the forward run.
4295 
4296    Collective on TS
4297 
4298    Input Arguments:
4299 .  ts - time stepping context
4300 
4301    Level: advanced
4302 
4303    Notes:
4304    This function cannot be called until TSStep() has been completed.
4305 
4306 .seealso: TSSolve(), TSAdjointCostIntegral()
4307 @*/
4308 PetscErrorCode TSForwardCostIntegral(TS ts)
4309 {
4310   PetscErrorCode ierr;
4311   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4312   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);
4313   ierr = (*ts->ops->forwardintegral)(ts);CHKERRQ(ierr);
4314   PetscFunctionReturn(0);
4315 }
4316 
4317 /*@
4318    TSSolve - Steps the requested number of timesteps.
4319 
4320    Collective on TS
4321 
4322    Input Parameter:
4323 +  ts - the TS context obtained from TSCreate()
4324 -  u - the solution vector  (can be null if TSSetSolution() was used and TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP) was not used,
4325                              otherwise must contain the initial conditions and will contain the solution at the final requested time
4326 
4327    Level: beginner
4328 
4329    Notes:
4330    The final time returned by this function may be different from the time of the internally
4331    held state accessible by TSGetSolution() and TSGetTime() because the method may have
4332    stepped over the final time.
4333 
4334 .keywords: TS, timestep, solve
4335 
4336 .seealso: TSCreate(), TSSetSolution(), TSStep(), TSGetTime(), TSGetSolveTime()
4337 @*/
4338 PetscErrorCode TSSolve(TS ts,Vec u)
4339 {
4340   Vec               solution;
4341   PetscErrorCode    ierr;
4342 
4343   PetscFunctionBegin;
4344   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4345   if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2);
4346 
4347   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 */
4348     if (!ts->vec_sol || u == ts->vec_sol) {
4349       ierr = VecDuplicate(u,&solution);CHKERRQ(ierr);
4350       ierr = TSSetSolution(ts,solution);CHKERRQ(ierr);
4351       ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */
4352     }
4353     ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr);
4354     if (ts->forward_solve) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Sensitivity analysis does not support the mode TS_EXACTFINALTIME_INTERPOLATE");
4355   } else if (u) {
4356     ierr = TSSetSolution(ts,u);CHKERRQ(ierr);
4357   }
4358   ierr = TSSetUp(ts);CHKERRQ(ierr);
4359   ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr);
4360 
4361   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>");
4362   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()");
4363   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");
4364 
4365   if (ts->forward_solve) {
4366     ierr = TSForwardSetUp(ts);CHKERRQ(ierr);
4367   }
4368 
4369   /* reset number of steps only when the step is not restarted. ARKIMEX
4370      restarts the step after an event. Resetting these counters in such case causes
4371      TSTrajectory to incorrectly save the output files
4372   */
4373   /* reset time step and iteration counters */
4374   if (!ts->steps) {
4375     ts->ksp_its           = 0;
4376     ts->snes_its          = 0;
4377     ts->num_snes_failures = 0;
4378     ts->reject            = 0;
4379     ts->steprestart       = PETSC_TRUE;
4380     ts->steprollback      = PETSC_FALSE;
4381   }
4382   if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP && ts->ptime + ts->time_step > ts->max_time) ts->time_step = ts->max_time - ts->ptime;
4383   ts->reason = TS_CONVERGED_ITERATING;
4384 
4385   ierr = TSViewFromOptions(ts,NULL,"-ts_view_pre");CHKERRQ(ierr);
4386 
4387   if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */
4388     ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr);
4389     if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);}
4390     ts->solvetime = ts->ptime;
4391     solution = ts->vec_sol;
4392   } else { /* Step the requested number of timesteps. */
4393     if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS;
4394     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
4395 
4396     if (!ts->steps) {
4397       ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4398       ierr = TSEventInitialize(ts->event,ts,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4399     }
4400 
4401     while (!ts->reason) {
4402       ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4403       if (!ts->steprollback) {
4404         ierr = TSPreStep(ts);CHKERRQ(ierr);
4405       }
4406       ierr = TSStep(ts);CHKERRQ(ierr);
4407       if (ts->testjacobian) {
4408         ierr = TSRHSJacobianTest(ts,NULL);CHKERRQ(ierr);
4409       }
4410       if (ts->testjacobiantranspose) {
4411         ierr = TSRHSJacobianTestTranspose(ts,NULL);CHKERRQ(ierr);
4412       }
4413       if (ts->vec_costintegral && ts->costintegralfwd) { /* Must evaluate the cost integral before event is handled. The cost integral value can also be rolled back. */
4414         ierr = TSForwardCostIntegral(ts);CHKERRQ(ierr);
4415       }
4416       if (ts->forward_solve) { /* compute forward sensitivities before event handling because postevent() may change RHS and jump conditions may have to be applied */
4417         ierr = TSForwardStep(ts);CHKERRQ(ierr);
4418       }
4419       ierr = TSPostEvaluate(ts);CHKERRQ(ierr);
4420       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. */
4421       if (ts->steprollback) {
4422         ierr = TSPostEvaluate(ts);CHKERRQ(ierr);
4423       }
4424       if (!ts->steprollback) {
4425         ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4426         ierr = TSPostStep(ts);CHKERRQ(ierr);
4427       }
4428     }
4429     ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4430 
4431     if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) {
4432       ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr);
4433       ts->solvetime = ts->max_time;
4434       solution = u;
4435       ierr = TSMonitor(ts,-1,ts->solvetime,solution);CHKERRQ(ierr);
4436     } else {
4437       if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);}
4438       ts->solvetime = ts->ptime;
4439       solution = ts->vec_sol;
4440     }
4441   }
4442 
4443   ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr);
4444   ierr = VecViewFromOptions(solution,NULL,"-ts_view_solution");CHKERRQ(ierr);
4445   ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr);
4446   if (ts->adjoint_solve) {
4447     ierr = TSAdjointSolve(ts);CHKERRQ(ierr);
4448   }
4449   PetscFunctionReturn(0);
4450 }
4451 
4452 /*@
4453  TSAdjointCostIntegral - Evaluate the cost integral in the adjoint run.
4454 
4455  Collective on TS
4456 
4457  Input Arguments:
4458  .  ts - time stepping context
4459 
4460  Level: advanced
4461 
4462  Notes:
4463  This function cannot be called until TSAdjointStep() has been completed.
4464 
4465  .seealso: TSAdjointSolve(), TSAdjointStep
4466  @*/
4467 PetscErrorCode TSAdjointCostIntegral(TS ts)
4468 {
4469     PetscErrorCode ierr;
4470     PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4471     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);
4472     ierr = (*ts->ops->adjointintegral)(ts);CHKERRQ(ierr);
4473     PetscFunctionReturn(0);
4474 }
4475 
4476 /*@
4477    TSAdjointSolve - Solves the discrete ajoint problem for an ODE/DAE
4478 
4479    Collective on TS
4480 
4481    Input Parameter:
4482 .  ts - the TS context obtained from TSCreate()
4483 
4484    Options Database:
4485 . -ts_adjoint_view_solution <viewerinfo> - views the first gradient with respect to the initial values
4486 
4487    Level: intermediate
4488 
4489    Notes:
4490    This must be called after a call to TSSolve() that solves the forward problem
4491 
4492    By default this will integrate back to the initial time, one can use TSAdjointSetSteps() to step back to a later time
4493 
4494 .keywords: TS, timestep, solve
4495 
4496 .seealso: TSCreate(), TSSetCostGradients(), TSSetSolution(), TSAdjointStep()
4497 @*/
4498 PetscErrorCode TSAdjointSolve(TS ts)
4499 {
4500   PetscErrorCode    ierr;
4501 
4502   PetscFunctionBegin;
4503   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4504   ierr = TSAdjointSetUp(ts);CHKERRQ(ierr);
4505 
4506   /* reset time step and iteration counters */
4507   ts->adjoint_steps     = 0;
4508   ts->ksp_its           = 0;
4509   ts->snes_its          = 0;
4510   ts->num_snes_failures = 0;
4511   ts->reject            = 0;
4512   ts->reason            = TS_CONVERGED_ITERATING;
4513 
4514   if (!ts->adjoint_max_steps) ts->adjoint_max_steps = ts->steps;
4515   if (ts->adjoint_steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS;
4516 
4517   while (!ts->reason) {
4518     ierr = TSTrajectoryGet(ts->trajectory,ts,ts->steps,&ts->ptime);CHKERRQ(ierr);
4519     ierr = TSAdjointMonitor(ts,ts->steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr);
4520     ierr = TSAdjointEventHandler(ts);CHKERRQ(ierr);
4521     ierr = TSAdjointStep(ts);CHKERRQ(ierr);
4522     if (ts->vec_costintegral && !ts->costintegralfwd) {
4523       ierr = TSAdjointCostIntegral(ts);CHKERRQ(ierr);
4524     }
4525   }
4526   ierr = TSTrajectoryGet(ts->trajectory,ts,ts->steps,&ts->ptime);CHKERRQ(ierr);
4527   ierr = TSAdjointMonitor(ts,ts->steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr);
4528   ts->solvetime = ts->ptime;
4529   ierr = TSTrajectoryViewFromOptions(ts->trajectory,NULL,"-ts_trajectory_view");CHKERRQ(ierr);
4530   ierr = VecViewFromOptions(ts->vecs_sensi[0],(PetscObject) ts, "-ts_adjoint_view_solution");CHKERRQ(ierr);
4531   ts->adjoint_max_steps = 0;
4532   PetscFunctionReturn(0);
4533 }
4534 
4535 /*@C
4536    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()
4537 
4538    Collective on TS
4539 
4540    Input Parameters:
4541 +  ts - time stepping context obtained from TSCreate()
4542 .  step - step number that has just completed
4543 .  ptime - model time of the state
4544 -  u - state at the current model time
4545 
4546    Notes:
4547    TSMonitor() is typically used automatically within the time stepping implementations.
4548    Users would almost never call this routine directly.
4549 
4550    A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions
4551 
4552    Level: developer
4553 
4554 .keywords: TS, timestep
4555 @*/
4556 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u)
4557 {
4558   DM             dm;
4559   PetscInt       i,n = ts->numbermonitors;
4560   PetscErrorCode ierr;
4561 
4562   PetscFunctionBegin;
4563   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4564   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
4565 
4566   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4567   ierr = DMSetOutputSequenceNumber(dm,step,ptime);CHKERRQ(ierr);
4568 
4569   ierr = VecLockPush(u);CHKERRQ(ierr);
4570   for (i=0; i<n; i++) {
4571     ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr);
4572   }
4573   ierr = VecLockPop(u);CHKERRQ(ierr);
4574   PetscFunctionReturn(0);
4575 }
4576 
4577 /*@C
4578    TSAdjointMonitor - Runs all user-provided adjoint monitor routines set using TSAdjointMonitorSet()
4579 
4580    Collective on TS
4581 
4582    Input Parameters:
4583 +  ts - time stepping context obtained from TSCreate()
4584 .  step - step number that has just completed
4585 .  ptime - model time of the state
4586 .  u - state at the current model time
4587 .  numcost - number of cost functions (dimension of lambda  or mu)
4588 .  lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables
4589 -  mu - vectors containing the gradients of the cost functions with respect to the problem parameters
4590 
4591    Notes:
4592    TSAdjointMonitor() is typically used automatically within the time stepping implementations.
4593    Users would almost never call this routine directly.
4594 
4595    Level: developer
4596 
4597 .keywords: TS, timestep
4598 @*/
4599 PetscErrorCode TSAdjointMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda, Vec *mu)
4600 {
4601   PetscErrorCode ierr;
4602   PetscInt       i,n = ts->numberadjointmonitors;
4603 
4604   PetscFunctionBegin;
4605   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4606   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
4607   ierr = VecLockPush(u);CHKERRQ(ierr);
4608   for (i=0; i<n; i++) {
4609     ierr = (*ts->adjointmonitor[i])(ts,step,ptime,u,numcost,lambda,mu,ts->adjointmonitorcontext[i]);CHKERRQ(ierr);
4610   }
4611   ierr = VecLockPop(u);CHKERRQ(ierr);
4612   PetscFunctionReturn(0);
4613 }
4614 
4615 /* ------------------------------------------------------------------------*/
4616 /*@C
4617    TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with
4618    TS to monitor the solution process graphically in various ways
4619 
4620    Collective on TS
4621 
4622    Input Parameters:
4623 +  host - the X display to open, or null for the local machine
4624 .  label - the title to put in the title bar
4625 .  x, y - the screen coordinates of the upper left coordinate of the window
4626 .  m, n - the screen width and height in pixels
4627 -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
4628 
4629    Output Parameter:
4630 .  ctx - the context
4631 
4632    Options Database Key:
4633 +  -ts_monitor_lg_timestep - automatically sets line graph monitor
4634 +  -ts_monitor_lg_timestep_log - automatically sets line graph monitor
4635 .  -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables())
4636 .  -ts_monitor_lg_error -  monitor the error
4637 .  -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep
4638 .  -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep
4639 -  -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true
4640 
4641    Notes:
4642    Use TSMonitorLGCtxDestroy() to destroy.
4643 
4644    One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform()
4645 
4646    Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the
4647    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
4648    as the first argument.
4649 
4650    One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames()
4651 
4652    Level: intermediate
4653 
4654 .keywords: TS, monitor, line graph, residual
4655 
4656 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(),
4657            TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
4658            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
4659            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
4660            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()
4661 
4662 @*/
4663 PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
4664 {
4665   PetscDraw      draw;
4666   PetscErrorCode ierr;
4667 
4668   PetscFunctionBegin;
4669   ierr = PetscNew(ctx);CHKERRQ(ierr);
4670   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr);
4671   ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr);
4672   ierr = PetscDrawLGCreate(draw,1,&(*ctx)->lg);CHKERRQ(ierr);
4673   ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr);
4674   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
4675   (*ctx)->howoften = howoften;
4676   PetscFunctionReturn(0);
4677 }
4678 
4679 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx)
4680 {
4681   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
4682   PetscReal      x   = ptime,y;
4683   PetscErrorCode ierr;
4684 
4685   PetscFunctionBegin;
4686   if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */
4687   if (!step) {
4688     PetscDrawAxis axis;
4689     const char *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step";
4690     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4691     ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time",ylabel);CHKERRQ(ierr);
4692     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4693   }
4694   ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr);
4695   if (ctx->semilogy) y = PetscLog10Real(y);
4696   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
4697   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
4698     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4699     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
4700   }
4701   PetscFunctionReturn(0);
4702 }
4703 
4704 /*@C
4705    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
4706    with TSMonitorLGCtxCreate().
4707 
4708    Collective on TSMonitorLGCtx
4709 
4710    Input Parameter:
4711 .  ctx - the monitor context
4712 
4713    Level: intermediate
4714 
4715 .keywords: TS, monitor, line graph, destroy
4716 
4717 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep();
4718 @*/
4719 PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
4720 {
4721   PetscErrorCode ierr;
4722 
4723   PetscFunctionBegin;
4724   if ((*ctx)->transformdestroy) {
4725     ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr);
4726   }
4727   ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr);
4728   ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr);
4729   ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr);
4730   ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr);
4731   ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr);
4732   ierr = PetscFree(*ctx);CHKERRQ(ierr);
4733   PetscFunctionReturn(0);
4734 }
4735 
4736 /*@
4737    TSGetTime - Gets the time of the most recently completed step.
4738 
4739    Not Collective
4740 
4741    Input Parameter:
4742 .  ts - the TS context obtained from TSCreate()
4743 
4744    Output Parameter:
4745 .  t  - the current time. This time may not corresponds to the final time set with TSSetMaxTime(), use TSGetSolveTime().
4746 
4747    Level: beginner
4748 
4749    Note:
4750    When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(),
4751    TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated.
4752 
4753 .seealso:  TSGetSolveTime(), TSSetTime(), TSGetTimeStep()
4754 
4755 .keywords: TS, get, time
4756 @*/
4757 PetscErrorCode  TSGetTime(TS ts,PetscReal *t)
4758 {
4759   PetscFunctionBegin;
4760   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4761   PetscValidRealPointer(t,2);
4762   *t = ts->ptime;
4763   PetscFunctionReturn(0);
4764 }
4765 
4766 /*@
4767    TSGetPrevTime - Gets the starting time of the previously completed step.
4768 
4769    Not Collective
4770 
4771    Input Parameter:
4772 .  ts - the TS context obtained from TSCreate()
4773 
4774    Output Parameter:
4775 .  t  - the previous time
4776 
4777    Level: beginner
4778 
4779 .seealso: TSGetTime(), TSGetSolveTime(), TSGetTimeStep()
4780 
4781 .keywords: TS, get, time
4782 @*/
4783 PetscErrorCode  TSGetPrevTime(TS ts,PetscReal *t)
4784 {
4785   PetscFunctionBegin;
4786   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4787   PetscValidRealPointer(t,2);
4788   *t = ts->ptime_prev;
4789   PetscFunctionReturn(0);
4790 }
4791 
4792 /*@
4793    TSSetTime - Allows one to reset the time.
4794 
4795    Logically Collective on TS
4796 
4797    Input Parameters:
4798 +  ts - the TS context obtained from TSCreate()
4799 -  time - the time
4800 
4801    Level: intermediate
4802 
4803 .seealso: TSGetTime(), TSSetMaxSteps()
4804 
4805 .keywords: TS, set, time
4806 @*/
4807 PetscErrorCode  TSSetTime(TS ts, PetscReal t)
4808 {
4809   PetscFunctionBegin;
4810   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4811   PetscValidLogicalCollectiveReal(ts,t,2);
4812   ts->ptime = t;
4813   PetscFunctionReturn(0);
4814 }
4815 
4816 /*@C
4817    TSSetOptionsPrefix - Sets the prefix used for searching for all
4818    TS options in the database.
4819 
4820    Logically Collective on TS
4821 
4822    Input Parameter:
4823 +  ts     - The TS context
4824 -  prefix - The prefix to prepend to all option names
4825 
4826    Notes:
4827    A hyphen (-) must NOT be given at the beginning of the prefix name.
4828    The first character of all runtime options is AUTOMATICALLY the
4829    hyphen.
4830 
4831    Level: advanced
4832 
4833 .keywords: TS, set, options, prefix, database
4834 
4835 .seealso: TSSetFromOptions()
4836 
4837 @*/
4838 PetscErrorCode  TSSetOptionsPrefix(TS ts,const char prefix[])
4839 {
4840   PetscErrorCode ierr;
4841   SNES           snes;
4842 
4843   PetscFunctionBegin;
4844   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4845   ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
4846   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4847   ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr);
4848   PetscFunctionReturn(0);
4849 }
4850 
4851 /*@C
4852    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
4853    TS options in the database.
4854 
4855    Logically Collective on TS
4856 
4857    Input Parameter:
4858 +  ts     - The TS context
4859 -  prefix - The prefix to prepend to all option names
4860 
4861    Notes:
4862    A hyphen (-) must NOT be given at the beginning of the prefix name.
4863    The first character of all runtime options is AUTOMATICALLY the
4864    hyphen.
4865 
4866    Level: advanced
4867 
4868 .keywords: TS, append, options, prefix, database
4869 
4870 .seealso: TSGetOptionsPrefix()
4871 
4872 @*/
4873 PetscErrorCode  TSAppendOptionsPrefix(TS ts,const char prefix[])
4874 {
4875   PetscErrorCode ierr;
4876   SNES           snes;
4877 
4878   PetscFunctionBegin;
4879   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4880   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
4881   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4882   ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr);
4883   PetscFunctionReturn(0);
4884 }
4885 
4886 /*@C
4887    TSGetOptionsPrefix - Sets the prefix used for searching for all
4888    TS options in the database.
4889 
4890    Not Collective
4891 
4892    Input Parameter:
4893 .  ts - The TS context
4894 
4895    Output Parameter:
4896 .  prefix - A pointer to the prefix string used
4897 
4898    Notes: On the fortran side, the user should pass in a string 'prifix' of
4899    sufficient length to hold the prefix.
4900 
4901    Level: intermediate
4902 
4903 .keywords: TS, get, options, prefix, database
4904 
4905 .seealso: TSAppendOptionsPrefix()
4906 @*/
4907 PetscErrorCode  TSGetOptionsPrefix(TS ts,const char *prefix[])
4908 {
4909   PetscErrorCode ierr;
4910 
4911   PetscFunctionBegin;
4912   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4913   PetscValidPointer(prefix,2);
4914   ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
4915   PetscFunctionReturn(0);
4916 }
4917 
4918 /*@C
4919    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
4920 
4921    Not Collective, but parallel objects are returned if TS is parallel
4922 
4923    Input Parameter:
4924 .  ts  - The TS context obtained from TSCreate()
4925 
4926    Output Parameters:
4927 +  Amat - The (approximate) Jacobian J of G, where U_t = G(U,t)  (or NULL)
4928 .  Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat  (or NULL)
4929 .  func - Function to compute the Jacobian of the RHS  (or NULL)
4930 -  ctx - User-defined context for Jacobian evaluation routine  (or NULL)
4931 
4932    Notes: You can pass in NULL for any return argument you do not need.
4933 
4934    Level: intermediate
4935 
4936 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetStepNumber()
4937 
4938 .keywords: TS, timestep, get, matrix, Jacobian
4939 @*/
4940 PetscErrorCode  TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx)
4941 {
4942   PetscErrorCode ierr;
4943   DM             dm;
4944 
4945   PetscFunctionBegin;
4946   if (Amat || Pmat) {
4947     SNES snes;
4948     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4949     ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
4950     ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
4951   }
4952   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4953   ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr);
4954   PetscFunctionReturn(0);
4955 }
4956 
4957 /*@C
4958    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
4959 
4960    Not Collective, but parallel objects are returned if TS is parallel
4961 
4962    Input Parameter:
4963 .  ts  - The TS context obtained from TSCreate()
4964 
4965    Output Parameters:
4966 +  Amat  - The (approximate) Jacobian of F(t,U,U_t)
4967 .  Pmat - The matrix from which the preconditioner is constructed, often the same as Amat
4968 .  f   - The function to compute the matrices
4969 - ctx - User-defined context for Jacobian evaluation routine
4970 
4971    Notes: You can pass in NULL for any return argument you do not need.
4972 
4973    Level: advanced
4974 
4975 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetStepNumber()
4976 
4977 .keywords: TS, timestep, get, matrix, Jacobian
4978 @*/
4979 PetscErrorCode  TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx)
4980 {
4981   PetscErrorCode ierr;
4982   DM             dm;
4983 
4984   PetscFunctionBegin;
4985   if (Amat || Pmat) {
4986     SNES snes;
4987     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4988     ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
4989     ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
4990   }
4991   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4992   ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr);
4993   PetscFunctionReturn(0);
4994 }
4995 
4996 /*@C
4997    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
4998    VecView() for the solution at each timestep
4999 
5000    Collective on TS
5001 
5002    Input Parameters:
5003 +  ts - the TS context
5004 .  step - current time-step
5005 .  ptime - current time
5006 -  dummy - either a viewer or NULL
5007 
5008    Options Database:
5009 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
5010 
5011    Notes: the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
5012        will look bad
5013 
5014    Level: intermediate
5015 
5016 .keywords: TS,  vector, monitor, view
5017 
5018 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5019 @*/
5020 PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
5021 {
5022   PetscErrorCode   ierr;
5023   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
5024   PetscDraw        draw;
5025 
5026   PetscFunctionBegin;
5027   if (!step && ictx->showinitial) {
5028     if (!ictx->initialsolution) {
5029       ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr);
5030     }
5031     ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr);
5032   }
5033   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
5034 
5035   if (ictx->showinitial) {
5036     PetscReal pause;
5037     ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr);
5038     ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr);
5039     ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr);
5040     ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr);
5041     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr);
5042   }
5043   ierr = VecView(u,ictx->viewer);CHKERRQ(ierr);
5044   if (ictx->showtimestepandtime) {
5045     PetscReal xl,yl,xr,yr,h;
5046     char      time[32];
5047 
5048     ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
5049     ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
5050     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
5051     h    = yl + .95*(yr - yl);
5052     ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
5053     ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
5054   }
5055 
5056   if (ictx->showinitial) {
5057     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr);
5058   }
5059   PetscFunctionReturn(0);
5060 }
5061 
5062 /*@C
5063    TSAdjointMonitorDrawSensi - Monitors progress of the adjoint TS solvers by calling
5064    VecView() for the sensitivities to initial states at each timestep
5065 
5066    Collective on TS
5067 
5068    Input Parameters:
5069 +  ts - the TS context
5070 .  step - current time-step
5071 .  ptime - current time
5072 .  u - current state
5073 .  numcost - number of cost functions
5074 .  lambda - sensitivities to initial conditions
5075 .  mu - sensitivities to parameters
5076 -  dummy - either a viewer or NULL
5077 
5078    Level: intermediate
5079 
5080 .keywords: TS,  vector, adjoint, monitor, view
5081 
5082 .seealso: TSAdjointMonitorSet(), TSAdjointMonitorDefault(), VecView()
5083 @*/
5084 PetscErrorCode  TSAdjointMonitorDrawSensi(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda,Vec *mu,void *dummy)
5085 {
5086   PetscErrorCode   ierr;
5087   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
5088   PetscDraw        draw;
5089   PetscReal        xl,yl,xr,yr,h;
5090   char             time[32];
5091 
5092   PetscFunctionBegin;
5093   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
5094 
5095   ierr = VecView(lambda[0],ictx->viewer);CHKERRQ(ierr);
5096   ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
5097   ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
5098   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
5099   h    = yl + .95*(yr - yl);
5100   ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
5101   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
5102   PetscFunctionReturn(0);
5103 }
5104 
5105 /*@C
5106    TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram
5107 
5108    Collective on TS
5109 
5110    Input Parameters:
5111 +  ts - the TS context
5112 .  step - current time-step
5113 .  ptime - current time
5114 -  dummy - either a viewer or NULL
5115 
5116    Level: intermediate
5117 
5118 .keywords: TS,  vector, monitor, view
5119 
5120 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5121 @*/
5122 PetscErrorCode  TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
5123 {
5124   PetscErrorCode    ierr;
5125   TSMonitorDrawCtx  ictx = (TSMonitorDrawCtx)dummy;
5126   PetscDraw         draw;
5127   PetscDrawAxis     axis;
5128   PetscInt          n;
5129   PetscMPIInt       size;
5130   PetscReal         U0,U1,xl,yl,xr,yr,h;
5131   char              time[32];
5132   const PetscScalar *U;
5133 
5134   PetscFunctionBegin;
5135   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size);CHKERRQ(ierr);
5136   if (size != 1) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs");
5137   ierr = VecGetSize(u,&n);CHKERRQ(ierr);
5138   if (n != 2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns");
5139 
5140   ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
5141   ierr = PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis);CHKERRQ(ierr);
5142   ierr = PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr);
5143   if (!step) {
5144     ierr = PetscDrawClear(draw);CHKERRQ(ierr);
5145     ierr = PetscDrawAxisDraw(axis);CHKERRQ(ierr);
5146   }
5147 
5148   ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr);
5149   U0 = PetscRealPart(U[0]);
5150   U1 = PetscRealPart(U[1]);
5151   ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr);
5152   if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0);
5153 
5154   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
5155   ierr = PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK);CHKERRQ(ierr);
5156   if (ictx->showtimestepandtime) {
5157     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
5158     ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
5159     h    = yl + .95*(yr - yl);
5160     ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
5161   }
5162   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
5163   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
5164   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
5165   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
5166   PetscFunctionReturn(0);
5167 }
5168 
5169 /*@C
5170    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
5171 
5172    Collective on TS
5173 
5174    Input Parameters:
5175 .    ctx - the monitor context
5176 
5177    Level: intermediate
5178 
5179 .keywords: TS,  vector, monitor, view
5180 
5181 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError()
5182 @*/
5183 PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
5184 {
5185   PetscErrorCode ierr;
5186 
5187   PetscFunctionBegin;
5188   ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr);
5189   ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr);
5190   ierr = PetscFree(*ictx);CHKERRQ(ierr);
5191   PetscFunctionReturn(0);
5192 }
5193 
5194 /*@C
5195    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
5196 
5197    Collective on TS
5198 
5199    Input Parameter:
5200 .    ts - time-step context
5201 
5202    Output Patameter:
5203 .    ctx - the monitor context
5204 
5205    Options Database:
5206 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
5207 
5208    Level: intermediate
5209 
5210 .keywords: TS,  vector, monitor, view
5211 
5212 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx()
5213 @*/
5214 PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
5215 {
5216   PetscErrorCode   ierr;
5217 
5218   PetscFunctionBegin;
5219   ierr = PetscNew(ctx);CHKERRQ(ierr);
5220   ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr);
5221   ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr);
5222 
5223   (*ctx)->howoften    = howoften;
5224   (*ctx)->showinitial = PETSC_FALSE;
5225   ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr);
5226 
5227   (*ctx)->showtimestepandtime = PETSC_FALSE;
5228   ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr);
5229   PetscFunctionReturn(0);
5230 }
5231 
5232 /*@C
5233    TSMonitorDrawSolutionFunction - Monitors progress of the TS solvers by calling
5234    VecView() for the solution provided by TSSetSolutionFunction() at each timestep
5235 
5236    Collective on TS
5237 
5238    Input Parameters:
5239 +  ts - the TS context
5240 .  step - current time-step
5241 .  ptime - current time
5242 -  dummy - either a viewer or NULL
5243 
5244    Options Database:
5245 .  -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
5246 
5247    Level: intermediate
5248 
5249 .keywords: TS,  vector, monitor, view
5250 
5251 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
5252 @*/
5253 PetscErrorCode  TSMonitorDrawSolutionFunction(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
5254 {
5255   PetscErrorCode   ierr;
5256   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
5257   PetscViewer      viewer = ctx->viewer;
5258   Vec              work;
5259 
5260   PetscFunctionBegin;
5261   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
5262   ierr = VecDuplicate(u,&work);CHKERRQ(ierr);
5263   ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr);
5264   ierr = VecView(work,viewer);CHKERRQ(ierr);
5265   ierr = VecDestroy(&work);CHKERRQ(ierr);
5266   PetscFunctionReturn(0);
5267 }
5268 
5269 /*@C
5270    TSMonitorDrawError - Monitors progress of the TS solvers by calling
5271    VecView() for the error at each timestep
5272 
5273    Collective on TS
5274 
5275    Input Parameters:
5276 +  ts - the TS context
5277 .  step - current time-step
5278 .  ptime - current time
5279 -  dummy - either a viewer or NULL
5280 
5281    Options Database:
5282 .  -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
5283 
5284    Level: intermediate
5285 
5286 .keywords: TS,  vector, monitor, view
5287 
5288 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
5289 @*/
5290 PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
5291 {
5292   PetscErrorCode   ierr;
5293   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
5294   PetscViewer      viewer = ctx->viewer;
5295   Vec              work;
5296 
5297   PetscFunctionBegin;
5298   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
5299   ierr = VecDuplicate(u,&work);CHKERRQ(ierr);
5300   ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr);
5301   ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr);
5302   ierr = VecView(work,viewer);CHKERRQ(ierr);
5303   ierr = VecDestroy(&work);CHKERRQ(ierr);
5304   PetscFunctionReturn(0);
5305 }
5306 
5307 #include <petsc/private/dmimpl.h>
5308 /*@
5309    TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS
5310 
5311    Logically Collective on TS and DM
5312 
5313    Input Parameters:
5314 +  ts - the ODE integrator object
5315 -  dm - the dm, cannot be NULL
5316 
5317    Level: intermediate
5318 
5319 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM()
5320 @*/
5321 PetscErrorCode  TSSetDM(TS ts,DM dm)
5322 {
5323   PetscErrorCode ierr;
5324   SNES           snes;
5325   DMTS           tsdm;
5326 
5327   PetscFunctionBegin;
5328   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5329   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
5330   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
5331   if (ts->dm) {               /* Move the DMTS context over to the new DM unless the new DM already has one */
5332     if (ts->dm->dmts && !dm->dmts) {
5333       ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr);
5334       ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr);
5335       if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */
5336         tsdm->originaldm = dm;
5337       }
5338     }
5339     ierr = DMDestroy(&ts->dm);CHKERRQ(ierr);
5340   }
5341   ts->dm = dm;
5342 
5343   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
5344   ierr = SNESSetDM(snes,dm);CHKERRQ(ierr);
5345   PetscFunctionReturn(0);
5346 }
5347 
5348 /*@
5349    TSGetDM - Gets the DM that may be used by some preconditioners
5350 
5351    Not Collective
5352 
5353    Input Parameter:
5354 . ts - the preconditioner context
5355 
5356    Output Parameter:
5357 .  dm - the dm
5358 
5359    Level: intermediate
5360 
5361 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM()
5362 @*/
5363 PetscErrorCode  TSGetDM(TS ts,DM *dm)
5364 {
5365   PetscErrorCode ierr;
5366 
5367   PetscFunctionBegin;
5368   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5369   if (!ts->dm) {
5370     ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr);
5371     if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
5372   }
5373   *dm = ts->dm;
5374   PetscFunctionReturn(0);
5375 }
5376 
5377 /*@
5378    SNESTSFormFunction - Function to evaluate nonlinear residual
5379 
5380    Logically Collective on SNES
5381 
5382    Input Parameter:
5383 + snes - nonlinear solver
5384 . U - the current state at which to evaluate the residual
5385 - ctx - user context, must be a TS
5386 
5387    Output Parameter:
5388 . F - the nonlinear residual
5389 
5390    Notes:
5391    This function is not normally called by users and is automatically registered with the SNES used by TS.
5392    It is most frequently passed to MatFDColoringSetFunction().
5393 
5394    Level: advanced
5395 
5396 .seealso: SNESSetFunction(), MatFDColoringSetFunction()
5397 @*/
5398 PetscErrorCode  SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx)
5399 {
5400   TS             ts = (TS)ctx;
5401   PetscErrorCode ierr;
5402 
5403   PetscFunctionBegin;
5404   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5405   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
5406   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
5407   PetscValidHeaderSpecific(ts,TS_CLASSID,4);
5408   ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr);
5409   PetscFunctionReturn(0);
5410 }
5411 
5412 /*@
5413    SNESTSFormJacobian - Function to evaluate the Jacobian
5414 
5415    Collective on SNES
5416 
5417    Input Parameter:
5418 + snes - nonlinear solver
5419 . U - the current state at which to evaluate the residual
5420 - ctx - user context, must be a TS
5421 
5422    Output Parameter:
5423 + A - the Jacobian
5424 . B - the preconditioning matrix (may be the same as A)
5425 - flag - indicates any structure change in the matrix
5426 
5427    Notes:
5428    This function is not normally called by users and is automatically registered with the SNES used by TS.
5429 
5430    Level: developer
5431 
5432 .seealso: SNESSetJacobian()
5433 @*/
5434 PetscErrorCode  SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx)
5435 {
5436   TS             ts = (TS)ctx;
5437   PetscErrorCode ierr;
5438 
5439   PetscFunctionBegin;
5440   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5441   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
5442   PetscValidPointer(A,3);
5443   PetscValidHeaderSpecific(A,MAT_CLASSID,3);
5444   PetscValidPointer(B,4);
5445   PetscValidHeaderSpecific(B,MAT_CLASSID,4);
5446   PetscValidHeaderSpecific(ts,TS_CLASSID,6);
5447   ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr);
5448   PetscFunctionReturn(0);
5449 }
5450 
5451 /*@C
5452    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only
5453 
5454    Collective on TS
5455 
5456    Input Arguments:
5457 +  ts - time stepping context
5458 .  t - time at which to evaluate
5459 .  U - state at which to evaluate
5460 -  ctx - context
5461 
5462    Output Arguments:
5463 .  F - right hand side
5464 
5465    Level: intermediate
5466 
5467    Notes:
5468    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
5469    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().
5470 
5471 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
5472 @*/
5473 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx)
5474 {
5475   PetscErrorCode ierr;
5476   Mat            Arhs,Brhs;
5477 
5478   PetscFunctionBegin;
5479   ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
5480   ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr);
5481   ierr = MatMult(Arhs,U,F);CHKERRQ(ierr);
5482   PetscFunctionReturn(0);
5483 }
5484 
5485 /*@C
5486    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
5487 
5488    Collective on TS
5489 
5490    Input Arguments:
5491 +  ts - time stepping context
5492 .  t - time at which to evaluate
5493 .  U - state at which to evaluate
5494 -  ctx - context
5495 
5496    Output Arguments:
5497 +  A - pointer to operator
5498 .  B - pointer to preconditioning matrix
5499 -  flg - matrix structure flag
5500 
5501    Level: intermediate
5502 
5503    Notes:
5504    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.
5505 
5506 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear()
5507 @*/
5508 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx)
5509 {
5510   PetscFunctionBegin;
5511   PetscFunctionReturn(0);
5512 }
5513 
5514 /*@C
5515    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
5516 
5517    Collective on TS
5518 
5519    Input Arguments:
5520 +  ts - time stepping context
5521 .  t - time at which to evaluate
5522 .  U - state at which to evaluate
5523 .  Udot - time derivative of state vector
5524 -  ctx - context
5525 
5526    Output Arguments:
5527 .  F - left hand side
5528 
5529    Level: intermediate
5530 
5531    Notes:
5532    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
5533    user is required to write their own TSComputeIFunction.
5534    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
5535    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().
5536 
5537    Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U
5538 
5539 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant(), TSComputeRHSFunctionLinear()
5540 @*/
5541 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx)
5542 {
5543   PetscErrorCode ierr;
5544   Mat            A,B;
5545 
5546   PetscFunctionBegin;
5547   ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr);
5548   ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr);
5549   ierr = MatMult(A,Udot,F);CHKERRQ(ierr);
5550   PetscFunctionReturn(0);
5551 }
5552 
5553 /*@C
5554    TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE
5555 
5556    Collective on TS
5557 
5558    Input Arguments:
5559 +  ts - time stepping context
5560 .  t - time at which to evaluate
5561 .  U - state at which to evaluate
5562 .  Udot - time derivative of state vector
5563 .  shift - shift to apply
5564 -  ctx - context
5565 
5566    Output Arguments:
5567 +  A - pointer to operator
5568 .  B - pointer to preconditioning matrix
5569 -  flg - matrix structure flag
5570 
5571    Level: advanced
5572 
5573    Notes:
5574    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.
5575 
5576    It is only appropriate for problems of the form
5577 
5578 $     M Udot = F(U,t)
5579 
5580   where M is constant and F is non-stiff.  The user must pass M to TSSetIJacobian().  The current implementation only
5581   works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing
5582   an implicit operator of the form
5583 
5584 $    shift*M + J
5585 
5586   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
5587   a copy of M or reassemble it when requested.
5588 
5589 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear()
5590 @*/
5591 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx)
5592 {
5593   PetscErrorCode ierr;
5594 
5595   PetscFunctionBegin;
5596   ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr);
5597   ts->ijacobian.shift = shift;
5598   PetscFunctionReturn(0);
5599 }
5600 
5601 /*@
5602    TSGetEquationType - Gets the type of the equation that TS is solving.
5603 
5604    Not Collective
5605 
5606    Input Parameter:
5607 .  ts - the TS context
5608 
5609    Output Parameter:
5610 .  equation_type - see TSEquationType
5611 
5612    Level: beginner
5613 
5614 .keywords: TS, equation type
5615 
5616 .seealso: TSSetEquationType(), TSEquationType
5617 @*/
5618 PetscErrorCode  TSGetEquationType(TS ts,TSEquationType *equation_type)
5619 {
5620   PetscFunctionBegin;
5621   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5622   PetscValidPointer(equation_type,2);
5623   *equation_type = ts->equation_type;
5624   PetscFunctionReturn(0);
5625 }
5626 
5627 /*@
5628    TSSetEquationType - Sets the type of the equation that TS is solving.
5629 
5630    Not Collective
5631 
5632    Input Parameter:
5633 +  ts - the TS context
5634 -  equation_type - see TSEquationType
5635 
5636    Level: advanced
5637 
5638 .keywords: TS, equation type
5639 
5640 .seealso: TSGetEquationType(), TSEquationType
5641 @*/
5642 PetscErrorCode  TSSetEquationType(TS ts,TSEquationType equation_type)
5643 {
5644   PetscFunctionBegin;
5645   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5646   ts->equation_type = equation_type;
5647   PetscFunctionReturn(0);
5648 }
5649 
5650 /*@
5651    TSGetConvergedReason - Gets the reason the TS iteration was stopped.
5652 
5653    Not Collective
5654 
5655    Input Parameter:
5656 .  ts - the TS context
5657 
5658    Output Parameter:
5659 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
5660             manual pages for the individual convergence tests for complete lists
5661 
5662    Level: beginner
5663 
5664    Notes:
5665    Can only be called after the call to TSSolve() is complete.
5666 
5667 .keywords: TS, nonlinear, set, convergence, test
5668 
5669 .seealso: TSSetConvergenceTest(), TSConvergedReason
5670 @*/
5671 PetscErrorCode  TSGetConvergedReason(TS ts,TSConvergedReason *reason)
5672 {
5673   PetscFunctionBegin;
5674   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5675   PetscValidPointer(reason,2);
5676   *reason = ts->reason;
5677   PetscFunctionReturn(0);
5678 }
5679 
5680 /*@
5681    TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve.
5682 
5683    Not Collective
5684 
5685    Input Parameter:
5686 +  ts - the TS context
5687 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
5688             manual pages for the individual convergence tests for complete lists
5689 
5690    Level: advanced
5691 
5692    Notes:
5693    Can only be called during TSSolve() is active.
5694 
5695 .keywords: TS, nonlinear, set, convergence, test
5696 
5697 .seealso: TSConvergedReason
5698 @*/
5699 PetscErrorCode  TSSetConvergedReason(TS ts,TSConvergedReason reason)
5700 {
5701   PetscFunctionBegin;
5702   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5703   ts->reason = reason;
5704   PetscFunctionReturn(0);
5705 }
5706 
5707 /*@
5708    TSGetSolveTime - Gets the time after a call to TSSolve()
5709 
5710    Not Collective
5711 
5712    Input Parameter:
5713 .  ts - the TS context
5714 
5715    Output Parameter:
5716 .  ftime - the final time. This time corresponds to the final time set with TSSetMaxTime()
5717 
5718    Level: beginner
5719 
5720    Notes:
5721    Can only be called after the call to TSSolve() is complete.
5722 
5723 .keywords: TS, nonlinear, set, convergence, test
5724 
5725 .seealso: TSSetConvergenceTest(), TSConvergedReason
5726 @*/
5727 PetscErrorCode  TSGetSolveTime(TS ts,PetscReal *ftime)
5728 {
5729   PetscFunctionBegin;
5730   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5731   PetscValidPointer(ftime,2);
5732   *ftime = ts->solvetime;
5733   PetscFunctionReturn(0);
5734 }
5735 
5736 /*@
5737    TSGetSNESIterations - Gets the total number of nonlinear iterations
5738    used by the time integrator.
5739 
5740    Not Collective
5741 
5742    Input Parameter:
5743 .  ts - TS context
5744 
5745    Output Parameter:
5746 .  nits - number of nonlinear iterations
5747 
5748    Notes:
5749    This counter is reset to zero for each successive call to TSSolve().
5750 
5751    Level: intermediate
5752 
5753 .keywords: TS, get, number, nonlinear, iterations
5754 
5755 .seealso:  TSGetKSPIterations()
5756 @*/
5757 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits)
5758 {
5759   PetscFunctionBegin;
5760   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5761   PetscValidIntPointer(nits,2);
5762   *nits = ts->snes_its;
5763   PetscFunctionReturn(0);
5764 }
5765 
5766 /*@
5767    TSGetKSPIterations - Gets the total number of linear iterations
5768    used by the time integrator.
5769 
5770    Not Collective
5771 
5772    Input Parameter:
5773 .  ts - TS context
5774 
5775    Output Parameter:
5776 .  lits - number of linear iterations
5777 
5778    Notes:
5779    This counter is reset to zero for each successive call to TSSolve().
5780 
5781    Level: intermediate
5782 
5783 .keywords: TS, get, number, linear, iterations
5784 
5785 .seealso:  TSGetSNESIterations(), SNESGetKSPIterations()
5786 @*/
5787 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits)
5788 {
5789   PetscFunctionBegin;
5790   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5791   PetscValidIntPointer(lits,2);
5792   *lits = ts->ksp_its;
5793   PetscFunctionReturn(0);
5794 }
5795 
5796 /*@
5797    TSGetStepRejections - Gets the total number of rejected steps.
5798 
5799    Not Collective
5800 
5801    Input Parameter:
5802 .  ts - TS context
5803 
5804    Output Parameter:
5805 .  rejects - number of steps rejected
5806 
5807    Notes:
5808    This counter is reset to zero for each successive call to TSSolve().
5809 
5810    Level: intermediate
5811 
5812 .keywords: TS, get, number
5813 
5814 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails()
5815 @*/
5816 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects)
5817 {
5818   PetscFunctionBegin;
5819   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5820   PetscValidIntPointer(rejects,2);
5821   *rejects = ts->reject;
5822   PetscFunctionReturn(0);
5823 }
5824 
5825 /*@
5826    TSGetSNESFailures - Gets the total number of failed SNES solves
5827 
5828    Not Collective
5829 
5830    Input Parameter:
5831 .  ts - TS context
5832 
5833    Output Parameter:
5834 .  fails - number of failed nonlinear solves
5835 
5836    Notes:
5837    This counter is reset to zero for each successive call to TSSolve().
5838 
5839    Level: intermediate
5840 
5841 .keywords: TS, get, number
5842 
5843 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures()
5844 @*/
5845 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails)
5846 {
5847   PetscFunctionBegin;
5848   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5849   PetscValidIntPointer(fails,2);
5850   *fails = ts->num_snes_failures;
5851   PetscFunctionReturn(0);
5852 }
5853 
5854 /*@
5855    TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails
5856 
5857    Not Collective
5858 
5859    Input Parameter:
5860 +  ts - TS context
5861 -  rejects - maximum number of rejected steps, pass -1 for unlimited
5862 
5863    Notes:
5864    The counter is reset to zero for each step
5865 
5866    Options Database Key:
5867  .  -ts_max_reject - Maximum number of step rejections before a step fails
5868 
5869    Level: intermediate
5870 
5871 .keywords: TS, set, maximum, number
5872 
5873 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
5874 @*/
5875 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects)
5876 {
5877   PetscFunctionBegin;
5878   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5879   ts->max_reject = rejects;
5880   PetscFunctionReturn(0);
5881 }
5882 
5883 /*@
5884    TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves
5885 
5886    Not Collective
5887 
5888    Input Parameter:
5889 +  ts - TS context
5890 -  fails - maximum number of failed nonlinear solves, pass -1 for unlimited
5891 
5892    Notes:
5893    The counter is reset to zero for each successive call to TSSolve().
5894 
5895    Options Database Key:
5896  .  -ts_max_snes_failures - Maximum number of nonlinear solve failures
5897 
5898    Level: intermediate
5899 
5900 .keywords: TS, set, maximum, number
5901 
5902 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason()
5903 @*/
5904 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails)
5905 {
5906   PetscFunctionBegin;
5907   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5908   ts->max_snes_failures = fails;
5909   PetscFunctionReturn(0);
5910 }
5911 
5912 /*@
5913    TSSetErrorIfStepFails - Error if no step succeeds
5914 
5915    Not Collective
5916 
5917    Input Parameter:
5918 +  ts - TS context
5919 -  err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure
5920 
5921    Options Database Key:
5922  .  -ts_error_if_step_fails - Error if no step succeeds
5923 
5924    Level: intermediate
5925 
5926 .keywords: TS, set, error
5927 
5928 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
5929 @*/
5930 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err)
5931 {
5932   PetscFunctionBegin;
5933   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5934   ts->errorifstepfailed = err;
5935   PetscFunctionReturn(0);
5936 }
5937 
5938 /*@C
5939    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
5940 
5941    Collective on TS
5942 
5943    Input Parameters:
5944 +  ts - the TS context
5945 .  step - current time-step
5946 .  ptime - current time
5947 .  u - current state
5948 -  vf - viewer and its format
5949 
5950    Level: intermediate
5951 
5952 .keywords: TS,  vector, monitor, view
5953 
5954 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5955 @*/
5956 PetscErrorCode  TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
5957 {
5958   PetscErrorCode ierr;
5959 
5960   PetscFunctionBegin;
5961   ierr = PetscViewerPushFormat(vf->viewer,vf->format);CHKERRQ(ierr);
5962   ierr = VecView(u,vf->viewer);CHKERRQ(ierr);
5963   ierr = PetscViewerPopFormat(vf->viewer);CHKERRQ(ierr);
5964   PetscFunctionReturn(0);
5965 }
5966 
5967 /*@C
5968    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
5969 
5970    Collective on TS
5971 
5972    Input Parameters:
5973 +  ts - the TS context
5974 .  step - current time-step
5975 .  ptime - current time
5976 .  u - current state
5977 -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
5978 
5979    Level: intermediate
5980 
5981    Notes:
5982    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.
5983    These are named according to the file name template.
5984 
5985    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().
5986 
5987 .keywords: TS,  vector, monitor, view
5988 
5989 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5990 @*/
5991 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
5992 {
5993   PetscErrorCode ierr;
5994   char           filename[PETSC_MAX_PATH_LEN];
5995   PetscViewer    viewer;
5996 
5997   PetscFunctionBegin;
5998   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
5999   ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr);
6000   ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr);
6001   ierr = VecView(u,viewer);CHKERRQ(ierr);
6002   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
6003   PetscFunctionReturn(0);
6004 }
6005 
6006 /*@C
6007    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
6008 
6009    Collective on TS
6010 
6011    Input Parameters:
6012 .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
6013 
6014    Level: intermediate
6015 
6016    Note:
6017    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
6018 
6019 .keywords: TS,  vector, monitor, view
6020 
6021 .seealso: TSMonitorSet(), TSMonitorSolutionVTK()
6022 @*/
6023 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
6024 {
6025   PetscErrorCode ierr;
6026 
6027   PetscFunctionBegin;
6028   ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr);
6029   PetscFunctionReturn(0);
6030 }
6031 
6032 /*@
6033    TSGetAdapt - Get the adaptive controller context for the current method
6034 
6035    Collective on TS if controller has not been created yet
6036 
6037    Input Arguments:
6038 .  ts - time stepping context
6039 
6040    Output Arguments:
6041 .  adapt - adaptive controller
6042 
6043    Level: intermediate
6044 
6045 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose()
6046 @*/
6047 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt)
6048 {
6049   PetscErrorCode ierr;
6050 
6051   PetscFunctionBegin;
6052   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6053   PetscValidPointer(adapt,2);
6054   if (!ts->adapt) {
6055     ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr);
6056     ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr);
6057     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr);
6058   }
6059   *adapt = ts->adapt;
6060   PetscFunctionReturn(0);
6061 }
6062 
6063 /*@
6064    TSSetTolerances - Set tolerances for local truncation error when using adaptive controller
6065 
6066    Logically Collective
6067 
6068    Input Arguments:
6069 +  ts - time integration context
6070 .  atol - scalar absolute tolerances, PETSC_DECIDE to leave current value
6071 .  vatol - vector of absolute tolerances or NULL, used in preference to atol if present
6072 .  rtol - scalar relative tolerances, PETSC_DECIDE to leave current value
6073 -  vrtol - vector of relative tolerances or NULL, used in preference to atol if present
6074 
6075    Options Database keys:
6076 +  -ts_rtol <rtol> - relative tolerance for local truncation error
6077 -  -ts_atol <atol> Absolute tolerance for local truncation error
6078 
6079    Notes:
6080    With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error
6081    (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be
6082    computed only for the differential or the algebraic part then this can be done using the vector of
6083    tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the
6084    differential part and infinity for the algebraic part, the LTE calculation will include only the
6085    differential variables.
6086 
6087    Level: beginner
6088 
6089 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances()
6090 @*/
6091 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol)
6092 {
6093   PetscErrorCode ierr;
6094 
6095   PetscFunctionBegin;
6096   if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol;
6097   if (vatol) {
6098     ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr);
6099     ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
6100     ts->vatol = vatol;
6101   }
6102   if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol;
6103   if (vrtol) {
6104     ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr);
6105     ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
6106     ts->vrtol = vrtol;
6107   }
6108   PetscFunctionReturn(0);
6109 }
6110 
6111 /*@
6112    TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
6113 
6114    Logically Collective
6115 
6116    Input Arguments:
6117 .  ts - time integration context
6118 
6119    Output Arguments:
6120 +  atol - scalar absolute tolerances, NULL to ignore
6121 .  vatol - vector of absolute tolerances, NULL to ignore
6122 .  rtol - scalar relative tolerances, NULL to ignore
6123 -  vrtol - vector of relative tolerances, NULL to ignore
6124 
6125    Level: beginner
6126 
6127 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances()
6128 @*/
6129 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol)
6130 {
6131   PetscFunctionBegin;
6132   if (atol)  *atol  = ts->atol;
6133   if (vatol) *vatol = ts->vatol;
6134   if (rtol)  *rtol  = ts->rtol;
6135   if (vrtol) *vrtol = ts->vrtol;
6136   PetscFunctionReturn(0);
6137 }
6138 
6139 /*@
6140    TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors
6141 
6142    Collective on TS
6143 
6144    Input Arguments:
6145 +  ts - time stepping context
6146 .  U - state vector, usually ts->vec_sol
6147 -  Y - state vector to be compared to U
6148 
6149    Output Arguments:
6150 .  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
6151 .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
6152 .  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
6153 
6154    Level: developer
6155 
6156 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity()
6157 @*/
6158 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6159 {
6160   PetscErrorCode    ierr;
6161   PetscInt          i,n,N,rstart;
6162   PetscInt          n_loc,na_loc,nr_loc;
6163   PetscReal         n_glb,na_glb,nr_glb;
6164   const PetscScalar *u,*y;
6165   PetscReal         sum,suma,sumr,gsum,gsuma,gsumr,diff;
6166   PetscReal         tol,tola,tolr;
6167   PetscReal         err_loc[6],err_glb[6];
6168 
6169   PetscFunctionBegin;
6170   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6171   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
6172   PetscValidHeaderSpecific(Y,VEC_CLASSID,3);
6173   PetscValidType(U,2);
6174   PetscValidType(Y,3);
6175   PetscCheckSameComm(U,2,Y,3);
6176   PetscValidPointer(norm,4);
6177   PetscValidPointer(norma,5);
6178   PetscValidPointer(normr,6);
6179   if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector");
6180 
6181   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
6182   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
6183   ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr);
6184   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
6185   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
6186   sum  = 0.; n_loc  = 0;
6187   suma = 0.; na_loc = 0;
6188   sumr = 0.; nr_loc = 0;
6189   if (ts->vatol && ts->vrtol) {
6190     const PetscScalar *atol,*rtol;
6191     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6192     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6193     for (i=0; i<n; i++) {
6194       diff = PetscAbsScalar(y[i] - u[i]);
6195       tola = PetscRealPart(atol[i]);
6196       if(tola>0.){
6197         suma  += PetscSqr(diff/tola);
6198         na_loc++;
6199       }
6200       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6201       if(tolr>0.){
6202         sumr  += PetscSqr(diff/tolr);
6203         nr_loc++;
6204       }
6205       tol=tola+tolr;
6206       if(tol>0.){
6207         sum  += PetscSqr(diff/tol);
6208         n_loc++;
6209       }
6210     }
6211     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6212     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6213   } else if (ts->vatol) {       /* vector atol, scalar rtol */
6214     const PetscScalar *atol;
6215     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6216     for (i=0; i<n; i++) {
6217       diff = PetscAbsScalar(y[i] - u[i]);
6218       tola = PetscRealPart(atol[i]);
6219       if(tola>0.){
6220         suma  += PetscSqr(diff/tola);
6221         na_loc++;
6222       }
6223       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6224       if(tolr>0.){
6225         sumr  += PetscSqr(diff/tolr);
6226         nr_loc++;
6227       }
6228       tol=tola+tolr;
6229       if(tol>0.){
6230         sum  += PetscSqr(diff/tol);
6231         n_loc++;
6232       }
6233     }
6234     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6235   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
6236     const PetscScalar *rtol;
6237     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6238     for (i=0; i<n; i++) {
6239       diff = PetscAbsScalar(y[i] - u[i]);
6240       tola = ts->atol;
6241       if(tola>0.){
6242         suma  += PetscSqr(diff/tola);
6243         na_loc++;
6244       }
6245       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6246       if(tolr>0.){
6247         sumr  += PetscSqr(diff/tolr);
6248         nr_loc++;
6249       }
6250       tol=tola+tolr;
6251       if(tol>0.){
6252         sum  += PetscSqr(diff/tol);
6253         n_loc++;
6254       }
6255     }
6256     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6257   } else {                      /* scalar atol, scalar rtol */
6258     for (i=0; i<n; i++) {
6259       diff = PetscAbsScalar(y[i] - u[i]);
6260      tola = ts->atol;
6261       if(tola>0.){
6262         suma  += PetscSqr(diff/tola);
6263         na_loc++;
6264       }
6265       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6266       if(tolr>0.){
6267         sumr  += PetscSqr(diff/tolr);
6268         nr_loc++;
6269       }
6270       tol=tola+tolr;
6271       if(tol>0.){
6272         sum  += PetscSqr(diff/tol);
6273         n_loc++;
6274       }
6275     }
6276   }
6277   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
6278   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
6279 
6280   err_loc[0] = sum;
6281   err_loc[1] = suma;
6282   err_loc[2] = sumr;
6283   err_loc[3] = (PetscReal)n_loc;
6284   err_loc[4] = (PetscReal)na_loc;
6285   err_loc[5] = (PetscReal)nr_loc;
6286 
6287   ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6288 
6289   gsum   = err_glb[0];
6290   gsuma  = err_glb[1];
6291   gsumr  = err_glb[2];
6292   n_glb  = err_glb[3];
6293   na_glb = err_glb[4];
6294   nr_glb = err_glb[5];
6295 
6296   *norm  = 0.;
6297   if(n_glb>0. ){*norm  = PetscSqrtReal(gsum  / n_glb );}
6298   *norma = 0.;
6299   if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);}
6300   *normr = 0.;
6301   if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);}
6302 
6303   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
6304   if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
6305   if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
6306   PetscFunctionReturn(0);
6307 }
6308 
6309 /*@
6310    TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors
6311 
6312    Collective on TS
6313 
6314    Input Arguments:
6315 +  ts - time stepping context
6316 .  U - state vector, usually ts->vec_sol
6317 -  Y - state vector to be compared to U
6318 
6319    Output Arguments:
6320 .  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
6321 .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
6322 .  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
6323 
6324    Level: developer
6325 
6326 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2()
6327 @*/
6328 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6329 {
6330   PetscErrorCode    ierr;
6331   PetscInt          i,n,N,rstart;
6332   const PetscScalar *u,*y;
6333   PetscReal         max,gmax,maxa,gmaxa,maxr,gmaxr;
6334   PetscReal         tol,tola,tolr,diff;
6335   PetscReal         err_loc[3],err_glb[3];
6336 
6337   PetscFunctionBegin;
6338   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6339   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
6340   PetscValidHeaderSpecific(Y,VEC_CLASSID,3);
6341   PetscValidType(U,2);
6342   PetscValidType(Y,3);
6343   PetscCheckSameComm(U,2,Y,3);
6344   PetscValidPointer(norm,4);
6345   PetscValidPointer(norma,5);
6346   PetscValidPointer(normr,6);
6347   if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector");
6348 
6349   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
6350   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
6351   ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr);
6352   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
6353   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
6354 
6355   max=0.;
6356   maxa=0.;
6357   maxr=0.;
6358 
6359   if (ts->vatol && ts->vrtol) {     /* vector atol, vector rtol */
6360     const PetscScalar *atol,*rtol;
6361     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6362     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6363 
6364     for (i=0; i<n; i++) {
6365       diff = PetscAbsScalar(y[i] - u[i]);
6366       tola = PetscRealPart(atol[i]);
6367       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6368       tol  = tola+tolr;
6369       if(tola>0.){
6370         maxa = PetscMax(maxa,diff / tola);
6371       }
6372       if(tolr>0.){
6373         maxr = PetscMax(maxr,diff / tolr);
6374       }
6375       if(tol>0.){
6376         max = PetscMax(max,diff / tol);
6377       }
6378     }
6379     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6380     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6381   } else if (ts->vatol) {       /* vector atol, scalar rtol */
6382     const PetscScalar *atol;
6383     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6384     for (i=0; i<n; i++) {
6385       diff = PetscAbsScalar(y[i] - u[i]);
6386       tola = PetscRealPart(atol[i]);
6387       tolr = ts->rtol  * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6388       tol  = tola+tolr;
6389       if(tola>0.){
6390         maxa = PetscMax(maxa,diff / tola);
6391       }
6392       if(tolr>0.){
6393         maxr = PetscMax(maxr,diff / tolr);
6394       }
6395       if(tol>0.){
6396         max = PetscMax(max,diff / tol);
6397       }
6398     }
6399     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6400   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
6401     const PetscScalar *rtol;
6402     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6403 
6404     for (i=0; i<n; i++) {
6405       diff = PetscAbsScalar(y[i] - u[i]);
6406       tola = ts->atol;
6407       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6408       tol  = tola+tolr;
6409       if(tola>0.){
6410         maxa = PetscMax(maxa,diff / tola);
6411       }
6412       if(tolr>0.){
6413         maxr = PetscMax(maxr,diff / tolr);
6414       }
6415       if(tol>0.){
6416         max = PetscMax(max,diff / tol);
6417       }
6418     }
6419     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6420   } else {                      /* scalar atol, scalar rtol */
6421 
6422     for (i=0; i<n; i++) {
6423       diff = PetscAbsScalar(y[i] - u[i]);
6424       tola = ts->atol;
6425       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6426       tol  = tola+tolr;
6427       if(tola>0.){
6428         maxa = PetscMax(maxa,diff / tola);
6429       }
6430       if(tolr>0.){
6431         maxr = PetscMax(maxr,diff / tolr);
6432       }
6433       if(tol>0.){
6434         max = PetscMax(max,diff / tol);
6435       }
6436     }
6437   }
6438   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
6439   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
6440   err_loc[0] = max;
6441   err_loc[1] = maxa;
6442   err_loc[2] = maxr;
6443   ierr  = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6444   gmax   = err_glb[0];
6445   gmaxa  = err_glb[1];
6446   gmaxr  = err_glb[2];
6447 
6448   *norm = gmax;
6449   *norma = gmaxa;
6450   *normr = gmaxr;
6451   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
6452     if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
6453     if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
6454   PetscFunctionReturn(0);
6455 }
6456 
6457 /*@
6458    TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances
6459 
6460    Collective on TS
6461 
6462    Input Arguments:
6463 +  ts - time stepping context
6464 .  U - state vector, usually ts->vec_sol
6465 .  Y - state vector to be compared to U
6466 -  wnormtype - norm type, either NORM_2 or NORM_INFINITY
6467 
6468    Output Arguments:
6469 .  norm  - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances
6470 .  norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user
6471 .  normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user
6472 
6473    Options Database Keys:
6474 .  -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
6475 
6476    Level: developer
6477 
6478 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2(), TSErrorWeightedENorm
6479 @*/
6480 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6481 {
6482   PetscErrorCode ierr;
6483 
6484   PetscFunctionBegin;
6485   if (wnormtype == NORM_2) {
6486     ierr = TSErrorWeightedNorm2(ts,U,Y,norm,norma,normr);CHKERRQ(ierr);
6487   } else if(wnormtype == NORM_INFINITY) {
6488     ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm,norma,normr);CHKERRQ(ierr);
6489   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
6490   PetscFunctionReturn(0);
6491 }
6492 
6493 
6494 /*@
6495    TSErrorWeightedENorm2 - compute a weighted 2 error norm based on supplied absolute and relative tolerances
6496 
6497    Collective on TS
6498 
6499    Input Arguments:
6500 +  ts - time stepping context
6501 .  E - error vector
6502 .  U - state vector, usually ts->vec_sol
6503 -  Y - state vector, previous time step
6504 
6505    Output Arguments:
6506 .  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
6507 .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
6508 .  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
6509 
6510    Level: developer
6511 
6512 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENormInfinity()
6513 @*/
6514 PetscErrorCode TSErrorWeightedENorm2(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6515 {
6516   PetscErrorCode    ierr;
6517   PetscInt          i,n,N,rstart;
6518   PetscInt          n_loc,na_loc,nr_loc;
6519   PetscReal         n_glb,na_glb,nr_glb;
6520   const PetscScalar *e,*u,*y;
6521   PetscReal         err,sum,suma,sumr,gsum,gsuma,gsumr;
6522   PetscReal         tol,tola,tolr;
6523   PetscReal         err_loc[6],err_glb[6];
6524 
6525   PetscFunctionBegin;
6526   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6527   PetscValidHeaderSpecific(E,VEC_CLASSID,2);
6528   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
6529   PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
6530   PetscValidType(E,2);
6531   PetscValidType(U,3);
6532   PetscValidType(Y,4);
6533   PetscCheckSameComm(E,2,U,3);
6534   PetscCheckSameComm(U,2,Y,3);
6535   PetscValidPointer(norm,5);
6536   PetscValidPointer(norma,6);
6537   PetscValidPointer(normr,7);
6538 
6539   ierr = VecGetSize(E,&N);CHKERRQ(ierr);
6540   ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr);
6541   ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr);
6542   ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr);
6543   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
6544   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
6545   sum  = 0.; n_loc  = 0;
6546   suma = 0.; na_loc = 0;
6547   sumr = 0.; nr_loc = 0;
6548   if (ts->vatol && ts->vrtol) {
6549     const PetscScalar *atol,*rtol;
6550     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6551     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6552     for (i=0; i<n; i++) {
6553       err = PetscAbsScalar(e[i]);
6554       tola = PetscRealPart(atol[i]);
6555       if(tola>0.){
6556         suma  += PetscSqr(err/tola);
6557         na_loc++;
6558       }
6559       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6560       if(tolr>0.){
6561         sumr  += PetscSqr(err/tolr);
6562         nr_loc++;
6563       }
6564       tol=tola+tolr;
6565       if(tol>0.){
6566         sum  += PetscSqr(err/tol);
6567         n_loc++;
6568       }
6569     }
6570     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6571     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6572   } else if (ts->vatol) {       /* vector atol, scalar rtol */
6573     const PetscScalar *atol;
6574     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6575     for (i=0; i<n; i++) {
6576       err = PetscAbsScalar(e[i]);
6577       tola = PetscRealPart(atol[i]);
6578       if(tola>0.){
6579         suma  += PetscSqr(err/tola);
6580         na_loc++;
6581       }
6582       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6583       if(tolr>0.){
6584         sumr  += PetscSqr(err/tolr);
6585         nr_loc++;
6586       }
6587       tol=tola+tolr;
6588       if(tol>0.){
6589         sum  += PetscSqr(err/tol);
6590         n_loc++;
6591       }
6592     }
6593     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6594   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
6595     const PetscScalar *rtol;
6596     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6597     for (i=0; i<n; i++) {
6598       err = PetscAbsScalar(e[i]);
6599       tola = ts->atol;
6600       if(tola>0.){
6601         suma  += PetscSqr(err/tola);
6602         na_loc++;
6603       }
6604       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6605       if(tolr>0.){
6606         sumr  += PetscSqr(err/tolr);
6607         nr_loc++;
6608       }
6609       tol=tola+tolr;
6610       if(tol>0.){
6611         sum  += PetscSqr(err/tol);
6612         n_loc++;
6613       }
6614     }
6615     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6616   } else {                      /* scalar atol, scalar rtol */
6617     for (i=0; i<n; i++) {
6618       err = PetscAbsScalar(e[i]);
6619      tola = ts->atol;
6620       if(tola>0.){
6621         suma  += PetscSqr(err/tola);
6622         na_loc++;
6623       }
6624       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6625       if(tolr>0.){
6626         sumr  += PetscSqr(err/tolr);
6627         nr_loc++;
6628       }
6629       tol=tola+tolr;
6630       if(tol>0.){
6631         sum  += PetscSqr(err/tol);
6632         n_loc++;
6633       }
6634     }
6635   }
6636   ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr);
6637   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
6638   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
6639 
6640   err_loc[0] = sum;
6641   err_loc[1] = suma;
6642   err_loc[2] = sumr;
6643   err_loc[3] = (PetscReal)n_loc;
6644   err_loc[4] = (PetscReal)na_loc;
6645   err_loc[5] = (PetscReal)nr_loc;
6646 
6647   ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6648 
6649   gsum   = err_glb[0];
6650   gsuma  = err_glb[1];
6651   gsumr  = err_glb[2];
6652   n_glb  = err_glb[3];
6653   na_glb = err_glb[4];
6654   nr_glb = err_glb[5];
6655 
6656   *norm  = 0.;
6657   if(n_glb>0. ){*norm  = PetscSqrtReal(gsum  / n_glb );}
6658   *norma = 0.;
6659   if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);}
6660   *normr = 0.;
6661   if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);}
6662 
6663   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
6664   if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
6665   if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
6666   PetscFunctionReturn(0);
6667 }
6668 
6669 /*@
6670    TSErrorWeightedENormInfinity - compute a weighted infinity error norm based on supplied absolute and relative tolerances
6671    Collective on TS
6672 
6673    Input Arguments:
6674 +  ts - time stepping context
6675 .  E - error vector
6676 .  U - state vector, usually ts->vec_sol
6677 -  Y - state vector, previous time step
6678 
6679    Output Arguments:
6680 .  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
6681 .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
6682 .  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
6683 
6684    Level: developer
6685 
6686 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENorm2()
6687 @*/
6688 PetscErrorCode TSErrorWeightedENormInfinity(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6689 {
6690   PetscErrorCode    ierr;
6691   PetscInt          i,n,N,rstart;
6692   const PetscScalar *e,*u,*y;
6693   PetscReal         err,max,gmax,maxa,gmaxa,maxr,gmaxr;
6694   PetscReal         tol,tola,tolr;
6695   PetscReal         err_loc[3],err_glb[3];
6696 
6697   PetscFunctionBegin;
6698   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6699   PetscValidHeaderSpecific(E,VEC_CLASSID,2);
6700   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
6701   PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
6702   PetscValidType(E,2);
6703   PetscValidType(U,3);
6704   PetscValidType(Y,4);
6705   PetscCheckSameComm(E,2,U,3);
6706   PetscCheckSameComm(U,2,Y,3);
6707   PetscValidPointer(norm,5);
6708   PetscValidPointer(norma,6);
6709   PetscValidPointer(normr,7);
6710 
6711   ierr = VecGetSize(E,&N);CHKERRQ(ierr);
6712   ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr);
6713   ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr);
6714   ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr);
6715   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
6716   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
6717 
6718   max=0.;
6719   maxa=0.;
6720   maxr=0.;
6721 
6722   if (ts->vatol && ts->vrtol) {     /* vector atol, vector rtol */
6723     const PetscScalar *atol,*rtol;
6724     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6725     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6726 
6727     for (i=0; i<n; i++) {
6728       err = PetscAbsScalar(e[i]);
6729       tola = PetscRealPart(atol[i]);
6730       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6731       tol  = tola+tolr;
6732       if(tola>0.){
6733         maxa = PetscMax(maxa,err / tola);
6734       }
6735       if(tolr>0.){
6736         maxr = PetscMax(maxr,err / tolr);
6737       }
6738       if(tol>0.){
6739         max = PetscMax(max,err / tol);
6740       }
6741     }
6742     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6743     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6744   } else if (ts->vatol) {       /* vector atol, scalar rtol */
6745     const PetscScalar *atol;
6746     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6747     for (i=0; i<n; i++) {
6748       err = PetscAbsScalar(e[i]);
6749       tola = PetscRealPart(atol[i]);
6750       tolr = ts->rtol  * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6751       tol  = tola+tolr;
6752       if(tola>0.){
6753         maxa = PetscMax(maxa,err / tola);
6754       }
6755       if(tolr>0.){
6756         maxr = PetscMax(maxr,err / tolr);
6757       }
6758       if(tol>0.){
6759         max = PetscMax(max,err / tol);
6760       }
6761     }
6762     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6763   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
6764     const PetscScalar *rtol;
6765     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6766 
6767     for (i=0; i<n; i++) {
6768       err = PetscAbsScalar(e[i]);
6769       tola = ts->atol;
6770       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6771       tol  = tola+tolr;
6772       if(tola>0.){
6773         maxa = PetscMax(maxa,err / tola);
6774       }
6775       if(tolr>0.){
6776         maxr = PetscMax(maxr,err / tolr);
6777       }
6778       if(tol>0.){
6779         max = PetscMax(max,err / tol);
6780       }
6781     }
6782     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6783   } else {                      /* scalar atol, scalar rtol */
6784 
6785     for (i=0; i<n; i++) {
6786       err = PetscAbsScalar(e[i]);
6787       tola = ts->atol;
6788       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6789       tol  = tola+tolr;
6790       if(tola>0.){
6791         maxa = PetscMax(maxa,err / tola);
6792       }
6793       if(tolr>0.){
6794         maxr = PetscMax(maxr,err / tolr);
6795       }
6796       if(tol>0.){
6797         max = PetscMax(max,err / tol);
6798       }
6799     }
6800   }
6801   ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr);
6802   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
6803   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
6804   err_loc[0] = max;
6805   err_loc[1] = maxa;
6806   err_loc[2] = maxr;
6807   ierr  = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6808   gmax   = err_glb[0];
6809   gmaxa  = err_glb[1];
6810   gmaxr  = err_glb[2];
6811 
6812   *norm = gmax;
6813   *norma = gmaxa;
6814   *normr = gmaxr;
6815   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
6816     if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
6817     if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
6818   PetscFunctionReturn(0);
6819 }
6820 
6821 /*@
6822    TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances
6823 
6824    Collective on TS
6825 
6826    Input Arguments:
6827 +  ts - time stepping context
6828 .  E - error vector
6829 .  U - state vector, usually ts->vec_sol
6830 .  Y - state vector, previous time step
6831 -  wnormtype - norm type, either NORM_2 or NORM_INFINITY
6832 
6833    Output Arguments:
6834 .  norm  - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances
6835 .  norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user
6836 .  normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user
6837 
6838    Options Database Keys:
6839 .  -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
6840 
6841    Level: developer
6842 
6843 .seealso: TSErrorWeightedENormInfinity(), TSErrorWeightedENorm2(), TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2()
6844 @*/
6845 PetscErrorCode TSErrorWeightedENorm(TS ts,Vec E,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6846 {
6847   PetscErrorCode ierr;
6848 
6849   PetscFunctionBegin;
6850   if (wnormtype == NORM_2) {
6851     ierr = TSErrorWeightedENorm2(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr);
6852   } else if(wnormtype == NORM_INFINITY) {
6853     ierr = TSErrorWeightedENormInfinity(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr);
6854   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
6855   PetscFunctionReturn(0);
6856 }
6857 
6858 
6859 /*@
6860    TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
6861 
6862    Logically Collective on TS
6863 
6864    Input Arguments:
6865 +  ts - time stepping context
6866 -  cfltime - maximum stable time step if using forward Euler (value can be different on each process)
6867 
6868    Note:
6869    After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
6870 
6871    Level: intermediate
6872 
6873 .seealso: TSGetCFLTime(), TSADAPTCFL
6874 @*/
6875 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime)
6876 {
6877   PetscFunctionBegin;
6878   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6879   ts->cfltime_local = cfltime;
6880   ts->cfltime       = -1.;
6881   PetscFunctionReturn(0);
6882 }
6883 
6884 /*@
6885    TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
6886 
6887    Collective on TS
6888 
6889    Input Arguments:
6890 .  ts - time stepping context
6891 
6892    Output Arguments:
6893 .  cfltime - maximum stable time step for forward Euler
6894 
6895    Level: advanced
6896 
6897 .seealso: TSSetCFLTimeLocal()
6898 @*/
6899 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime)
6900 {
6901   PetscErrorCode ierr;
6902 
6903   PetscFunctionBegin;
6904   if (ts->cfltime < 0) {
6905     ierr = MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6906   }
6907   *cfltime = ts->cfltime;
6908   PetscFunctionReturn(0);
6909 }
6910 
6911 /*@
6912    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
6913 
6914    Input Parameters:
6915 .  ts   - the TS context.
6916 .  xl   - lower bound.
6917 .  xu   - upper bound.
6918 
6919    Notes:
6920    If this routine is not called then the lower and upper bounds are set to
6921    PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp().
6922 
6923    Level: advanced
6924 
6925 @*/
6926 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
6927 {
6928   PetscErrorCode ierr;
6929   SNES           snes;
6930 
6931   PetscFunctionBegin;
6932   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
6933   ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr);
6934   PetscFunctionReturn(0);
6935 }
6936 
6937 #if defined(PETSC_HAVE_MATLAB_ENGINE)
6938 #include <mex.h>
6939 
6940 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext;
6941 
6942 /*
6943    TSComputeFunction_Matlab - Calls the function that has been set with
6944                          TSSetFunctionMatlab().
6945 
6946    Collective on TS
6947 
6948    Input Parameters:
6949 +  snes - the TS context
6950 -  u - input vector
6951 
6952    Output Parameter:
6953 .  y - function vector, as set by TSSetFunction()
6954 
6955    Notes:
6956    TSComputeFunction() is typically used within nonlinear solvers
6957    implementations, so most users would not generally call this routine
6958    themselves.
6959 
6960    Level: developer
6961 
6962 .keywords: TS, nonlinear, compute, function
6963 
6964 .seealso: TSSetFunction(), TSGetFunction()
6965 */
6966 PetscErrorCode  TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx)
6967 {
6968   PetscErrorCode  ierr;
6969   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
6970   int             nlhs  = 1,nrhs = 7;
6971   mxArray         *plhs[1],*prhs[7];
6972   long long int   lx = 0,lxdot = 0,ly = 0,ls = 0;
6973 
6974   PetscFunctionBegin;
6975   PetscValidHeaderSpecific(snes,TS_CLASSID,1);
6976   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
6977   PetscValidHeaderSpecific(udot,VEC_CLASSID,4);
6978   PetscValidHeaderSpecific(y,VEC_CLASSID,5);
6979   PetscCheckSameComm(snes,1,u,3);
6980   PetscCheckSameComm(snes,1,y,5);
6981 
6982   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
6983   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
6984   ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr);
6985   ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr);
6986 
6987   prhs[0] =  mxCreateDoubleScalar((double)ls);
6988   prhs[1] =  mxCreateDoubleScalar(time);
6989   prhs[2] =  mxCreateDoubleScalar((double)lx);
6990   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
6991   prhs[4] =  mxCreateDoubleScalar((double)ly);
6992   prhs[5] =  mxCreateString(sctx->funcname);
6993   prhs[6] =  sctx->ctx;
6994   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr);
6995   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
6996   mxDestroyArray(prhs[0]);
6997   mxDestroyArray(prhs[1]);
6998   mxDestroyArray(prhs[2]);
6999   mxDestroyArray(prhs[3]);
7000   mxDestroyArray(prhs[4]);
7001   mxDestroyArray(prhs[5]);
7002   mxDestroyArray(plhs[0]);
7003   PetscFunctionReturn(0);
7004 }
7005 
7006 /*
7007    TSSetFunctionMatlab - Sets the function evaluation routine and function
7008    vector for use by the TS routines in solving ODEs
7009    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
7010 
7011    Logically Collective on TS
7012 
7013    Input Parameters:
7014 +  ts - the TS context
7015 -  func - function evaluation routine
7016 
7017    Calling sequence of func:
7018 $    func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx);
7019 
7020    Level: beginner
7021 
7022 .keywords: TS, nonlinear, set, function
7023 
7024 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
7025 */
7026 PetscErrorCode  TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx)
7027 {
7028   PetscErrorCode  ierr;
7029   TSMatlabContext *sctx;
7030 
7031   PetscFunctionBegin;
7032   /* currently sctx is memory bleed */
7033   ierr = PetscNew(&sctx);CHKERRQ(ierr);
7034   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
7035   /*
7036      This should work, but it doesn't
7037   sctx->ctx = ctx;
7038   mexMakeArrayPersistent(sctx->ctx);
7039   */
7040   sctx->ctx = mxDuplicateArray(ctx);
7041 
7042   ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr);
7043   PetscFunctionReturn(0);
7044 }
7045 
7046 /*
7047    TSComputeJacobian_Matlab - Calls the function that has been set with
7048                          TSSetJacobianMatlab().
7049 
7050    Collective on TS
7051 
7052    Input Parameters:
7053 +  ts - the TS context
7054 .  u - input vector
7055 .  A, B - the matrices
7056 -  ctx - user context
7057 
7058    Level: developer
7059 
7060 .keywords: TS, nonlinear, compute, function
7061 
7062 .seealso: TSSetFunction(), TSGetFunction()
7063 @*/
7064 PetscErrorCode  TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat A,Mat B,void *ctx)
7065 {
7066   PetscErrorCode  ierr;
7067   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
7068   int             nlhs  = 2,nrhs = 9;
7069   mxArray         *plhs[2],*prhs[9];
7070   long long int   lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0;
7071 
7072   PetscFunctionBegin;
7073   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
7074   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
7075 
7076   /* call Matlab function in ctx with arguments u and y */
7077 
7078   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
7079   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
7080   ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr);
7081   ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr);
7082   ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr);
7083 
7084   prhs[0] =  mxCreateDoubleScalar((double)ls);
7085   prhs[1] =  mxCreateDoubleScalar((double)time);
7086   prhs[2] =  mxCreateDoubleScalar((double)lx);
7087   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
7088   prhs[4] =  mxCreateDoubleScalar((double)shift);
7089   prhs[5] =  mxCreateDoubleScalar((double)lA);
7090   prhs[6] =  mxCreateDoubleScalar((double)lB);
7091   prhs[7] =  mxCreateString(sctx->funcname);
7092   prhs[8] =  sctx->ctx;
7093   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr);
7094   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
7095   mxDestroyArray(prhs[0]);
7096   mxDestroyArray(prhs[1]);
7097   mxDestroyArray(prhs[2]);
7098   mxDestroyArray(prhs[3]);
7099   mxDestroyArray(prhs[4]);
7100   mxDestroyArray(prhs[5]);
7101   mxDestroyArray(prhs[6]);
7102   mxDestroyArray(prhs[7]);
7103   mxDestroyArray(plhs[0]);
7104   mxDestroyArray(plhs[1]);
7105   PetscFunctionReturn(0);
7106 }
7107 
7108 /*
7109    TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
7110    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
7111 
7112    Logically Collective on TS
7113 
7114    Input Parameters:
7115 +  ts - the TS context
7116 .  A,B - Jacobian matrices
7117 .  func - function evaluation routine
7118 -  ctx - user context
7119 
7120    Calling sequence of func:
7121 $    flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx);
7122 
7123    Level: developer
7124 
7125 .keywords: TS, nonlinear, set, function
7126 
7127 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
7128 */
7129 PetscErrorCode  TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx)
7130 {
7131   PetscErrorCode  ierr;
7132   TSMatlabContext *sctx;
7133 
7134   PetscFunctionBegin;
7135   /* currently sctx is memory bleed */
7136   ierr = PetscNew(&sctx);CHKERRQ(ierr);
7137   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
7138   /*
7139      This should work, but it doesn't
7140   sctx->ctx = ctx;
7141   mexMakeArrayPersistent(sctx->ctx);
7142   */
7143   sctx->ctx = mxDuplicateArray(ctx);
7144 
7145   ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
7146   PetscFunctionReturn(0);
7147 }
7148 
7149 /*
7150    TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab().
7151 
7152    Collective on TS
7153 
7154 .seealso: TSSetFunction(), TSGetFunction()
7155 @*/
7156 PetscErrorCode  TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx)
7157 {
7158   PetscErrorCode  ierr;
7159   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
7160   int             nlhs  = 1,nrhs = 6;
7161   mxArray         *plhs[1],*prhs[6];
7162   long long int   lx = 0,ls = 0;
7163 
7164   PetscFunctionBegin;
7165   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
7166   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
7167 
7168   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
7169   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
7170 
7171   prhs[0] =  mxCreateDoubleScalar((double)ls);
7172   prhs[1] =  mxCreateDoubleScalar((double)it);
7173   prhs[2] =  mxCreateDoubleScalar((double)time);
7174   prhs[3] =  mxCreateDoubleScalar((double)lx);
7175   prhs[4] =  mxCreateString(sctx->funcname);
7176   prhs[5] =  sctx->ctx;
7177   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr);
7178   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
7179   mxDestroyArray(prhs[0]);
7180   mxDestroyArray(prhs[1]);
7181   mxDestroyArray(prhs[2]);
7182   mxDestroyArray(prhs[3]);
7183   mxDestroyArray(prhs[4]);
7184   mxDestroyArray(plhs[0]);
7185   PetscFunctionReturn(0);
7186 }
7187 
7188 /*
7189    TSMonitorSetMatlab - Sets the monitor function from Matlab
7190 
7191    Level: developer
7192 
7193 .keywords: TS, nonlinear, set, function
7194 
7195 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
7196 */
7197 PetscErrorCode  TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx)
7198 {
7199   PetscErrorCode  ierr;
7200   TSMatlabContext *sctx;
7201 
7202   PetscFunctionBegin;
7203   /* currently sctx is memory bleed */
7204   ierr = PetscNew(&sctx);CHKERRQ(ierr);
7205   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
7206   /*
7207      This should work, but it doesn't
7208   sctx->ctx = ctx;
7209   mexMakeArrayPersistent(sctx->ctx);
7210   */
7211   sctx->ctx = mxDuplicateArray(ctx);
7212 
7213   ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr);
7214   PetscFunctionReturn(0);
7215 }
7216 #endif
7217 
7218 /*@C
7219    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
7220        in a time based line graph
7221 
7222    Collective on TS
7223 
7224    Input Parameters:
7225 +  ts - the TS context
7226 .  step - current time-step
7227 .  ptime - current time
7228 .  u - current solution
7229 -  dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate()
7230 
7231    Options Database:
7232 .   -ts_monitor_lg_solution_variables
7233 
7234    Level: intermediate
7235 
7236    Notes: Each process in a parallel run displays its component solutions in a separate window
7237 
7238 .keywords: TS,  vector, monitor, view
7239 
7240 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
7241            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
7242            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
7243            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()
7244 @*/
7245 PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
7246 {
7247   PetscErrorCode    ierr;
7248   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dctx;
7249   const PetscScalar *yy;
7250   Vec               v;
7251 
7252   PetscFunctionBegin;
7253   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
7254   if (!step) {
7255     PetscDrawAxis axis;
7256     PetscInt      dim;
7257     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
7258     ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr);
7259     if (!ctx->names) {
7260       PetscBool flg;
7261       /* user provides names of variables to plot but no names has been set so assume names are integer values */
7262       ierr = PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg);CHKERRQ(ierr);
7263       if (flg) {
7264         PetscInt i,n;
7265         char     **names;
7266         ierr = VecGetSize(u,&n);CHKERRQ(ierr);
7267         ierr = PetscMalloc1(n+1,&names);CHKERRQ(ierr);
7268         for (i=0; i<n; i++) {
7269           ierr = PetscMalloc1(5,&names[i]);CHKERRQ(ierr);
7270           ierr = PetscSNPrintf(names[i],5,"%D",i);CHKERRQ(ierr);
7271         }
7272         names[n] = NULL;
7273         ctx->names = names;
7274       }
7275     }
7276     if (ctx->names && !ctx->displaynames) {
7277       char      **displaynames;
7278       PetscBool flg;
7279       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
7280       ierr = PetscMalloc1(dim+1,&displaynames);CHKERRQ(ierr);
7281       ierr = PetscMemzero(displaynames,(dim+1)*sizeof(char*));CHKERRQ(ierr);
7282       ierr = PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr);
7283       if (flg) {
7284         ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr);
7285       }
7286       ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr);
7287     }
7288     if (ctx->displaynames) {
7289       ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr);
7290       ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr);
7291     } else if (ctx->names) {
7292       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
7293       ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
7294       ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr);
7295     } else {
7296       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
7297       ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
7298     }
7299     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
7300   }
7301 
7302   if (!ctx->transform) v = u;
7303   else {ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);}
7304   ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr);
7305   if (ctx->displaynames) {
7306     PetscInt i;
7307     for (i=0; i<ctx->ndisplayvariables; i++)
7308       ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]);
7309     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr);
7310   } else {
7311 #if defined(PETSC_USE_COMPLEX)
7312     PetscInt  i,n;
7313     PetscReal *yreal;
7314     ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
7315     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
7316     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
7317     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
7318     ierr = PetscFree(yreal);CHKERRQ(ierr);
7319 #else
7320     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
7321 #endif
7322   }
7323   ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr);
7324   if (ctx->transform) {ierr = VecDestroy(&v);CHKERRQ(ierr);}
7325 
7326   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
7327     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7328     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7329   }
7330   PetscFunctionReturn(0);
7331 }
7332 
7333 /*@C
7334    TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
7335 
7336    Collective on TS
7337 
7338    Input Parameters:
7339 +  ts - the TS context
7340 -  names - the names of the components, final string must be NULL
7341 
7342    Level: intermediate
7343 
7344    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
7345 
7346 .keywords: TS,  vector, monitor, view
7347 
7348 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames()
7349 @*/
7350 PetscErrorCode  TSMonitorLGSetVariableNames(TS ts,const char * const *names)
7351 {
7352   PetscErrorCode    ierr;
7353   PetscInt          i;
7354 
7355   PetscFunctionBegin;
7356   for (i=0; i<ts->numbermonitors; i++) {
7357     if (ts->monitor[i] == TSMonitorLGSolution) {
7358       ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr);
7359       break;
7360     }
7361   }
7362   PetscFunctionReturn(0);
7363 }
7364 
7365 /*@C
7366    TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
7367 
7368    Collective on TS
7369 
7370    Input Parameters:
7371 +  ts - the TS context
7372 -  names - the names of the components, final string must be NULL
7373 
7374    Level: intermediate
7375 
7376 .keywords: TS,  vector, monitor, view
7377 
7378 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames()
7379 @*/
7380 PetscErrorCode  TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names)
7381 {
7382   PetscErrorCode    ierr;
7383 
7384   PetscFunctionBegin;
7385   ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr);
7386   ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr);
7387   PetscFunctionReturn(0);
7388 }
7389 
7390 /*@C
7391    TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot
7392 
7393    Collective on TS
7394 
7395    Input Parameter:
7396 .  ts - the TS context
7397 
7398    Output Parameter:
7399 .  names - the names of the components, final string must be NULL
7400 
7401    Level: intermediate
7402 
7403    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
7404 
7405 .keywords: TS,  vector, monitor, view
7406 
7407 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
7408 @*/
7409 PetscErrorCode  TSMonitorLGGetVariableNames(TS ts,const char *const **names)
7410 {
7411   PetscInt       i;
7412 
7413   PetscFunctionBegin;
7414   *names = NULL;
7415   for (i=0; i<ts->numbermonitors; i++) {
7416     if (ts->monitor[i] == TSMonitorLGSolution) {
7417       TSMonitorLGCtx  ctx = (TSMonitorLGCtx) ts->monitorcontext[i];
7418       *names = (const char *const *)ctx->names;
7419       break;
7420     }
7421   }
7422   PetscFunctionReturn(0);
7423 }
7424 
7425 /*@C
7426    TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor
7427 
7428    Collective on TS
7429 
7430    Input Parameters:
7431 +  ctx - the TSMonitorLG context
7432 .  displaynames - the names of the components, final string must be NULL
7433 
7434    Level: intermediate
7435 
7436 .keywords: TS,  vector, monitor, view
7437 
7438 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
7439 @*/
7440 PetscErrorCode  TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames)
7441 {
7442   PetscInt          j = 0,k;
7443   PetscErrorCode    ierr;
7444 
7445   PetscFunctionBegin;
7446   if (!ctx->names) PetscFunctionReturn(0);
7447   ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr);
7448   ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr);
7449   while (displaynames[j]) j++;
7450   ctx->ndisplayvariables = j;
7451   ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr);
7452   ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr);
7453   j = 0;
7454   while (displaynames[j]) {
7455     k = 0;
7456     while (ctx->names[k]) {
7457       PetscBool flg;
7458       ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr);
7459       if (flg) {
7460         ctx->displayvariables[j] = k;
7461         break;
7462       }
7463       k++;
7464     }
7465     j++;
7466   }
7467   PetscFunctionReturn(0);
7468 }
7469 
7470 /*@C
7471    TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor
7472 
7473    Collective on TS
7474 
7475    Input Parameters:
7476 +  ts - the TS context
7477 .  displaynames - the names of the components, final string must be NULL
7478 
7479    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
7480 
7481    Level: intermediate
7482 
7483 .keywords: TS,  vector, monitor, view
7484 
7485 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
7486 @*/
7487 PetscErrorCode  TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames)
7488 {
7489   PetscInt          i;
7490   PetscErrorCode    ierr;
7491 
7492   PetscFunctionBegin;
7493   for (i=0; i<ts->numbermonitors; i++) {
7494     if (ts->monitor[i] == TSMonitorLGSolution) {
7495       ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr);
7496       break;
7497     }
7498   }
7499   PetscFunctionReturn(0);
7500 }
7501 
7502 /*@C
7503    TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed
7504 
7505    Collective on TS
7506 
7507    Input Parameters:
7508 +  ts - the TS context
7509 .  transform - the transform function
7510 .  destroy - function to destroy the optional context
7511 -  ctx - optional context used by transform function
7512 
7513    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
7514 
7515    Level: intermediate
7516 
7517 .keywords: TS,  vector, monitor, view
7518 
7519 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform()
7520 @*/
7521 PetscErrorCode  TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
7522 {
7523   PetscInt          i;
7524   PetscErrorCode    ierr;
7525 
7526   PetscFunctionBegin;
7527   for (i=0; i<ts->numbermonitors; i++) {
7528     if (ts->monitor[i] == TSMonitorLGSolution) {
7529       ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr);
7530     }
7531   }
7532   PetscFunctionReturn(0);
7533 }
7534 
7535 /*@C
7536    TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed
7537 
7538    Collective on TSLGCtx
7539 
7540    Input Parameters:
7541 +  ts - the TS context
7542 .  transform - the transform function
7543 .  destroy - function to destroy the optional context
7544 -  ctx - optional context used by transform function
7545 
7546    Level: intermediate
7547 
7548 .keywords: TS,  vector, monitor, view
7549 
7550 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform()
7551 @*/
7552 PetscErrorCode  TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
7553 {
7554   PetscFunctionBegin;
7555   ctx->transform    = transform;
7556   ctx->transformdestroy = destroy;
7557   ctx->transformctx = tctx;
7558   PetscFunctionReturn(0);
7559 }
7560 
7561 /*@C
7562    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error
7563        in a time based line graph
7564 
7565    Collective on TS
7566 
7567    Input Parameters:
7568 +  ts - the TS context
7569 .  step - current time-step
7570 .  ptime - current time
7571 .  u - current solution
7572 -  dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate()
7573 
7574    Level: intermediate
7575 
7576    Notes: Each process in a parallel run displays its component errors in a separate window
7577 
7578    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
7579 
7580    Options Database Keys:
7581 .  -ts_monitor_lg_error - create a graphical monitor of error history
7582 
7583 .keywords: TS,  vector, monitor, view
7584 
7585 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
7586 @*/
7587 PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
7588 {
7589   PetscErrorCode    ierr;
7590   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
7591   const PetscScalar *yy;
7592   Vec               y;
7593 
7594   PetscFunctionBegin;
7595   if (!step) {
7596     PetscDrawAxis axis;
7597     PetscInt      dim;
7598     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
7599     ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Error");CHKERRQ(ierr);
7600     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
7601     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
7602     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
7603   }
7604   ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
7605   ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr);
7606   ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr);
7607   ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr);
7608 #if defined(PETSC_USE_COMPLEX)
7609   {
7610     PetscReal *yreal;
7611     PetscInt  i,n;
7612     ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr);
7613     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
7614     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
7615     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
7616     ierr = PetscFree(yreal);CHKERRQ(ierr);
7617   }
7618 #else
7619   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
7620 #endif
7621   ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr);
7622   ierr = VecDestroy(&y);CHKERRQ(ierr);
7623   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
7624     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7625     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7626   }
7627   PetscFunctionReturn(0);
7628 }
7629 
7630 /*@C
7631    TSMonitorError - Monitors progress of the TS solvers by printing the 2 norm of the error at each timestep
7632 
7633    Collective on TS
7634 
7635    Input Parameters:
7636 +  ts - the TS context
7637 .  step - current time-step
7638 .  ptime - current time
7639 .  u - current solution
7640 -  dctx - unused context
7641 
7642    Level: intermediate
7643 
7644    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
7645 
7646    Options Database Keys:
7647 .  -ts_monitor_error - create a graphical monitor of error history
7648 
7649 .keywords: TS,  vector, monitor, view
7650 
7651 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
7652 @*/
7653 PetscErrorCode  TSMonitorError(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
7654 {
7655   PetscErrorCode    ierr;
7656   Vec               y;
7657   PetscReal         nrm;
7658   PetscBool         flg;
7659 
7660   PetscFunctionBegin;
7661   ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
7662   ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr);
7663   ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr);
7664   ierr = PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERASCII,&flg);CHKERRQ(ierr);
7665   if (flg) {
7666     ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
7667     ierr = PetscViewerASCIIPrintf(vf->viewer,"2-norm of error %g\n",(double)nrm);CHKERRQ(ierr);
7668   }
7669   ierr = PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERDRAW,&flg);CHKERRQ(ierr);
7670   if (flg) {
7671     ierr = VecView(y,vf->viewer);CHKERRQ(ierr);
7672   }
7673   ierr = VecDestroy(&y);CHKERRQ(ierr);
7674   PetscFunctionReturn(0);
7675 }
7676 
7677 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
7678 {
7679   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
7680   PetscReal      x   = ptime,y;
7681   PetscErrorCode ierr;
7682   PetscInt       its;
7683 
7684   PetscFunctionBegin;
7685   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
7686   if (!n) {
7687     PetscDrawAxis axis;
7688     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
7689     ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr);
7690     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
7691     ctx->snes_its = 0;
7692   }
7693   ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr);
7694   y    = its - ctx->snes_its;
7695   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
7696   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
7697     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7698     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7699   }
7700   ctx->snes_its = its;
7701   PetscFunctionReturn(0);
7702 }
7703 
7704 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
7705 {
7706   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
7707   PetscReal      x   = ptime,y;
7708   PetscErrorCode ierr;
7709   PetscInt       its;
7710 
7711   PetscFunctionBegin;
7712   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
7713   if (!n) {
7714     PetscDrawAxis axis;
7715     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
7716     ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr);
7717     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
7718     ctx->ksp_its = 0;
7719   }
7720   ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr);
7721   y    = its - ctx->ksp_its;
7722   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
7723   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
7724     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7725     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7726   }
7727   ctx->ksp_its = its;
7728   PetscFunctionReturn(0);
7729 }
7730 
7731 /*@
7732    TSComputeLinearStability - computes the linear stability function at a point
7733 
7734    Collective on TS and Vec
7735 
7736    Input Parameters:
7737 +  ts - the TS context
7738 -  xr,xi - real and imaginary part of input arguments
7739 
7740    Output Parameters:
7741 .  yr,yi - real and imaginary part of function value
7742 
7743    Level: developer
7744 
7745 .keywords: TS, compute
7746 
7747 .seealso: TSSetRHSFunction(), TSComputeIFunction()
7748 @*/
7749 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi)
7750 {
7751   PetscErrorCode ierr;
7752 
7753   PetscFunctionBegin;
7754   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
7755   if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method");
7756   ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr);
7757   PetscFunctionReturn(0);
7758 }
7759 
7760 /* ------------------------------------------------------------------------*/
7761 /*@C
7762    TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope()
7763 
7764    Collective on TS
7765 
7766    Input Parameters:
7767 .  ts  - the ODE solver object
7768 
7769    Output Parameter:
7770 .  ctx - the context
7771 
7772    Level: intermediate
7773 
7774 .keywords: TS, monitor, line graph, residual, seealso
7775 
7776 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError()
7777 
7778 @*/
7779 PetscErrorCode  TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx)
7780 {
7781   PetscErrorCode ierr;
7782 
7783   PetscFunctionBegin;
7784   ierr = PetscNew(ctx);CHKERRQ(ierr);
7785   PetscFunctionReturn(0);
7786 }
7787 
7788 /*@C
7789    TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution
7790 
7791    Collective on TS
7792 
7793    Input Parameters:
7794 +  ts - the TS context
7795 .  step - current time-step
7796 .  ptime - current time
7797 .  u  - current solution
7798 -  dctx - the envelope context
7799 
7800    Options Database:
7801 .  -ts_monitor_envelope
7802 
7803    Level: intermediate
7804 
7805    Notes: after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope
7806 
7807 .keywords: TS,  vector, monitor, view
7808 
7809 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate()
7810 @*/
7811 PetscErrorCode  TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
7812 {
7813   PetscErrorCode       ierr;
7814   TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx;
7815 
7816   PetscFunctionBegin;
7817   if (!ctx->max) {
7818     ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr);
7819     ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr);
7820     ierr = VecCopy(u,ctx->max);CHKERRQ(ierr);
7821     ierr = VecCopy(u,ctx->min);CHKERRQ(ierr);
7822   } else {
7823     ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr);
7824     ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr);
7825   }
7826   PetscFunctionReturn(0);
7827 }
7828 
7829 /*@C
7830    TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution
7831 
7832    Collective on TS
7833 
7834    Input Parameter:
7835 .  ts - the TS context
7836 
7837    Output Parameter:
7838 +  max - the maximum values
7839 -  min - the minimum values
7840 
7841    Notes: If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored
7842 
7843    Level: intermediate
7844 
7845 .keywords: TS,  vector, monitor, view
7846 
7847 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
7848 @*/
7849 PetscErrorCode  TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min)
7850 {
7851   PetscInt i;
7852 
7853   PetscFunctionBegin;
7854   if (max) *max = NULL;
7855   if (min) *min = NULL;
7856   for (i=0; i<ts->numbermonitors; i++) {
7857     if (ts->monitor[i] == TSMonitorEnvelope) {
7858       TSMonitorEnvelopeCtx  ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i];
7859       if (max) *max = ctx->max;
7860       if (min) *min = ctx->min;
7861       break;
7862     }
7863   }
7864   PetscFunctionReturn(0);
7865 }
7866 
7867 /*@C
7868    TSMonitorEnvelopeCtxDestroy - Destroys a context that was created  with TSMonitorEnvelopeCtxCreate().
7869 
7870    Collective on TSMonitorEnvelopeCtx
7871 
7872    Input Parameter:
7873 .  ctx - the monitor context
7874 
7875    Level: intermediate
7876 
7877 .keywords: TS, monitor, line graph, destroy
7878 
7879 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep()
7880 @*/
7881 PetscErrorCode  TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx)
7882 {
7883   PetscErrorCode ierr;
7884 
7885   PetscFunctionBegin;
7886   ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr);
7887   ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr);
7888   ierr = PetscFree(*ctx);CHKERRQ(ierr);
7889   PetscFunctionReturn(0);
7890 }
7891 
7892 /*@
7893    TSRestartStep - Flags the solver to restart the next step
7894 
7895    Collective on TS
7896 
7897    Input Parameter:
7898 .  ts - the TS context obtained from TSCreate()
7899 
7900    Level: advanced
7901 
7902    Notes:
7903    Multistep methods like BDF or Runge-Kutta methods with FSAL property require restarting the solver in the event of
7904    discontinuities. These discontinuities may be introduced as a consequence of explicitly modifications to the solution
7905    vector (which PETSc attempts to detect and handle) or problem coefficients (which PETSc is not able to detect). For
7906    the sake of correctness and maximum safety, users are expected to call TSRestart() whenever they introduce
7907    discontinuities in callback routines (e.g. prestep and poststep routines, or implicit/rhs function routines with
7908    discontinuous source terms).
7909 
7910 .keywords: TS, timestep, restart
7911 
7912 .seealso: TSSolve(), TSSetPreStep(), TSSetPostStep()
7913 @*/
7914 PetscErrorCode TSRestartStep(TS ts)
7915 {
7916   PetscFunctionBegin;
7917   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
7918   ts->steprestart = PETSC_TRUE;
7919   PetscFunctionReturn(0);
7920 }
7921 
7922 /*@
7923    TSRollBack - Rolls back one time step
7924 
7925    Collective on TS
7926 
7927    Input Parameter:
7928 .  ts - the TS context obtained from TSCreate()
7929 
7930    Level: advanced
7931 
7932 .keywords: TS, timestep, rollback
7933 
7934 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate()
7935 @*/
7936 PetscErrorCode  TSRollBack(TS ts)
7937 {
7938   PetscErrorCode ierr;
7939 
7940   PetscFunctionBegin;
7941   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
7942   if (ts->steprollback) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TSRollBack already called");
7943   if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name);
7944   ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr);
7945   ts->time_step = ts->ptime - ts->ptime_prev;
7946   ts->ptime = ts->ptime_prev;
7947   ts->ptime_prev = ts->ptime_prev_rollback;
7948   ts->steps--;
7949   ts->steprollback = PETSC_TRUE;
7950   PetscFunctionReturn(0);
7951 }
7952 
7953 /*@
7954    TSGetStages - Get the number of stages and stage values
7955 
7956    Input Parameter:
7957 .  ts - the TS context obtained from TSCreate()
7958 
7959    Level: advanced
7960 
7961 .keywords: TS, getstages
7962 
7963 .seealso: TSCreate()
7964 @*/
7965 PetscErrorCode  TSGetStages(TS ts,PetscInt *ns,Vec **Y)
7966 {
7967   PetscErrorCode ierr;
7968 
7969   PetscFunctionBegin;
7970   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
7971   PetscValidPointer(ns,2);
7972 
7973   if (!ts->ops->getstages) *ns=0;
7974   else {
7975     ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr);
7976   }
7977   PetscFunctionReturn(0);
7978 }
7979 
7980 /*@C
7981   TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity.
7982 
7983   Collective on SNES
7984 
7985   Input Parameters:
7986 + ts - the TS context
7987 . t - current timestep
7988 . U - state vector
7989 . Udot - time derivative of state vector
7990 . shift - shift to apply, see note below
7991 - ctx - an optional user context
7992 
7993   Output Parameters:
7994 + J - Jacobian matrix (not altered in this routine)
7995 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J)
7996 
7997   Level: intermediate
7998 
7999   Notes:
8000   If F(t,U,Udot)=0 is the DAE, the required Jacobian is
8001 
8002   dF/dU + shift*dF/dUdot
8003 
8004   Most users should not need to explicitly call this routine, as it
8005   is used internally within the nonlinear solvers.
8006 
8007   This will first try to get the coloring from the DM.  If the DM type has no coloring
8008   routine, then it will try to get the coloring from the matrix.  This requires that the
8009   matrix have nonzero entries precomputed.
8010 
8011 .keywords: TS, finite differences, Jacobian, coloring, sparse
8012 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction()
8013 @*/
8014 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx)
8015 {
8016   SNES           snes;
8017   MatFDColoring  color;
8018   PetscBool      hascolor, matcolor = PETSC_FALSE;
8019   PetscErrorCode ierr;
8020 
8021   PetscFunctionBegin;
8022   ierr = PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr);
8023   ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr);
8024   if (!color) {
8025     DM         dm;
8026     ISColoring iscoloring;
8027 
8028     ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
8029     ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr);
8030     if (hascolor && !matcolor) {
8031       ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr);
8032       ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr);
8033       ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr);
8034       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
8035       ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr);
8036       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
8037     } else {
8038       MatColoring mc;
8039 
8040       ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr);
8041       ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr);
8042       ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr);
8043       ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr);
8044       ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr);
8045       ierr = MatColoringDestroy(&mc);CHKERRQ(ierr);
8046       ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr);
8047       ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr);
8048       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
8049       ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr);
8050       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
8051     }
8052     ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr);
8053     ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr);
8054   }
8055   ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr);
8056   ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr);
8057   if (J != B) {
8058     ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
8059     ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
8060   }
8061   PetscFunctionReturn(0);
8062 }
8063 
8064 /*@
8065     TSSetFunctionDomainError - Set the function testing if the current state vector is valid
8066 
8067     Input Parameters:
8068     ts - the TS context
8069     func - function called within TSFunctionDomainError
8070 
8071     Level: intermediate
8072 
8073 .keywords: TS, state, domain
8074 .seealso: TSAdaptCheckStage(), TSFunctionDomainError()
8075 @*/
8076 
8077 PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*))
8078 {
8079   PetscFunctionBegin;
8080   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
8081   ts->functiondomainerror = func;
8082   PetscFunctionReturn(0);
8083 }
8084 
8085 /*@
8086     TSFunctionDomainError - Check if the current state is valid
8087 
8088     Input Parameters:
8089     ts - the TS context
8090     stagetime - time of the simulation
8091     Y - state vector to check.
8092 
8093     Output Parameter:
8094     accept - Set to PETSC_FALSE if the current state vector is valid.
8095 
8096     Note:
8097     This function should be used to ensure the state is in a valid part of the space.
8098     For example, one can ensure here all values are positive.
8099 
8100     Level: advanced
8101 @*/
8102 PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept)
8103 {
8104   PetscErrorCode ierr;
8105 
8106   PetscFunctionBegin;
8107 
8108   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
8109   *accept = PETSC_TRUE;
8110   if (ts->functiondomainerror) {
8111     PetscStackCallStandard((*ts->functiondomainerror),(ts,stagetime,Y,accept));
8112   }
8113   PetscFunctionReturn(0);
8114 }
8115 
8116 /*@C
8117   TSClone - This function clones a time step object.
8118 
8119   Collective on MPI_Comm
8120 
8121   Input Parameter:
8122 . tsin    - The input TS
8123 
8124   Output Parameter:
8125 . tsout   - The output TS (cloned)
8126 
8127   Notes:
8128   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.
8129 
8130   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);
8131 
8132   Level: developer
8133 
8134 .keywords: TS, clone
8135 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType()
8136 @*/
8137 PetscErrorCode  TSClone(TS tsin, TS *tsout)
8138 {
8139   TS             t;
8140   PetscErrorCode ierr;
8141   SNES           snes_start;
8142   DM             dm;
8143   TSType         type;
8144 
8145   PetscFunctionBegin;
8146   PetscValidPointer(tsin,1);
8147   *tsout = NULL;
8148 
8149   ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr);
8150 
8151   /* General TS description */
8152   t->numbermonitors    = 0;
8153   t->setupcalled       = 0;
8154   t->ksp_its           = 0;
8155   t->snes_its          = 0;
8156   t->nwork             = 0;
8157   t->rhsjacobian.time  = -1e20;
8158   t->rhsjacobian.scale = 1.;
8159   t->ijacobian.shift   = 1.;
8160 
8161   ierr = TSGetSNES(tsin,&snes_start);CHKERRQ(ierr);
8162   ierr = TSSetSNES(t,snes_start);CHKERRQ(ierr);
8163 
8164   ierr = TSGetDM(tsin,&dm);CHKERRQ(ierr);
8165   ierr = TSSetDM(t,dm);CHKERRQ(ierr);
8166 
8167   t->adapt = tsin->adapt;
8168   ierr = PetscObjectReference((PetscObject)t->adapt);CHKERRQ(ierr);
8169 
8170   t->trajectory = tsin->trajectory;
8171   ierr = PetscObjectReference((PetscObject)t->trajectory);CHKERRQ(ierr);
8172 
8173   t->event = tsin->event;
8174   if (t->event) t->event->refct++;
8175 
8176   t->problem_type      = tsin->problem_type;
8177   t->ptime             = tsin->ptime;
8178   t->ptime_prev        = tsin->ptime_prev;
8179   t->time_step         = tsin->time_step;
8180   t->max_time          = tsin->max_time;
8181   t->steps             = tsin->steps;
8182   t->max_steps         = tsin->max_steps;
8183   t->equation_type     = tsin->equation_type;
8184   t->atol              = tsin->atol;
8185   t->rtol              = tsin->rtol;
8186   t->max_snes_failures = tsin->max_snes_failures;
8187   t->max_reject        = tsin->max_reject;
8188   t->errorifstepfailed = tsin->errorifstepfailed;
8189 
8190   ierr = TSGetType(tsin,&type);CHKERRQ(ierr);
8191   ierr = TSSetType(t,type);CHKERRQ(ierr);
8192 
8193   t->vec_sol           = NULL;
8194 
8195   t->cfltime          = tsin->cfltime;
8196   t->cfltime_local    = tsin->cfltime_local;
8197   t->exact_final_time = tsin->exact_final_time;
8198 
8199   ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr);
8200 
8201   if (((PetscObject)tsin)->fortran_func_pointers) {
8202     PetscInt i;
8203     ierr = PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers);CHKERRQ(ierr);
8204     for (i=0; i<10; i++) {
8205       ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i];
8206     }
8207   }
8208   *tsout = t;
8209   PetscFunctionReturn(0);
8210 }
8211 
8212 static PetscErrorCode RHSWrapperFunction_TSRHSJacobianTest(void* ctx,Vec x,Vec y)
8213 {
8214   PetscErrorCode ierr;
8215   TS             ts = (TS) ctx;
8216 
8217   PetscFunctionBegin;
8218   ierr = TSComputeRHSFunction(ts,0,x,y);CHKERRQ(ierr);
8219   PetscFunctionReturn(0);
8220 }
8221 
8222 /*@
8223     TSRHSJacobianTest - Compares the multiply routine provided to the MATSHELL with differencing on the TS given RHS function.
8224 
8225    Logically Collective on TS and Mat
8226 
8227     Input Parameters:
8228     TS - the time stepping routine
8229 
8230    Output Parameter:
8231 .   flg - PETSC_TRUE if the multiply is likely correct
8232 
8233    Options Database:
8234  .   -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - run the test at each timestep of the integrator
8235 
8236    Level: advanced
8237 
8238    Notes: This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian
8239 
8240 .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellTestMultTranspose(), TSRHSJacobianTestTranspose()
8241 @*/
8242 PetscErrorCode  TSRHSJacobianTest(TS ts,PetscBool *flg)
8243 {
8244   Mat            J,B;
8245   PetscErrorCode ierr;
8246   TSRHSJacobian  func;
8247   void*          ctx;
8248 
8249   PetscFunctionBegin;
8250   ierr = TSGetRHSJacobian(ts,&J,&B,&func,&ctx);CHKERRQ(ierr);
8251   ierr = (*func)(ts,0.0,ts->vec_sol,J,B,ctx);CHKERRQ(ierr);
8252   ierr = MatShellTestMult(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg);CHKERRQ(ierr);
8253   PetscFunctionReturn(0);
8254 }
8255 
8256 /*@C
8257     TSRHSJacobianTestTranspose - Compares the multiply transpose routine provided to the MATSHELL with differencing on the TS given RHS function.
8258 
8259    Logically Collective on TS and Mat
8260 
8261     Input Parameters:
8262     TS - the time stepping routine
8263 
8264    Output Parameter:
8265 .   flg - PETSC_TRUE if the multiply is likely correct
8266 
8267    Options Database:
8268 .   -ts_rhs_jacobian_test_mult_transpose -mat_shell_test_mult_transpose_view - run the test at each timestep of the integrator
8269 
8270    Notes: This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian
8271 
8272    Level: advanced
8273 
8274 .seealso: MatCreateShell(), MatShellGetContext(), MatShellGetOperation(), MatShellTestMultTranspose(), TSRHSJacobianTest()
8275 @*/
8276 PetscErrorCode  TSRHSJacobianTestTranspose(TS ts,PetscBool *flg)
8277 {
8278   Mat            J,B;
8279   PetscErrorCode ierr;
8280   void           *ctx;
8281   TSRHSJacobian  func;
8282 
8283   PetscFunctionBegin;
8284   ierr = TSGetRHSJacobian(ts,&J,&B,&func,&ctx);CHKERRQ(ierr);
8285   ierr = (*func)(ts,0.0,ts->vec_sol,J,B,ctx);CHKERRQ(ierr);
8286   ierr = MatShellTestMultTranspose(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg);CHKERRQ(ierr);
8287   PetscFunctionReturn(0);
8288 }
8289