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