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