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