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