xref: /petsc/src/ts/interface/ts.c (revision 96a0c9949c19278363492ba7462c3ac2a88a3ed1)
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 = PetscViewerSetFormat(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 = PetscViewerSetFormat(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 = VecViewFromOptions(ts->vecs_sensi[0],(PetscObject) ts, "-ts_adjoint_view_solution");CHKERRQ(ierr);
3604   PetscFunctionReturn(0);
3605 }
3606 
3607 #undef __FUNCT__
3608 #define __FUNCT__ "TSMonitor"
3609 /*@C
3610    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()
3611 
3612    Collective on TS
3613 
3614    Input Parameters:
3615 +  ts - time stepping context obtained from TSCreate()
3616 .  step - step number that has just completed
3617 .  ptime - model time of the state
3618 -  u - state at the current model time
3619 
3620    Notes:
3621    TSMonitor() is typically used automatically within the time stepping implementations.
3622    Users would almost never call this routine directly.
3623 
3624    Level: developer
3625 
3626 .keywords: TS, timestep
3627 @*/
3628 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u)
3629 {
3630   PetscErrorCode ierr;
3631   PetscInt       i,n = ts->numbermonitors;
3632 
3633   PetscFunctionBegin;
3634   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3635   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
3636   ierr = VecLockPush(u);CHKERRQ(ierr);
3637   for (i=0; i<n; i++) {
3638     ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr);
3639   }
3640   ierr = VecLockPop(u);CHKERRQ(ierr);
3641   PetscFunctionReturn(0);
3642 }
3643 
3644 #undef __FUNCT__
3645 #define __FUNCT__ "TSAdjointMonitor"
3646 /*@C
3647    TSAdjointMonitor - Runs all user-provided adjoint monitor routines set using TSAdjointMonitorSet()
3648 
3649    Collective on TS
3650 
3651    Input Parameters:
3652 +  ts - time stepping context obtained from TSCreate()
3653 .  step - step number that has just completed
3654 .  ptime - model time of the state
3655 .  u - state at the current model time
3656 .  numcost - number of cost functions (dimension of lambda  or mu)
3657 .  lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables
3658 -  mu - vectors containing the gradients of the cost functions with respect to the problem parameters
3659 
3660    Notes:
3661    TSAdjointMonitor() is typically used automatically within the time stepping implementations.
3662    Users would almost never call this routine directly.
3663 
3664    Level: developer
3665 
3666 .keywords: TS, timestep
3667 @*/
3668 PetscErrorCode TSAdjointMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda, Vec *mu)
3669 {
3670   PetscErrorCode ierr;
3671   PetscInt       i,n = ts->numberadjointmonitors;
3672 
3673   PetscFunctionBegin;
3674   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3675   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
3676   ierr = VecLockPush(u);CHKERRQ(ierr);
3677   for (i=0; i<n; i++) {
3678     ierr = (*ts->adjointmonitor[i])(ts,step,ptime,u,numcost,lambda,mu,ts->adjointmonitorcontext[i]);CHKERRQ(ierr);
3679   }
3680   ierr = VecLockPop(u);CHKERRQ(ierr);
3681   PetscFunctionReturn(0);
3682 }
3683 
3684 /* ------------------------------------------------------------------------*/
3685 #undef __FUNCT__
3686 #define __FUNCT__ "TSMonitorLGCtxCreate"
3687 /*@C
3688    TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with
3689    TS to monitor the solution process graphically in various ways
3690 
3691    Collective on TS
3692 
3693    Input Parameters:
3694 +  host - the X display to open, or null for the local machine
3695 .  label - the title to put in the title bar
3696 .  x, y - the screen coordinates of the upper left coordinate of the window
3697 .  m, n - the screen width and height in pixels
3698 -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
3699 
3700    Output Parameter:
3701 .  ctx - the context
3702 
3703    Options Database Key:
3704 +  -ts_monitor_lg_timestep - automatically sets line graph monitor
3705 .  -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables())
3706 .  -ts_monitor_lg_error -  monitor the error
3707 .  -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep
3708 .  -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep
3709 -  -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true
3710 
3711    Notes:
3712    Use TSMonitorLGCtxDestroy() to destroy.
3713 
3714    One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform()
3715 
3716    Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the
3717    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
3718    as the first argument.
3719 
3720    One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames()
3721 
3722 
3723    Level: intermediate
3724 
3725 .keywords: TS, monitor, line graph, residual
3726 
3727 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(),
3728            TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
3729            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
3730            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
3731            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()
3732 
3733 @*/
3734 PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
3735 {
3736   PetscDraw      draw;
3737   PetscErrorCode ierr;
3738 
3739   PetscFunctionBegin;
3740   ierr = PetscNew(ctx);CHKERRQ(ierr);
3741   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr);
3742   ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr);
3743   ierr = PetscDrawLGCreate(draw,1,&(*ctx)->lg);CHKERRQ(ierr);
3744   ierr = PetscDrawLGSetUseMarkers((*ctx)->lg,PETSC_TRUE);CHKERRQ(ierr);
3745   ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr);
3746   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
3747   (*ctx)->howoften = howoften;
3748   PetscFunctionReturn(0);
3749 }
3750 
3751 #undef __FUNCT__
3752 #define __FUNCT__ "TSMonitorLGTimeStep"
3753 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx)
3754 {
3755   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
3756   PetscReal      x   = ptime,y;
3757   PetscErrorCode ierr;
3758 
3759   PetscFunctionBegin;
3760   if (!step) {
3761     PetscDrawAxis axis;
3762     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
3763     ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time","Time step");CHKERRQ(ierr);
3764     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
3765   }
3766   ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr);
3767   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
3768   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
3769     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
3770   }
3771   PetscFunctionReturn(0);
3772 }
3773 
3774 #undef __FUNCT__
3775 #define __FUNCT__ "TSMonitorLGCtxDestroy"
3776 /*@C
3777    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
3778    with TSMonitorLGCtxCreate().
3779 
3780    Collective on TSMonitorLGCtx
3781 
3782    Input Parameter:
3783 .  ctx - the monitor context
3784 
3785    Level: intermediate
3786 
3787 .keywords: TS, monitor, line graph, destroy
3788 
3789 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep();
3790 @*/
3791 PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
3792 {
3793   PetscErrorCode ierr;
3794 
3795   PetscFunctionBegin;
3796   if ((*ctx)->transformdestroy) {
3797     ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr);
3798   }
3799   ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr);
3800   ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr);
3801   ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr);
3802   ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr);
3803   ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr);
3804   ierr = PetscFree(*ctx);CHKERRQ(ierr);
3805   PetscFunctionReturn(0);
3806 }
3807 
3808 #undef __FUNCT__
3809 #define __FUNCT__ "TSGetTime"
3810 /*@
3811    TSGetTime - Gets the time of the most recently completed step.
3812 
3813    Not Collective
3814 
3815    Input Parameter:
3816 .  ts - the TS context obtained from TSCreate()
3817 
3818    Output Parameter:
3819 .  t  - the current time
3820 
3821    Level: beginner
3822 
3823    Note:
3824    When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(),
3825    TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated.
3826 
3827 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
3828 
3829 .keywords: TS, get, time
3830 @*/
3831 PetscErrorCode  TSGetTime(TS ts,PetscReal *t)
3832 {
3833   PetscFunctionBegin;
3834   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3835   PetscValidRealPointer(t,2);
3836   *t = ts->ptime;
3837   PetscFunctionReturn(0);
3838 }
3839 
3840 #undef __FUNCT__
3841 #define __FUNCT__ "TSGetPrevTime"
3842 /*@
3843    TSGetPrevTime - Gets the starting time of the previously completed step.
3844 
3845    Not Collective
3846 
3847    Input Parameter:
3848 .  ts - the TS context obtained from TSCreate()
3849 
3850    Output Parameter:
3851 .  t  - the previous time
3852 
3853    Level: beginner
3854 
3855 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
3856 
3857 .keywords: TS, get, time
3858 @*/
3859 PetscErrorCode  TSGetPrevTime(TS ts,PetscReal *t)
3860 {
3861   PetscFunctionBegin;
3862   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3863   PetscValidRealPointer(t,2);
3864   *t = ts->ptime_prev;
3865   PetscFunctionReturn(0);
3866 }
3867 
3868 #undef __FUNCT__
3869 #define __FUNCT__ "TSSetTime"
3870 /*@
3871    TSSetTime - Allows one to reset the time.
3872 
3873    Logically Collective on TS
3874 
3875    Input Parameters:
3876 +  ts - the TS context obtained from TSCreate()
3877 -  time - the time
3878 
3879    Level: intermediate
3880 
3881 .seealso: TSGetTime(), TSSetDuration()
3882 
3883 .keywords: TS, set, time
3884 @*/
3885 PetscErrorCode  TSSetTime(TS ts, PetscReal t)
3886 {
3887   PetscFunctionBegin;
3888   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3889   PetscValidLogicalCollectiveReal(ts,t,2);
3890   ts->ptime = t;
3891   PetscFunctionReturn(0);
3892 }
3893 
3894 #undef __FUNCT__
3895 #define __FUNCT__ "TSSetOptionsPrefix"
3896 /*@C
3897    TSSetOptionsPrefix - Sets the prefix used for searching for all
3898    TS options in the database.
3899 
3900    Logically Collective on TS
3901 
3902    Input Parameter:
3903 +  ts     - The TS context
3904 -  prefix - The prefix to prepend to all option names
3905 
3906    Notes:
3907    A hyphen (-) must NOT be given at the beginning of the prefix name.
3908    The first character of all runtime options is AUTOMATICALLY the
3909    hyphen.
3910 
3911    Level: advanced
3912 
3913 .keywords: TS, set, options, prefix, database
3914 
3915 .seealso: TSSetFromOptions()
3916 
3917 @*/
3918 PetscErrorCode  TSSetOptionsPrefix(TS ts,const char prefix[])
3919 {
3920   PetscErrorCode ierr;
3921   SNES           snes;
3922 
3923   PetscFunctionBegin;
3924   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3925   ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
3926   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3927   ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr);
3928   PetscFunctionReturn(0);
3929 }
3930 
3931 
3932 #undef __FUNCT__
3933 #define __FUNCT__ "TSAppendOptionsPrefix"
3934 /*@C
3935    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
3936    TS options in the database.
3937 
3938    Logically Collective on TS
3939 
3940    Input Parameter:
3941 +  ts     - The TS context
3942 -  prefix - The prefix to prepend to all option names
3943 
3944    Notes:
3945    A hyphen (-) must NOT be given at the beginning of the prefix name.
3946    The first character of all runtime options is AUTOMATICALLY the
3947    hyphen.
3948 
3949    Level: advanced
3950 
3951 .keywords: TS, append, options, prefix, database
3952 
3953 .seealso: TSGetOptionsPrefix()
3954 
3955 @*/
3956 PetscErrorCode  TSAppendOptionsPrefix(TS ts,const char prefix[])
3957 {
3958   PetscErrorCode ierr;
3959   SNES           snes;
3960 
3961   PetscFunctionBegin;
3962   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3963   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
3964   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3965   ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr);
3966   PetscFunctionReturn(0);
3967 }
3968 
3969 #undef __FUNCT__
3970 #define __FUNCT__ "TSGetOptionsPrefix"
3971 /*@C
3972    TSGetOptionsPrefix - Sets the prefix used for searching for all
3973    TS options in the database.
3974 
3975    Not Collective
3976 
3977    Input Parameter:
3978 .  ts - The TS context
3979 
3980    Output Parameter:
3981 .  prefix - A pointer to the prefix string used
3982 
3983    Notes: On the fortran side, the user should pass in a string 'prifix' of
3984    sufficient length to hold the prefix.
3985 
3986    Level: intermediate
3987 
3988 .keywords: TS, get, options, prefix, database
3989 
3990 .seealso: TSAppendOptionsPrefix()
3991 @*/
3992 PetscErrorCode  TSGetOptionsPrefix(TS ts,const char *prefix[])
3993 {
3994   PetscErrorCode ierr;
3995 
3996   PetscFunctionBegin;
3997   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3998   PetscValidPointer(prefix,2);
3999   ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
4000   PetscFunctionReturn(0);
4001 }
4002 
4003 #undef __FUNCT__
4004 #define __FUNCT__ "TSGetRHSJacobian"
4005 /*@C
4006    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
4007 
4008    Not Collective, but parallel objects are returned if TS is parallel
4009 
4010    Input Parameter:
4011 .  ts  - The TS context obtained from TSCreate()
4012 
4013    Output Parameters:
4014 +  Amat - The (approximate) Jacobian J of G, where U_t = G(U,t)  (or NULL)
4015 .  Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat  (or NULL)
4016 .  func - Function to compute the Jacobian of the RHS  (or NULL)
4017 -  ctx - User-defined context for Jacobian evaluation routine  (or NULL)
4018 
4019    Notes: You can pass in NULL for any return argument you do not need.
4020 
4021    Level: intermediate
4022 
4023 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
4024 
4025 .keywords: TS, timestep, get, matrix, Jacobian
4026 @*/
4027 PetscErrorCode  TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx)
4028 {
4029   PetscErrorCode ierr;
4030   SNES           snes;
4031   DM             dm;
4032 
4033   PetscFunctionBegin;
4034   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4035   ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
4036   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4037   ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr);
4038   PetscFunctionReturn(0);
4039 }
4040 
4041 #undef __FUNCT__
4042 #define __FUNCT__ "TSGetIJacobian"
4043 /*@C
4044    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
4045 
4046    Not Collective, but parallel objects are returned if TS is parallel
4047 
4048    Input Parameter:
4049 .  ts  - The TS context obtained from TSCreate()
4050 
4051    Output Parameters:
4052 +  Amat  - The (approximate) Jacobian of F(t,U,U_t)
4053 .  Pmat - The matrix from which the preconditioner is constructed, often the same as Amat
4054 .  f   - The function to compute the matrices
4055 - ctx - User-defined context for Jacobian evaluation routine
4056 
4057    Notes: You can pass in NULL for any return argument you do not need.
4058 
4059    Level: advanced
4060 
4061 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
4062 
4063 .keywords: TS, timestep, get, matrix, Jacobian
4064 @*/
4065 PetscErrorCode  TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx)
4066 {
4067   PetscErrorCode ierr;
4068   SNES           snes;
4069   DM             dm;
4070 
4071   PetscFunctionBegin;
4072   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4073   ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
4074   ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
4075   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4076   ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr);
4077   PetscFunctionReturn(0);
4078 }
4079 
4080 
4081 #undef __FUNCT__
4082 #define __FUNCT__ "TSMonitorDrawSolution"
4083 /*@C
4084    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
4085    VecView() for the solution at each timestep
4086 
4087    Collective on TS
4088 
4089    Input Parameters:
4090 +  ts - the TS context
4091 .  step - current time-step
4092 .  ptime - current time
4093 -  dummy - either a viewer or NULL
4094 
4095    Options Database:
4096 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
4097 
4098    Notes: the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
4099        will look bad
4100 
4101    Level: intermediate
4102 
4103 .keywords: TS,  vector, monitor, view
4104 
4105 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4106 @*/
4107 PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4108 {
4109   PetscErrorCode   ierr;
4110   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
4111   PetscDraw        draw;
4112 
4113   PetscFunctionBegin;
4114   if (!step && ictx->showinitial) {
4115     if (!ictx->initialsolution) {
4116       ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr);
4117     }
4118     ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr);
4119   }
4120   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
4121 
4122   if (ictx->showinitial) {
4123     PetscReal pause;
4124     ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr);
4125     ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr);
4126     ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr);
4127     ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr);
4128     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr);
4129   }
4130   ierr = VecView(u,ictx->viewer);CHKERRQ(ierr);
4131   if (ictx->showtimestepandtime) {
4132     PetscReal xl,yl,xr,yr,h;
4133     char      time[32];
4134 
4135     ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
4136     ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
4137     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
4138     h    = yl + .95*(yr - yl);
4139     ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
4140     ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
4141   }
4142 
4143   if (ictx->showinitial) {
4144     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr);
4145   }
4146   PetscFunctionReturn(0);
4147 }
4148 
4149 #undef __FUNCT__
4150 #define __FUNCT__ "TSAdjointMonitorDrawSensi"
4151 /*@C
4152    TSAdjointMonitorDrawSensi - Monitors progress of the adjoint TS solvers by calling
4153    VecView() for the sensitivities to initial states at each timestep
4154 
4155    Collective on TS
4156 
4157    Input Parameters:
4158 +  ts - the TS context
4159 .  step - current time-step
4160 .  ptime - current time
4161 .  u - current state
4162 .  numcost - number of cost functions
4163 .  lambda - sensitivities to initial conditions
4164 .  mu - sensitivities to parameters
4165 -  dummy - either a viewer or NULL
4166 
4167    Level: intermediate
4168 
4169 .keywords: TS,  vector, adjoint, monitor, view
4170 
4171 .seealso: TSAdjointMonitorSet(), TSAdjointMonitorDefault(), VecView()
4172 @*/
4173 PetscErrorCode  TSAdjointMonitorDrawSensi(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda,Vec *mu,void *dummy)
4174 {
4175   PetscErrorCode   ierr;
4176   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
4177   PetscDraw        draw;
4178   PetscReal        xl,yl,xr,yr,h;
4179   char             time[32];
4180 
4181   PetscFunctionBegin;
4182   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
4183 
4184   ierr = VecView(lambda[0],ictx->viewer);CHKERRQ(ierr);
4185   ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
4186   ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
4187   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
4188   h    = yl + .95*(yr - yl);
4189   ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
4190   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
4191 
4192   PetscFunctionReturn(0);
4193 }
4194 
4195 #undef __FUNCT__
4196 #define __FUNCT__ "TSMonitorDrawSolutionPhase"
4197 /*@C
4198    TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram
4199 
4200    Collective on TS
4201 
4202    Input Parameters:
4203 +  ts - the TS context
4204 .  step - current time-step
4205 .  ptime - current time
4206 -  dummy - either a viewer or NULL
4207 
4208    Level: intermediate
4209 
4210 .keywords: TS,  vector, monitor, view
4211 
4212 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4213 @*/
4214 PetscErrorCode  TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4215 {
4216   PetscErrorCode    ierr;
4217   TSMonitorDrawCtx  ictx = (TSMonitorDrawCtx)dummy;
4218   PetscDraw         draw;
4219   MPI_Comm          comm;
4220   PetscInt          n;
4221   PetscMPIInt       size;
4222   PetscReal         xl,yl,xr,yr,h;
4223   char              time[32];
4224   const PetscScalar *U;
4225 
4226   PetscFunctionBegin;
4227   ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr);
4228   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
4229   if (size != 1) SETERRQ(comm,PETSC_ERR_SUP,"Only allowed for sequential runs");
4230   ierr = VecGetSize(u,&n);CHKERRQ(ierr);
4231   if (n != 2) SETERRQ(comm,PETSC_ERR_SUP,"Only for ODEs with two unknowns");
4232 
4233   ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
4234 
4235   ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr);
4236   ierr = PetscDrawAxisGetLimits(ictx->axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr);
4237   if ((PetscRealPart(U[0]) < xl) || (PetscRealPart(U[1]) < yl) || (PetscRealPart(U[0]) > xr) || (PetscRealPart(U[1]) > yr)) {
4238       ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr);
4239       PetscFunctionReturn(0);
4240   }
4241   if (!step) ictx->color++;
4242   ierr = PetscDrawPoint(draw,PetscRealPart(U[0]),PetscRealPart(U[1]),ictx->color);CHKERRQ(ierr);
4243   ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr);
4244 
4245   if (ictx->showtimestepandtime) {
4246     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
4247     ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
4248     h    = yl + .95*(yr - yl);
4249     ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
4250   }
4251   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
4252   PetscFunctionReturn(0);
4253 }
4254 
4255 
4256 #undef __FUNCT__
4257 #define __FUNCT__ "TSMonitorDrawCtxDestroy"
4258 /*@C
4259    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
4260 
4261    Collective on TS
4262 
4263    Input Parameters:
4264 .    ctx - the monitor context
4265 
4266    Level: intermediate
4267 
4268 .keywords: TS,  vector, monitor, view
4269 
4270 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError()
4271 @*/
4272 PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
4273 {
4274   PetscErrorCode ierr;
4275 
4276   PetscFunctionBegin;
4277   ierr = PetscDrawAxisDestroy(&(*ictx)->axis);CHKERRQ(ierr);
4278   ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr);
4279   ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr);
4280   ierr = PetscFree(*ictx);CHKERRQ(ierr);
4281   PetscFunctionReturn(0);
4282 }
4283 
4284 #undef __FUNCT__
4285 #define __FUNCT__ "TSMonitorDrawCtxCreate"
4286 /*@C
4287    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
4288 
4289    Collective on TS
4290 
4291    Input Parameter:
4292 .    ts - time-step context
4293 
4294    Output Patameter:
4295 .    ctx - the monitor context
4296 
4297    Options Database:
4298 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
4299 
4300    Level: intermediate
4301 
4302 .keywords: TS,  vector, monitor, view
4303 
4304 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx()
4305 @*/
4306 PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
4307 {
4308   PetscErrorCode   ierr;
4309 
4310   PetscFunctionBegin;
4311   ierr = PetscNew(ctx);CHKERRQ(ierr);
4312   ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr);
4313   ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr);
4314 
4315   (*ctx)->howoften    = howoften;
4316   (*ctx)->showinitial = PETSC_FALSE;
4317   ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr);
4318 
4319   (*ctx)->showtimestepandtime = PETSC_FALSE;
4320   ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr);
4321   (*ctx)->color = PETSC_DRAW_WHITE;
4322   PetscFunctionReturn(0);
4323 }
4324 
4325 #undef __FUNCT__
4326 #define __FUNCT__ "TSMonitorDrawError"
4327 /*@C
4328    TSMonitorDrawError - Monitors progress of the TS solvers by calling
4329    VecView() for the error at each timestep
4330 
4331    Collective on TS
4332 
4333    Input Parameters:
4334 +  ts - the TS context
4335 .  step - current time-step
4336 .  ptime - current time
4337 -  dummy - either a viewer or NULL
4338 
4339    Level: intermediate
4340 
4341 .keywords: TS,  vector, monitor, view
4342 
4343 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4344 @*/
4345 PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4346 {
4347   PetscErrorCode   ierr;
4348   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
4349   PetscViewer      viewer = ctx->viewer;
4350   Vec              work;
4351 
4352   PetscFunctionBegin;
4353   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
4354   ierr = VecDuplicate(u,&work);CHKERRQ(ierr);
4355   ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr);
4356   ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr);
4357   ierr = VecView(work,viewer);CHKERRQ(ierr);
4358   ierr = VecDestroy(&work);CHKERRQ(ierr);
4359   PetscFunctionReturn(0);
4360 }
4361 
4362 #include <petsc/private/dmimpl.h>
4363 #undef __FUNCT__
4364 #define __FUNCT__ "TSSetDM"
4365 /*@
4366    TSSetDM - Sets the DM that may be used by some preconditioners
4367 
4368    Logically Collective on TS and DM
4369 
4370    Input Parameters:
4371 +  ts - the preconditioner context
4372 -  dm - the dm
4373 
4374    Level: intermediate
4375 
4376 
4377 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM()
4378 @*/
4379 PetscErrorCode  TSSetDM(TS ts,DM dm)
4380 {
4381   PetscErrorCode ierr;
4382   SNES           snes;
4383   DMTS           tsdm;
4384 
4385   PetscFunctionBegin;
4386   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4387   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
4388   if (ts->dm) {               /* Move the DMTS context over to the new DM unless the new DM already has one */
4389     if (ts->dm->dmts && !dm->dmts) {
4390       ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr);
4391       ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr);
4392       if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */
4393         tsdm->originaldm = dm;
4394       }
4395     }
4396     ierr = DMDestroy(&ts->dm);CHKERRQ(ierr);
4397   }
4398   ts->dm = dm;
4399 
4400   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4401   ierr = SNESSetDM(snes,dm);CHKERRQ(ierr);
4402   PetscFunctionReturn(0);
4403 }
4404 
4405 #undef __FUNCT__
4406 #define __FUNCT__ "TSGetDM"
4407 /*@
4408    TSGetDM - Gets the DM that may be used by some preconditioners
4409 
4410    Not Collective
4411 
4412    Input Parameter:
4413 . ts - the preconditioner context
4414 
4415    Output Parameter:
4416 .  dm - the dm
4417 
4418    Level: intermediate
4419 
4420 
4421 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM()
4422 @*/
4423 PetscErrorCode  TSGetDM(TS ts,DM *dm)
4424 {
4425   PetscErrorCode ierr;
4426 
4427   PetscFunctionBegin;
4428   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4429   if (!ts->dm) {
4430     ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr);
4431     if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
4432   }
4433   *dm = ts->dm;
4434   PetscFunctionReturn(0);
4435 }
4436 
4437 #undef __FUNCT__
4438 #define __FUNCT__ "SNESTSFormFunction"
4439 /*@
4440    SNESTSFormFunction - Function to evaluate nonlinear residual
4441 
4442    Logically Collective on SNES
4443 
4444    Input Parameter:
4445 + snes - nonlinear solver
4446 . U - the current state at which to evaluate the residual
4447 - ctx - user context, must be a TS
4448 
4449    Output Parameter:
4450 . F - the nonlinear residual
4451 
4452    Notes:
4453    This function is not normally called by users and is automatically registered with the SNES used by TS.
4454    It is most frequently passed to MatFDColoringSetFunction().
4455 
4456    Level: advanced
4457 
4458 .seealso: SNESSetFunction(), MatFDColoringSetFunction()
4459 @*/
4460 PetscErrorCode  SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx)
4461 {
4462   TS             ts = (TS)ctx;
4463   PetscErrorCode ierr;
4464 
4465   PetscFunctionBegin;
4466   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4467   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
4468   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
4469   PetscValidHeaderSpecific(ts,TS_CLASSID,4);
4470   ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr);
4471   PetscFunctionReturn(0);
4472 }
4473 
4474 #undef __FUNCT__
4475 #define __FUNCT__ "SNESTSFormJacobian"
4476 /*@
4477    SNESTSFormJacobian - Function to evaluate the Jacobian
4478 
4479    Collective on SNES
4480 
4481    Input Parameter:
4482 + snes - nonlinear solver
4483 . U - the current state at which to evaluate the residual
4484 - ctx - user context, must be a TS
4485 
4486    Output Parameter:
4487 + A - the Jacobian
4488 . B - the preconditioning matrix (may be the same as A)
4489 - flag - indicates any structure change in the matrix
4490 
4491    Notes:
4492    This function is not normally called by users and is automatically registered with the SNES used by TS.
4493 
4494    Level: developer
4495 
4496 .seealso: SNESSetJacobian()
4497 @*/
4498 PetscErrorCode  SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx)
4499 {
4500   TS             ts = (TS)ctx;
4501   PetscErrorCode ierr;
4502 
4503   PetscFunctionBegin;
4504   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4505   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
4506   PetscValidPointer(A,3);
4507   PetscValidHeaderSpecific(A,MAT_CLASSID,3);
4508   PetscValidPointer(B,4);
4509   PetscValidHeaderSpecific(B,MAT_CLASSID,4);
4510   PetscValidHeaderSpecific(ts,TS_CLASSID,6);
4511   ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr);
4512   PetscFunctionReturn(0);
4513 }
4514 
4515 #undef __FUNCT__
4516 #define __FUNCT__ "TSComputeRHSFunctionLinear"
4517 /*@C
4518    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only
4519 
4520    Collective on TS
4521 
4522    Input Arguments:
4523 +  ts - time stepping context
4524 .  t - time at which to evaluate
4525 .  U - state at which to evaluate
4526 -  ctx - context
4527 
4528    Output Arguments:
4529 .  F - right hand side
4530 
4531    Level: intermediate
4532 
4533    Notes:
4534    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
4535    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().
4536 
4537 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
4538 @*/
4539 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx)
4540 {
4541   PetscErrorCode ierr;
4542   Mat            Arhs,Brhs;
4543 
4544   PetscFunctionBegin;
4545   ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
4546   ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr);
4547   ierr = MatMult(Arhs,U,F);CHKERRQ(ierr);
4548   PetscFunctionReturn(0);
4549 }
4550 
4551 #undef __FUNCT__
4552 #define __FUNCT__ "TSComputeRHSJacobianConstant"
4553 /*@C
4554    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
4555 
4556    Collective on TS
4557 
4558    Input Arguments:
4559 +  ts - time stepping context
4560 .  t - time at which to evaluate
4561 .  U - state at which to evaluate
4562 -  ctx - context
4563 
4564    Output Arguments:
4565 +  A - pointer to operator
4566 .  B - pointer to preconditioning matrix
4567 -  flg - matrix structure flag
4568 
4569    Level: intermediate
4570 
4571    Notes:
4572    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.
4573 
4574 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear()
4575 @*/
4576 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx)
4577 {
4578   PetscFunctionBegin;
4579   PetscFunctionReturn(0);
4580 }
4581 
4582 #undef __FUNCT__
4583 #define __FUNCT__ "TSComputeIFunctionLinear"
4584 /*@C
4585    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
4586 
4587    Collective on TS
4588 
4589    Input Arguments:
4590 +  ts - time stepping context
4591 .  t - time at which to evaluate
4592 .  U - state at which to evaluate
4593 .  Udot - time derivative of state vector
4594 -  ctx - context
4595 
4596    Output Arguments:
4597 .  F - left hand side
4598 
4599    Level: intermediate
4600 
4601    Notes:
4602    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
4603    user is required to write their own TSComputeIFunction.
4604    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
4605    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().
4606 
4607    Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U
4608 
4609 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant(), TSComputeRHSFunctionLinear()
4610 @*/
4611 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx)
4612 {
4613   PetscErrorCode ierr;
4614   Mat            A,B;
4615 
4616   PetscFunctionBegin;
4617   ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr);
4618   ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr);
4619   ierr = MatMult(A,Udot,F);CHKERRQ(ierr);
4620   PetscFunctionReturn(0);
4621 }
4622 
4623 #undef __FUNCT__
4624 #define __FUNCT__ "TSComputeIJacobianConstant"
4625 /*@C
4626    TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE
4627 
4628    Collective on TS
4629 
4630    Input Arguments:
4631 +  ts - time stepping context
4632 .  t - time at which to evaluate
4633 .  U - state at which to evaluate
4634 .  Udot - time derivative of state vector
4635 .  shift - shift to apply
4636 -  ctx - context
4637 
4638    Output Arguments:
4639 +  A - pointer to operator
4640 .  B - pointer to preconditioning matrix
4641 -  flg - matrix structure flag
4642 
4643    Level: advanced
4644 
4645    Notes:
4646    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.
4647 
4648    It is only appropriate for problems of the form
4649 
4650 $     M Udot = F(U,t)
4651 
4652   where M is constant and F is non-stiff.  The user must pass M to TSSetIJacobian().  The current implementation only
4653   works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing
4654   an implicit operator of the form
4655 
4656 $    shift*M + J
4657 
4658   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
4659   a copy of M or reassemble it when requested.
4660 
4661 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear()
4662 @*/
4663 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx)
4664 {
4665   PetscErrorCode ierr;
4666 
4667   PetscFunctionBegin;
4668   ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr);
4669   ts->ijacobian.shift = shift;
4670   PetscFunctionReturn(0);
4671 }
4672 
4673 #undef __FUNCT__
4674 #define __FUNCT__ "TSGetEquationType"
4675 /*@
4676    TSGetEquationType - Gets the type of the equation that TS is solving.
4677 
4678    Not Collective
4679 
4680    Input Parameter:
4681 .  ts - the TS context
4682 
4683    Output Parameter:
4684 .  equation_type - see TSEquationType
4685 
4686    Level: beginner
4687 
4688 .keywords: TS, equation type
4689 
4690 .seealso: TSSetEquationType(), TSEquationType
4691 @*/
4692 PetscErrorCode  TSGetEquationType(TS ts,TSEquationType *equation_type)
4693 {
4694   PetscFunctionBegin;
4695   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4696   PetscValidPointer(equation_type,2);
4697   *equation_type = ts->equation_type;
4698   PetscFunctionReturn(0);
4699 }
4700 
4701 #undef __FUNCT__
4702 #define __FUNCT__ "TSSetEquationType"
4703 /*@
4704    TSSetEquationType - Sets the type of the equation that TS is solving.
4705 
4706    Not Collective
4707 
4708    Input Parameter:
4709 +  ts - the TS context
4710 -  equation_type - see TSEquationType
4711 
4712    Level: advanced
4713 
4714 .keywords: TS, equation type
4715 
4716 .seealso: TSGetEquationType(), TSEquationType
4717 @*/
4718 PetscErrorCode  TSSetEquationType(TS ts,TSEquationType equation_type)
4719 {
4720   PetscFunctionBegin;
4721   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4722   ts->equation_type = equation_type;
4723   PetscFunctionReturn(0);
4724 }
4725 
4726 #undef __FUNCT__
4727 #define __FUNCT__ "TSGetConvergedReason"
4728 /*@
4729    TSGetConvergedReason - Gets the reason the TS iteration was stopped.
4730 
4731    Not Collective
4732 
4733    Input Parameter:
4734 .  ts - the TS context
4735 
4736    Output Parameter:
4737 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
4738             manual pages for the individual convergence tests for complete lists
4739 
4740    Level: beginner
4741 
4742    Notes:
4743    Can only be called after the call to TSSolve() is complete.
4744 
4745 .keywords: TS, nonlinear, set, convergence, test
4746 
4747 .seealso: TSSetConvergenceTest(), TSConvergedReason
4748 @*/
4749 PetscErrorCode  TSGetConvergedReason(TS ts,TSConvergedReason *reason)
4750 {
4751   PetscFunctionBegin;
4752   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4753   PetscValidPointer(reason,2);
4754   *reason = ts->reason;
4755   PetscFunctionReturn(0);
4756 }
4757 
4758 #undef __FUNCT__
4759 #define __FUNCT__ "TSSetConvergedReason"
4760 /*@
4761    TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve.
4762 
4763    Not Collective
4764 
4765    Input Parameter:
4766 +  ts - the TS context
4767 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
4768             manual pages for the individual convergence tests for complete lists
4769 
4770    Level: advanced
4771 
4772    Notes:
4773    Can only be called during TSSolve() is active.
4774 
4775 .keywords: TS, nonlinear, set, convergence, test
4776 
4777 .seealso: TSConvergedReason
4778 @*/
4779 PetscErrorCode  TSSetConvergedReason(TS ts,TSConvergedReason reason)
4780 {
4781   PetscFunctionBegin;
4782   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4783   ts->reason = reason;
4784   PetscFunctionReturn(0);
4785 }
4786 
4787 #undef __FUNCT__
4788 #define __FUNCT__ "TSGetSolveTime"
4789 /*@
4790    TSGetSolveTime - Gets the time after a call to TSSolve()
4791 
4792    Not Collective
4793 
4794    Input Parameter:
4795 .  ts - the TS context
4796 
4797    Output Parameter:
4798 .  ftime - the final time. This time should correspond to the final time set with TSSetDuration()
4799 
4800    Level: beginner
4801 
4802    Notes:
4803    Can only be called after the call to TSSolve() is complete.
4804 
4805 .keywords: TS, nonlinear, set, convergence, test
4806 
4807 .seealso: TSSetConvergenceTest(), TSConvergedReason
4808 @*/
4809 PetscErrorCode  TSGetSolveTime(TS ts,PetscReal *ftime)
4810 {
4811   PetscFunctionBegin;
4812   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4813   PetscValidPointer(ftime,2);
4814   *ftime = ts->solvetime;
4815   PetscFunctionReturn(0);
4816 }
4817 
4818 #undef __FUNCT__
4819 #define __FUNCT__ "TSGetTotalSteps"
4820 /*@
4821    TSGetTotalSteps - Gets the total number of steps done since the last call to TSSetUp() or TSCreate()
4822 
4823    Not Collective
4824 
4825    Input Parameter:
4826 .  ts - the TS context
4827 
4828    Output Parameter:
4829 .  steps - the number of steps
4830 
4831    Level: beginner
4832 
4833    Notes:
4834    Includes the number of steps for all calls to TSSolve() since TSSetUp() was called
4835 
4836 .keywords: TS, nonlinear, set, convergence, test
4837 
4838 .seealso: TSSetConvergenceTest(), TSConvergedReason
4839 @*/
4840 PetscErrorCode  TSGetTotalSteps(TS ts,PetscInt *steps)
4841 {
4842   PetscFunctionBegin;
4843   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4844   PetscValidPointer(steps,2);
4845   *steps = ts->total_steps;
4846   PetscFunctionReturn(0);
4847 }
4848 
4849 #undef __FUNCT__
4850 #define __FUNCT__ "TSGetSNESIterations"
4851 /*@
4852    TSGetSNESIterations - Gets the total number of nonlinear iterations
4853    used by the time integrator.
4854 
4855    Not Collective
4856 
4857    Input Parameter:
4858 .  ts - TS context
4859 
4860    Output Parameter:
4861 .  nits - number of nonlinear iterations
4862 
4863    Notes:
4864    This counter is reset to zero for each successive call to TSSolve().
4865 
4866    Level: intermediate
4867 
4868 .keywords: TS, get, number, nonlinear, iterations
4869 
4870 .seealso:  TSGetKSPIterations()
4871 @*/
4872 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits)
4873 {
4874   PetscFunctionBegin;
4875   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4876   PetscValidIntPointer(nits,2);
4877   *nits = ts->snes_its;
4878   PetscFunctionReturn(0);
4879 }
4880 
4881 #undef __FUNCT__
4882 #define __FUNCT__ "TSGetKSPIterations"
4883 /*@
4884    TSGetKSPIterations - Gets the total number of linear iterations
4885    used by the time integrator.
4886 
4887    Not Collective
4888 
4889    Input Parameter:
4890 .  ts - TS context
4891 
4892    Output Parameter:
4893 .  lits - number of linear iterations
4894 
4895    Notes:
4896    This counter is reset to zero for each successive call to TSSolve().
4897 
4898    Level: intermediate
4899 
4900 .keywords: TS, get, number, linear, iterations
4901 
4902 .seealso:  TSGetSNESIterations(), SNESGetKSPIterations()
4903 @*/
4904 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits)
4905 {
4906   PetscFunctionBegin;
4907   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4908   PetscValidIntPointer(lits,2);
4909   *lits = ts->ksp_its;
4910   PetscFunctionReturn(0);
4911 }
4912 
4913 #undef __FUNCT__
4914 #define __FUNCT__ "TSGetStepRejections"
4915 /*@
4916    TSGetStepRejections - Gets the total number of rejected steps.
4917 
4918    Not Collective
4919 
4920    Input Parameter:
4921 .  ts - TS context
4922 
4923    Output Parameter:
4924 .  rejects - number of steps rejected
4925 
4926    Notes:
4927    This counter is reset to zero for each successive call to TSSolve().
4928 
4929    Level: intermediate
4930 
4931 .keywords: TS, get, number
4932 
4933 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails()
4934 @*/
4935 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects)
4936 {
4937   PetscFunctionBegin;
4938   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4939   PetscValidIntPointer(rejects,2);
4940   *rejects = ts->reject;
4941   PetscFunctionReturn(0);
4942 }
4943 
4944 #undef __FUNCT__
4945 #define __FUNCT__ "TSGetSNESFailures"
4946 /*@
4947    TSGetSNESFailures - Gets the total number of failed SNES solves
4948 
4949    Not Collective
4950 
4951    Input Parameter:
4952 .  ts - TS context
4953 
4954    Output Parameter:
4955 .  fails - number of failed nonlinear solves
4956 
4957    Notes:
4958    This counter is reset to zero for each successive call to TSSolve().
4959 
4960    Level: intermediate
4961 
4962 .keywords: TS, get, number
4963 
4964 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures()
4965 @*/
4966 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails)
4967 {
4968   PetscFunctionBegin;
4969   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4970   PetscValidIntPointer(fails,2);
4971   *fails = ts->num_snes_failures;
4972   PetscFunctionReturn(0);
4973 }
4974 
4975 #undef __FUNCT__
4976 #define __FUNCT__ "TSSetMaxStepRejections"
4977 /*@
4978    TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails
4979 
4980    Not Collective
4981 
4982    Input Parameter:
4983 +  ts - TS context
4984 -  rejects - maximum number of rejected steps, pass -1 for unlimited
4985 
4986    Notes:
4987    The counter is reset to zero for each step
4988 
4989    Options Database Key:
4990  .  -ts_max_reject - Maximum number of step rejections before a step fails
4991 
4992    Level: intermediate
4993 
4994 .keywords: TS, set, maximum, number
4995 
4996 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
4997 @*/
4998 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects)
4999 {
5000   PetscFunctionBegin;
5001   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5002   ts->max_reject = rejects;
5003   PetscFunctionReturn(0);
5004 }
5005 
5006 #undef __FUNCT__
5007 #define __FUNCT__ "TSSetMaxSNESFailures"
5008 /*@
5009    TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves
5010 
5011    Not Collective
5012 
5013    Input Parameter:
5014 +  ts - TS context
5015 -  fails - maximum number of failed nonlinear solves, pass -1 for unlimited
5016 
5017    Notes:
5018    The counter is reset to zero for each successive call to TSSolve().
5019 
5020    Options Database Key:
5021  .  -ts_max_snes_failures - Maximum number of nonlinear solve failures
5022 
5023    Level: intermediate
5024 
5025 .keywords: TS, set, maximum, number
5026 
5027 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason()
5028 @*/
5029 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails)
5030 {
5031   PetscFunctionBegin;
5032   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5033   ts->max_snes_failures = fails;
5034   PetscFunctionReturn(0);
5035 }
5036 
5037 #undef __FUNCT__
5038 #define __FUNCT__ "TSSetErrorIfStepFails"
5039 /*@
5040    TSSetErrorIfStepFails - Error if no step succeeds
5041 
5042    Not Collective
5043 
5044    Input Parameter:
5045 +  ts - TS context
5046 -  err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure
5047 
5048    Options Database Key:
5049  .  -ts_error_if_step_fails - Error if no step succeeds
5050 
5051    Level: intermediate
5052 
5053 .keywords: TS, set, error
5054 
5055 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
5056 @*/
5057 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err)
5058 {
5059   PetscFunctionBegin;
5060   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5061   ts->errorifstepfailed = err;
5062   PetscFunctionReturn(0);
5063 }
5064 
5065 #undef __FUNCT__
5066 #define __FUNCT__ "TSMonitorSolution"
5067 /*@C
5068    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
5069 
5070    Collective on TS
5071 
5072    Input Parameters:
5073 +  ts - the TS context
5074 .  step - current time-step
5075 .  ptime - current time
5076 .  u - current state
5077 -  viewer - binary viewer
5078 
5079    Level: intermediate
5080 
5081 .keywords: TS,  vector, monitor, view
5082 
5083 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5084 @*/
5085 PetscErrorCode  TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *viewer)
5086 {
5087   PetscErrorCode ierr;
5088   PetscViewer    v = (PetscViewer)viewer;
5089 
5090   PetscFunctionBegin;
5091   ierr = VecView(u,v);CHKERRQ(ierr);
5092   PetscFunctionReturn(0);
5093 }
5094 
5095 #undef __FUNCT__
5096 #define __FUNCT__ "TSMonitorSolutionVTK"
5097 /*@C
5098    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
5099 
5100    Collective on TS
5101 
5102    Input Parameters:
5103 +  ts - the TS context
5104 .  step - current time-step
5105 .  ptime - current time
5106 .  u - current state
5107 -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
5108 
5109    Level: intermediate
5110 
5111    Notes:
5112    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.
5113    These are named according to the file name template.
5114 
5115    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().
5116 
5117 .keywords: TS,  vector, monitor, view
5118 
5119 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5120 @*/
5121 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
5122 {
5123   PetscErrorCode ierr;
5124   char           filename[PETSC_MAX_PATH_LEN];
5125   PetscViewer    viewer;
5126 
5127   PetscFunctionBegin;
5128   ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr);
5129   ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr);
5130   ierr = VecView(u,viewer);CHKERRQ(ierr);
5131   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
5132   PetscFunctionReturn(0);
5133 }
5134 
5135 #undef __FUNCT__
5136 #define __FUNCT__ "TSMonitorSolutionVTKDestroy"
5137 /*@C
5138    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
5139 
5140    Collective on TS
5141 
5142    Input Parameters:
5143 .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
5144 
5145    Level: intermediate
5146 
5147    Note:
5148    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
5149 
5150 .keywords: TS,  vector, monitor, view
5151 
5152 .seealso: TSMonitorSet(), TSMonitorSolutionVTK()
5153 @*/
5154 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
5155 {
5156   PetscErrorCode ierr;
5157 
5158   PetscFunctionBegin;
5159   ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr);
5160   PetscFunctionReturn(0);
5161 }
5162 
5163 #undef __FUNCT__
5164 #define __FUNCT__ "TSGetAdapt"
5165 /*@
5166    TSGetAdapt - Get the adaptive controller context for the current method
5167 
5168    Collective on TS if controller has not been created yet
5169 
5170    Input Arguments:
5171 .  ts - time stepping context
5172 
5173    Output Arguments:
5174 .  adapt - adaptive controller
5175 
5176    Level: intermediate
5177 
5178 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose()
5179 @*/
5180 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt)
5181 {
5182   PetscErrorCode ierr;
5183 
5184   PetscFunctionBegin;
5185   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5186   PetscValidPointer(adapt,2);
5187   if (!ts->adapt) {
5188     ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr);
5189     ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr);
5190     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr);
5191   }
5192   *adapt = ts->adapt;
5193   PetscFunctionReturn(0);
5194 }
5195 
5196 #undef __FUNCT__
5197 #define __FUNCT__ "TSSetTolerances"
5198 /*@
5199    TSSetTolerances - Set tolerances for local truncation error when using adaptive controller
5200 
5201    Logically Collective
5202 
5203    Input Arguments:
5204 +  ts - time integration context
5205 .  atol - scalar absolute tolerances, PETSC_DECIDE to leave current value
5206 .  vatol - vector of absolute tolerances or NULL, used in preference to atol if present
5207 .  rtol - scalar relative tolerances, PETSC_DECIDE to leave current value
5208 -  vrtol - vector of relative tolerances or NULL, used in preference to atol if present
5209 
5210    Options Database keys:
5211 +  -ts_rtol <rtol> - relative tolerance for local truncation error
5212 -  -ts_atol <atol> Absolute tolerance for local truncation error
5213 
5214    Notes:
5215    With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error
5216    (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be
5217    computed only for the differential or the algebraic part then this can be done using the vector of
5218    tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the
5219    differential part and infinity for the algebraic part, the LTE calculation will include only the
5220    differential variables.
5221 
5222    Level: beginner
5223 
5224 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances()
5225 @*/
5226 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol)
5227 {
5228   PetscErrorCode ierr;
5229 
5230   PetscFunctionBegin;
5231   if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol;
5232   if (vatol) {
5233     ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr);
5234     ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
5235 
5236     ts->vatol = vatol;
5237   }
5238   if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol;
5239   if (vrtol) {
5240     ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr);
5241     ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
5242 
5243     ts->vrtol = vrtol;
5244   }
5245   PetscFunctionReturn(0);
5246 }
5247 
5248 #undef __FUNCT__
5249 #define __FUNCT__ "TSGetTolerances"
5250 /*@
5251    TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
5252 
5253    Logically Collective
5254 
5255    Input Arguments:
5256 .  ts - time integration context
5257 
5258    Output Arguments:
5259 +  atol - scalar absolute tolerances, NULL to ignore
5260 .  vatol - vector of absolute tolerances, NULL to ignore
5261 .  rtol - scalar relative tolerances, NULL to ignore
5262 -  vrtol - vector of relative tolerances, NULL to ignore
5263 
5264    Level: beginner
5265 
5266 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances()
5267 @*/
5268 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol)
5269 {
5270   PetscFunctionBegin;
5271   if (atol)  *atol  = ts->atol;
5272   if (vatol) *vatol = ts->vatol;
5273   if (rtol)  *rtol  = ts->rtol;
5274   if (vrtol) *vrtol = ts->vrtol;
5275   PetscFunctionReturn(0);
5276 }
5277 
5278 #undef __FUNCT__
5279 #define __FUNCT__ "TSErrorWeightedNorm2"
5280 /*@
5281    TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors
5282 
5283    Collective on TS
5284 
5285    Input Arguments:
5286 +  ts - time stepping context
5287 .  U - state vector, usually ts->vec_sol
5288 -  Y - state vector to be compared to U
5289 
5290    Output Arguments:
5291 .  norm - weighted norm, a value of 1.0 is considered small
5292 
5293    Level: developer
5294 
5295 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity()
5296 @*/
5297 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm)
5298 {
5299   PetscErrorCode    ierr;
5300   PetscInt          i,n,N,rstart;
5301   const PetscScalar *u,*y;
5302   PetscReal         sum,gsum;
5303   PetscReal         tol;
5304 
5305   PetscFunctionBegin;
5306   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5307   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
5308   PetscValidHeaderSpecific(Y,VEC_CLASSID,3);
5309   PetscValidType(U,2);
5310   PetscValidType(Y,3);
5311   PetscCheckSameComm(U,2,Y,3);
5312   PetscValidPointer(norm,4);
5313   if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector");
5314 
5315   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
5316   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
5317   ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr);
5318   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
5319   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
5320   sum  = 0.;
5321   if (ts->vatol && ts->vrtol) {
5322     const PetscScalar *atol,*rtol;
5323     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5324     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5325     for (i=0; i<n; i++) {
5326       tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5327       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
5328     }
5329     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5330     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5331   } else if (ts->vatol) {       /* vector atol, scalar rtol */
5332     const PetscScalar *atol;
5333     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5334     for (i=0; i<n; i++) {
5335       tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5336       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
5337     }
5338     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5339   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
5340     const PetscScalar *rtol;
5341     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5342     for (i=0; i<n; i++) {
5343       tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5344       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
5345     }
5346     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5347   } else {                      /* scalar atol, scalar rtol */
5348     for (i=0; i<n; i++) {
5349       tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5350       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
5351     }
5352   }
5353   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
5354   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
5355 
5356   ierr  = MPIU_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
5357   *norm = PetscSqrtReal(gsum / N);
5358 
5359   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
5360   PetscFunctionReturn(0);
5361 }
5362 
5363 #undef __FUNCT__
5364 #define __FUNCT__ "TSErrorWeightedNormInfinity"
5365 /*@
5366    TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors
5367 
5368    Collective on TS
5369 
5370    Input Arguments:
5371 +  ts - time stepping context
5372 .  U - state vector, usually ts->vec_sol
5373 -  Y - state vector to be compared to U
5374 
5375    Output Arguments:
5376 .  norm - weighted norm, a value of 1.0 is considered small
5377 
5378    Level: developer
5379 
5380 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2()
5381 @*/
5382 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm)
5383 {
5384   PetscErrorCode    ierr;
5385   PetscInt          i,n,N,rstart,k;
5386   const PetscScalar *u,*y;
5387   PetscReal         max,gmax;
5388   PetscReal         tol;
5389 
5390   PetscFunctionBegin;
5391   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5392   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
5393   PetscValidHeaderSpecific(Y,VEC_CLASSID,3);
5394   PetscValidType(U,2);
5395   PetscValidType(Y,3);
5396   PetscCheckSameComm(U,2,Y,3);
5397   PetscValidPointer(norm,4);
5398   if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector");
5399 
5400   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
5401   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
5402   ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr);
5403   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
5404   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
5405   if (ts->vatol && ts->vrtol) {
5406     const PetscScalar *atol,*rtol;
5407     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5408     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5409     k = 0;
5410     tol = PetscRealPart(atol[k]) + PetscRealPart(rtol[k]) * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k]));
5411     max = PetscAbsScalar(y[k] - u[k]) / tol;
5412     for (i=1; i<n; i++) {
5413       tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5414       max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol);
5415     }
5416     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5417     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5418   } else if (ts->vatol) {       /* vector atol, scalar rtol */
5419     const PetscScalar *atol;
5420     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5421     k = 0;
5422     tol = PetscRealPart(atol[k]) + ts->rtol * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k]));
5423     max = PetscAbsScalar(y[k] - u[k]) / tol;
5424     for (i=1; i<n; i++) {
5425       tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5426       max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol);
5427     }
5428     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5429   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
5430     const PetscScalar *rtol;
5431     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5432     k = 0;
5433     tol = ts->atol + PetscRealPart(rtol[k]) * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k]));
5434     max = PetscAbsScalar(y[k] - u[k]) / tol;
5435     for (i=1; i<n; i++) {
5436       tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5437       max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol);
5438     }
5439     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5440   } else {                      /* scalar atol, scalar rtol */
5441     k = 0;
5442     tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k]));
5443     max = PetscAbsScalar(y[k] - u[k]) / tol;
5444     for (i=1; i<n; i++) {
5445       tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5446       max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol);
5447     }
5448   }
5449   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
5450   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
5451 
5452   ierr  = MPIU_Allreduce(&max,&gmax,1,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
5453   *norm = gmax;
5454 
5455   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
5456   PetscFunctionReturn(0);
5457 }
5458 
5459 #undef __FUNCT__
5460 #define __FUNCT__ "TSErrorWeightedNorm"
5461 /*@
5462    TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors
5463 
5464    Collective on TS
5465 
5466    Input Arguments:
5467 +  ts - time stepping context
5468 .  U - state vector, usually ts->vec_sol
5469 .  Y - state vector to be compared to U
5470 -  wnormtype - norm type, either NORM_2 or NORM_INFINITY
5471 
5472    Output Arguments:
5473 .  norm - weighted norm, a value of 1.0 is considered small
5474 
5475 
5476    Options Database Keys:
5477 .  -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
5478 
5479    Level: developer
5480 
5481 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2()
5482 @*/
5483 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm)
5484 {
5485   PetscErrorCode ierr;
5486 
5487   PetscFunctionBegin;
5488   if (wnormtype == NORM_2) {
5489     ierr = TSErrorWeightedNorm2(ts,U,Y,norm);CHKERRQ(ierr);
5490   } else if(wnormtype == NORM_INFINITY) {
5491     ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm);CHKERRQ(ierr);
5492   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
5493   PetscFunctionReturn(0);
5494 }
5495 
5496 #undef __FUNCT__
5497 #define __FUNCT__ "TSSetCFLTimeLocal"
5498 /*@
5499    TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
5500 
5501    Logically Collective on TS
5502 
5503    Input Arguments:
5504 +  ts - time stepping context
5505 -  cfltime - maximum stable time step if using forward Euler (value can be different on each process)
5506 
5507    Note:
5508    After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
5509 
5510    Level: intermediate
5511 
5512 .seealso: TSGetCFLTime(), TSADAPTCFL
5513 @*/
5514 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime)
5515 {
5516   PetscFunctionBegin;
5517   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5518   ts->cfltime_local = cfltime;
5519   ts->cfltime       = -1.;
5520   PetscFunctionReturn(0);
5521 }
5522 
5523 #undef __FUNCT__
5524 #define __FUNCT__ "TSGetCFLTime"
5525 /*@
5526    TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
5527 
5528    Collective on TS
5529 
5530    Input Arguments:
5531 .  ts - time stepping context
5532 
5533    Output Arguments:
5534 .  cfltime - maximum stable time step for forward Euler
5535 
5536    Level: advanced
5537 
5538 .seealso: TSSetCFLTimeLocal()
5539 @*/
5540 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime)
5541 {
5542   PetscErrorCode ierr;
5543 
5544   PetscFunctionBegin;
5545   if (ts->cfltime < 0) {
5546     ierr = MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
5547   }
5548   *cfltime = ts->cfltime;
5549   PetscFunctionReturn(0);
5550 }
5551 
5552 #undef __FUNCT__
5553 #define __FUNCT__ "TSVISetVariableBounds"
5554 /*@
5555    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
5556 
5557    Input Parameters:
5558 .  ts   - the TS context.
5559 .  xl   - lower bound.
5560 .  xu   - upper bound.
5561 
5562    Notes:
5563    If this routine is not called then the lower and upper bounds are set to
5564    PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp().
5565 
5566    Level: advanced
5567 
5568 @*/
5569 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
5570 {
5571   PetscErrorCode ierr;
5572   SNES           snes;
5573 
5574   PetscFunctionBegin;
5575   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
5576   ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr);
5577   PetscFunctionReturn(0);
5578 }
5579 
5580 #if defined(PETSC_HAVE_MATLAB_ENGINE)
5581 #include <mex.h>
5582 
5583 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext;
5584 
5585 #undef __FUNCT__
5586 #define __FUNCT__ "TSComputeFunction_Matlab"
5587 /*
5588    TSComputeFunction_Matlab - Calls the function that has been set with
5589                          TSSetFunctionMatlab().
5590 
5591    Collective on TS
5592 
5593    Input Parameters:
5594 +  snes - the TS context
5595 -  u - input vector
5596 
5597    Output Parameter:
5598 .  y - function vector, as set by TSSetFunction()
5599 
5600    Notes:
5601    TSComputeFunction() is typically used within nonlinear solvers
5602    implementations, so most users would not generally call this routine
5603    themselves.
5604 
5605    Level: developer
5606 
5607 .keywords: TS, nonlinear, compute, function
5608 
5609 .seealso: TSSetFunction(), TSGetFunction()
5610 */
5611 PetscErrorCode  TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx)
5612 {
5613   PetscErrorCode  ierr;
5614   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
5615   int             nlhs  = 1,nrhs = 7;
5616   mxArray         *plhs[1],*prhs[7];
5617   long long int   lx = 0,lxdot = 0,ly = 0,ls = 0;
5618 
5619   PetscFunctionBegin;
5620   PetscValidHeaderSpecific(snes,TS_CLASSID,1);
5621   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
5622   PetscValidHeaderSpecific(udot,VEC_CLASSID,4);
5623   PetscValidHeaderSpecific(y,VEC_CLASSID,5);
5624   PetscCheckSameComm(snes,1,u,3);
5625   PetscCheckSameComm(snes,1,y,5);
5626 
5627   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
5628   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
5629   ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr);
5630   ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr);
5631 
5632   prhs[0] =  mxCreateDoubleScalar((double)ls);
5633   prhs[1] =  mxCreateDoubleScalar(time);
5634   prhs[2] =  mxCreateDoubleScalar((double)lx);
5635   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
5636   prhs[4] =  mxCreateDoubleScalar((double)ly);
5637   prhs[5] =  mxCreateString(sctx->funcname);
5638   prhs[6] =  sctx->ctx;
5639   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr);
5640   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
5641   mxDestroyArray(prhs[0]);
5642   mxDestroyArray(prhs[1]);
5643   mxDestroyArray(prhs[2]);
5644   mxDestroyArray(prhs[3]);
5645   mxDestroyArray(prhs[4]);
5646   mxDestroyArray(prhs[5]);
5647   mxDestroyArray(plhs[0]);
5648   PetscFunctionReturn(0);
5649 }
5650 
5651 
5652 #undef __FUNCT__
5653 #define __FUNCT__ "TSSetFunctionMatlab"
5654 /*
5655    TSSetFunctionMatlab - Sets the function evaluation routine and function
5656    vector for use by the TS routines in solving ODEs
5657    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
5658 
5659    Logically Collective on TS
5660 
5661    Input Parameters:
5662 +  ts - the TS context
5663 -  func - function evaluation routine
5664 
5665    Calling sequence of func:
5666 $    func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx);
5667 
5668    Level: beginner
5669 
5670 .keywords: TS, nonlinear, set, function
5671 
5672 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
5673 */
5674 PetscErrorCode  TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx)
5675 {
5676   PetscErrorCode  ierr;
5677   TSMatlabContext *sctx;
5678 
5679   PetscFunctionBegin;
5680   /* currently sctx is memory bleed */
5681   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
5682   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
5683   /*
5684      This should work, but it doesn't
5685   sctx->ctx = ctx;
5686   mexMakeArrayPersistent(sctx->ctx);
5687   */
5688   sctx->ctx = mxDuplicateArray(ctx);
5689 
5690   ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr);
5691   PetscFunctionReturn(0);
5692 }
5693 
5694 #undef __FUNCT__
5695 #define __FUNCT__ "TSComputeJacobian_Matlab"
5696 /*
5697    TSComputeJacobian_Matlab - Calls the function that has been set with
5698                          TSSetJacobianMatlab().
5699 
5700    Collective on TS
5701 
5702    Input Parameters:
5703 +  ts - the TS context
5704 .  u - input vector
5705 .  A, B - the matrices
5706 -  ctx - user context
5707 
5708    Level: developer
5709 
5710 .keywords: TS, nonlinear, compute, function
5711 
5712 .seealso: TSSetFunction(), TSGetFunction()
5713 @*/
5714 PetscErrorCode  TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat A,Mat B,void *ctx)
5715 {
5716   PetscErrorCode  ierr;
5717   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
5718   int             nlhs  = 2,nrhs = 9;
5719   mxArray         *plhs[2],*prhs[9];
5720   long long int   lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0;
5721 
5722   PetscFunctionBegin;
5723   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5724   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
5725 
5726   /* call Matlab function in ctx with arguments u and y */
5727 
5728   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
5729   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
5730   ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr);
5731   ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr);
5732   ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr);
5733 
5734   prhs[0] =  mxCreateDoubleScalar((double)ls);
5735   prhs[1] =  mxCreateDoubleScalar((double)time);
5736   prhs[2] =  mxCreateDoubleScalar((double)lx);
5737   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
5738   prhs[4] =  mxCreateDoubleScalar((double)shift);
5739   prhs[5] =  mxCreateDoubleScalar((double)lA);
5740   prhs[6] =  mxCreateDoubleScalar((double)lB);
5741   prhs[7] =  mxCreateString(sctx->funcname);
5742   prhs[8] =  sctx->ctx;
5743   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr);
5744   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
5745   mxDestroyArray(prhs[0]);
5746   mxDestroyArray(prhs[1]);
5747   mxDestroyArray(prhs[2]);
5748   mxDestroyArray(prhs[3]);
5749   mxDestroyArray(prhs[4]);
5750   mxDestroyArray(prhs[5]);
5751   mxDestroyArray(prhs[6]);
5752   mxDestroyArray(prhs[7]);
5753   mxDestroyArray(plhs[0]);
5754   mxDestroyArray(plhs[1]);
5755   PetscFunctionReturn(0);
5756 }
5757 
5758 
5759 #undef __FUNCT__
5760 #define __FUNCT__ "TSSetJacobianMatlab"
5761 /*
5762    TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
5763    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
5764 
5765    Logically Collective on TS
5766 
5767    Input Parameters:
5768 +  ts - the TS context
5769 .  A,B - Jacobian matrices
5770 .  func - function evaluation routine
5771 -  ctx - user context
5772 
5773    Calling sequence of func:
5774 $    flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx);
5775 
5776 
5777    Level: developer
5778 
5779 .keywords: TS, nonlinear, set, function
5780 
5781 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
5782 */
5783 PetscErrorCode  TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx)
5784 {
5785   PetscErrorCode  ierr;
5786   TSMatlabContext *sctx;
5787 
5788   PetscFunctionBegin;
5789   /* currently sctx is memory bleed */
5790   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
5791   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
5792   /*
5793      This should work, but it doesn't
5794   sctx->ctx = ctx;
5795   mexMakeArrayPersistent(sctx->ctx);
5796   */
5797   sctx->ctx = mxDuplicateArray(ctx);
5798 
5799   ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
5800   PetscFunctionReturn(0);
5801 }
5802 
5803 #undef __FUNCT__
5804 #define __FUNCT__ "TSMonitor_Matlab"
5805 /*
5806    TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab().
5807 
5808    Collective on TS
5809 
5810 .seealso: TSSetFunction(), TSGetFunction()
5811 @*/
5812 PetscErrorCode  TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx)
5813 {
5814   PetscErrorCode  ierr;
5815   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
5816   int             nlhs  = 1,nrhs = 6;
5817   mxArray         *plhs[1],*prhs[6];
5818   long long int   lx = 0,ls = 0;
5819 
5820   PetscFunctionBegin;
5821   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5822   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
5823 
5824   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
5825   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
5826 
5827   prhs[0] =  mxCreateDoubleScalar((double)ls);
5828   prhs[1] =  mxCreateDoubleScalar((double)it);
5829   prhs[2] =  mxCreateDoubleScalar((double)time);
5830   prhs[3] =  mxCreateDoubleScalar((double)lx);
5831   prhs[4] =  mxCreateString(sctx->funcname);
5832   prhs[5] =  sctx->ctx;
5833   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr);
5834   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
5835   mxDestroyArray(prhs[0]);
5836   mxDestroyArray(prhs[1]);
5837   mxDestroyArray(prhs[2]);
5838   mxDestroyArray(prhs[3]);
5839   mxDestroyArray(prhs[4]);
5840   mxDestroyArray(plhs[0]);
5841   PetscFunctionReturn(0);
5842 }
5843 
5844 
5845 #undef __FUNCT__
5846 #define __FUNCT__ "TSMonitorSetMatlab"
5847 /*
5848    TSMonitorSetMatlab - Sets the monitor function from Matlab
5849 
5850    Level: developer
5851 
5852 .keywords: TS, nonlinear, set, function
5853 
5854 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
5855 */
5856 PetscErrorCode  TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx)
5857 {
5858   PetscErrorCode  ierr;
5859   TSMatlabContext *sctx;
5860 
5861   PetscFunctionBegin;
5862   /* currently sctx is memory bleed */
5863   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
5864   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
5865   /*
5866      This should work, but it doesn't
5867   sctx->ctx = ctx;
5868   mexMakeArrayPersistent(sctx->ctx);
5869   */
5870   sctx->ctx = mxDuplicateArray(ctx);
5871 
5872   ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr);
5873   PetscFunctionReturn(0);
5874 }
5875 #endif
5876 
5877 #undef __FUNCT__
5878 #define __FUNCT__ "TSMonitorLGSolution"
5879 /*@C
5880    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
5881        in a time based line graph
5882 
5883    Collective on TS
5884 
5885    Input Parameters:
5886 +  ts - the TS context
5887 .  step - current time-step
5888 .  ptime - current time
5889 .  u - current solution
5890 -  dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate()
5891 
5892    Options Database:
5893 .   -ts_monitor_lg_solution_variables
5894 
5895    Level: intermediate
5896 
5897     Notes: each process in a parallel run displays its component solutions in a separate window
5898 
5899 .keywords: TS,  vector, monitor, view
5900 
5901 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
5902            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
5903            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
5904            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()
5905 @*/
5906 PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
5907 {
5908   PetscErrorCode    ierr;
5909   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dctx;
5910   const PetscScalar *yy;
5911   PetscInt          dim;
5912   Vec               v;
5913 
5914   PetscFunctionBegin;
5915   if (!step) {
5916     PetscDrawAxis axis;
5917     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
5918     ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr);
5919     if (ctx->names && !ctx->displaynames) {
5920       char      **displaynames;
5921       PetscBool flg;
5922 
5923       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
5924       ierr = PetscMalloc((dim+1)*sizeof(char*),&displaynames);CHKERRQ(ierr);
5925       ierr = PetscMemzero(displaynames,(dim+1)*sizeof(char*));CHKERRQ(ierr);
5926       ierr = PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr);
5927       if (flg) {
5928         ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr);
5929       }
5930       ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr);
5931     }
5932     if (ctx->displaynames) {
5933       ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr);
5934       ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr);
5935     } else if (ctx->names) {
5936       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
5937       ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
5938       ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr);
5939     } else {
5940       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
5941       ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
5942     }
5943     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
5944   }
5945   if (ctx->transform) {
5946     ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);
5947   } else {
5948     v = u;
5949   }
5950   ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr);
5951 #if defined(PETSC_USE_COMPLEX)
5952   {
5953     PetscReal *yreal;
5954     PetscInt  i,n;
5955     ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
5956     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
5957     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
5958     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
5959     ierr = PetscFree(yreal);CHKERRQ(ierr);
5960   }
5961 #else
5962   if (ctx->displaynames) {
5963     PetscInt i;
5964     for (i=0; i<ctx->ndisplayvariables; i++) {
5965       ctx->displayvalues[i] = yy[ctx->displayvariables[i]];
5966     }
5967     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr);
5968   } else {
5969     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
5970   }
5971 #endif
5972   ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr);
5973   if (ctx->transform) {
5974     ierr = VecDestroy(&v);CHKERRQ(ierr);
5975   }
5976   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
5977     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
5978   }
5979   PetscFunctionReturn(0);
5980 }
5981 
5982 
5983 #undef __FUNCT__
5984 #define __FUNCT__ "TSMonitorLGSetVariableNames"
5985 /*@C
5986    TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
5987 
5988    Collective on TS
5989 
5990    Input Parameters:
5991 +  ts - the TS context
5992 -  names - the names of the components, final string must be NULL
5993 
5994    Level: intermediate
5995 
5996    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
5997 
5998 .keywords: TS,  vector, monitor, view
5999 
6000 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames()
6001 @*/
6002 PetscErrorCode  TSMonitorLGSetVariableNames(TS ts,const char * const *names)
6003 {
6004   PetscErrorCode    ierr;
6005   PetscInt          i;
6006 
6007   PetscFunctionBegin;
6008   for (i=0; i<ts->numbermonitors; i++) {
6009     if (ts->monitor[i] == TSMonitorLGSolution) {
6010       ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr);
6011       break;
6012     }
6013   }
6014   PetscFunctionReturn(0);
6015 }
6016 
6017 #undef __FUNCT__
6018 #define __FUNCT__ "TSMonitorLGCtxSetVariableNames"
6019 /*@C
6020    TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
6021 
6022    Collective on TS
6023 
6024    Input Parameters:
6025 +  ts - the TS context
6026 -  names - the names of the components, final string must be NULL
6027 
6028    Level: intermediate
6029 
6030 .keywords: TS,  vector, monitor, view
6031 
6032 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames()
6033 @*/
6034 PetscErrorCode  TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names)
6035 {
6036   PetscErrorCode    ierr;
6037 
6038   PetscFunctionBegin;
6039   ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr);
6040   ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr);
6041   PetscFunctionReturn(0);
6042 }
6043 
6044 #undef __FUNCT__
6045 #define __FUNCT__ "TSMonitorLGGetVariableNames"
6046 /*@C
6047    TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot
6048 
6049    Collective on TS
6050 
6051    Input Parameter:
6052 .  ts - the TS context
6053 
6054    Output Parameter:
6055 .  names - the names of the components, final string must be NULL
6056 
6057    Level: intermediate
6058 
6059    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
6060 
6061 .keywords: TS,  vector, monitor, view
6062 
6063 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
6064 @*/
6065 PetscErrorCode  TSMonitorLGGetVariableNames(TS ts,const char *const **names)
6066 {
6067   PetscInt       i;
6068 
6069   PetscFunctionBegin;
6070   *names = NULL;
6071   for (i=0; i<ts->numbermonitors; i++) {
6072     if (ts->monitor[i] == TSMonitorLGSolution) {
6073       TSMonitorLGCtx  ctx = (TSMonitorLGCtx) ts->monitorcontext[i];
6074       *names = (const char *const *)ctx->names;
6075       break;
6076     }
6077   }
6078   PetscFunctionReturn(0);
6079 }
6080 
6081 #undef __FUNCT__
6082 #define __FUNCT__ "TSMonitorLGCtxSetDisplayVariables"
6083 /*@C
6084    TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor
6085 
6086    Collective on TS
6087 
6088    Input Parameters:
6089 +  ctx - the TSMonitorLG context
6090 .  displaynames - the names of the components, final string must be NULL
6091 
6092    Level: intermediate
6093 
6094 .keywords: TS,  vector, monitor, view
6095 
6096 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
6097 @*/
6098 PetscErrorCode  TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames)
6099 {
6100   PetscInt          j = 0,k;
6101   PetscErrorCode    ierr;
6102 
6103   PetscFunctionBegin;
6104   if (!ctx->names) PetscFunctionReturn(0);
6105   ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr);
6106   ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr);
6107   while (displaynames[j]) j++;
6108   ctx->ndisplayvariables = j;
6109   ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr);
6110   ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr);
6111   j = 0;
6112   while (displaynames[j]) {
6113     k = 0;
6114     while (ctx->names[k]) {
6115       PetscBool flg;
6116       ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr);
6117       if (flg) {
6118         ctx->displayvariables[j] = k;
6119         break;
6120       }
6121       k++;
6122     }
6123     j++;
6124   }
6125   PetscFunctionReturn(0);
6126 }
6127 
6128 
6129 #undef __FUNCT__
6130 #define __FUNCT__ "TSMonitorLGSetDisplayVariables"
6131 /*@C
6132    TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor
6133 
6134    Collective on TS
6135 
6136    Input Parameters:
6137 +  ts - the TS context
6138 .  displaynames - the names of the components, final string must be NULL
6139 
6140    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
6141 
6142    Level: intermediate
6143 
6144 .keywords: TS,  vector, monitor, view
6145 
6146 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
6147 @*/
6148 PetscErrorCode  TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames)
6149 {
6150   PetscInt          i;
6151   PetscErrorCode    ierr;
6152 
6153   PetscFunctionBegin;
6154   for (i=0; i<ts->numbermonitors; i++) {
6155     if (ts->monitor[i] == TSMonitorLGSolution) {
6156       ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr);
6157       break;
6158     }
6159   }
6160   PetscFunctionReturn(0);
6161 }
6162 
6163 #undef __FUNCT__
6164 #define __FUNCT__ "TSMonitorLGSetTransform"
6165 /*@C
6166    TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed
6167 
6168    Collective on TS
6169 
6170    Input Parameters:
6171 +  ts - the TS context
6172 .  transform - the transform function
6173 .  destroy - function to destroy the optional context
6174 -  ctx - optional context used by transform function
6175 
6176    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
6177 
6178    Level: intermediate
6179 
6180 .keywords: TS,  vector, monitor, view
6181 
6182 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform()
6183 @*/
6184 PetscErrorCode  TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
6185 {
6186   PetscInt          i;
6187   PetscErrorCode    ierr;
6188 
6189   PetscFunctionBegin;
6190   for (i=0; i<ts->numbermonitors; i++) {
6191     if (ts->monitor[i] == TSMonitorLGSolution) {
6192       ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr);
6193     }
6194   }
6195   PetscFunctionReturn(0);
6196 }
6197 
6198 #undef __FUNCT__
6199 #define __FUNCT__ "TSMonitorLGCtxSetTransform"
6200 /*@C
6201    TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed
6202 
6203    Collective on TSLGCtx
6204 
6205    Input Parameters:
6206 +  ts - the TS context
6207 .  transform - the transform function
6208 .  destroy - function to destroy the optional context
6209 -  ctx - optional context used by transform function
6210 
6211    Level: intermediate
6212 
6213 .keywords: TS,  vector, monitor, view
6214 
6215 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform()
6216 @*/
6217 PetscErrorCode  TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
6218 {
6219   PetscFunctionBegin;
6220   ctx->transform    = transform;
6221   ctx->transformdestroy = destroy;
6222   ctx->transformctx = tctx;
6223   PetscFunctionReturn(0);
6224 }
6225 
6226 #undef __FUNCT__
6227 #define __FUNCT__ "TSMonitorLGError"
6228 /*@C
6229    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector
6230        in a time based line graph
6231 
6232    Collective on TS
6233 
6234    Input Parameters:
6235 +  ts - the TS context
6236 .  step - current time-step
6237 .  ptime - current time
6238 .  u - current solution
6239 -  dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate()
6240 
6241    Level: intermediate
6242 
6243    Notes:
6244    Only for sequential solves.
6245 
6246    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
6247 
6248    Options Database Keys:
6249 .  -ts_monitor_lg_error - create a graphical monitor of error history
6250 
6251 .keywords: TS,  vector, monitor, view
6252 
6253 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
6254 @*/
6255 PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
6256 {
6257   PetscErrorCode    ierr;
6258   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
6259   const PetscScalar *yy;
6260   Vec               y;
6261   PetscInt          dim;
6262 
6263   PetscFunctionBegin;
6264   if (!step) {
6265     PetscDrawAxis axis;
6266     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
6267     ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr);
6268     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
6269     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
6270     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
6271   }
6272   ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
6273   ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr);
6274   ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr);
6275   ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr);
6276 #if defined(PETSC_USE_COMPLEX)
6277   {
6278     PetscReal *yreal;
6279     PetscInt  i,n;
6280     ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr);
6281     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
6282     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
6283     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
6284     ierr = PetscFree(yreal);CHKERRQ(ierr);
6285   }
6286 #else
6287   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
6288 #endif
6289   ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr);
6290   ierr = VecDestroy(&y);CHKERRQ(ierr);
6291   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
6292     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
6293   }
6294   PetscFunctionReturn(0);
6295 }
6296 
6297 #undef __FUNCT__
6298 #define __FUNCT__ "TSMonitorLGSNESIterations"
6299 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
6300 {
6301   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
6302   PetscReal      x   = ptime,y;
6303   PetscErrorCode ierr;
6304   PetscInt       its;
6305 
6306   PetscFunctionBegin;
6307   if (!n) {
6308     PetscDrawAxis axis;
6309 
6310     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
6311     ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr);
6312     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
6313 
6314     ctx->snes_its = 0;
6315   }
6316   ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr);
6317   y    = its - ctx->snes_its;
6318   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
6319   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
6320     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
6321   }
6322   ctx->snes_its = its;
6323   PetscFunctionReturn(0);
6324 }
6325 
6326 #undef __FUNCT__
6327 #define __FUNCT__ "TSMonitorLGKSPIterations"
6328 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
6329 {
6330   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
6331   PetscReal      x   = ptime,y;
6332   PetscErrorCode ierr;
6333   PetscInt       its;
6334 
6335   PetscFunctionBegin;
6336   if (!n) {
6337     PetscDrawAxis axis;
6338 
6339     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
6340     ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr);
6341     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
6342 
6343     ctx->ksp_its = 0;
6344   }
6345   ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr);
6346   y    = its - ctx->ksp_its;
6347   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
6348   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
6349     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
6350   }
6351   ctx->ksp_its = its;
6352   PetscFunctionReturn(0);
6353 }
6354 
6355 #undef __FUNCT__
6356 #define __FUNCT__ "TSComputeLinearStability"
6357 /*@
6358    TSComputeLinearStability - computes the linear stability function at a point
6359 
6360    Collective on TS and Vec
6361 
6362    Input Parameters:
6363 +  ts - the TS context
6364 -  xr,xi - real and imaginary part of input arguments
6365 
6366    Output Parameters:
6367 .  yr,yi - real and imaginary part of function value
6368 
6369    Level: developer
6370 
6371 .keywords: TS, compute
6372 
6373 .seealso: TSSetRHSFunction(), TSComputeIFunction()
6374 @*/
6375 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi)
6376 {
6377   PetscErrorCode ierr;
6378 
6379   PetscFunctionBegin;
6380   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6381   if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method");
6382   ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr);
6383   PetscFunctionReturn(0);
6384 }
6385 
6386 /* ------------------------------------------------------------------------*/
6387 #undef __FUNCT__
6388 #define __FUNCT__ "TSMonitorEnvelopeCtxCreate"
6389 /*@C
6390    TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope()
6391 
6392    Collective on TS
6393 
6394    Input Parameters:
6395 .  ts  - the ODE solver object
6396 
6397    Output Parameter:
6398 .  ctx - the context
6399 
6400    Level: intermediate
6401 
6402 .keywords: TS, monitor, line graph, residual, seealso
6403 
6404 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError()
6405 
6406 @*/
6407 PetscErrorCode  TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx)
6408 {
6409   PetscErrorCode ierr;
6410 
6411   PetscFunctionBegin;
6412   ierr = PetscNew(ctx);CHKERRQ(ierr);
6413   PetscFunctionReturn(0);
6414 }
6415 
6416 #undef __FUNCT__
6417 #define __FUNCT__ "TSMonitorEnvelope"
6418 /*@C
6419    TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution
6420 
6421    Collective on TS
6422 
6423    Input Parameters:
6424 +  ts - the TS context
6425 .  step - current time-step
6426 .  ptime - current time
6427 .  u  - current solution
6428 -  dctx - the envelope context
6429 
6430    Options Database:
6431 .  -ts_monitor_envelope
6432 
6433    Level: intermediate
6434 
6435    Notes: after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope
6436 
6437 .keywords: TS,  vector, monitor, view
6438 
6439 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate()
6440 @*/
6441 PetscErrorCode  TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
6442 {
6443   PetscErrorCode       ierr;
6444   TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx;
6445 
6446   PetscFunctionBegin;
6447   if (!ctx->max) {
6448     ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr);
6449     ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr);
6450     ierr = VecCopy(u,ctx->max);CHKERRQ(ierr);
6451     ierr = VecCopy(u,ctx->min);CHKERRQ(ierr);
6452   } else {
6453     ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr);
6454     ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr);
6455   }
6456   PetscFunctionReturn(0);
6457 }
6458 
6459 
6460 #undef __FUNCT__
6461 #define __FUNCT__ "TSMonitorEnvelopeGetBounds"
6462 /*@C
6463    TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution
6464 
6465    Collective on TS
6466 
6467    Input Parameter:
6468 .  ts - the TS context
6469 
6470    Output Parameter:
6471 +  max - the maximum values
6472 -  min - the minimum values
6473 
6474    Notes: If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored
6475 
6476    Level: intermediate
6477 
6478 .keywords: TS,  vector, monitor, view
6479 
6480 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
6481 @*/
6482 PetscErrorCode  TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min)
6483 {
6484   PetscInt i;
6485 
6486   PetscFunctionBegin;
6487   if (max) *max = NULL;
6488   if (min) *min = NULL;
6489   for (i=0; i<ts->numbermonitors; i++) {
6490     if (ts->monitor[i] == TSMonitorEnvelope) {
6491       TSMonitorEnvelopeCtx  ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i];
6492       if (max) *max = ctx->max;
6493       if (min) *min = ctx->min;
6494       break;
6495     }
6496   }
6497   PetscFunctionReturn(0);
6498 }
6499 
6500 #undef __FUNCT__
6501 #define __FUNCT__ "TSMonitorEnvelopeCtxDestroy"
6502 /*@C
6503    TSMonitorEnvelopeCtxDestroy - Destroys a context that was created  with TSMonitorEnvelopeCtxCreate().
6504 
6505    Collective on TSMonitorEnvelopeCtx
6506 
6507    Input Parameter:
6508 .  ctx - the monitor context
6509 
6510    Level: intermediate
6511 
6512 .keywords: TS, monitor, line graph, destroy
6513 
6514 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep()
6515 @*/
6516 PetscErrorCode  TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx)
6517 {
6518   PetscErrorCode ierr;
6519 
6520   PetscFunctionBegin;
6521   ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr);
6522   ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr);
6523   ierr = PetscFree(*ctx);CHKERRQ(ierr);
6524   PetscFunctionReturn(0);
6525 }
6526 
6527 #undef __FUNCT__
6528 #define __FUNCT__ "TSRollBack"
6529 /*@
6530    TSRollBack - Rolls back one time step
6531 
6532    Collective on TS
6533 
6534    Input Parameter:
6535 .  ts - the TS context obtained from TSCreate()
6536 
6537    Level: advanced
6538 
6539 .keywords: TS, timestep, rollback
6540 
6541 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate()
6542 @*/
6543 PetscErrorCode  TSRollBack(TS ts)
6544 {
6545   PetscErrorCode ierr;
6546 
6547   PetscFunctionBegin;
6548   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
6549 
6550   if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name);
6551   ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr);
6552   ts->time_step = ts->ptime - ts->ptime_prev;
6553   ts->ptime = ts->ptime_prev;
6554   ts->steprollback = PETSC_TRUE; /* Flag to indicate that the step is rollbacked */
6555   PetscFunctionReturn(0);
6556 }
6557 
6558 #undef __FUNCT__
6559 #define __FUNCT__ "TSGetStages"
6560 /*@
6561    TSGetStages - Get the number of stages and stage values
6562 
6563    Input Parameter:
6564 .  ts - the TS context obtained from TSCreate()
6565 
6566    Level: advanced
6567 
6568 .keywords: TS, getstages
6569 
6570 .seealso: TSCreate()
6571 @*/
6572 PetscErrorCode  TSGetStages(TS ts,PetscInt *ns, Vec **Y)
6573 {
6574   PetscErrorCode ierr;
6575 
6576   PetscFunctionBegin;
6577   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
6578   PetscValidPointer(ns,2);
6579 
6580   if (!ts->ops->getstages) *ns=0;
6581   else {
6582     ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr);
6583   }
6584   PetscFunctionReturn(0);
6585 }
6586 
6587 #undef __FUNCT__
6588 #define __FUNCT__ "TSComputeIJacobianDefaultColor"
6589 /*@C
6590   TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity.
6591 
6592   Collective on SNES
6593 
6594   Input Parameters:
6595 + ts - the TS context
6596 . t - current timestep
6597 . U - state vector
6598 . Udot - time derivative of state vector
6599 . shift - shift to apply, see note below
6600 - ctx - an optional user context
6601 
6602   Output Parameters:
6603 + J - Jacobian matrix (not altered in this routine)
6604 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J)
6605 
6606   Level: intermediate
6607 
6608   Notes:
6609   If F(t,U,Udot)=0 is the DAE, the required Jacobian is
6610 
6611   dF/dU + shift*dF/dUdot
6612 
6613   Most users should not need to explicitly call this routine, as it
6614   is used internally within the nonlinear solvers.
6615 
6616   This will first try to get the coloring from the DM.  If the DM type has no coloring
6617   routine, then it will try to get the coloring from the matrix.  This requires that the
6618   matrix have nonzero entries precomputed.
6619 
6620 .keywords: TS, finite differences, Jacobian, coloring, sparse
6621 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction()
6622 @*/
6623 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx)
6624 {
6625   SNES           snes;
6626   MatFDColoring  color;
6627   PetscBool      hascolor, matcolor = PETSC_FALSE;
6628   PetscErrorCode ierr;
6629 
6630   PetscFunctionBegin;
6631   ierr = PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr);
6632   ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr);
6633   if (!color) {
6634     DM         dm;
6635     ISColoring iscoloring;
6636 
6637     ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
6638     ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr);
6639     if (hascolor && !matcolor) {
6640       ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr);
6641       ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr);
6642       ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr);
6643       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
6644       ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr);
6645       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
6646     } else {
6647       MatColoring mc;
6648 
6649       ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr);
6650       ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr);
6651       ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr);
6652       ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr);
6653       ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr);
6654       ierr = MatColoringDestroy(&mc);CHKERRQ(ierr);
6655       ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr);
6656       ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr);
6657       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
6658       ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr);
6659       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
6660     }
6661     ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr);
6662     ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr);
6663   }
6664   ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr);
6665   ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr);
6666   if (J != B) {
6667     ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
6668     ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
6669   }
6670   PetscFunctionReturn(0);
6671 }
6672 
6673 #undef __FUNCT__
6674 #define __FUNCT__ "TSSetFunctionDomainError"
6675 /*@
6676     TSSetFunctionDomainError - Set the function testing if the current state vector is valid
6677 
6678     Input Parameters:
6679     ts - the TS context
6680     func - function called within TSFunctionDomainError
6681 
6682     Level: intermediate
6683 
6684 .keywords: TS, state, domain
6685 .seealso: TSAdaptCheckStage(), TSFunctionDomainError()
6686 @*/
6687 
6688 PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*))
6689 {
6690   PetscFunctionBegin;
6691   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
6692   ts->functiondomainerror = func;
6693   PetscFunctionReturn(0);
6694 }
6695 
6696 #undef __FUNCT__
6697 #define __FUNCT__ "TSFunctionDomainError"
6698 /*@
6699     TSFunctionDomainError - Check if the current state is valid
6700 
6701     Input Parameters:
6702     ts - the TS context
6703     stagetime - time of the simulation
6704     Y - state vector to check.
6705 
6706     Output Parameter:
6707     accept - Set to PETSC_FALSE if the current state vector is valid.
6708 
6709     Note:
6710     This function should be used to ensure the state is in a valid part of the space.
6711     For example, one can ensure here all values are positive.
6712 
6713     Level: advanced
6714 @*/
6715 PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept)
6716 {
6717   PetscErrorCode ierr;
6718 
6719   PetscFunctionBegin;
6720 
6721   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6722   *accept = PETSC_TRUE;
6723   if (ts->functiondomainerror) {
6724     PetscStackCallStandard((*ts->functiondomainerror),(ts,stagetime,Y,accept));
6725   }
6726   PetscFunctionReturn(0);
6727 }
6728 
6729 #undef  __FUNCT__
6730 #define __FUNCT__ "TSClone"
6731 /*@C
6732   TSClone - This function clones a time step object.
6733 
6734   Collective on MPI_Comm
6735 
6736   Input Parameter:
6737 . tsin    - The input TS
6738 
6739   Output Parameter:
6740 . tsout   - The output TS (cloned)
6741 
6742   Notes:
6743   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.
6744 
6745   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);
6746 
6747   Level: developer
6748 
6749 .keywords: TS, clone
6750 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType()
6751 @*/
6752 PetscErrorCode  TSClone(TS tsin, TS *tsout)
6753 {
6754   TS             t;
6755   PetscErrorCode ierr;
6756   SNES           snes_start;
6757   DM             dm;
6758   TSType         type;
6759 
6760   PetscFunctionBegin;
6761   PetscValidPointer(tsin,1);
6762   *tsout = NULL;
6763 
6764   ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr);
6765 
6766   /* General TS description */
6767   t->numbermonitors    = 0;
6768   t->setupcalled       = 0;
6769   t->ksp_its           = 0;
6770   t->snes_its          = 0;
6771   t->nwork             = 0;
6772   t->rhsjacobian.time  = -1e20;
6773   t->rhsjacobian.scale = 1.;
6774   t->ijacobian.shift   = 1.;
6775 
6776   ierr = TSGetSNES(tsin,&snes_start);                   CHKERRQ(ierr);
6777   ierr = TSSetSNES(t,snes_start);                       CHKERRQ(ierr);
6778 
6779   ierr = TSGetDM(tsin,&dm);                             CHKERRQ(ierr);
6780   ierr = TSSetDM(t,dm);                                 CHKERRQ(ierr);
6781 
6782   t->adapt=tsin->adapt;
6783   PetscObjectReference((PetscObject)t->adapt);
6784 
6785   t->problem_type      = tsin->problem_type;
6786   t->ptime             = tsin->ptime;
6787   t->time_step         = tsin->time_step;
6788   t->time_step_orig    = tsin->time_step_orig;
6789   t->max_time          = tsin->max_time;
6790   t->steps             = tsin->steps;
6791   t->max_steps         = tsin->max_steps;
6792   t->equation_type     = tsin->equation_type;
6793   t->atol              = tsin->atol;
6794   t->rtol              = tsin->rtol;
6795   t->max_snes_failures = tsin->max_snes_failures;
6796   t->max_reject        = tsin->max_reject;
6797   t->errorifstepfailed = tsin->errorifstepfailed;
6798 
6799   ierr = TSGetType(tsin,&type); CHKERRQ(ierr);
6800   ierr = TSSetType(t,type);     CHKERRQ(ierr);
6801 
6802   t->vec_sol           = NULL;
6803 
6804   t->cfltime          = tsin->cfltime;
6805   t->cfltime_local    = tsin->cfltime_local;
6806   t->exact_final_time = tsin->exact_final_time;
6807 
6808   ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr);
6809 
6810   if (((PetscObject)tsin)->fortran_func_pointers) {
6811     PetscInt i;
6812     ierr = PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers);CHKERRQ(ierr);
6813     for (i=0; i<10; i++) {
6814       ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i];
6815     }
6816   }
6817   *tsout = t;
6818   PetscFunctionReturn(0);
6819 }
6820