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