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