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