xref: /petsc/src/ts/interface/ts.c (revision 4613cb51df04ebd62033c615073409cdf9f13ab4)
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 #undef __FUNCT__
15 #define __FUNCT__ "TSSetTypeFromOptions"
16 /*
17   TSSetTypeFromOptions - Sets the type of ts from user options.
18 
19   Collective on TS
20 
21   Input Parameter:
22 . ts - The ts
23 
24   Level: intermediate
25 
26 .keywords: TS, set, options, database, type
27 .seealso: TSSetFromOptions(), TSSetType()
28 */
29 static PetscErrorCode TSSetTypeFromOptions(TS ts)
30 {
31   PetscBool      opt;
32   const char     *defaultType;
33   char           typeName[256];
34   PetscErrorCode ierr;
35 
36   PetscFunctionBegin;
37   if (((PetscObject)ts)->type_name) defaultType = ((PetscObject)ts)->type_name;
38   else defaultType = TSEULER;
39 
40   if (!TSRegisterAllCalled) {ierr = TSRegisterAll(NULL);CHKERRQ(ierr);}
41   ierr = PetscOptionsList("-ts_type", "TS method"," TSSetType", TSList, defaultType, typeName, 256, &opt);CHKERRQ(ierr);
42   if (opt) {
43     ierr = TSSetType(ts, typeName);CHKERRQ(ierr);
44   } else {
45     ierr = TSSetType(ts, defaultType);CHKERRQ(ierr);
46   }
47   PetscFunctionReturn(0);
48 }
49 
50 struct _n_TSMonitorDrawCtx {
51   PetscViewer   viewer;
52   PetscDrawAxis axis;
53   Vec           initialsolution;
54   PetscBool     showinitial;
55   PetscInt      howoften;  /* when > 0 uses step % howoften, when negative only final solution plotted */
56   PetscBool     showtimestepandtime;
57   int           color;
58 };
59 
60 #undef __FUNCT__
61 #define __FUNCT__ "TSSetFromOptions"
62 /*@
63    TSSetFromOptions - Sets various TS parameters from user options.
64 
65    Collective on TS
66 
67    Input Parameter:
68 .  ts - the TS context obtained from TSCreate()
69 
70    Options Database Keys:
71 +  -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSGL, TSSSP
72 .  -ts_max_steps maxsteps - maximum number of time-steps to take
73 .  -ts_final_time time - maximum time to compute to
74 .  -ts_dt dt - initial time step
75 .  -ts_monitor - print information at each timestep
76 .  -ts_monitor_lg_timestep - Monitor timestep size graphically
77 .  -ts_monitor_lg_solution - Monitor solution graphically
78 .  -ts_monitor_lg_error - Monitor error graphically
79 .  -ts_monitor_lg_snes_iterations - Monitor number nonlinear iterations for each timestep graphically
80 .  -ts_monitor_lg_ksp_iterations - Monitor number nonlinear iterations for each timestep graphically
81 .  -ts_monitor_sp_eig - Monitor eigenvalues of linearized operator graphically
82 .  -ts_monitor_draw_solution - Monitor solution graphically
83 .  -ts_monitor_draw_solution_phase - Monitor solution graphically with phase diagram
84 .  -ts_monitor_draw_error - Monitor error graphically
85 .  -ts_monitor_solution_binary <filename> - Save each solution to a binary file
86 -  -ts_monitor_solution_vtk <filename.vts> - Save each time step to a binary file, use filename-%%03D.vts
87 
88    Developer Note: We should unify all the -ts_monitor options in the way that -xxx_view has been unified
89 
90    Level: beginner
91 
92 .keywords: TS, timestep, set, options, database
93 
94 .seealso: TSGetType()
95 @*/
96 PetscErrorCode  TSSetFromOptions(TS ts)
97 {
98   PetscBool              opt,flg;
99   PetscErrorCode         ierr;
100   PetscViewer            monviewer;
101   char                   monfilename[PETSC_MAX_PATH_LEN];
102   SNES                   snes;
103   TSAdapt                adapt;
104   PetscReal              time_step;
105   TSExactFinalTimeOption eftopt;
106   char                   dir[16];
107 
108   PetscFunctionBegin;
109   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
110   ierr = PetscObjectOptionsBegin((PetscObject)ts);CHKERRQ(ierr);
111   /* Handle TS type options */
112   ierr = TSSetTypeFromOptions(ts);CHKERRQ(ierr);
113 
114   /* Handle generic TS options */
115   ierr = PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetDuration",ts->max_steps,&ts->max_steps,NULL);CHKERRQ(ierr);
116   ierr = PetscOptionsReal("-ts_final_time","Time to run to","TSSetDuration",ts->max_time,&ts->max_time,NULL);CHKERRQ(ierr);
117   ierr = PetscOptionsReal("-ts_init_time","Initial time","TSSetTime",ts->ptime,&ts->ptime,NULL);CHKERRQ(ierr);
118   ierr = PetscOptionsReal("-ts_dt","Initial time step","TSSetTimeStep",ts->time_step,&time_step,&flg);CHKERRQ(ierr);
119   if (flg) {
120     ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr);
121   }
122   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);
123   if (flg) {ierr = TSSetExactFinalTime(ts,eftopt);CHKERRQ(ierr);}
124   ierr = PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","TSSetMaxSNESFailures",ts->max_snes_failures,&ts->max_snes_failures,NULL);CHKERRQ(ierr);
125   ierr = PetscOptionsInt("-ts_max_reject","Maximum number of step rejections before step fails","TSSetMaxStepRejections",ts->max_reject,&ts->max_reject,NULL);CHKERRQ(ierr);
126   ierr = PetscOptionsBool("-ts_error_if_step_fails","Error if no step succeeds","TSSetErrorIfStepFails",ts->errorifstepfailed,&ts->errorifstepfailed,NULL);CHKERRQ(ierr);
127   ierr = PetscOptionsReal("-ts_rtol","Relative tolerance for local truncation error","TSSetTolerances",ts->rtol,&ts->rtol,NULL);CHKERRQ(ierr);
128   ierr = PetscOptionsReal("-ts_atol","Absolute tolerance for local truncation error","TSSetTolerances",ts->atol,&ts->atol,NULL);CHKERRQ(ierr);
129 
130   /* Monitor options */
131   ierr = PetscOptionsString("-ts_monitor","Monitor timestep size","TSMonitorDefault","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
132   if (flg) {
133     ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ts),monfilename,&monviewer);CHKERRQ(ierr);
134     ierr = TSMonitorSet(ts,TSMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
135   }
136   ierr = PetscOptionsString("-ts_monitor_python","Use Python function","TSMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
137   if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ts,monfilename);CHKERRQ(ierr);}
138 
139   ierr = PetscOptionsName("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",&opt);CHKERRQ(ierr);
140   if (opt) {
141     TSMonitorLGCtx ctx;
142     PetscInt       howoften = 1;
143 
144     ierr = PetscOptionsInt("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",howoften,&howoften,NULL);CHKERRQ(ierr);
145     ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr);
146     ierr = TSMonitorSet(ts,TSMonitorLGTimeStep,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
147   }
148   ierr = PetscOptionsName("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",&opt);CHKERRQ(ierr);
149   if (opt) {
150     TSMonitorLGCtx ctx;
151     PetscInt       howoften = 1;
152 
153     ierr = PetscOptionsInt("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",howoften,&howoften,NULL);CHKERRQ(ierr);
154     ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr);
155     ierr = TSMonitorSet(ts,TSMonitorLGSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
156   }
157   ierr = PetscOptionsName("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",&opt);CHKERRQ(ierr);
158   if (opt) {
159     TSMonitorLGCtx ctx;
160     PetscInt       howoften = 1;
161 
162     ierr = PetscOptionsInt("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",howoften,&howoften,NULL);CHKERRQ(ierr);
163     ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr);
164     ierr = TSMonitorSet(ts,TSMonitorLGError,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
165   }
166   ierr = PetscOptionsName("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",&opt);CHKERRQ(ierr);
167   if (opt) {
168     TSMonitorLGCtx ctx;
169     PetscInt       howoften = 1;
170 
171     ierr = PetscOptionsInt("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",howoften,&howoften,NULL);CHKERRQ(ierr);
172     ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr);
173     ierr = TSMonitorSet(ts,TSMonitorLGSNESIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
174   }
175   ierr = PetscOptionsName("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",&opt);CHKERRQ(ierr);
176   if (opt) {
177     TSMonitorLGCtx ctx;
178     PetscInt       howoften = 1;
179 
180     ierr = PetscOptionsInt("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",howoften,&howoften,NULL);CHKERRQ(ierr);
181     ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr);
182     ierr = TSMonitorSet(ts,TSMonitorLGKSPIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
183   }
184   ierr = PetscOptionsName("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",&opt);CHKERRQ(ierr);
185   if (opt) {
186     TSMonitorSPEigCtx ctx;
187     PetscInt          howoften = 1;
188 
189     ierr = PetscOptionsInt("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",howoften,&howoften,NULL);CHKERRQ(ierr);
190     ierr = TSMonitorSPEigCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr);
191     ierr = TSMonitorSet(ts,TSMonitorSPEig,ctx,(PetscErrorCode (*)(void**))TSMonitorSPEigCtxDestroy);CHKERRQ(ierr);
192   }
193   opt  = PETSC_FALSE;
194   ierr = PetscOptionsName("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",&opt);CHKERRQ(ierr);
195   if (opt) {
196     TSMonitorDrawCtx ctx;
197     PetscInt         howoften = 1;
198 
199     ierr = PetscOptionsInt("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",howoften,&howoften,NULL);CHKERRQ(ierr);
200     ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr);
201     ierr = TSMonitorSet(ts,TSMonitorDrawSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr);
202   }
203   opt  = PETSC_FALSE;
204   ierr = PetscOptionsName("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",&opt);CHKERRQ(ierr);
205   if (opt) {
206     TSMonitorDrawCtx ctx;
207     PetscReal        bounds[4];
208     PetscInt         n = 4;
209     PetscDraw        draw;
210 
211     ierr = PetscOptionsRealArray("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",bounds,&n,NULL);CHKERRQ(ierr);
212     if (n != 4) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Must provide bounding box of phase field");
213     ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,1,&ctx);CHKERRQ(ierr);
214     ierr = PetscViewerDrawGetDraw(ctx->viewer,0,&draw);CHKERRQ(ierr);
215     ierr = PetscDrawClear(draw);CHKERRQ(ierr);
216     ierr = PetscDrawAxisCreate(draw,&ctx->axis);CHKERRQ(ierr);
217     ierr = PetscDrawAxisSetLimits(ctx->axis,bounds[0],bounds[2],bounds[1],bounds[3]);CHKERRQ(ierr);
218     ierr = PetscDrawAxisDraw(ctx->axis);CHKERRQ(ierr);
219     //    ierr = PetscDrawSetCoordinates(draw,bounds[0],bounds[1],bounds[2],bounds[3]);CHKERRQ(ierr);
220     ierr = TSMonitorSet(ts,TSMonitorDrawSolutionPhase,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr);
221   }
222   opt  = PETSC_FALSE;
223   ierr = PetscOptionsName("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",&opt);CHKERRQ(ierr);
224   if (opt) {
225     TSMonitorDrawCtx ctx;
226     PetscInt         howoften = 1;
227 
228     ierr = PetscOptionsInt("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",howoften,&howoften,NULL);CHKERRQ(ierr);
229     ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr);
230     ierr = TSMonitorSet(ts,TSMonitorDrawError,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr);
231   }
232   opt  = PETSC_FALSE;
233   ierr = PetscOptionsString("-ts_monitor_solution_binary","Save each solution to a binary file","TSMonitorSolutionBinary",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
234   if (flg) {
235     PetscViewer ctx;
236     if (monfilename[0]) {
237       ierr = PetscViewerBinaryOpen(PetscObjectComm((PetscObject)ts),monfilename,FILE_MODE_WRITE,&ctx);CHKERRQ(ierr);
238       ierr = TSMonitorSet(ts,TSMonitorSolutionBinary,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
239     } else {
240       ctx = PETSC_VIEWER_BINARY_(PetscObjectComm((PetscObject)ts));
241       ierr = TSMonitorSet(ts,TSMonitorSolutionBinary,ctx,(PetscErrorCode (*)(void**))NULL);CHKERRQ(ierr);
242     }
243   }
244   opt  = PETSC_FALSE;
245   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);
246   if (flg) {
247     const char *ptr,*ptr2;
248     char       *filetemplate;
249     if (!monfilename[0]) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts");
250     /* Do some cursory validation of the input. */
251     ierr = PetscStrstr(monfilename,"%",(char**)&ptr);CHKERRQ(ierr);
252     if (!ptr) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts");
253     for (ptr++; ptr && *ptr; ptr++) {
254       ierr = PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);CHKERRQ(ierr);
255       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");
256       if (ptr2) break;
257     }
258     ierr = PetscStrallocpy(monfilename,&filetemplate);CHKERRQ(ierr);
259     ierr = TSMonitorSet(ts,TSMonitorSolutionVTK,filetemplate,(PetscErrorCode (*)(void**))TSMonitorSolutionVTKDestroy);CHKERRQ(ierr);
260   }
261 
262   ierr = PetscOptionsString("-ts_monitor_dmda_ray","Display a ray of the solution","None","y=0",dir,16,&flg);CHKERRQ(ierr);
263   if (flg) {
264     TSMonitorDMDARayCtx *rayctx;
265     int                 ray = 0;
266     DMDADirection       ddir;
267     DM                  da;
268     PetscMPIInt         rank;
269 
270     if (dir[1] != '=') SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir);
271     if (dir[0] == 'x') ddir = DMDA_X;
272     else if (dir[0] == 'y') ddir = DMDA_Y;
273     else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir);
274     sscanf(dir+2,"%d",&ray);
275 
276     ierr = PetscInfo2(((PetscObject)ts),"Displaying DMDA ray %c = %D\n",dir[0],ray);CHKERRQ(ierr);
277     ierr = PetscNew(TSMonitorDMDARayCtx,&rayctx);CHKERRQ(ierr);
278     ierr = TSGetDM(ts,&da);CHKERRQ(ierr);
279     ierr = DMDAGetRay(da,ddir,ray,&rayctx->ray,&rayctx->scatter);CHKERRQ(ierr);
280     ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)ts),&rank);CHKERRQ(ierr);
281     if (!rank) {
282       ierr = PetscViewerDrawOpen(PETSC_COMM_SELF,0,0,0,0,600,300,&rayctx->viewer);CHKERRQ(ierr);
283     }
284     ierr = TSMonitorSet(ts,TSMonitorDMDARay,rayctx,TSMonitorDMDARayDestroy);CHKERRQ(ierr);
285   }
286 
287   ierr = TSGetTSAdapt(ts,&adapt);CHKERRQ(ierr);
288   ierr = TSAdaptSetFromOptions(adapt);CHKERRQ(ierr);
289 
290   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
291   if (ts->problem_type == TS_LINEAR) {ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);}
292 
293   /* Handle specific TS options */
294   if (ts->ops->setfromoptions) {
295     ierr = (*ts->ops->setfromoptions)(ts);CHKERRQ(ierr);
296   }
297 
298   /* process any options handlers added with PetscObjectAddOptionsHandler() */
299   ierr = PetscObjectProcessOptionsHandlers((PetscObject)ts);CHKERRQ(ierr);
300   ierr = PetscOptionsEnd();CHKERRQ(ierr);
301   PetscFunctionReturn(0);
302 }
303 
304 #undef __FUNCT__
305 #undef __FUNCT__
306 #define __FUNCT__ "TSComputeRHSJacobian"
307 /*@
308    TSComputeRHSJacobian - Computes the Jacobian matrix that has been
309       set with TSSetRHSJacobian().
310 
311    Collective on TS and Vec
312 
313    Input Parameters:
314 +  ts - the TS context
315 .  t - current timestep
316 -  U - input vector
317 
318    Output Parameters:
319 +  A - Jacobian matrix
320 .  B - optional preconditioning matrix
321 -  flag - flag indicating matrix structure
322 
323    Notes:
324    Most users should not need to explicitly call this routine, as it
325    is used internally within the nonlinear solvers.
326 
327    See KSPSetOperators() for important information about setting the
328    flag parameter.
329 
330    Level: developer
331 
332 .keywords: SNES, compute, Jacobian, matrix
333 
334 .seealso:  TSSetRHSJacobian(), KSPSetOperators()
335 @*/
336 PetscErrorCode  TSComputeRHSJacobian(TS ts,PetscReal t,Vec U,Mat *A,Mat *B,MatStructure *flg)
337 {
338   PetscErrorCode ierr;
339   PetscInt       Ustate;
340   DM             dm;
341   DMTS           tsdm;
342   TSRHSJacobian  rhsjacobianfunc;
343   void           *ctx;
344   TSIJacobian    ijacobianfunc;
345 
346   PetscFunctionBegin;
347   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
348   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
349   PetscCheckSameComm(ts,1,U,3);
350   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
351   ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr);
352   ierr = DMTSGetRHSJacobian(dm,&rhsjacobianfunc,&ctx);CHKERRQ(ierr);
353   ierr = DMTSGetIJacobian(dm,&ijacobianfunc,NULL);CHKERRQ(ierr);
354   ierr = PetscObjectStateQuery((PetscObject)U,&Ustate);CHKERRQ(ierr);
355   if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.X == U && ts->rhsjacobian.Xstate == Ustate))) {
356     *flg = ts->rhsjacobian.mstructure;
357     PetscFunctionReturn(0);
358   }
359 
360   if (!rhsjacobianfunc && !ijacobianfunc) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()");
361 
362   if (rhsjacobianfunc) {
363     ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr);
364     *flg = DIFFERENT_NONZERO_PATTERN;
365     PetscStackPush("TS user Jacobian function");
366     ierr = (*rhsjacobianfunc)(ts,t,U,A,B,flg,ctx);CHKERRQ(ierr);
367     PetscStackPop;
368     ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr);
369     /* make sure user returned a correct Jacobian and preconditioner */
370     PetscValidHeaderSpecific(*A,MAT_CLASSID,4);
371     PetscValidHeaderSpecific(*B,MAT_CLASSID,5);
372   } else {
373     ierr = MatZeroEntries(*A);CHKERRQ(ierr);
374     if (*A != *B) {ierr = MatZeroEntries(*B);CHKERRQ(ierr);}
375     *flg = SAME_NONZERO_PATTERN;
376   }
377   ts->rhsjacobian.time       = t;
378   ts->rhsjacobian.X          = U;
379   ierr                       = PetscObjectStateQuery((PetscObject)U,&ts->rhsjacobian.Xstate);CHKERRQ(ierr);
380   ts->rhsjacobian.mstructure = *flg;
381   PetscFunctionReturn(0);
382 }
383 
384 #undef __FUNCT__
385 #define __FUNCT__ "TSComputeRHSFunction"
386 /*@
387    TSComputeRHSFunction - Evaluates the right-hand-side function.
388 
389    Collective on TS and Vec
390 
391    Input Parameters:
392 +  ts - the TS context
393 .  t - current time
394 -  U - state vector
395 
396    Output Parameter:
397 .  y - right hand side
398 
399    Note:
400    Most users should not need to explicitly call this routine, as it
401    is used internally within the nonlinear solvers.
402 
403    Level: developer
404 
405 .keywords: TS, compute
406 
407 .seealso: TSSetRHSFunction(), TSComputeIFunction()
408 @*/
409 PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec U,Vec y)
410 {
411   PetscErrorCode ierr;
412   TSRHSFunction  rhsfunction;
413   TSIFunction    ifunction;
414   void           *ctx;
415   DM             dm;
416 
417   PetscFunctionBegin;
418   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
419   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
420   PetscValidHeaderSpecific(y,VEC_CLASSID,4);
421   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
422   ierr = DMTSGetRHSFunction(dm,&rhsfunction,&ctx);CHKERRQ(ierr);
423   ierr = DMTSGetIFunction(dm,&ifunction,NULL);CHKERRQ(ierr);
424 
425   if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()");
426 
427   ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr);
428   if (rhsfunction) {
429     PetscStackPush("TS user right-hand-side function");
430     ierr = (*rhsfunction)(ts,t,U,y,ctx);CHKERRQ(ierr);
431     PetscStackPop;
432   } else {
433     ierr = VecZeroEntries(y);CHKERRQ(ierr);
434   }
435 
436   ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr);
437   PetscFunctionReturn(0);
438 }
439 
440 #undef __FUNCT__
441 #define __FUNCT__ "TSComputeSolutionFunction"
442 /*@
443    TSComputeSolutionFunction - Evaluates the solution function.
444 
445    Collective on TS and Vec
446 
447    Input Parameters:
448 +  ts - the TS context
449 -  t - current time
450 
451    Output Parameter:
452 .  U - the solution
453 
454    Note:
455    Most users should not need to explicitly call this routine, as it
456    is used internally within the nonlinear solvers.
457 
458    Level: developer
459 
460 .keywords: TS, compute
461 
462 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction()
463 @*/
464 PetscErrorCode TSComputeSolutionFunction(TS ts,PetscReal t,Vec U)
465 {
466   PetscErrorCode     ierr;
467   TSSolutionFunction solutionfunction;
468   void               *ctx;
469   DM                 dm;
470 
471   PetscFunctionBegin;
472   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
473   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
474   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
475   ierr = DMTSGetSolutionFunction(dm,&solutionfunction,&ctx);CHKERRQ(ierr);
476 
477   if (solutionfunction) {
478     PetscStackPush("TS user solution function");
479     ierr = (*solutionfunction)(ts,t,U,ctx);CHKERRQ(ierr);
480     PetscStackPop;
481   }
482   PetscFunctionReturn(0);
483 }
484 #undef __FUNCT__
485 #define __FUNCT__ "TSComputeForcingFunction"
486 /*@
487    TSComputeForcingFunction - Evaluates the forcing function.
488 
489    Collective on TS and Vec
490 
491    Input Parameters:
492 +  ts - the TS context
493 -  t - current time
494 
495    Output Parameter:
496 .  U - the function value
497 
498    Note:
499    Most users should not need to explicitly call this routine, as it
500    is used internally within the nonlinear solvers.
501 
502    Level: developer
503 
504 .keywords: TS, compute
505 
506 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction()
507 @*/
508 PetscErrorCode TSComputeForcingFunction(TS ts,PetscReal t,Vec U)
509 {
510   PetscErrorCode     ierr, (*forcing)(TS,PetscReal,Vec,void*);
511   void               *ctx;
512   DM                 dm;
513 
514   PetscFunctionBegin;
515   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
516   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
517   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
518   ierr = DMTSGetForcingFunction(dm,&forcing,&ctx);CHKERRQ(ierr);
519 
520   if (forcing) {
521     PetscStackPush("TS user forcing function");
522     ierr = (*forcing)(ts,t,U,ctx);CHKERRQ(ierr);
523     PetscStackPop;
524   }
525   PetscFunctionReturn(0);
526 }
527 
528 #undef __FUNCT__
529 #define __FUNCT__ "TSGetRHSVec_Private"
530 static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs)
531 {
532   Vec            F;
533   PetscErrorCode ierr;
534 
535   PetscFunctionBegin;
536   *Frhs = NULL;
537   ierr  = TSGetIFunction(ts,&F,NULL,NULL);CHKERRQ(ierr);
538   if (!ts->Frhs) {
539     ierr = VecDuplicate(F,&ts->Frhs);CHKERRQ(ierr);
540   }
541   *Frhs = ts->Frhs;
542   PetscFunctionReturn(0);
543 }
544 
545 #undef __FUNCT__
546 #define __FUNCT__ "TSGetRHSMats_Private"
547 static PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs)
548 {
549   Mat            A,B;
550   PetscErrorCode ierr;
551 
552   PetscFunctionBegin;
553   ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr);
554   if (Arhs) {
555     if (!ts->Arhs) {
556       ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs);CHKERRQ(ierr);
557     }
558     *Arhs = ts->Arhs;
559   }
560   if (Brhs) {
561     if (!ts->Brhs) {
562       ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs);CHKERRQ(ierr);
563     }
564     *Brhs = ts->Brhs;
565   }
566   PetscFunctionReturn(0);
567 }
568 
569 #undef __FUNCT__
570 #define __FUNCT__ "TSComputeIFunction"
571 /*@
572    TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,U,Udot)=0
573 
574    Collective on TS and Vec
575 
576    Input Parameters:
577 +  ts - the TS context
578 .  t - current time
579 .  U - state vector
580 .  Udot - time derivative of state vector
581 -  imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate
582 
583    Output Parameter:
584 .  Y - right hand side
585 
586    Note:
587    Most users should not need to explicitly call this routine, as it
588    is used internally within the nonlinear solvers.
589 
590    If the user did did not write their equations in implicit form, this
591    function recasts them in implicit form.
592 
593    Level: developer
594 
595 .keywords: TS, compute
596 
597 .seealso: TSSetIFunction(), TSComputeRHSFunction()
598 @*/
599 PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec U,Vec Udot,Vec Y,PetscBool imex)
600 {
601   PetscErrorCode ierr;
602   TSIFunction    ifunction;
603   TSRHSFunction  rhsfunction;
604   void           *ctx;
605   DM             dm;
606 
607   PetscFunctionBegin;
608   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
609   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
610   PetscValidHeaderSpecific(Udot,VEC_CLASSID,4);
611   PetscValidHeaderSpecific(Y,VEC_CLASSID,5);
612 
613   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
614   ierr = DMTSGetIFunction(dm,&ifunction,&ctx);CHKERRQ(ierr);
615   ierr = DMTSGetRHSFunction(dm,&rhsfunction,NULL);CHKERRQ(ierr);
616 
617   if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()");
618 
619   ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr);
620   if (ifunction) {
621     PetscStackPush("TS user implicit function");
622     ierr = (*ifunction)(ts,t,U,Udot,Y,ctx);CHKERRQ(ierr);
623     PetscStackPop;
624   }
625   if (imex) {
626     if (!ifunction) {
627       ierr = VecCopy(Udot,Y);CHKERRQ(ierr);
628     }
629   } else if (rhsfunction) {
630     if (ifunction) {
631       Vec Frhs;
632       ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr);
633       ierr = TSComputeRHSFunction(ts,t,U,Frhs);CHKERRQ(ierr);
634       ierr = VecAXPY(Y,-1,Frhs);CHKERRQ(ierr);
635     } else {
636       ierr = TSComputeRHSFunction(ts,t,U,Y);CHKERRQ(ierr);
637       ierr = VecAYPX(Y,-1,Udot);CHKERRQ(ierr);
638     }
639   }
640   ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr);
641   PetscFunctionReturn(0);
642 }
643 
644 #undef __FUNCT__
645 #define __FUNCT__ "TSComputeIJacobian"
646 /*@
647    TSComputeIJacobian - Evaluates the Jacobian of the DAE
648 
649    Collective on TS and Vec
650 
651    Input
652       Input Parameters:
653 +  ts - the TS context
654 .  t - current timestep
655 .  U - state vector
656 .  Udot - time derivative of state vector
657 .  shift - shift to apply, see note below
658 -  imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate
659 
660    Output Parameters:
661 +  A - Jacobian matrix
662 .  B - optional preconditioning matrix
663 -  flag - flag indicating matrix structure
664 
665    Notes:
666    If F(t,U,Udot)=0 is the DAE, the required Jacobian is
667 
668    dF/dU + shift*dF/dUdot
669 
670    Most users should not need to explicitly call this routine, as it
671    is used internally within the nonlinear solvers.
672 
673    Level: developer
674 
675 .keywords: TS, compute, Jacobian, matrix
676 
677 .seealso:  TSSetIJacobian()
678 @*/
679 PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,PetscBool imex)
680 {
681   PetscInt       Ustate, Udotstate;
682   PetscErrorCode ierr;
683   TSIJacobian    ijacobian;
684   TSRHSJacobian  rhsjacobian;
685   DM             dm;
686   void           *ctx;
687 
688   PetscFunctionBegin;
689   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
690   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
691   PetscValidHeaderSpecific(Udot,VEC_CLASSID,4);
692   PetscValidPointer(A,6);
693   PetscValidHeaderSpecific(*A,MAT_CLASSID,6);
694   PetscValidPointer(B,7);
695   PetscValidHeaderSpecific(*B,MAT_CLASSID,7);
696   PetscValidPointer(flg,8);
697 
698   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
699   ierr = DMTSGetIJacobian(dm,&ijacobian,&ctx);CHKERRQ(ierr);
700   ierr = DMTSGetRHSJacobian(dm,&rhsjacobian,NULL);CHKERRQ(ierr);
701 
702   ierr = PetscObjectStateQuery((PetscObject)U,&Ustate);CHKERRQ(ierr);
703   ierr = PetscObjectStateQuery((PetscObject)Udot,&Udotstate);CHKERRQ(ierr);
704   if (ts->ijacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->ijacobian.X == U && ts->ijacobian.Xstate == Ustate && ts->ijacobian.Xdot == Udot && ts->ijacobian.Xdotstate == Udotstate && ts->ijacobian.imex == imex))) {
705     *flg = ts->ijacobian.mstructure;
706     ierr = MatScale(*A, shift / ts->ijacobian.shift);CHKERRQ(ierr);
707     PetscFunctionReturn(0);
708   }
709 
710   if (!rhsjacobian && !ijacobian) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()");
711 
712   *flg = SAME_NONZERO_PATTERN;  /* In case we're solving a linear problem in which case it wouldn't get initialized below. */
713   ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr);
714   if (ijacobian) {
715     *flg = DIFFERENT_NONZERO_PATTERN;
716     PetscStackPush("TS user implicit Jacobian");
717     ierr = (*ijacobian)(ts,t,U,Udot,shift,A,B,flg,ctx);CHKERRQ(ierr);
718     PetscStackPop;
719     /* make sure user returned a correct Jacobian and preconditioner */
720     PetscValidHeaderSpecific(*A,MAT_CLASSID,4);
721     PetscValidHeaderSpecific(*B,MAT_CLASSID,5);
722   }
723   if (imex) {
724     if (!ijacobian) {  /* system was written as Udot = G(t,U) */
725       ierr = MatZeroEntries(*A);CHKERRQ(ierr);
726       ierr = MatShift(*A,shift);CHKERRQ(ierr);
727       if (*A != *B) {
728         ierr = MatZeroEntries(*B);CHKERRQ(ierr);
729         ierr = MatShift(*B,shift);CHKERRQ(ierr);
730       }
731       *flg = SAME_PRECONDITIONER;
732     }
733   } else {
734     if (!ijacobian) {
735       ierr = TSComputeRHSJacobian(ts,t,U,A,B,flg);CHKERRQ(ierr);
736       ierr = MatScale(*A,-1);CHKERRQ(ierr);
737       ierr = MatShift(*A,shift);CHKERRQ(ierr);
738       if (*A != *B) {
739         ierr = MatScale(*B,-1);CHKERRQ(ierr);
740         ierr = MatShift(*B,shift);CHKERRQ(ierr);
741       }
742     } else if (rhsjacobian) {
743       Mat          Arhs,Brhs;
744       MatStructure axpy,flg2 = DIFFERENT_NONZERO_PATTERN;
745       ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
746       ierr = TSComputeRHSJacobian(ts,t,U,&Arhs,&Brhs,&flg2);CHKERRQ(ierr);
747       axpy = (*flg == flg2) ? SAME_NONZERO_PATTERN : DIFFERENT_NONZERO_PATTERN;
748       ierr = MatAXPY(*A,-1,Arhs,axpy);CHKERRQ(ierr);
749       if (*A != *B) {
750         ierr = MatAXPY(*B,-1,Brhs,axpy);CHKERRQ(ierr);
751       }
752       *flg = PetscMin(*flg,flg2);
753     }
754   }
755 
756   ts->ijacobian.time = t;
757   ts->ijacobian.X    = U;
758   ts->ijacobian.Xdot = Udot;
759 
760   ierr = PetscObjectStateQuery((PetscObject)U,&ts->ijacobian.Xstate);CHKERRQ(ierr);
761   ierr = PetscObjectStateQuery((PetscObject)Udot,&ts->ijacobian.Xdotstate);CHKERRQ(ierr);
762 
763   ts->ijacobian.shift      = shift;
764   ts->ijacobian.imex       = imex;
765   ts->ijacobian.mstructure = *flg;
766 
767   ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,*A,*B);CHKERRQ(ierr);
768   PetscFunctionReturn(0);
769 }
770 
771 #undef __FUNCT__
772 #define __FUNCT__ "TSSetRHSFunction"
773 /*@C
774     TSSetRHSFunction - Sets the routine for evaluating the function,
775     where U_t = G(t,u).
776 
777     Logically Collective on TS
778 
779     Input Parameters:
780 +   ts - the TS context obtained from TSCreate()
781 .   r - vector to put the computed right hand side (or NULL to have it created)
782 .   f - routine for evaluating the right-hand-side function
783 -   ctx - [optional] user-defined context for private data for the
784           function evaluation routine (may be NULL)
785 
786     Calling sequence of func:
787 $     func (TS ts,PetscReal t,Vec u,Vec F,void *ctx);
788 
789 +   t - current timestep
790 .   u - input vector
791 .   F - function vector
792 -   ctx - [optional] user-defined function context
793 
794     Level: beginner
795 
796 .keywords: TS, timestep, set, right-hand-side, function
797 
798 .seealso: TSSetRHSJacobian(), TSSetIJacobian()
799 @*/
800 PetscErrorCode  TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx)
801 {
802   PetscErrorCode ierr;
803   SNES           snes;
804   Vec            ralloc = NULL;
805   DM             dm;
806 
807   PetscFunctionBegin;
808   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
809   if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2);
810 
811   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
812   ierr = DMTSSetRHSFunction(dm,f,ctx);CHKERRQ(ierr);
813   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
814   if (!r && !ts->dm && ts->vec_sol) {
815     ierr = VecDuplicate(ts->vec_sol,&ralloc);CHKERRQ(ierr);
816     r    = ralloc;
817   }
818   ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr);
819   ierr = VecDestroy(&ralloc);CHKERRQ(ierr);
820   PetscFunctionReturn(0);
821 }
822 
823 #undef __FUNCT__
824 #define __FUNCT__ "TSSetSolutionFunction"
825 /*@C
826     TSSetSolutionFunction - Provide a function that computes the solution of the ODE or DAE
827 
828     Logically Collective on TS
829 
830     Input Parameters:
831 +   ts - the TS context obtained from TSCreate()
832 .   f - routine for evaluating the solution
833 -   ctx - [optional] user-defined context for private data for the
834           function evaluation routine (may be NULL)
835 
836     Calling sequence of func:
837 $     func (TS ts,PetscReal t,Vec u,void *ctx);
838 
839 +   t - current timestep
840 .   u - output vector
841 -   ctx - [optional] user-defined function context
842 
843     Notes:
844     This routine is used for testing accuracy of time integration schemes when you already know the solution.
845     If analytic solutions are not known for your system, consider using the Method of Manufactured Solutions to
846     create closed-form solutions with non-physical forcing terms.
847 
848     For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history.
849 
850     Level: beginner
851 
852 .keywords: TS, timestep, set, right-hand-side, function
853 
854 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetForcingFunction()
855 @*/
856 PetscErrorCode  TSSetSolutionFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx)
857 {
858   PetscErrorCode ierr;
859   DM             dm;
860 
861   PetscFunctionBegin;
862   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
863   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
864   ierr = DMTSSetSolutionFunction(dm,f,ctx);CHKERRQ(ierr);
865   PetscFunctionReturn(0);
866 }
867 
868 #undef __FUNCT__
869 #define __FUNCT__ "TSSetForcingFunction"
870 /*@C
871     TSSetForcingFunction - Provide a function that computes a forcing term for a ODE or PDE
872 
873     Logically Collective on TS
874 
875     Input Parameters:
876 +   ts - the TS context obtained from TSCreate()
877 .   f - routine for evaluating the forcing function
878 -   ctx - [optional] user-defined context for private data for the
879           function evaluation routine (may be NULL)
880 
881     Calling sequence of func:
882 $     func (TS ts,PetscReal t,Vec u,void *ctx);
883 
884 +   t - current timestep
885 .   u - output vector
886 -   ctx - [optional] user-defined function context
887 
888     Notes:
889     This routine is useful for testing accuracy of time integration schemes when using the Method of Manufactured Solutions to
890     create closed-form solutions with a non-physical forcing term.
891 
892     For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history.
893 
894     Level: beginner
895 
896 .keywords: TS, timestep, set, right-hand-side, function
897 
898 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetSolutionFunction()
899 @*/
900 PetscErrorCode  TSSetForcingFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx)
901 {
902   PetscErrorCode ierr;
903   DM             dm;
904 
905   PetscFunctionBegin;
906   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
907   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
908   ierr = DMTSSetForcingFunction(dm,f,ctx);CHKERRQ(ierr);
909   PetscFunctionReturn(0);
910 }
911 
912 #undef __FUNCT__
913 #define __FUNCT__ "TSSetRHSJacobian"
914 /*@C
915    TSSetRHSJacobian - Sets the function to compute the Jacobian of F,
916    where U_t = G(U,t), as well as the location to store the matrix.
917 
918    Logically Collective on TS
919 
920    Input Parameters:
921 +  ts  - the TS context obtained from TSCreate()
922 .  A   - Jacobian matrix
923 .  B   - preconditioner matrix (usually same as A)
924 .  f   - the Jacobian evaluation routine
925 -  ctx - [optional] user-defined context for private data for the
926          Jacobian evaluation routine (may be NULL)
927 
928    Calling sequence of func:
929 $     func (TS ts,PetscReal t,Vec u,Mat *A,Mat *B,MatStructure *flag,void *ctx);
930 
931 +  t - current timestep
932 .  u - input vector
933 .  A - matrix A, where U_t = A(t)u
934 .  B - preconditioner matrix, usually the same as A
935 .  flag - flag indicating information about the preconditioner matrix
936           structure (same as flag in KSPSetOperators())
937 -  ctx - [optional] user-defined context for matrix evaluation routine
938 
939    Notes:
940    See KSPSetOperators() for important information about setting the flag
941    output parameter in the routine func().  Be sure to read this information!
942 
943    The routine func() takes Mat * as the matrix arguments rather than Mat.
944    This allows the matrix evaluation routine to replace A and/or B with a
945    completely new matrix structure (not just different matrix elements)
946    when appropriate, for instance, if the nonzero structure is changing
947    throughout the global iterations.
948 
949    Level: beginner
950 
951 .keywords: TS, timestep, set, right-hand-side, Jacobian
952 
953 .seealso: SNESDefaultComputeJacobianColor(), TSSetRHSFunction()
954 
955 @*/
956 PetscErrorCode  TSSetRHSJacobian(TS ts,Mat A,Mat B,TSRHSJacobian f,void *ctx)
957 {
958   PetscErrorCode ierr;
959   SNES           snes;
960   DM             dm;
961   TSIJacobian    ijacobian;
962 
963   PetscFunctionBegin;
964   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
965   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
966   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
967   if (A) PetscCheckSameComm(ts,1,A,2);
968   if (B) PetscCheckSameComm(ts,1,B,3);
969 
970   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
971   ierr = DMTSSetRHSJacobian(dm,f,ctx);CHKERRQ(ierr);
972   ierr = DMTSGetIJacobian(dm,&ijacobian,NULL);CHKERRQ(ierr);
973 
974   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
975   if (!ijacobian) {
976     ierr = SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);CHKERRQ(ierr);
977   }
978   if (A) {
979     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
980     ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr);
981 
982     ts->Arhs = A;
983   }
984   if (B) {
985     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
986     ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr);
987 
988     ts->Brhs = B;
989   }
990   PetscFunctionReturn(0);
991 }
992 
993 
994 #undef __FUNCT__
995 #define __FUNCT__ "TSSetIFunction"
996 /*@C
997    TSSetIFunction - Set the function to compute F(t,U,U_t) where F() = 0 is the DAE to be solved.
998 
999    Logically Collective on TS
1000 
1001    Input Parameters:
1002 +  ts  - the TS context obtained from TSCreate()
1003 .  r   - vector to hold the residual (or NULL to have it created internally)
1004 .  f   - the function evaluation routine
1005 -  ctx - user-defined context for private data for the function evaluation routine (may be NULL)
1006 
1007    Calling sequence of f:
1008 $  f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx);
1009 
1010 +  t   - time at step/stage being solved
1011 .  u   - state vector
1012 .  u_t - time derivative of state vector
1013 .  F   - function vector
1014 -  ctx - [optional] user-defined context for matrix evaluation routine
1015 
1016    Important:
1017    The user MUST call either this routine, TSSetRHSFunction().  This routine must be used when not solving an ODE, for example a DAE.
1018 
1019    Level: beginner
1020 
1021 .keywords: TS, timestep, set, DAE, Jacobian
1022 
1023 .seealso: TSSetRHSJacobian(), TSSetRHSFunction(), TSSetIJacobian()
1024 @*/
1025 PetscErrorCode  TSSetIFunction(TS ts,Vec res,TSIFunction f,void *ctx)
1026 {
1027   PetscErrorCode ierr;
1028   SNES           snes;
1029   Vec            resalloc = NULL;
1030   DM             dm;
1031 
1032   PetscFunctionBegin;
1033   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1034   if (res) PetscValidHeaderSpecific(res,VEC_CLASSID,2);
1035 
1036   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1037   ierr = DMTSSetIFunction(dm,f,ctx);CHKERRQ(ierr);
1038 
1039   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1040   if (!res && !ts->dm && ts->vec_sol) {
1041     ierr = VecDuplicate(ts->vec_sol,&resalloc);CHKERRQ(ierr);
1042     res  = resalloc;
1043   }
1044   ierr = SNESSetFunction(snes,res,SNESTSFormFunction,ts);CHKERRQ(ierr);
1045   ierr = VecDestroy(&resalloc);CHKERRQ(ierr);
1046   PetscFunctionReturn(0);
1047 }
1048 
1049 #undef __FUNCT__
1050 #define __FUNCT__ "TSGetIFunction"
1051 /*@C
1052    TSGetIFunction - Returns the vector where the implicit residual is stored and the function/contex to compute it.
1053 
1054    Not Collective
1055 
1056    Input Parameter:
1057 .  ts - the TS context
1058 
1059    Output Parameter:
1060 +  r - vector to hold residual (or NULL)
1061 .  func - the function to compute residual (or NULL)
1062 -  ctx - the function context (or NULL)
1063 
1064    Level: advanced
1065 
1066 .keywords: TS, nonlinear, get, function
1067 
1068 .seealso: TSSetIFunction(), SNESGetFunction()
1069 @*/
1070 PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx)
1071 {
1072   PetscErrorCode ierr;
1073   SNES           snes;
1074   DM             dm;
1075 
1076   PetscFunctionBegin;
1077   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1078   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1079   ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr);
1080   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1081   ierr = DMTSGetIFunction(dm,func,ctx);CHKERRQ(ierr);
1082   PetscFunctionReturn(0);
1083 }
1084 
1085 #undef __FUNCT__
1086 #define __FUNCT__ "TSGetRHSFunction"
1087 /*@C
1088    TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it.
1089 
1090    Not Collective
1091 
1092    Input Parameter:
1093 .  ts - the TS context
1094 
1095    Output Parameter:
1096 +  r - vector to hold computed right hand side (or NULL)
1097 .  func - the function to compute right hand side (or NULL)
1098 -  ctx - the function context (or NULL)
1099 
1100    Level: advanced
1101 
1102 .keywords: TS, nonlinear, get, function
1103 
1104 .seealso: TSSetRhsfunction(), SNESGetFunction()
1105 @*/
1106 PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx)
1107 {
1108   PetscErrorCode ierr;
1109   SNES           snes;
1110   DM             dm;
1111 
1112   PetscFunctionBegin;
1113   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1114   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1115   ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr);
1116   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1117   ierr = DMTSGetRHSFunction(dm,func,ctx);CHKERRQ(ierr);
1118   PetscFunctionReturn(0);
1119 }
1120 
1121 #undef __FUNCT__
1122 #define __FUNCT__ "TSSetIJacobian"
1123 /*@C
1124    TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function
1125         you provided with TSSetIFunction().
1126 
1127    Logically Collective on TS
1128 
1129    Input Parameters:
1130 +  ts  - the TS context obtained from TSCreate()
1131 .  A   - Jacobian matrix
1132 .  B   - preconditioning matrix for A (may be same as A)
1133 .  f   - the Jacobian evaluation routine
1134 -  ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL)
1135 
1136    Calling sequence of f:
1137 $  f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat *A,Mat *B,MatStructure *flag,void *ctx);
1138 
1139 +  t    - time at step/stage being solved
1140 .  U    - state vector
1141 .  U_t  - time derivative of state vector
1142 .  a    - shift
1143 .  A    - Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t
1144 .  B    - preconditioning matrix for A, may be same as A
1145 .  flag - flag indicating information about the preconditioner matrix
1146           structure (same as flag in KSPSetOperators())
1147 -  ctx  - [optional] user-defined context for matrix evaluation routine
1148 
1149    Notes:
1150    The matrices A and B are exactly the matrices that are used by SNES for the nonlinear solve.
1151 
1152    The matrix dF/dU + a*dF/dU_t you provide turns out to be
1153    the Jacobian of F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved.
1154    The time integrator internally approximates U_t by W+a*U where the positive "shift"
1155    a and vector W depend on the integration method, step size, and past states. For example with
1156    the backward Euler method a = 1/dt and W = -a*U(previous timestep) so
1157    W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt
1158 
1159    Level: beginner
1160 
1161 .keywords: TS, timestep, DAE, Jacobian
1162 
1163 .seealso: TSSetIFunction(), TSSetRHSJacobian(), SNESDefaultComputeJacobianColor(), SNESDefaultComputeJacobian()
1164 
1165 @*/
1166 PetscErrorCode  TSSetIJacobian(TS ts,Mat A,Mat B,TSIJacobian f,void *ctx)
1167 {
1168   PetscErrorCode ierr;
1169   SNES           snes;
1170   DM             dm;
1171 
1172   PetscFunctionBegin;
1173   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1174   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
1175   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
1176   if (A) PetscCheckSameComm(ts,1,A,2);
1177   if (B) PetscCheckSameComm(ts,1,B,3);
1178 
1179   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1180   ierr = DMTSSetIJacobian(dm,f,ctx);CHKERRQ(ierr);
1181 
1182   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1183   ierr = SNESSetJacobian(snes,A,B,SNESTSFormJacobian,ts);CHKERRQ(ierr);
1184   PetscFunctionReturn(0);
1185 }
1186 
1187 #undef __FUNCT__
1188 #define __FUNCT__ "TSLoad"
1189 /*@C
1190   TSLoad - Loads a KSP that has been stored in binary  with KSPView().
1191 
1192   Collective on PetscViewer
1193 
1194   Input Parameters:
1195 + newdm - the newly loaded TS, this needs to have been created with TSCreate() or
1196            some related function before a call to TSLoad().
1197 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen()
1198 
1199    Level: intermediate
1200 
1201   Notes:
1202    The type is determined by the data in the file, any type set into the TS before this call is ignored.
1203 
1204   Notes for advanced users:
1205   Most users should not need to know the details of the binary storage
1206   format, since TSLoad() and TSView() completely hide these details.
1207   But for anyone who's interested, the standard binary matrix storage
1208   format is
1209 .vb
1210      has not yet been determined
1211 .ve
1212 
1213 .seealso: PetscViewerBinaryOpen(), TSView(), MatLoad(), VecLoad()
1214 @*/
1215 PetscErrorCode  TSLoad(TS ts, PetscViewer viewer)
1216 {
1217   PetscErrorCode ierr;
1218   PetscBool      isbinary;
1219   PetscInt       classid;
1220   char           type[256];
1221   DMTS           sdm;
1222   DM             dm;
1223 
1224   PetscFunctionBegin;
1225   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1226   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1227   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1228   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
1229 
1230   ierr = PetscViewerBinaryRead(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr);
1231   if (classid != TS_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Not TS next in file");
1232   ierr = PetscViewerBinaryRead(viewer,type,256,PETSC_CHAR);CHKERRQ(ierr);
1233   ierr = TSSetType(ts, type);CHKERRQ(ierr);
1234   if (ts->ops->load) {
1235     ierr = (*ts->ops->load)(ts,viewer);CHKERRQ(ierr);
1236   }
1237   ierr = DMCreate(PetscObjectComm((PetscObject)ts),&dm);CHKERRQ(ierr);
1238   ierr = DMLoad(dm,viewer);CHKERRQ(ierr);
1239   ierr = TSSetDM(ts,dm);CHKERRQ(ierr);
1240   ierr = DMCreateGlobalVector(ts->dm,&ts->vec_sol);CHKERRQ(ierr);
1241   ierr = VecLoad(ts->vec_sol,viewer);CHKERRQ(ierr);
1242   ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr);
1243   ierr = DMTSLoad(sdm,viewer);CHKERRQ(ierr);
1244   PetscFunctionReturn(0);
1245 }
1246 
1247 #include <petscdraw.h>
1248 #undef __FUNCT__
1249 #define __FUNCT__ "TSView"
1250 /*@C
1251     TSView - Prints the TS data structure.
1252 
1253     Collective on TS
1254 
1255     Input Parameters:
1256 +   ts - the TS context obtained from TSCreate()
1257 -   viewer - visualization context
1258 
1259     Options Database Key:
1260 .   -ts_view - calls TSView() at end of TSStep()
1261 
1262     Notes:
1263     The available visualization contexts include
1264 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
1265 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
1266          output where only the first processor opens
1267          the file.  All other processors send their
1268          data to the first processor to print.
1269 
1270     The user can open an alternative visualization context with
1271     PetscViewerASCIIOpen() - output to a specified file.
1272 
1273     Level: beginner
1274 
1275 .keywords: TS, timestep, view
1276 
1277 .seealso: PetscViewerASCIIOpen()
1278 @*/
1279 PetscErrorCode  TSView(TS ts,PetscViewer viewer)
1280 {
1281   PetscErrorCode ierr;
1282   TSType         type;
1283   PetscBool      iascii,isstring,isundials,isbinary,isdraw;
1284   DMTS           sdm;
1285 
1286   PetscFunctionBegin;
1287   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1288   if (!viewer) {
1289     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ts),&viewer);CHKERRQ(ierr);
1290   }
1291   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1292   PetscCheckSameComm(ts,1,viewer,2);
1293 
1294   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1295   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
1296   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1297   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
1298   if (iascii) {
1299     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer,"TS Object");CHKERRQ(ierr);
1300     ierr = PetscViewerASCIIPrintf(viewer,"  maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr);
1301     ierr = PetscViewerASCIIPrintf(viewer,"  maximum time=%G\n",ts->max_time);CHKERRQ(ierr);
1302     if (ts->problem_type == TS_NONLINEAR) {
1303       ierr = PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solver iterations=%D\n",ts->snes_its);CHKERRQ(ierr);
1304       ierr = PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solve failures=%D\n",ts->num_snes_failures);CHKERRQ(ierr);
1305     }
1306     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",ts->ksp_its);CHKERRQ(ierr);
1307     ierr = PetscViewerASCIIPrintf(viewer,"  total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr);
1308     ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr);
1309     ierr = DMTSView(sdm,viewer);CHKERRQ(ierr);
1310     if (ts->ops->view) {
1311       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1312       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1313       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1314     }
1315   } else if (isstring) {
1316     ierr = TSGetType(ts,&type);CHKERRQ(ierr);
1317     ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr);
1318   } else if (isbinary) {
1319     PetscInt    classid = TS_FILE_CLASSID;
1320     MPI_Comm    comm;
1321     PetscMPIInt rank;
1322     char        type[256];
1323 
1324     ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr);
1325     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
1326     if (!rank) {
1327       ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
1328       ierr = PetscStrncpy(type,((PetscObject)ts)->type_name,256);CHKERRQ(ierr);
1329       ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
1330     }
1331     if (ts->ops->view) {
1332       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1333     }
1334     ierr = DMView(ts->dm,viewer);CHKERRQ(ierr);
1335     ierr = VecView(ts->vec_sol,viewer);CHKERRQ(ierr);
1336     ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr);
1337     ierr = DMTSView(sdm,viewer);CHKERRQ(ierr);
1338   } else if (isdraw) {
1339     PetscDraw draw;
1340     char      str[36];
1341     PetscReal x,y,bottom,h;
1342 
1343     ierr   = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1344     ierr   = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
1345     ierr   = PetscStrcpy(str,"TS: ");CHKERRQ(ierr);
1346     ierr   = PetscStrcat(str,((PetscObject)ts)->type_name);CHKERRQ(ierr);
1347     ierr   = PetscDrawBoxedString(draw,x,y,PETSC_DRAW_BLACK,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr);
1348     bottom = y - h;
1349     ierr   = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
1350     if (ts->ops->view) {
1351       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1352     }
1353     ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr);
1354   }
1355   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1356   ierr = PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr);
1357   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1358   PetscFunctionReturn(0);
1359 }
1360 
1361 
1362 #undef __FUNCT__
1363 #define __FUNCT__ "TSSetApplicationContext"
1364 /*@
1365    TSSetApplicationContext - Sets an optional user-defined context for
1366    the timesteppers.
1367 
1368    Logically Collective on TS
1369 
1370    Input Parameters:
1371 +  ts - the TS context obtained from TSCreate()
1372 -  usrP - optional user context
1373 
1374    Level: intermediate
1375 
1376 .keywords: TS, timestep, set, application, context
1377 
1378 .seealso: TSGetApplicationContext()
1379 @*/
1380 PetscErrorCode  TSSetApplicationContext(TS ts,void *usrP)
1381 {
1382   PetscFunctionBegin;
1383   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1384   ts->user = usrP;
1385   PetscFunctionReturn(0);
1386 }
1387 
1388 #undef __FUNCT__
1389 #define __FUNCT__ "TSGetApplicationContext"
1390 /*@
1391     TSGetApplicationContext - Gets the user-defined context for the
1392     timestepper.
1393 
1394     Not Collective
1395 
1396     Input Parameter:
1397 .   ts - the TS context obtained from TSCreate()
1398 
1399     Output Parameter:
1400 .   usrP - user context
1401 
1402     Level: intermediate
1403 
1404 .keywords: TS, timestep, get, application, context
1405 
1406 .seealso: TSSetApplicationContext()
1407 @*/
1408 PetscErrorCode  TSGetApplicationContext(TS ts,void *usrP)
1409 {
1410   PetscFunctionBegin;
1411   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1412   *(void**)usrP = ts->user;
1413   PetscFunctionReturn(0);
1414 }
1415 
1416 #undef __FUNCT__
1417 #define __FUNCT__ "TSGetTimeStepNumber"
1418 /*@
1419    TSGetTimeStepNumber - Gets the number of time steps completed.
1420 
1421    Not Collective
1422 
1423    Input Parameter:
1424 .  ts - the TS context obtained from TSCreate()
1425 
1426    Output Parameter:
1427 .  iter - number of steps completed so far
1428 
1429    Level: intermediate
1430 
1431 .keywords: TS, timestep, get, iteration, number
1432 .seealso: TSGetTime(), TSGetTimeStep(), TSSetPreStep(), TSSetPreStage(), TSSetPostStep()
1433 @*/
1434 PetscErrorCode  TSGetTimeStepNumber(TS ts,PetscInt *iter)
1435 {
1436   PetscFunctionBegin;
1437   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1438   PetscValidIntPointer(iter,2);
1439   *iter = ts->steps;
1440   PetscFunctionReturn(0);
1441 }
1442 
1443 #undef __FUNCT__
1444 #define __FUNCT__ "TSSetInitialTimeStep"
1445 /*@
1446    TSSetInitialTimeStep - Sets the initial timestep to be used,
1447    as well as the initial time.
1448 
1449    Logically Collective on TS
1450 
1451    Input Parameters:
1452 +  ts - the TS context obtained from TSCreate()
1453 .  initial_time - the initial time
1454 -  time_step - the size of the timestep
1455 
1456    Level: intermediate
1457 
1458 .seealso: TSSetTimeStep(), TSGetTimeStep()
1459 
1460 .keywords: TS, set, initial, timestep
1461 @*/
1462 PetscErrorCode  TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step)
1463 {
1464   PetscErrorCode ierr;
1465 
1466   PetscFunctionBegin;
1467   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1468   ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr);
1469   ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr);
1470   PetscFunctionReturn(0);
1471 }
1472 
1473 #undef __FUNCT__
1474 #define __FUNCT__ "TSSetTimeStep"
1475 /*@
1476    TSSetTimeStep - Allows one to reset the timestep at any time,
1477    useful for simple pseudo-timestepping codes.
1478 
1479    Logically Collective on TS
1480 
1481    Input Parameters:
1482 +  ts - the TS context obtained from TSCreate()
1483 -  time_step - the size of the timestep
1484 
1485    Level: intermediate
1486 
1487 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
1488 
1489 .keywords: TS, set, timestep
1490 @*/
1491 PetscErrorCode  TSSetTimeStep(TS ts,PetscReal time_step)
1492 {
1493   PetscFunctionBegin;
1494   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1495   PetscValidLogicalCollectiveReal(ts,time_step,2);
1496   ts->time_step      = time_step;
1497   ts->time_step_orig = time_step;
1498   PetscFunctionReturn(0);
1499 }
1500 
1501 #undef __FUNCT__
1502 #define __FUNCT__ "TSSetExactFinalTime"
1503 /*@
1504    TSSetExactFinalTime - Determines whether to adapt the final time step to
1505      match the exact final time, interpolate solution to the exact final time,
1506      or just return at the final time TS computed.
1507 
1508   Logically Collective on TS
1509 
1510    Input Parameter:
1511 +   ts - the time-step context
1512 -   eftopt - exact final time option
1513 
1514    Level: beginner
1515 
1516 .seealso: TSExactFinalTimeOption
1517 @*/
1518 PetscErrorCode  TSSetExactFinalTime(TS ts,TSExactFinalTimeOption eftopt)
1519 {
1520   PetscFunctionBegin;
1521   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1522   PetscValidLogicalCollectiveEnum(ts,eftopt,2);
1523   ts->exact_final_time = eftopt;
1524   PetscFunctionReturn(0);
1525 }
1526 
1527 #undef __FUNCT__
1528 #define __FUNCT__ "TSGetTimeStep"
1529 /*@
1530    TSGetTimeStep - Gets the current timestep size.
1531 
1532    Not Collective
1533 
1534    Input Parameter:
1535 .  ts - the TS context obtained from TSCreate()
1536 
1537    Output Parameter:
1538 .  dt - the current timestep size
1539 
1540    Level: intermediate
1541 
1542 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
1543 
1544 .keywords: TS, get, timestep
1545 @*/
1546 PetscErrorCode  TSGetTimeStep(TS ts,PetscReal *dt)
1547 {
1548   PetscFunctionBegin;
1549   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1550   PetscValidRealPointer(dt,2);
1551   *dt = ts->time_step;
1552   PetscFunctionReturn(0);
1553 }
1554 
1555 #undef __FUNCT__
1556 #define __FUNCT__ "TSGetSolution"
1557 /*@
1558    TSGetSolution - Returns the solution at the present timestep. It
1559    is valid to call this routine inside the function that you are evaluating
1560    in order to move to the new timestep. This vector not changed until
1561    the solution at the next timestep has been calculated.
1562 
1563    Not Collective, but Vec returned is parallel if TS is parallel
1564 
1565    Input Parameter:
1566 .  ts - the TS context obtained from TSCreate()
1567 
1568    Output Parameter:
1569 .  v - the vector containing the solution
1570 
1571    Level: intermediate
1572 
1573 .seealso: TSGetTimeStep()
1574 
1575 .keywords: TS, timestep, get, solution
1576 @*/
1577 PetscErrorCode  TSGetSolution(TS ts,Vec *v)
1578 {
1579   PetscFunctionBegin;
1580   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1581   PetscValidPointer(v,2);
1582   *v = ts->vec_sol;
1583   PetscFunctionReturn(0);
1584 }
1585 
1586 /* ----- Routines to initialize and destroy a timestepper ---- */
1587 #undef __FUNCT__
1588 #define __FUNCT__ "TSSetProblemType"
1589 /*@
1590   TSSetProblemType - Sets the type of problem to be solved.
1591 
1592   Not collective
1593 
1594   Input Parameters:
1595 + ts   - The TS
1596 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1597 .vb
1598          U_t - A U = 0      (linear)
1599          U_t - A(t) U = 0   (linear)
1600          F(t,U,U_t) = 0     (nonlinear)
1601 .ve
1602 
1603    Level: beginner
1604 
1605 .keywords: TS, problem type
1606 .seealso: TSSetUp(), TSProblemType, TS
1607 @*/
1608 PetscErrorCode  TSSetProblemType(TS ts, TSProblemType type)
1609 {
1610   PetscErrorCode ierr;
1611 
1612   PetscFunctionBegin;
1613   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1614   ts->problem_type = type;
1615   if (type == TS_LINEAR) {
1616     SNES snes;
1617     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1618     ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);
1619   }
1620   PetscFunctionReturn(0);
1621 }
1622 
1623 #undef __FUNCT__
1624 #define __FUNCT__ "TSGetProblemType"
1625 /*@C
1626   TSGetProblemType - Gets the type of problem to be solved.
1627 
1628   Not collective
1629 
1630   Input Parameter:
1631 . ts   - The TS
1632 
1633   Output Parameter:
1634 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1635 .vb
1636          M U_t = A U
1637          M(t) U_t = A(t) U
1638          F(t,U,U_t)
1639 .ve
1640 
1641    Level: beginner
1642 
1643 .keywords: TS, problem type
1644 .seealso: TSSetUp(), TSProblemType, TS
1645 @*/
1646 PetscErrorCode  TSGetProblemType(TS ts, TSProblemType *type)
1647 {
1648   PetscFunctionBegin;
1649   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1650   PetscValidIntPointer(type,2);
1651   *type = ts->problem_type;
1652   PetscFunctionReturn(0);
1653 }
1654 
1655 #undef __FUNCT__
1656 #define __FUNCT__ "TSSetUp"
1657 /*@
1658    TSSetUp - Sets up the internal data structures for the later use
1659    of a timestepper.
1660 
1661    Collective on TS
1662 
1663    Input Parameter:
1664 .  ts - the TS context obtained from TSCreate()
1665 
1666    Notes:
1667    For basic use of the TS solvers the user need not explicitly call
1668    TSSetUp(), since these actions will automatically occur during
1669    the call to TSStep().  However, if one wishes to control this
1670    phase separately, TSSetUp() should be called after TSCreate()
1671    and optional routines of the form TSSetXXX(), but before TSStep().
1672 
1673    Level: advanced
1674 
1675 .keywords: TS, timestep, setup
1676 
1677 .seealso: TSCreate(), TSStep(), TSDestroy()
1678 @*/
1679 PetscErrorCode  TSSetUp(TS ts)
1680 {
1681   PetscErrorCode ierr;
1682   DM             dm;
1683   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
1684   PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
1685   TSIJacobian    ijac;
1686   TSRHSJacobian  rhsjac;
1687 
1688   PetscFunctionBegin;
1689   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1690   if (ts->setupcalled) PetscFunctionReturn(0);
1691 
1692   if (!((PetscObject)ts)->type_name) {
1693     ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr);
1694   }
1695 
1696   if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first");
1697 
1698   ierr = TSGetTSAdapt(ts,&ts->adapt);CHKERRQ(ierr);
1699 
1700   if (ts->ops->setup) {
1701     ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr);
1702   }
1703 
1704   /* in the case where we've set a DMTSFunction or what have you, we need the default SNESFunction
1705    to be set right but can't do it elsewhere due to the overreliance on ctx=ts.
1706    */
1707   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1708   ierr = DMSNESGetFunction(dm,&func,NULL);CHKERRQ(ierr);
1709   if (!func) {
1710     ierr =DMSNESSetFunction(dm,SNESTSFormFunction,ts);CHKERRQ(ierr);
1711   }
1712   /* if the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it.
1713      Otherwise, the SNES will use coloring internally to form the Jacobian.
1714    */
1715   ierr = DMSNESGetJacobian(dm,&jac,NULL);CHKERRQ(ierr);
1716   ierr = DMTSGetIJacobian(dm,&ijac,NULL);CHKERRQ(ierr);
1717   ierr = DMTSGetRHSJacobian(dm,&rhsjac,NULL);CHKERRQ(ierr);
1718   if (!jac && (ijac || rhsjac)) {
1719     ierr = DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);CHKERRQ(ierr);
1720   }
1721   ts->setupcalled = PETSC_TRUE;
1722   PetscFunctionReturn(0);
1723 }
1724 
1725 #undef __FUNCT__
1726 #define __FUNCT__ "TSReset"
1727 /*@
1728    TSReset - Resets a TS context and removes any allocated Vecs and Mats.
1729 
1730    Collective on TS
1731 
1732    Input Parameter:
1733 .  ts - the TS context obtained from TSCreate()
1734 
1735    Level: beginner
1736 
1737 .keywords: TS, timestep, reset
1738 
1739 .seealso: TSCreate(), TSSetup(), TSDestroy()
1740 @*/
1741 PetscErrorCode  TSReset(TS ts)
1742 {
1743   PetscErrorCode ierr;
1744 
1745   PetscFunctionBegin;
1746   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1747   if (ts->ops->reset) {
1748     ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr);
1749   }
1750   if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);}
1751 
1752   ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr);
1753   ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr);
1754   ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr);
1755   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
1756   ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
1757   ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
1758   ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr);
1759 
1760   ts->setupcalled = PETSC_FALSE;
1761   PetscFunctionReturn(0);
1762 }
1763 
1764 #undef __FUNCT__
1765 #define __FUNCT__ "TSDestroy"
1766 /*@
1767    TSDestroy - Destroys the timestepper context that was created
1768    with TSCreate().
1769 
1770    Collective on TS
1771 
1772    Input Parameter:
1773 .  ts - the TS context obtained from TSCreate()
1774 
1775    Level: beginner
1776 
1777 .keywords: TS, timestepper, destroy
1778 
1779 .seealso: TSCreate(), TSSetUp(), TSSolve()
1780 @*/
1781 PetscErrorCode  TSDestroy(TS *ts)
1782 {
1783   PetscErrorCode ierr;
1784 
1785   PetscFunctionBegin;
1786   if (!*ts) PetscFunctionReturn(0);
1787   PetscValidHeaderSpecific((*ts),TS_CLASSID,1);
1788   if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);}
1789 
1790   ierr = TSReset((*ts));CHKERRQ(ierr);
1791 
1792   /* if memory was published with AMS then destroy it */
1793   ierr = PetscObjectDepublish((*ts));CHKERRQ(ierr);
1794   if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);}
1795 
1796   ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr);
1797   ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr);
1798   ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr);
1799   ierr = TSMonitorCancel((*ts));CHKERRQ(ierr);
1800 
1801   ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr);
1802   PetscFunctionReturn(0);
1803 }
1804 
1805 #undef __FUNCT__
1806 #define __FUNCT__ "TSGetSNES"
1807 /*@
1808    TSGetSNES - Returns the SNES (nonlinear solver) associated with
1809    a TS (timestepper) context. Valid only for nonlinear problems.
1810 
1811    Not Collective, but SNES is parallel if TS is parallel
1812 
1813    Input Parameter:
1814 .  ts - the TS context obtained from TSCreate()
1815 
1816    Output Parameter:
1817 .  snes - the nonlinear solver context
1818 
1819    Notes:
1820    The user can then directly manipulate the SNES context to set various
1821    options, etc.  Likewise, the user can then extract and manipulate the
1822    KSP, KSP, and PC contexts as well.
1823 
1824    TSGetSNES() does not work for integrators that do not use SNES; in
1825    this case TSGetSNES() returns NULL in snes.
1826 
1827    Level: beginner
1828 
1829 .keywords: timestep, get, SNES
1830 @*/
1831 PetscErrorCode  TSGetSNES(TS ts,SNES *snes)
1832 {
1833   PetscErrorCode ierr;
1834 
1835   PetscFunctionBegin;
1836   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1837   PetscValidPointer(snes,2);
1838   if (!ts->snes) {
1839     ierr = SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);CHKERRQ(ierr);
1840     ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr);
1841     ierr = PetscLogObjectParent(ts,ts->snes);CHKERRQ(ierr);
1842     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr);
1843     if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
1844     if (ts->problem_type == TS_LINEAR) {
1845       ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr);
1846     }
1847   }
1848   *snes = ts->snes;
1849   PetscFunctionReturn(0);
1850 }
1851 
1852 #undef __FUNCT__
1853 #define __FUNCT__ "TSSetSNES"
1854 /*@
1855    TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context
1856 
1857    Collective
1858 
1859    Input Parameter:
1860 +  ts - the TS context obtained from TSCreate()
1861 -  snes - the nonlinear solver context
1862 
1863    Notes:
1864    Most users should have the TS created by calling TSGetSNES()
1865 
1866    Level: developer
1867 
1868 .keywords: timestep, set, SNES
1869 @*/
1870 PetscErrorCode TSSetSNES(TS ts,SNES snes)
1871 {
1872   PetscErrorCode ierr;
1873   PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
1874 
1875   PetscFunctionBegin;
1876   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1877   PetscValidHeaderSpecific(snes,SNES_CLASSID,2);
1878   ierr = PetscObjectReference((PetscObject)snes);CHKERRQ(ierr);
1879   ierr = SNESDestroy(&ts->snes);CHKERRQ(ierr);
1880 
1881   ts->snes = snes;
1882 
1883   ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr);
1884   ierr = SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);CHKERRQ(ierr);
1885   if (func == SNESTSFormJacobian) {
1886     ierr = SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);CHKERRQ(ierr);
1887   }
1888   PetscFunctionReturn(0);
1889 }
1890 
1891 #undef __FUNCT__
1892 #define __FUNCT__ "TSGetKSP"
1893 /*@
1894    TSGetKSP - Returns the KSP (linear solver) associated with
1895    a TS (timestepper) context.
1896 
1897    Not Collective, but KSP is parallel if TS is parallel
1898 
1899    Input Parameter:
1900 .  ts - the TS context obtained from TSCreate()
1901 
1902    Output Parameter:
1903 .  ksp - the nonlinear solver context
1904 
1905    Notes:
1906    The user can then directly manipulate the KSP context to set various
1907    options, etc.  Likewise, the user can then extract and manipulate the
1908    KSP and PC contexts as well.
1909 
1910    TSGetKSP() does not work for integrators that do not use KSP;
1911    in this case TSGetKSP() returns NULL in ksp.
1912 
1913    Level: beginner
1914 
1915 .keywords: timestep, get, KSP
1916 @*/
1917 PetscErrorCode  TSGetKSP(TS ts,KSP *ksp)
1918 {
1919   PetscErrorCode ierr;
1920   SNES           snes;
1921 
1922   PetscFunctionBegin;
1923   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1924   PetscValidPointer(ksp,2);
1925   if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first");
1926   if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()");
1927   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1928   ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr);
1929   PetscFunctionReturn(0);
1930 }
1931 
1932 /* ----------- Routines to set solver parameters ---------- */
1933 
1934 #undef __FUNCT__
1935 #define __FUNCT__ "TSGetDuration"
1936 /*@
1937    TSGetDuration - Gets the maximum number of timesteps to use and
1938    maximum time for iteration.
1939 
1940    Not Collective
1941 
1942    Input Parameters:
1943 +  ts       - the TS context obtained from TSCreate()
1944 .  maxsteps - maximum number of iterations to use, or NULL
1945 -  maxtime  - final time to iterate to, or NULL
1946 
1947    Level: intermediate
1948 
1949 .keywords: TS, timestep, get, maximum, iterations, time
1950 @*/
1951 PetscErrorCode  TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
1952 {
1953   PetscFunctionBegin;
1954   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1955   if (maxsteps) {
1956     PetscValidIntPointer(maxsteps,2);
1957     *maxsteps = ts->max_steps;
1958   }
1959   if (maxtime) {
1960     PetscValidScalarPointer(maxtime,3);
1961     *maxtime = ts->max_time;
1962   }
1963   PetscFunctionReturn(0);
1964 }
1965 
1966 #undef __FUNCT__
1967 #define __FUNCT__ "TSSetDuration"
1968 /*@
1969    TSSetDuration - Sets the maximum number of timesteps to use and
1970    maximum time for iteration.
1971 
1972    Logically Collective on TS
1973 
1974    Input Parameters:
1975 +  ts - the TS context obtained from TSCreate()
1976 .  maxsteps - maximum number of iterations to use
1977 -  maxtime - final time to iterate to
1978 
1979    Options Database Keys:
1980 .  -ts_max_steps <maxsteps> - Sets maxsteps
1981 .  -ts_final_time <maxtime> - Sets maxtime
1982 
1983    Notes:
1984    The default maximum number of iterations is 5000. Default time is 5.0
1985 
1986    Level: intermediate
1987 
1988 .keywords: TS, timestep, set, maximum, iterations
1989 
1990 .seealso: TSSetExactFinalTime()
1991 @*/
1992 PetscErrorCode  TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime)
1993 {
1994   PetscFunctionBegin;
1995   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1996   PetscValidLogicalCollectiveInt(ts,maxsteps,2);
1997   PetscValidLogicalCollectiveReal(ts,maxtime,2);
1998   if (maxsteps >= 0) ts->max_steps = maxsteps;
1999   if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime;
2000   PetscFunctionReturn(0);
2001 }
2002 
2003 #undef __FUNCT__
2004 #define __FUNCT__ "TSSetSolution"
2005 /*@
2006    TSSetSolution - Sets the initial solution vector
2007    for use by the TS routines.
2008 
2009    Logically Collective on TS and Vec
2010 
2011    Input Parameters:
2012 +  ts - the TS context obtained from TSCreate()
2013 -  u - the solution vector
2014 
2015    Level: beginner
2016 
2017 .keywords: TS, timestep, set, solution, initial conditions
2018 @*/
2019 PetscErrorCode  TSSetSolution(TS ts,Vec u)
2020 {
2021   PetscErrorCode ierr;
2022   DM             dm;
2023 
2024   PetscFunctionBegin;
2025   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2026   PetscValidHeaderSpecific(u,VEC_CLASSID,2);
2027   ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr);
2028   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
2029 
2030   ts->vec_sol = u;
2031 
2032   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2033   ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr);
2034   PetscFunctionReturn(0);
2035 }
2036 
2037 #undef __FUNCT__
2038 #define __FUNCT__ "TSSetPreStep"
2039 /*@C
2040   TSSetPreStep - Sets the general-purpose function
2041   called once at the beginning of each time step.
2042 
2043   Logically Collective on TS
2044 
2045   Input Parameters:
2046 + ts   - The TS context obtained from TSCreate()
2047 - func - The function
2048 
2049   Calling sequence of func:
2050 . func (TS ts);
2051 
2052   Level: intermediate
2053 
2054   Note:
2055   If a step is rejected, TSStep() will call this routine again before each attempt.
2056   The last completed time step number can be queried using TSGetTimeStepNumber(), the
2057   size of the step being attempted can be obtained using TSGetTimeStep().
2058 
2059 .keywords: TS, timestep
2060 .seealso: TSSetPreStage(), TSSetPostStep(), TSStep()
2061 @*/
2062 PetscErrorCode  TSSetPreStep(TS ts, PetscErrorCode (*func)(TS))
2063 {
2064   PetscFunctionBegin;
2065   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2066   ts->ops->prestep = func;
2067   PetscFunctionReturn(0);
2068 }
2069 
2070 #undef __FUNCT__
2071 #define __FUNCT__ "TSPreStep"
2072 /*@
2073   TSPreStep - Runs the user-defined pre-step function.
2074 
2075   Collective on TS
2076 
2077   Input Parameters:
2078 . ts   - The TS context obtained from TSCreate()
2079 
2080   Notes:
2081   TSPreStep() is typically used within time stepping implementations,
2082   so most users would not generally call this routine themselves.
2083 
2084   Level: developer
2085 
2086 .keywords: TS, timestep
2087 .seealso: TSSetPreStep(), TSPreStage(), TSPostStep()
2088 @*/
2089 PetscErrorCode  TSPreStep(TS ts)
2090 {
2091   PetscErrorCode ierr;
2092 
2093   PetscFunctionBegin;
2094   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2095   if (ts->ops->prestep) {
2096     PetscStackPush("TS PreStep function");
2097     ierr = (*ts->ops->prestep)(ts);CHKERRQ(ierr);
2098     PetscStackPop;
2099   }
2100   PetscFunctionReturn(0);
2101 }
2102 
2103 #undef __FUNCT__
2104 #define __FUNCT__ "TSSetPreStage"
2105 /*@C
2106   TSSetPreStage - Sets the general-purpose function
2107   called once at the beginning of each stage.
2108 
2109   Logically Collective on TS
2110 
2111   Input Parameters:
2112 + ts   - The TS context obtained from TSCreate()
2113 - func - The function
2114 
2115   Calling sequence of func:
2116 . PetscErrorCode func(TS ts, PetscReal stagetime);
2117 
2118   Level: intermediate
2119 
2120   Note:
2121   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
2122   The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being
2123   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
2124 
2125 .keywords: TS, timestep
2126 .seealso: TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
2127 @*/
2128 PetscErrorCode  TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal))
2129 {
2130   PetscFunctionBegin;
2131   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2132   ts->ops->prestage = func;
2133   PetscFunctionReturn(0);
2134 }
2135 
2136 #undef __FUNCT__
2137 #define __FUNCT__ "TSPreStage"
2138 /*@
2139   TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage()
2140 
2141   Collective on TS
2142 
2143   Input Parameters:
2144 . ts   - The TS context obtained from TSCreate()
2145 
2146   Notes:
2147   TSPreStage() is typically used within time stepping implementations,
2148   most users would not generally call this routine themselves.
2149 
2150   Level: developer
2151 
2152 .keywords: TS, timestep
2153 .seealso: TSSetPreStep(), TSPreStep(), TSPostStep()
2154 @*/
2155 PetscErrorCode  TSPreStage(TS ts, PetscReal stagetime)
2156 {
2157   PetscErrorCode ierr;
2158 
2159   PetscFunctionBegin;
2160   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2161   if (ts->ops->prestage) {
2162     PetscStackPush("TS PreStage function");
2163     ierr = (*ts->ops->prestage)(ts,stagetime);CHKERRQ(ierr);
2164     PetscStackPop;
2165   }
2166   PetscFunctionReturn(0);
2167 }
2168 
2169 #undef __FUNCT__
2170 #define __FUNCT__ "TSSetPostStep"
2171 /*@C
2172   TSSetPostStep - Sets the general-purpose function
2173   called once at the end of each time step.
2174 
2175   Logically Collective on TS
2176 
2177   Input Parameters:
2178 + ts   - The TS context obtained from TSCreate()
2179 - func - The function
2180 
2181   Calling sequence of func:
2182 $ func (TS ts);
2183 
2184   Level: intermediate
2185 
2186 .keywords: TS, timestep
2187 .seealso: TSSetPreStep(), TSSetPreStage(), TSGetTimeStep(), TSGetTimeStepNumber(), TSGetTime()
2188 @*/
2189 PetscErrorCode  TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
2190 {
2191   PetscFunctionBegin;
2192   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2193   ts->ops->poststep = func;
2194   PetscFunctionReturn(0);
2195 }
2196 
2197 #undef __FUNCT__
2198 #define __FUNCT__ "TSPostStep"
2199 /*@
2200   TSPostStep - Runs the user-defined post-step function.
2201 
2202   Collective on TS
2203 
2204   Input Parameters:
2205 . ts   - The TS context obtained from TSCreate()
2206 
2207   Notes:
2208   TSPostStep() is typically used within time stepping implementations,
2209   so most users would not generally call this routine themselves.
2210 
2211   Level: developer
2212 
2213 .keywords: TS, timestep
2214 @*/
2215 PetscErrorCode  TSPostStep(TS ts)
2216 {
2217   PetscErrorCode ierr;
2218 
2219   PetscFunctionBegin;
2220   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2221   if (ts->ops->poststep) {
2222     PetscStackPush("TS PostStep function");
2223     ierr = (*ts->ops->poststep)(ts);CHKERRQ(ierr);
2224     PetscStackPop;
2225   }
2226   PetscFunctionReturn(0);
2227 }
2228 
2229 /* ------------ Routines to set performance monitoring options ----------- */
2230 
2231 #undef __FUNCT__
2232 #define __FUNCT__ "TSMonitorSet"
2233 /*@C
2234    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
2235    timestep to display the iteration's  progress.
2236 
2237    Logically Collective on TS
2238 
2239    Input Parameters:
2240 +  ts - the TS context obtained from TSCreate()
2241 .  monitor - monitoring routine
2242 .  mctx - [optional] user-defined context for private data for the
2243              monitor routine (use NULL if no context is desired)
2244 -  monitordestroy - [optional] routine that frees monitor context
2245           (may be NULL)
2246 
2247    Calling sequence of monitor:
2248 $    int monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
2249 
2250 +    ts - the TS context
2251 .    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
2252                                been interpolated to)
2253 .    time - current time
2254 .    u - current iterate
2255 -    mctx - [optional] monitoring context
2256 
2257    Notes:
2258    This routine adds an additional monitor to the list of monitors that
2259    already has been loaded.
2260 
2261    Fortran notes: Only a single monitor function can be set for each TS object
2262 
2263    Level: intermediate
2264 
2265 .keywords: TS, timestep, set, monitor
2266 
2267 .seealso: TSMonitorDefault(), TSMonitorCancel()
2268 @*/
2269 PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**))
2270 {
2271   PetscFunctionBegin;
2272   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2273   if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2274   ts->monitor[ts->numbermonitors]          = monitor;
2275   ts->monitordestroy[ts->numbermonitors]   = mdestroy;
2276   ts->monitorcontext[ts->numbermonitors++] = (void*)mctx;
2277   PetscFunctionReturn(0);
2278 }
2279 
2280 #undef __FUNCT__
2281 #define __FUNCT__ "TSMonitorCancel"
2282 /*@C
2283    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
2284 
2285    Logically Collective on TS
2286 
2287    Input Parameters:
2288 .  ts - the TS context obtained from TSCreate()
2289 
2290    Notes:
2291    There is no way to remove a single, specific monitor.
2292 
2293    Level: intermediate
2294 
2295 .keywords: TS, timestep, set, monitor
2296 
2297 .seealso: TSMonitorDefault(), TSMonitorSet()
2298 @*/
2299 PetscErrorCode  TSMonitorCancel(TS ts)
2300 {
2301   PetscErrorCode ierr;
2302   PetscInt       i;
2303 
2304   PetscFunctionBegin;
2305   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2306   for (i=0; i<ts->numbermonitors; i++) {
2307     if (ts->monitordestroy[i]) {
2308       ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr);
2309     }
2310   }
2311   ts->numbermonitors = 0;
2312   PetscFunctionReturn(0);
2313 }
2314 
2315 #undef __FUNCT__
2316 #define __FUNCT__ "TSMonitorDefault"
2317 /*@
2318    TSMonitorDefault - Sets the Default monitor
2319 
2320    Level: intermediate
2321 
2322 .keywords: TS, set, monitor
2323 
2324 .seealso: TSMonitorDefault(), TSMonitorSet()
2325 @*/
2326 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *dummy)
2327 {
2328   PetscErrorCode ierr;
2329   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)ts));
2330 
2331   PetscFunctionBegin;
2332   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
2333   ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g\n",step,(double)ts->time_step,(double)ptime);CHKERRQ(ierr);
2334   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
2335   PetscFunctionReturn(0);
2336 }
2337 
2338 #undef __FUNCT__
2339 #define __FUNCT__ "TSSetRetainStages"
2340 /*@
2341    TSSetRetainStages - Request that all stages in the upcoming step be stored so that interpolation will be available.
2342 
2343    Logically Collective on TS
2344 
2345    Input Argument:
2346 .  ts - time stepping context
2347 
2348    Output Argument:
2349 .  flg - PETSC_TRUE or PETSC_FALSE
2350 
2351    Level: intermediate
2352 
2353 .keywords: TS, set
2354 
2355 .seealso: TSInterpolate(), TSSetPostStep()
2356 @*/
2357 PetscErrorCode TSSetRetainStages(TS ts,PetscBool flg)
2358 {
2359   PetscFunctionBegin;
2360   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2361   ts->retain_stages = flg;
2362   PetscFunctionReturn(0);
2363 }
2364 
2365 #undef __FUNCT__
2366 #define __FUNCT__ "TSInterpolate"
2367 /*@
2368    TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval
2369 
2370    Collective on TS
2371 
2372    Input Argument:
2373 +  ts - time stepping context
2374 -  t - time to interpolate to
2375 
2376    Output Argument:
2377 .  U - state at given time
2378 
2379    Notes:
2380    The user should call TSSetRetainStages() before taking a step in which interpolation will be requested.
2381 
2382    Level: intermediate
2383 
2384    Developer Notes:
2385    TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints.
2386 
2387 .keywords: TS, set
2388 
2389 .seealso: TSSetRetainStages(), TSSetPostStep()
2390 @*/
2391 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U)
2392 {
2393   PetscErrorCode ierr;
2394 
2395   PetscFunctionBegin;
2396   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2397   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,ts->ptime-ts->time_step_prev,ts->ptime);
2398   if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name);
2399   ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr);
2400   PetscFunctionReturn(0);
2401 }
2402 
2403 #undef __FUNCT__
2404 #define __FUNCT__ "TSStep"
2405 /*@
2406    TSStep - Steps one time step
2407 
2408    Collective on TS
2409 
2410    Input Parameter:
2411 .  ts - the TS context obtained from TSCreate()
2412 
2413    Level: intermediate
2414 
2415    Notes:
2416    The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may
2417    be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages.
2418 
2419    This may over-step the final time provided in TSSetDuration() depending on the time-step used. TSSolve() interpolates to exactly the
2420    time provided in TSSetDuration(). One can use TSInterpolate() to determine an interpolated solution within the final timestep.
2421 
2422 .keywords: TS, timestep, solve
2423 
2424 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate()
2425 @*/
2426 PetscErrorCode  TSStep(TS ts)
2427 {
2428   PetscReal      ptime_prev;
2429   PetscErrorCode ierr;
2430 
2431   PetscFunctionBegin;
2432   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2433   ierr = TSSetUp(ts);CHKERRQ(ierr);
2434 
2435   ts->reason = TS_CONVERGED_ITERATING;
2436   ptime_prev = ts->ptime;
2437 
2438   ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr);
2439   ierr = (*ts->ops->step)(ts);CHKERRQ(ierr);
2440   ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr);
2441 
2442   ts->time_step_prev = ts->ptime - ptime_prev;
2443 
2444   if (ts->reason < 0) {
2445     if (ts->errorifstepfailed) {
2446       if (ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) {
2447         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]);
2448       } else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]);
2449     }
2450   } else if (!ts->reason) {
2451     if (ts->steps >= ts->max_steps)     ts->reason = TS_CONVERGED_ITS;
2452     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
2453   }
2454   PetscFunctionReturn(0);
2455 }
2456 
2457 #undef __FUNCT__
2458 #define __FUNCT__ "TSEvaluateStep"
2459 /*@
2460    TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy.
2461 
2462    Collective on TS
2463 
2464    Input Arguments:
2465 +  ts - time stepping context
2466 .  order - desired order of accuracy
2467 -  done - whether the step was evaluated at this order (pass NULL to generate an error if not available)
2468 
2469    Output Arguments:
2470 .  U - state at the end of the current step
2471 
2472    Level: advanced
2473 
2474    Notes:
2475    This function cannot be called until all stages have been evaluated.
2476    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.
2477 
2478 .seealso: TSStep(), TSAdapt
2479 @*/
2480 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done)
2481 {
2482   PetscErrorCode ierr;
2483 
2484   PetscFunctionBegin;
2485   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2486   PetscValidType(ts,1);
2487   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
2488   if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name);
2489   ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr);
2490   PetscFunctionReturn(0);
2491 }
2492 
2493 #undef __FUNCT__
2494 #define __FUNCT__ "TSSolve"
2495 /*@
2496    TSSolve - Steps the requested number of timesteps.
2497 
2498    Collective on TS
2499 
2500    Input Parameter:
2501 +  ts - the TS context obtained from TSCreate()
2502 -  u - the solution vector  (can be null if TSSetSolution() was used, otherwise must contain the initial conditions)
2503 
2504    Level: beginner
2505 
2506    Notes:
2507    The final time returned by this function may be different from the time of the internally
2508    held state accessible by TSGetSolution() and TSGetTime() because the method may have
2509    stepped over the final time.
2510 
2511 .keywords: TS, timestep, solve
2512 
2513 .seealso: TSCreate(), TSSetSolution(), TSStep()
2514 @*/
2515 PetscErrorCode TSSolve(TS ts,Vec u)
2516 {
2517   PetscBool         flg;
2518   PetscViewer       viewer;
2519   PetscErrorCode    ierr;
2520   PetscViewerFormat format;
2521 
2522   PetscFunctionBegin;
2523   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2524   if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2);
2525   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 */
2526     if (!ts->vec_sol || u == ts->vec_sol) {
2527       Vec y;
2528       ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
2529       ierr = TSSetSolution(ts,y);CHKERRQ(ierr);
2530       ierr = VecDestroy(&y);CHKERRQ(ierr); /* grant ownership */
2531     }
2532     if (u) {
2533       ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr);
2534     }
2535   } else if (u) {
2536     ierr = TSSetSolution(ts,u);CHKERRQ(ierr);
2537   }
2538   ierr = TSSetUp(ts);CHKERRQ(ierr);
2539   /* reset time step and iteration counters */
2540   ts->steps             = 0;
2541   ts->ksp_its           = 0;
2542   ts->snes_its          = 0;
2543   ts->num_snes_failures = 0;
2544   ts->reject            = 0;
2545   ts->reason            = TS_CONVERGED_ITERATING;
2546 
2547   if (ts->ops->solve) {         /* This private interface is transitional and should be removed when all implementations are updated. */
2548     ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr);
2549     ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);
2550 
2551     ts->solvetime = ts->ptime;
2552   } else {
2553     /* steps the requested number of timesteps. */
2554     ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
2555     if (ts->steps >= ts->max_steps)     ts->reason = TS_CONVERGED_ITS;
2556     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
2557     while (!ts->reason) {
2558       ierr = TSStep(ts);CHKERRQ(ierr);
2559       ierr = TSPostStep(ts);CHKERRQ(ierr);
2560       ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
2561     }
2562     if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) {
2563       ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr);
2564 
2565       ts->solvetime = ts->max_time;
2566     } else {
2567       if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);}
2568       ts->solvetime = ts->ptime;
2569     }
2570   }
2571   ierr = TSMonitor(ts,-1,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
2572   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts),((PetscObject)ts)->prefix,"-ts_view",&viewer,&format,&flg);CHKERRQ(ierr);
2573   if (flg && !PetscPreLoadingOn) {
2574     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
2575     ierr = TSView(ts,viewer);CHKERRQ(ierr);
2576     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
2577     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
2578   }
2579   PetscFunctionReturn(0);
2580 }
2581 
2582 #undef __FUNCT__
2583 #define __FUNCT__ "TSMonitor"
2584 /*@
2585    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()
2586 
2587    Collective on TS
2588 
2589    Input Parameters:
2590 +  ts - time stepping context obtained from TSCreate()
2591 .  step - step number that has just completed
2592 .  ptime - model time of the state
2593 -  u - state at the current model time
2594 
2595    Notes:
2596    TSMonitor() is typically used within the time stepping implementations.
2597    Users might call this function when using the TSStep() interface instead of TSSolve().
2598 
2599    Level: advanced
2600 
2601 .keywords: TS, timestep
2602 @*/
2603 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u)
2604 {
2605   PetscErrorCode ierr;
2606   PetscInt       i,n = ts->numbermonitors;
2607 
2608   PetscFunctionBegin;
2609   for (i=0; i<n; i++) {
2610     ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr);
2611   }
2612   PetscFunctionReturn(0);
2613 }
2614 
2615 /* ------------------------------------------------------------------------*/
2616 struct _n_TSMonitorLGCtx {
2617   PetscDrawLG lg;
2618   PetscInt    howoften;  /* when > 0 uses step % howoften, when negative only final solution plotted */
2619   PetscInt    ksp_its,snes_its;
2620 };
2621 
2622 
2623 #undef __FUNCT__
2624 #define __FUNCT__ "TSMonitorLGCtxCreate"
2625 /*@C
2626    TSMonitorLGCtxCreate - Creates a line graph context for use with
2627    TS to monitor the solution process graphically in various ways
2628 
2629    Collective on TS
2630 
2631    Input Parameters:
2632 +  host - the X display to open, or null for the local machine
2633 .  label - the title to put in the title bar
2634 .  x, y - the screen coordinates of the upper left coordinate of the window
2635 .  m, n - the screen width and height in pixels
2636 -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
2637 
2638    Output Parameter:
2639 .  ctx - the context
2640 
2641    Options Database Key:
2642 +  -ts_monitor_lg_timestep - automatically sets line graph monitor
2643 .  -ts_monitor_lg_solution -
2644 .  -ts_monitor_lg_error -
2645 .  -ts_monitor_lg_ksp_iterations -
2646 .  -ts_monitor_lg_snes_iterations -
2647 -  -lg_indicate_data_points <true,false> - indicate the data points (at each time step) on the plot; default is true
2648 
2649    Notes:
2650    Use TSMonitorLGCtxDestroy() to destroy.
2651 
2652    Level: intermediate
2653 
2654 .keywords: TS, monitor, line graph, residual, seealso
2655 
2656 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError()
2657 
2658 @*/
2659 PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
2660 {
2661   PetscDraw      win;
2662   PetscErrorCode ierr;
2663   PetscBool      flg = PETSC_TRUE;
2664 
2665   PetscFunctionBegin;
2666   ierr = PetscNew(struct _n_TSMonitorLGCtx,ctx);CHKERRQ(ierr);
2667   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&win);CHKERRQ(ierr);
2668   ierr = PetscDrawSetFromOptions(win);CHKERRQ(ierr);
2669   ierr = PetscDrawLGCreate(win,1,&(*ctx)->lg);CHKERRQ(ierr);
2670   ierr = PetscOptionsGetBool(NULL,"-lg_indicate_data_points",&flg,NULL);CHKERRQ(ierr);
2671   if (flg) {
2672     ierr = PetscDrawLGIndicateDataPoints((*ctx)->lg);CHKERRQ(ierr);
2673   }
2674   ierr = PetscLogObjectParent((*ctx)->lg,win);CHKERRQ(ierr);
2675   (*ctx)->howoften = howoften;
2676   PetscFunctionReturn(0);
2677 }
2678 
2679 #undef __FUNCT__
2680 #define __FUNCT__ "TSMonitorLGTimeStep"
2681 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
2682 {
2683   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
2684   PetscReal      x   = ptime,y;
2685   PetscErrorCode ierr;
2686 
2687   PetscFunctionBegin;
2688   if (!n) {
2689     PetscDrawAxis axis;
2690     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
2691     ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time","Time step");CHKERRQ(ierr);
2692     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
2693   }
2694   ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr);
2695   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
2696   if (((ctx->howoften > 0) && (!(n % ctx->howoften))) || ((ctx->howoften == -1) && (n == -1))) {
2697     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
2698   }
2699   PetscFunctionReturn(0);
2700 }
2701 
2702 #undef __FUNCT__
2703 #define __FUNCT__ "TSMonitorLGCtxDestroy"
2704 /*@C
2705    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
2706    with TSMonitorLGCtxCreate().
2707 
2708    Collective on TSMonitorLGCtx
2709 
2710    Input Parameter:
2711 .  ctx - the monitor context
2712 
2713    Level: intermediate
2714 
2715 .keywords: TS, monitor, line graph, destroy
2716 
2717 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep();
2718 @*/
2719 PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
2720 {
2721   PetscDraw      draw;
2722   PetscErrorCode ierr;
2723 
2724   PetscFunctionBegin;
2725   ierr = PetscDrawLGGetDraw((*ctx)->lg,&draw);CHKERRQ(ierr);
2726   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
2727   ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr);
2728   ierr = PetscFree(*ctx);CHKERRQ(ierr);
2729   PetscFunctionReturn(0);
2730 }
2731 
2732 #undef __FUNCT__
2733 #define __FUNCT__ "TSGetTime"
2734 /*@
2735    TSGetTime - Gets the time of the most recently completed step.
2736 
2737    Not Collective
2738 
2739    Input Parameter:
2740 .  ts - the TS context obtained from TSCreate()
2741 
2742    Output Parameter:
2743 .  t  - the current time
2744 
2745    Level: beginner
2746 
2747    Note:
2748    When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(),
2749    TSSetPreStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated.
2750 
2751 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
2752 
2753 .keywords: TS, get, time
2754 @*/
2755 PetscErrorCode  TSGetTime(TS ts,PetscReal *t)
2756 {
2757   PetscFunctionBegin;
2758   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2759   PetscValidRealPointer(t,2);
2760   *t = ts->ptime;
2761   PetscFunctionReturn(0);
2762 }
2763 
2764 #undef __FUNCT__
2765 #define __FUNCT__ "TSSetTime"
2766 /*@
2767    TSSetTime - Allows one to reset the time.
2768 
2769    Logically Collective on TS
2770 
2771    Input Parameters:
2772 +  ts - the TS context obtained from TSCreate()
2773 -  time - the time
2774 
2775    Level: intermediate
2776 
2777 .seealso: TSGetTime(), TSSetDuration()
2778 
2779 .keywords: TS, set, time
2780 @*/
2781 PetscErrorCode  TSSetTime(TS ts, PetscReal t)
2782 {
2783   PetscFunctionBegin;
2784   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2785   PetscValidLogicalCollectiveReal(ts,t,2);
2786   ts->ptime = t;
2787   PetscFunctionReturn(0);
2788 }
2789 
2790 #undef __FUNCT__
2791 #define __FUNCT__ "TSSetOptionsPrefix"
2792 /*@C
2793    TSSetOptionsPrefix - Sets the prefix used for searching for all
2794    TS options in the database.
2795 
2796    Logically Collective on TS
2797 
2798    Input Parameter:
2799 +  ts     - The TS context
2800 -  prefix - The prefix to prepend to all option names
2801 
2802    Notes:
2803    A hyphen (-) must NOT be given at the beginning of the prefix name.
2804    The first character of all runtime options is AUTOMATICALLY the
2805    hyphen.
2806 
2807    Level: advanced
2808 
2809 .keywords: TS, set, options, prefix, database
2810 
2811 .seealso: TSSetFromOptions()
2812 
2813 @*/
2814 PetscErrorCode  TSSetOptionsPrefix(TS ts,const char prefix[])
2815 {
2816   PetscErrorCode ierr;
2817   SNES           snes;
2818 
2819   PetscFunctionBegin;
2820   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2821   ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2822   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2823   ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr);
2824   PetscFunctionReturn(0);
2825 }
2826 
2827 
2828 #undef __FUNCT__
2829 #define __FUNCT__ "TSAppendOptionsPrefix"
2830 /*@C
2831    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
2832    TS options in the database.
2833 
2834    Logically Collective on TS
2835 
2836    Input Parameter:
2837 +  ts     - The TS context
2838 -  prefix - The prefix to prepend to all option names
2839 
2840    Notes:
2841    A hyphen (-) must NOT be given at the beginning of the prefix name.
2842    The first character of all runtime options is AUTOMATICALLY the
2843    hyphen.
2844 
2845    Level: advanced
2846 
2847 .keywords: TS, append, options, prefix, database
2848 
2849 .seealso: TSGetOptionsPrefix()
2850 
2851 @*/
2852 PetscErrorCode  TSAppendOptionsPrefix(TS ts,const char prefix[])
2853 {
2854   PetscErrorCode ierr;
2855   SNES           snes;
2856 
2857   PetscFunctionBegin;
2858   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2859   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2860   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2861   ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr);
2862   PetscFunctionReturn(0);
2863 }
2864 
2865 #undef __FUNCT__
2866 #define __FUNCT__ "TSGetOptionsPrefix"
2867 /*@C
2868    TSGetOptionsPrefix - Sets the prefix used for searching for all
2869    TS options in the database.
2870 
2871    Not Collective
2872 
2873    Input Parameter:
2874 .  ts - The TS context
2875 
2876    Output Parameter:
2877 .  prefix - A pointer to the prefix string used
2878 
2879    Notes: On the fortran side, the user should pass in a string 'prifix' of
2880    sufficient length to hold the prefix.
2881 
2882    Level: intermediate
2883 
2884 .keywords: TS, get, options, prefix, database
2885 
2886 .seealso: TSAppendOptionsPrefix()
2887 @*/
2888 PetscErrorCode  TSGetOptionsPrefix(TS ts,const char *prefix[])
2889 {
2890   PetscErrorCode ierr;
2891 
2892   PetscFunctionBegin;
2893   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2894   PetscValidPointer(prefix,2);
2895   ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2896   PetscFunctionReturn(0);
2897 }
2898 
2899 #undef __FUNCT__
2900 #define __FUNCT__ "TSGetRHSJacobian"
2901 /*@C
2902    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
2903 
2904    Not Collective, but parallel objects are returned if TS is parallel
2905 
2906    Input Parameter:
2907 .  ts  - The TS context obtained from TSCreate()
2908 
2909    Output Parameters:
2910 +  J   - The Jacobian J of F, where U_t = G(U,t)
2911 .  M   - The preconditioner matrix, usually the same as J
2912 .  func - Function to compute the Jacobian of the RHS
2913 -  ctx - User-defined context for Jacobian evaluation routine
2914 
2915    Notes: You can pass in NULL for any return argument you do not need.
2916 
2917    Level: intermediate
2918 
2919 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
2920 
2921 .keywords: TS, timestep, get, matrix, Jacobian
2922 @*/
2923 PetscErrorCode  TSGetRHSJacobian(TS ts,Mat *J,Mat *M,TSRHSJacobian *func,void **ctx)
2924 {
2925   PetscErrorCode ierr;
2926   SNES           snes;
2927   DM             dm;
2928 
2929   PetscFunctionBegin;
2930   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2931   ierr = SNESGetJacobian(snes,J,M,NULL,NULL);CHKERRQ(ierr);
2932   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2933   ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr);
2934   PetscFunctionReturn(0);
2935 }
2936 
2937 #undef __FUNCT__
2938 #define __FUNCT__ "TSGetIJacobian"
2939 /*@C
2940    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
2941 
2942    Not Collective, but parallel objects are returned if TS is parallel
2943 
2944    Input Parameter:
2945 .  ts  - The TS context obtained from TSCreate()
2946 
2947    Output Parameters:
2948 +  A   - The Jacobian of F(t,U,U_t)
2949 .  B   - The preconditioner matrix, often the same as A
2950 .  f   - The function to compute the matrices
2951 - ctx - User-defined context for Jacobian evaluation routine
2952 
2953    Notes: You can pass in NULL for any return argument you do not need.
2954 
2955    Level: advanced
2956 
2957 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
2958 
2959 .keywords: TS, timestep, get, matrix, Jacobian
2960 @*/
2961 PetscErrorCode  TSGetIJacobian(TS ts,Mat *A,Mat *B,TSIJacobian *f,void **ctx)
2962 {
2963   PetscErrorCode ierr;
2964   SNES           snes;
2965   DM             dm;
2966 
2967   PetscFunctionBegin;
2968   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2969   ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
2970   ierr = SNESGetJacobian(snes,A,B,NULL,NULL);CHKERRQ(ierr);
2971   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2972   ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr);
2973   PetscFunctionReturn(0);
2974 }
2975 
2976 
2977 #undef __FUNCT__
2978 #define __FUNCT__ "TSMonitorDrawSolution"
2979 /*@C
2980    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
2981    VecView() for the solution at each timestep
2982 
2983    Collective on TS
2984 
2985    Input Parameters:
2986 +  ts - the TS context
2987 .  step - current time-step
2988 .  ptime - current time
2989 -  dummy - either a viewer or NULL
2990 
2991    Options Database:
2992 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
2993 
2994    Notes: the initial solution and current solution are not displayed with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
2995        will look bad
2996 
2997    Level: intermediate
2998 
2999 .keywords: TS,  vector, monitor, view
3000 
3001 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3002 @*/
3003 PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
3004 {
3005   PetscErrorCode   ierr;
3006   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
3007   PetscDraw        draw;
3008 
3009   PetscFunctionBegin;
3010   if (!step && ictx->showinitial) {
3011     if (!ictx->initialsolution) {
3012       ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr);
3013     }
3014     ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr);
3015   }
3016   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften)) && (step > -1)) || ((ictx->howoften == -1) && (step == -1)))) PetscFunctionReturn(0);
3017 
3018   if (ictx->showinitial) {
3019     PetscReal pause;
3020     ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr);
3021     ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr);
3022     ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr);
3023     ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr);
3024     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr);
3025   }
3026   ierr = VecView(u,ictx->viewer);CHKERRQ(ierr);
3027   if (ictx->showtimestepandtime) {
3028     PetscReal xl,yl,xr,yr,tw,w,h;
3029     char      time[32];
3030     size_t    len;
3031 
3032     ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
3033     ierr = PetscSNPrintf(time,32,"Timestep %d Time %f",(int)step,(double)ptime);CHKERRQ(ierr);
3034     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
3035     ierr =  PetscStrlen(time,&len);CHKERRQ(ierr);
3036     ierr = PetscDrawStringGetSize(draw,&tw,NULL);CHKERRQ(ierr);
3037     w    = xl + .5*(xr - xl) - .5*len*tw;
3038     h    = yl + .95*(yr - yl);
3039     ierr = PetscDrawString(draw,w,h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
3040     ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
3041   }
3042 
3043   if (ictx->showinitial) {
3044     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr);
3045   }
3046   PetscFunctionReturn(0);
3047 }
3048 
3049 #undef __FUNCT__
3050 #define __FUNCT__ "TSMonitorDrawSolutionPhase"
3051 /*@C
3052    TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram
3053 
3054    Collective on TS
3055 
3056    Input Parameters:
3057 +  ts - the TS context
3058 .  step - current time-step
3059 .  ptime - current time
3060 -  dummy - either a viewer or NULL
3061 
3062    Level: intermediate
3063 
3064 .keywords: TS,  vector, monitor, view
3065 
3066 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3067 @*/
3068 PetscErrorCode  TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
3069 {
3070   PetscErrorCode    ierr;
3071   TSMonitorDrawCtx  ictx = (TSMonitorDrawCtx)dummy;
3072   PetscDraw         draw;
3073   MPI_Comm          comm;
3074   PetscInt          n;
3075   PetscMPIInt       size;
3076   PetscReal         xl,yl,xr,yr,tw,w,h;
3077   char              time[32];
3078   size_t            len;
3079   const PetscScalar *U;
3080 
3081   PetscFunctionBegin;
3082   ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr);
3083   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
3084   if (size != 1) SETERRQ(comm,PETSC_ERR_SUP,"Only allowed for sequential runs");
3085   ierr = VecGetSize(u,&n);CHKERRQ(ierr);
3086   if (n != 2) SETERRQ(comm,PETSC_ERR_SUP,"Only for ODEs with two unknowns");
3087 
3088   ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
3089 
3090   ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr);
3091   ierr = PetscDrawAxisGetLimits(ictx->axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr);
3092   if ((U[0] < xl) || (U[1] < yl) || (U[0] > xr) || (U[1] > yr)) {
3093       ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr);
3094       PetscFunctionReturn(0);
3095   }
3096   if (!step) ictx->color++;
3097   ierr = PetscDrawPoint(draw,PetscRealPart(U[0]),PetscRealPart(U[1]),ictx->color);CHKERRQ(ierr);
3098   ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr);
3099 
3100   if (ictx->showtimestepandtime) {
3101     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
3102     ierr = PetscSNPrintf(time,32,"Timestep %d Time %f",(int)step,(double)ptime);CHKERRQ(ierr);
3103     ierr = PetscStrlen(time,&len);CHKERRQ(ierr);
3104     ierr = PetscDrawStringGetSize(draw,&tw,NULL);CHKERRQ(ierr);
3105     w    = xl + .5*(xr - xl) - .5*len*tw;
3106     h    = yl + .95*(yr - yl);
3107     ierr = PetscDrawString(draw,w,h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
3108   }
3109   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
3110   PetscFunctionReturn(0);
3111 }
3112 
3113 
3114 #undef __FUNCT__
3115 #define __FUNCT__ "TSMonitorDrawCtxDestroy"
3116 /*@C
3117    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
3118 
3119    Collective on TS
3120 
3121    Input Parameters:
3122 .    ctx - the monitor context
3123 
3124    Level: intermediate
3125 
3126 .keywords: TS,  vector, monitor, view
3127 
3128 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError()
3129 @*/
3130 PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
3131 {
3132   PetscErrorCode ierr;
3133 
3134   PetscFunctionBegin;
3135   ierr = PetscDrawAxisDestroy(&(*ictx)->axis);CHKERRQ(ierr);
3136   ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr);
3137   ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr);
3138   ierr = PetscFree(*ictx);CHKERRQ(ierr);
3139   PetscFunctionReturn(0);
3140 }
3141 
3142 #undef __FUNCT__
3143 #define __FUNCT__ "TSMonitorDrawCtxCreate"
3144 /*@C
3145    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
3146 
3147    Collective on TS
3148 
3149    Input Parameter:
3150 .    ts - time-step context
3151 
3152    Output Patameter:
3153 .    ctx - the monitor context
3154 
3155    Options Database:
3156 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
3157 
3158    Level: intermediate
3159 
3160 .keywords: TS,  vector, monitor, view
3161 
3162 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx()
3163 @*/
3164 PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
3165 {
3166   PetscErrorCode   ierr;
3167 
3168   PetscFunctionBegin;
3169   ierr = PetscNew(struct _n_TSMonitorDrawCtx,ctx);CHKERRQ(ierr);
3170   ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr);
3171   ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr);
3172 
3173   (*ctx)->howoften    = howoften;
3174   (*ctx)->showinitial = PETSC_FALSE;
3175   ierr = PetscOptionsGetBool(NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr);
3176 
3177   (*ctx)->showtimestepandtime = PETSC_FALSE;
3178   ierr = PetscOptionsGetBool(NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr);
3179   (*ctx)->color = PETSC_DRAW_WHITE;
3180   PetscFunctionReturn(0);
3181 }
3182 
3183 #undef __FUNCT__
3184 #define __FUNCT__ "TSMonitorDrawError"
3185 /*@C
3186    TSMonitorDrawError - Monitors progress of the TS solvers by calling
3187    VecView() for the error at each timestep
3188 
3189    Collective on TS
3190 
3191    Input Parameters:
3192 +  ts - the TS context
3193 .  step - current time-step
3194 .  ptime - current time
3195 -  dummy - either a viewer or NULL
3196 
3197    Level: intermediate
3198 
3199 .keywords: TS,  vector, monitor, view
3200 
3201 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3202 @*/
3203 PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
3204 {
3205   PetscErrorCode   ierr;
3206   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
3207   PetscViewer      viewer = ctx->viewer;
3208   Vec              work;
3209 
3210   PetscFunctionBegin;
3211   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1)))) PetscFunctionReturn(0);
3212   ierr = VecDuplicate(u,&work);CHKERRQ(ierr);
3213   ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr);
3214   ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr);
3215   ierr = VecView(work,viewer);CHKERRQ(ierr);
3216   ierr = VecDestroy(&work);CHKERRQ(ierr);
3217   PetscFunctionReturn(0);
3218 }
3219 
3220 #include <petsc-private/dmimpl.h>
3221 #undef __FUNCT__
3222 #define __FUNCT__ "TSSetDM"
3223 /*@
3224    TSSetDM - Sets the DM that may be used by some preconditioners
3225 
3226    Logically Collective on TS and DM
3227 
3228    Input Parameters:
3229 +  ts - the preconditioner context
3230 -  dm - the dm
3231 
3232    Level: intermediate
3233 
3234 
3235 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM()
3236 @*/
3237 PetscErrorCode  TSSetDM(TS ts,DM dm)
3238 {
3239   PetscErrorCode ierr;
3240   SNES           snes;
3241   DMTS           tsdm;
3242 
3243   PetscFunctionBegin;
3244   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3245   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
3246   if (ts->dm) {               /* Move the DMTS context over to the new DM unless the new DM already has one */
3247     if (ts->dm->dmts && !dm->dmts) {
3248       ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr);
3249       ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr);
3250       if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */
3251         tsdm->originaldm = dm;
3252       }
3253     }
3254     ierr = DMDestroy(&ts->dm);CHKERRQ(ierr);
3255   }
3256   ts->dm = dm;
3257 
3258   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3259   ierr = SNESSetDM(snes,dm);CHKERRQ(ierr);
3260   PetscFunctionReturn(0);
3261 }
3262 
3263 #undef __FUNCT__
3264 #define __FUNCT__ "TSGetDM"
3265 /*@
3266    TSGetDM - Gets the DM that may be used by some preconditioners
3267 
3268    Not Collective
3269 
3270    Input Parameter:
3271 . ts - the preconditioner context
3272 
3273    Output Parameter:
3274 .  dm - the dm
3275 
3276    Level: intermediate
3277 
3278 
3279 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM()
3280 @*/
3281 PetscErrorCode  TSGetDM(TS ts,DM *dm)
3282 {
3283   PetscErrorCode ierr;
3284 
3285   PetscFunctionBegin;
3286   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3287   if (!ts->dm) {
3288     ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr);
3289     if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
3290   }
3291   *dm = ts->dm;
3292   PetscFunctionReturn(0);
3293 }
3294 
3295 #undef __FUNCT__
3296 #define __FUNCT__ "SNESTSFormFunction"
3297 /*@
3298    SNESTSFormFunction - Function to evaluate nonlinear residual
3299 
3300    Logically Collective on SNES
3301 
3302    Input Parameter:
3303 + snes - nonlinear solver
3304 . U - the current state at which to evaluate the residual
3305 - ctx - user context, must be a TS
3306 
3307    Output Parameter:
3308 . F - the nonlinear residual
3309 
3310    Notes:
3311    This function is not normally called by users and is automatically registered with the SNES used by TS.
3312    It is most frequently passed to MatFDColoringSetFunction().
3313 
3314    Level: advanced
3315 
3316 .seealso: SNESSetFunction(), MatFDColoringSetFunction()
3317 @*/
3318 PetscErrorCode  SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx)
3319 {
3320   TS             ts = (TS)ctx;
3321   PetscErrorCode ierr;
3322 
3323   PetscFunctionBegin;
3324   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3325   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
3326   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
3327   PetscValidHeaderSpecific(ts,TS_CLASSID,4);
3328   ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr);
3329   PetscFunctionReturn(0);
3330 }
3331 
3332 #undef __FUNCT__
3333 #define __FUNCT__ "SNESTSFormJacobian"
3334 /*@
3335    SNESTSFormJacobian - Function to evaluate the Jacobian
3336 
3337    Collective on SNES
3338 
3339    Input Parameter:
3340 + snes - nonlinear solver
3341 . U - the current state at which to evaluate the residual
3342 - ctx - user context, must be a TS
3343 
3344    Output Parameter:
3345 + A - the Jacobian
3346 . B - the preconditioning matrix (may be the same as A)
3347 - flag - indicates any structure change in the matrix
3348 
3349    Notes:
3350    This function is not normally called by users and is automatically registered with the SNES used by TS.
3351 
3352    Level: developer
3353 
3354 .seealso: SNESSetJacobian()
3355 @*/
3356 PetscErrorCode  SNESTSFormJacobian(SNES snes,Vec U,Mat *A,Mat *B,MatStructure *flag,void *ctx)
3357 {
3358   TS             ts = (TS)ctx;
3359   PetscErrorCode ierr;
3360 
3361   PetscFunctionBegin;
3362   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3363   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
3364   PetscValidPointer(A,3);
3365   PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
3366   PetscValidPointer(B,4);
3367   PetscValidHeaderSpecific(*B,MAT_CLASSID,4);
3368   PetscValidPointer(flag,5);
3369   PetscValidHeaderSpecific(ts,TS_CLASSID,6);
3370   ierr = (ts->ops->snesjacobian)(snes,U,A,B,flag,ts);CHKERRQ(ierr);
3371   PetscFunctionReturn(0);
3372 }
3373 
3374 #undef __FUNCT__
3375 #define __FUNCT__ "TSComputeRHSFunctionLinear"
3376 /*@C
3377    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only
3378 
3379    Collective on TS
3380 
3381    Input Arguments:
3382 +  ts - time stepping context
3383 .  t - time at which to evaluate
3384 .  U - state at which to evaluate
3385 -  ctx - context
3386 
3387    Output Arguments:
3388 .  F - right hand side
3389 
3390    Level: intermediate
3391 
3392    Notes:
3393    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
3394    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().
3395 
3396 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
3397 @*/
3398 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx)
3399 {
3400   PetscErrorCode ierr;
3401   Mat            Arhs,Brhs;
3402   MatStructure   flg2;
3403 
3404   PetscFunctionBegin;
3405   ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
3406   ierr = TSComputeRHSJacobian(ts,t,U,&Arhs,&Brhs,&flg2);CHKERRQ(ierr);
3407   ierr = MatMult(Arhs,U,F);CHKERRQ(ierr);
3408   PetscFunctionReturn(0);
3409 }
3410 
3411 #undef __FUNCT__
3412 #define __FUNCT__ "TSComputeRHSJacobianConstant"
3413 /*@C
3414    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
3415 
3416    Collective on TS
3417 
3418    Input Arguments:
3419 +  ts - time stepping context
3420 .  t - time at which to evaluate
3421 .  U - state at which to evaluate
3422 -  ctx - context
3423 
3424    Output Arguments:
3425 +  A - pointer to operator
3426 .  B - pointer to preconditioning matrix
3427 -  flg - matrix structure flag
3428 
3429    Level: intermediate
3430 
3431    Notes:
3432    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.
3433 
3434 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear()
3435 @*/
3436 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat *A,Mat *B,MatStructure *flg,void *ctx)
3437 {
3438   PetscFunctionBegin;
3439   *flg = SAME_PRECONDITIONER;
3440   PetscFunctionReturn(0);
3441 }
3442 
3443 #undef __FUNCT__
3444 #define __FUNCT__ "TSComputeIFunctionLinear"
3445 /*@C
3446    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
3447 
3448    Collective on TS
3449 
3450    Input Arguments:
3451 +  ts - time stepping context
3452 .  t - time at which to evaluate
3453 .  U - state at which to evaluate
3454 .  Udot - time derivative of state vector
3455 -  ctx - context
3456 
3457    Output Arguments:
3458 .  F - left hand side
3459 
3460    Level: intermediate
3461 
3462    Notes:
3463    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
3464    user is required to write their own TSComputeIFunction.
3465    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
3466    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().
3467 
3468 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant()
3469 @*/
3470 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx)
3471 {
3472   PetscErrorCode ierr;
3473   Mat            A,B;
3474   MatStructure   flg2;
3475 
3476   PetscFunctionBegin;
3477   ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr);
3478   ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,&A,&B,&flg2,PETSC_TRUE);CHKERRQ(ierr);
3479   ierr = MatMult(A,Udot,F);CHKERRQ(ierr);
3480   PetscFunctionReturn(0);
3481 }
3482 
3483 #undef __FUNCT__
3484 #define __FUNCT__ "TSComputeIJacobianConstant"
3485 /*@C
3486    TSComputeIJacobianConstant - Reuses a Jacobian that is time-independent.
3487 
3488    Collective on TS
3489 
3490    Input Arguments:
3491 +  ts - time stepping context
3492 .  t - time at which to evaluate
3493 .  U - state at which to evaluate
3494 .  Udot - time derivative of state vector
3495 .  shift - shift to apply
3496 -  ctx - context
3497 
3498    Output Arguments:
3499 +  A - pointer to operator
3500 .  B - pointer to preconditioning matrix
3501 -  flg - matrix structure flag
3502 
3503    Level: intermediate
3504 
3505    Notes:
3506    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.
3507 
3508 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear()
3509 @*/
3510 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,void *ctx)
3511 {
3512   PetscFunctionBegin;
3513   *flg = SAME_PRECONDITIONER;
3514   PetscFunctionReturn(0);
3515 }
3516 #undef __FUNCT__
3517 #define __FUNCT__ "TSGetEquationType"
3518 /*@
3519    TSGetEquationType - Gets the type of the equation that TS is solving.
3520 
3521    Not Collective
3522 
3523    Input Parameter:
3524 .  ts - the TS context
3525 
3526    Output Parameter:
3527 .  equation_type - see TSEquatioType
3528 
3529    Level: beginner
3530 
3531 .keywords: TS, equation type
3532 
3533 .seealso: TSSetEquationType(), TSEquationType
3534 @*/
3535 PetscErrorCode  TSGetEquationType(TS ts,TSEquationType *equation_type)
3536 {
3537   PetscFunctionBegin;
3538   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3539   PetscValidPointer(equation_type,2);
3540   *equation_type = ts->equation_type;
3541   PetscFunctionReturn(0);
3542 }
3543 
3544 #undef __FUNCT__
3545 #define __FUNCT__ "TSSetEquationType"
3546 /*@
3547    TSSetEquationType - Sets the type of the equation that TS is solving.
3548 
3549    Not Collective
3550 
3551    Input Parameter:
3552 +  ts - the TS context
3553 .  equation_type - see TSEquatioType
3554 
3555    Level: advanced
3556 
3557 .keywords: TS, equation type
3558 
3559 .seealso: TSGetEquationType(), TSEquationType
3560 @*/
3561 PetscErrorCode  TSSetEquationType(TS ts,TSEquationType equation_type)
3562 {
3563   PetscFunctionBegin;
3564   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3565   ts->equation_type = equation_type;
3566   PetscFunctionReturn(0);
3567 }
3568 
3569 #undef __FUNCT__
3570 #define __FUNCT__ "TSGetConvergedReason"
3571 /*@
3572    TSGetConvergedReason - Gets the reason the TS iteration was stopped.
3573 
3574    Not Collective
3575 
3576    Input Parameter:
3577 .  ts - the TS context
3578 
3579    Output Parameter:
3580 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
3581             manual pages for the individual convergence tests for complete lists
3582 
3583    Level: beginner
3584 
3585    Notes:
3586    Can only be called after the call to TSSolve() is complete.
3587 
3588 .keywords: TS, nonlinear, set, convergence, test
3589 
3590 .seealso: TSSetConvergenceTest(), TSConvergedReason
3591 @*/
3592 PetscErrorCode  TSGetConvergedReason(TS ts,TSConvergedReason *reason)
3593 {
3594   PetscFunctionBegin;
3595   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3596   PetscValidPointer(reason,2);
3597   *reason = ts->reason;
3598   PetscFunctionReturn(0);
3599 }
3600 
3601 #undef __FUNCT__
3602 #define __FUNCT__ "TSSetConvergedReason"
3603 /*@
3604    TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve.
3605 
3606    Not Collective
3607 
3608    Input Parameter:
3609 +  ts - the TS context
3610 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
3611             manual pages for the individual convergence tests for complete lists
3612 
3613    Level: advanced
3614 
3615    Notes:
3616    Can only be called during TSSolve() is active.
3617 
3618 .keywords: TS, nonlinear, set, convergence, test
3619 
3620 .seealso: TSConvergedReason
3621 @*/
3622 PetscErrorCode  TSSetConvergedReason(TS ts,TSConvergedReason reason)
3623 {
3624   PetscFunctionBegin;
3625   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3626   ts->reason = reason;
3627   PetscFunctionReturn(0);
3628 }
3629 
3630 #undef __FUNCT__
3631 #define __FUNCT__ "TSGetSolveTime"
3632 /*@
3633    TSGetSolveTime - Gets the time after a call to TSSolve()
3634 
3635    Not Collective
3636 
3637    Input Parameter:
3638 .  ts - the TS context
3639 
3640    Output Parameter:
3641 .  ftime - the final time. This time should correspond to the final time set with TSSetDuration()
3642 
3643    Level: beginner
3644 
3645    Notes:
3646    Can only be called after the call to TSSolve() is complete.
3647 
3648 .keywords: TS, nonlinear, set, convergence, test
3649 
3650 .seealso: TSSetConvergenceTest(), TSConvergedReason
3651 @*/
3652 PetscErrorCode  TSGetSolveTime(TS ts,PetscReal *ftime)
3653 {
3654   PetscFunctionBegin;
3655   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3656   PetscValidPointer(ftime,2);
3657   *ftime = ts->solvetime;
3658   PetscFunctionReturn(0);
3659 }
3660 
3661 #undef __FUNCT__
3662 #define __FUNCT__ "TSGetSNESIterations"
3663 /*@
3664    TSGetSNESIterations - Gets the total number of nonlinear iterations
3665    used by the time integrator.
3666 
3667    Not Collective
3668 
3669    Input Parameter:
3670 .  ts - TS context
3671 
3672    Output Parameter:
3673 .  nits - number of nonlinear iterations
3674 
3675    Notes:
3676    This counter is reset to zero for each successive call to TSSolve().
3677 
3678    Level: intermediate
3679 
3680 .keywords: TS, get, number, nonlinear, iterations
3681 
3682 .seealso:  TSGetKSPIterations()
3683 @*/
3684 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits)
3685 {
3686   PetscFunctionBegin;
3687   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3688   PetscValidIntPointer(nits,2);
3689   *nits = ts->snes_its;
3690   PetscFunctionReturn(0);
3691 }
3692 
3693 #undef __FUNCT__
3694 #define __FUNCT__ "TSGetKSPIterations"
3695 /*@
3696    TSGetKSPIterations - Gets the total number of linear iterations
3697    used by the time integrator.
3698 
3699    Not Collective
3700 
3701    Input Parameter:
3702 .  ts - TS context
3703 
3704    Output Parameter:
3705 .  lits - number of linear iterations
3706 
3707    Notes:
3708    This counter is reset to zero for each successive call to TSSolve().
3709 
3710    Level: intermediate
3711 
3712 .keywords: TS, get, number, linear, iterations
3713 
3714 .seealso:  TSGetSNESIterations(), SNESGetKSPIterations()
3715 @*/
3716 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits)
3717 {
3718   PetscFunctionBegin;
3719   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3720   PetscValidIntPointer(lits,2);
3721   *lits = ts->ksp_its;
3722   PetscFunctionReturn(0);
3723 }
3724 
3725 #undef __FUNCT__
3726 #define __FUNCT__ "TSGetStepRejections"
3727 /*@
3728    TSGetStepRejections - Gets the total number of rejected steps.
3729 
3730    Not Collective
3731 
3732    Input Parameter:
3733 .  ts - TS context
3734 
3735    Output Parameter:
3736 .  rejects - number of steps rejected
3737 
3738    Notes:
3739    This counter is reset to zero for each successive call to TSSolve().
3740 
3741    Level: intermediate
3742 
3743 .keywords: TS, get, number
3744 
3745 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails()
3746 @*/
3747 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects)
3748 {
3749   PetscFunctionBegin;
3750   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3751   PetscValidIntPointer(rejects,2);
3752   *rejects = ts->reject;
3753   PetscFunctionReturn(0);
3754 }
3755 
3756 #undef __FUNCT__
3757 #define __FUNCT__ "TSGetSNESFailures"
3758 /*@
3759    TSGetSNESFailures - Gets the total number of failed SNES solves
3760 
3761    Not Collective
3762 
3763    Input Parameter:
3764 .  ts - TS context
3765 
3766    Output Parameter:
3767 .  fails - number of failed nonlinear solves
3768 
3769    Notes:
3770    This counter is reset to zero for each successive call to TSSolve().
3771 
3772    Level: intermediate
3773 
3774 .keywords: TS, get, number
3775 
3776 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures()
3777 @*/
3778 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails)
3779 {
3780   PetscFunctionBegin;
3781   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3782   PetscValidIntPointer(fails,2);
3783   *fails = ts->num_snes_failures;
3784   PetscFunctionReturn(0);
3785 }
3786 
3787 #undef __FUNCT__
3788 #define __FUNCT__ "TSSetMaxStepRejections"
3789 /*@
3790    TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails
3791 
3792    Not Collective
3793 
3794    Input Parameter:
3795 +  ts - TS context
3796 -  rejects - maximum number of rejected steps, pass -1 for unlimited
3797 
3798    Notes:
3799    The counter is reset to zero for each step
3800 
3801    Options Database Key:
3802  .  -ts_max_reject - Maximum number of step rejections before a step fails
3803 
3804    Level: intermediate
3805 
3806 .keywords: TS, set, maximum, number
3807 
3808 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
3809 @*/
3810 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects)
3811 {
3812   PetscFunctionBegin;
3813   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3814   ts->max_reject = rejects;
3815   PetscFunctionReturn(0);
3816 }
3817 
3818 #undef __FUNCT__
3819 #define __FUNCT__ "TSSetMaxSNESFailures"
3820 /*@
3821    TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves
3822 
3823    Not Collective
3824 
3825    Input Parameter:
3826 +  ts - TS context
3827 -  fails - maximum number of failed nonlinear solves, pass -1 for unlimited
3828 
3829    Notes:
3830    The counter is reset to zero for each successive call to TSSolve().
3831 
3832    Options Database Key:
3833  .  -ts_max_snes_failures - Maximum number of nonlinear solve failures
3834 
3835    Level: intermediate
3836 
3837 .keywords: TS, set, maximum, number
3838 
3839 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason()
3840 @*/
3841 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails)
3842 {
3843   PetscFunctionBegin;
3844   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3845   ts->max_snes_failures = fails;
3846   PetscFunctionReturn(0);
3847 }
3848 
3849 #undef __FUNCT__
3850 #define __FUNCT__ "TSSetErrorIfStepFails()"
3851 /*@
3852    TSSetErrorIfStepFails - Error if no step succeeds
3853 
3854    Not Collective
3855 
3856    Input Parameter:
3857 +  ts - TS context
3858 -  err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure
3859 
3860    Options Database Key:
3861  .  -ts_error_if_step_fails - Error if no step succeeds
3862 
3863    Level: intermediate
3864 
3865 .keywords: TS, set, error
3866 
3867 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
3868 @*/
3869 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err)
3870 {
3871   PetscFunctionBegin;
3872   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3873   ts->errorifstepfailed = err;
3874   PetscFunctionReturn(0);
3875 }
3876 
3877 #undef __FUNCT__
3878 #define __FUNCT__ "TSMonitorSolutionBinary"
3879 /*@C
3880    TSMonitorSolutionBinary - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file
3881 
3882    Collective on TS
3883 
3884    Input Parameters:
3885 +  ts - the TS context
3886 .  step - current time-step
3887 .  ptime - current time
3888 .  u - current state
3889 -  viewer - binary viewer
3890 
3891    Level: intermediate
3892 
3893 .keywords: TS,  vector, monitor, view
3894 
3895 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3896 @*/
3897 PetscErrorCode  TSMonitorSolutionBinary(TS ts,PetscInt step,PetscReal ptime,Vec u,void *viewer)
3898 {
3899   PetscErrorCode ierr;
3900   PetscViewer    v = (PetscViewer)viewer;
3901 
3902   PetscFunctionBegin;
3903   ierr = VecView(u,v);CHKERRQ(ierr);
3904   PetscFunctionReturn(0);
3905 }
3906 
3907 #undef __FUNCT__
3908 #define __FUNCT__ "TSMonitorSolutionVTK"
3909 /*@C
3910    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
3911 
3912    Collective on TS
3913 
3914    Input Parameters:
3915 +  ts - the TS context
3916 .  step - current time-step
3917 .  ptime - current time
3918 .  u - current state
3919 -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
3920 
3921    Level: intermediate
3922 
3923    Notes:
3924    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.
3925    These are named according to the file name template.
3926 
3927    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().
3928 
3929 .keywords: TS,  vector, monitor, view
3930 
3931 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3932 @*/
3933 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
3934 {
3935   PetscErrorCode ierr;
3936   char           filename[PETSC_MAX_PATH_LEN];
3937   PetscViewer    viewer;
3938 
3939   PetscFunctionBegin;
3940   ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr);
3941   ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr);
3942   ierr = VecView(u,viewer);CHKERRQ(ierr);
3943   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3944   PetscFunctionReturn(0);
3945 }
3946 
3947 #undef __FUNCT__
3948 #define __FUNCT__ "TSMonitorSolutionVTKDestroy"
3949 /*@C
3950    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
3951 
3952    Collective on TS
3953 
3954    Input Parameters:
3955 .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
3956 
3957    Level: intermediate
3958 
3959    Note:
3960    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
3961 
3962 .keywords: TS,  vector, monitor, view
3963 
3964 .seealso: TSMonitorSet(), TSMonitorSolutionVTK()
3965 @*/
3966 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
3967 {
3968   PetscErrorCode ierr;
3969 
3970   PetscFunctionBegin;
3971   ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr);
3972   PetscFunctionReturn(0);
3973 }
3974 
3975 #undef __FUNCT__
3976 #define __FUNCT__ "TSGetTSAdapt"
3977 /*@
3978    TSGetTSAdapt - Get the adaptive controller context for the current method
3979 
3980    Collective on TS if controller has not been created yet
3981 
3982    Input Arguments:
3983 .  ts - time stepping context
3984 
3985    Output Arguments:
3986 .  adapt - adaptive controller
3987 
3988    Level: intermediate
3989 
3990 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose()
3991 @*/
3992 PetscErrorCode TSGetTSAdapt(TS ts,TSAdapt *adapt)
3993 {
3994   PetscErrorCode ierr;
3995 
3996   PetscFunctionBegin;
3997   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3998   PetscValidPointer(adapt,2);
3999   if (!ts->adapt) {
4000     ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr);
4001     ierr = PetscLogObjectParent(ts,ts->adapt);CHKERRQ(ierr);
4002     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr);
4003   }
4004   *adapt = ts->adapt;
4005   PetscFunctionReturn(0);
4006 }
4007 
4008 #undef __FUNCT__
4009 #define __FUNCT__ "TSSetTolerances"
4010 /*@
4011    TSSetTolerances - Set tolerances for local truncation error when using adaptive controller
4012 
4013    Logically Collective
4014 
4015    Input Arguments:
4016 +  ts - time integration context
4017 .  atol - scalar absolute tolerances, PETSC_DECIDE to leave current value
4018 .  vatol - vector of absolute tolerances or NULL, used in preference to atol if present
4019 .  rtol - scalar relative tolerances, PETSC_DECIDE to leave current value
4020 -  vrtol - vector of relative tolerances or NULL, used in preference to atol if present
4021 
4022    Level: beginner
4023 
4024 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances()
4025 @*/
4026 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol)
4027 {
4028   PetscErrorCode ierr;
4029 
4030   PetscFunctionBegin;
4031   if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol;
4032   if (vatol) {
4033     ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr);
4034     ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
4035 
4036     ts->vatol = vatol;
4037   }
4038   if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol;
4039   if (vrtol) {
4040     ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr);
4041     ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
4042 
4043     ts->vrtol = vrtol;
4044   }
4045   PetscFunctionReturn(0);
4046 }
4047 
4048 #undef __FUNCT__
4049 #define __FUNCT__ "TSGetTolerances"
4050 /*@
4051    TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
4052 
4053    Logically Collective
4054 
4055    Input Arguments:
4056 .  ts - time integration context
4057 
4058    Output Arguments:
4059 +  atol - scalar absolute tolerances, NULL to ignore
4060 .  vatol - vector of absolute tolerances, NULL to ignore
4061 .  rtol - scalar relative tolerances, NULL to ignore
4062 -  vrtol - vector of relative tolerances, NULL to ignore
4063 
4064    Level: beginner
4065 
4066 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances()
4067 @*/
4068 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol)
4069 {
4070   PetscFunctionBegin;
4071   if (atol)  *atol  = ts->atol;
4072   if (vatol) *vatol = ts->vatol;
4073   if (rtol)  *rtol  = ts->rtol;
4074   if (vrtol) *vrtol = ts->vrtol;
4075   PetscFunctionReturn(0);
4076 }
4077 
4078 #undef __FUNCT__
4079 #define __FUNCT__ "TSErrorNormWRMS"
4080 /*@
4081    TSErrorNormWRMS - compute a weighted norm of the difference between a vector and the current state
4082 
4083    Collective on TS
4084 
4085    Input Arguments:
4086 +  ts - time stepping context
4087 -  Y - state vector to be compared to ts->vec_sol
4088 
4089    Output Arguments:
4090 .  norm - weighted norm, a value of 1.0 is considered small
4091 
4092    Level: developer
4093 
4094 .seealso: TSSetTolerances()
4095 @*/
4096 PetscErrorCode TSErrorNormWRMS(TS ts,Vec Y,PetscReal *norm)
4097 {
4098   PetscErrorCode    ierr;
4099   PetscInt          i,n,N;
4100   const PetscScalar *u,*y;
4101   Vec               U;
4102   PetscReal         sum,gsum;
4103 
4104   PetscFunctionBegin;
4105   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4106   PetscValidHeaderSpecific(Y,VEC_CLASSID,2);
4107   PetscValidPointer(norm,3);
4108   U = ts->vec_sol;
4109   PetscCheckSameTypeAndComm(U,1,Y,2);
4110   if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"Y cannot be the TS solution vector");
4111 
4112   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
4113   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
4114   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
4115   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
4116   sum  = 0.;
4117   if (ts->vatol && ts->vrtol) {
4118     const PetscScalar *atol,*rtol;
4119     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
4120     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
4121     for (i=0; i<n; i++) {
4122       PetscReal tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
4123       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
4124     }
4125     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
4126     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
4127   } else if (ts->vatol) {       /* vector atol, scalar rtol */
4128     const PetscScalar *atol;
4129     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
4130     for (i=0; i<n; i++) {
4131       PetscReal tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
4132       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
4133     }
4134     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
4135   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
4136     const PetscScalar *rtol;
4137     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
4138     for (i=0; i<n; i++) {
4139       PetscReal tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
4140       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
4141     }
4142     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
4143   } else {                      /* scalar atol, scalar rtol */
4144     for (i=0; i<n; i++) {
4145       PetscReal tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
4146       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
4147     }
4148   }
4149   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
4150   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
4151 
4152   ierr  = MPI_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
4153   *norm = PetscSqrtReal(gsum / N);
4154   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
4155   PetscFunctionReturn(0);
4156 }
4157 
4158 #undef __FUNCT__
4159 #define __FUNCT__ "TSSetCFLTimeLocal"
4160 /*@
4161    TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
4162 
4163    Logically Collective on TS
4164 
4165    Input Arguments:
4166 +  ts - time stepping context
4167 -  cfltime - maximum stable time step if using forward Euler (value can be different on each process)
4168 
4169    Note:
4170    After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
4171 
4172    Level: intermediate
4173 
4174 .seealso: TSGetCFLTime(), TSADAPTCFL
4175 @*/
4176 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime)
4177 {
4178   PetscFunctionBegin;
4179   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4180   ts->cfltime_local = cfltime;
4181   ts->cfltime       = -1.;
4182   PetscFunctionReturn(0);
4183 }
4184 
4185 #undef __FUNCT__
4186 #define __FUNCT__ "TSGetCFLTime"
4187 /*@
4188    TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
4189 
4190    Collective on TS
4191 
4192    Input Arguments:
4193 .  ts - time stepping context
4194 
4195    Output Arguments:
4196 .  cfltime - maximum stable time step for forward Euler
4197 
4198    Level: advanced
4199 
4200 .seealso: TSSetCFLTimeLocal()
4201 @*/
4202 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime)
4203 {
4204   PetscErrorCode ierr;
4205 
4206   PetscFunctionBegin;
4207   if (ts->cfltime < 0) {
4208     ierr = MPI_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
4209   }
4210   *cfltime = ts->cfltime;
4211   PetscFunctionReturn(0);
4212 }
4213 
4214 #undef __FUNCT__
4215 #define __FUNCT__ "TSVISetVariableBounds"
4216 /*@
4217    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
4218 
4219    Input Parameters:
4220 .  ts   - the TS context.
4221 .  xl   - lower bound.
4222 .  xu   - upper bound.
4223 
4224    Notes:
4225    If this routine is not called then the lower and upper bounds are set to
4226    SNES_VI_NINF and SNES_VI_INF respectively during SNESSetUp().
4227 
4228    Level: advanced
4229 
4230 @*/
4231 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
4232 {
4233   PetscErrorCode ierr;
4234   SNES           snes;
4235 
4236   PetscFunctionBegin;
4237   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4238   ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr);
4239   PetscFunctionReturn(0);
4240 }
4241 
4242 #if defined(PETSC_HAVE_MATLAB_ENGINE)
4243 #include <mex.h>
4244 
4245 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext;
4246 
4247 #undef __FUNCT__
4248 #define __FUNCT__ "TSComputeFunction_Matlab"
4249 /*
4250    TSComputeFunction_Matlab - Calls the function that has been set with
4251                          TSSetFunctionMatlab().
4252 
4253    Collective on TS
4254 
4255    Input Parameters:
4256 +  snes - the TS context
4257 -  u - input vector
4258 
4259    Output Parameter:
4260 .  y - function vector, as set by TSSetFunction()
4261 
4262    Notes:
4263    TSComputeFunction() is typically used within nonlinear solvers
4264    implementations, so most users would not generally call this routine
4265    themselves.
4266 
4267    Level: developer
4268 
4269 .keywords: TS, nonlinear, compute, function
4270 
4271 .seealso: TSSetFunction(), TSGetFunction()
4272 */
4273 PetscErrorCode  TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx)
4274 {
4275   PetscErrorCode  ierr;
4276   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
4277   int             nlhs  = 1,nrhs = 7;
4278   mxArray         *plhs[1],*prhs[7];
4279   long long int   lx = 0,lxdot = 0,ly = 0,ls = 0;
4280 
4281   PetscFunctionBegin;
4282   PetscValidHeaderSpecific(snes,TS_CLASSID,1);
4283   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
4284   PetscValidHeaderSpecific(udot,VEC_CLASSID,4);
4285   PetscValidHeaderSpecific(y,VEC_CLASSID,5);
4286   PetscCheckSameComm(snes,1,u,3);
4287   PetscCheckSameComm(snes,1,y,5);
4288 
4289   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4290   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
4291   ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr);
4292   ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr);
4293 
4294   prhs[0] =  mxCreateDoubleScalar((double)ls);
4295   prhs[1] =  mxCreateDoubleScalar(time);
4296   prhs[2] =  mxCreateDoubleScalar((double)lx);
4297   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
4298   prhs[4] =  mxCreateDoubleScalar((double)ly);
4299   prhs[5] =  mxCreateString(sctx->funcname);
4300   prhs[6] =  sctx->ctx;
4301   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr);
4302   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4303   mxDestroyArray(prhs[0]);
4304   mxDestroyArray(prhs[1]);
4305   mxDestroyArray(prhs[2]);
4306   mxDestroyArray(prhs[3]);
4307   mxDestroyArray(prhs[4]);
4308   mxDestroyArray(prhs[5]);
4309   mxDestroyArray(plhs[0]);
4310   PetscFunctionReturn(0);
4311 }
4312 
4313 
4314 #undef __FUNCT__
4315 #define __FUNCT__ "TSSetFunctionMatlab"
4316 /*
4317    TSSetFunctionMatlab - Sets the function evaluation routine and function
4318    vector for use by the TS routines in solving ODEs
4319    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
4320 
4321    Logically Collective on TS
4322 
4323    Input Parameters:
4324 +  ts - the TS context
4325 -  func - function evaluation routine
4326 
4327    Calling sequence of func:
4328 $    func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx);
4329 
4330    Level: beginner
4331 
4332 .keywords: TS, nonlinear, set, function
4333 
4334 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
4335 */
4336 PetscErrorCode  TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx)
4337 {
4338   PetscErrorCode  ierr;
4339   TSMatlabContext *sctx;
4340 
4341   PetscFunctionBegin;
4342   /* currently sctx is memory bleed */
4343   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
4344   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4345   /*
4346      This should work, but it doesn't
4347   sctx->ctx = ctx;
4348   mexMakeArrayPersistent(sctx->ctx);
4349   */
4350   sctx->ctx = mxDuplicateArray(ctx);
4351 
4352   ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr);
4353   PetscFunctionReturn(0);
4354 }
4355 
4356 #undef __FUNCT__
4357 #define __FUNCT__ "TSComputeJacobian_Matlab"
4358 /*
4359    TSComputeJacobian_Matlab - Calls the function that has been set with
4360                          TSSetJacobianMatlab().
4361 
4362    Collective on TS
4363 
4364    Input Parameters:
4365 +  ts - the TS context
4366 .  u - input vector
4367 .  A, B - the matrices
4368 -  ctx - user context
4369 
4370    Output Parameter:
4371 .  flag - structure of the matrix
4372 
4373    Level: developer
4374 
4375 .keywords: TS, nonlinear, compute, function
4376 
4377 .seealso: TSSetFunction(), TSGetFunction()
4378 @*/
4379 PetscErrorCode  TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flag, void *ctx)
4380 {
4381   PetscErrorCode  ierr;
4382   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
4383   int             nlhs  = 2,nrhs = 9;
4384   mxArray         *plhs[2],*prhs[9];
4385   long long int   lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0;
4386 
4387   PetscFunctionBegin;
4388   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4389   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
4390 
4391   /* call Matlab function in ctx with arguments u and y */
4392 
4393   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
4394   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
4395   ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr);
4396   ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr);
4397   ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr);
4398 
4399   prhs[0] =  mxCreateDoubleScalar((double)ls);
4400   prhs[1] =  mxCreateDoubleScalar((double)time);
4401   prhs[2] =  mxCreateDoubleScalar((double)lx);
4402   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
4403   prhs[4] =  mxCreateDoubleScalar((double)shift);
4404   prhs[5] =  mxCreateDoubleScalar((double)lA);
4405   prhs[6] =  mxCreateDoubleScalar((double)lB);
4406   prhs[7] =  mxCreateString(sctx->funcname);
4407   prhs[8] =  sctx->ctx;
4408   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr);
4409   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4410   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
4411   mxDestroyArray(prhs[0]);
4412   mxDestroyArray(prhs[1]);
4413   mxDestroyArray(prhs[2]);
4414   mxDestroyArray(prhs[3]);
4415   mxDestroyArray(prhs[4]);
4416   mxDestroyArray(prhs[5]);
4417   mxDestroyArray(prhs[6]);
4418   mxDestroyArray(prhs[7]);
4419   mxDestroyArray(plhs[0]);
4420   mxDestroyArray(plhs[1]);
4421   PetscFunctionReturn(0);
4422 }
4423 
4424 
4425 #undef __FUNCT__
4426 #define __FUNCT__ "TSSetJacobianMatlab"
4427 /*
4428    TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
4429    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
4430 
4431    Logically Collective on TS
4432 
4433    Input Parameters:
4434 +  ts - the TS context
4435 .  A,B - Jacobian matrices
4436 .  func - function evaluation routine
4437 -  ctx - user context
4438 
4439    Calling sequence of func:
4440 $    flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx);
4441 
4442 
4443    Level: developer
4444 
4445 .keywords: TS, nonlinear, set, function
4446 
4447 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
4448 */
4449 PetscErrorCode  TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx)
4450 {
4451   PetscErrorCode  ierr;
4452   TSMatlabContext *sctx;
4453 
4454   PetscFunctionBegin;
4455   /* currently sctx is memory bleed */
4456   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
4457   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4458   /*
4459      This should work, but it doesn't
4460   sctx->ctx = ctx;
4461   mexMakeArrayPersistent(sctx->ctx);
4462   */
4463   sctx->ctx = mxDuplicateArray(ctx);
4464 
4465   ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
4466   PetscFunctionReturn(0);
4467 }
4468 
4469 #undef __FUNCT__
4470 #define __FUNCT__ "TSMonitor_Matlab"
4471 /*
4472    TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab().
4473 
4474    Collective on TS
4475 
4476 .seealso: TSSetFunction(), TSGetFunction()
4477 @*/
4478 PetscErrorCode  TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx)
4479 {
4480   PetscErrorCode  ierr;
4481   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
4482   int             nlhs  = 1,nrhs = 6;
4483   mxArray         *plhs[1],*prhs[6];
4484   long long int   lx = 0,ls = 0;
4485 
4486   PetscFunctionBegin;
4487   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4488   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
4489 
4490   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
4491   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
4492 
4493   prhs[0] =  mxCreateDoubleScalar((double)ls);
4494   prhs[1] =  mxCreateDoubleScalar((double)it);
4495   prhs[2] =  mxCreateDoubleScalar((double)time);
4496   prhs[3] =  mxCreateDoubleScalar((double)lx);
4497   prhs[4] =  mxCreateString(sctx->funcname);
4498   prhs[5] =  sctx->ctx;
4499   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr);
4500   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4501   mxDestroyArray(prhs[0]);
4502   mxDestroyArray(prhs[1]);
4503   mxDestroyArray(prhs[2]);
4504   mxDestroyArray(prhs[3]);
4505   mxDestroyArray(prhs[4]);
4506   mxDestroyArray(plhs[0]);
4507   PetscFunctionReturn(0);
4508 }
4509 
4510 
4511 #undef __FUNCT__
4512 #define __FUNCT__ "TSMonitorSetMatlab"
4513 /*
4514    TSMonitorSetMatlab - Sets the monitor function from Matlab
4515 
4516    Level: developer
4517 
4518 .keywords: TS, nonlinear, set, function
4519 
4520 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
4521 */
4522 PetscErrorCode  TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx)
4523 {
4524   PetscErrorCode  ierr;
4525   TSMatlabContext *sctx;
4526 
4527   PetscFunctionBegin;
4528   /* currently sctx is memory bleed */
4529   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
4530   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4531   /*
4532      This should work, but it doesn't
4533   sctx->ctx = ctx;
4534   mexMakeArrayPersistent(sctx->ctx);
4535   */
4536   sctx->ctx = mxDuplicateArray(ctx);
4537 
4538   ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr);
4539   PetscFunctionReturn(0);
4540 }
4541 #endif
4542 
4543 
4544 
4545 #undef __FUNCT__
4546 #define __FUNCT__ "TSMonitorLGSolution"
4547 /*@C
4548    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
4549        in a time based line graph
4550 
4551    Collective on TS
4552 
4553    Input Parameters:
4554 +  ts - the TS context
4555 .  step - current time-step
4556 .  ptime - current time
4557 -  lg - a line graph object
4558 
4559    Level: intermediate
4560 
4561     Notes: each process in a parallel run displays its component solutions in a separate window
4562 
4563 .keywords: TS,  vector, monitor, view
4564 
4565 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4566 @*/
4567 PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4568 {
4569   PetscErrorCode    ierr;
4570   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
4571   const PetscScalar *yy;
4572   PetscInt          dim;
4573 
4574   PetscFunctionBegin;
4575   if (!step) {
4576     PetscDrawAxis axis;
4577     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4578     ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr);
4579     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
4580     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
4581     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4582   }
4583   ierr = VecGetArrayRead(u,&yy);CHKERRQ(ierr);
4584 #if defined(PETSC_USE_COMPLEX)
4585   {
4586     PetscReal *yreal;
4587     PetscInt  i,n;
4588     ierr = VecGetLocalSize(u,&n);CHKERRQ(ierr);
4589     ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr);
4590     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
4591     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
4592     ierr = PetscFree(yreal);CHKERRQ(ierr);
4593   }
4594 #else
4595   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
4596 #endif
4597   ierr = VecRestoreArrayRead(u,&yy);CHKERRQ(ierr);
4598   if (((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1))) {
4599     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4600   }
4601   PetscFunctionReturn(0);
4602 }
4603 
4604 #undef __FUNCT__
4605 #define __FUNCT__ "TSMonitorLGError"
4606 /*@C
4607    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector
4608        in a time based line graph
4609 
4610    Collective on TS
4611 
4612    Input Parameters:
4613 +  ts - the TS context
4614 .  step - current time-step
4615 .  ptime - current time
4616 -  lg - a line graph object
4617 
4618    Level: intermediate
4619 
4620    Notes:
4621    Only for sequential solves.
4622 
4623    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
4624 
4625    Options Database Keys:
4626 .  -ts_monitor_lg_error - create a graphical monitor of error history
4627 
4628 .keywords: TS,  vector, monitor, view
4629 
4630 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
4631 @*/
4632 PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4633 {
4634   PetscErrorCode    ierr;
4635   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
4636   const PetscScalar *yy;
4637   Vec               y;
4638   PetscInt          dim;
4639 
4640   PetscFunctionBegin;
4641   if (!step) {
4642     PetscDrawAxis axis;
4643     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4644     ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr);
4645     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
4646     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
4647     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4648   }
4649   ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
4650   ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr);
4651   ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr);
4652   ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr);
4653 #if defined(PETSC_USE_COMPLEX)
4654   {
4655     PetscReal *yreal;
4656     PetscInt  i,n;
4657     ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr);
4658     ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr);
4659     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
4660     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
4661     ierr = PetscFree(yreal);CHKERRQ(ierr);
4662   }
4663 #else
4664   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
4665 #endif
4666   ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr);
4667   ierr = VecDestroy(&y);CHKERRQ(ierr);
4668   if (((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1))) {
4669     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4670   }
4671   PetscFunctionReturn(0);
4672 }
4673 
4674 #undef __FUNCT__
4675 #define __FUNCT__ "TSMonitorLGSNESIterations"
4676 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
4677 {
4678   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
4679   PetscReal      x   = ptime,y;
4680   PetscErrorCode ierr;
4681   PetscInt       its;
4682 
4683   PetscFunctionBegin;
4684   if (!n) {
4685     PetscDrawAxis axis;
4686 
4687     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4688     ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr);
4689     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4690 
4691     ctx->snes_its = 0;
4692   }
4693   ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr);
4694   y    = its - ctx->snes_its;
4695   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
4696   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
4697     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4698   }
4699   ctx->snes_its = its;
4700   PetscFunctionReturn(0);
4701 }
4702 
4703 #undef __FUNCT__
4704 #define __FUNCT__ "TSMonitorLGKSPIterations"
4705 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
4706 {
4707   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
4708   PetscReal      x   = ptime,y;
4709   PetscErrorCode ierr;
4710   PetscInt       its;
4711 
4712   PetscFunctionBegin;
4713   if (!n) {
4714     PetscDrawAxis axis;
4715 
4716     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4717     ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr);
4718     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4719 
4720     ctx->ksp_its = 0;
4721   }
4722   ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr);
4723   y    = its - ctx->ksp_its;
4724   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
4725   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
4726     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4727   }
4728   ctx->ksp_its = its;
4729   PetscFunctionReturn(0);
4730 }
4731 
4732 #undef __FUNCT__
4733 #define __FUNCT__ "TSComputeLinearStability"
4734 /*@
4735    TSComputeLinearStability - computes the linear stability function at a point
4736 
4737    Collective on TS and Vec
4738 
4739    Input Parameters:
4740 +  ts - the TS context
4741 -  xr,xi - real and imaginary part of input arguments
4742 
4743    Output Parameters:
4744 .  yr,yi - real and imaginary part of function value
4745 
4746    Level: developer
4747 
4748 .keywords: TS, compute
4749 
4750 .seealso: TSSetRHSFunction(), TSComputeIFunction()
4751 @*/
4752 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi)
4753 {
4754   PetscErrorCode ierr;
4755 
4756   PetscFunctionBegin;
4757   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4758   if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method");
4759   ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr);
4760   PetscFunctionReturn(0);
4761 }
4762