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