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