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