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