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