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