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