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