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