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