xref: /petsc/src/ts/interface/ts.c (revision efd4aadf157bf1ba2d80c2be092fcf4247860003)
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     if (ts->ops->view) {
1917       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1918       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1919       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1920     }
1921     ierr = PetscViewerASCIIPrintf(viewer,"  maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr);
1922     ierr = PetscViewerASCIIPrintf(viewer,"  maximum time=%g\n",(double)ts->max_time);CHKERRQ(ierr);
1923     if (ts->usessnes) {
1924       PetscBool lin;
1925       if (ts->problem_type == TS_NONLINEAR) {
1926         ierr = PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solver iterations=%D\n",ts->snes_its);CHKERRQ(ierr);
1927       }
1928       ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",ts->ksp_its);CHKERRQ(ierr);
1929       ierr = PetscObjectTypeCompare((PetscObject)ts->snes,SNESKSPONLY,&lin);CHKERRQ(ierr);
1930       ierr = PetscViewerASCIIPrintf(viewer,"  total number of %slinear solve failures=%D\n",lin ? "" : "non",ts->num_snes_failures);CHKERRQ(ierr);
1931     }
1932     ierr = PetscViewerASCIIPrintf(viewer,"  total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr);
1933     if (ts->vrtol) {
1934       ierr = PetscViewerASCIIPrintf(viewer,"  using vector of relative error tolerances, ");CHKERRQ(ierr);
1935     } else {
1936       ierr = PetscViewerASCIIPrintf(viewer,"  using relative error tolerance of %g, ",(double)ts->rtol);CHKERRQ(ierr);
1937     }
1938     if (ts->vatol) {
1939       ierr = PetscViewerASCIIPrintf(viewer,"  using vector of absolute error tolerances\n");CHKERRQ(ierr);
1940     } else {
1941       ierr = PetscViewerASCIIPrintf(viewer,"  using absolute error tolerance of %g\n",(double)ts->atol);CHKERRQ(ierr);
1942     }
1943     ierr = TSAdaptView(ts->adapt,viewer);CHKERRQ(ierr);
1944     if (ts->snes && ts->usessnes)  {ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);}
1945     ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr);
1946     ierr = DMTSView(sdm,viewer);CHKERRQ(ierr);
1947   } else if (isstring) {
1948     ierr = TSGetType(ts,&type);CHKERRQ(ierr);
1949     ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr);
1950   } else if (isbinary) {
1951     PetscInt    classid = TS_FILE_CLASSID;
1952     MPI_Comm    comm;
1953     PetscMPIInt rank;
1954     char        type[256];
1955 
1956     ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr);
1957     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
1958     if (!rank) {
1959       ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
1960       ierr = PetscStrncpy(type,((PetscObject)ts)->type_name,256);CHKERRQ(ierr);
1961       ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
1962     }
1963     if (ts->ops->view) {
1964       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1965     }
1966     if (ts->adapt) {ierr = TSAdaptView(ts->adapt,viewer);CHKERRQ(ierr);}
1967     ierr = DMView(ts->dm,viewer);CHKERRQ(ierr);
1968     ierr = VecView(ts->vec_sol,viewer);CHKERRQ(ierr);
1969     ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr);
1970     ierr = DMTSView(sdm,viewer);CHKERRQ(ierr);
1971   } else if (isdraw) {
1972     PetscDraw draw;
1973     char      str[36];
1974     PetscReal x,y,bottom,h;
1975 
1976     ierr   = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1977     ierr   = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
1978     ierr   = PetscStrcpy(str,"TS: ");CHKERRQ(ierr);
1979     ierr   = PetscStrcat(str,((PetscObject)ts)->type_name);CHKERRQ(ierr);
1980     ierr   = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLACK,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr);
1981     bottom = y - h;
1982     ierr   = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
1983     if (ts->ops->view) {
1984       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1985     }
1986     if (ts->adapt) {ierr = TSAdaptView(ts->adapt,viewer);CHKERRQ(ierr);}
1987     if (ts->snes)  {ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr);}
1988     ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr);
1989 #if defined(PETSC_HAVE_SAWS)
1990   } else if (issaws) {
1991     PetscMPIInt rank;
1992     const char  *name;
1993 
1994     ierr = PetscObjectGetName((PetscObject)ts,&name);CHKERRQ(ierr);
1995     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1996     if (!((PetscObject)ts)->amsmem && !rank) {
1997       char       dir[1024];
1998 
1999       ierr = PetscObjectViewSAWs((PetscObject)ts,viewer);CHKERRQ(ierr);
2000       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time_step",name);CHKERRQ(ierr);
2001       PetscStackCallSAWs(SAWs_Register,(dir,&ts->steps,1,SAWs_READ,SAWs_INT));
2002       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time",name);CHKERRQ(ierr);
2003       PetscStackCallSAWs(SAWs_Register,(dir,&ts->ptime,1,SAWs_READ,SAWs_DOUBLE));
2004     }
2005     if (ts->ops->view) {
2006       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
2007     }
2008 #endif
2009   }
2010 
2011   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2012   ierr = PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr);
2013   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2014   PetscFunctionReturn(0);
2015 }
2016 
2017 
2018 /*@
2019    TSSetApplicationContext - Sets an optional user-defined context for
2020    the timesteppers.
2021 
2022    Logically Collective on TS
2023 
2024    Input Parameters:
2025 +  ts - the TS context obtained from TSCreate()
2026 -  usrP - optional user context
2027 
2028    Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this
2029     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
2030 
2031    Level: intermediate
2032 
2033 .keywords: TS, timestep, set, application, context
2034 
2035 .seealso: TSGetApplicationContext()
2036 @*/
2037 PetscErrorCode  TSSetApplicationContext(TS ts,void *usrP)
2038 {
2039   PetscFunctionBegin;
2040   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2041   ts->user = usrP;
2042   PetscFunctionReturn(0);
2043 }
2044 
2045 /*@
2046     TSGetApplicationContext - Gets the user-defined context for the
2047     timestepper.
2048 
2049     Not Collective
2050 
2051     Input Parameter:
2052 .   ts - the TS context obtained from TSCreate()
2053 
2054     Output Parameter:
2055 .   usrP - user context
2056 
2057    Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this
2058     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
2059 
2060     Level: intermediate
2061 
2062 .keywords: TS, timestep, get, application, context
2063 
2064 .seealso: TSSetApplicationContext()
2065 @*/
2066 PetscErrorCode  TSGetApplicationContext(TS ts,void *usrP)
2067 {
2068   PetscFunctionBegin;
2069   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2070   *(void**)usrP = ts->user;
2071   PetscFunctionReturn(0);
2072 }
2073 
2074 /*@
2075    TSGetTimeStepNumber - Gets the number of time steps completed.
2076 
2077    Not Collective
2078 
2079    Input Parameter:
2080 .  ts - the TS context obtained from TSCreate()
2081 
2082    Output Parameter:
2083 .  iter - number of steps completed so far
2084 
2085    Level: intermediate
2086 
2087 .keywords: TS, timestep, get, iteration, number
2088 .seealso: TSGetTime(), TSGetTimeStep(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSSetPostStep()
2089 @*/
2090 PetscErrorCode  TSGetTimeStepNumber(TS ts,PetscInt *iter)
2091 {
2092   PetscFunctionBegin;
2093   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2094   PetscValidIntPointer(iter,2);
2095   *iter = ts->steps;
2096   PetscFunctionReturn(0);
2097 }
2098 
2099 /*@
2100    TSSetInitialTimeStep - Sets the initial timestep to be used,
2101    as well as the initial time.
2102 
2103    Logically Collective on TS
2104 
2105    Input Parameters:
2106 +  ts - the TS context obtained from TSCreate()
2107 .  initial_time - the initial time
2108 -  time_step - the size of the timestep
2109 
2110    Level: intermediate
2111 
2112 .seealso: TSSetTimeStep(), TSGetTimeStep()
2113 
2114 .keywords: TS, set, initial, timestep
2115 @*/
2116 PetscErrorCode  TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step)
2117 {
2118   PetscErrorCode ierr;
2119 
2120   PetscFunctionBegin;
2121   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2122   ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr);
2123   ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr);
2124   PetscFunctionReturn(0);
2125 }
2126 
2127 /*@
2128    TSSetTimeStep - Allows one to reset the timestep at any time,
2129    useful for simple pseudo-timestepping codes.
2130 
2131    Logically Collective on TS
2132 
2133    Input Parameters:
2134 +  ts - the TS context obtained from TSCreate()
2135 -  time_step - the size of the timestep
2136 
2137    Level: intermediate
2138 
2139 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
2140 
2141 .keywords: TS, set, timestep
2142 @*/
2143 PetscErrorCode  TSSetTimeStep(TS ts,PetscReal time_step)
2144 {
2145   PetscFunctionBegin;
2146   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2147   PetscValidLogicalCollectiveReal(ts,time_step,2);
2148   ts->time_step = time_step;
2149   PetscFunctionReturn(0);
2150 }
2151 
2152 /*@
2153    TSSetExactFinalTime - Determines whether to adapt the final time step to
2154      match the exact final time, interpolate solution to the exact final time,
2155      or just return at the final time TS computed.
2156 
2157   Logically Collective on TS
2158 
2159    Input Parameter:
2160 +   ts - the time-step context
2161 -   eftopt - exact final time option
2162 
2163 $  TS_EXACTFINALTIME_STEPOVER    - Don't do anything if final time is exceeded
2164 $  TS_EXACTFINALTIME_INTERPOLATE - Interpolate back to final time
2165 $  TS_EXACTFINALTIME_MATCHSTEP - Adapt final time step to match the final time
2166 
2167    Options Database:
2168 .   -ts_exact_final_time <stepover,interpolate,matchstep> - select the final step at runtime
2169 
2170    Warning: If you use the option TS_EXACTFINALTIME_STEPOVER the solution may be at a very different time
2171     then the final time you selected.
2172 
2173    Level: beginner
2174 
2175 .seealso: TSExactFinalTimeOption
2176 @*/
2177 PetscErrorCode  TSSetExactFinalTime(TS ts,TSExactFinalTimeOption eftopt)
2178 {
2179   PetscFunctionBegin;
2180   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2181   PetscValidLogicalCollectiveEnum(ts,eftopt,2);
2182   ts->exact_final_time = eftopt;
2183   PetscFunctionReturn(0);
2184 }
2185 
2186 /*@
2187    TSGetTimeStep - Gets the current timestep size.
2188 
2189    Not Collective
2190 
2191    Input Parameter:
2192 .  ts - the TS context obtained from TSCreate()
2193 
2194    Output Parameter:
2195 .  dt - the current timestep size
2196 
2197    Level: intermediate
2198 
2199 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
2200 
2201 .keywords: TS, get, timestep
2202 @*/
2203 PetscErrorCode  TSGetTimeStep(TS ts,PetscReal *dt)
2204 {
2205   PetscFunctionBegin;
2206   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2207   PetscValidRealPointer(dt,2);
2208   *dt = ts->time_step;
2209   PetscFunctionReturn(0);
2210 }
2211 
2212 /*@
2213    TSGetSolution - Returns the solution at the present timestep. It
2214    is valid to call this routine inside the function that you are evaluating
2215    in order to move to the new timestep. This vector not changed until
2216    the solution at the next timestep has been calculated.
2217 
2218    Not Collective, but Vec returned is parallel if TS is parallel
2219 
2220    Input Parameter:
2221 .  ts - the TS context obtained from TSCreate()
2222 
2223    Output Parameter:
2224 .  v - the vector containing the solution
2225 
2226    Note: If you used TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP); this does not return the solution at the requested
2227    final time. It returns the solution at the next timestep.
2228 
2229    Level: intermediate
2230 
2231 .seealso: TSGetTimeStep(), TSGetTime(), TSGetSolveTime(), TSGetSolutionComponents()
2232 
2233 .keywords: TS, timestep, get, solution
2234 @*/
2235 PetscErrorCode  TSGetSolution(TS ts,Vec *v)
2236 {
2237   PetscFunctionBegin;
2238   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2239   PetscValidPointer(v,2);
2240   *v = ts->vec_sol;
2241   PetscFunctionReturn(0);
2242 }
2243 
2244 /*@
2245    TSGetSolutionComponents - Returns any solution components at the present
2246    timestep, if available for the time integration method being used.
2247    Solution components are quantities that share the same size and
2248    structure as the solution vector.
2249 
2250    Not Collective, but Vec returned is parallel if TS is parallel
2251 
2252    Parameters :
2253 .  ts - the TS context obtained from TSCreate() (input parameter).
2254 .  n - If v is PETSC_NULL, then the number of solution components is
2255        returned through n, else the n-th solution component is
2256        returned in v.
2257 .  v - the vector containing the n-th solution component
2258        (may be PETSC_NULL to use this function to find out
2259         the number of solutions components).
2260 
2261    Level: advanced
2262 
2263 .seealso: TSGetSolution()
2264 
2265 .keywords: TS, timestep, get, solution
2266 @*/
2267 PetscErrorCode  TSGetSolutionComponents(TS ts,PetscInt *n,Vec *v)
2268 {
2269   PetscErrorCode ierr;
2270 
2271   PetscFunctionBegin;
2272   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2273   if (!ts->ops->getsolutioncomponents) *n = 0;
2274   else {
2275     ierr = (*ts->ops->getsolutioncomponents)(ts,n,v);CHKERRQ(ierr);
2276   }
2277   PetscFunctionReturn(0);
2278 }
2279 
2280 /*@
2281    TSGetAuxSolution - Returns an auxiliary solution at the present
2282    timestep, if available for the time integration method being used.
2283 
2284    Not Collective, but Vec returned is parallel if TS is parallel
2285 
2286    Parameters :
2287 .  ts - the TS context obtained from TSCreate() (input parameter).
2288 .  v - the vector containing the auxiliary solution
2289 
2290    Level: intermediate
2291 
2292 .seealso: TSGetSolution()
2293 
2294 .keywords: TS, timestep, get, solution
2295 @*/
2296 PetscErrorCode  TSGetAuxSolution(TS ts,Vec *v)
2297 {
2298   PetscErrorCode ierr;
2299 
2300   PetscFunctionBegin;
2301   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2302   if (ts->ops->getauxsolution) {
2303     ierr = (*ts->ops->getauxsolution)(ts,v);CHKERRQ(ierr);
2304   } else {
2305     ierr = VecZeroEntries(*v); CHKERRQ(ierr);
2306   }
2307   PetscFunctionReturn(0);
2308 }
2309 
2310 /*@
2311    TSGetTimeError - Returns the estimated error vector, if the chosen
2312    TSType has an error estimation functionality.
2313 
2314    Not Collective, but Vec returned is parallel if TS is parallel
2315 
2316    Note: MUST call after TSSetUp()
2317 
2318    Parameters :
2319 .  ts - the TS context obtained from TSCreate() (input parameter).
2320 .  n - current estimate (n=0) or previous one (n=-1)
2321 .  v - the vector containing the error (same size as the solution).
2322 
2323    Level: intermediate
2324 
2325 .seealso: TSGetSolution(), TSSetTimeError()
2326 
2327 .keywords: TS, timestep, get, error
2328 @*/
2329 PetscErrorCode  TSGetTimeError(TS ts,PetscInt n,Vec *v)
2330 {
2331   PetscErrorCode ierr;
2332 
2333   PetscFunctionBegin;
2334   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2335   if (ts->ops->gettimeerror) {
2336     ierr = (*ts->ops->gettimeerror)(ts,n,v);CHKERRQ(ierr);
2337   } else {
2338     ierr = VecZeroEntries(*v);CHKERRQ(ierr);
2339   }
2340   PetscFunctionReturn(0);
2341 }
2342 
2343 /*@
2344    TSSetTimeError - Sets the estimated error vector, if the chosen
2345    TSType has an error estimation functionality. This can be used
2346    to restart such a time integrator with a given error vector.
2347 
2348    Not Collective, but Vec returned is parallel if TS is parallel
2349 
2350    Parameters :
2351 .  ts - the TS context obtained from TSCreate() (input parameter).
2352 .  v - the vector containing the error (same size as the solution).
2353 
2354    Level: intermediate
2355 
2356 .seealso: TSSetSolution(), TSGetTimeError)
2357 
2358 .keywords: TS, timestep, get, error
2359 @*/
2360 PetscErrorCode  TSSetTimeError(TS ts,Vec v)
2361 {
2362   PetscErrorCode ierr;
2363 
2364   PetscFunctionBegin;
2365   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2366   if (!ts->setupcalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetUp() first");
2367   if (ts->ops->settimeerror) {
2368     ierr = (*ts->ops->settimeerror)(ts,v);CHKERRQ(ierr);
2369   }
2370   PetscFunctionReturn(0);
2371 }
2372 
2373 /*@
2374    TSGetCostGradients - Returns the gradients from the TSAdjointSolve()
2375 
2376    Not Collective, but Vec returned is parallel if TS is parallel
2377 
2378    Input Parameter:
2379 .  ts - the TS context obtained from TSCreate()
2380 
2381    Output Parameter:
2382 +  lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables
2383 -  mu - vectors containing the gradients of the cost functions with respect to the problem parameters
2384 
2385    Level: intermediate
2386 
2387 .seealso: TSGetTimeStep()
2388 
2389 .keywords: TS, timestep, get, sensitivity
2390 @*/
2391 PetscErrorCode  TSGetCostGradients(TS ts,PetscInt *numcost,Vec **lambda,Vec **mu)
2392 {
2393   PetscFunctionBegin;
2394   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2395   if (numcost) *numcost = ts->numcost;
2396   if (lambda)  *lambda  = ts->vecs_sensi;
2397   if (mu)      *mu      = ts->vecs_sensip;
2398   PetscFunctionReturn(0);
2399 }
2400 
2401 /* ----- Routines to initialize and destroy a timestepper ---- */
2402 /*@
2403   TSSetProblemType - Sets the type of problem to be solved.
2404 
2405   Not collective
2406 
2407   Input Parameters:
2408 + ts   - The TS
2409 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
2410 .vb
2411          U_t - A U = 0      (linear)
2412          U_t - A(t) U = 0   (linear)
2413          F(t,U,U_t) = 0     (nonlinear)
2414 .ve
2415 
2416    Level: beginner
2417 
2418 .keywords: TS, problem type
2419 .seealso: TSSetUp(), TSProblemType, TS
2420 @*/
2421 PetscErrorCode  TSSetProblemType(TS ts, TSProblemType type)
2422 {
2423   PetscErrorCode ierr;
2424 
2425   PetscFunctionBegin;
2426   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2427   ts->problem_type = type;
2428   if (type == TS_LINEAR) {
2429     SNES snes;
2430     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2431     ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);
2432   }
2433   PetscFunctionReturn(0);
2434 }
2435 
2436 /*@C
2437   TSGetProblemType - Gets the type of problem to be solved.
2438 
2439   Not collective
2440 
2441   Input Parameter:
2442 . ts   - The TS
2443 
2444   Output Parameter:
2445 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
2446 .vb
2447          M U_t = A U
2448          M(t) U_t = A(t) U
2449          F(t,U,U_t)
2450 .ve
2451 
2452    Level: beginner
2453 
2454 .keywords: TS, problem type
2455 .seealso: TSSetUp(), TSProblemType, TS
2456 @*/
2457 PetscErrorCode  TSGetProblemType(TS ts, TSProblemType *type)
2458 {
2459   PetscFunctionBegin;
2460   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2461   PetscValidIntPointer(type,2);
2462   *type = ts->problem_type;
2463   PetscFunctionReturn(0);
2464 }
2465 
2466 /*@
2467    TSSetUp - Sets up the internal data structures for the later use
2468    of a timestepper.
2469 
2470    Collective on TS
2471 
2472    Input Parameter:
2473 .  ts - the TS context obtained from TSCreate()
2474 
2475    Notes:
2476    For basic use of the TS solvers the user need not explicitly call
2477    TSSetUp(), since these actions will automatically occur during
2478    the call to TSStep().  However, if one wishes to control this
2479    phase separately, TSSetUp() should be called after TSCreate()
2480    and optional routines of the form TSSetXXX(), but before TSStep().
2481 
2482    Level: advanced
2483 
2484 .keywords: TS, timestep, setup
2485 
2486 .seealso: TSCreate(), TSStep(), TSDestroy()
2487 @*/
2488 PetscErrorCode  TSSetUp(TS ts)
2489 {
2490   PetscErrorCode ierr;
2491   DM             dm;
2492   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
2493   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
2494   TSIFunction    ifun;
2495   TSIJacobian    ijac;
2496   TSI2Jacobian   i2jac;
2497   TSRHSJacobian  rhsjac;
2498   PetscBool      isnone;
2499 
2500   PetscFunctionBegin;
2501   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2502   if (ts->setupcalled) PetscFunctionReturn(0);
2503 
2504   if (!((PetscObject)ts)->type_name) {
2505     ierr = TSGetIFunction(ts,NULL,&ifun,NULL);CHKERRQ(ierr);
2506     ierr = TSSetType(ts,ifun ? TSBEULER : TSEULER);CHKERRQ(ierr);
2507   }
2508 
2509   if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first");
2510 
2511   if (ts->rhsjacobian.reuse) {
2512     Mat Amat,Pmat;
2513     SNES snes;
2514     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2515     ierr = SNESGetJacobian(snes,&Amat,&Pmat,NULL,NULL);CHKERRQ(ierr);
2516     /* Matching matrices implies that an IJacobian is NOT set, because if it had been set, the IJacobian's matrix would
2517      * have displaced the RHS matrix */
2518     if (Amat == ts->Arhs) {
2519       ierr = MatDuplicate(ts->Arhs,MAT_DO_NOT_COPY_VALUES,&Amat);CHKERRQ(ierr);
2520       ierr = SNESSetJacobian(snes,Amat,NULL,NULL,NULL);CHKERRQ(ierr);
2521       ierr = MatDestroy(&Amat);CHKERRQ(ierr);
2522     }
2523     if (Pmat == ts->Brhs) {
2524       ierr = MatDuplicate(ts->Brhs,MAT_DO_NOT_COPY_VALUES,&Pmat);CHKERRQ(ierr);
2525       ierr = SNESSetJacobian(snes,NULL,Pmat,NULL,NULL);CHKERRQ(ierr);
2526       ierr = MatDestroy(&Pmat);CHKERRQ(ierr);
2527     }
2528   }
2529 
2530   ierr = TSGetAdapt(ts,&ts->adapt);CHKERRQ(ierr);
2531   ierr = TSAdaptSetDefaultType(ts->adapt,ts->default_adapt_type);CHKERRQ(ierr);
2532 
2533   if (ts->ops->setup) {
2534     ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr);
2535   }
2536 
2537   /* Attempt to check/preset a default value for the exact final time option */
2538   ierr = PetscObjectTypeCompare((PetscObject)ts->adapt,TSADAPTNONE,&isnone);CHKERRQ(ierr);
2539   if (!isnone && ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED)
2540     ts->exact_final_time = TS_EXACTFINALTIME_MATCHSTEP;
2541 
2542   /* In the case where we've set a DMTSFunction or what have you, we need the default SNESFunction
2543      to be set right but can't do it elsewhere due to the overreliance on ctx=ts.
2544    */
2545   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2546   ierr = DMSNESGetFunction(dm,&func,NULL);CHKERRQ(ierr);
2547   if (!func) {
2548     ierr = DMSNESSetFunction(dm,SNESTSFormFunction,ts);CHKERRQ(ierr);
2549   }
2550   /* If the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it.
2551      Otherwise, the SNES will use coloring internally to form the Jacobian.
2552    */
2553   ierr = DMSNESGetJacobian(dm,&jac,NULL);CHKERRQ(ierr);
2554   ierr = DMTSGetIJacobian(dm,&ijac,NULL);CHKERRQ(ierr);
2555   ierr = DMTSGetI2Jacobian(dm,&i2jac,NULL);CHKERRQ(ierr);
2556   ierr = DMTSGetRHSJacobian(dm,&rhsjac,NULL);CHKERRQ(ierr);
2557   if (!jac && (ijac || i2jac || rhsjac)) {
2558     ierr = DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);CHKERRQ(ierr);
2559   }
2560 
2561   /* if time integration scheme has a starting method, call it */
2562   if (ts->ops->startingmethod) {
2563     ierr = (*ts->ops->startingmethod)(ts);CHKERRQ(ierr);
2564   }
2565 
2566   ts->setupcalled = PETSC_TRUE;
2567   PetscFunctionReturn(0);
2568 }
2569 
2570 /*@
2571    TSAdjointSetUp - Sets up the internal data structures for the later use
2572    of an adjoint solver
2573 
2574    Collective on TS
2575 
2576    Input Parameter:
2577 .  ts - the TS context obtained from TSCreate()
2578 
2579    Level: advanced
2580 
2581 .keywords: TS, timestep, setup
2582 
2583 .seealso: TSCreate(), TSAdjointStep(), TSSetCostGradients()
2584 @*/
2585 PetscErrorCode  TSAdjointSetUp(TS ts)
2586 {
2587   PetscErrorCode ierr;
2588 
2589   PetscFunctionBegin;
2590   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2591   if (ts->adjointsetupcalled) PetscFunctionReturn(0);
2592   if (!ts->vecs_sensi) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetCostGradients() first");
2593 
2594   if (ts->vec_costintegral) { /* if there is integral in the cost function*/
2595     ierr = VecDuplicateVecs(ts->vecs_sensi[0],ts->numcost,&ts->vecs_drdy);CHKERRQ(ierr);
2596     if (ts->vecs_sensip){
2597       ierr = VecDuplicateVecs(ts->vecs_sensip[0],ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr);
2598     }
2599   }
2600 
2601   if (ts->ops->adjointsetup) {
2602     ierr = (*ts->ops->adjointsetup)(ts);CHKERRQ(ierr);
2603   }
2604   ts->adjointsetupcalled = PETSC_TRUE;
2605   PetscFunctionReturn(0);
2606 }
2607 
2608 /*@
2609    TSReset - Resets a TS context and removes any allocated Vecs and Mats.
2610 
2611    Collective on TS
2612 
2613    Input Parameter:
2614 .  ts - the TS context obtained from TSCreate()
2615 
2616    Level: beginner
2617 
2618 .keywords: TS, timestep, reset
2619 
2620 .seealso: TSCreate(), TSSetup(), TSDestroy()
2621 @*/
2622 PetscErrorCode  TSReset(TS ts)
2623 {
2624   PetscErrorCode ierr;
2625 
2626   PetscFunctionBegin;
2627   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2628 
2629   if (ts->ops->reset) {
2630     ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr);
2631   }
2632   if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);}
2633   if (ts->adapt) {ierr = TSAdaptReset(ts->adapt);CHKERRQ(ierr);}
2634 
2635   ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr);
2636   ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr);
2637   ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr);
2638   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
2639   ierr = VecDestroy(&ts->vec_dot);CHKERRQ(ierr);
2640   ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
2641   ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
2642   ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr);
2643 
2644  if (ts->vec_costintegral) {
2645     ierr = VecDestroyVecs(ts->numcost,&ts->vecs_drdy);CHKERRQ(ierr);
2646     if (ts->vecs_drdp){
2647       ierr = VecDestroyVecs(ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr);
2648     }
2649   }
2650   ts->vecs_sensi  = NULL;
2651   ts->vecs_sensip = NULL;
2652   ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr);
2653   ierr = VecDestroy(&ts->vec_costintegral);CHKERRQ(ierr);
2654   ierr = VecDestroy(&ts->vec_costintegrand);CHKERRQ(ierr);
2655   ts->setupcalled = PETSC_FALSE;
2656   PetscFunctionReturn(0);
2657 }
2658 
2659 /*@
2660    TSDestroy - Destroys the timestepper context that was created
2661    with TSCreate().
2662 
2663    Collective on TS
2664 
2665    Input Parameter:
2666 .  ts - the TS context obtained from TSCreate()
2667 
2668    Level: beginner
2669 
2670 .keywords: TS, timestepper, destroy
2671 
2672 .seealso: TSCreate(), TSSetUp(), TSSolve()
2673 @*/
2674 PetscErrorCode  TSDestroy(TS *ts)
2675 {
2676   PetscErrorCode ierr;
2677 
2678   PetscFunctionBegin;
2679   if (!*ts) PetscFunctionReturn(0);
2680   PetscValidHeaderSpecific((*ts),TS_CLASSID,1);
2681   if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);}
2682 
2683   ierr = TSReset((*ts));CHKERRQ(ierr);
2684 
2685   /* if memory was published with SAWs then destroy it */
2686   ierr = PetscObjectSAWsViewOff((PetscObject)*ts);CHKERRQ(ierr);
2687   if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);}
2688 
2689   ierr = TSTrajectoryDestroy(&(*ts)->trajectory);CHKERRQ(ierr);
2690 
2691   ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr);
2692   ierr = TSEventDestroy(&(*ts)->event);CHKERRQ(ierr);
2693 
2694   ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr);
2695   ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr);
2696   ierr = TSMonitorCancel((*ts));CHKERRQ(ierr);
2697   ierr = TSAdjointMonitorCancel((*ts));CHKERRQ(ierr);
2698 
2699   ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr);
2700   PetscFunctionReturn(0);
2701 }
2702 
2703 /*@
2704    TSGetSNES - Returns the SNES (nonlinear solver) associated with
2705    a TS (timestepper) context. Valid only for nonlinear problems.
2706 
2707    Not Collective, but SNES is parallel if TS is parallel
2708 
2709    Input Parameter:
2710 .  ts - the TS context obtained from TSCreate()
2711 
2712    Output Parameter:
2713 .  snes - the nonlinear solver context
2714 
2715    Notes:
2716    The user can then directly manipulate the SNES context to set various
2717    options, etc.  Likewise, the user can then extract and manipulate the
2718    KSP, KSP, and PC contexts as well.
2719 
2720    TSGetSNES() does not work for integrators that do not use SNES; in
2721    this case TSGetSNES() returns NULL in snes.
2722 
2723    Level: beginner
2724 
2725 .keywords: timestep, get, SNES
2726 @*/
2727 PetscErrorCode  TSGetSNES(TS ts,SNES *snes)
2728 {
2729   PetscErrorCode ierr;
2730 
2731   PetscFunctionBegin;
2732   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2733   PetscValidPointer(snes,2);
2734   if (!ts->snes) {
2735     ierr = SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);CHKERRQ(ierr);
2736     ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr);
2737     ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->snes);CHKERRQ(ierr);
2738     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr);
2739     if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
2740     if (ts->problem_type == TS_LINEAR) {
2741       ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr);
2742     }
2743   }
2744   *snes = ts->snes;
2745   PetscFunctionReturn(0);
2746 }
2747 
2748 /*@
2749    TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context
2750 
2751    Collective
2752 
2753    Input Parameter:
2754 +  ts - the TS context obtained from TSCreate()
2755 -  snes - the nonlinear solver context
2756 
2757    Notes:
2758    Most users should have the TS created by calling TSGetSNES()
2759 
2760    Level: developer
2761 
2762 .keywords: timestep, set, SNES
2763 @*/
2764 PetscErrorCode TSSetSNES(TS ts,SNES snes)
2765 {
2766   PetscErrorCode ierr;
2767   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
2768 
2769   PetscFunctionBegin;
2770   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2771   PetscValidHeaderSpecific(snes,SNES_CLASSID,2);
2772   ierr = PetscObjectReference((PetscObject)snes);CHKERRQ(ierr);
2773   ierr = SNESDestroy(&ts->snes);CHKERRQ(ierr);
2774 
2775   ts->snes = snes;
2776 
2777   ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr);
2778   ierr = SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);CHKERRQ(ierr);
2779   if (func == SNESTSFormJacobian) {
2780     ierr = SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);CHKERRQ(ierr);
2781   }
2782   PetscFunctionReturn(0);
2783 }
2784 
2785 /*@
2786    TSGetKSP - Returns the KSP (linear solver) associated with
2787    a TS (timestepper) context.
2788 
2789    Not Collective, but KSP is parallel if TS is parallel
2790 
2791    Input Parameter:
2792 .  ts - the TS context obtained from TSCreate()
2793 
2794    Output Parameter:
2795 .  ksp - the nonlinear solver context
2796 
2797    Notes:
2798    The user can then directly manipulate the KSP context to set various
2799    options, etc.  Likewise, the user can then extract and manipulate the
2800    KSP and PC contexts as well.
2801 
2802    TSGetKSP() does not work for integrators that do not use KSP;
2803    in this case TSGetKSP() returns NULL in ksp.
2804 
2805    Level: beginner
2806 
2807 .keywords: timestep, get, KSP
2808 @*/
2809 PetscErrorCode  TSGetKSP(TS ts,KSP *ksp)
2810 {
2811   PetscErrorCode ierr;
2812   SNES           snes;
2813 
2814   PetscFunctionBegin;
2815   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2816   PetscValidPointer(ksp,2);
2817   if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first");
2818   if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()");
2819   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2820   ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr);
2821   PetscFunctionReturn(0);
2822 }
2823 
2824 /* ----------- Routines to set solver parameters ---------- */
2825 
2826 /*@
2827    TSGetDuration - Gets the maximum number of timesteps to use and
2828    maximum time for iteration.
2829 
2830    Not Collective
2831 
2832    Input Parameters:
2833 +  ts       - the TS context obtained from TSCreate()
2834 .  maxsteps - maximum number of iterations to use, or NULL
2835 -  maxtime  - final time to iterate to, or NULL
2836 
2837    Level: intermediate
2838 
2839 .keywords: TS, timestep, get, maximum, iterations, time
2840 @*/
2841 PetscErrorCode  TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
2842 {
2843   PetscFunctionBegin;
2844   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2845   if (maxsteps) {
2846     PetscValidIntPointer(maxsteps,2);
2847     *maxsteps = ts->max_steps;
2848   }
2849   if (maxtime) {
2850     PetscValidScalarPointer(maxtime,3);
2851     *maxtime = ts->max_time;
2852   }
2853   PetscFunctionReturn(0);
2854 }
2855 
2856 /*@
2857    TSSetDuration - Sets the maximum number of timesteps to use and
2858    maximum time for iteration.
2859 
2860    Logically Collective on TS
2861 
2862    Input Parameters:
2863 +  ts - the TS context obtained from TSCreate()
2864 .  maxsteps - maximum number of iterations to use
2865 -  maxtime - final time to iterate to
2866 
2867    Options Database Keys:
2868 .  -ts_max_steps <maxsteps> - Sets maxsteps
2869 .  -ts_final_time <maxtime> - Sets maxtime
2870 
2871    Notes:
2872    The default maximum number of iterations is 5000. Default time is 5.0
2873 
2874    Level: intermediate
2875 
2876 .keywords: TS, timestep, set, maximum, iterations
2877 
2878 .seealso: TSSetExactFinalTime()
2879 @*/
2880 PetscErrorCode  TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime)
2881 {
2882   PetscFunctionBegin;
2883   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2884   PetscValidLogicalCollectiveInt(ts,maxsteps,2);
2885   PetscValidLogicalCollectiveReal(ts,maxtime,2);
2886   if (maxsteps >= 0) ts->max_steps = maxsteps;
2887   if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime;
2888   PetscFunctionReturn(0);
2889 }
2890 
2891 /*@
2892    TSSetSolution - Sets the initial solution vector
2893    for use by the TS routines.
2894 
2895    Logically Collective on TS and Vec
2896 
2897    Input Parameters:
2898 +  ts - the TS context obtained from TSCreate()
2899 -  u - the solution vector
2900 
2901    Level: beginner
2902 
2903 .keywords: TS, timestep, set, solution, initial conditions
2904 @*/
2905 PetscErrorCode  TSSetSolution(TS ts,Vec u)
2906 {
2907   PetscErrorCode ierr;
2908   DM             dm;
2909 
2910   PetscFunctionBegin;
2911   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2912   PetscValidHeaderSpecific(u,VEC_CLASSID,2);
2913   ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr);
2914   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
2915   ts->vec_sol = u;
2916 
2917   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2918   ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr);
2919   PetscFunctionReturn(0);
2920 }
2921 
2922 /*@
2923    TSAdjointSetSteps - Sets the number of steps the adjoint solver should take backward in time
2924 
2925    Logically Collective on TS
2926 
2927    Input Parameters:
2928 +  ts - the TS context obtained from TSCreate()
2929 .  steps - number of steps to use
2930 
2931    Level: intermediate
2932 
2933    Notes: Normally one does not call this and TSAdjointSolve() integrates back to the original timestep. One can call this
2934           so as to integrate back to less than the original timestep
2935 
2936 .keywords: TS, timestep, set, maximum, iterations
2937 
2938 .seealso: TSSetExactFinalTime()
2939 @*/
2940 PetscErrorCode  TSAdjointSetSteps(TS ts,PetscInt steps)
2941 {
2942   PetscFunctionBegin;
2943   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2944   PetscValidLogicalCollectiveInt(ts,steps,2);
2945   if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back a negative number of steps");
2946   if (steps > ts->total_steps) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back more than the total number of forward steps");
2947   ts->adjoint_max_steps = steps;
2948   PetscFunctionReturn(0);
2949 }
2950 
2951 /*@
2952    TSSetCostGradients - Sets the initial value of the gradients of the cost function w.r.t. initial conditions and w.r.t. the problem parameters
2953       for use by the TSAdjoint routines.
2954 
2955    Logically Collective on TS and Vec
2956 
2957    Input Parameters:
2958 +  ts - the TS context obtained from TSCreate()
2959 .  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
2960 -  mu - gradients with respect to the parameters, the number of entries in these vectors is the same as the number of parameters
2961 
2962    Level: beginner
2963 
2964    Notes: the entries in these vectors must be correctly initialized with the values lamda_i = df/dy|finaltime  mu_i = df/dp|finaltime
2965 
2966 .keywords: TS, timestep, set, sensitivity, initial conditions
2967 @*/
2968 PetscErrorCode  TSSetCostGradients(TS ts,PetscInt numcost,Vec *lambda,Vec *mu)
2969 {
2970   PetscFunctionBegin;
2971   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2972   PetscValidPointer(lambda,2);
2973   ts->vecs_sensi  = lambda;
2974   ts->vecs_sensip = mu;
2975   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");
2976   ts->numcost  = numcost;
2977   PetscFunctionReturn(0);
2978 }
2979 
2980 /*@C
2981   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.
2982 
2983   Logically Collective on TS
2984 
2985   Input Parameters:
2986 + ts   - The TS context obtained from TSCreate()
2987 - func - The function
2988 
2989   Calling sequence of func:
2990 $ func (TS ts,PetscReal t,Vec y,Mat A,void *ctx);
2991 +   t - current timestep
2992 .   y - input vector (current ODE solution)
2993 .   A - output matrix
2994 -   ctx - [optional] user-defined function context
2995 
2996   Level: intermediate
2997 
2998   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
2999 
3000 .keywords: TS, sensitivity
3001 .seealso:
3002 @*/
3003 PetscErrorCode  TSAdjointSetRHSJacobian(TS ts,Mat Amat,PetscErrorCode (*func)(TS,PetscReal,Vec,Mat,void*),void *ctx)
3004 {
3005   PetscErrorCode ierr;
3006 
3007   PetscFunctionBegin;
3008   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3009   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
3010 
3011   ts->rhsjacobianp    = func;
3012   ts->rhsjacobianpctx = ctx;
3013   if(Amat) {
3014     ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr);
3015     ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr);
3016     ts->Jacp = Amat;
3017   }
3018   PetscFunctionReturn(0);
3019 }
3020 
3021 /*@C
3022   TSAdjointComputeRHSJacobian - Runs the user-defined Jacobian function.
3023 
3024   Collective on TS
3025 
3026   Input Parameters:
3027 . ts   - The TS context obtained from TSCreate()
3028 
3029   Level: developer
3030 
3031 .keywords: TS, sensitivity
3032 .seealso: TSAdjointSetRHSJacobian()
3033 @*/
3034 PetscErrorCode  TSAdjointComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat Amat)
3035 {
3036   PetscErrorCode ierr;
3037 
3038   PetscFunctionBegin;
3039   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3040   PetscValidHeaderSpecific(X,VEC_CLASSID,3);
3041   PetscValidPointer(Amat,4);
3042 
3043   PetscStackPush("TS user JacobianP function for sensitivity analysis");
3044   ierr = (*ts->rhsjacobianp)(ts,t,X,Amat,ts->rhsjacobianpctx); CHKERRQ(ierr);
3045   PetscStackPop;
3046   PetscFunctionReturn(0);
3047 }
3048 
3049 /*@C
3050     TSSetCostIntegrand - Sets the routine for evaluating the integral term in one or more cost functions
3051 
3052     Logically Collective on TS
3053 
3054     Input Parameters:
3055 +   ts - the TS context obtained from TSCreate()
3056 .   numcost - number of gradients to be computed, this is the number of cost functions
3057 .   rf - routine for evaluating the integrand function
3058 .   drdyf - function that computes the gradients of the r's with respect to y,NULL if not a function y
3059 .   drdpf - function that computes the gradients of the r's with respect to p, NULL if not a function of p
3060 .   fwd - flag indicating whether to evaluate cost integral in the forward run or the adjoint run
3061 -   ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
3062 
3063     Calling sequence of rf:
3064 $     rf(TS ts,PetscReal t,Vec y,Vec f[],void *ctx);
3065 
3066 +   t - current timestep
3067 .   y - input vector
3068 .   f - function result; one vector entry for each cost function
3069 -   ctx - [optional] user-defined function context
3070 
3071    Calling sequence of drdyf:
3072 $    PetscErroCode drdyf(TS ts,PetscReal t,Vec y,Vec *drdy,void *ctx);
3073 
3074    Calling sequence of drdpf:
3075 $    PetscErroCode drdpf(TS ts,PetscReal t,Vec y,Vec *drdp,void *ctx);
3076 
3077     Level: intermediate
3078 
3079     Notes: For optimization there is generally a single cost function, numcost = 1. For sensitivities there may be multiple cost functions
3080 
3081 .keywords: TS, sensitivity analysis, timestep, set, quadrature, function
3082 
3083 .seealso: TSAdjointSetRHSJacobian(),TSGetCostGradients(), TSSetCostGradients()
3084 @*/
3085 PetscErrorCode  TSSetCostIntegrand(TS ts,PetscInt numcost,PetscErrorCode (*rf)(TS,PetscReal,Vec,Vec,void*),
3086                                                           PetscErrorCode (*drdyf)(TS,PetscReal,Vec,Vec*,void*),
3087                                                           PetscErrorCode (*drdpf)(TS,PetscReal,Vec,Vec*,void*),
3088                                                           PetscBool fwd,void *ctx)
3089 {
3090   PetscErrorCode ierr;
3091 
3092   PetscFunctionBegin;
3093   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3094   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()");
3095   if (!ts->numcost) ts->numcost=numcost;
3096 
3097   ts->costintegralfwd  = fwd; /* Evaluate the cost integral in forward run if fwd is true */
3098   ierr                 = VecCreateSeq(PETSC_COMM_SELF,numcost,&ts->vec_costintegral);CHKERRQ(ierr);
3099   ierr                 = VecDuplicate(ts->vec_costintegral,&ts->vec_costintegrand);CHKERRQ(ierr);
3100   ts->costintegrand    = rf;
3101   ts->costintegrandctx = ctx;
3102   ts->drdyfunction     = drdyf;
3103   ts->drdpfunction     = drdpf;
3104   PetscFunctionReturn(0);
3105 }
3106 
3107 /*@
3108    TSGetCostIntegral - Returns the values of the integral term in the cost functions.
3109    It is valid to call the routine after a backward run.
3110 
3111    Not Collective
3112 
3113    Input Parameter:
3114 .  ts - the TS context obtained from TSCreate()
3115 
3116    Output Parameter:
3117 .  v - the vector containing the integrals for each cost function
3118 
3119    Level: intermediate
3120 
3121 .seealso: TSSetCostIntegrand()
3122 
3123 .keywords: TS, sensitivity analysis
3124 @*/
3125 PetscErrorCode  TSGetCostIntegral(TS ts,Vec *v)
3126 {
3127   PetscFunctionBegin;
3128   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3129   PetscValidPointer(v,2);
3130   *v = ts->vec_costintegral;
3131   PetscFunctionReturn(0);
3132 }
3133 
3134 /*@
3135    TSAdjointComputeCostIntegrand - Evaluates the integral function in the cost functions.
3136 
3137    Input Parameters:
3138 +  ts - the TS context
3139 .  t - current time
3140 -  y - state vector, i.e. current solution
3141 
3142    Output Parameter:
3143 .  q - vector of size numcost to hold the outputs
3144 
3145    Note:
3146    Most users should not need to explicitly call this routine, as it
3147    is used internally within the sensitivity analysis context.
3148 
3149    Level: developer
3150 
3151 .keywords: TS, compute
3152 
3153 .seealso: TSSetCostIntegrand()
3154 @*/
3155 PetscErrorCode TSAdjointComputeCostIntegrand(TS ts,PetscReal t,Vec y,Vec q)
3156 {
3157   PetscErrorCode ierr;
3158 
3159   PetscFunctionBegin;
3160   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3161   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
3162   PetscValidHeaderSpecific(q,VEC_CLASSID,4);
3163 
3164   ierr = PetscLogEventBegin(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr);
3165   if (ts->costintegrand) {
3166     PetscStackPush("TS user integrand in the cost function");
3167     ierr = (*ts->costintegrand)(ts,t,y,q,ts->costintegrandctx);CHKERRQ(ierr);
3168     PetscStackPop;
3169   } else {
3170     ierr = VecZeroEntries(q);CHKERRQ(ierr);
3171   }
3172 
3173   ierr = PetscLogEventEnd(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr);
3174   PetscFunctionReturn(0);
3175 }
3176 
3177 /*@
3178   TSAdjointComputeDRDYFunction - Runs the user-defined DRDY function.
3179 
3180   Collective on TS
3181 
3182   Input Parameters:
3183 . ts   - The TS context obtained from TSCreate()
3184 
3185   Notes:
3186   TSAdjointComputeDRDYFunction() is typically used for sensitivity implementation,
3187   so most users would not generally call this routine themselves.
3188 
3189   Level: developer
3190 
3191 .keywords: TS, sensitivity
3192 .seealso: TSAdjointComputeDRDYFunction()
3193 @*/
3194 PetscErrorCode  TSAdjointComputeDRDYFunction(TS ts,PetscReal t,Vec y,Vec *drdy)
3195 {
3196   PetscErrorCode ierr;
3197 
3198   PetscFunctionBegin;
3199   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3200   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
3201 
3202   PetscStackPush("TS user DRDY function for sensitivity analysis");
3203   ierr = (*ts->drdyfunction)(ts,t,y,drdy,ts->costintegrandctx); CHKERRQ(ierr);
3204   PetscStackPop;
3205   PetscFunctionReturn(0);
3206 }
3207 
3208 /*@
3209   TSAdjointComputeDRDPFunction - Runs the user-defined DRDP function.
3210 
3211   Collective on TS
3212 
3213   Input Parameters:
3214 . ts   - The TS context obtained from TSCreate()
3215 
3216   Notes:
3217   TSDRDPFunction() is typically used for sensitivity implementation,
3218   so most users would not generally call this routine themselves.
3219 
3220   Level: developer
3221 
3222 .keywords: TS, sensitivity
3223 .seealso: TSAdjointSetDRDPFunction()
3224 @*/
3225 PetscErrorCode  TSAdjointComputeDRDPFunction(TS ts,PetscReal t,Vec y,Vec *drdp)
3226 {
3227   PetscErrorCode ierr;
3228 
3229   PetscFunctionBegin;
3230   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3231   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
3232 
3233   PetscStackPush("TS user DRDP function for sensitivity analysis");
3234   ierr = (*ts->drdpfunction)(ts,t,y,drdp,ts->costintegrandctx); CHKERRQ(ierr);
3235   PetscStackPop;
3236   PetscFunctionReturn(0);
3237 }
3238 
3239 /*@C
3240   TSSetPreStep - Sets the general-purpose function
3241   called once at the beginning of each time step.
3242 
3243   Logically Collective on TS
3244 
3245   Input Parameters:
3246 + ts   - The TS context obtained from TSCreate()
3247 - func - The function
3248 
3249   Calling sequence of func:
3250 . func (TS ts);
3251 
3252   Level: intermediate
3253 
3254 .keywords: TS, timestep
3255 .seealso: TSSetPreStage(), TSSetPostStage(), TSSetPostStep(), TSStep()
3256 @*/
3257 PetscErrorCode  TSSetPreStep(TS ts, PetscErrorCode (*func)(TS))
3258 {
3259   PetscFunctionBegin;
3260   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3261   ts->prestep = func;
3262   PetscFunctionReturn(0);
3263 }
3264 
3265 /*@
3266   TSPreStep - Runs the user-defined pre-step function.
3267 
3268   Collective on TS
3269 
3270   Input Parameters:
3271 . ts   - The TS context obtained from TSCreate()
3272 
3273   Notes:
3274   TSPreStep() is typically used within time stepping implementations,
3275   so most users would not generally call this routine themselves.
3276 
3277   Level: developer
3278 
3279 .keywords: TS, timestep
3280 .seealso: TSSetPreStep(), TSPreStage(), TSPostStage(), TSPostStep()
3281 @*/
3282 PetscErrorCode  TSPreStep(TS ts)
3283 {
3284   PetscErrorCode ierr;
3285 
3286   PetscFunctionBegin;
3287   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3288   if (ts->prestep) {
3289     PetscStackCallStandard((*ts->prestep),(ts));
3290   }
3291   PetscFunctionReturn(0);
3292 }
3293 
3294 /*@C
3295   TSSetPreStage - Sets the general-purpose function
3296   called once at the beginning of each stage.
3297 
3298   Logically Collective on TS
3299 
3300   Input Parameters:
3301 + ts   - The TS context obtained from TSCreate()
3302 - func - The function
3303 
3304   Calling sequence of func:
3305 . PetscErrorCode func(TS ts, PetscReal stagetime);
3306 
3307   Level: intermediate
3308 
3309   Note:
3310   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
3311   The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being
3312   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
3313 
3314 .keywords: TS, timestep
3315 .seealso: TSSetPostStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
3316 @*/
3317 PetscErrorCode  TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal))
3318 {
3319   PetscFunctionBegin;
3320   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3321   ts->prestage = func;
3322   PetscFunctionReturn(0);
3323 }
3324 
3325 /*@C
3326   TSSetPostStage - Sets the general-purpose function
3327   called once at the end of each stage.
3328 
3329   Logically Collective on TS
3330 
3331   Input Parameters:
3332 + ts   - The TS context obtained from TSCreate()
3333 - func - The function
3334 
3335   Calling sequence of func:
3336 . PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y);
3337 
3338   Level: intermediate
3339 
3340   Note:
3341   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
3342   The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being
3343   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
3344 
3345 .keywords: TS, timestep
3346 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
3347 @*/
3348 PetscErrorCode  TSSetPostStage(TS ts, PetscErrorCode (*func)(TS,PetscReal,PetscInt,Vec*))
3349 {
3350   PetscFunctionBegin;
3351   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3352   ts->poststage = func;
3353   PetscFunctionReturn(0);
3354 }
3355 
3356 /*@C
3357   TSSetPostEvaluate - Sets the general-purpose function
3358   called once at the end of each step evaluation.
3359 
3360   Logically Collective on TS
3361 
3362   Input Parameters:
3363 + ts   - The TS context obtained from TSCreate()
3364 - func - The function
3365 
3366   Calling sequence of func:
3367 . PetscErrorCode func(TS ts);
3368 
3369   Level: intermediate
3370 
3371   Note:
3372   Semantically, TSSetPostEvaluate() differs from TSSetPostStep() since the function it sets is called before event-handling
3373   thus guaranteeing the same solution (computed by the time-stepper) will be passed to it. On the other hand, TSPostStep()
3374   may be passed a different solution, possibly changed by the event handler. TSPostEvaluate() is called after the next step
3375   solution is evaluated allowing to modify it, if need be. The solution can be obtained with TSGetSolution(), the time step
3376   with TSGetTimeStep(), and the time at the start of the step is available via TSGetTime()
3377 
3378 .keywords: TS, timestep
3379 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
3380 @*/
3381 PetscErrorCode  TSSetPostEvaluate(TS ts, PetscErrorCode (*func)(TS))
3382 {
3383   PetscFunctionBegin;
3384   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3385   ts->postevaluate = func;
3386   PetscFunctionReturn(0);
3387 }
3388 
3389 /*@
3390   TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage()
3391 
3392   Collective on TS
3393 
3394   Input Parameters:
3395 . ts          - The TS context obtained from TSCreate()
3396   stagetime   - The absolute time of the current stage
3397 
3398   Notes:
3399   TSPreStage() is typically used within time stepping implementations,
3400   most users would not generally call this routine themselves.
3401 
3402   Level: developer
3403 
3404 .keywords: TS, timestep
3405 .seealso: TSPostStage(), TSSetPreStep(), TSPreStep(), TSPostStep()
3406 @*/
3407 PetscErrorCode  TSPreStage(TS ts, PetscReal stagetime)
3408 {
3409   PetscErrorCode ierr;
3410 
3411   PetscFunctionBegin;
3412   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3413   if (ts->prestage) {
3414     PetscStackCallStandard((*ts->prestage),(ts,stagetime));
3415   }
3416   PetscFunctionReturn(0);
3417 }
3418 
3419 /*@
3420   TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage()
3421 
3422   Collective on TS
3423 
3424   Input Parameters:
3425 . ts          - The TS context obtained from TSCreate()
3426   stagetime   - The absolute time of the current stage
3427   stageindex  - Stage number
3428   Y           - Array of vectors (of size = total number
3429                 of stages) with the stage solutions
3430 
3431   Notes:
3432   TSPostStage() is typically used within time stepping implementations,
3433   most users would not generally call this routine themselves.
3434 
3435   Level: developer
3436 
3437 .keywords: TS, timestep
3438 .seealso: TSPreStage(), TSSetPreStep(), TSPreStep(), TSPostStep()
3439 @*/
3440 PetscErrorCode  TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y)
3441 {
3442   PetscErrorCode ierr;
3443 
3444   PetscFunctionBegin;
3445   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3446   if (ts->poststage) {
3447     PetscStackCallStandard((*ts->poststage),(ts,stagetime,stageindex,Y));
3448   }
3449   PetscFunctionReturn(0);
3450 }
3451 
3452 /*@
3453   TSPostEvaluate - Runs the user-defined post-evaluate function set using TSSetPostEvaluate()
3454 
3455   Collective on TS
3456 
3457   Input Parameters:
3458 . ts          - The TS context obtained from TSCreate()
3459 
3460   Notes:
3461   TSPostEvaluate() is typically used within time stepping implementations,
3462   most users would not generally call this routine themselves.
3463 
3464   Level: developer
3465 
3466 .keywords: TS, timestep
3467 .seealso: TSSetPostEvaluate(), TSSetPreStep(), TSPreStep(), TSPostStep()
3468 @*/
3469 PetscErrorCode  TSPostEvaluate(TS ts)
3470 {
3471   PetscErrorCode ierr;
3472 
3473   PetscFunctionBegin;
3474   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3475   if (ts->postevaluate) {
3476     PetscStackCallStandard((*ts->postevaluate),(ts));
3477   }
3478   PetscFunctionReturn(0);
3479 }
3480 
3481 /*@C
3482   TSSetPostStep - Sets the general-purpose function
3483   called once at the end of each time step.
3484 
3485   Logically Collective on TS
3486 
3487   Input Parameters:
3488 + ts   - The TS context obtained from TSCreate()
3489 - func - The function
3490 
3491   Calling sequence of func:
3492 $ func (TS ts);
3493 
3494   Notes:
3495   The function set by TSSetPostStep() is called after each successful step. The solution vector X
3496   obtained by TSGetSolution() may be different than that computed at the step end if the event handler
3497   locates an event and TSPostEvent() modifies it. Use TSSetPostEvaluate() if an unmodified solution is needed instead.
3498 
3499   Level: intermediate
3500 
3501 .keywords: TS, timestep
3502 .seealso: TSSetPreStep(), TSSetPreStage(), TSSetPostEvaluate(), TSGetTimeStep(), TSGetTimeStepNumber(), TSGetTime()
3503 @*/
3504 PetscErrorCode  TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
3505 {
3506   PetscFunctionBegin;
3507   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3508   ts->poststep = func;
3509   PetscFunctionReturn(0);
3510 }
3511 
3512 /*@
3513   TSPostStep - Runs the user-defined post-step function.
3514 
3515   Collective on TS
3516 
3517   Input Parameters:
3518 . ts   - The TS context obtained from TSCreate()
3519 
3520   Notes:
3521   TSPostStep() is typically used within time stepping implementations,
3522   so most users would not generally call this routine themselves.
3523 
3524   Level: developer
3525 
3526 .keywords: TS, timestep
3527 @*/
3528 PetscErrorCode  TSPostStep(TS ts)
3529 {
3530   PetscErrorCode ierr;
3531 
3532   PetscFunctionBegin;
3533   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3534   if (ts->poststep) {
3535     PetscStackCallStandard((*ts->poststep),(ts));
3536   }
3537   PetscFunctionReturn(0);
3538 }
3539 
3540 /* ------------ Routines to set performance monitoring options ----------- */
3541 
3542 /*@C
3543    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
3544    timestep to display the iteration's  progress.
3545 
3546    Logically Collective on TS
3547 
3548    Input Parameters:
3549 +  ts - the TS context obtained from TSCreate()
3550 .  monitor - monitoring routine
3551 .  mctx - [optional] user-defined context for private data for the
3552              monitor routine (use NULL if no context is desired)
3553 -  monitordestroy - [optional] routine that frees monitor context
3554           (may be NULL)
3555 
3556    Calling sequence of monitor:
3557 $    int monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
3558 
3559 +    ts - the TS context
3560 .    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)
3561 .    time - current time
3562 .    u - current iterate
3563 -    mctx - [optional] monitoring context
3564 
3565    Notes:
3566    This routine adds an additional monitor to the list of monitors that
3567    already has been loaded.
3568 
3569    Fortran notes: Only a single monitor function can be set for each TS object
3570 
3571    Level: intermediate
3572 
3573 .keywords: TS, timestep, set, monitor
3574 
3575 .seealso: TSMonitorDefault(), TSMonitorCancel()
3576 @*/
3577 PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**))
3578 {
3579   PetscErrorCode ierr;
3580   PetscInt       i;
3581   PetscBool      identical;
3582 
3583   PetscFunctionBegin;
3584   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3585   for (i=0; i<ts->numbermonitors;i++) {
3586     ierr = PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical);CHKERRQ(ierr);
3587     if (identical) PetscFunctionReturn(0);
3588   }
3589   if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
3590   ts->monitor[ts->numbermonitors]          = monitor;
3591   ts->monitordestroy[ts->numbermonitors]   = mdestroy;
3592   ts->monitorcontext[ts->numbermonitors++] = (void*)mctx;
3593   PetscFunctionReturn(0);
3594 }
3595 
3596 /*@C
3597    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
3598 
3599    Logically Collective on TS
3600 
3601    Input Parameters:
3602 .  ts - the TS context obtained from TSCreate()
3603 
3604    Notes:
3605    There is no way to remove a single, specific monitor.
3606 
3607    Level: intermediate
3608 
3609 .keywords: TS, timestep, set, monitor
3610 
3611 .seealso: TSMonitorDefault(), TSMonitorSet()
3612 @*/
3613 PetscErrorCode  TSMonitorCancel(TS ts)
3614 {
3615   PetscErrorCode ierr;
3616   PetscInt       i;
3617 
3618   PetscFunctionBegin;
3619   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3620   for (i=0; i<ts->numbermonitors; i++) {
3621     if (ts->monitordestroy[i]) {
3622       ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr);
3623     }
3624   }
3625   ts->numbermonitors = 0;
3626   PetscFunctionReturn(0);
3627 }
3628 
3629 /*@C
3630    TSMonitorDefault - The Default monitor, prints the timestep and time for each step
3631 
3632    Level: intermediate
3633 
3634 .keywords: TS, set, monitor
3635 
3636 .seealso:  TSMonitorSet()
3637 @*/
3638 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf)
3639 {
3640   PetscErrorCode ierr;
3641   PetscViewer    viewer =  vf->viewer;
3642   PetscBool      iascii,ibinary;
3643 
3644   PetscFunctionBegin;
3645   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
3646   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
3647   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
3648   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
3649   if (iascii) {
3650     ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
3651     if (step == -1){ /* this indicates it is an interpolated solution */
3652       ierr = PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %D and %D\n",(double)ptime,ts->steps-1,ts->steps);CHKERRQ(ierr);
3653     } else {
3654       ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr);
3655     }
3656     ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
3657   } else if (ibinary) {
3658     PetscMPIInt rank;
3659     ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
3660     if (!rank) {
3661       PetscBool skipHeader;
3662       PetscInt  classid = REAL_FILE_CLASSID;
3663 
3664       ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
3665       if (!skipHeader) {
3666          ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
3667        }
3668       ierr = PetscRealView(1,&ptime,viewer);CHKERRQ(ierr);
3669     } else {
3670       ierr = PetscRealView(0,&ptime,viewer);CHKERRQ(ierr);
3671     }
3672   }
3673   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
3674   PetscFunctionReturn(0);
3675 }
3676 
3677 /*@C
3678    TSAdjointMonitorSet - Sets an ADDITIONAL function that is to be used at every
3679    timestep to display the iteration's  progress.
3680 
3681    Logically Collective on TS
3682 
3683    Input Parameters:
3684 +  ts - the TS context obtained from TSCreate()
3685 .  adjointmonitor - monitoring routine
3686 .  adjointmctx - [optional] user-defined context for private data for the
3687              monitor routine (use NULL if no context is desired)
3688 -  adjointmonitordestroy - [optional] routine that frees monitor context
3689           (may be NULL)
3690 
3691    Calling sequence of monitor:
3692 $    int adjointmonitor(TS ts,PetscInt steps,PetscReal time,Vec u,PetscInt numcost,Vec *lambda, Vec *mu,void *adjointmctx)
3693 
3694 +    ts - the TS context
3695 .    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
3696                                been interpolated to)
3697 .    time - current time
3698 .    u - current iterate
3699 .    numcost - number of cost functionos
3700 .    lambda - sensitivities to initial conditions
3701 .    mu - sensitivities to parameters
3702 -    adjointmctx - [optional] adjoint monitoring context
3703 
3704    Notes:
3705    This routine adds an additional monitor to the list of monitors that
3706    already has been loaded.
3707 
3708    Fortran notes: Only a single monitor function can be set for each TS object
3709 
3710    Level: intermediate
3711 
3712 .keywords: TS, timestep, set, adjoint, monitor
3713 
3714 .seealso: TSAdjointMonitorCancel()
3715 @*/
3716 PetscErrorCode  TSAdjointMonitorSet(TS ts,PetscErrorCode (*adjointmonitor)(TS,PetscInt,PetscReal,Vec,PetscInt,Vec*,Vec*,void*),void *adjointmctx,PetscErrorCode (*adjointmdestroy)(void**))
3717 {
3718   PetscErrorCode ierr;
3719   PetscInt       i;
3720   PetscBool      identical;
3721 
3722   PetscFunctionBegin;
3723   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3724   for (i=0; i<ts->numbermonitors;i++) {
3725     ierr = PetscMonitorCompare((PetscErrorCode (*)(void))adjointmonitor,adjointmctx,adjointmdestroy,(PetscErrorCode (*)(void))ts->adjointmonitor[i],ts->adjointmonitorcontext[i],ts->adjointmonitordestroy[i],&identical);CHKERRQ(ierr);
3726     if (identical) PetscFunctionReturn(0);
3727   }
3728   if (ts->numberadjointmonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many adjoint monitors set");
3729   ts->adjointmonitor[ts->numberadjointmonitors]          = adjointmonitor;
3730   ts->adjointmonitordestroy[ts->numberadjointmonitors]   = adjointmdestroy;
3731   ts->adjointmonitorcontext[ts->numberadjointmonitors++] = (void*)adjointmctx;
3732   PetscFunctionReturn(0);
3733 }
3734 
3735 /*@C
3736    TSAdjointMonitorCancel - Clears all the adjoint monitors that have been set on a time-step object.
3737 
3738    Logically Collective on TS
3739 
3740    Input Parameters:
3741 .  ts - the TS context obtained from TSCreate()
3742 
3743    Notes:
3744    There is no way to remove a single, specific monitor.
3745 
3746    Level: intermediate
3747 
3748 .keywords: TS, timestep, set, adjoint, monitor
3749 
3750 .seealso: TSAdjointMonitorSet()
3751 @*/
3752 PetscErrorCode  TSAdjointMonitorCancel(TS ts)
3753 {
3754   PetscErrorCode ierr;
3755   PetscInt       i;
3756 
3757   PetscFunctionBegin;
3758   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3759   for (i=0; i<ts->numberadjointmonitors; i++) {
3760     if (ts->adjointmonitordestroy[i]) {
3761       ierr = (*ts->adjointmonitordestroy[i])(&ts->adjointmonitorcontext[i]);CHKERRQ(ierr);
3762     }
3763   }
3764   ts->numberadjointmonitors = 0;
3765   PetscFunctionReturn(0);
3766 }
3767 
3768 /*@C
3769    TSAdjointMonitorDefault - the default monitor of adjoint computations
3770 
3771    Level: intermediate
3772 
3773 .keywords: TS, set, monitor
3774 
3775 .seealso: TSAdjointMonitorSet()
3776 @*/
3777 PetscErrorCode TSAdjointMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscInt numcost,Vec *lambda,Vec *mu,PetscViewerAndFormat *vf)
3778 {
3779   PetscErrorCode ierr;
3780   PetscViewer    viewer = vf->viewer;
3781 
3782   PetscFunctionBegin;
3783   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
3784   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
3785   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
3786   ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr);
3787   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
3788   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
3789   PetscFunctionReturn(0);
3790 }
3791 
3792 /*@
3793    TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval
3794 
3795    Collective on TS
3796 
3797    Input Argument:
3798 +  ts - time stepping context
3799 -  t - time to interpolate to
3800 
3801    Output Argument:
3802 .  U - state at given time
3803 
3804    Level: intermediate
3805 
3806    Developer Notes:
3807    TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints.
3808 
3809 .keywords: TS, set
3810 
3811 .seealso: TSSetExactFinalTime(), TSSolve()
3812 @*/
3813 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U)
3814 {
3815   PetscErrorCode ierr;
3816 
3817   PetscFunctionBegin;
3818   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3819   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
3820   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);
3821   if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name);
3822   ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr);
3823   PetscFunctionReturn(0);
3824 }
3825 
3826 /*@
3827    TSStep - Steps one time step
3828 
3829    Collective on TS
3830 
3831    Input Parameter:
3832 .  ts - the TS context obtained from TSCreate()
3833 
3834    Level: developer
3835 
3836    Notes:
3837    The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine.
3838 
3839    The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may
3840    be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages.
3841 
3842    This may over-step the final time provided in TSSetDuration() depending on the time-step used. TSSolve() interpolates to exactly the
3843    time provided in TSSetDuration(). One can use TSInterpolate() to determine an interpolated solution within the final timestep.
3844 
3845 .keywords: TS, timestep, solve
3846 
3847 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate()
3848 @*/
3849 PetscErrorCode  TSStep(TS ts)
3850 {
3851   PetscErrorCode   ierr;
3852   static PetscBool cite = PETSC_FALSE;
3853   PetscReal        ptime;
3854 
3855   PetscFunctionBegin;
3856   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3857   ierr = PetscCitationsRegister("@techreport{tspaper,\n"
3858                                 "  title       = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n"
3859                                 "  author      = {Shrirang Abhyankar and Jed Brown and Emil Constantinescu and Debojyoti Ghosh and Barry F. Smith},\n"
3860                                 "  type        = {Preprint},\n"
3861                                 "  number      = {ANL/MCS-P5061-0114},\n"
3862                                 "  institution = {Argonne National Laboratory},\n"
3863                                 "  year        = {2014}\n}\n",&cite);CHKERRQ(ierr);
3864 
3865   ierr = TSSetUp(ts);CHKERRQ(ierr);
3866   ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr);
3867 
3868   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()");
3869   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");
3870 
3871   if (!ts->steps) ts->ptime_prev = ts->ptime;
3872   ts->reason = TS_CONVERGED_ITERATING;
3873   ptime = ts->ptime; ts->ptime_prev_rollback = ts->ptime_prev;
3874   if (!ts->ops->step) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name);
3875   ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr);
3876   ierr = (*ts->ops->step)(ts);CHKERRQ(ierr);
3877   ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr);
3878   ts->ptime_prev = ptime;
3879   ts->steps++; ts->total_steps++;
3880   ts->steprollback = PETSC_FALSE;
3881   ts->steprestart  = PETSC_FALSE;
3882 
3883   if (ts->reason < 0) {
3884     if (ts->errorifstepfailed) {
3885       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]);
3886       else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]);
3887     }
3888   } else if (!ts->reason) {
3889     if (ts->steps >= ts->max_steps)     ts->reason = TS_CONVERGED_ITS;
3890     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
3891   }
3892   PetscFunctionReturn(0);
3893 }
3894 
3895 /*@
3896    TSAdjointStep - Steps one time step backward in the adjoint run
3897 
3898    Collective on TS
3899 
3900    Input Parameter:
3901 .  ts - the TS context obtained from TSCreate()
3902 
3903    Level: intermediate
3904 
3905 .keywords: TS, adjoint, step
3906 
3907 .seealso: TSAdjointSetUp(), TSAdjointSolve()
3908 @*/
3909 PetscErrorCode  TSAdjointStep(TS ts)
3910 {
3911   DM               dm;
3912   PetscErrorCode   ierr;
3913 
3914   PetscFunctionBegin;
3915   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3916   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
3917   ierr = TSAdjointSetUp(ts);CHKERRQ(ierr);
3918 
3919   ierr = VecViewFromOptions(ts->vec_sol,(PetscObject)ts,"-ts_view_solution");CHKERRQ(ierr);
3920 
3921   ts->reason = TS_CONVERGED_ITERATING;
3922   ts->ptime_prev = ts->ptime;
3923   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);
3924   ierr = PetscLogEventBegin(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr);
3925   ierr = (*ts->ops->adjointstep)(ts);CHKERRQ(ierr);
3926   ierr = PetscLogEventEnd(TS_AdjointStep,ts,0,0,0);CHKERRQ(ierr);
3927   ts->steps++; ts->total_steps--;
3928 
3929   if (ts->reason < 0) {
3930     if (ts->errorifstepfailed) {
3931       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]);
3932       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]);
3933       else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]);
3934     }
3935   } else if (!ts->reason) {
3936     if (ts->steps >= ts->adjoint_max_steps) ts->reason = TS_CONVERGED_ITS;
3937   }
3938   PetscFunctionReturn(0);
3939 }
3940 
3941 /*@
3942    TSEvaluateWLTE - Evaluate the weighted local truncation error norm
3943    at the end of a time step with a given order of accuracy.
3944 
3945    Collective on TS
3946 
3947    Input Arguments:
3948 +  ts - time stepping context
3949 .  wnormtype - norm type, either NORM_2 or NORM_INFINITY
3950 -  order - optional, desired order for the error evaluation or PETSC_DECIDE
3951 
3952    Output Arguments:
3953 +  order - optional, the actual order of the error evaluation
3954 -  wlte - the weighted local truncation error norm
3955 
3956    Level: advanced
3957 
3958    Notes:
3959    If the timestepper cannot evaluate the error in a particular step
3960    (eg. in the first step or restart steps after event handling),
3961    this routine returns wlte=-1.0 .
3962 
3963 .seealso: TSStep(), TSAdapt, TSErrorWeightedNorm()
3964 @*/
3965 PetscErrorCode TSEvaluateWLTE(TS ts,NormType wnormtype,PetscInt *order,PetscReal *wlte)
3966 {
3967   PetscErrorCode ierr;
3968 
3969   PetscFunctionBegin;
3970   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3971   PetscValidType(ts,1);
3972   PetscValidLogicalCollectiveEnum(ts,wnormtype,4);
3973   if (order) PetscValidIntPointer(order,3);
3974   if (order) PetscValidLogicalCollectiveInt(ts,*order,3);
3975   PetscValidRealPointer(wlte,4);
3976   if (wnormtype != NORM_2 && wnormtype != NORM_INFINITY) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
3977   if (!ts->ops->evaluatewlte) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateWLTE not implemented for type '%s'",((PetscObject)ts)->type_name);
3978   ierr = (*ts->ops->evaluatewlte)(ts,wnormtype,order,wlte);CHKERRQ(ierr);
3979   PetscFunctionReturn(0);
3980 }
3981 
3982 /*@
3983    TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy.
3984 
3985    Collective on TS
3986 
3987    Input Arguments:
3988 +  ts - time stepping context
3989 .  order - desired order of accuracy
3990 -  done - whether the step was evaluated at this order (pass NULL to generate an error if not available)
3991 
3992    Output Arguments:
3993 .  U - state at the end of the current step
3994 
3995    Level: advanced
3996 
3997    Notes:
3998    This function cannot be called until all stages have been evaluated.
3999    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.
4000 
4001 .seealso: TSStep(), TSAdapt
4002 @*/
4003 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done)
4004 {
4005   PetscErrorCode ierr;
4006 
4007   PetscFunctionBegin;
4008   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4009   PetscValidType(ts,1);
4010   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
4011   if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name);
4012   ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr);
4013   PetscFunctionReturn(0);
4014 }
4015 
4016 /*@
4017  TSForwardCostIntegral - Evaluate the cost integral in the forward run.
4018 
4019  Collective on TS
4020 
4021  Input Arguments:
4022  .  ts - time stepping context
4023 
4024  Level: advanced
4025 
4026  Notes:
4027  This function cannot be called until TSStep() has been completed.
4028 
4029  .seealso: TSSolve(), TSAdjointCostIntegral()
4030  @*/
4031 PetscErrorCode TSForwardCostIntegral(TS ts)
4032 {
4033     PetscErrorCode ierr;
4034     PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4035     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);
4036     ierr = (*ts->ops->forwardintegral)(ts);CHKERRQ(ierr);
4037     PetscFunctionReturn(0);
4038 }
4039 
4040 /*@
4041    TSSolve - Steps the requested number of timesteps.
4042 
4043    Collective on TS
4044 
4045    Input Parameter:
4046 +  ts - the TS context obtained from TSCreate()
4047 -  u - the solution vector  (can be null if TSSetSolution() was used and TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP) was not used,
4048                              otherwise must contain the initial conditions and will contain the solution at the final requested time
4049 
4050    Level: beginner
4051 
4052    Notes:
4053    The final time returned by this function may be different from the time of the internally
4054    held state accessible by TSGetSolution() and TSGetTime() because the method may have
4055    stepped over the final time.
4056 
4057 .keywords: TS, timestep, solve
4058 
4059 .seealso: TSCreate(), TSSetSolution(), TSStep(), TSGetTime(), TSGetSolveTime()
4060 @*/
4061 PetscErrorCode TSSolve(TS ts,Vec u)
4062 {
4063   Vec               solution;
4064   PetscErrorCode    ierr;
4065 
4066   PetscFunctionBegin;
4067   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4068   if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2);
4069 
4070   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 */
4071     PetscValidHeaderSpecific(u,VEC_CLASSID,2);
4072     if (!ts->vec_sol || u == ts->vec_sol) {
4073       ierr = VecDuplicate(u,&solution);CHKERRQ(ierr);
4074       ierr = TSSetSolution(ts,solution);CHKERRQ(ierr);
4075       ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */
4076     }
4077     ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr);
4078   } else if (u) {
4079     ierr = TSSetSolution(ts,u);CHKERRQ(ierr);
4080   }
4081   ierr = TSSetUp(ts);CHKERRQ(ierr);
4082   ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr);
4083 
4084   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()");
4085   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");
4086 
4087   /* reset number of steps only when the step is not restarted. ARKIMEX
4088      restarts the step after an event. Resetting these counters in such a case causes
4089      TSTrajectory to incorrectly save the output files
4090   */
4091 
4092   ts->steps             = 0;
4093   ts->ksp_its           = 0;
4094   ts->snes_its          = 0;
4095   ts->num_snes_failures = 0;
4096   ts->reject            = 0;
4097   ts->reason            = TS_CONVERGED_ITERATING;
4098 
4099   ierr = TSViewFromOptions(ts,NULL,"-ts_view_pre");CHKERRQ(ierr);
4100 
4101   if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */
4102     ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr);
4103     if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);}
4104     ts->solvetime = ts->ptime;
4105     solution = ts->vec_sol;
4106   } else { /* Step the requested number of timesteps. */
4107     if (ts->steps >= ts->max_steps)     ts->reason = TS_CONVERGED_ITS;
4108     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
4109 
4110     ierr = TSTrajectorySet(ts->trajectory,ts,ts->total_steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4111     ierr = TSEventInitialize(ts->event,ts,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4112 
4113     ts->steprollback = PETSC_FALSE;
4114     ts->steprestart  = PETSC_TRUE;
4115 
4116     while (!ts->reason) {
4117       ierr = TSMonitor(ts,ts->total_steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4118       if (!ts->steprollback) {
4119         ierr = TSPreStep(ts);CHKERRQ(ierr);
4120       }
4121       ierr = TSStep(ts);CHKERRQ(ierr);
4122       if (ts->vec_costintegral && ts->costintegralfwd) { /* Must evaluate the cost integral before event is handled. The cost integral value can also be rolled back. */
4123         ierr = TSForwardCostIntegral(ts);CHKERRQ(ierr);
4124       }
4125       ierr = TSPostEvaluate(ts);CHKERRQ(ierr);
4126       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. */
4127       if (!ts->steprollback) {
4128         ierr = TSTrajectorySet(ts->trajectory,ts,ts->total_steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4129         ierr = TSPostStep(ts);CHKERRQ(ierr);
4130       }
4131     }
4132     ierr = TSMonitor(ts,ts->total_steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
4133 
4134     if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) {
4135       ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr);
4136       ts->solvetime = ts->max_time;
4137       solution = u;
4138       ierr = TSMonitor(ts,-1,ts->solvetime,solution);CHKERRQ(ierr);
4139     } else {
4140       if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);}
4141       ts->solvetime = ts->ptime;
4142       solution = ts->vec_sol;
4143     }
4144   }
4145 
4146   ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr);
4147   ierr = VecViewFromOptions(solution,NULL,"-ts_view_solution");CHKERRQ(ierr);
4148   ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr);
4149   if (ts->adjoint_solve) {
4150     ierr = TSAdjointSolve(ts);CHKERRQ(ierr);
4151   }
4152   PetscFunctionReturn(0);
4153 }
4154 
4155 /*@
4156  TSAdjointCostIntegral - Evaluate the cost integral in the adjoint run.
4157 
4158  Collective on TS
4159 
4160  Input Arguments:
4161  .  ts - time stepping context
4162 
4163  Level: advanced
4164 
4165  Notes:
4166  This function cannot be called until TSAdjointStep() has been completed.
4167 
4168  .seealso: TSAdjointSolve(), TSAdjointStep
4169  @*/
4170 PetscErrorCode TSAdjointCostIntegral(TS ts)
4171 {
4172     PetscErrorCode ierr;
4173     PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4174     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);
4175     ierr = (*ts->ops->adjointintegral)(ts);CHKERRQ(ierr);
4176     PetscFunctionReturn(0);
4177 }
4178 
4179 /*@
4180    TSAdjointSolve - Solves the discrete ajoint problem for an ODE/DAE
4181 
4182    Collective on TS
4183 
4184    Input Parameter:
4185 .  ts - the TS context obtained from TSCreate()
4186 
4187    Options Database:
4188 . -ts_adjoint_view_solution <viewerinfo> - views the first gradient with respect to the initial conditions
4189 
4190    Level: intermediate
4191 
4192    Notes:
4193    This must be called after a call to TSSolve() that solves the forward problem
4194 
4195    By default this will integrate back to the initial time, one can use TSAdjointSetSteps() to step back to a later time
4196 
4197 .keywords: TS, timestep, solve
4198 
4199 .seealso: TSCreate(), TSSetCostGradients(), TSSetSolution(), TSAdjointStep()
4200 @*/
4201 PetscErrorCode TSAdjointSolve(TS ts)
4202 {
4203   PetscErrorCode    ierr;
4204 
4205   PetscFunctionBegin;
4206   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4207   ierr = TSAdjointSetUp(ts);CHKERRQ(ierr);
4208 
4209   /* reset time step and iteration counters */
4210   ts->steps             = 0;
4211   ts->ksp_its           = 0;
4212   ts->snes_its          = 0;
4213   ts->num_snes_failures = 0;
4214   ts->reject            = 0;
4215   ts->reason            = TS_CONVERGED_ITERATING;
4216 
4217   if (!ts->adjoint_max_steps) ts->adjoint_max_steps = ts->total_steps;
4218 
4219   if (ts->steps >= ts->adjoint_max_steps)     ts->reason = TS_CONVERGED_ITS;
4220   while (!ts->reason) {
4221     ierr = TSTrajectoryGet(ts->trajectory,ts,ts->total_steps,&ts->ptime);CHKERRQ(ierr);
4222     ierr = TSAdjointMonitor(ts,ts->total_steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr);
4223     ierr = TSAdjointEventHandler(ts);CHKERRQ(ierr);
4224     ierr = TSAdjointStep(ts);CHKERRQ(ierr);
4225     if (ts->vec_costintegral && !ts->costintegralfwd) {
4226       ierr = TSAdjointCostIntegral(ts);CHKERRQ(ierr);
4227     }
4228   }
4229   ierr = TSTrajectoryGet(ts->trajectory,ts,ts->total_steps,&ts->ptime);CHKERRQ(ierr);
4230   ierr = TSAdjointMonitor(ts,ts->total_steps,ts->ptime,ts->vec_sol,ts->numcost,ts->vecs_sensi,ts->vecs_sensip);CHKERRQ(ierr);
4231   ts->solvetime = ts->ptime;
4232   ierr = TSTrajectoryViewFromOptions(ts->trajectory,NULL,"-ts_trajectory_view");CHKERRQ(ierr);
4233   ierr = VecViewFromOptions(ts->vecs_sensi[0],(PetscObject) ts, "-ts_adjoint_view_solution");CHKERRQ(ierr);
4234   PetscFunctionReturn(0);
4235 }
4236 
4237 /*@C
4238    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()
4239 
4240    Collective on TS
4241 
4242    Input Parameters:
4243 +  ts - time stepping context obtained from TSCreate()
4244 .  step - step number that has just completed
4245 .  ptime - model time of the state
4246 -  u - state at the current model time
4247 
4248    Notes:
4249    TSMonitor() is typically used automatically within the time stepping implementations.
4250    Users would almost never call this routine directly.
4251 
4252    A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions
4253 
4254    Level: developer
4255 
4256 .keywords: TS, timestep
4257 @*/
4258 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u)
4259 {
4260   DM             dm;
4261   PetscInt       i,n = ts->numbermonitors;
4262   PetscErrorCode ierr;
4263 
4264   PetscFunctionBegin;
4265   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4266   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
4267 
4268   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4269   ierr = DMSetOutputSequenceNumber(dm,step,ptime);CHKERRQ(ierr);
4270 
4271   ierr = VecLockPush(u);CHKERRQ(ierr);
4272   for (i=0; i<n; i++) {
4273     ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr);
4274   }
4275   ierr = VecLockPop(u);CHKERRQ(ierr);
4276   PetscFunctionReturn(0);
4277 }
4278 
4279 /*@C
4280    TSAdjointMonitor - Runs all user-provided adjoint monitor routines set using TSAdjointMonitorSet()
4281 
4282    Collective on TS
4283 
4284    Input Parameters:
4285 +  ts - time stepping context obtained from TSCreate()
4286 .  step - step number that has just completed
4287 .  ptime - model time of the state
4288 .  u - state at the current model time
4289 .  numcost - number of cost functions (dimension of lambda  or mu)
4290 .  lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables
4291 -  mu - vectors containing the gradients of the cost functions with respect to the problem parameters
4292 
4293    Notes:
4294    TSAdjointMonitor() is typically used automatically within the time stepping implementations.
4295    Users would almost never call this routine directly.
4296 
4297    Level: developer
4298 
4299 .keywords: TS, timestep
4300 @*/
4301 PetscErrorCode TSAdjointMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda, Vec *mu)
4302 {
4303   PetscErrorCode ierr;
4304   PetscInt       i,n = ts->numberadjointmonitors;
4305 
4306   PetscFunctionBegin;
4307   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4308   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
4309   ierr = VecLockPush(u);CHKERRQ(ierr);
4310   for (i=0; i<n; i++) {
4311     ierr = (*ts->adjointmonitor[i])(ts,step,ptime,u,numcost,lambda,mu,ts->adjointmonitorcontext[i]);CHKERRQ(ierr);
4312   }
4313   ierr = VecLockPop(u);CHKERRQ(ierr);
4314   PetscFunctionReturn(0);
4315 }
4316 
4317 /* ------------------------------------------------------------------------*/
4318 /*@C
4319    TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with
4320    TS to monitor the solution process graphically in various ways
4321 
4322    Collective on TS
4323 
4324    Input Parameters:
4325 +  host - the X display to open, or null for the local machine
4326 .  label - the title to put in the title bar
4327 .  x, y - the screen coordinates of the upper left coordinate of the window
4328 .  m, n - the screen width and height in pixels
4329 -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
4330 
4331    Output Parameter:
4332 .  ctx - the context
4333 
4334    Options Database Key:
4335 +  -ts_monitor_lg_timestep - automatically sets line graph monitor
4336 .  -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables())
4337 .  -ts_monitor_lg_error -  monitor the error
4338 .  -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep
4339 .  -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep
4340 -  -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true
4341 
4342    Notes:
4343    Use TSMonitorLGCtxDestroy() to destroy.
4344 
4345    One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform()
4346 
4347    Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the
4348    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
4349    as the first argument.
4350 
4351    One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames()
4352 
4353 
4354    Level: intermediate
4355 
4356 .keywords: TS, monitor, line graph, residual
4357 
4358 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(),
4359            TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
4360            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
4361            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
4362            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()
4363 
4364 @*/
4365 PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
4366 {
4367   PetscDraw      draw;
4368   PetscErrorCode ierr;
4369 
4370   PetscFunctionBegin;
4371   ierr = PetscNew(ctx);CHKERRQ(ierr);
4372   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr);
4373   ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr);
4374   ierr = PetscDrawLGCreate(draw,1,&(*ctx)->lg);CHKERRQ(ierr);
4375   ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr);
4376   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
4377   (*ctx)->howoften = howoften;
4378   PetscFunctionReturn(0);
4379 }
4380 
4381 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx)
4382 {
4383   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
4384   PetscReal      x   = ptime,y;
4385   PetscErrorCode ierr;
4386 
4387   PetscFunctionBegin;
4388   if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */
4389   if (!step) {
4390     PetscDrawAxis axis;
4391     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4392     ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time","Time Step");CHKERRQ(ierr);
4393     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4394   }
4395   ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr);
4396   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
4397   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
4398     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4399     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
4400   }
4401   PetscFunctionReturn(0);
4402 }
4403 
4404 /*@C
4405    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
4406    with TSMonitorLGCtxCreate().
4407 
4408    Collective on TSMonitorLGCtx
4409 
4410    Input Parameter:
4411 .  ctx - the monitor context
4412 
4413    Level: intermediate
4414 
4415 .keywords: TS, monitor, line graph, destroy
4416 
4417 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep();
4418 @*/
4419 PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
4420 {
4421   PetscErrorCode ierr;
4422 
4423   PetscFunctionBegin;
4424   if ((*ctx)->transformdestroy) {
4425     ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr);
4426   }
4427   ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr);
4428   ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr);
4429   ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr);
4430   ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr);
4431   ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr);
4432   ierr = PetscFree(*ctx);CHKERRQ(ierr);
4433   PetscFunctionReturn(0);
4434 }
4435 
4436 /*@
4437    TSGetTime - Gets the time of the most recently completed step.
4438 
4439    Not Collective
4440 
4441    Input Parameter:
4442 .  ts - the TS context obtained from TSCreate()
4443 
4444    Output Parameter:
4445 .  t  - the current time. This time may not corresponds to the final time set with TSSetDuration(), use TSGetSolveTime().
4446 
4447    Level: beginner
4448 
4449    Note:
4450    When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(),
4451    TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated.
4452 
4453 .seealso: TSSetInitialTimeStep(), TSGetTimeStep(), TSGetSolveTime()
4454 
4455 .keywords: TS, get, time
4456 @*/
4457 PetscErrorCode  TSGetTime(TS ts,PetscReal *t)
4458 {
4459   PetscFunctionBegin;
4460   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4461   PetscValidRealPointer(t,2);
4462   *t = ts->ptime;
4463   PetscFunctionReturn(0);
4464 }
4465 
4466 /*@
4467    TSGetPrevTime - Gets the starting time of the previously completed step.
4468 
4469    Not Collective
4470 
4471    Input Parameter:
4472 .  ts - the TS context obtained from TSCreate()
4473 
4474    Output Parameter:
4475 .  t  - the previous time
4476 
4477    Level: beginner
4478 
4479 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
4480 
4481 .keywords: TS, get, time
4482 @*/
4483 PetscErrorCode  TSGetPrevTime(TS ts,PetscReal *t)
4484 {
4485   PetscFunctionBegin;
4486   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4487   PetscValidRealPointer(t,2);
4488   *t = ts->ptime_prev;
4489   PetscFunctionReturn(0);
4490 }
4491 
4492 /*@
4493    TSSetTime - Allows one to reset the time.
4494 
4495    Logically Collective on TS
4496 
4497    Input Parameters:
4498 +  ts - the TS context obtained from TSCreate()
4499 -  time - the time
4500 
4501    Level: intermediate
4502 
4503 .seealso: TSGetTime(), TSSetDuration()
4504 
4505 .keywords: TS, set, time
4506 @*/
4507 PetscErrorCode  TSSetTime(TS ts, PetscReal t)
4508 {
4509   PetscFunctionBegin;
4510   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4511   PetscValidLogicalCollectiveReal(ts,t,2);
4512   ts->ptime = t;
4513   PetscFunctionReturn(0);
4514 }
4515 
4516 /*@C
4517    TSSetOptionsPrefix - Sets the prefix used for searching for all
4518    TS options in the database.
4519 
4520    Logically Collective on TS
4521 
4522    Input Parameter:
4523 +  ts     - The TS context
4524 -  prefix - The prefix to prepend to all option names
4525 
4526    Notes:
4527    A hyphen (-) must NOT be given at the beginning of the prefix name.
4528    The first character of all runtime options is AUTOMATICALLY the
4529    hyphen.
4530 
4531    Level: advanced
4532 
4533 .keywords: TS, set, options, prefix, database
4534 
4535 .seealso: TSSetFromOptions()
4536 
4537 @*/
4538 PetscErrorCode  TSSetOptionsPrefix(TS ts,const char prefix[])
4539 {
4540   PetscErrorCode ierr;
4541   SNES           snes;
4542 
4543   PetscFunctionBegin;
4544   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4545   ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
4546   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4547   ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr);
4548   PetscFunctionReturn(0);
4549 }
4550 
4551 
4552 /*@C
4553    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
4554    TS options in the database.
4555 
4556    Logically Collective on TS
4557 
4558    Input Parameter:
4559 +  ts     - The TS context
4560 -  prefix - The prefix to prepend to all option names
4561 
4562    Notes:
4563    A hyphen (-) must NOT be given at the beginning of the prefix name.
4564    The first character of all runtime options is AUTOMATICALLY the
4565    hyphen.
4566 
4567    Level: advanced
4568 
4569 .keywords: TS, append, options, prefix, database
4570 
4571 .seealso: TSGetOptionsPrefix()
4572 
4573 @*/
4574 PetscErrorCode  TSAppendOptionsPrefix(TS ts,const char prefix[])
4575 {
4576   PetscErrorCode ierr;
4577   SNES           snes;
4578 
4579   PetscFunctionBegin;
4580   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4581   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
4582   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4583   ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr);
4584   PetscFunctionReturn(0);
4585 }
4586 
4587 /*@C
4588    TSGetOptionsPrefix - Sets the prefix used for searching for all
4589    TS options in the database.
4590 
4591    Not Collective
4592 
4593    Input Parameter:
4594 .  ts - The TS context
4595 
4596    Output Parameter:
4597 .  prefix - A pointer to the prefix string used
4598 
4599    Notes: On the fortran side, the user should pass in a string 'prifix' of
4600    sufficient length to hold the prefix.
4601 
4602    Level: intermediate
4603 
4604 .keywords: TS, get, options, prefix, database
4605 
4606 .seealso: TSAppendOptionsPrefix()
4607 @*/
4608 PetscErrorCode  TSGetOptionsPrefix(TS ts,const char *prefix[])
4609 {
4610   PetscErrorCode ierr;
4611 
4612   PetscFunctionBegin;
4613   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4614   PetscValidPointer(prefix,2);
4615   ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
4616   PetscFunctionReturn(0);
4617 }
4618 
4619 /*@C
4620    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
4621 
4622    Not Collective, but parallel objects are returned if TS is parallel
4623 
4624    Input Parameter:
4625 .  ts  - The TS context obtained from TSCreate()
4626 
4627    Output Parameters:
4628 +  Amat - The (approximate) Jacobian J of G, where U_t = G(U,t)  (or NULL)
4629 .  Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat  (or NULL)
4630 .  func - Function to compute the Jacobian of the RHS  (or NULL)
4631 -  ctx - User-defined context for Jacobian evaluation routine  (or NULL)
4632 
4633    Notes: You can pass in NULL for any return argument you do not need.
4634 
4635    Level: intermediate
4636 
4637 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
4638 
4639 .keywords: TS, timestep, get, matrix, Jacobian
4640 @*/
4641 PetscErrorCode  TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx)
4642 {
4643   PetscErrorCode ierr;
4644   DM             dm;
4645 
4646   PetscFunctionBegin;
4647   if (Amat || Pmat) {
4648     SNES snes;
4649     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4650     ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
4651     ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
4652   }
4653   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4654   ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr);
4655   PetscFunctionReturn(0);
4656 }
4657 
4658 /*@C
4659    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
4660 
4661    Not Collective, but parallel objects are returned if TS is parallel
4662 
4663    Input Parameter:
4664 .  ts  - The TS context obtained from TSCreate()
4665 
4666    Output Parameters:
4667 +  Amat  - The (approximate) Jacobian of F(t,U,U_t)
4668 .  Pmat - The matrix from which the preconditioner is constructed, often the same as Amat
4669 .  f   - The function to compute the matrices
4670 - ctx - User-defined context for Jacobian evaluation routine
4671 
4672    Notes: You can pass in NULL for any return argument you do not need.
4673 
4674    Level: advanced
4675 
4676 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
4677 
4678 .keywords: TS, timestep, get, matrix, Jacobian
4679 @*/
4680 PetscErrorCode  TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx)
4681 {
4682   PetscErrorCode ierr;
4683   DM             dm;
4684 
4685   PetscFunctionBegin;
4686   if (Amat || Pmat) {
4687     SNES snes;
4688     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4689     ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
4690     ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
4691   }
4692   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
4693   ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr);
4694   PetscFunctionReturn(0);
4695 }
4696 
4697 
4698 /*@C
4699    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
4700    VecView() for the solution at each timestep
4701 
4702    Collective on TS
4703 
4704    Input Parameters:
4705 +  ts - the TS context
4706 .  step - current time-step
4707 .  ptime - current time
4708 -  dummy - either a viewer or NULL
4709 
4710    Options Database:
4711 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
4712 
4713    Notes: the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
4714        will look bad
4715 
4716    Level: intermediate
4717 
4718 .keywords: TS,  vector, monitor, view
4719 
4720 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4721 @*/
4722 PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4723 {
4724   PetscErrorCode   ierr;
4725   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
4726   PetscDraw        draw;
4727 
4728   PetscFunctionBegin;
4729   if (!step && ictx->showinitial) {
4730     if (!ictx->initialsolution) {
4731       ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr);
4732     }
4733     ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr);
4734   }
4735   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
4736 
4737   if (ictx->showinitial) {
4738     PetscReal pause;
4739     ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr);
4740     ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr);
4741     ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr);
4742     ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr);
4743     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr);
4744   }
4745   ierr = VecView(u,ictx->viewer);CHKERRQ(ierr);
4746   if (ictx->showtimestepandtime) {
4747     PetscReal xl,yl,xr,yr,h;
4748     char      time[32];
4749 
4750     ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
4751     ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
4752     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
4753     h    = yl + .95*(yr - yl);
4754     ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
4755     ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
4756   }
4757 
4758   if (ictx->showinitial) {
4759     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr);
4760   }
4761   PetscFunctionReturn(0);
4762 }
4763 
4764 /*@C
4765    TSAdjointMonitorDrawSensi - Monitors progress of the adjoint TS solvers by calling
4766    VecView() for the sensitivities to initial states at each timestep
4767 
4768    Collective on TS
4769 
4770    Input Parameters:
4771 +  ts - the TS context
4772 .  step - current time-step
4773 .  ptime - current time
4774 .  u - current state
4775 .  numcost - number of cost functions
4776 .  lambda - sensitivities to initial conditions
4777 .  mu - sensitivities to parameters
4778 -  dummy - either a viewer or NULL
4779 
4780    Level: intermediate
4781 
4782 .keywords: TS,  vector, adjoint, monitor, view
4783 
4784 .seealso: TSAdjointMonitorSet(), TSAdjointMonitorDefault(), VecView()
4785 @*/
4786 PetscErrorCode  TSAdjointMonitorDrawSensi(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscInt numcost,Vec *lambda,Vec *mu,void *dummy)
4787 {
4788   PetscErrorCode   ierr;
4789   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
4790   PetscDraw        draw;
4791   PetscReal        xl,yl,xr,yr,h;
4792   char             time[32];
4793 
4794   PetscFunctionBegin;
4795   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
4796 
4797   ierr = VecView(lambda[0],ictx->viewer);CHKERRQ(ierr);
4798   ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
4799   ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
4800   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
4801   h    = yl + .95*(yr - yl);
4802   ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
4803   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
4804   PetscFunctionReturn(0);
4805 }
4806 
4807 /*@C
4808    TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram
4809 
4810    Collective on TS
4811 
4812    Input Parameters:
4813 +  ts - the TS context
4814 .  step - current time-step
4815 .  ptime - current time
4816 -  dummy - either a viewer or NULL
4817 
4818    Level: intermediate
4819 
4820 .keywords: TS,  vector, monitor, view
4821 
4822 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4823 @*/
4824 PetscErrorCode  TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4825 {
4826   PetscErrorCode    ierr;
4827   TSMonitorDrawCtx  ictx = (TSMonitorDrawCtx)dummy;
4828   PetscDraw         draw;
4829   PetscDrawAxis     axis;
4830   PetscInt          n;
4831   PetscMPIInt       size;
4832   PetscReal         U0,U1,xl,yl,xr,yr,h;
4833   char              time[32];
4834   const PetscScalar *U;
4835 
4836   PetscFunctionBegin;
4837   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size);CHKERRQ(ierr);
4838   if (size != 1) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs");
4839   ierr = VecGetSize(u,&n);CHKERRQ(ierr);
4840   if (n != 2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns");
4841 
4842   ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
4843   ierr = PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis);CHKERRQ(ierr);
4844   ierr = PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr);
4845   if (!step) {
4846     ierr = PetscDrawClear(draw);CHKERRQ(ierr);
4847     ierr = PetscDrawAxisDraw(axis);CHKERRQ(ierr);
4848   }
4849 
4850   ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr);
4851   U0 = PetscRealPart(U[0]);
4852   U1 = PetscRealPart(U[1]);
4853   ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr);
4854   if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0);
4855 
4856   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
4857   ierr = PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK);CHKERRQ(ierr);
4858   if (ictx->showtimestepandtime) {
4859     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
4860     ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
4861     h    = yl + .95*(yr - yl);
4862     ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
4863   }
4864   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
4865   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
4866   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
4867   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
4868   PetscFunctionReturn(0);
4869 }
4870 
4871 
4872 /*@C
4873    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
4874 
4875    Collective on TS
4876 
4877    Input Parameters:
4878 .    ctx - the monitor context
4879 
4880    Level: intermediate
4881 
4882 .keywords: TS,  vector, monitor, view
4883 
4884 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError()
4885 @*/
4886 PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
4887 {
4888   PetscErrorCode ierr;
4889 
4890   PetscFunctionBegin;
4891   ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr);
4892   ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr);
4893   ierr = PetscFree(*ictx);CHKERRQ(ierr);
4894   PetscFunctionReturn(0);
4895 }
4896 
4897 /*@C
4898    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
4899 
4900    Collective on TS
4901 
4902    Input Parameter:
4903 .    ts - time-step context
4904 
4905    Output Patameter:
4906 .    ctx - the monitor context
4907 
4908    Options Database:
4909 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
4910 
4911    Level: intermediate
4912 
4913 .keywords: TS,  vector, monitor, view
4914 
4915 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx()
4916 @*/
4917 PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
4918 {
4919   PetscErrorCode   ierr;
4920 
4921   PetscFunctionBegin;
4922   ierr = PetscNew(ctx);CHKERRQ(ierr);
4923   ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr);
4924   ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr);
4925 
4926   (*ctx)->howoften    = howoften;
4927   (*ctx)->showinitial = PETSC_FALSE;
4928   ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr);
4929 
4930   (*ctx)->showtimestepandtime = PETSC_FALSE;
4931   ierr = PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr);
4932   PetscFunctionReturn(0);
4933 }
4934 
4935 /*@C
4936    TSMonitorDrawError - Monitors progress of the TS solvers by calling
4937    VecView() for the error at each timestep
4938 
4939    Collective on TS
4940 
4941    Input Parameters:
4942 +  ts - the TS context
4943 .  step - current time-step
4944 .  ptime - current time
4945 -  dummy - either a viewer or NULL
4946 
4947    Level: intermediate
4948 
4949 .keywords: TS,  vector, monitor, view
4950 
4951 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4952 @*/
4953 PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4954 {
4955   PetscErrorCode   ierr;
4956   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
4957   PetscViewer      viewer = ctx->viewer;
4958   Vec              work;
4959 
4960   PetscFunctionBegin;
4961   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
4962   ierr = VecDuplicate(u,&work);CHKERRQ(ierr);
4963   ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr);
4964   ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr);
4965   ierr = VecView(work,viewer);CHKERRQ(ierr);
4966   ierr = VecDestroy(&work);CHKERRQ(ierr);
4967   PetscFunctionReturn(0);
4968 }
4969 
4970 #include <petsc/private/dmimpl.h>
4971 /*@
4972    TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS
4973 
4974    Logically Collective on TS and DM
4975 
4976    Input Parameters:
4977 +  ts - the ODE integrator object
4978 -  dm - the dm, cannot be NULL
4979 
4980    Level: intermediate
4981 
4982 
4983 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM()
4984 @*/
4985 PetscErrorCode  TSSetDM(TS ts,DM dm)
4986 {
4987   PetscErrorCode ierr;
4988   SNES           snes;
4989   DMTS           tsdm;
4990 
4991   PetscFunctionBegin;
4992   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4993   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
4994   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
4995   if (ts->dm) {               /* Move the DMTS context over to the new DM unless the new DM already has one */
4996     if (ts->dm->dmts && !dm->dmts) {
4997       ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr);
4998       ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr);
4999       if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */
5000         tsdm->originaldm = dm;
5001       }
5002     }
5003     ierr = DMDestroy(&ts->dm);CHKERRQ(ierr);
5004   }
5005   ts->dm = dm;
5006 
5007   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
5008   ierr = SNESSetDM(snes,dm);CHKERRQ(ierr);
5009   PetscFunctionReturn(0);
5010 }
5011 
5012 /*@
5013    TSGetDM - Gets the DM that may be used by some preconditioners
5014 
5015    Not Collective
5016 
5017    Input Parameter:
5018 . ts - the preconditioner context
5019 
5020    Output Parameter:
5021 .  dm - the dm
5022 
5023    Level: intermediate
5024 
5025 
5026 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM()
5027 @*/
5028 PetscErrorCode  TSGetDM(TS ts,DM *dm)
5029 {
5030   PetscErrorCode ierr;
5031 
5032   PetscFunctionBegin;
5033   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5034   if (!ts->dm) {
5035     ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr);
5036     if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
5037   }
5038   *dm = ts->dm;
5039   PetscFunctionReturn(0);
5040 }
5041 
5042 /*@
5043    SNESTSFormFunction - Function to evaluate nonlinear residual
5044 
5045    Logically Collective on SNES
5046 
5047    Input Parameter:
5048 + snes - nonlinear solver
5049 . U - the current state at which to evaluate the residual
5050 - ctx - user context, must be a TS
5051 
5052    Output Parameter:
5053 . F - the nonlinear residual
5054 
5055    Notes:
5056    This function is not normally called by users and is automatically registered with the SNES used by TS.
5057    It is most frequently passed to MatFDColoringSetFunction().
5058 
5059    Level: advanced
5060 
5061 .seealso: SNESSetFunction(), MatFDColoringSetFunction()
5062 @*/
5063 PetscErrorCode  SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx)
5064 {
5065   TS             ts = (TS)ctx;
5066   PetscErrorCode ierr;
5067 
5068   PetscFunctionBegin;
5069   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5070   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
5071   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
5072   PetscValidHeaderSpecific(ts,TS_CLASSID,4);
5073   ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr);
5074   PetscFunctionReturn(0);
5075 }
5076 
5077 /*@
5078    SNESTSFormJacobian - Function to evaluate the Jacobian
5079 
5080    Collective on SNES
5081 
5082    Input Parameter:
5083 + snes - nonlinear solver
5084 . U - the current state at which to evaluate the residual
5085 - ctx - user context, must be a TS
5086 
5087    Output Parameter:
5088 + A - the Jacobian
5089 . B - the preconditioning matrix (may be the same as A)
5090 - flag - indicates any structure change in the matrix
5091 
5092    Notes:
5093    This function is not normally called by users and is automatically registered with the SNES used by TS.
5094 
5095    Level: developer
5096 
5097 .seealso: SNESSetJacobian()
5098 @*/
5099 PetscErrorCode  SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx)
5100 {
5101   TS             ts = (TS)ctx;
5102   PetscErrorCode ierr;
5103 
5104   PetscFunctionBegin;
5105   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5106   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
5107   PetscValidPointer(A,3);
5108   PetscValidHeaderSpecific(A,MAT_CLASSID,3);
5109   PetscValidPointer(B,4);
5110   PetscValidHeaderSpecific(B,MAT_CLASSID,4);
5111   PetscValidHeaderSpecific(ts,TS_CLASSID,6);
5112   ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr);
5113   PetscFunctionReturn(0);
5114 }
5115 
5116 /*@C
5117    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only
5118 
5119    Collective on TS
5120 
5121    Input Arguments:
5122 +  ts - time stepping context
5123 .  t - time at which to evaluate
5124 .  U - state at which to evaluate
5125 -  ctx - context
5126 
5127    Output Arguments:
5128 .  F - right hand side
5129 
5130    Level: intermediate
5131 
5132    Notes:
5133    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
5134    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().
5135 
5136 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
5137 @*/
5138 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx)
5139 {
5140   PetscErrorCode ierr;
5141   Mat            Arhs,Brhs;
5142 
5143   PetscFunctionBegin;
5144   ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
5145   ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr);
5146   ierr = MatMult(Arhs,U,F);CHKERRQ(ierr);
5147   PetscFunctionReturn(0);
5148 }
5149 
5150 /*@C
5151    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
5152 
5153    Collective on TS
5154 
5155    Input Arguments:
5156 +  ts - time stepping context
5157 .  t - time at which to evaluate
5158 .  U - state at which to evaluate
5159 -  ctx - context
5160 
5161    Output Arguments:
5162 +  A - pointer to operator
5163 .  B - pointer to preconditioning matrix
5164 -  flg - matrix structure flag
5165 
5166    Level: intermediate
5167 
5168    Notes:
5169    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.
5170 
5171 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear()
5172 @*/
5173 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx)
5174 {
5175   PetscFunctionBegin;
5176   PetscFunctionReturn(0);
5177 }
5178 
5179 /*@C
5180    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
5181 
5182    Collective on TS
5183 
5184    Input Arguments:
5185 +  ts - time stepping context
5186 .  t - time at which to evaluate
5187 .  U - state at which to evaluate
5188 .  Udot - time derivative of state vector
5189 -  ctx - context
5190 
5191    Output Arguments:
5192 .  F - left hand side
5193 
5194    Level: intermediate
5195 
5196    Notes:
5197    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
5198    user is required to write their own TSComputeIFunction.
5199    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
5200    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().
5201 
5202    Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U
5203 
5204 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant(), TSComputeRHSFunctionLinear()
5205 @*/
5206 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx)
5207 {
5208   PetscErrorCode ierr;
5209   Mat            A,B;
5210 
5211   PetscFunctionBegin;
5212   ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr);
5213   ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr);
5214   ierr = MatMult(A,Udot,F);CHKERRQ(ierr);
5215   PetscFunctionReturn(0);
5216 }
5217 
5218 /*@C
5219    TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE
5220 
5221    Collective on TS
5222 
5223    Input Arguments:
5224 +  ts - time stepping context
5225 .  t - time at which to evaluate
5226 .  U - state at which to evaluate
5227 .  Udot - time derivative of state vector
5228 .  shift - shift to apply
5229 -  ctx - context
5230 
5231    Output Arguments:
5232 +  A - pointer to operator
5233 .  B - pointer to preconditioning matrix
5234 -  flg - matrix structure flag
5235 
5236    Level: advanced
5237 
5238    Notes:
5239    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.
5240 
5241    It is only appropriate for problems of the form
5242 
5243 $     M Udot = F(U,t)
5244 
5245   where M is constant and F is non-stiff.  The user must pass M to TSSetIJacobian().  The current implementation only
5246   works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing
5247   an implicit operator of the form
5248 
5249 $    shift*M + J
5250 
5251   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
5252   a copy of M or reassemble it when requested.
5253 
5254 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear()
5255 @*/
5256 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx)
5257 {
5258   PetscErrorCode ierr;
5259 
5260   PetscFunctionBegin;
5261   ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr);
5262   ts->ijacobian.shift = shift;
5263   PetscFunctionReturn(0);
5264 }
5265 
5266 /*@
5267    TSGetEquationType - Gets the type of the equation that TS is solving.
5268 
5269    Not Collective
5270 
5271    Input Parameter:
5272 .  ts - the TS context
5273 
5274    Output Parameter:
5275 .  equation_type - see TSEquationType
5276 
5277    Level: beginner
5278 
5279 .keywords: TS, equation type
5280 
5281 .seealso: TSSetEquationType(), TSEquationType
5282 @*/
5283 PetscErrorCode  TSGetEquationType(TS ts,TSEquationType *equation_type)
5284 {
5285   PetscFunctionBegin;
5286   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5287   PetscValidPointer(equation_type,2);
5288   *equation_type = ts->equation_type;
5289   PetscFunctionReturn(0);
5290 }
5291 
5292 /*@
5293    TSSetEquationType - Sets the type of the equation that TS is solving.
5294 
5295    Not Collective
5296 
5297    Input Parameter:
5298 +  ts - the TS context
5299 -  equation_type - see TSEquationType
5300 
5301    Level: advanced
5302 
5303 .keywords: TS, equation type
5304 
5305 .seealso: TSGetEquationType(), TSEquationType
5306 @*/
5307 PetscErrorCode  TSSetEquationType(TS ts,TSEquationType equation_type)
5308 {
5309   PetscFunctionBegin;
5310   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5311   ts->equation_type = equation_type;
5312   PetscFunctionReturn(0);
5313 }
5314 
5315 /*@
5316    TSGetConvergedReason - Gets the reason the TS iteration was stopped.
5317 
5318    Not Collective
5319 
5320    Input Parameter:
5321 .  ts - the TS context
5322 
5323    Output Parameter:
5324 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
5325             manual pages for the individual convergence tests for complete lists
5326 
5327    Level: beginner
5328 
5329    Notes:
5330    Can only be called after the call to TSSolve() is complete.
5331 
5332 .keywords: TS, nonlinear, set, convergence, test
5333 
5334 .seealso: TSSetConvergenceTest(), TSConvergedReason
5335 @*/
5336 PetscErrorCode  TSGetConvergedReason(TS ts,TSConvergedReason *reason)
5337 {
5338   PetscFunctionBegin;
5339   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5340   PetscValidPointer(reason,2);
5341   *reason = ts->reason;
5342   PetscFunctionReturn(0);
5343 }
5344 
5345 /*@
5346    TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve.
5347 
5348    Not Collective
5349 
5350    Input Parameter:
5351 +  ts - the TS context
5352 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
5353             manual pages for the individual convergence tests for complete lists
5354 
5355    Level: advanced
5356 
5357    Notes:
5358    Can only be called during TSSolve() is active.
5359 
5360 .keywords: TS, nonlinear, set, convergence, test
5361 
5362 .seealso: TSConvergedReason
5363 @*/
5364 PetscErrorCode  TSSetConvergedReason(TS ts,TSConvergedReason reason)
5365 {
5366   PetscFunctionBegin;
5367   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5368   ts->reason = reason;
5369   PetscFunctionReturn(0);
5370 }
5371 
5372 /*@
5373    TSGetSolveTime - Gets the time after a call to TSSolve()
5374 
5375    Not Collective
5376 
5377    Input Parameter:
5378 .  ts - the TS context
5379 
5380    Output Parameter:
5381 .  ftime - the final time. This time corresponds to the final time set with TSSetDuration()
5382 
5383    Level: beginner
5384 
5385    Notes:
5386    Can only be called after the call to TSSolve() is complete.
5387 
5388 .keywords: TS, nonlinear, set, convergence, test
5389 
5390 .seealso: TSSetConvergenceTest(), TSConvergedReason
5391 @*/
5392 PetscErrorCode  TSGetSolveTime(TS ts,PetscReal *ftime)
5393 {
5394   PetscFunctionBegin;
5395   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5396   PetscValidPointer(ftime,2);
5397   *ftime = ts->solvetime;
5398   PetscFunctionReturn(0);
5399 }
5400 
5401 /*@
5402    TSGetTotalSteps - Gets the total number of steps done since the last call to TSSetUp() or TSCreate()
5403 
5404    Not Collective
5405 
5406    Input Parameter:
5407 .  ts - the TS context
5408 
5409    Output Parameter:
5410 .  steps - the number of steps
5411 
5412    Level: beginner
5413 
5414    Notes:
5415    Includes the number of steps for all calls to TSSolve() since TSSetUp() was called
5416 
5417 .keywords: TS, nonlinear, set, convergence, test
5418 
5419 .seealso: TSSetConvergenceTest(), TSConvergedReason
5420 @*/
5421 PetscErrorCode  TSGetTotalSteps(TS ts,PetscInt *steps)
5422 {
5423   PetscFunctionBegin;
5424   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5425   PetscValidPointer(steps,2);
5426   *steps = ts->total_steps;
5427   PetscFunctionReturn(0);
5428 }
5429 
5430 /*@
5431    TSGetSNESIterations - Gets the total number of nonlinear iterations
5432    used by the time integrator.
5433 
5434    Not Collective
5435 
5436    Input Parameter:
5437 .  ts - TS context
5438 
5439    Output Parameter:
5440 .  nits - number of nonlinear iterations
5441 
5442    Notes:
5443    This counter is reset to zero for each successive call to TSSolve().
5444 
5445    Level: intermediate
5446 
5447 .keywords: TS, get, number, nonlinear, iterations
5448 
5449 .seealso:  TSGetKSPIterations()
5450 @*/
5451 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits)
5452 {
5453   PetscFunctionBegin;
5454   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5455   PetscValidIntPointer(nits,2);
5456   *nits = ts->snes_its;
5457   PetscFunctionReturn(0);
5458 }
5459 
5460 /*@
5461    TSGetKSPIterations - Gets the total number of linear iterations
5462    used by the time integrator.
5463 
5464    Not Collective
5465 
5466    Input Parameter:
5467 .  ts - TS context
5468 
5469    Output Parameter:
5470 .  lits - number of linear iterations
5471 
5472    Notes:
5473    This counter is reset to zero for each successive call to TSSolve().
5474 
5475    Level: intermediate
5476 
5477 .keywords: TS, get, number, linear, iterations
5478 
5479 .seealso:  TSGetSNESIterations(), SNESGetKSPIterations()
5480 @*/
5481 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits)
5482 {
5483   PetscFunctionBegin;
5484   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5485   PetscValidIntPointer(lits,2);
5486   *lits = ts->ksp_its;
5487   PetscFunctionReturn(0);
5488 }
5489 
5490 /*@
5491    TSGetStepRejections - Gets the total number of rejected steps.
5492 
5493    Not Collective
5494 
5495    Input Parameter:
5496 .  ts - TS context
5497 
5498    Output Parameter:
5499 .  rejects - number of steps rejected
5500 
5501    Notes:
5502    This counter is reset to zero for each successive call to TSSolve().
5503 
5504    Level: intermediate
5505 
5506 .keywords: TS, get, number
5507 
5508 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails()
5509 @*/
5510 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects)
5511 {
5512   PetscFunctionBegin;
5513   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5514   PetscValidIntPointer(rejects,2);
5515   *rejects = ts->reject;
5516   PetscFunctionReturn(0);
5517 }
5518 
5519 /*@
5520    TSGetSNESFailures - Gets the total number of failed SNES solves
5521 
5522    Not Collective
5523 
5524    Input Parameter:
5525 .  ts - TS context
5526 
5527    Output Parameter:
5528 .  fails - number of failed nonlinear solves
5529 
5530    Notes:
5531    This counter is reset to zero for each successive call to TSSolve().
5532 
5533    Level: intermediate
5534 
5535 .keywords: TS, get, number
5536 
5537 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures()
5538 @*/
5539 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails)
5540 {
5541   PetscFunctionBegin;
5542   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5543   PetscValidIntPointer(fails,2);
5544   *fails = ts->num_snes_failures;
5545   PetscFunctionReturn(0);
5546 }
5547 
5548 /*@
5549    TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails
5550 
5551    Not Collective
5552 
5553    Input Parameter:
5554 +  ts - TS context
5555 -  rejects - maximum number of rejected steps, pass -1 for unlimited
5556 
5557    Notes:
5558    The counter is reset to zero for each step
5559 
5560    Options Database Key:
5561  .  -ts_max_reject - Maximum number of step rejections before a step fails
5562 
5563    Level: intermediate
5564 
5565 .keywords: TS, set, maximum, number
5566 
5567 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
5568 @*/
5569 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects)
5570 {
5571   PetscFunctionBegin;
5572   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5573   ts->max_reject = rejects;
5574   PetscFunctionReturn(0);
5575 }
5576 
5577 /*@
5578    TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves
5579 
5580    Not Collective
5581 
5582    Input Parameter:
5583 +  ts - TS context
5584 -  fails - maximum number of failed nonlinear solves, pass -1 for unlimited
5585 
5586    Notes:
5587    The counter is reset to zero for each successive call to TSSolve().
5588 
5589    Options Database Key:
5590  .  -ts_max_snes_failures - Maximum number of nonlinear solve failures
5591 
5592    Level: intermediate
5593 
5594 .keywords: TS, set, maximum, number
5595 
5596 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason()
5597 @*/
5598 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails)
5599 {
5600   PetscFunctionBegin;
5601   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5602   ts->max_snes_failures = fails;
5603   PetscFunctionReturn(0);
5604 }
5605 
5606 /*@
5607    TSSetErrorIfStepFails - Error if no step succeeds
5608 
5609    Not Collective
5610 
5611    Input Parameter:
5612 +  ts - TS context
5613 -  err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure
5614 
5615    Options Database Key:
5616  .  -ts_error_if_step_fails - Error if no step succeeds
5617 
5618    Level: intermediate
5619 
5620 .keywords: TS, set, error
5621 
5622 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
5623 @*/
5624 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err)
5625 {
5626   PetscFunctionBegin;
5627   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5628   ts->errorifstepfailed = err;
5629   PetscFunctionReturn(0);
5630 }
5631 
5632 /*@C
5633    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
5634 
5635    Collective on TS
5636 
5637    Input Parameters:
5638 +  ts - the TS context
5639 .  step - current time-step
5640 .  ptime - current time
5641 .  u - current state
5642 -  vf - viewer and its format
5643 
5644    Level: intermediate
5645 
5646 .keywords: TS,  vector, monitor, view
5647 
5648 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5649 @*/
5650 PetscErrorCode  TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
5651 {
5652   PetscErrorCode ierr;
5653 
5654   PetscFunctionBegin;
5655   ierr = PetscViewerPushFormat(vf->viewer,vf->format);CHKERRQ(ierr);
5656   ierr = VecView(u,vf->viewer);CHKERRQ(ierr);
5657   ierr = PetscViewerPopFormat(vf->viewer);CHKERRQ(ierr);
5658   PetscFunctionReturn(0);
5659 }
5660 
5661 /*@C
5662    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
5663 
5664    Collective on TS
5665 
5666    Input Parameters:
5667 +  ts - the TS context
5668 .  step - current time-step
5669 .  ptime - current time
5670 .  u - current state
5671 -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
5672 
5673    Level: intermediate
5674 
5675    Notes:
5676    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.
5677    These are named according to the file name template.
5678 
5679    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().
5680 
5681 .keywords: TS,  vector, monitor, view
5682 
5683 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5684 @*/
5685 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
5686 {
5687   PetscErrorCode ierr;
5688   char           filename[PETSC_MAX_PATH_LEN];
5689   PetscViewer    viewer;
5690 
5691   PetscFunctionBegin;
5692   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
5693   ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr);
5694   ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr);
5695   ierr = VecView(u,viewer);CHKERRQ(ierr);
5696   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
5697   PetscFunctionReturn(0);
5698 }
5699 
5700 /*@C
5701    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
5702 
5703    Collective on TS
5704 
5705    Input Parameters:
5706 .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
5707 
5708    Level: intermediate
5709 
5710    Note:
5711    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
5712 
5713 .keywords: TS,  vector, monitor, view
5714 
5715 .seealso: TSMonitorSet(), TSMonitorSolutionVTK()
5716 @*/
5717 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
5718 {
5719   PetscErrorCode ierr;
5720 
5721   PetscFunctionBegin;
5722   ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr);
5723   PetscFunctionReturn(0);
5724 }
5725 
5726 /*@
5727    TSGetAdapt - Get the adaptive controller context for the current method
5728 
5729    Collective on TS if controller has not been created yet
5730 
5731    Input Arguments:
5732 .  ts - time stepping context
5733 
5734    Output Arguments:
5735 .  adapt - adaptive controller
5736 
5737    Level: intermediate
5738 
5739 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose()
5740 @*/
5741 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt)
5742 {
5743   PetscErrorCode ierr;
5744 
5745   PetscFunctionBegin;
5746   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5747   PetscValidPointer(adapt,2);
5748   if (!ts->adapt) {
5749     ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr);
5750     ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr);
5751     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr);
5752   }
5753   *adapt = ts->adapt;
5754   PetscFunctionReturn(0);
5755 }
5756 
5757 /*@
5758    TSSetTolerances - Set tolerances for local truncation error when using adaptive controller
5759 
5760    Logically Collective
5761 
5762    Input Arguments:
5763 +  ts - time integration context
5764 .  atol - scalar absolute tolerances, PETSC_DECIDE to leave current value
5765 .  vatol - vector of absolute tolerances or NULL, used in preference to atol if present
5766 .  rtol - scalar relative tolerances, PETSC_DECIDE to leave current value
5767 -  vrtol - vector of relative tolerances or NULL, used in preference to atol if present
5768 
5769    Options Database keys:
5770 +  -ts_rtol <rtol> - relative tolerance for local truncation error
5771 -  -ts_atol <atol> Absolute tolerance for local truncation error
5772 
5773    Notes:
5774    With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error
5775    (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be
5776    computed only for the differential or the algebraic part then this can be done using the vector of
5777    tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the
5778    differential part and infinity for the algebraic part, the LTE calculation will include only the
5779    differential variables.
5780 
5781    Level: beginner
5782 
5783 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances()
5784 @*/
5785 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol)
5786 {
5787   PetscErrorCode ierr;
5788 
5789   PetscFunctionBegin;
5790   if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol;
5791   if (vatol) {
5792     ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr);
5793     ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
5794     ts->vatol = vatol;
5795   }
5796   if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol;
5797   if (vrtol) {
5798     ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr);
5799     ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
5800     ts->vrtol = vrtol;
5801   }
5802   PetscFunctionReturn(0);
5803 }
5804 
5805 /*@
5806    TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
5807 
5808    Logically Collective
5809 
5810    Input Arguments:
5811 .  ts - time integration context
5812 
5813    Output Arguments:
5814 +  atol - scalar absolute tolerances, NULL to ignore
5815 .  vatol - vector of absolute tolerances, NULL to ignore
5816 .  rtol - scalar relative tolerances, NULL to ignore
5817 -  vrtol - vector of relative tolerances, NULL to ignore
5818 
5819    Level: beginner
5820 
5821 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances()
5822 @*/
5823 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol)
5824 {
5825   PetscFunctionBegin;
5826   if (atol)  *atol  = ts->atol;
5827   if (vatol) *vatol = ts->vatol;
5828   if (rtol)  *rtol  = ts->rtol;
5829   if (vrtol) *vrtol = ts->vrtol;
5830   PetscFunctionReturn(0);
5831 }
5832 
5833 /*@
5834    TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors
5835 
5836    Collective on TS
5837 
5838    Input Arguments:
5839 +  ts - time stepping context
5840 .  U - state vector, usually ts->vec_sol
5841 -  Y - state vector to be compared to U
5842 
5843    Output Arguments:
5844 .  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
5845 .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
5846 .  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
5847 
5848    Level: developer
5849 
5850 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity()
5851 @*/
5852 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
5853 {
5854   PetscErrorCode    ierr;
5855   PetscInt          i,n,N,rstart;
5856   PetscInt          n_loc,na_loc,nr_loc;
5857   PetscReal         n_glb,na_glb,nr_glb;
5858   const PetscScalar *u,*y;
5859   PetscReal         sum,suma,sumr,gsum,gsuma,gsumr,diff;
5860   PetscReal         tol,tola,tolr;
5861   PetscReal         err_loc[6],err_glb[6];
5862 
5863   PetscFunctionBegin;
5864   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5865   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
5866   PetscValidHeaderSpecific(Y,VEC_CLASSID,3);
5867   PetscValidType(U,2);
5868   PetscValidType(Y,3);
5869   PetscCheckSameComm(U,2,Y,3);
5870   PetscValidPointer(norm,4);
5871   PetscValidPointer(norma,5);
5872   PetscValidPointer(normr,6);
5873   if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector");
5874 
5875   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
5876   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
5877   ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr);
5878   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
5879   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
5880   sum  = 0.; n_loc  = 0;
5881   suma = 0.; na_loc = 0;
5882   sumr = 0.; nr_loc = 0;
5883   if (ts->vatol && ts->vrtol) {
5884     const PetscScalar *atol,*rtol;
5885     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5886     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5887     for (i=0; i<n; i++) {
5888       diff = PetscAbsScalar(y[i] - u[i]);
5889       tola = PetscRealPart(atol[i]);
5890       if(tola>0.){
5891         suma  += PetscSqr(diff/tola);
5892         na_loc++;
5893       }
5894       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5895       if(tolr>0.){
5896         sumr  += PetscSqr(diff/tolr);
5897         nr_loc++;
5898       }
5899       tol=tola+tolr;
5900       if(tol>0.){
5901         sum  += PetscSqr(diff/tol);
5902         n_loc++;
5903       }
5904     }
5905     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5906     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5907   } else if (ts->vatol) {       /* vector atol, scalar rtol */
5908     const PetscScalar *atol;
5909     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5910     for (i=0; i<n; i++) {
5911       diff = PetscAbsScalar(y[i] - u[i]);
5912       tola = PetscRealPart(atol[i]);
5913       if(tola>0.){
5914         suma  += PetscSqr(diff/tola);
5915         na_loc++;
5916       }
5917       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5918       if(tolr>0.){
5919         sumr  += PetscSqr(diff/tolr);
5920         nr_loc++;
5921       }
5922       tol=tola+tolr;
5923       if(tol>0.){
5924         sum  += PetscSqr(diff/tol);
5925         n_loc++;
5926       }
5927     }
5928     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5929   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
5930     const PetscScalar *rtol;
5931     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5932     for (i=0; i<n; i++) {
5933       diff = PetscAbsScalar(y[i] - u[i]);
5934       tola = ts->atol;
5935       if(tola>0.){
5936         suma  += PetscSqr(diff/tola);
5937         na_loc++;
5938       }
5939       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5940       if(tolr>0.){
5941         sumr  += PetscSqr(diff/tolr);
5942         nr_loc++;
5943       }
5944       tol=tola+tolr;
5945       if(tol>0.){
5946         sum  += PetscSqr(diff/tol);
5947         n_loc++;
5948       }
5949     }
5950     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5951   } else {                      /* scalar atol, scalar rtol */
5952     for (i=0; i<n; i++) {
5953       diff = PetscAbsScalar(y[i] - u[i]);
5954      tola = ts->atol;
5955       if(tola>0.){
5956         suma  += PetscSqr(diff/tola);
5957         na_loc++;
5958       }
5959       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5960       if(tolr>0.){
5961         sumr  += PetscSqr(diff/tolr);
5962         nr_loc++;
5963       }
5964       tol=tola+tolr;
5965       if(tol>0.){
5966         sum  += PetscSqr(diff/tol);
5967         n_loc++;
5968       }
5969     }
5970   }
5971   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
5972   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
5973 
5974   err_loc[0] = sum;
5975   err_loc[1] = suma;
5976   err_loc[2] = sumr;
5977   err_loc[3] = (PetscReal)n_loc;
5978   err_loc[4] = (PetscReal)na_loc;
5979   err_loc[5] = (PetscReal)nr_loc;
5980 
5981   ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
5982 
5983   gsum   = err_glb[0];
5984   gsuma  = err_glb[1];
5985   gsumr  = err_glb[2];
5986   n_glb  = err_glb[3];
5987   na_glb = err_glb[4];
5988   nr_glb = err_glb[5];
5989 
5990   *norm  = 0.;
5991   if(n_glb>0. ){*norm  = PetscSqrtReal(gsum  / n_glb );}
5992   *norma = 0.;
5993   if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);}
5994   *normr = 0.;
5995   if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);}
5996 
5997   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
5998   if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
5999   if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
6000   PetscFunctionReturn(0);
6001 }
6002 
6003 /*@
6004    TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors
6005 
6006    Collective on TS
6007 
6008    Input Arguments:
6009 +  ts - time stepping context
6010 .  U - state vector, usually ts->vec_sol
6011 -  Y - state vector to be compared to U
6012 
6013    Output Arguments:
6014 .  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
6015 .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
6016 .  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
6017 
6018    Level: developer
6019 
6020 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2()
6021 @*/
6022 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6023 {
6024   PetscErrorCode    ierr;
6025   PetscInt          i,n,N,rstart;
6026   const PetscScalar *u,*y;
6027   PetscReal         max,gmax,maxa,gmaxa,maxr,gmaxr;
6028   PetscReal         tol,tola,tolr,diff;
6029   PetscReal         err_loc[3],err_glb[3];
6030 
6031   PetscFunctionBegin;
6032   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6033   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
6034   PetscValidHeaderSpecific(Y,VEC_CLASSID,3);
6035   PetscValidType(U,2);
6036   PetscValidType(Y,3);
6037   PetscCheckSameComm(U,2,Y,3);
6038   PetscValidPointer(norm,4);
6039   PetscValidPointer(norma,5);
6040   PetscValidPointer(normr,6);
6041   if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector");
6042 
6043   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
6044   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
6045   ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr);
6046   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
6047   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
6048 
6049   max=0.;
6050   maxa=0.;
6051   maxr=0.;
6052 
6053   if (ts->vatol && ts->vrtol) {     /* vector atol, vector rtol */
6054     const PetscScalar *atol,*rtol;
6055     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6056     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6057 
6058     for (i=0; i<n; i++) {
6059       diff = PetscAbsScalar(y[i] - u[i]);
6060       tola = PetscRealPart(atol[i]);
6061       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6062       tol  = tola+tolr;
6063       if(tola>0.){
6064         maxa = PetscMax(maxa,diff / tola);
6065       }
6066       if(tolr>0.){
6067         maxr = PetscMax(maxr,diff / tolr);
6068       }
6069       if(tol>0.){
6070         max = PetscMax(max,diff / tol);
6071       }
6072     }
6073     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6074     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6075   } else if (ts->vatol) {       /* vector atol, scalar rtol */
6076     const PetscScalar *atol;
6077     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6078     for (i=0; i<n; i++) {
6079       diff = PetscAbsScalar(y[i] - u[i]);
6080       tola = PetscRealPart(atol[i]);
6081       tolr = ts->rtol  * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6082       tol  = tola+tolr;
6083       if(tola>0.){
6084         maxa = PetscMax(maxa,diff / tola);
6085       }
6086       if(tolr>0.){
6087         maxr = PetscMax(maxr,diff / tolr);
6088       }
6089       if(tol>0.){
6090         max = PetscMax(max,diff / tol);
6091       }
6092     }
6093     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6094   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
6095     const PetscScalar *rtol;
6096     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6097 
6098     for (i=0; i<n; i++) {
6099       diff = PetscAbsScalar(y[i] - u[i]);
6100       tola = ts->atol;
6101       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6102       tol  = tola+tolr;
6103       if(tola>0.){
6104         maxa = PetscMax(maxa,diff / tola);
6105       }
6106       if(tolr>0.){
6107         maxr = PetscMax(maxr,diff / tolr);
6108       }
6109       if(tol>0.){
6110         max = PetscMax(max,diff / tol);
6111       }
6112     }
6113     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6114   } else {                      /* scalar atol, scalar rtol */
6115 
6116     for (i=0; i<n; i++) {
6117       diff = PetscAbsScalar(y[i] - u[i]);
6118       tola = ts->atol;
6119       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6120       tol  = tola+tolr;
6121       if(tola>0.){
6122         maxa = PetscMax(maxa,diff / tola);
6123       }
6124       if(tolr>0.){
6125         maxr = PetscMax(maxr,diff / tolr);
6126       }
6127       if(tol>0.){
6128         max = PetscMax(max,diff / tol);
6129       }
6130     }
6131   }
6132   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
6133   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
6134   err_loc[0] = max;
6135   err_loc[1] = maxa;
6136   err_loc[2] = maxr;
6137   ierr  = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6138   gmax   = err_glb[0];
6139   gmaxa  = err_glb[1];
6140   gmaxr  = err_glb[2];
6141 
6142   *norm = gmax;
6143   *norma = gmaxa;
6144   *normr = gmaxr;
6145   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
6146     if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
6147     if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
6148   PetscFunctionReturn(0);
6149 }
6150 
6151 /*@
6152    TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances
6153 
6154    Collective on TS
6155 
6156    Input Arguments:
6157 +  ts - time stepping context
6158 .  U - state vector, usually ts->vec_sol
6159 .  Y - state vector to be compared to U
6160 -  wnormtype - norm type, either NORM_2 or NORM_INFINITY
6161 
6162    Output Arguments:
6163 .  norm  - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances
6164 .  norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user
6165 .  normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user
6166 
6167    Options Database Keys:
6168 .  -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
6169 
6170    Level: developer
6171 
6172 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2(), TSErrorWeightedENorm
6173 @*/
6174 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6175 {
6176   PetscErrorCode ierr;
6177 
6178   PetscFunctionBegin;
6179   if (wnormtype == NORM_2) {
6180     ierr = TSErrorWeightedNorm2(ts,U,Y,norm,norma,normr);CHKERRQ(ierr);
6181   } else if(wnormtype == NORM_INFINITY) {
6182     ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm,norma,normr);CHKERRQ(ierr);
6183   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
6184   PetscFunctionReturn(0);
6185 }
6186 
6187 
6188 /*@
6189    TSErrorWeightedENorm2 - compute a weighted 2 error norm based on supplied absolute and relative tolerances
6190 
6191    Collective on TS
6192 
6193    Input Arguments:
6194 +  ts - time stepping context
6195 .  E - error vector
6196 .  U - state vector, usually ts->vec_sol
6197 -  Y - state vector, previous time step
6198 
6199    Output Arguments:
6200 .  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
6201 .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
6202 .  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
6203 
6204    Level: developer
6205 
6206 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENormInfinity()
6207 @*/
6208 PetscErrorCode TSErrorWeightedENorm2(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6209 {
6210   PetscErrorCode    ierr;
6211   PetscInt          i,n,N,rstart;
6212   PetscInt          n_loc,na_loc,nr_loc;
6213   PetscReal         n_glb,na_glb,nr_glb;
6214   const PetscScalar *e,*u,*y;
6215   PetscReal         err,sum,suma,sumr,gsum,gsuma,gsumr;
6216   PetscReal         tol,tola,tolr;
6217   PetscReal         err_loc[6],err_glb[6];
6218 
6219   PetscFunctionBegin;
6220   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6221   PetscValidHeaderSpecific(E,VEC_CLASSID,2);
6222   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
6223   PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
6224   PetscValidType(E,2);
6225   PetscValidType(U,3);
6226   PetscValidType(Y,4);
6227   PetscCheckSameComm(E,2,U,3);
6228   PetscCheckSameComm(U,2,Y,3);
6229   PetscValidPointer(norm,5);
6230   PetscValidPointer(norma,6);
6231   PetscValidPointer(normr,7);
6232 
6233   ierr = VecGetSize(E,&N);CHKERRQ(ierr);
6234   ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr);
6235   ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr);
6236   ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr);
6237   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
6238   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
6239   sum  = 0.; n_loc  = 0;
6240   suma = 0.; na_loc = 0;
6241   sumr = 0.; nr_loc = 0;
6242   if (ts->vatol && ts->vrtol) {
6243     const PetscScalar *atol,*rtol;
6244     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6245     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6246     for (i=0; i<n; i++) {
6247       err = PetscAbsScalar(e[i]);
6248       tola = PetscRealPart(atol[i]);
6249       if(tola>0.){
6250         suma  += PetscSqr(err/tola);
6251         na_loc++;
6252       }
6253       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6254       if(tolr>0.){
6255         sumr  += PetscSqr(err/tolr);
6256         nr_loc++;
6257       }
6258       tol=tola+tolr;
6259       if(tol>0.){
6260         sum  += PetscSqr(err/tol);
6261         n_loc++;
6262       }
6263     }
6264     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6265     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6266   } else if (ts->vatol) {       /* vector atol, scalar rtol */
6267     const PetscScalar *atol;
6268     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6269     for (i=0; i<n; i++) {
6270       err = PetscAbsScalar(e[i]);
6271       tola = PetscRealPart(atol[i]);
6272       if(tola>0.){
6273         suma  += PetscSqr(err/tola);
6274         na_loc++;
6275       }
6276       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6277       if(tolr>0.){
6278         sumr  += PetscSqr(err/tolr);
6279         nr_loc++;
6280       }
6281       tol=tola+tolr;
6282       if(tol>0.){
6283         sum  += PetscSqr(err/tol);
6284         n_loc++;
6285       }
6286     }
6287     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6288   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
6289     const PetscScalar *rtol;
6290     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6291     for (i=0; i<n; i++) {
6292       err = PetscAbsScalar(e[i]);
6293       tola = ts->atol;
6294       if(tola>0.){
6295         suma  += PetscSqr(err/tola);
6296         na_loc++;
6297       }
6298       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6299       if(tolr>0.){
6300         sumr  += PetscSqr(err/tolr);
6301         nr_loc++;
6302       }
6303       tol=tola+tolr;
6304       if(tol>0.){
6305         sum  += PetscSqr(err/tol);
6306         n_loc++;
6307       }
6308     }
6309     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6310   } else {                      /* scalar atol, scalar rtol */
6311     for (i=0; i<n; i++) {
6312       err = PetscAbsScalar(e[i]);
6313      tola = ts->atol;
6314       if(tola>0.){
6315         suma  += PetscSqr(err/tola);
6316         na_loc++;
6317       }
6318       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6319       if(tolr>0.){
6320         sumr  += PetscSqr(err/tolr);
6321         nr_loc++;
6322       }
6323       tol=tola+tolr;
6324       if(tol>0.){
6325         sum  += PetscSqr(err/tol);
6326         n_loc++;
6327       }
6328     }
6329   }
6330   ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr);
6331   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
6332   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
6333 
6334   err_loc[0] = sum;
6335   err_loc[1] = suma;
6336   err_loc[2] = sumr;
6337   err_loc[3] = (PetscReal)n_loc;
6338   err_loc[4] = (PetscReal)na_loc;
6339   err_loc[5] = (PetscReal)nr_loc;
6340 
6341   ierr = MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6342 
6343   gsum   = err_glb[0];
6344   gsuma  = err_glb[1];
6345   gsumr  = err_glb[2];
6346   n_glb  = err_glb[3];
6347   na_glb = err_glb[4];
6348   nr_glb = err_glb[5];
6349 
6350   *norm  = 0.;
6351   if(n_glb>0. ){*norm  = PetscSqrtReal(gsum  / n_glb );}
6352   *norma = 0.;
6353   if(na_glb>0.){*norma = PetscSqrtReal(gsuma / na_glb);}
6354   *normr = 0.;
6355   if(nr_glb>0.){*normr = PetscSqrtReal(gsumr / nr_glb);}
6356 
6357   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
6358   if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
6359   if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
6360   PetscFunctionReturn(0);
6361 }
6362 
6363 /*@
6364    TSErrorWeightedENormInfinity - compute a weighted infinity error norm based on supplied absolute and relative tolerances
6365    Collective on TS
6366 
6367    Input Arguments:
6368 +  ts - time stepping context
6369 .  E - error vector
6370 .  U - state vector, usually ts->vec_sol
6371 -  Y - state vector, previous time step
6372 
6373    Output Arguments:
6374 .  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
6375 .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
6376 .  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
6377 
6378    Level: developer
6379 
6380 .seealso: TSErrorWeightedENorm(), TSErrorWeightedENorm2()
6381 @*/
6382 PetscErrorCode TSErrorWeightedENormInfinity(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6383 {
6384   PetscErrorCode    ierr;
6385   PetscInt          i,n,N,rstart;
6386   const PetscScalar *e,*u,*y;
6387   PetscReal         err,max,gmax,maxa,gmaxa,maxr,gmaxr;
6388   PetscReal         tol,tola,tolr;
6389   PetscReal         err_loc[3],err_glb[3];
6390 
6391   PetscFunctionBegin;
6392   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6393   PetscValidHeaderSpecific(E,VEC_CLASSID,2);
6394   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
6395   PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
6396   PetscValidType(E,2);
6397   PetscValidType(U,3);
6398   PetscValidType(Y,4);
6399   PetscCheckSameComm(E,2,U,3);
6400   PetscCheckSameComm(U,2,Y,3);
6401   PetscValidPointer(norm,5);
6402   PetscValidPointer(norma,6);
6403   PetscValidPointer(normr,7);
6404 
6405   ierr = VecGetSize(E,&N);CHKERRQ(ierr);
6406   ierr = VecGetLocalSize(E,&n);CHKERRQ(ierr);
6407   ierr = VecGetOwnershipRange(E,&rstart,NULL);CHKERRQ(ierr);
6408   ierr = VecGetArrayRead(E,&e);CHKERRQ(ierr);
6409   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
6410   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
6411 
6412   max=0.;
6413   maxa=0.;
6414   maxr=0.;
6415 
6416   if (ts->vatol && ts->vrtol) {     /* vector atol, vector rtol */
6417     const PetscScalar *atol,*rtol;
6418     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6419     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6420 
6421     for (i=0; i<n; i++) {
6422       err = PetscAbsScalar(e[i]);
6423       tola = PetscRealPart(atol[i]);
6424       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6425       tol  = tola+tolr;
6426       if(tola>0.){
6427         maxa = PetscMax(maxa,err / tola);
6428       }
6429       if(tolr>0.){
6430         maxr = PetscMax(maxr,err / tolr);
6431       }
6432       if(tol>0.){
6433         max = PetscMax(max,err / tol);
6434       }
6435     }
6436     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6437     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6438   } else if (ts->vatol) {       /* vector atol, scalar rtol */
6439     const PetscScalar *atol;
6440     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6441     for (i=0; i<n; i++) {
6442       err = PetscAbsScalar(e[i]);
6443       tola = PetscRealPart(atol[i]);
6444       tolr = ts->rtol  * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6445       tol  = tola+tolr;
6446       if(tola>0.){
6447         maxa = PetscMax(maxa,err / tola);
6448       }
6449       if(tolr>0.){
6450         maxr = PetscMax(maxr,err / tolr);
6451       }
6452       if(tol>0.){
6453         max = PetscMax(max,err / tol);
6454       }
6455     }
6456     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
6457   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
6458     const PetscScalar *rtol;
6459     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6460 
6461     for (i=0; i<n; i++) {
6462       err = PetscAbsScalar(e[i]);
6463       tola = ts->atol;
6464       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6465       tol  = tola+tolr;
6466       if(tola>0.){
6467         maxa = PetscMax(maxa,err / tola);
6468       }
6469       if(tolr>0.){
6470         maxr = PetscMax(maxr,err / tolr);
6471       }
6472       if(tol>0.){
6473         max = PetscMax(max,err / tol);
6474       }
6475     }
6476     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
6477   } else {                      /* scalar atol, scalar rtol */
6478 
6479     for (i=0; i<n; i++) {
6480       err = PetscAbsScalar(e[i]);
6481       tola = ts->atol;
6482       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
6483       tol  = tola+tolr;
6484       if(tola>0.){
6485         maxa = PetscMax(maxa,err / tola);
6486       }
6487       if(tolr>0.){
6488         maxr = PetscMax(maxr,err / tolr);
6489       }
6490       if(tol>0.){
6491         max = PetscMax(max,err / tol);
6492       }
6493     }
6494   }
6495   ierr = VecRestoreArrayRead(E,&e);CHKERRQ(ierr);
6496   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
6497   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
6498   err_loc[0] = max;
6499   err_loc[1] = maxa;
6500   err_loc[2] = maxr;
6501   ierr  = MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6502   gmax   = err_glb[0];
6503   gmaxa  = err_glb[1];
6504   gmaxr  = err_glb[2];
6505 
6506   *norm = gmax;
6507   *norma = gmaxa;
6508   *normr = gmaxr;
6509   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
6510     if (PetscIsInfOrNanScalar(*norma)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
6511     if (PetscIsInfOrNanScalar(*normr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
6512   PetscFunctionReturn(0);
6513 }
6514 
6515 /*@
6516    TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances
6517 
6518    Collective on TS
6519 
6520    Input Arguments:
6521 +  ts - time stepping context
6522 .  E - error vector
6523 .  U - state vector, usually ts->vec_sol
6524 .  Y - state vector, previous time step
6525 -  wnormtype - norm type, either NORM_2 or NORM_INFINITY
6526 
6527    Output Arguments:
6528 .  norm  - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances
6529 .  norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user
6530 .  normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user
6531 
6532    Options Database Keys:
6533 .  -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
6534 
6535    Level: developer
6536 
6537 .seealso: TSErrorWeightedENormInfinity(), TSErrorWeightedENorm2(), TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2()
6538 @*/
6539 PetscErrorCode TSErrorWeightedENorm(TS ts,Vec E,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr)
6540 {
6541   PetscErrorCode ierr;
6542 
6543   PetscFunctionBegin;
6544   if (wnormtype == NORM_2) {
6545     ierr = TSErrorWeightedENorm2(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr);
6546   } else if(wnormtype == NORM_INFINITY) {
6547     ierr = TSErrorWeightedENormInfinity(ts,E,U,Y,norm,norma,normr);CHKERRQ(ierr);
6548   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
6549   PetscFunctionReturn(0);
6550 }
6551 
6552 
6553 /*@
6554    TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
6555 
6556    Logically Collective on TS
6557 
6558    Input Arguments:
6559 +  ts - time stepping context
6560 -  cfltime - maximum stable time step if using forward Euler (value can be different on each process)
6561 
6562    Note:
6563    After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
6564 
6565    Level: intermediate
6566 
6567 .seealso: TSGetCFLTime(), TSADAPTCFL
6568 @*/
6569 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime)
6570 {
6571   PetscFunctionBegin;
6572   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6573   ts->cfltime_local = cfltime;
6574   ts->cfltime       = -1.;
6575   PetscFunctionReturn(0);
6576 }
6577 
6578 /*@
6579    TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
6580 
6581    Collective on TS
6582 
6583    Input Arguments:
6584 .  ts - time stepping context
6585 
6586    Output Arguments:
6587 .  cfltime - maximum stable time step for forward Euler
6588 
6589    Level: advanced
6590 
6591 .seealso: TSSetCFLTimeLocal()
6592 @*/
6593 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime)
6594 {
6595   PetscErrorCode ierr;
6596 
6597   PetscFunctionBegin;
6598   if (ts->cfltime < 0) {
6599     ierr = MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
6600   }
6601   *cfltime = ts->cfltime;
6602   PetscFunctionReturn(0);
6603 }
6604 
6605 /*@
6606    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
6607 
6608    Input Parameters:
6609 .  ts   - the TS context.
6610 .  xl   - lower bound.
6611 .  xu   - upper bound.
6612 
6613    Notes:
6614    If this routine is not called then the lower and upper bounds are set to
6615    PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp().
6616 
6617    Level: advanced
6618 
6619 @*/
6620 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
6621 {
6622   PetscErrorCode ierr;
6623   SNES           snes;
6624 
6625   PetscFunctionBegin;
6626   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
6627   ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr);
6628   PetscFunctionReturn(0);
6629 }
6630 
6631 #if defined(PETSC_HAVE_MATLAB_ENGINE)
6632 #include <mex.h>
6633 
6634 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext;
6635 
6636 /*
6637    TSComputeFunction_Matlab - Calls the function that has been set with
6638                          TSSetFunctionMatlab().
6639 
6640    Collective on TS
6641 
6642    Input Parameters:
6643 +  snes - the TS context
6644 -  u - input vector
6645 
6646    Output Parameter:
6647 .  y - function vector, as set by TSSetFunction()
6648 
6649    Notes:
6650    TSComputeFunction() is typically used within nonlinear solvers
6651    implementations, so most users would not generally call this routine
6652    themselves.
6653 
6654    Level: developer
6655 
6656 .keywords: TS, nonlinear, compute, function
6657 
6658 .seealso: TSSetFunction(), TSGetFunction()
6659 */
6660 PetscErrorCode  TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx)
6661 {
6662   PetscErrorCode  ierr;
6663   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
6664   int             nlhs  = 1,nrhs = 7;
6665   mxArray         *plhs[1],*prhs[7];
6666   long long int   lx = 0,lxdot = 0,ly = 0,ls = 0;
6667 
6668   PetscFunctionBegin;
6669   PetscValidHeaderSpecific(snes,TS_CLASSID,1);
6670   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
6671   PetscValidHeaderSpecific(udot,VEC_CLASSID,4);
6672   PetscValidHeaderSpecific(y,VEC_CLASSID,5);
6673   PetscCheckSameComm(snes,1,u,3);
6674   PetscCheckSameComm(snes,1,y,5);
6675 
6676   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
6677   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
6678   ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr);
6679   ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr);
6680 
6681   prhs[0] =  mxCreateDoubleScalar((double)ls);
6682   prhs[1] =  mxCreateDoubleScalar(time);
6683   prhs[2] =  mxCreateDoubleScalar((double)lx);
6684   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
6685   prhs[4] =  mxCreateDoubleScalar((double)ly);
6686   prhs[5] =  mxCreateString(sctx->funcname);
6687   prhs[6] =  sctx->ctx;
6688   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr);
6689   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
6690   mxDestroyArray(prhs[0]);
6691   mxDestroyArray(prhs[1]);
6692   mxDestroyArray(prhs[2]);
6693   mxDestroyArray(prhs[3]);
6694   mxDestroyArray(prhs[4]);
6695   mxDestroyArray(prhs[5]);
6696   mxDestroyArray(plhs[0]);
6697   PetscFunctionReturn(0);
6698 }
6699 
6700 
6701 /*
6702    TSSetFunctionMatlab - Sets the function evaluation routine and function
6703    vector for use by the TS routines in solving ODEs
6704    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
6705 
6706    Logically Collective on TS
6707 
6708    Input Parameters:
6709 +  ts - the TS context
6710 -  func - function evaluation routine
6711 
6712    Calling sequence of func:
6713 $    func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx);
6714 
6715    Level: beginner
6716 
6717 .keywords: TS, nonlinear, set, function
6718 
6719 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
6720 */
6721 PetscErrorCode  TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx)
6722 {
6723   PetscErrorCode  ierr;
6724   TSMatlabContext *sctx;
6725 
6726   PetscFunctionBegin;
6727   /* currently sctx is memory bleed */
6728   ierr = PetscNew(&sctx);CHKERRQ(ierr);
6729   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
6730   /*
6731      This should work, but it doesn't
6732   sctx->ctx = ctx;
6733   mexMakeArrayPersistent(sctx->ctx);
6734   */
6735   sctx->ctx = mxDuplicateArray(ctx);
6736 
6737   ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr);
6738   PetscFunctionReturn(0);
6739 }
6740 
6741 /*
6742    TSComputeJacobian_Matlab - Calls the function that has been set with
6743                          TSSetJacobianMatlab().
6744 
6745    Collective on TS
6746 
6747    Input Parameters:
6748 +  ts - the TS context
6749 .  u - input vector
6750 .  A, B - the matrices
6751 -  ctx - user context
6752 
6753    Level: developer
6754 
6755 .keywords: TS, nonlinear, compute, function
6756 
6757 .seealso: TSSetFunction(), TSGetFunction()
6758 @*/
6759 PetscErrorCode  TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat A,Mat B,void *ctx)
6760 {
6761   PetscErrorCode  ierr;
6762   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
6763   int             nlhs  = 2,nrhs = 9;
6764   mxArray         *plhs[2],*prhs[9];
6765   long long int   lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0;
6766 
6767   PetscFunctionBegin;
6768   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6769   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
6770 
6771   /* call Matlab function in ctx with arguments u and y */
6772 
6773   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
6774   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
6775   ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr);
6776   ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr);
6777   ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr);
6778 
6779   prhs[0] =  mxCreateDoubleScalar((double)ls);
6780   prhs[1] =  mxCreateDoubleScalar((double)time);
6781   prhs[2] =  mxCreateDoubleScalar((double)lx);
6782   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
6783   prhs[4] =  mxCreateDoubleScalar((double)shift);
6784   prhs[5] =  mxCreateDoubleScalar((double)lA);
6785   prhs[6] =  mxCreateDoubleScalar((double)lB);
6786   prhs[7] =  mxCreateString(sctx->funcname);
6787   prhs[8] =  sctx->ctx;
6788   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr);
6789   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
6790   mxDestroyArray(prhs[0]);
6791   mxDestroyArray(prhs[1]);
6792   mxDestroyArray(prhs[2]);
6793   mxDestroyArray(prhs[3]);
6794   mxDestroyArray(prhs[4]);
6795   mxDestroyArray(prhs[5]);
6796   mxDestroyArray(prhs[6]);
6797   mxDestroyArray(prhs[7]);
6798   mxDestroyArray(plhs[0]);
6799   mxDestroyArray(plhs[1]);
6800   PetscFunctionReturn(0);
6801 }
6802 
6803 
6804 /*
6805    TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
6806    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
6807 
6808    Logically Collective on TS
6809 
6810    Input Parameters:
6811 +  ts - the TS context
6812 .  A,B - Jacobian matrices
6813 .  func - function evaluation routine
6814 -  ctx - user context
6815 
6816    Calling sequence of func:
6817 $    flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx);
6818 
6819 
6820    Level: developer
6821 
6822 .keywords: TS, nonlinear, set, function
6823 
6824 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
6825 */
6826 PetscErrorCode  TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx)
6827 {
6828   PetscErrorCode  ierr;
6829   TSMatlabContext *sctx;
6830 
6831   PetscFunctionBegin;
6832   /* currently sctx is memory bleed */
6833   ierr = PetscNew(&sctx);CHKERRQ(ierr);
6834   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
6835   /*
6836      This should work, but it doesn't
6837   sctx->ctx = ctx;
6838   mexMakeArrayPersistent(sctx->ctx);
6839   */
6840   sctx->ctx = mxDuplicateArray(ctx);
6841 
6842   ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
6843   PetscFunctionReturn(0);
6844 }
6845 
6846 /*
6847    TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab().
6848 
6849    Collective on TS
6850 
6851 .seealso: TSSetFunction(), TSGetFunction()
6852 @*/
6853 PetscErrorCode  TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx)
6854 {
6855   PetscErrorCode  ierr;
6856   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
6857   int             nlhs  = 1,nrhs = 6;
6858   mxArray         *plhs[1],*prhs[6];
6859   long long int   lx = 0,ls = 0;
6860 
6861   PetscFunctionBegin;
6862   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6863   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
6864 
6865   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
6866   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
6867 
6868   prhs[0] =  mxCreateDoubleScalar((double)ls);
6869   prhs[1] =  mxCreateDoubleScalar((double)it);
6870   prhs[2] =  mxCreateDoubleScalar((double)time);
6871   prhs[3] =  mxCreateDoubleScalar((double)lx);
6872   prhs[4] =  mxCreateString(sctx->funcname);
6873   prhs[5] =  sctx->ctx;
6874   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr);
6875   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
6876   mxDestroyArray(prhs[0]);
6877   mxDestroyArray(prhs[1]);
6878   mxDestroyArray(prhs[2]);
6879   mxDestroyArray(prhs[3]);
6880   mxDestroyArray(prhs[4]);
6881   mxDestroyArray(plhs[0]);
6882   PetscFunctionReturn(0);
6883 }
6884 
6885 
6886 /*
6887    TSMonitorSetMatlab - Sets the monitor function from Matlab
6888 
6889    Level: developer
6890 
6891 .keywords: TS, nonlinear, set, function
6892 
6893 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
6894 */
6895 PetscErrorCode  TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx)
6896 {
6897   PetscErrorCode  ierr;
6898   TSMatlabContext *sctx;
6899 
6900   PetscFunctionBegin;
6901   /* currently sctx is memory bleed */
6902   ierr = PetscNew(&sctx);CHKERRQ(ierr);
6903   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
6904   /*
6905      This should work, but it doesn't
6906   sctx->ctx = ctx;
6907   mexMakeArrayPersistent(sctx->ctx);
6908   */
6909   sctx->ctx = mxDuplicateArray(ctx);
6910 
6911   ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr);
6912   PetscFunctionReturn(0);
6913 }
6914 #endif
6915 
6916 /*@C
6917    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
6918        in a time based line graph
6919 
6920    Collective on TS
6921 
6922    Input Parameters:
6923 +  ts - the TS context
6924 .  step - current time-step
6925 .  ptime - current time
6926 .  u - current solution
6927 -  dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate()
6928 
6929    Options Database:
6930 .   -ts_monitor_lg_solution_variables
6931 
6932    Level: intermediate
6933 
6934    Notes: Each process in a parallel run displays its component solutions in a separate window
6935 
6936 .keywords: TS,  vector, monitor, view
6937 
6938 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
6939            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
6940            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
6941            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()
6942 @*/
6943 PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
6944 {
6945   PetscErrorCode    ierr;
6946   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dctx;
6947   const PetscScalar *yy;
6948   Vec               v;
6949 
6950   PetscFunctionBegin;
6951   if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
6952   if (!step) {
6953     PetscDrawAxis axis;
6954     PetscInt      dim;
6955     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
6956     ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr);
6957     if (!ctx->names) {
6958       PetscBool flg;
6959       /* user provides names of variables to plot but no names has been set so assume names are integer values */
6960       ierr = PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg);CHKERRQ(ierr);
6961       if (flg) {
6962         PetscInt i,n;
6963         char     **names;
6964         ierr = VecGetSize(u,&n);CHKERRQ(ierr);
6965         ierr = PetscMalloc1(n+1,&names);CHKERRQ(ierr);
6966         for (i=0; i<n; i++) {
6967           ierr = PetscMalloc1(5,&names[i]);CHKERRQ(ierr);
6968           ierr = PetscSNPrintf(names[i],5,"%D",i);CHKERRQ(ierr);
6969         }
6970         names[n] = NULL;
6971         ctx->names = names;
6972       }
6973     }
6974     if (ctx->names && !ctx->displaynames) {
6975       char      **displaynames;
6976       PetscBool flg;
6977       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
6978       ierr = PetscMalloc1(dim+1,&displaynames);CHKERRQ(ierr);
6979       ierr = PetscMemzero(displaynames,(dim+1)*sizeof(char*));CHKERRQ(ierr);
6980       ierr = PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr);
6981       if (flg) {
6982         ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr);
6983       }
6984       ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr);
6985     }
6986     if (ctx->displaynames) {
6987       ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr);
6988       ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr);
6989     } else if (ctx->names) {
6990       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
6991       ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
6992       ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr);
6993     } else {
6994       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
6995       ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
6996     }
6997     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
6998   }
6999 
7000   if (!ctx->transform) v = u;
7001   else {ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);}
7002   ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr);
7003   if (ctx->displaynames) {
7004     PetscInt i;
7005     for (i=0; i<ctx->ndisplayvariables; i++)
7006       ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]);
7007     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr);
7008   } else {
7009 #if defined(PETSC_USE_COMPLEX)
7010     PetscInt  i,n;
7011     PetscReal *yreal;
7012     ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
7013     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
7014     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
7015     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
7016     ierr = PetscFree(yreal);CHKERRQ(ierr);
7017 #else
7018     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
7019 #endif
7020   }
7021   ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr);
7022   if (ctx->transform) {ierr = VecDestroy(&v);CHKERRQ(ierr);}
7023 
7024   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
7025     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7026     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7027   }
7028   PetscFunctionReturn(0);
7029 }
7030 
7031 
7032 /*@C
7033    TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
7034 
7035    Collective on TS
7036 
7037    Input Parameters:
7038 +  ts - the TS context
7039 -  names - the names of the components, final string must be NULL
7040 
7041    Level: intermediate
7042 
7043    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
7044 
7045 .keywords: TS,  vector, monitor, view
7046 
7047 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames()
7048 @*/
7049 PetscErrorCode  TSMonitorLGSetVariableNames(TS ts,const char * const *names)
7050 {
7051   PetscErrorCode    ierr;
7052   PetscInt          i;
7053 
7054   PetscFunctionBegin;
7055   for (i=0; i<ts->numbermonitors; i++) {
7056     if (ts->monitor[i] == TSMonitorLGSolution) {
7057       ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr);
7058       break;
7059     }
7060   }
7061   PetscFunctionReturn(0);
7062 }
7063 
7064 /*@C
7065    TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
7066 
7067    Collective on TS
7068 
7069    Input Parameters:
7070 +  ts - the TS context
7071 -  names - the names of the components, final string must be NULL
7072 
7073    Level: intermediate
7074 
7075 .keywords: TS,  vector, monitor, view
7076 
7077 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames()
7078 @*/
7079 PetscErrorCode  TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names)
7080 {
7081   PetscErrorCode    ierr;
7082 
7083   PetscFunctionBegin;
7084   ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr);
7085   ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr);
7086   PetscFunctionReturn(0);
7087 }
7088 
7089 /*@C
7090    TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot
7091 
7092    Collective on TS
7093 
7094    Input Parameter:
7095 .  ts - the TS context
7096 
7097    Output Parameter:
7098 .  names - the names of the components, final string must be NULL
7099 
7100    Level: intermediate
7101 
7102    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
7103 
7104 .keywords: TS,  vector, monitor, view
7105 
7106 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
7107 @*/
7108 PetscErrorCode  TSMonitorLGGetVariableNames(TS ts,const char *const **names)
7109 {
7110   PetscInt       i;
7111 
7112   PetscFunctionBegin;
7113   *names = NULL;
7114   for (i=0; i<ts->numbermonitors; i++) {
7115     if (ts->monitor[i] == TSMonitorLGSolution) {
7116       TSMonitorLGCtx  ctx = (TSMonitorLGCtx) ts->monitorcontext[i];
7117       *names = (const char *const *)ctx->names;
7118       break;
7119     }
7120   }
7121   PetscFunctionReturn(0);
7122 }
7123 
7124 /*@C
7125    TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor
7126 
7127    Collective on TS
7128 
7129    Input Parameters:
7130 +  ctx - the TSMonitorLG context
7131 .  displaynames - the names of the components, final string must be NULL
7132 
7133    Level: intermediate
7134 
7135 .keywords: TS,  vector, monitor, view
7136 
7137 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
7138 @*/
7139 PetscErrorCode  TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames)
7140 {
7141   PetscInt          j = 0,k;
7142   PetscErrorCode    ierr;
7143 
7144   PetscFunctionBegin;
7145   if (!ctx->names) PetscFunctionReturn(0);
7146   ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr);
7147   ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr);
7148   while (displaynames[j]) j++;
7149   ctx->ndisplayvariables = j;
7150   ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr);
7151   ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr);
7152   j = 0;
7153   while (displaynames[j]) {
7154     k = 0;
7155     while (ctx->names[k]) {
7156       PetscBool flg;
7157       ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr);
7158       if (flg) {
7159         ctx->displayvariables[j] = k;
7160         break;
7161       }
7162       k++;
7163     }
7164     j++;
7165   }
7166   PetscFunctionReturn(0);
7167 }
7168 
7169 
7170 /*@C
7171    TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor
7172 
7173    Collective on TS
7174 
7175    Input Parameters:
7176 +  ts - the TS context
7177 .  displaynames - the names of the components, final string must be NULL
7178 
7179    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
7180 
7181    Level: intermediate
7182 
7183 .keywords: TS,  vector, monitor, view
7184 
7185 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
7186 @*/
7187 PetscErrorCode  TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames)
7188 {
7189   PetscInt          i;
7190   PetscErrorCode    ierr;
7191 
7192   PetscFunctionBegin;
7193   for (i=0; i<ts->numbermonitors; i++) {
7194     if (ts->monitor[i] == TSMonitorLGSolution) {
7195       ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr);
7196       break;
7197     }
7198   }
7199   PetscFunctionReturn(0);
7200 }
7201 
7202 /*@C
7203    TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed
7204 
7205    Collective on TS
7206 
7207    Input Parameters:
7208 +  ts - the TS context
7209 .  transform - the transform function
7210 .  destroy - function to destroy the optional context
7211 -  ctx - optional context used by transform function
7212 
7213    Notes: If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored
7214 
7215    Level: intermediate
7216 
7217 .keywords: TS,  vector, monitor, view
7218 
7219 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform()
7220 @*/
7221 PetscErrorCode  TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
7222 {
7223   PetscInt          i;
7224   PetscErrorCode    ierr;
7225 
7226   PetscFunctionBegin;
7227   for (i=0; i<ts->numbermonitors; i++) {
7228     if (ts->monitor[i] == TSMonitorLGSolution) {
7229       ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr);
7230     }
7231   }
7232   PetscFunctionReturn(0);
7233 }
7234 
7235 /*@C
7236    TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed
7237 
7238    Collective on TSLGCtx
7239 
7240    Input Parameters:
7241 +  ts - the TS context
7242 .  transform - the transform function
7243 .  destroy - function to destroy the optional context
7244 -  ctx - optional context used by transform function
7245 
7246    Level: intermediate
7247 
7248 .keywords: TS,  vector, monitor, view
7249 
7250 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform()
7251 @*/
7252 PetscErrorCode  TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
7253 {
7254   PetscFunctionBegin;
7255   ctx->transform    = transform;
7256   ctx->transformdestroy = destroy;
7257   ctx->transformctx = tctx;
7258   PetscFunctionReturn(0);
7259 }
7260 
7261 /*@C
7262    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector
7263        in a time based line graph
7264 
7265    Collective on TS
7266 
7267    Input Parameters:
7268 +  ts - the TS context
7269 .  step - current time-step
7270 .  ptime - current time
7271 .  u - current solution
7272 -  dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate()
7273 
7274    Level: intermediate
7275 
7276    Notes: Each process in a parallel run displays its component errors in a separate window
7277 
7278    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
7279 
7280    Options Database Keys:
7281 .  -ts_monitor_lg_error - create a graphical monitor of error history
7282 
7283 .keywords: TS,  vector, monitor, view
7284 
7285 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
7286 @*/
7287 PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
7288 {
7289   PetscErrorCode    ierr;
7290   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
7291   const PetscScalar *yy;
7292   Vec               y;
7293 
7294   PetscFunctionBegin;
7295   if (!step) {
7296     PetscDrawAxis axis;
7297     PetscInt      dim;
7298     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
7299     ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr);
7300     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
7301     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
7302     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
7303   }
7304   ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
7305   ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr);
7306   ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr);
7307   ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr);
7308 #if defined(PETSC_USE_COMPLEX)
7309   {
7310     PetscReal *yreal;
7311     PetscInt  i,n;
7312     ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr);
7313     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
7314     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
7315     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
7316     ierr = PetscFree(yreal);CHKERRQ(ierr);
7317   }
7318 #else
7319   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
7320 #endif
7321   ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr);
7322   ierr = VecDestroy(&y);CHKERRQ(ierr);
7323   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
7324     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7325     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7326   }
7327   PetscFunctionReturn(0);
7328 }
7329 
7330 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
7331 {
7332   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
7333   PetscReal      x   = ptime,y;
7334   PetscErrorCode ierr;
7335   PetscInt       its;
7336 
7337   PetscFunctionBegin;
7338   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
7339   if (!n) {
7340     PetscDrawAxis axis;
7341     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
7342     ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr);
7343     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
7344     ctx->snes_its = 0;
7345   }
7346   ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr);
7347   y    = its - ctx->snes_its;
7348   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
7349   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
7350     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7351     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7352   }
7353   ctx->snes_its = its;
7354   PetscFunctionReturn(0);
7355 }
7356 
7357 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
7358 {
7359   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
7360   PetscReal      x   = ptime,y;
7361   PetscErrorCode ierr;
7362   PetscInt       its;
7363 
7364   PetscFunctionBegin;
7365   if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */
7366   if (!n) {
7367     PetscDrawAxis axis;
7368     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
7369     ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr);
7370     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
7371     ctx->ksp_its = 0;
7372   }
7373   ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr);
7374   y    = its - ctx->ksp_its;
7375   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
7376   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
7377     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
7378     ierr = PetscDrawLGSave(ctx->lg);CHKERRQ(ierr);
7379   }
7380   ctx->ksp_its = its;
7381   PetscFunctionReturn(0);
7382 }
7383 
7384 /*@
7385    TSComputeLinearStability - computes the linear stability function at a point
7386 
7387    Collective on TS and Vec
7388 
7389    Input Parameters:
7390 +  ts - the TS context
7391 -  xr,xi - real and imaginary part of input arguments
7392 
7393    Output Parameters:
7394 .  yr,yi - real and imaginary part of function value
7395 
7396    Level: developer
7397 
7398 .keywords: TS, compute
7399 
7400 .seealso: TSSetRHSFunction(), TSComputeIFunction()
7401 @*/
7402 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi)
7403 {
7404   PetscErrorCode ierr;
7405 
7406   PetscFunctionBegin;
7407   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
7408   if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method");
7409   ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr);
7410   PetscFunctionReturn(0);
7411 }
7412 
7413 /* ------------------------------------------------------------------------*/
7414 /*@C
7415    TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope()
7416 
7417    Collective on TS
7418 
7419    Input Parameters:
7420 .  ts  - the ODE solver object
7421 
7422    Output Parameter:
7423 .  ctx - the context
7424 
7425    Level: intermediate
7426 
7427 .keywords: TS, monitor, line graph, residual, seealso
7428 
7429 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError()
7430 
7431 @*/
7432 PetscErrorCode  TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx)
7433 {
7434   PetscErrorCode ierr;
7435 
7436   PetscFunctionBegin;
7437   ierr = PetscNew(ctx);CHKERRQ(ierr);
7438   PetscFunctionReturn(0);
7439 }
7440 
7441 /*@C
7442    TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution
7443 
7444    Collective on TS
7445 
7446    Input Parameters:
7447 +  ts - the TS context
7448 .  step - current time-step
7449 .  ptime - current time
7450 .  u  - current solution
7451 -  dctx - the envelope context
7452 
7453    Options Database:
7454 .  -ts_monitor_envelope
7455 
7456    Level: intermediate
7457 
7458    Notes: after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope
7459 
7460 .keywords: TS,  vector, monitor, view
7461 
7462 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate()
7463 @*/
7464 PetscErrorCode  TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
7465 {
7466   PetscErrorCode       ierr;
7467   TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx;
7468 
7469   PetscFunctionBegin;
7470   if (!ctx->max) {
7471     ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr);
7472     ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr);
7473     ierr = VecCopy(u,ctx->max);CHKERRQ(ierr);
7474     ierr = VecCopy(u,ctx->min);CHKERRQ(ierr);
7475   } else {
7476     ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr);
7477     ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr);
7478   }
7479   PetscFunctionReturn(0);
7480 }
7481 
7482 
7483 /*@C
7484    TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution
7485 
7486    Collective on TS
7487 
7488    Input Parameter:
7489 .  ts - the TS context
7490 
7491    Output Parameter:
7492 +  max - the maximum values
7493 -  min - the minimum values
7494 
7495    Notes: If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored
7496 
7497    Level: intermediate
7498 
7499 .keywords: TS,  vector, monitor, view
7500 
7501 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
7502 @*/
7503 PetscErrorCode  TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min)
7504 {
7505   PetscInt i;
7506 
7507   PetscFunctionBegin;
7508   if (max) *max = NULL;
7509   if (min) *min = NULL;
7510   for (i=0; i<ts->numbermonitors; i++) {
7511     if (ts->monitor[i] == TSMonitorEnvelope) {
7512       TSMonitorEnvelopeCtx  ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i];
7513       if (max) *max = ctx->max;
7514       if (min) *min = ctx->min;
7515       break;
7516     }
7517   }
7518   PetscFunctionReturn(0);
7519 }
7520 
7521 /*@C
7522    TSMonitorEnvelopeCtxDestroy - Destroys a context that was created  with TSMonitorEnvelopeCtxCreate().
7523 
7524    Collective on TSMonitorEnvelopeCtx
7525 
7526    Input Parameter:
7527 .  ctx - the monitor context
7528 
7529    Level: intermediate
7530 
7531 .keywords: TS, monitor, line graph, destroy
7532 
7533 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep()
7534 @*/
7535 PetscErrorCode  TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx)
7536 {
7537   PetscErrorCode ierr;
7538 
7539   PetscFunctionBegin;
7540   ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr);
7541   ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr);
7542   ierr = PetscFree(*ctx);CHKERRQ(ierr);
7543   PetscFunctionReturn(0);
7544 }
7545 
7546 /*@
7547    TSRollBack - Rolls back one time step
7548 
7549    Collective on TS
7550 
7551    Input Parameter:
7552 .  ts - the TS context obtained from TSCreate()
7553 
7554    Level: advanced
7555 
7556 .keywords: TS, timestep, rollback
7557 
7558 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate()
7559 @*/
7560 PetscErrorCode  TSRollBack(TS ts)
7561 {
7562   PetscErrorCode ierr;
7563 
7564   PetscFunctionBegin;
7565   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
7566   if (ts->steprollback) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TSRollBack already called");
7567   if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name);
7568   ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr);
7569   ts->time_step = ts->ptime - ts->ptime_prev;
7570   ts->ptime = ts->ptime_prev;
7571   ts->ptime_prev = ts->ptime_prev_rollback;
7572   ts->steps--; ts->total_steps--;
7573   ierr = TSPostEvaluate(ts);CHKERRQ(ierr);
7574   ts->steprollback = PETSC_TRUE;
7575   PetscFunctionReturn(0);
7576 }
7577 
7578 /*@
7579    TSGetStages - Get the number of stages and stage values
7580 
7581    Input Parameter:
7582 .  ts - the TS context obtained from TSCreate()
7583 
7584    Level: advanced
7585 
7586 .keywords: TS, getstages
7587 
7588 .seealso: TSCreate()
7589 @*/
7590 PetscErrorCode  TSGetStages(TS ts,PetscInt *ns,Vec **Y)
7591 {
7592   PetscErrorCode ierr;
7593 
7594   PetscFunctionBegin;
7595   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
7596   PetscValidPointer(ns,2);
7597 
7598   if (!ts->ops->getstages) *ns=0;
7599   else {
7600     ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr);
7601   }
7602   PetscFunctionReturn(0);
7603 }
7604 
7605 /*@C
7606   TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity.
7607 
7608   Collective on SNES
7609 
7610   Input Parameters:
7611 + ts - the TS context
7612 . t - current timestep
7613 . U - state vector
7614 . Udot - time derivative of state vector
7615 . shift - shift to apply, see note below
7616 - ctx - an optional user context
7617 
7618   Output Parameters:
7619 + J - Jacobian matrix (not altered in this routine)
7620 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J)
7621 
7622   Level: intermediate
7623 
7624   Notes:
7625   If F(t,U,Udot)=0 is the DAE, the required Jacobian is
7626 
7627   dF/dU + shift*dF/dUdot
7628 
7629   Most users should not need to explicitly call this routine, as it
7630   is used internally within the nonlinear solvers.
7631 
7632   This will first try to get the coloring from the DM.  If the DM type has no coloring
7633   routine, then it will try to get the coloring from the matrix.  This requires that the
7634   matrix have nonzero entries precomputed.
7635 
7636 .keywords: TS, finite differences, Jacobian, coloring, sparse
7637 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction()
7638 @*/
7639 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx)
7640 {
7641   SNES           snes;
7642   MatFDColoring  color;
7643   PetscBool      hascolor, matcolor = PETSC_FALSE;
7644   PetscErrorCode ierr;
7645 
7646   PetscFunctionBegin;
7647   ierr = PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr);
7648   ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr);
7649   if (!color) {
7650     DM         dm;
7651     ISColoring iscoloring;
7652 
7653     ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
7654     ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr);
7655     if (hascolor && !matcolor) {
7656       ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr);
7657       ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr);
7658       ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr);
7659       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
7660       ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr);
7661       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
7662     } else {
7663       MatColoring mc;
7664 
7665       ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr);
7666       ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr);
7667       ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr);
7668       ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr);
7669       ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr);
7670       ierr = MatColoringDestroy(&mc);CHKERRQ(ierr);
7671       ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr);
7672       ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr);
7673       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
7674       ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr);
7675       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
7676     }
7677     ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr);
7678     ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr);
7679   }
7680   ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr);
7681   ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr);
7682   if (J != B) {
7683     ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
7684     ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
7685   }
7686   PetscFunctionReturn(0);
7687 }
7688 
7689 /*@
7690     TSSetFunctionDomainError - Set the function testing if the current state vector is valid
7691 
7692     Input Parameters:
7693     ts - the TS context
7694     func - function called within TSFunctionDomainError
7695 
7696     Level: intermediate
7697 
7698 .keywords: TS, state, domain
7699 .seealso: TSAdaptCheckStage(), TSFunctionDomainError()
7700 @*/
7701 
7702 PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*))
7703 {
7704   PetscFunctionBegin;
7705   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
7706   ts->functiondomainerror = func;
7707   PetscFunctionReturn(0);
7708 }
7709 
7710 /*@
7711     TSFunctionDomainError - Check if the current state is valid
7712 
7713     Input Parameters:
7714     ts - the TS context
7715     stagetime - time of the simulation
7716     Y - state vector to check.
7717 
7718     Output Parameter:
7719     accept - Set to PETSC_FALSE if the current state vector is valid.
7720 
7721     Note:
7722     This function should be used to ensure the state is in a valid part of the space.
7723     For example, one can ensure here all values are positive.
7724 
7725     Level: advanced
7726 @*/
7727 PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept)
7728 {
7729   PetscErrorCode ierr;
7730 
7731   PetscFunctionBegin;
7732 
7733   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
7734   *accept = PETSC_TRUE;
7735   if (ts->functiondomainerror) {
7736     PetscStackCallStandard((*ts->functiondomainerror),(ts,stagetime,Y,accept));
7737   }
7738   PetscFunctionReturn(0);
7739 }
7740 
7741 /*@C
7742   TSClone - This function clones a time step object.
7743 
7744   Collective on MPI_Comm
7745 
7746   Input Parameter:
7747 . tsin    - The input TS
7748 
7749   Output Parameter:
7750 . tsout   - The output TS (cloned)
7751 
7752   Notes:
7753   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.
7754 
7755   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);
7756 
7757   Level: developer
7758 
7759 .keywords: TS, clone
7760 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType()
7761 @*/
7762 PetscErrorCode  TSClone(TS tsin, TS *tsout)
7763 {
7764   TS             t;
7765   PetscErrorCode ierr;
7766   SNES           snes_start;
7767   DM             dm;
7768   TSType         type;
7769 
7770   PetscFunctionBegin;
7771   PetscValidPointer(tsin,1);
7772   *tsout = NULL;
7773 
7774   ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr);
7775 
7776   /* General TS description */
7777   t->numbermonitors    = 0;
7778   t->setupcalled       = 0;
7779   t->ksp_its           = 0;
7780   t->snes_its          = 0;
7781   t->nwork             = 0;
7782   t->rhsjacobian.time  = -1e20;
7783   t->rhsjacobian.scale = 1.;
7784   t->ijacobian.shift   = 1.;
7785 
7786   ierr = TSGetSNES(tsin,&snes_start);CHKERRQ(ierr);
7787   ierr = TSSetSNES(t,snes_start);CHKERRQ(ierr);
7788 
7789   ierr = TSGetDM(tsin,&dm);CHKERRQ(ierr);
7790   ierr = TSSetDM(t,dm);CHKERRQ(ierr);
7791 
7792   t->adapt = tsin->adapt;
7793   ierr = PetscObjectReference((PetscObject)t->adapt);CHKERRQ(ierr);
7794 
7795   t->trajectory = tsin->trajectory;
7796   ierr = PetscObjectReference((PetscObject)t->trajectory);CHKERRQ(ierr);
7797 
7798   t->event = tsin->event;
7799   if (t->event) t->event->refct++;
7800 
7801   t->problem_type      = tsin->problem_type;
7802   t->ptime             = tsin->ptime;
7803   t->ptime_prev        = tsin->ptime_prev;
7804   t->time_step         = tsin->time_step;
7805   t->max_time          = tsin->max_time;
7806   t->steps             = tsin->steps;
7807   t->total_steps       = tsin->total_steps;
7808   t->max_steps         = tsin->max_steps;
7809   t->equation_type     = tsin->equation_type;
7810   t->atol              = tsin->atol;
7811   t->rtol              = tsin->rtol;
7812   t->max_snes_failures = tsin->max_snes_failures;
7813   t->max_reject        = tsin->max_reject;
7814   t->errorifstepfailed = tsin->errorifstepfailed;
7815 
7816   ierr = TSGetType(tsin,&type);CHKERRQ(ierr);
7817   ierr = TSSetType(t,type);CHKERRQ(ierr);
7818 
7819   t->vec_sol           = NULL;
7820 
7821   t->cfltime          = tsin->cfltime;
7822   t->cfltime_local    = tsin->cfltime_local;
7823   t->exact_final_time = tsin->exact_final_time;
7824 
7825   ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr);
7826 
7827   if (((PetscObject)tsin)->fortran_func_pointers) {
7828     PetscInt i;
7829     ierr = PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers);CHKERRQ(ierr);
7830     for (i=0; i<10; i++) {
7831       ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i];
7832     }
7833   }
7834   *tsout = t;
7835   PetscFunctionReturn(0);
7836 }
7837