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