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