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