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