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