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