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