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