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