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