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