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