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