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