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