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