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