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