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