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