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