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