xref: /petsc/src/ts/interface/ts.c (revision 82c86c8f8a181c1295b98e018a5a0771744eccf1)
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(PetscObjectComm((PetscObject)ts),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(PetscObjectComm((PetscObject)ts),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(PetscObjectComm((PetscObject)ts),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(PetscObjectComm((PetscObject)ts),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(PetscObjectComm((PetscObject)ts),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_(PetscObjectComm((PetscObject)ts));
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(PetscObjectComm((PetscObject)ts),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(PetscObjectComm((PetscObject)ts),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(PetscObjectComm((PetscObject)ts),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(PetscObjectComm((PetscObject)ts),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(PetscObjectComm((PetscObject)ts),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(PetscObjectComm((PetscObject)ts),&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(PetscObjectComm((PetscObject)ts),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(PetscObjectComm((PetscObject)ts),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(PetscObjectComm((PetscObject)ts),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(PetscObjectComm((PetscObject)ts),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(PetscObjectComm((PetscObject)ts),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(PetscObjectComm((PetscObject)ts),&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 #include <petscdraw.h>
1216 #undef __FUNCT__
1217 #define __FUNCT__ "TSView"
1218 /*@C
1219     TSView - Prints the TS data structure.
1220 
1221     Collective on TS
1222 
1223     Input Parameters:
1224 +   ts - the TS context obtained from TSCreate()
1225 -   viewer - visualization context
1226 
1227     Options Database Key:
1228 .   -ts_view - calls TSView() at end of TSStep()
1229 
1230     Notes:
1231     The available visualization contexts include
1232 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
1233 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
1234          output where only the first processor opens
1235          the file.  All other processors send their
1236          data to the first processor to print.
1237 
1238     The user can open an alternative visualization context with
1239     PetscViewerASCIIOpen() - output to a specified file.
1240 
1241     Level: beginner
1242 
1243 .keywords: TS, timestep, view
1244 
1245 .seealso: PetscViewerASCIIOpen()
1246 @*/
1247 PetscErrorCode  TSView(TS ts,PetscViewer viewer)
1248 {
1249   PetscErrorCode ierr;
1250   TSType         type;
1251   PetscBool      iascii,isstring,isundials,isbinary,isdraw;
1252   DMTS           sdm;
1253 
1254   PetscFunctionBegin;
1255   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1256   if (!viewer) {
1257     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ts),&viewer);CHKERRQ(ierr);
1258   }
1259   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1260   PetscCheckSameComm(ts,1,viewer,2);
1261 
1262   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1263   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
1264   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1265   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
1266   if (iascii) {
1267     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer,"TS Object");CHKERRQ(ierr);
1268     ierr = PetscViewerASCIIPrintf(viewer,"  maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr);
1269     ierr = PetscViewerASCIIPrintf(viewer,"  maximum time=%G\n",ts->max_time);CHKERRQ(ierr);
1270     if (ts->problem_type == TS_NONLINEAR) {
1271       ierr = PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solver iterations=%D\n",ts->snes_its);CHKERRQ(ierr);
1272       ierr = PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solve failures=%D\n",ts->num_snes_failures);CHKERRQ(ierr);
1273     }
1274     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",ts->ksp_its);CHKERRQ(ierr);
1275     ierr = PetscViewerASCIIPrintf(viewer,"  total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr);
1276     ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr);
1277     ierr = DMTSView(sdm,viewer);CHKERRQ(ierr);
1278     if (ts->ops->view) {
1279       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1280       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1281       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1282     }
1283   } else if (isstring) {
1284     ierr = TSGetType(ts,&type);CHKERRQ(ierr);
1285     ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr);
1286   } else if (isbinary) {
1287     PetscInt    classid = TS_FILE_CLASSID;
1288     MPI_Comm    comm;
1289     PetscMPIInt rank;
1290     char        type[256];
1291 
1292     ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr);
1293     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
1294     if (!rank) {
1295       ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
1296       ierr = PetscStrncpy(type,((PetscObject)ts)->type_name,256);CHKERRQ(ierr);
1297       ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
1298     }
1299     if (ts->ops->view) {
1300       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1301     }
1302     ierr = DMView(ts->dm,viewer);CHKERRQ(ierr);
1303     ierr = VecView(ts->vec_sol,viewer);CHKERRQ(ierr);
1304     ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr);
1305     ierr = DMTSView(sdm,viewer);CHKERRQ(ierr);
1306   } else if (isdraw) {
1307     PetscDraw draw;
1308     char      str[36];
1309     PetscReal x,y,bottom,h;
1310 
1311     ierr   = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1312     ierr   = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
1313     ierr   = PetscStrcpy(str,"TS: ");CHKERRQ(ierr);
1314     ierr   = PetscStrcat(str,((PetscObject)ts)->type_name);CHKERRQ(ierr);
1315     ierr   = PetscDrawBoxedString(draw,x,y,PETSC_DRAW_BLACK,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr);
1316     bottom = y - h;
1317     ierr   = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
1318     if (ts->ops->view) {
1319       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1320     }
1321     ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr);
1322   }
1323   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1324   ierr = PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr);
1325   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1326   PetscFunctionReturn(0);
1327 }
1328 
1329 
1330 #undef __FUNCT__
1331 #define __FUNCT__ "TSSetApplicationContext"
1332 /*@
1333    TSSetApplicationContext - Sets an optional user-defined context for
1334    the timesteppers.
1335 
1336    Logically Collective on TS
1337 
1338    Input Parameters:
1339 +  ts - the TS context obtained from TSCreate()
1340 -  usrP - optional user context
1341 
1342    Level: intermediate
1343 
1344 .keywords: TS, timestep, set, application, context
1345 
1346 .seealso: TSGetApplicationContext()
1347 @*/
1348 PetscErrorCode  TSSetApplicationContext(TS ts,void *usrP)
1349 {
1350   PetscFunctionBegin;
1351   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1352   ts->user = usrP;
1353   PetscFunctionReturn(0);
1354 }
1355 
1356 #undef __FUNCT__
1357 #define __FUNCT__ "TSGetApplicationContext"
1358 /*@
1359     TSGetApplicationContext - Gets the user-defined context for the
1360     timestepper.
1361 
1362     Not Collective
1363 
1364     Input Parameter:
1365 .   ts - the TS context obtained from TSCreate()
1366 
1367     Output Parameter:
1368 .   usrP - user context
1369 
1370     Level: intermediate
1371 
1372 .keywords: TS, timestep, get, application, context
1373 
1374 .seealso: TSSetApplicationContext()
1375 @*/
1376 PetscErrorCode  TSGetApplicationContext(TS ts,void *usrP)
1377 {
1378   PetscFunctionBegin;
1379   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1380   *(void**)usrP = ts->user;
1381   PetscFunctionReturn(0);
1382 }
1383 
1384 #undef __FUNCT__
1385 #define __FUNCT__ "TSGetTimeStepNumber"
1386 /*@
1387    TSGetTimeStepNumber - Gets the number of time steps completed.
1388 
1389    Not Collective
1390 
1391    Input Parameter:
1392 .  ts - the TS context obtained from TSCreate()
1393 
1394    Output Parameter:
1395 .  iter - number of steps completed so far
1396 
1397    Level: intermediate
1398 
1399 .keywords: TS, timestep, get, iteration, number
1400 .seealso: TSGetTime(), TSGetTimeStep(), TSSetPreStep(), TSSetPreStage(), TSSetPostStep()
1401 @*/
1402 PetscErrorCode  TSGetTimeStepNumber(TS ts,PetscInt *iter)
1403 {
1404   PetscFunctionBegin;
1405   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1406   PetscValidIntPointer(iter,2);
1407   *iter = ts->steps;
1408   PetscFunctionReturn(0);
1409 }
1410 
1411 #undef __FUNCT__
1412 #define __FUNCT__ "TSSetInitialTimeStep"
1413 /*@
1414    TSSetInitialTimeStep - Sets the initial timestep to be used,
1415    as well as the initial time.
1416 
1417    Logically Collective on TS
1418 
1419    Input Parameters:
1420 +  ts - the TS context obtained from TSCreate()
1421 .  initial_time - the initial time
1422 -  time_step - the size of the timestep
1423 
1424    Level: intermediate
1425 
1426 .seealso: TSSetTimeStep(), TSGetTimeStep()
1427 
1428 .keywords: TS, set, initial, timestep
1429 @*/
1430 PetscErrorCode  TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step)
1431 {
1432   PetscErrorCode ierr;
1433 
1434   PetscFunctionBegin;
1435   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1436   ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr);
1437   ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr);
1438   PetscFunctionReturn(0);
1439 }
1440 
1441 #undef __FUNCT__
1442 #define __FUNCT__ "TSSetTimeStep"
1443 /*@
1444    TSSetTimeStep - Allows one to reset the timestep at any time,
1445    useful for simple pseudo-timestepping codes.
1446 
1447    Logically Collective on TS
1448 
1449    Input Parameters:
1450 +  ts - the TS context obtained from TSCreate()
1451 -  time_step - the size of the timestep
1452 
1453    Level: intermediate
1454 
1455 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
1456 
1457 .keywords: TS, set, timestep
1458 @*/
1459 PetscErrorCode  TSSetTimeStep(TS ts,PetscReal time_step)
1460 {
1461   PetscFunctionBegin;
1462   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1463   PetscValidLogicalCollectiveReal(ts,time_step,2);
1464   ts->time_step      = time_step;
1465   ts->time_step_orig = time_step;
1466   PetscFunctionReturn(0);
1467 }
1468 
1469 #undef __FUNCT__
1470 #define __FUNCT__ "TSSetExactFinalTime"
1471 /*@
1472    TSSetExactFinalTime - Determines whether to adapt the final time step to
1473      match the exact final time, interpolate solution to the exact final time,
1474      or just return at the final time TS computed.
1475 
1476   Logically Collective on TS
1477 
1478    Input Parameter:
1479 +   ts - the time-step context
1480 -   eftopt - exact final time option
1481 
1482    Level: beginner
1483 
1484 .seealso: TSExactFinalTimeOption
1485 @*/
1486 PetscErrorCode  TSSetExactFinalTime(TS ts,TSExactFinalTimeOption eftopt)
1487 {
1488   PetscFunctionBegin;
1489   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1490   PetscValidLogicalCollectiveEnum(ts,eftopt,2);
1491   ts->exact_final_time = eftopt;
1492   PetscFunctionReturn(0);
1493 }
1494 
1495 #undef __FUNCT__
1496 #define __FUNCT__ "TSGetTimeStep"
1497 /*@
1498    TSGetTimeStep - Gets the current timestep size.
1499 
1500    Not Collective
1501 
1502    Input Parameter:
1503 .  ts - the TS context obtained from TSCreate()
1504 
1505    Output Parameter:
1506 .  dt - the current timestep size
1507 
1508    Level: intermediate
1509 
1510 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
1511 
1512 .keywords: TS, get, timestep
1513 @*/
1514 PetscErrorCode  TSGetTimeStep(TS ts,PetscReal *dt)
1515 {
1516   PetscFunctionBegin;
1517   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1518   PetscValidRealPointer(dt,2);
1519   *dt = ts->time_step;
1520   PetscFunctionReturn(0);
1521 }
1522 
1523 #undef __FUNCT__
1524 #define __FUNCT__ "TSGetSolution"
1525 /*@
1526    TSGetSolution - Returns the solution at the present timestep. It
1527    is valid to call this routine inside the function that you are evaluating
1528    in order to move to the new timestep. This vector not changed until
1529    the solution at the next timestep has been calculated.
1530 
1531    Not Collective, but Vec returned is parallel if TS is parallel
1532 
1533    Input Parameter:
1534 .  ts - the TS context obtained from TSCreate()
1535 
1536    Output Parameter:
1537 .  v - the vector containing the solution
1538 
1539    Level: intermediate
1540 
1541 .seealso: TSGetTimeStep()
1542 
1543 .keywords: TS, timestep, get, solution
1544 @*/
1545 PetscErrorCode  TSGetSolution(TS ts,Vec *v)
1546 {
1547   PetscFunctionBegin;
1548   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1549   PetscValidPointer(v,2);
1550   *v = ts->vec_sol;
1551   PetscFunctionReturn(0);
1552 }
1553 
1554 /* ----- Routines to initialize and destroy a timestepper ---- */
1555 #undef __FUNCT__
1556 #define __FUNCT__ "TSSetProblemType"
1557 /*@
1558   TSSetProblemType - Sets the type of problem to be solved.
1559 
1560   Not collective
1561 
1562   Input Parameters:
1563 + ts   - The TS
1564 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1565 .vb
1566          U_t - A U = 0      (linear)
1567          U_t - A(t) U = 0   (linear)
1568          F(t,U,U_t) = 0     (nonlinear)
1569 .ve
1570 
1571    Level: beginner
1572 
1573 .keywords: TS, problem type
1574 .seealso: TSSetUp(), TSProblemType, TS
1575 @*/
1576 PetscErrorCode  TSSetProblemType(TS ts, TSProblemType type)
1577 {
1578   PetscErrorCode ierr;
1579 
1580   PetscFunctionBegin;
1581   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1582   ts->problem_type = type;
1583   if (type == TS_LINEAR) {
1584     SNES snes;
1585     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1586     ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);
1587   }
1588   PetscFunctionReturn(0);
1589 }
1590 
1591 #undef __FUNCT__
1592 #define __FUNCT__ "TSGetProblemType"
1593 /*@C
1594   TSGetProblemType - Gets the type of problem to be solved.
1595 
1596   Not collective
1597 
1598   Input Parameter:
1599 . ts   - The TS
1600 
1601   Output Parameter:
1602 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1603 .vb
1604          M U_t = A U
1605          M(t) U_t = A(t) U
1606          F(t,U,U_t)
1607 .ve
1608 
1609    Level: beginner
1610 
1611 .keywords: TS, problem type
1612 .seealso: TSSetUp(), TSProblemType, TS
1613 @*/
1614 PetscErrorCode  TSGetProblemType(TS ts, TSProblemType *type)
1615 {
1616   PetscFunctionBegin;
1617   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1618   PetscValidIntPointer(type,2);
1619   *type = ts->problem_type;
1620   PetscFunctionReturn(0);
1621 }
1622 
1623 #undef __FUNCT__
1624 #define __FUNCT__ "TSSetUp"
1625 /*@
1626    TSSetUp - Sets up the internal data structures for the later use
1627    of a timestepper.
1628 
1629    Collective on TS
1630 
1631    Input Parameter:
1632 .  ts - the TS context obtained from TSCreate()
1633 
1634    Notes:
1635    For basic use of the TS solvers the user need not explicitly call
1636    TSSetUp(), since these actions will automatically occur during
1637    the call to TSStep().  However, if one wishes to control this
1638    phase separately, TSSetUp() should be called after TSCreate()
1639    and optional routines of the form TSSetXXX(), but before TSStep().
1640 
1641    Level: advanced
1642 
1643 .keywords: TS, timestep, setup
1644 
1645 .seealso: TSCreate(), TSStep(), TSDestroy()
1646 @*/
1647 PetscErrorCode  TSSetUp(TS ts)
1648 {
1649   PetscErrorCode ierr;
1650   DM             dm;
1651   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
1652   PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
1653   TSIJacobian    ijac;
1654   TSRHSJacobian  rhsjac;
1655 
1656   PetscFunctionBegin;
1657   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1658   if (ts->setupcalled) PetscFunctionReturn(0);
1659 
1660   if (!((PetscObject)ts)->type_name) {
1661     ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr);
1662   }
1663 
1664   if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first");
1665 
1666   ierr = TSGetTSAdapt(ts,&ts->adapt);CHKERRQ(ierr);
1667 
1668   if (ts->ops->setup) {
1669     ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr);
1670   }
1671 
1672   /* in the case where we've set a DMTSFunction or what have you, we need the default SNESFunction
1673    to be set right but can't do it elsewhere due to the overreliance on ctx=ts.
1674    */
1675   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1676   ierr = DMSNESGetFunction(dm,&func,NULL);CHKERRQ(ierr);
1677   if (!func) {
1678     ierr =DMSNESSetFunction(dm,SNESTSFormFunction,ts);CHKERRQ(ierr);
1679   }
1680   /* if the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it.
1681      Otherwise, the SNES will use coloring internally to form the Jacobian.
1682    */
1683   ierr = DMSNESGetJacobian(dm,&jac,NULL);CHKERRQ(ierr);
1684   ierr = DMTSGetIJacobian(dm,&ijac,NULL);CHKERRQ(ierr);
1685   ierr = DMTSGetRHSJacobian(dm,&rhsjac,NULL);CHKERRQ(ierr);
1686   if (!jac && (ijac || rhsjac)) {
1687     ierr = DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);CHKERRQ(ierr);
1688   }
1689   ts->setupcalled = PETSC_TRUE;
1690   PetscFunctionReturn(0);
1691 }
1692 
1693 #undef __FUNCT__
1694 #define __FUNCT__ "TSReset"
1695 /*@
1696    TSReset - Resets a TS context and removes any allocated Vecs and Mats.
1697 
1698    Collective on TS
1699 
1700    Input Parameter:
1701 .  ts - the TS context obtained from TSCreate()
1702 
1703    Level: beginner
1704 
1705 .keywords: TS, timestep, reset
1706 
1707 .seealso: TSCreate(), TSSetup(), TSDestroy()
1708 @*/
1709 PetscErrorCode  TSReset(TS ts)
1710 {
1711   PetscErrorCode ierr;
1712 
1713   PetscFunctionBegin;
1714   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1715   if (ts->ops->reset) {
1716     ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr);
1717   }
1718   if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);}
1719 
1720   ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr);
1721   ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr);
1722   ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr);
1723   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
1724   ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
1725   ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
1726   ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr);
1727 
1728   ts->setupcalled = PETSC_FALSE;
1729   PetscFunctionReturn(0);
1730 }
1731 
1732 #undef __FUNCT__
1733 #define __FUNCT__ "TSDestroy"
1734 /*@
1735    TSDestroy - Destroys the timestepper context that was created
1736    with TSCreate().
1737 
1738    Collective on TS
1739 
1740    Input Parameter:
1741 .  ts - the TS context obtained from TSCreate()
1742 
1743    Level: beginner
1744 
1745 .keywords: TS, timestepper, destroy
1746 
1747 .seealso: TSCreate(), TSSetUp(), TSSolve()
1748 @*/
1749 PetscErrorCode  TSDestroy(TS *ts)
1750 {
1751   PetscErrorCode ierr;
1752 
1753   PetscFunctionBegin;
1754   if (!*ts) PetscFunctionReturn(0);
1755   PetscValidHeaderSpecific((*ts),TS_CLASSID,1);
1756   if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);}
1757 
1758   ierr = TSReset((*ts));CHKERRQ(ierr);
1759 
1760   /* if memory was published with AMS then destroy it */
1761   ierr = PetscObjectDepublish((*ts));CHKERRQ(ierr);
1762   if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);}
1763 
1764   ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr);
1765   ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr);
1766   ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr);
1767   ierr = TSMonitorCancel((*ts));CHKERRQ(ierr);
1768 
1769   ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr);
1770   PetscFunctionReturn(0);
1771 }
1772 
1773 #undef __FUNCT__
1774 #define __FUNCT__ "TSGetSNES"
1775 /*@
1776    TSGetSNES - Returns the SNES (nonlinear solver) associated with
1777    a TS (timestepper) context. Valid only for nonlinear problems.
1778 
1779    Not Collective, but SNES is parallel if TS is parallel
1780 
1781    Input Parameter:
1782 .  ts - the TS context obtained from TSCreate()
1783 
1784    Output Parameter:
1785 .  snes - the nonlinear solver context
1786 
1787    Notes:
1788    The user can then directly manipulate the SNES context to set various
1789    options, etc.  Likewise, the user can then extract and manipulate the
1790    KSP, KSP, and PC contexts as well.
1791 
1792    TSGetSNES() does not work for integrators that do not use SNES; in
1793    this case TSGetSNES() returns NULL in snes.
1794 
1795    Level: beginner
1796 
1797 .keywords: timestep, get, SNES
1798 @*/
1799 PetscErrorCode  TSGetSNES(TS ts,SNES *snes)
1800 {
1801   PetscErrorCode ierr;
1802 
1803   PetscFunctionBegin;
1804   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1805   PetscValidPointer(snes,2);
1806   if (!ts->snes) {
1807     ierr = SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);CHKERRQ(ierr);
1808     ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr);
1809     ierr = PetscLogObjectParent(ts,ts->snes);CHKERRQ(ierr);
1810     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr);
1811     if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
1812     if (ts->problem_type == TS_LINEAR) {
1813       ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr);
1814     }
1815   }
1816   *snes = ts->snes;
1817   PetscFunctionReturn(0);
1818 }
1819 
1820 #undef __FUNCT__
1821 #define __FUNCT__ "TSSetSNES"
1822 /*@
1823    TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context
1824 
1825    Collective
1826 
1827    Input Parameter:
1828 +  ts - the TS context obtained from TSCreate()
1829 -  snes - the nonlinear solver context
1830 
1831    Notes:
1832    Most users should have the TS created by calling TSGetSNES()
1833 
1834    Level: developer
1835 
1836 .keywords: timestep, set, SNES
1837 @*/
1838 PetscErrorCode TSSetSNES(TS ts,SNES snes)
1839 {
1840   PetscErrorCode ierr;
1841   PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
1842 
1843   PetscFunctionBegin;
1844   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1845   PetscValidHeaderSpecific(snes,SNES_CLASSID,2);
1846   ierr = PetscObjectReference((PetscObject)snes);CHKERRQ(ierr);
1847   ierr = SNESDestroy(&ts->snes);CHKERRQ(ierr);
1848 
1849   ts->snes = snes;
1850 
1851   ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr);
1852   ierr = SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);CHKERRQ(ierr);
1853   if (func == SNESTSFormJacobian) {
1854     ierr = SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);CHKERRQ(ierr);
1855   }
1856   PetscFunctionReturn(0);
1857 }
1858 
1859 #undef __FUNCT__
1860 #define __FUNCT__ "TSGetKSP"
1861 /*@
1862    TSGetKSP - Returns the KSP (linear solver) associated with
1863    a TS (timestepper) context.
1864 
1865    Not Collective, but KSP is parallel if TS is parallel
1866 
1867    Input Parameter:
1868 .  ts - the TS context obtained from TSCreate()
1869 
1870    Output Parameter:
1871 .  ksp - the nonlinear solver context
1872 
1873    Notes:
1874    The user can then directly manipulate the KSP context to set various
1875    options, etc.  Likewise, the user can then extract and manipulate the
1876    KSP and PC contexts as well.
1877 
1878    TSGetKSP() does not work for integrators that do not use KSP;
1879    in this case TSGetKSP() returns NULL in ksp.
1880 
1881    Level: beginner
1882 
1883 .keywords: timestep, get, KSP
1884 @*/
1885 PetscErrorCode  TSGetKSP(TS ts,KSP *ksp)
1886 {
1887   PetscErrorCode ierr;
1888   SNES           snes;
1889 
1890   PetscFunctionBegin;
1891   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1892   PetscValidPointer(ksp,2);
1893   if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first");
1894   if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()");
1895   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1896   ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr);
1897   PetscFunctionReturn(0);
1898 }
1899 
1900 /* ----------- Routines to set solver parameters ---------- */
1901 
1902 #undef __FUNCT__
1903 #define __FUNCT__ "TSGetDuration"
1904 /*@
1905    TSGetDuration - Gets the maximum number of timesteps to use and
1906    maximum time for iteration.
1907 
1908    Not Collective
1909 
1910    Input Parameters:
1911 +  ts       - the TS context obtained from TSCreate()
1912 .  maxsteps - maximum number of iterations to use, or NULL
1913 -  maxtime  - final time to iterate to, or NULL
1914 
1915    Level: intermediate
1916 
1917 .keywords: TS, timestep, get, maximum, iterations, time
1918 @*/
1919 PetscErrorCode  TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
1920 {
1921   PetscFunctionBegin;
1922   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1923   if (maxsteps) {
1924     PetscValidIntPointer(maxsteps,2);
1925     *maxsteps = ts->max_steps;
1926   }
1927   if (maxtime) {
1928     PetscValidScalarPointer(maxtime,3);
1929     *maxtime = ts->max_time;
1930   }
1931   PetscFunctionReturn(0);
1932 }
1933 
1934 #undef __FUNCT__
1935 #define __FUNCT__ "TSSetDuration"
1936 /*@
1937    TSSetDuration - Sets the maximum number of timesteps to use and
1938    maximum time for iteration.
1939 
1940    Logically Collective on TS
1941 
1942    Input Parameters:
1943 +  ts - the TS context obtained from TSCreate()
1944 .  maxsteps - maximum number of iterations to use
1945 -  maxtime - final time to iterate to
1946 
1947    Options Database Keys:
1948 .  -ts_max_steps <maxsteps> - Sets maxsteps
1949 .  -ts_final_time <maxtime> - Sets maxtime
1950 
1951    Notes:
1952    The default maximum number of iterations is 5000. Default time is 5.0
1953 
1954    Level: intermediate
1955 
1956 .keywords: TS, timestep, set, maximum, iterations
1957 
1958 .seealso: TSSetExactFinalTime()
1959 @*/
1960 PetscErrorCode  TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime)
1961 {
1962   PetscFunctionBegin;
1963   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1964   PetscValidLogicalCollectiveInt(ts,maxsteps,2);
1965   PetscValidLogicalCollectiveReal(ts,maxtime,2);
1966   if (maxsteps >= 0) ts->max_steps = maxsteps;
1967   if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime;
1968   PetscFunctionReturn(0);
1969 }
1970 
1971 #undef __FUNCT__
1972 #define __FUNCT__ "TSSetSolution"
1973 /*@
1974    TSSetSolution - Sets the initial solution vector
1975    for use by the TS routines.
1976 
1977    Logically Collective on TS and Vec
1978 
1979    Input Parameters:
1980 +  ts - the TS context obtained from TSCreate()
1981 -  u - the solution vector
1982 
1983    Level: beginner
1984 
1985 .keywords: TS, timestep, set, solution, initial conditions
1986 @*/
1987 PetscErrorCode  TSSetSolution(TS ts,Vec u)
1988 {
1989   PetscErrorCode ierr;
1990   DM             dm;
1991 
1992   PetscFunctionBegin;
1993   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1994   PetscValidHeaderSpecific(u,VEC_CLASSID,2);
1995   ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr);
1996   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
1997 
1998   ts->vec_sol = u;
1999 
2000   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2001   ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr);
2002   PetscFunctionReturn(0);
2003 }
2004 
2005 #undef __FUNCT__
2006 #define __FUNCT__ "TSSetPreStep"
2007 /*@C
2008   TSSetPreStep - Sets the general-purpose function
2009   called once at the beginning of each time step.
2010 
2011   Logically Collective on TS
2012 
2013   Input Parameters:
2014 + ts   - The TS context obtained from TSCreate()
2015 - func - The function
2016 
2017   Calling sequence of func:
2018 . func (TS ts);
2019 
2020   Level: intermediate
2021 
2022   Note:
2023   If a step is rejected, TSStep() will call this routine again before each attempt.
2024   The last completed time step number can be queried using TSGetTimeStepNumber(), the
2025   size of the step being attempted can be obtained using TSGetTimeStep().
2026 
2027 .keywords: TS, timestep
2028 .seealso: TSSetPreStage(), TSSetPostStep(), TSStep()
2029 @*/
2030 PetscErrorCode  TSSetPreStep(TS ts, PetscErrorCode (*func)(TS))
2031 {
2032   PetscFunctionBegin;
2033   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2034   ts->ops->prestep = func;
2035   PetscFunctionReturn(0);
2036 }
2037 
2038 #undef __FUNCT__
2039 #define __FUNCT__ "TSPreStep"
2040 /*@
2041   TSPreStep - Runs the user-defined pre-step function.
2042 
2043   Collective on TS
2044 
2045   Input Parameters:
2046 . ts   - The TS context obtained from TSCreate()
2047 
2048   Notes:
2049   TSPreStep() is typically used within time stepping implementations,
2050   so most users would not generally call this routine themselves.
2051 
2052   Level: developer
2053 
2054 .keywords: TS, timestep
2055 .seealso: TSSetPreStep(), TSPreStage(), TSPostStep()
2056 @*/
2057 PetscErrorCode  TSPreStep(TS ts)
2058 {
2059   PetscErrorCode ierr;
2060 
2061   PetscFunctionBegin;
2062   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2063   if (ts->ops->prestep) {
2064     PetscStackPush("TS PreStep function");
2065     ierr = (*ts->ops->prestep)(ts);CHKERRQ(ierr);
2066     PetscStackPop;
2067   }
2068   PetscFunctionReturn(0);
2069 }
2070 
2071 #undef __FUNCT__
2072 #define __FUNCT__ "TSSetPreStage"
2073 /*@C
2074   TSSetPreStage - Sets the general-purpose function
2075   called once at the beginning of each stage.
2076 
2077   Logically Collective on TS
2078 
2079   Input Parameters:
2080 + ts   - The TS context obtained from TSCreate()
2081 - func - The function
2082 
2083   Calling sequence of func:
2084 . PetscErrorCode func(TS ts, PetscReal stagetime);
2085 
2086   Level: intermediate
2087 
2088   Note:
2089   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
2090   The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being
2091   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
2092 
2093 .keywords: TS, timestep
2094 .seealso: TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
2095 @*/
2096 PetscErrorCode  TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal))
2097 {
2098   PetscFunctionBegin;
2099   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2100   ts->ops->prestage = func;
2101   PetscFunctionReturn(0);
2102 }
2103 
2104 #undef __FUNCT__
2105 #define __FUNCT__ "TSPreStage"
2106 /*@
2107   TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage()
2108 
2109   Collective on TS
2110 
2111   Input Parameters:
2112 . ts   - The TS context obtained from TSCreate()
2113 
2114   Notes:
2115   TSPreStage() is typically used within time stepping implementations,
2116   most users would not generally call this routine themselves.
2117 
2118   Level: developer
2119 
2120 .keywords: TS, timestep
2121 .seealso: TSSetPreStep(), TSPreStep(), TSPostStep()
2122 @*/
2123 PetscErrorCode  TSPreStage(TS ts, PetscReal stagetime)
2124 {
2125   PetscErrorCode ierr;
2126 
2127   PetscFunctionBegin;
2128   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2129   if (ts->ops->prestage) {
2130     PetscStackPush("TS PreStage function");
2131     ierr = (*ts->ops->prestage)(ts,stagetime);CHKERRQ(ierr);
2132     PetscStackPop;
2133   }
2134   PetscFunctionReturn(0);
2135 }
2136 
2137 #undef __FUNCT__
2138 #define __FUNCT__ "TSSetPostStep"
2139 /*@C
2140   TSSetPostStep - Sets the general-purpose function
2141   called once at the end of each time step.
2142 
2143   Logically Collective on TS
2144 
2145   Input Parameters:
2146 + ts   - The TS context obtained from TSCreate()
2147 - func - The function
2148 
2149   Calling sequence of func:
2150 $ func (TS ts);
2151 
2152   Level: intermediate
2153 
2154 .keywords: TS, timestep
2155 .seealso: TSSetPreStep(), TSSetPreStage(), TSGetTimeStep(), TSGetTimeStepNumber(), TSGetTime()
2156 @*/
2157 PetscErrorCode  TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
2158 {
2159   PetscFunctionBegin;
2160   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2161   ts->ops->poststep = func;
2162   PetscFunctionReturn(0);
2163 }
2164 
2165 #undef __FUNCT__
2166 #define __FUNCT__ "TSPostStep"
2167 /*@
2168   TSPostStep - Runs the user-defined post-step function.
2169 
2170   Collective on TS
2171 
2172   Input Parameters:
2173 . ts   - The TS context obtained from TSCreate()
2174 
2175   Notes:
2176   TSPostStep() is typically used within time stepping implementations,
2177   so most users would not generally call this routine themselves.
2178 
2179   Level: developer
2180 
2181 .keywords: TS, timestep
2182 @*/
2183 PetscErrorCode  TSPostStep(TS ts)
2184 {
2185   PetscErrorCode ierr;
2186 
2187   PetscFunctionBegin;
2188   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2189   if (ts->ops->poststep) {
2190     PetscStackPush("TS PostStep function");
2191     ierr = (*ts->ops->poststep)(ts);CHKERRQ(ierr);
2192     PetscStackPop;
2193   }
2194   PetscFunctionReturn(0);
2195 }
2196 
2197 /* ------------ Routines to set performance monitoring options ----------- */
2198 
2199 #undef __FUNCT__
2200 #define __FUNCT__ "TSMonitorSet"
2201 /*@C
2202    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
2203    timestep to display the iteration's  progress.
2204 
2205    Logically Collective on TS
2206 
2207    Input Parameters:
2208 +  ts - the TS context obtained from TSCreate()
2209 .  monitor - monitoring routine
2210 .  mctx - [optional] user-defined context for private data for the
2211              monitor routine (use NULL if no context is desired)
2212 -  monitordestroy - [optional] routine that frees monitor context
2213           (may be NULL)
2214 
2215    Calling sequence of monitor:
2216 $    int monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
2217 
2218 +    ts - the TS context
2219 .    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
2220                                been interpolated to)
2221 .    time - current time
2222 .    u - current iterate
2223 -    mctx - [optional] monitoring context
2224 
2225    Notes:
2226    This routine adds an additional monitor to the list of monitors that
2227    already has been loaded.
2228 
2229    Fortran notes: Only a single monitor function can be set for each TS object
2230 
2231    Level: intermediate
2232 
2233 .keywords: TS, timestep, set, monitor
2234 
2235 .seealso: TSMonitorDefault(), TSMonitorCancel()
2236 @*/
2237 PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**))
2238 {
2239   PetscFunctionBegin;
2240   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2241   if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2242   ts->monitor[ts->numbermonitors]          = monitor;
2243   ts->monitordestroy[ts->numbermonitors]   = mdestroy;
2244   ts->monitorcontext[ts->numbermonitors++] = (void*)mctx;
2245   PetscFunctionReturn(0);
2246 }
2247 
2248 #undef __FUNCT__
2249 #define __FUNCT__ "TSMonitorCancel"
2250 /*@C
2251    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
2252 
2253    Logically Collective on TS
2254 
2255    Input Parameters:
2256 .  ts - the TS context obtained from TSCreate()
2257 
2258    Notes:
2259    There is no way to remove a single, specific monitor.
2260 
2261    Level: intermediate
2262 
2263 .keywords: TS, timestep, set, monitor
2264 
2265 .seealso: TSMonitorDefault(), TSMonitorSet()
2266 @*/
2267 PetscErrorCode  TSMonitorCancel(TS ts)
2268 {
2269   PetscErrorCode ierr;
2270   PetscInt       i;
2271 
2272   PetscFunctionBegin;
2273   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2274   for (i=0; i<ts->numbermonitors; i++) {
2275     if (ts->monitordestroy[i]) {
2276       ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr);
2277     }
2278   }
2279   ts->numbermonitors = 0;
2280   PetscFunctionReturn(0);
2281 }
2282 
2283 #undef __FUNCT__
2284 #define __FUNCT__ "TSMonitorDefault"
2285 /*@
2286    TSMonitorDefault - Sets the Default monitor
2287 
2288    Level: intermediate
2289 
2290 .keywords: TS, set, monitor
2291 
2292 .seealso: TSMonitorDefault(), TSMonitorSet()
2293 @*/
2294 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *dummy)
2295 {
2296   PetscErrorCode ierr;
2297   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)ts));
2298 
2299   PetscFunctionBegin;
2300   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
2301   ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g\n",step,(double)ts->time_step,(double)ptime);CHKERRQ(ierr);
2302   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
2303   PetscFunctionReturn(0);
2304 }
2305 
2306 #undef __FUNCT__
2307 #define __FUNCT__ "TSSetRetainStages"
2308 /*@
2309    TSSetRetainStages - Request that all stages in the upcoming step be stored so that interpolation will be available.
2310 
2311    Logically Collective on TS
2312 
2313    Input Argument:
2314 .  ts - time stepping context
2315 
2316    Output Argument:
2317 .  flg - PETSC_TRUE or PETSC_FALSE
2318 
2319    Level: intermediate
2320 
2321 .keywords: TS, set
2322 
2323 .seealso: TSInterpolate(), TSSetPostStep()
2324 @*/
2325 PetscErrorCode TSSetRetainStages(TS ts,PetscBool flg)
2326 {
2327   PetscFunctionBegin;
2328   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2329   ts->retain_stages = flg;
2330   PetscFunctionReturn(0);
2331 }
2332 
2333 #undef __FUNCT__
2334 #define __FUNCT__ "TSInterpolate"
2335 /*@
2336    TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval
2337 
2338    Collective on TS
2339 
2340    Input Argument:
2341 +  ts - time stepping context
2342 -  t - time to interpolate to
2343 
2344    Output Argument:
2345 .  U - state at given time
2346 
2347    Notes:
2348    The user should call TSSetRetainStages() before taking a step in which interpolation will be requested.
2349 
2350    Level: intermediate
2351 
2352    Developer Notes:
2353    TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints.
2354 
2355 .keywords: TS, set
2356 
2357 .seealso: TSSetRetainStages(), TSSetPostStep()
2358 @*/
2359 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U)
2360 {
2361   PetscErrorCode ierr;
2362 
2363   PetscFunctionBegin;
2364   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2365   if (t < ts->ptime - ts->time_step_prev || t > ts->ptime) SETERRQ3(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Requested time %G not in last time steps [%G,%G]",t,ts->ptime-ts->time_step_prev,ts->ptime);
2366   if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name);
2367   ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr);
2368   PetscFunctionReturn(0);
2369 }
2370 
2371 #undef __FUNCT__
2372 #define __FUNCT__ "TSStep"
2373 /*@
2374    TSStep - Steps one time step
2375 
2376    Collective on TS
2377 
2378    Input Parameter:
2379 .  ts - the TS context obtained from TSCreate()
2380 
2381    Level: intermediate
2382 
2383    Notes:
2384    The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may
2385    be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages.
2386 
2387    This may over-step the final time provided in TSSetDuration() depending on the time-step used. TSSolve() interpolates to exactly the
2388    time provided in TSSetDuration(). One can use TSInterpolate() to determine an interpolated solution within the final timestep.
2389 
2390 .keywords: TS, timestep, solve
2391 
2392 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate()
2393 @*/
2394 PetscErrorCode  TSStep(TS ts)
2395 {
2396   PetscReal      ptime_prev;
2397   PetscErrorCode ierr;
2398 
2399   PetscFunctionBegin;
2400   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2401   ierr = TSSetUp(ts);CHKERRQ(ierr);
2402 
2403   ts->reason = TS_CONVERGED_ITERATING;
2404   ptime_prev = ts->ptime;
2405 
2406   ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr);
2407   ierr = (*ts->ops->step)(ts);CHKERRQ(ierr);
2408   ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr);
2409 
2410   ts->time_step_prev = ts->ptime - ptime_prev;
2411 
2412   if (ts->reason < 0) {
2413     if (ts->errorifstepfailed) {
2414       if (ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) {
2415         SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s, increase -ts_max_snes_failures or make negative to attempt recovery",TSConvergedReasons[ts->reason]);
2416       } else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]);
2417     }
2418   } else if (!ts->reason) {
2419     if (ts->steps >= ts->max_steps)     ts->reason = TS_CONVERGED_ITS;
2420     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
2421   }
2422   PetscFunctionReturn(0);
2423 }
2424 
2425 #undef __FUNCT__
2426 #define __FUNCT__ "TSEvaluateStep"
2427 /*@
2428    TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy.
2429 
2430    Collective on TS
2431 
2432    Input Arguments:
2433 +  ts - time stepping context
2434 .  order - desired order of accuracy
2435 -  done - whether the step was evaluated at this order (pass NULL to generate an error if not available)
2436 
2437    Output Arguments:
2438 .  U - state at the end of the current step
2439 
2440    Level: advanced
2441 
2442    Notes:
2443    This function cannot be called until all stages have been evaluated.
2444    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.
2445 
2446 .seealso: TSStep(), TSAdapt
2447 @*/
2448 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done)
2449 {
2450   PetscErrorCode ierr;
2451 
2452   PetscFunctionBegin;
2453   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2454   PetscValidType(ts,1);
2455   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
2456   if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name);
2457   ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr);
2458   PetscFunctionReturn(0);
2459 }
2460 
2461 #undef __FUNCT__
2462 #define __FUNCT__ "TSSolve"
2463 /*@
2464    TSSolve - Steps the requested number of timesteps.
2465 
2466    Collective on TS
2467 
2468    Input Parameter:
2469 +  ts - the TS context obtained from TSCreate()
2470 -  u - the solution vector  (can be null if TSSetSolution() was used, otherwise must contain the initial conditions)
2471 
2472    Level: beginner
2473 
2474    Notes:
2475    The final time returned by this function may be different from the time of the internally
2476    held state accessible by TSGetSolution() and TSGetTime() because the method may have
2477    stepped over the final time.
2478 
2479 .keywords: TS, timestep, solve
2480 
2481 .seealso: TSCreate(), TSSetSolution(), TSStep()
2482 @*/
2483 PetscErrorCode TSSolve(TS ts,Vec u)
2484 {
2485   PetscBool         flg;
2486   PetscViewer       viewer;
2487   PetscErrorCode    ierr;
2488   PetscViewerFormat format;
2489 
2490   PetscFunctionBegin;
2491   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2492   if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2);
2493   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 */
2494     if (!ts->vec_sol || u == ts->vec_sol) {
2495       Vec y;
2496       ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
2497       ierr = TSSetSolution(ts,y);CHKERRQ(ierr);
2498       ierr = VecDestroy(&y);CHKERRQ(ierr); /* grant ownership */
2499     }
2500     if (u) {
2501       ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr);
2502     }
2503   } else if (u) {
2504     ierr = TSSetSolution(ts,u);CHKERRQ(ierr);
2505   }
2506   ierr = TSSetUp(ts);CHKERRQ(ierr);
2507   /* reset time step and iteration counters */
2508   ts->steps             = 0;
2509   ts->ksp_its           = 0;
2510   ts->snes_its          = 0;
2511   ts->num_snes_failures = 0;
2512   ts->reject            = 0;
2513   ts->reason            = TS_CONVERGED_ITERATING;
2514 
2515   if (ts->ops->solve) {         /* This private interface is transitional and should be removed when all implementations are updated. */
2516     ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr);
2517     ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);
2518 
2519     ts->solvetime = ts->ptime;
2520   } else {
2521     /* steps the requested number of timesteps. */
2522     ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
2523     if (ts->steps >= ts->max_steps)     ts->reason = TS_CONVERGED_ITS;
2524     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
2525     while (!ts->reason) {
2526       ierr = TSStep(ts);CHKERRQ(ierr);
2527       ierr = TSPostStep(ts);CHKERRQ(ierr);
2528       ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
2529     }
2530     if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) {
2531       ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr);
2532 
2533       ts->solvetime = ts->max_time;
2534     } else {
2535       if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);}
2536       ts->solvetime = ts->ptime;
2537     }
2538   }
2539   ierr = TSMonitor(ts,-1,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
2540   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts),((PetscObject)ts)->prefix,"-ts_view",&viewer,&format,&flg);CHKERRQ(ierr);
2541   if (flg && !PetscPreLoadingOn) {
2542     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
2543     ierr = TSView(ts,viewer);CHKERRQ(ierr);
2544     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
2545     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
2546   }
2547   PetscFunctionReturn(0);
2548 }
2549 
2550 #undef __FUNCT__
2551 #define __FUNCT__ "TSMonitor"
2552 /*@
2553    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()
2554 
2555    Collective on TS
2556 
2557    Input Parameters:
2558 +  ts - time stepping context obtained from TSCreate()
2559 .  step - step number that has just completed
2560 .  ptime - model time of the state
2561 -  u - state at the current model time
2562 
2563    Notes:
2564    TSMonitor() is typically used within the time stepping implementations.
2565    Users might call this function when using the TSStep() interface instead of TSSolve().
2566 
2567    Level: advanced
2568 
2569 .keywords: TS, timestep
2570 @*/
2571 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u)
2572 {
2573   PetscErrorCode ierr;
2574   PetscInt       i,n = ts->numbermonitors;
2575 
2576   PetscFunctionBegin;
2577   for (i=0; i<n; i++) {
2578     ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr);
2579   }
2580   PetscFunctionReturn(0);
2581 }
2582 
2583 /* ------------------------------------------------------------------------*/
2584 struct _n_TSMonitorLGCtx {
2585   PetscDrawLG lg;
2586   PetscInt    howoften;  /* when > 0 uses step % howoften, when negative only final solution plotted */
2587   PetscInt    ksp_its,snes_its;
2588 };
2589 
2590 
2591 #undef __FUNCT__
2592 #define __FUNCT__ "TSMonitorLGCtxCreate"
2593 /*@C
2594    TSMonitorLGCtxCreate - Creates a line graph context for use with
2595    TS to monitor the solution process graphically in various ways
2596 
2597    Collective on TS
2598 
2599    Input Parameters:
2600 +  host - the X display to open, or null for the local machine
2601 .  label - the title to put in the title bar
2602 .  x, y - the screen coordinates of the upper left coordinate of the window
2603 .  m, n - the screen width and height in pixels
2604 -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
2605 
2606    Output Parameter:
2607 .  ctx - the context
2608 
2609    Options Database Key:
2610 +  -ts_monitor_lg_timestep - automatically sets line graph monitor
2611 .  -ts_monitor_lg_solution -
2612 .  -ts_monitor_lg_error -
2613 .  -ts_monitor_lg_ksp_iterations -
2614 .  -ts_monitor_lg_snes_iterations -
2615 -  -lg_indicate_data_points <true,false> - indicate the data points (at each time step) on the plot; default is true
2616 
2617    Notes:
2618    Use TSMonitorLGCtxDestroy() to destroy.
2619 
2620    Level: intermediate
2621 
2622 .keywords: TS, monitor, line graph, residual, seealso
2623 
2624 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError()
2625 
2626 @*/
2627 PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
2628 {
2629   PetscDraw      win;
2630   PetscErrorCode ierr;
2631   PetscBool      flg = PETSC_TRUE;
2632 
2633   PetscFunctionBegin;
2634   ierr = PetscNew(struct _n_TSMonitorLGCtx,ctx);CHKERRQ(ierr);
2635   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&win);CHKERRQ(ierr);
2636   ierr = PetscDrawSetFromOptions(win);CHKERRQ(ierr);
2637   ierr = PetscDrawLGCreate(win,1,&(*ctx)->lg);CHKERRQ(ierr);
2638   ierr = PetscOptionsGetBool(NULL,"-lg_indicate_data_points",&flg,NULL);CHKERRQ(ierr);
2639   if (flg) {
2640     ierr = PetscDrawLGIndicateDataPoints((*ctx)->lg);CHKERRQ(ierr);
2641   }
2642   ierr = PetscLogObjectParent((*ctx)->lg,win);CHKERRQ(ierr);
2643   (*ctx)->howoften = howoften;
2644   PetscFunctionReturn(0);
2645 }
2646 
2647 #undef __FUNCT__
2648 #define __FUNCT__ "TSMonitorLGTimeStep"
2649 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
2650 {
2651   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
2652   PetscReal      x   = ptime,y;
2653   PetscErrorCode ierr;
2654 
2655   PetscFunctionBegin;
2656   if (!n) {
2657     PetscDrawAxis axis;
2658     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
2659     ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time","Time step");CHKERRQ(ierr);
2660     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
2661   }
2662   ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr);
2663   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
2664   if (((ctx->howoften > 0) && (!(n % ctx->howoften))) || ((ctx->howoften == -1) && (n == -1))) {
2665     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
2666   }
2667   PetscFunctionReturn(0);
2668 }
2669 
2670 #undef __FUNCT__
2671 #define __FUNCT__ "TSMonitorLGCtxDestroy"
2672 /*@C
2673    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
2674    with TSMonitorLGCtxCreate().
2675 
2676    Collective on TSMonitorLGCtx
2677 
2678    Input Parameter:
2679 .  ctx - the monitor context
2680 
2681    Level: intermediate
2682 
2683 .keywords: TS, monitor, line graph, destroy
2684 
2685 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep();
2686 @*/
2687 PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
2688 {
2689   PetscDraw      draw;
2690   PetscErrorCode ierr;
2691 
2692   PetscFunctionBegin;
2693   ierr = PetscDrawLGGetDraw((*ctx)->lg,&draw);CHKERRQ(ierr);
2694   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
2695   ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr);
2696   ierr = PetscFree(*ctx);CHKERRQ(ierr);
2697   PetscFunctionReturn(0);
2698 }
2699 
2700 #undef __FUNCT__
2701 #define __FUNCT__ "TSGetTime"
2702 /*@
2703    TSGetTime - Gets the time of the most recently completed step.
2704 
2705    Not Collective
2706 
2707    Input Parameter:
2708 .  ts - the TS context obtained from TSCreate()
2709 
2710    Output Parameter:
2711 .  t  - the current time
2712 
2713    Level: beginner
2714 
2715    Note:
2716    When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(),
2717    TSSetPreStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated.
2718 
2719 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
2720 
2721 .keywords: TS, get, time
2722 @*/
2723 PetscErrorCode  TSGetTime(TS ts,PetscReal *t)
2724 {
2725   PetscFunctionBegin;
2726   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2727   PetscValidRealPointer(t,2);
2728   *t = ts->ptime;
2729   PetscFunctionReturn(0);
2730 }
2731 
2732 #undef __FUNCT__
2733 #define __FUNCT__ "TSSetTime"
2734 /*@
2735    TSSetTime - Allows one to reset the time.
2736 
2737    Logically Collective on TS
2738 
2739    Input Parameters:
2740 +  ts - the TS context obtained from TSCreate()
2741 -  time - the time
2742 
2743    Level: intermediate
2744 
2745 .seealso: TSGetTime(), TSSetDuration()
2746 
2747 .keywords: TS, set, time
2748 @*/
2749 PetscErrorCode  TSSetTime(TS ts, PetscReal t)
2750 {
2751   PetscFunctionBegin;
2752   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2753   PetscValidLogicalCollectiveReal(ts,t,2);
2754   ts->ptime = t;
2755   PetscFunctionReturn(0);
2756 }
2757 
2758 #undef __FUNCT__
2759 #define __FUNCT__ "TSSetOptionsPrefix"
2760 /*@C
2761    TSSetOptionsPrefix - Sets the prefix used for searching for all
2762    TS options in the database.
2763 
2764    Logically Collective on TS
2765 
2766    Input Parameter:
2767 +  ts     - The TS context
2768 -  prefix - The prefix to prepend to all option names
2769 
2770    Notes:
2771    A hyphen (-) must NOT be given at the beginning of the prefix name.
2772    The first character of all runtime options is AUTOMATICALLY the
2773    hyphen.
2774 
2775    Level: advanced
2776 
2777 .keywords: TS, set, options, prefix, database
2778 
2779 .seealso: TSSetFromOptions()
2780 
2781 @*/
2782 PetscErrorCode  TSSetOptionsPrefix(TS ts,const char prefix[])
2783 {
2784   PetscErrorCode ierr;
2785   SNES           snes;
2786 
2787   PetscFunctionBegin;
2788   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2789   ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2790   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2791   ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr);
2792   PetscFunctionReturn(0);
2793 }
2794 
2795 
2796 #undef __FUNCT__
2797 #define __FUNCT__ "TSAppendOptionsPrefix"
2798 /*@C
2799    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
2800    TS options in the database.
2801 
2802    Logically Collective on TS
2803 
2804    Input Parameter:
2805 +  ts     - The TS context
2806 -  prefix - The prefix to prepend to all option names
2807 
2808    Notes:
2809    A hyphen (-) must NOT be given at the beginning of the prefix name.
2810    The first character of all runtime options is AUTOMATICALLY the
2811    hyphen.
2812 
2813    Level: advanced
2814 
2815 .keywords: TS, append, options, prefix, database
2816 
2817 .seealso: TSGetOptionsPrefix()
2818 
2819 @*/
2820 PetscErrorCode  TSAppendOptionsPrefix(TS ts,const char prefix[])
2821 {
2822   PetscErrorCode ierr;
2823   SNES           snes;
2824 
2825   PetscFunctionBegin;
2826   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2827   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2828   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2829   ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr);
2830   PetscFunctionReturn(0);
2831 }
2832 
2833 #undef __FUNCT__
2834 #define __FUNCT__ "TSGetOptionsPrefix"
2835 /*@C
2836    TSGetOptionsPrefix - Sets the prefix used for searching for all
2837    TS options in the database.
2838 
2839    Not Collective
2840 
2841    Input Parameter:
2842 .  ts - The TS context
2843 
2844    Output Parameter:
2845 .  prefix - A pointer to the prefix string used
2846 
2847    Notes: On the fortran side, the user should pass in a string 'prifix' of
2848    sufficient length to hold the prefix.
2849 
2850    Level: intermediate
2851 
2852 .keywords: TS, get, options, prefix, database
2853 
2854 .seealso: TSAppendOptionsPrefix()
2855 @*/
2856 PetscErrorCode  TSGetOptionsPrefix(TS ts,const char *prefix[])
2857 {
2858   PetscErrorCode ierr;
2859 
2860   PetscFunctionBegin;
2861   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2862   PetscValidPointer(prefix,2);
2863   ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2864   PetscFunctionReturn(0);
2865 }
2866 
2867 #undef __FUNCT__
2868 #define __FUNCT__ "TSGetRHSJacobian"
2869 /*@C
2870    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
2871 
2872    Not Collective, but parallel objects are returned if TS is parallel
2873 
2874    Input Parameter:
2875 .  ts  - The TS context obtained from TSCreate()
2876 
2877    Output Parameters:
2878 +  J   - The Jacobian J of F, where U_t = G(U,t)
2879 .  M   - The preconditioner matrix, usually the same as J
2880 .  func - Function to compute the Jacobian of the RHS
2881 -  ctx - User-defined context for Jacobian evaluation routine
2882 
2883    Notes: You can pass in NULL for any return argument you do not need.
2884 
2885    Level: intermediate
2886 
2887 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
2888 
2889 .keywords: TS, timestep, get, matrix, Jacobian
2890 @*/
2891 PetscErrorCode  TSGetRHSJacobian(TS ts,Mat *J,Mat *M,TSRHSJacobian *func,void **ctx)
2892 {
2893   PetscErrorCode ierr;
2894   SNES           snes;
2895   DM             dm;
2896 
2897   PetscFunctionBegin;
2898   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2899   ierr = SNESGetJacobian(snes,J,M,NULL,NULL);CHKERRQ(ierr);
2900   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2901   ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr);
2902   PetscFunctionReturn(0);
2903 }
2904 
2905 #undef __FUNCT__
2906 #define __FUNCT__ "TSGetIJacobian"
2907 /*@C
2908    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
2909 
2910    Not Collective, but parallel objects are returned if TS is parallel
2911 
2912    Input Parameter:
2913 .  ts  - The TS context obtained from TSCreate()
2914 
2915    Output Parameters:
2916 +  A   - The Jacobian of F(t,U,U_t)
2917 .  B   - The preconditioner matrix, often the same as A
2918 .  f   - The function to compute the matrices
2919 - ctx - User-defined context for Jacobian evaluation routine
2920 
2921    Notes: You can pass in NULL for any return argument you do not need.
2922 
2923    Level: advanced
2924 
2925 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
2926 
2927 .keywords: TS, timestep, get, matrix, Jacobian
2928 @*/
2929 PetscErrorCode  TSGetIJacobian(TS ts,Mat *A,Mat *B,TSIJacobian *f,void **ctx)
2930 {
2931   PetscErrorCode ierr;
2932   SNES           snes;
2933   DM             dm;
2934 
2935   PetscFunctionBegin;
2936   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2937   ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
2938   ierr = SNESGetJacobian(snes,A,B,NULL,NULL);CHKERRQ(ierr);
2939   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2940   ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr);
2941   PetscFunctionReturn(0);
2942 }
2943 
2944 struct _n_TSMonitorDrawCtx {
2945   PetscViewer viewer;
2946   Vec         initialsolution;
2947   PetscBool   showinitial;
2948   PetscInt    howoften;  /* when > 0 uses step % howoften, when negative only final solution plotted */
2949   PetscBool   showtimestepandtime;
2950 };
2951 
2952 #undef __FUNCT__
2953 #define __FUNCT__ "TSMonitorDrawSolution"
2954 /*@C
2955    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
2956    VecView() for the solution at each timestep
2957 
2958    Collective on TS
2959 
2960    Input Parameters:
2961 +  ts - the TS context
2962 .  step - current time-step
2963 .  ptime - current time
2964 -  dummy - either a viewer or NULL
2965 
2966    Options Database:
2967 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
2968 
2969    Notes: the initial solution and current solution are not displayed with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
2970        will look bad
2971 
2972    Level: intermediate
2973 
2974 .keywords: TS,  vector, monitor, view
2975 
2976 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
2977 @*/
2978 PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
2979 {
2980   PetscErrorCode   ierr;
2981   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
2982   PetscDraw        draw;
2983 
2984   PetscFunctionBegin;
2985   if (!step && ictx->showinitial) {
2986     if (!ictx->initialsolution) {
2987       ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr);
2988     }
2989     ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr);
2990   }
2991   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften)) && (step > -1)) || ((ictx->howoften == -1) && (step == -1)))) PetscFunctionReturn(0);
2992 
2993   if (ictx->showinitial) {
2994     PetscReal pause;
2995     ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr);
2996     ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr);
2997     ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr);
2998     ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr);
2999     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr);
3000   }
3001   ierr = VecView(u,ictx->viewer);CHKERRQ(ierr);
3002   if (ictx->showtimestepandtime) {
3003     PetscReal xl,yl,xr,yr,tw,w,h;
3004     char      time[32];
3005     size_t    len;
3006 
3007     ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
3008     ierr = PetscSNPrintf(time,32,"Timestep %d Time %f",(int)step,(double)ptime);CHKERRQ(ierr);
3009     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
3010     ierr =  PetscStrlen(time,&len);CHKERRQ(ierr);
3011     ierr = PetscDrawStringGetSize(draw,&tw,NULL);CHKERRQ(ierr);
3012     w    = xl + .5*(xr - xl) - .5*len*tw;
3013     h    = yl + .95*(yr - yl);
3014     ierr = PetscDrawString(draw,w,h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
3015     ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
3016   }
3017 
3018   if (ictx->showinitial) {
3019     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr);
3020   }
3021   PetscFunctionReturn(0);
3022 }
3023 
3024 
3025 #undef __FUNCT__
3026 #define __FUNCT__ "TSMonitorDrawCtxDestroy"
3027 /*@C
3028    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
3029 
3030    Collective on TS
3031 
3032    Input Parameters:
3033 .    ctx - the monitor context
3034 
3035    Level: intermediate
3036 
3037 .keywords: TS,  vector, monitor, view
3038 
3039 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError()
3040 @*/
3041 PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
3042 {
3043   PetscErrorCode ierr;
3044 
3045   PetscFunctionBegin;
3046   ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr);
3047   ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr);
3048   ierr = PetscFree(*ictx);CHKERRQ(ierr);
3049   PetscFunctionReturn(0);
3050 }
3051 
3052 #undef __FUNCT__
3053 #define __FUNCT__ "TSMonitorDrawCtxCreate"
3054 /*@C
3055    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
3056 
3057    Collective on TS
3058 
3059    Input Parameter:
3060 .    ts - time-step context
3061 
3062    Output Patameter:
3063 .    ctx - the monitor context
3064 
3065    Options Database:
3066 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
3067 
3068    Level: intermediate
3069 
3070 .keywords: TS,  vector, monitor, view
3071 
3072 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx()
3073 @*/
3074 PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
3075 {
3076   PetscErrorCode   ierr;
3077 
3078   PetscFunctionBegin;
3079   ierr = PetscNew(struct _n_TSMonitorDrawCtx,ctx);CHKERRQ(ierr);
3080   ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr);
3081   ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr);
3082 
3083   (*ctx)->howoften    = howoften;
3084   (*ctx)->showinitial = PETSC_FALSE;
3085   ierr = PetscOptionsGetBool(NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr);
3086 
3087   (*ctx)->showtimestepandtime = PETSC_FALSE;
3088   ierr = PetscOptionsGetBool(NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr);
3089   PetscFunctionReturn(0);
3090 }
3091 
3092 #undef __FUNCT__
3093 #define __FUNCT__ "TSMonitorDrawError"
3094 /*@C
3095    TSMonitorDrawError - Monitors progress of the TS solvers by calling
3096    VecView() for the error at each timestep
3097 
3098    Collective on TS
3099 
3100    Input Parameters:
3101 +  ts - the TS context
3102 .  step - current time-step
3103 .  ptime - current time
3104 -  dummy - either a viewer or NULL
3105 
3106    Level: intermediate
3107 
3108 .keywords: TS,  vector, monitor, view
3109 
3110 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3111 @*/
3112 PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
3113 {
3114   PetscErrorCode   ierr;
3115   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
3116   PetscViewer      viewer = ctx->viewer;
3117   Vec              work;
3118 
3119   PetscFunctionBegin;
3120   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1)))) PetscFunctionReturn(0);
3121   ierr = VecDuplicate(u,&work);CHKERRQ(ierr);
3122   ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr);
3123   ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr);
3124   ierr = VecView(work,viewer);CHKERRQ(ierr);
3125   ierr = VecDestroy(&work);CHKERRQ(ierr);
3126   PetscFunctionReturn(0);
3127 }
3128 
3129 #include <petsc-private/dmimpl.h>
3130 #undef __FUNCT__
3131 #define __FUNCT__ "TSSetDM"
3132 /*@
3133    TSSetDM - Sets the DM that may be used by some preconditioners
3134 
3135    Logically Collective on TS and DM
3136 
3137    Input Parameters:
3138 +  ts - the preconditioner context
3139 -  dm - the dm
3140 
3141    Level: intermediate
3142 
3143 
3144 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM()
3145 @*/
3146 PetscErrorCode  TSSetDM(TS ts,DM dm)
3147 {
3148   PetscErrorCode ierr;
3149   SNES           snes;
3150   DMTS           tsdm;
3151 
3152   PetscFunctionBegin;
3153   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3154   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
3155   if (ts->dm) {               /* Move the DMTS context over to the new DM unless the new DM already has one */
3156     if (ts->dm->dmts && !dm->dmts) {
3157       ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr);
3158       ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr);
3159       if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */
3160         tsdm->originaldm = dm;
3161       }
3162     }
3163     ierr = DMDestroy(&ts->dm);CHKERRQ(ierr);
3164   }
3165   ts->dm = dm;
3166 
3167   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3168   ierr = SNESSetDM(snes,dm);CHKERRQ(ierr);
3169   PetscFunctionReturn(0);
3170 }
3171 
3172 #undef __FUNCT__
3173 #define __FUNCT__ "TSGetDM"
3174 /*@
3175    TSGetDM - Gets the DM that may be used by some preconditioners
3176 
3177    Not Collective
3178 
3179    Input Parameter:
3180 . ts - the preconditioner context
3181 
3182    Output Parameter:
3183 .  dm - the dm
3184 
3185    Level: intermediate
3186 
3187 
3188 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM()
3189 @*/
3190 PetscErrorCode  TSGetDM(TS ts,DM *dm)
3191 {
3192   PetscErrorCode ierr;
3193 
3194   PetscFunctionBegin;
3195   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3196   if (!ts->dm) {
3197     ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr);
3198     if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
3199   }
3200   *dm = ts->dm;
3201   PetscFunctionReturn(0);
3202 }
3203 
3204 #undef __FUNCT__
3205 #define __FUNCT__ "SNESTSFormFunction"
3206 /*@
3207    SNESTSFormFunction - Function to evaluate nonlinear residual
3208 
3209    Logically Collective on SNES
3210 
3211    Input Parameter:
3212 + snes - nonlinear solver
3213 . U - the current state at which to evaluate the residual
3214 - ctx - user context, must be a TS
3215 
3216    Output Parameter:
3217 . F - the nonlinear residual
3218 
3219    Notes:
3220    This function is not normally called by users and is automatically registered with the SNES used by TS.
3221    It is most frequently passed to MatFDColoringSetFunction().
3222 
3223    Level: advanced
3224 
3225 .seealso: SNESSetFunction(), MatFDColoringSetFunction()
3226 @*/
3227 PetscErrorCode  SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx)
3228 {
3229   TS             ts = (TS)ctx;
3230   PetscErrorCode ierr;
3231 
3232   PetscFunctionBegin;
3233   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3234   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
3235   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
3236   PetscValidHeaderSpecific(ts,TS_CLASSID,4);
3237   ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr);
3238   PetscFunctionReturn(0);
3239 }
3240 
3241 #undef __FUNCT__
3242 #define __FUNCT__ "SNESTSFormJacobian"
3243 /*@
3244    SNESTSFormJacobian - Function to evaluate the Jacobian
3245 
3246    Collective on SNES
3247 
3248    Input Parameter:
3249 + snes - nonlinear solver
3250 . U - the current state at which to evaluate the residual
3251 - ctx - user context, must be a TS
3252 
3253    Output Parameter:
3254 + A - the Jacobian
3255 . B - the preconditioning matrix (may be the same as A)
3256 - flag - indicates any structure change in the matrix
3257 
3258    Notes:
3259    This function is not normally called by users and is automatically registered with the SNES used by TS.
3260 
3261    Level: developer
3262 
3263 .seealso: SNESSetJacobian()
3264 @*/
3265 PetscErrorCode  SNESTSFormJacobian(SNES snes,Vec U,Mat *A,Mat *B,MatStructure *flag,void *ctx)
3266 {
3267   TS             ts = (TS)ctx;
3268   PetscErrorCode ierr;
3269 
3270   PetscFunctionBegin;
3271   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3272   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
3273   PetscValidPointer(A,3);
3274   PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
3275   PetscValidPointer(B,4);
3276   PetscValidHeaderSpecific(*B,MAT_CLASSID,4);
3277   PetscValidPointer(flag,5);
3278   PetscValidHeaderSpecific(ts,TS_CLASSID,6);
3279   ierr = (ts->ops->snesjacobian)(snes,U,A,B,flag,ts);CHKERRQ(ierr);
3280   PetscFunctionReturn(0);
3281 }
3282 
3283 #undef __FUNCT__
3284 #define __FUNCT__ "TSComputeRHSFunctionLinear"
3285 /*@C
3286    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only
3287 
3288    Collective on TS
3289 
3290    Input Arguments:
3291 +  ts - time stepping context
3292 .  t - time at which to evaluate
3293 .  U - state at which to evaluate
3294 -  ctx - context
3295 
3296    Output Arguments:
3297 .  F - right hand side
3298 
3299    Level: intermediate
3300 
3301    Notes:
3302    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
3303    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().
3304 
3305 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
3306 @*/
3307 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx)
3308 {
3309   PetscErrorCode ierr;
3310   Mat            Arhs,Brhs;
3311   MatStructure   flg2;
3312 
3313   PetscFunctionBegin;
3314   ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
3315   ierr = TSComputeRHSJacobian(ts,t,U,&Arhs,&Brhs,&flg2);CHKERRQ(ierr);
3316   ierr = MatMult(Arhs,U,F);CHKERRQ(ierr);
3317   PetscFunctionReturn(0);
3318 }
3319 
3320 #undef __FUNCT__
3321 #define __FUNCT__ "TSComputeRHSJacobianConstant"
3322 /*@C
3323    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
3324 
3325    Collective on TS
3326 
3327    Input Arguments:
3328 +  ts - time stepping context
3329 .  t - time at which to evaluate
3330 .  U - state at which to evaluate
3331 -  ctx - context
3332 
3333    Output Arguments:
3334 +  A - pointer to operator
3335 .  B - pointer to preconditioning matrix
3336 -  flg - matrix structure flag
3337 
3338    Level: intermediate
3339 
3340    Notes:
3341    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.
3342 
3343 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear()
3344 @*/
3345 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat *A,Mat *B,MatStructure *flg,void *ctx)
3346 {
3347   PetscFunctionBegin;
3348   *flg = SAME_PRECONDITIONER;
3349   PetscFunctionReturn(0);
3350 }
3351 
3352 #undef __FUNCT__
3353 #define __FUNCT__ "TSComputeIFunctionLinear"
3354 /*@C
3355    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
3356 
3357    Collective on TS
3358 
3359    Input Arguments:
3360 +  ts - time stepping context
3361 .  t - time at which to evaluate
3362 .  U - state at which to evaluate
3363 .  Udot - time derivative of state vector
3364 -  ctx - context
3365 
3366    Output Arguments:
3367 .  F - left hand side
3368 
3369    Level: intermediate
3370 
3371    Notes:
3372    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
3373    user is required to write their own TSComputeIFunction.
3374    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
3375    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().
3376 
3377 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant()
3378 @*/
3379 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx)
3380 {
3381   PetscErrorCode ierr;
3382   Mat            A,B;
3383   MatStructure   flg2;
3384 
3385   PetscFunctionBegin;
3386   ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr);
3387   ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,&A,&B,&flg2,PETSC_TRUE);CHKERRQ(ierr);
3388   ierr = MatMult(A,Udot,F);CHKERRQ(ierr);
3389   PetscFunctionReturn(0);
3390 }
3391 
3392 #undef __FUNCT__
3393 #define __FUNCT__ "TSComputeIJacobianConstant"
3394 /*@C
3395    TSComputeIJacobianConstant - Reuses a Jacobian that is time-independent.
3396 
3397    Collective on TS
3398 
3399    Input Arguments:
3400 +  ts - time stepping context
3401 .  t - time at which to evaluate
3402 .  U - state at which to evaluate
3403 .  Udot - time derivative of state vector
3404 .  shift - shift to apply
3405 -  ctx - context
3406 
3407    Output Arguments:
3408 +  A - pointer to operator
3409 .  B - pointer to preconditioning matrix
3410 -  flg - matrix structure flag
3411 
3412    Level: intermediate
3413 
3414    Notes:
3415    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.
3416 
3417 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear()
3418 @*/
3419 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,void *ctx)
3420 {
3421   PetscFunctionBegin;
3422   *flg = SAME_PRECONDITIONER;
3423   PetscFunctionReturn(0);
3424 }
3425 #undef __FUNCT__
3426 #define __FUNCT__ "TSGetEquationType"
3427 /*@
3428    TSGetEquationType - Gets the type of the equation that TS is solving.
3429 
3430    Not Collective
3431 
3432    Input Parameter:
3433 .  ts - the TS context
3434 
3435    Output Parameter:
3436 .  equation_type - see TSEquatioType
3437 
3438    Level: beginner
3439 
3440 .keywords: TS, equation type
3441 
3442 .seealso: TSSetEquationType(), TSEquationType
3443 @*/
3444 PetscErrorCode  TSGetEquationType(TS ts,TSEquationType *equation_type)
3445 {
3446   PetscFunctionBegin;
3447   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3448   PetscValidPointer(equation_type,2);
3449   *equation_type = ts->equation_type;
3450   PetscFunctionReturn(0);
3451 }
3452 
3453 #undef __FUNCT__
3454 #define __FUNCT__ "TSSetEquationType"
3455 /*@
3456    TSSetEquationType - Sets the type of the equation that TS is solving.
3457 
3458    Not Collective
3459 
3460    Input Parameter:
3461 +  ts - the TS context
3462 .  equation_type - see TSEquatioType
3463 
3464    Level: advanced
3465 
3466 .keywords: TS, equation type
3467 
3468 .seealso: TSGetEquationType(), TSEquationType
3469 @*/
3470 PetscErrorCode  TSSetEquationType(TS ts,TSEquationType equation_type)
3471 {
3472   PetscFunctionBegin;
3473   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3474   ts->equation_type = equation_type;
3475   PetscFunctionReturn(0);
3476 }
3477 
3478 #undef __FUNCT__
3479 #define __FUNCT__ "TSGetConvergedReason"
3480 /*@
3481    TSGetConvergedReason - Gets the reason the TS iteration was stopped.
3482 
3483    Not Collective
3484 
3485    Input Parameter:
3486 .  ts - the TS context
3487 
3488    Output Parameter:
3489 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
3490             manual pages for the individual convergence tests for complete lists
3491 
3492    Level: beginner
3493 
3494    Notes:
3495    Can only be called after the call to TSSolve() is complete.
3496 
3497 .keywords: TS, nonlinear, set, convergence, test
3498 
3499 .seealso: TSSetConvergenceTest(), TSConvergedReason
3500 @*/
3501 PetscErrorCode  TSGetConvergedReason(TS ts,TSConvergedReason *reason)
3502 {
3503   PetscFunctionBegin;
3504   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3505   PetscValidPointer(reason,2);
3506   *reason = ts->reason;
3507   PetscFunctionReturn(0);
3508 }
3509 
3510 #undef __FUNCT__
3511 #define __FUNCT__ "TSSetConvergedReason"
3512 /*@
3513    TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve.
3514 
3515    Not Collective
3516 
3517    Input Parameter:
3518 +  ts - the TS context
3519 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
3520             manual pages for the individual convergence tests for complete lists
3521 
3522    Level: advanced
3523 
3524    Notes:
3525    Can only be called during TSSolve() is active.
3526 
3527 .keywords: TS, nonlinear, set, convergence, test
3528 
3529 .seealso: TSConvergedReason
3530 @*/
3531 PetscErrorCode  TSSetConvergedReason(TS ts,TSConvergedReason reason)
3532 {
3533   PetscFunctionBegin;
3534   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3535   ts->reason = reason;
3536   PetscFunctionReturn(0);
3537 }
3538 
3539 #undef __FUNCT__
3540 #define __FUNCT__ "TSGetSolveTime"
3541 /*@
3542    TSGetSolveTime - Gets the time after a call to TSSolve()
3543 
3544    Not Collective
3545 
3546    Input Parameter:
3547 .  ts - the TS context
3548 
3549    Output Parameter:
3550 .  ftime - the final time. This time should correspond to the final time set with TSSetDuration()
3551 
3552    Level: beginner
3553 
3554    Notes:
3555    Can only be called after the call to TSSolve() is complete.
3556 
3557 .keywords: TS, nonlinear, set, convergence, test
3558 
3559 .seealso: TSSetConvergenceTest(), TSConvergedReason
3560 @*/
3561 PetscErrorCode  TSGetSolveTime(TS ts,PetscReal *ftime)
3562 {
3563   PetscFunctionBegin;
3564   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3565   PetscValidPointer(ftime,2);
3566   *ftime = ts->solvetime;
3567   PetscFunctionReturn(0);
3568 }
3569 
3570 #undef __FUNCT__
3571 #define __FUNCT__ "TSGetSNESIterations"
3572 /*@
3573    TSGetSNESIterations - Gets the total number of nonlinear iterations
3574    used by the time integrator.
3575 
3576    Not Collective
3577 
3578    Input Parameter:
3579 .  ts - TS context
3580 
3581    Output Parameter:
3582 .  nits - number of nonlinear iterations
3583 
3584    Notes:
3585    This counter is reset to zero for each successive call to TSSolve().
3586 
3587    Level: intermediate
3588 
3589 .keywords: TS, get, number, nonlinear, iterations
3590 
3591 .seealso:  TSGetKSPIterations()
3592 @*/
3593 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits)
3594 {
3595   PetscFunctionBegin;
3596   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3597   PetscValidIntPointer(nits,2);
3598   *nits = ts->snes_its;
3599   PetscFunctionReturn(0);
3600 }
3601 
3602 #undef __FUNCT__
3603 #define __FUNCT__ "TSGetKSPIterations"
3604 /*@
3605    TSGetKSPIterations - Gets the total number of linear iterations
3606    used by the time integrator.
3607 
3608    Not Collective
3609 
3610    Input Parameter:
3611 .  ts - TS context
3612 
3613    Output Parameter:
3614 .  lits - number of linear iterations
3615 
3616    Notes:
3617    This counter is reset to zero for each successive call to TSSolve().
3618 
3619    Level: intermediate
3620 
3621 .keywords: TS, get, number, linear, iterations
3622 
3623 .seealso:  TSGetSNESIterations(), SNESGetKSPIterations()
3624 @*/
3625 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits)
3626 {
3627   PetscFunctionBegin;
3628   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3629   PetscValidIntPointer(lits,2);
3630   *lits = ts->ksp_its;
3631   PetscFunctionReturn(0);
3632 }
3633 
3634 #undef __FUNCT__
3635 #define __FUNCT__ "TSGetStepRejections"
3636 /*@
3637    TSGetStepRejections - Gets the total number of rejected steps.
3638 
3639    Not Collective
3640 
3641    Input Parameter:
3642 .  ts - TS context
3643 
3644    Output Parameter:
3645 .  rejects - number of steps rejected
3646 
3647    Notes:
3648    This counter is reset to zero for each successive call to TSSolve().
3649 
3650    Level: intermediate
3651 
3652 .keywords: TS, get, number
3653 
3654 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails()
3655 @*/
3656 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects)
3657 {
3658   PetscFunctionBegin;
3659   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3660   PetscValidIntPointer(rejects,2);
3661   *rejects = ts->reject;
3662   PetscFunctionReturn(0);
3663 }
3664 
3665 #undef __FUNCT__
3666 #define __FUNCT__ "TSGetSNESFailures"
3667 /*@
3668    TSGetSNESFailures - Gets the total number of failed SNES solves
3669 
3670    Not Collective
3671 
3672    Input Parameter:
3673 .  ts - TS context
3674 
3675    Output Parameter:
3676 .  fails - number of failed nonlinear solves
3677 
3678    Notes:
3679    This counter is reset to zero for each successive call to TSSolve().
3680 
3681    Level: intermediate
3682 
3683 .keywords: TS, get, number
3684 
3685 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures()
3686 @*/
3687 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails)
3688 {
3689   PetscFunctionBegin;
3690   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3691   PetscValidIntPointer(fails,2);
3692   *fails = ts->num_snes_failures;
3693   PetscFunctionReturn(0);
3694 }
3695 
3696 #undef __FUNCT__
3697 #define __FUNCT__ "TSSetMaxStepRejections"
3698 /*@
3699    TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails
3700 
3701    Not Collective
3702 
3703    Input Parameter:
3704 +  ts - TS context
3705 -  rejects - maximum number of rejected steps, pass -1 for unlimited
3706 
3707    Notes:
3708    The counter is reset to zero for each step
3709 
3710    Options Database Key:
3711  .  -ts_max_reject - Maximum number of step rejections before a step fails
3712 
3713    Level: intermediate
3714 
3715 .keywords: TS, set, maximum, number
3716 
3717 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
3718 @*/
3719 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects)
3720 {
3721   PetscFunctionBegin;
3722   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3723   ts->max_reject = rejects;
3724   PetscFunctionReturn(0);
3725 }
3726 
3727 #undef __FUNCT__
3728 #define __FUNCT__ "TSSetMaxSNESFailures"
3729 /*@
3730    TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves
3731 
3732    Not Collective
3733 
3734    Input Parameter:
3735 +  ts - TS context
3736 -  fails - maximum number of failed nonlinear solves, pass -1 for unlimited
3737 
3738    Notes:
3739    The counter is reset to zero for each successive call to TSSolve().
3740 
3741    Options Database Key:
3742  .  -ts_max_snes_failures - Maximum number of nonlinear solve failures
3743 
3744    Level: intermediate
3745 
3746 .keywords: TS, set, maximum, number
3747 
3748 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason()
3749 @*/
3750 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails)
3751 {
3752   PetscFunctionBegin;
3753   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3754   ts->max_snes_failures = fails;
3755   PetscFunctionReturn(0);
3756 }
3757 
3758 #undef __FUNCT__
3759 #define __FUNCT__ "TSSetErrorIfStepFails()"
3760 /*@
3761    TSSetErrorIfStepFails - Error if no step succeeds
3762 
3763    Not Collective
3764 
3765    Input Parameter:
3766 +  ts - TS context
3767 -  err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure
3768 
3769    Options Database Key:
3770  .  -ts_error_if_step_fails - Error if no step succeeds
3771 
3772    Level: intermediate
3773 
3774 .keywords: TS, set, error
3775 
3776 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
3777 @*/
3778 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err)
3779 {
3780   PetscFunctionBegin;
3781   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3782   ts->errorifstepfailed = err;
3783   PetscFunctionReturn(0);
3784 }
3785 
3786 #undef __FUNCT__
3787 #define __FUNCT__ "TSMonitorSolutionBinary"
3788 /*@C
3789    TSMonitorSolutionBinary - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file
3790 
3791    Collective on TS
3792 
3793    Input Parameters:
3794 +  ts - the TS context
3795 .  step - current time-step
3796 .  ptime - current time
3797 .  u - current state
3798 -  viewer - binary viewer
3799 
3800    Level: intermediate
3801 
3802 .keywords: TS,  vector, monitor, view
3803 
3804 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3805 @*/
3806 PetscErrorCode  TSMonitorSolutionBinary(TS ts,PetscInt step,PetscReal ptime,Vec u,void *viewer)
3807 {
3808   PetscErrorCode ierr;
3809   PetscViewer    v = (PetscViewer)viewer;
3810 
3811   PetscFunctionBegin;
3812   ierr = VecView(u,v);CHKERRQ(ierr);
3813   PetscFunctionReturn(0);
3814 }
3815 
3816 #undef __FUNCT__
3817 #define __FUNCT__ "TSMonitorSolutionVTK"
3818 /*@C
3819    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
3820 
3821    Collective on TS
3822 
3823    Input Parameters:
3824 +  ts - the TS context
3825 .  step - current time-step
3826 .  ptime - current time
3827 .  u - current state
3828 -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
3829 
3830    Level: intermediate
3831 
3832    Notes:
3833    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.
3834    These are named according to the file name template.
3835 
3836    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().
3837 
3838 .keywords: TS,  vector, monitor, view
3839 
3840 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3841 @*/
3842 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
3843 {
3844   PetscErrorCode ierr;
3845   char           filename[PETSC_MAX_PATH_LEN];
3846   PetscViewer    viewer;
3847 
3848   PetscFunctionBegin;
3849   ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr);
3850   ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr);
3851   ierr = VecView(u,viewer);CHKERRQ(ierr);
3852   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3853   PetscFunctionReturn(0);
3854 }
3855 
3856 #undef __FUNCT__
3857 #define __FUNCT__ "TSMonitorSolutionVTKDestroy"
3858 /*@C
3859    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
3860 
3861    Collective on TS
3862 
3863    Input Parameters:
3864 .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
3865 
3866    Level: intermediate
3867 
3868    Note:
3869    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
3870 
3871 .keywords: TS,  vector, monitor, view
3872 
3873 .seealso: TSMonitorSet(), TSMonitorSolutionVTK()
3874 @*/
3875 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
3876 {
3877   PetscErrorCode ierr;
3878 
3879   PetscFunctionBegin;
3880   ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr);
3881   PetscFunctionReturn(0);
3882 }
3883 
3884 #undef __FUNCT__
3885 #define __FUNCT__ "TSGetTSAdapt"
3886 /*@
3887    TSGetTSAdapt - Get the adaptive controller context for the current method
3888 
3889    Collective on TS if controller has not been created yet
3890 
3891    Input Arguments:
3892 .  ts - time stepping context
3893 
3894    Output Arguments:
3895 .  adapt - adaptive controller
3896 
3897    Level: intermediate
3898 
3899 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose()
3900 @*/
3901 PetscErrorCode TSGetTSAdapt(TS ts,TSAdapt *adapt)
3902 {
3903   PetscErrorCode ierr;
3904 
3905   PetscFunctionBegin;
3906   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3907   PetscValidPointer(adapt,2);
3908   if (!ts->adapt) {
3909     ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr);
3910     ierr = PetscLogObjectParent(ts,ts->adapt);CHKERRQ(ierr);
3911     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr);
3912   }
3913   *adapt = ts->adapt;
3914   PetscFunctionReturn(0);
3915 }
3916 
3917 #undef __FUNCT__
3918 #define __FUNCT__ "TSSetTolerances"
3919 /*@
3920    TSSetTolerances - Set tolerances for local truncation error when using adaptive controller
3921 
3922    Logically Collective
3923 
3924    Input Arguments:
3925 +  ts - time integration context
3926 .  atol - scalar absolute tolerances, PETSC_DECIDE to leave current value
3927 .  vatol - vector of absolute tolerances or NULL, used in preference to atol if present
3928 .  rtol - scalar relative tolerances, PETSC_DECIDE to leave current value
3929 -  vrtol - vector of relative tolerances or NULL, used in preference to atol if present
3930 
3931    Level: beginner
3932 
3933 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances()
3934 @*/
3935 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol)
3936 {
3937   PetscErrorCode ierr;
3938 
3939   PetscFunctionBegin;
3940   if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol;
3941   if (vatol) {
3942     ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr);
3943     ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
3944 
3945     ts->vatol = vatol;
3946   }
3947   if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol;
3948   if (vrtol) {
3949     ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr);
3950     ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
3951 
3952     ts->vrtol = vrtol;
3953   }
3954   PetscFunctionReturn(0);
3955 }
3956 
3957 #undef __FUNCT__
3958 #define __FUNCT__ "TSGetTolerances"
3959 /*@
3960    TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
3961 
3962    Logically Collective
3963 
3964    Input Arguments:
3965 .  ts - time integration context
3966 
3967    Output Arguments:
3968 +  atol - scalar absolute tolerances, NULL to ignore
3969 .  vatol - vector of absolute tolerances, NULL to ignore
3970 .  rtol - scalar relative tolerances, NULL to ignore
3971 -  vrtol - vector of relative tolerances, NULL to ignore
3972 
3973    Level: beginner
3974 
3975 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances()
3976 @*/
3977 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol)
3978 {
3979   PetscFunctionBegin;
3980   if (atol)  *atol  = ts->atol;
3981   if (vatol) *vatol = ts->vatol;
3982   if (rtol)  *rtol  = ts->rtol;
3983   if (vrtol) *vrtol = ts->vrtol;
3984   PetscFunctionReturn(0);
3985 }
3986 
3987 #undef __FUNCT__
3988 #define __FUNCT__ "TSErrorNormWRMS"
3989 /*@
3990    TSErrorNormWRMS - compute a weighted norm of the difference between a vector and the current state
3991 
3992    Collective on TS
3993 
3994    Input Arguments:
3995 +  ts - time stepping context
3996 -  Y - state vector to be compared to ts->vec_sol
3997 
3998    Output Arguments:
3999 .  norm - weighted norm, a value of 1.0 is considered small
4000 
4001    Level: developer
4002 
4003 .seealso: TSSetTolerances()
4004 @*/
4005 PetscErrorCode TSErrorNormWRMS(TS ts,Vec Y,PetscReal *norm)
4006 {
4007   PetscErrorCode    ierr;
4008   PetscInt          i,n,N;
4009   const PetscScalar *u,*y;
4010   Vec               U;
4011   PetscReal         sum,gsum;
4012 
4013   PetscFunctionBegin;
4014   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4015   PetscValidHeaderSpecific(Y,VEC_CLASSID,2);
4016   PetscValidPointer(norm,3);
4017   U = ts->vec_sol;
4018   PetscCheckSameTypeAndComm(U,1,Y,2);
4019   if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"Y cannot be the TS solution vector");
4020 
4021   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
4022   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
4023   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
4024   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
4025   sum  = 0.;
4026   if (ts->vatol && ts->vrtol) {
4027     const PetscScalar *atol,*rtol;
4028     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
4029     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
4030     for (i=0; i<n; i++) {
4031       PetscReal tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
4032       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
4033     }
4034     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
4035     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
4036   } else if (ts->vatol) {       /* vector atol, scalar rtol */
4037     const PetscScalar *atol;
4038     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
4039     for (i=0; i<n; i++) {
4040       PetscReal tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
4041       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
4042     }
4043     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
4044   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
4045     const PetscScalar *rtol;
4046     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
4047     for (i=0; i<n; i++) {
4048       PetscReal tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
4049       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
4050     }
4051     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
4052   } else {                      /* scalar atol, scalar rtol */
4053     for (i=0; i<n; i++) {
4054       PetscReal tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
4055       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
4056     }
4057   }
4058   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
4059   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
4060 
4061   ierr  = MPI_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
4062   *norm = PetscSqrtReal(gsum / N);
4063   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
4064   PetscFunctionReturn(0);
4065 }
4066 
4067 #undef __FUNCT__
4068 #define __FUNCT__ "TSSetCFLTimeLocal"
4069 /*@
4070    TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
4071 
4072    Logically Collective on TS
4073 
4074    Input Arguments:
4075 +  ts - time stepping context
4076 -  cfltime - maximum stable time step if using forward Euler (value can be different on each process)
4077 
4078    Note:
4079    After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
4080 
4081    Level: intermediate
4082 
4083 .seealso: TSGetCFLTime(), TSADAPTCFL
4084 @*/
4085 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime)
4086 {
4087   PetscFunctionBegin;
4088   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4089   ts->cfltime_local = cfltime;
4090   ts->cfltime       = -1.;
4091   PetscFunctionReturn(0);
4092 }
4093 
4094 #undef __FUNCT__
4095 #define __FUNCT__ "TSGetCFLTime"
4096 /*@
4097    TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
4098 
4099    Collective on TS
4100 
4101    Input Arguments:
4102 .  ts - time stepping context
4103 
4104    Output Arguments:
4105 .  cfltime - maximum stable time step for forward Euler
4106 
4107    Level: advanced
4108 
4109 .seealso: TSSetCFLTimeLocal()
4110 @*/
4111 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime)
4112 {
4113   PetscErrorCode ierr;
4114 
4115   PetscFunctionBegin;
4116   if (ts->cfltime < 0) {
4117     ierr = MPI_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
4118   }
4119   *cfltime = ts->cfltime;
4120   PetscFunctionReturn(0);
4121 }
4122 
4123 #undef __FUNCT__
4124 #define __FUNCT__ "TSVISetVariableBounds"
4125 /*@
4126    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
4127 
4128    Input Parameters:
4129 .  ts   - the TS context.
4130 .  xl   - lower bound.
4131 .  xu   - upper bound.
4132 
4133    Notes:
4134    If this routine is not called then the lower and upper bounds are set to
4135    SNES_VI_NINF and SNES_VI_INF respectively during SNESSetUp().
4136 
4137    Level: advanced
4138 
4139 @*/
4140 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
4141 {
4142   PetscErrorCode ierr;
4143   SNES           snes;
4144 
4145   PetscFunctionBegin;
4146   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4147   ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr);
4148   PetscFunctionReturn(0);
4149 }
4150 
4151 #if defined(PETSC_HAVE_MATLAB_ENGINE)
4152 #include <mex.h>
4153 
4154 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext;
4155 
4156 #undef __FUNCT__
4157 #define __FUNCT__ "TSComputeFunction_Matlab"
4158 /*
4159    TSComputeFunction_Matlab - Calls the function that has been set with
4160                          TSSetFunctionMatlab().
4161 
4162    Collective on TS
4163 
4164    Input Parameters:
4165 +  snes - the TS context
4166 -  u - input vector
4167 
4168    Output Parameter:
4169 .  y - function vector, as set by TSSetFunction()
4170 
4171    Notes:
4172    TSComputeFunction() is typically used within nonlinear solvers
4173    implementations, so most users would not generally call this routine
4174    themselves.
4175 
4176    Level: developer
4177 
4178 .keywords: TS, nonlinear, compute, function
4179 
4180 .seealso: TSSetFunction(), TSGetFunction()
4181 */
4182 PetscErrorCode  TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx)
4183 {
4184   PetscErrorCode  ierr;
4185   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
4186   int             nlhs  = 1,nrhs = 7;
4187   mxArray         *plhs[1],*prhs[7];
4188   long long int   lx = 0,lxdot = 0,ly = 0,ls = 0;
4189 
4190   PetscFunctionBegin;
4191   PetscValidHeaderSpecific(snes,TS_CLASSID,1);
4192   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
4193   PetscValidHeaderSpecific(udot,VEC_CLASSID,4);
4194   PetscValidHeaderSpecific(y,VEC_CLASSID,5);
4195   PetscCheckSameComm(snes,1,u,3);
4196   PetscCheckSameComm(snes,1,y,5);
4197 
4198   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4199   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
4200   ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr);
4201   ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr);
4202 
4203   prhs[0] =  mxCreateDoubleScalar((double)ls);
4204   prhs[1] =  mxCreateDoubleScalar(time);
4205   prhs[2] =  mxCreateDoubleScalar((double)lx);
4206   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
4207   prhs[4] =  mxCreateDoubleScalar((double)ly);
4208   prhs[5] =  mxCreateString(sctx->funcname);
4209   prhs[6] =  sctx->ctx;
4210   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr);
4211   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4212   mxDestroyArray(prhs[0]);
4213   mxDestroyArray(prhs[1]);
4214   mxDestroyArray(prhs[2]);
4215   mxDestroyArray(prhs[3]);
4216   mxDestroyArray(prhs[4]);
4217   mxDestroyArray(prhs[5]);
4218   mxDestroyArray(plhs[0]);
4219   PetscFunctionReturn(0);
4220 }
4221 
4222 
4223 #undef __FUNCT__
4224 #define __FUNCT__ "TSSetFunctionMatlab"
4225 /*
4226    TSSetFunctionMatlab - Sets the function evaluation routine and function
4227    vector for use by the TS routines in solving ODEs
4228    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
4229 
4230    Logically Collective on TS
4231 
4232    Input Parameters:
4233 +  ts - the TS context
4234 -  func - function evaluation routine
4235 
4236    Calling sequence of func:
4237 $    func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx);
4238 
4239    Level: beginner
4240 
4241 .keywords: TS, nonlinear, set, function
4242 
4243 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
4244 */
4245 PetscErrorCode  TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx)
4246 {
4247   PetscErrorCode  ierr;
4248   TSMatlabContext *sctx;
4249 
4250   PetscFunctionBegin;
4251   /* currently sctx is memory bleed */
4252   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
4253   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4254   /*
4255      This should work, but it doesn't
4256   sctx->ctx = ctx;
4257   mexMakeArrayPersistent(sctx->ctx);
4258   */
4259   sctx->ctx = mxDuplicateArray(ctx);
4260 
4261   ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr);
4262   PetscFunctionReturn(0);
4263 }
4264 
4265 #undef __FUNCT__
4266 #define __FUNCT__ "TSComputeJacobian_Matlab"
4267 /*
4268    TSComputeJacobian_Matlab - Calls the function that has been set with
4269                          TSSetJacobianMatlab().
4270 
4271    Collective on TS
4272 
4273    Input Parameters:
4274 +  ts - the TS context
4275 .  u - input vector
4276 .  A, B - the matrices
4277 -  ctx - user context
4278 
4279    Output Parameter:
4280 .  flag - structure of the matrix
4281 
4282    Level: developer
4283 
4284 .keywords: TS, nonlinear, compute, function
4285 
4286 .seealso: TSSetFunction(), TSGetFunction()
4287 @*/
4288 PetscErrorCode  TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flag, void *ctx)
4289 {
4290   PetscErrorCode  ierr;
4291   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
4292   int             nlhs  = 2,nrhs = 9;
4293   mxArray         *plhs[2],*prhs[9];
4294   long long int   lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0;
4295 
4296   PetscFunctionBegin;
4297   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4298   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
4299 
4300   /* call Matlab function in ctx with arguments u and y */
4301 
4302   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
4303   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
4304   ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr);
4305   ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr);
4306   ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr);
4307 
4308   prhs[0] =  mxCreateDoubleScalar((double)ls);
4309   prhs[1] =  mxCreateDoubleScalar((double)time);
4310   prhs[2] =  mxCreateDoubleScalar((double)lx);
4311   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
4312   prhs[4] =  mxCreateDoubleScalar((double)shift);
4313   prhs[5] =  mxCreateDoubleScalar((double)lA);
4314   prhs[6] =  mxCreateDoubleScalar((double)lB);
4315   prhs[7] =  mxCreateString(sctx->funcname);
4316   prhs[8] =  sctx->ctx;
4317   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr);
4318   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4319   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
4320   mxDestroyArray(prhs[0]);
4321   mxDestroyArray(prhs[1]);
4322   mxDestroyArray(prhs[2]);
4323   mxDestroyArray(prhs[3]);
4324   mxDestroyArray(prhs[4]);
4325   mxDestroyArray(prhs[5]);
4326   mxDestroyArray(prhs[6]);
4327   mxDestroyArray(prhs[7]);
4328   mxDestroyArray(plhs[0]);
4329   mxDestroyArray(plhs[1]);
4330   PetscFunctionReturn(0);
4331 }
4332 
4333 
4334 #undef __FUNCT__
4335 #define __FUNCT__ "TSSetJacobianMatlab"
4336 /*
4337    TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
4338    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
4339 
4340    Logically Collective on TS
4341 
4342    Input Parameters:
4343 +  ts - the TS context
4344 .  A,B - Jacobian matrices
4345 .  func - function evaluation routine
4346 -  ctx - user context
4347 
4348    Calling sequence of func:
4349 $    flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx);
4350 
4351 
4352    Level: developer
4353 
4354 .keywords: TS, nonlinear, set, function
4355 
4356 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
4357 */
4358 PetscErrorCode  TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx)
4359 {
4360   PetscErrorCode  ierr;
4361   TSMatlabContext *sctx;
4362 
4363   PetscFunctionBegin;
4364   /* currently sctx is memory bleed */
4365   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
4366   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4367   /*
4368      This should work, but it doesn't
4369   sctx->ctx = ctx;
4370   mexMakeArrayPersistent(sctx->ctx);
4371   */
4372   sctx->ctx = mxDuplicateArray(ctx);
4373 
4374   ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
4375   PetscFunctionReturn(0);
4376 }
4377 
4378 #undef __FUNCT__
4379 #define __FUNCT__ "TSMonitor_Matlab"
4380 /*
4381    TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab().
4382 
4383    Collective on TS
4384 
4385 .seealso: TSSetFunction(), TSGetFunction()
4386 @*/
4387 PetscErrorCode  TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx)
4388 {
4389   PetscErrorCode  ierr;
4390   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
4391   int             nlhs  = 1,nrhs = 6;
4392   mxArray         *plhs[1],*prhs[6];
4393   long long int   lx = 0,ls = 0;
4394 
4395   PetscFunctionBegin;
4396   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4397   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
4398 
4399   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
4400   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
4401 
4402   prhs[0] =  mxCreateDoubleScalar((double)ls);
4403   prhs[1] =  mxCreateDoubleScalar((double)it);
4404   prhs[2] =  mxCreateDoubleScalar((double)time);
4405   prhs[3] =  mxCreateDoubleScalar((double)lx);
4406   prhs[4] =  mxCreateString(sctx->funcname);
4407   prhs[5] =  sctx->ctx;
4408   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr);
4409   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4410   mxDestroyArray(prhs[0]);
4411   mxDestroyArray(prhs[1]);
4412   mxDestroyArray(prhs[2]);
4413   mxDestroyArray(prhs[3]);
4414   mxDestroyArray(prhs[4]);
4415   mxDestroyArray(plhs[0]);
4416   PetscFunctionReturn(0);
4417 }
4418 
4419 
4420 #undef __FUNCT__
4421 #define __FUNCT__ "TSMonitorSetMatlab"
4422 /*
4423    TSMonitorSetMatlab - Sets the monitor function from Matlab
4424 
4425    Level: developer
4426 
4427 .keywords: TS, nonlinear, set, function
4428 
4429 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
4430 */
4431 PetscErrorCode  TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx)
4432 {
4433   PetscErrorCode  ierr;
4434   TSMatlabContext *sctx;
4435 
4436   PetscFunctionBegin;
4437   /* currently sctx is memory bleed */
4438   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
4439   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4440   /*
4441      This should work, but it doesn't
4442   sctx->ctx = ctx;
4443   mexMakeArrayPersistent(sctx->ctx);
4444   */
4445   sctx->ctx = mxDuplicateArray(ctx);
4446 
4447   ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr);
4448   PetscFunctionReturn(0);
4449 }
4450 #endif
4451 
4452 
4453 
4454 #undef __FUNCT__
4455 #define __FUNCT__ "TSMonitorLGSolution"
4456 /*@C
4457    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
4458        in a time based line graph
4459 
4460    Collective on TS
4461 
4462    Input Parameters:
4463 +  ts - the TS context
4464 .  step - current time-step
4465 .  ptime - current time
4466 -  lg - a line graph object
4467 
4468    Level: intermediate
4469 
4470     Notes: each process in a parallel run displays its component solutions in a separate window
4471 
4472 .keywords: TS,  vector, monitor, view
4473 
4474 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4475 @*/
4476 PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4477 {
4478   PetscErrorCode    ierr;
4479   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
4480   const PetscScalar *yy;
4481   PetscInt          dim;
4482 
4483   PetscFunctionBegin;
4484   if (!step) {
4485     PetscDrawAxis axis;
4486     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4487     ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr);
4488     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
4489     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
4490     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4491   }
4492   ierr = VecGetArrayRead(u,&yy);CHKERRQ(ierr);
4493 #if defined(PETSC_USE_COMPLEX)
4494   {
4495     PetscReal *yreal;
4496     PetscInt  i,n;
4497     ierr = VecGetLocalSize(u,&n);CHKERRQ(ierr);
4498     ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr);
4499     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
4500     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
4501     ierr = PetscFree(yreal);CHKERRQ(ierr);
4502   }
4503 #else
4504   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
4505 #endif
4506   ierr = VecRestoreArrayRead(u,&yy);CHKERRQ(ierr);
4507   if (((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1))) {
4508     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4509   }
4510   PetscFunctionReturn(0);
4511 }
4512 
4513 #undef __FUNCT__
4514 #define __FUNCT__ "TSMonitorLGError"
4515 /*@C
4516    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector
4517        in a time based line graph
4518 
4519    Collective on TS
4520 
4521    Input Parameters:
4522 +  ts - the TS context
4523 .  step - current time-step
4524 .  ptime - current time
4525 -  lg - a line graph object
4526 
4527    Level: intermediate
4528 
4529    Notes:
4530    Only for sequential solves.
4531 
4532    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
4533 
4534    Options Database Keys:
4535 .  -ts_monitor_lg_error - create a graphical monitor of error history
4536 
4537 .keywords: TS,  vector, monitor, view
4538 
4539 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
4540 @*/
4541 PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4542 {
4543   PetscErrorCode    ierr;
4544   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
4545   const PetscScalar *yy;
4546   Vec               y;
4547   PetscInt          dim;
4548 
4549   PetscFunctionBegin;
4550   if (!step) {
4551     PetscDrawAxis axis;
4552     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4553     ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr);
4554     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
4555     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
4556     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4557   }
4558   ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
4559   ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr);
4560   ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr);
4561   ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr);
4562 #if defined(PETSC_USE_COMPLEX)
4563   {
4564     PetscReal *yreal;
4565     PetscInt  i,n;
4566     ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr);
4567     ierr = PetscMalloc(n*sizeof(PetscReal),&yreal);CHKERRQ(ierr);
4568     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
4569     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
4570     ierr = PetscFree(yreal);CHKERRQ(ierr);
4571   }
4572 #else
4573   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
4574 #endif
4575   ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr);
4576   ierr = VecDestroy(&y);CHKERRQ(ierr);
4577   if (((ctx->howoften > 0) && (!(step % ctx->howoften)) && (step > -1)) || ((ctx->howoften == -1) && (step == -1))) {
4578     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4579   }
4580   PetscFunctionReturn(0);
4581 }
4582 
4583 #undef __FUNCT__
4584 #define __FUNCT__ "TSMonitorLGSNESIterations"
4585 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
4586 {
4587   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
4588   PetscReal      x   = ptime,y;
4589   PetscErrorCode ierr;
4590   PetscInt       its;
4591 
4592   PetscFunctionBegin;
4593   if (!n) {
4594     PetscDrawAxis axis;
4595 
4596     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4597     ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr);
4598     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4599 
4600     ctx->snes_its = 0;
4601   }
4602   ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr);
4603   y    = its - ctx->snes_its;
4604   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
4605   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
4606     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4607   }
4608   ctx->snes_its = its;
4609   PetscFunctionReturn(0);
4610 }
4611 
4612 #undef __FUNCT__
4613 #define __FUNCT__ "TSMonitorLGKSPIterations"
4614 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
4615 {
4616   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
4617   PetscReal      x   = ptime,y;
4618   PetscErrorCode ierr;
4619   PetscInt       its;
4620 
4621   PetscFunctionBegin;
4622   if (!n) {
4623     PetscDrawAxis axis;
4624 
4625     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
4626     ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr);
4627     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
4628 
4629     ctx->ksp_its = 0;
4630   }
4631   ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr);
4632   y    = its - ctx->ksp_its;
4633   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
4634   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
4635     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
4636   }
4637   ctx->ksp_its = its;
4638   PetscFunctionReturn(0);
4639 }
4640 
4641 #undef __FUNCT__
4642 #define __FUNCT__ "TSComputeLinearStability"
4643 /*@
4644    TSComputeLinearStability - computes the linear stability function at a point
4645 
4646    Collective on TS and Vec
4647 
4648    Input Parameters:
4649 +  ts - the TS context
4650 -  xr,xi - real and imaginary part of input arguments
4651 
4652    Output Parameters:
4653 .  yr,yi - real and imaginary part of function value
4654 
4655    Level: developer
4656 
4657 .keywords: TS, compute
4658 
4659 .seealso: TSSetRHSFunction(), TSComputeIFunction()
4660 @*/
4661 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi)
4662 {
4663   PetscErrorCode ierr;
4664 
4665   PetscFunctionBegin;
4666   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4667   if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method");
4668   ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr);
4669   PetscFunctionReturn(0);
4670 }
4671