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