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