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