xref: /petsc/src/ts/interface/ts.c (revision 5a3a76d07e72bd733c23cdbf132d31c2a5ff3d88)
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->ptime >= ts->max_time) {
1865       ierr = TSInterpolate(ts,ts->max_time,x);CHKERRQ(ierr);
1866       if (ftime) *ftime = ts->max_time;
1867     } else if (ftime) *ftime = ts->ptime;
1868   }
1869   ierr = PetscOptionsGetString(((PetscObject)ts)->prefix,"-ts_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
1870   if (flg && !PetscPreLoadingOn) {
1871     ierr = PetscViewerASCIIOpen(((PetscObject)ts)->comm,filename,&viewer);CHKERRQ(ierr);
1872     ierr = TSView(ts,viewer);CHKERRQ(ierr);
1873     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1874   }
1875   PetscFunctionReturn(0);
1876 }
1877 
1878 #undef __FUNCT__
1879 #define __FUNCT__ "TSMonitor"
1880 /*
1881      Runs the user provided monitor routines, if they exists.
1882 */
1883 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec x)
1884 {
1885   PetscErrorCode ierr;
1886   PetscInt       i,n = ts->numbermonitors;
1887 
1888   PetscFunctionBegin;
1889   for (i=0; i<n; i++) {
1890     ierr = (*ts->monitor[i])(ts,step,ptime,x,ts->monitorcontext[i]);CHKERRQ(ierr);
1891   }
1892   PetscFunctionReturn(0);
1893 }
1894 
1895 /* ------------------------------------------------------------------------*/
1896 
1897 #undef __FUNCT__
1898 #define __FUNCT__ "TSMonitorLGCreate"
1899 /*@C
1900    TSMonitorLGCreate - Creates a line graph context for use with
1901    TS to monitor convergence of preconditioned residual norms.
1902 
1903    Collective on TS
1904 
1905    Input Parameters:
1906 +  host - the X display to open, or null for the local machine
1907 .  label - the title to put in the title bar
1908 .  x, y - the screen coordinates of the upper left coordinate of the window
1909 -  m, n - the screen width and height in pixels
1910 
1911    Output Parameter:
1912 .  draw - the drawing context
1913 
1914    Options Database Key:
1915 .  -ts_monitor_draw - automatically sets line graph monitor
1916 
1917    Notes:
1918    Use TSMonitorLGDestroy() to destroy this line graph, not PetscDrawLGDestroy().
1919 
1920    Level: intermediate
1921 
1922 .keywords: TS, monitor, line graph, residual, seealso
1923 
1924 .seealso: TSMonitorLGDestroy(), TSMonitorSet()
1925 
1926 @*/
1927 PetscErrorCode  TSMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1928 {
1929   PetscDraw      win;
1930   PetscErrorCode ierr;
1931 
1932   PetscFunctionBegin;
1933   ierr = PetscDrawCreate(PETSC_COMM_SELF,host,label,x,y,m,n,&win);CHKERRQ(ierr);
1934   ierr = PetscDrawSetType(win,PETSC_DRAW_X);CHKERRQ(ierr);
1935   ierr = PetscDrawLGCreate(win,1,draw);CHKERRQ(ierr);
1936   ierr = PetscDrawLGIndicateDataPoints(*draw);CHKERRQ(ierr);
1937 
1938   ierr = PetscLogObjectParent(*draw,win);CHKERRQ(ierr);
1939   PetscFunctionReturn(0);
1940 }
1941 
1942 #undef __FUNCT__
1943 #define __FUNCT__ "TSMonitorLG"
1944 PetscErrorCode TSMonitorLG(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
1945 {
1946   PetscDrawLG    lg = (PetscDrawLG) monctx;
1947   PetscReal      x,y = ptime;
1948   PetscErrorCode ierr;
1949 
1950   PetscFunctionBegin;
1951   if (!monctx) {
1952     MPI_Comm    comm;
1953     PetscViewer viewer;
1954 
1955     ierr   = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr);
1956     viewer = PETSC_VIEWER_DRAW_(comm);
1957     ierr   = PetscViewerDrawGetDrawLG(viewer,0,&lg);CHKERRQ(ierr);
1958   }
1959 
1960   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
1961   x = (PetscReal)n;
1962   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
1963   if (n < 20 || (n % 5)) {
1964     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
1965   }
1966   PetscFunctionReturn(0);
1967 }
1968 
1969 #undef __FUNCT__
1970 #define __FUNCT__ "TSMonitorLGDestroy"
1971 /*@C
1972    TSMonitorLGDestroy - Destroys a line graph context that was created
1973    with TSMonitorLGCreate().
1974 
1975    Collective on PetscDrawLG
1976 
1977    Input Parameter:
1978 .  draw - the drawing context
1979 
1980    Level: intermediate
1981 
1982 .keywords: TS, monitor, line graph, destroy
1983 
1984 .seealso: TSMonitorLGCreate(),  TSMonitorSet(), TSMonitorLG();
1985 @*/
1986 PetscErrorCode  TSMonitorLGDestroy(PetscDrawLG *drawlg)
1987 {
1988   PetscDraw      draw;
1989   PetscErrorCode ierr;
1990 
1991   PetscFunctionBegin;
1992   ierr = PetscDrawLGGetDraw(*drawlg,&draw);CHKERRQ(ierr);
1993   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
1994   ierr = PetscDrawLGDestroy(drawlg);CHKERRQ(ierr);
1995   PetscFunctionReturn(0);
1996 }
1997 
1998 #undef __FUNCT__
1999 #define __FUNCT__ "TSGetTime"
2000 /*@
2001    TSGetTime - Gets the current time.
2002 
2003    Not Collective
2004 
2005    Input Parameter:
2006 .  ts - the TS context obtained from TSCreate()
2007 
2008    Output Parameter:
2009 .  t  - the current time
2010 
2011    Level: beginner
2012 
2013 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
2014 
2015 .keywords: TS, get, time
2016 @*/
2017 PetscErrorCode  TSGetTime(TS ts,PetscReal* t)
2018 {
2019   PetscFunctionBegin;
2020   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2021   PetscValidDoublePointer(t,2);
2022   *t = ts->ptime;
2023   PetscFunctionReturn(0);
2024 }
2025 
2026 #undef __FUNCT__
2027 #define __FUNCT__ "TSSetTime"
2028 /*@
2029    TSSetTime - Allows one to reset the time.
2030 
2031    Logically Collective on TS
2032 
2033    Input Parameters:
2034 +  ts - the TS context obtained from TSCreate()
2035 -  time - the time
2036 
2037    Level: intermediate
2038 
2039 .seealso: TSGetTime(), TSSetDuration()
2040 
2041 .keywords: TS, set, time
2042 @*/
2043 PetscErrorCode  TSSetTime(TS ts, PetscReal t)
2044 {
2045   PetscFunctionBegin;
2046   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2047   PetscValidLogicalCollectiveReal(ts,t,2);
2048   ts->ptime = t;
2049   PetscFunctionReturn(0);
2050 }
2051 
2052 #undef __FUNCT__
2053 #define __FUNCT__ "TSSetOptionsPrefix"
2054 /*@C
2055    TSSetOptionsPrefix - Sets the prefix used for searching for all
2056    TS options in the database.
2057 
2058    Logically Collective on TS
2059 
2060    Input Parameter:
2061 +  ts     - The TS context
2062 -  prefix - The prefix to prepend to all option names
2063 
2064    Notes:
2065    A hyphen (-) must NOT be given at the beginning of the prefix name.
2066    The first character of all runtime options is AUTOMATICALLY the
2067    hyphen.
2068 
2069    Level: advanced
2070 
2071 .keywords: TS, set, options, prefix, database
2072 
2073 .seealso: TSSetFromOptions()
2074 
2075 @*/
2076 PetscErrorCode  TSSetOptionsPrefix(TS ts,const char prefix[])
2077 {
2078   PetscErrorCode ierr;
2079   SNES           snes;
2080 
2081   PetscFunctionBegin;
2082   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2083   ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2084   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2085   ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr);
2086   PetscFunctionReturn(0);
2087 }
2088 
2089 
2090 #undef __FUNCT__
2091 #define __FUNCT__ "TSAppendOptionsPrefix"
2092 /*@C
2093    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
2094    TS options in the database.
2095 
2096    Logically Collective on TS
2097 
2098    Input Parameter:
2099 +  ts     - The TS context
2100 -  prefix - The prefix to prepend to all option names
2101 
2102    Notes:
2103    A hyphen (-) must NOT be given at the beginning of the prefix name.
2104    The first character of all runtime options is AUTOMATICALLY the
2105    hyphen.
2106 
2107    Level: advanced
2108 
2109 .keywords: TS, append, options, prefix, database
2110 
2111 .seealso: TSGetOptionsPrefix()
2112 
2113 @*/
2114 PetscErrorCode  TSAppendOptionsPrefix(TS ts,const char prefix[])
2115 {
2116   PetscErrorCode ierr;
2117   SNES           snes;
2118 
2119   PetscFunctionBegin;
2120   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2121   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2122   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2123   ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr);
2124   PetscFunctionReturn(0);
2125 }
2126 
2127 #undef __FUNCT__
2128 #define __FUNCT__ "TSGetOptionsPrefix"
2129 /*@C
2130    TSGetOptionsPrefix - Sets the prefix used for searching for all
2131    TS options in the database.
2132 
2133    Not Collective
2134 
2135    Input Parameter:
2136 .  ts - The TS context
2137 
2138    Output Parameter:
2139 .  prefix - A pointer to the prefix string used
2140 
2141    Notes: On the fortran side, the user should pass in a string 'prifix' of
2142    sufficient length to hold the prefix.
2143 
2144    Level: intermediate
2145 
2146 .keywords: TS, get, options, prefix, database
2147 
2148 .seealso: TSAppendOptionsPrefix()
2149 @*/
2150 PetscErrorCode  TSGetOptionsPrefix(TS ts,const char *prefix[])
2151 {
2152   PetscErrorCode ierr;
2153 
2154   PetscFunctionBegin;
2155   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2156   PetscValidPointer(prefix,2);
2157   ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
2158   PetscFunctionReturn(0);
2159 }
2160 
2161 #undef __FUNCT__
2162 #define __FUNCT__ "TSGetRHSJacobian"
2163 /*@C
2164    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
2165 
2166    Not Collective, but parallel objects are returned if TS is parallel
2167 
2168    Input Parameter:
2169 .  ts  - The TS context obtained from TSCreate()
2170 
2171    Output Parameters:
2172 +  J   - The Jacobian J of F, where U_t = F(U,t)
2173 .  M   - The preconditioner matrix, usually the same as J
2174 .  func - Function to compute the Jacobian of the RHS
2175 -  ctx - User-defined context for Jacobian evaluation routine
2176 
2177    Notes: You can pass in PETSC_NULL for any return argument you do not need.
2178 
2179    Level: intermediate
2180 
2181 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
2182 
2183 .keywords: TS, timestep, get, matrix, Jacobian
2184 @*/
2185 PetscErrorCode  TSGetRHSJacobian(TS ts,Mat *J,Mat *M,TSRHSJacobian *func,void **ctx)
2186 {
2187   PetscErrorCode ierr;
2188   SNES           snes;
2189 
2190   PetscFunctionBegin;
2191   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2192   ierr = SNESGetJacobian(snes,J,M,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2193   if (func) *func = ts->userops->rhsjacobian;
2194   if (ctx) *ctx = ts->jacP;
2195   PetscFunctionReturn(0);
2196 }
2197 
2198 #undef __FUNCT__
2199 #define __FUNCT__ "TSGetIJacobian"
2200 /*@C
2201    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
2202 
2203    Not Collective, but parallel objects are returned if TS is parallel
2204 
2205    Input Parameter:
2206 .  ts  - The TS context obtained from TSCreate()
2207 
2208    Output Parameters:
2209 +  A   - The Jacobian of F(t,U,U_t)
2210 .  B   - The preconditioner matrix, often the same as A
2211 .  f   - The function to compute the matrices
2212 - ctx - User-defined context for Jacobian evaluation routine
2213 
2214    Notes: You can pass in PETSC_NULL for any return argument you do not need.
2215 
2216    Level: advanced
2217 
2218 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
2219 
2220 .keywords: TS, timestep, get, matrix, Jacobian
2221 @*/
2222 PetscErrorCode  TSGetIJacobian(TS ts,Mat *A,Mat *B,TSIJacobian *f,void **ctx)
2223 {
2224   PetscErrorCode ierr;
2225   SNES           snes;
2226 
2227   PetscFunctionBegin;
2228   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2229   ierr = SNESGetJacobian(snes,A,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2230   if (f) *f = ts->userops->ijacobian;
2231   if (ctx) *ctx = ts->jacP;
2232   PetscFunctionReturn(0);
2233 }
2234 
2235 #undef __FUNCT__
2236 #define __FUNCT__ "TSMonitorSolution"
2237 /*@C
2238    TSMonitorSolution - Monitors progress of the TS solvers by calling
2239    VecView() for the solution at each timestep
2240 
2241    Collective on TS
2242 
2243    Input Parameters:
2244 +  ts - the TS context
2245 .  step - current time-step
2246 .  ptime - current time
2247 -  dummy - either a viewer or PETSC_NULL
2248 
2249    Level: intermediate
2250 
2251 .keywords: TS,  vector, monitor, view
2252 
2253 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
2254 @*/
2255 PetscErrorCode  TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec x,void *dummy)
2256 {
2257   PetscErrorCode ierr;
2258   PetscViewer    viewer = (PetscViewer) dummy;
2259 
2260   PetscFunctionBegin;
2261   if (!dummy) {
2262     viewer = PETSC_VIEWER_DRAW_(((PetscObject)ts)->comm);
2263   }
2264   ierr = VecView(x,viewer);CHKERRQ(ierr);
2265   PetscFunctionReturn(0);
2266 }
2267 
2268 
2269 #undef __FUNCT__
2270 #define __FUNCT__ "TSSetDM"
2271 /*@
2272    TSSetDM - Sets the DM that may be used by some preconditioners
2273 
2274    Logically Collective on TS and DM
2275 
2276    Input Parameters:
2277 +  ts - the preconditioner context
2278 -  dm - the dm
2279 
2280    Level: intermediate
2281 
2282 
2283 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM()
2284 @*/
2285 PetscErrorCode  TSSetDM(TS ts,DM dm)
2286 {
2287   PetscErrorCode ierr;
2288   SNES           snes;
2289 
2290   PetscFunctionBegin;
2291   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2292   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
2293   ierr = DMDestroy(&ts->dm);CHKERRQ(ierr);
2294   ts->dm = dm;
2295   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2296   ierr = SNESSetDM(snes,dm);CHKERRQ(ierr);
2297   PetscFunctionReturn(0);
2298 }
2299 
2300 #undef __FUNCT__
2301 #define __FUNCT__ "TSGetDM"
2302 /*@
2303    TSGetDM - Gets the DM that may be used by some preconditioners
2304 
2305    Not Collective
2306 
2307    Input Parameter:
2308 . ts - the preconditioner context
2309 
2310    Output Parameter:
2311 .  dm - the dm
2312 
2313    Level: intermediate
2314 
2315 
2316 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM()
2317 @*/
2318 PetscErrorCode  TSGetDM(TS ts,DM *dm)
2319 {
2320   PetscFunctionBegin;
2321   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2322   *dm = ts->dm;
2323   PetscFunctionReturn(0);
2324 }
2325 
2326 #undef __FUNCT__
2327 #define __FUNCT__ "SNESTSFormFunction"
2328 /*@
2329    SNESTSFormFunction - Function to evaluate nonlinear residual
2330 
2331    Logically Collective on SNES
2332 
2333    Input Parameter:
2334 + snes - nonlinear solver
2335 . X - the current state at which to evaluate the residual
2336 - ctx - user context, must be a TS
2337 
2338    Output Parameter:
2339 . F - the nonlinear residual
2340 
2341    Notes:
2342    This function is not normally called by users and is automatically registered with the SNES used by TS.
2343    It is most frequently passed to MatFDColoringSetFunction().
2344 
2345    Level: advanced
2346 
2347 .seealso: SNESSetFunction(), MatFDColoringSetFunction()
2348 @*/
2349 PetscErrorCode  SNESTSFormFunction(SNES snes,Vec X,Vec F,void *ctx)
2350 {
2351   TS ts = (TS)ctx;
2352   PetscErrorCode ierr;
2353 
2354   PetscFunctionBegin;
2355   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2356   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
2357   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
2358   PetscValidHeaderSpecific(ts,TS_CLASSID,4);
2359   ierr = (ts->ops->snesfunction)(snes,X,F,ts);CHKERRQ(ierr);
2360   PetscFunctionReturn(0);
2361 }
2362 
2363 #undef __FUNCT__
2364 #define __FUNCT__ "SNESTSFormJacobian"
2365 /*@
2366    SNESTSFormJacobian - Function to evaluate the Jacobian
2367 
2368    Collective on SNES
2369 
2370    Input Parameter:
2371 + snes - nonlinear solver
2372 . X - the current state at which to evaluate the residual
2373 - ctx - user context, must be a TS
2374 
2375    Output Parameter:
2376 + A - the Jacobian
2377 . B - the preconditioning matrix (may be the same as A)
2378 - flag - indicates any structure change in the matrix
2379 
2380    Notes:
2381    This function is not normally called by users and is automatically registered with the SNES used by TS.
2382 
2383    Level: developer
2384 
2385 .seealso: SNESSetJacobian()
2386 @*/
2387 PetscErrorCode  SNESTSFormJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flag,void *ctx)
2388 {
2389   TS ts = (TS)ctx;
2390   PetscErrorCode ierr;
2391 
2392   PetscFunctionBegin;
2393   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2394   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
2395   PetscValidPointer(A,3);
2396   PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
2397   PetscValidPointer(B,4);
2398   PetscValidHeaderSpecific(*B,MAT_CLASSID,4);
2399   PetscValidPointer(flag,5);
2400   PetscValidHeaderSpecific(ts,TS_CLASSID,6);
2401   ierr = (ts->ops->snesjacobian)(snes,X,A,B,flag,ts);CHKERRQ(ierr);
2402   PetscFunctionReturn(0);
2403 }
2404 
2405 #undef __FUNCT__
2406 #define __FUNCT__ "TSComputeRHSFunctionLinear"
2407 /*@C
2408    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only
2409 
2410    Collective on TS
2411 
2412    Input Arguments:
2413 +  ts - time stepping context
2414 .  t - time at which to evaluate
2415 .  X - state at which to evaluate
2416 -  ctx - context
2417 
2418    Output Arguments:
2419 .  F - right hand side
2420 
2421    Level: intermediate
2422 
2423    Notes:
2424    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
2425    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().
2426 
2427 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
2428 @*/
2429 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec X,Vec F,void *ctx)
2430 {
2431   PetscErrorCode ierr;
2432   Mat Arhs,Brhs;
2433   MatStructure flg2;
2434 
2435   PetscFunctionBegin;
2436   ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
2437   ierr = TSComputeRHSJacobian(ts,t,X,&Arhs,&Brhs,&flg2);CHKERRQ(ierr);
2438   ierr = MatMult(Arhs,X,F);CHKERRQ(ierr);
2439   PetscFunctionReturn(0);
2440 }
2441 
2442 #undef __FUNCT__
2443 #define __FUNCT__ "TSComputeRHSJacobianConstant"
2444 /*@C
2445    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
2446 
2447    Collective on TS
2448 
2449    Input Arguments:
2450 +  ts - time stepping context
2451 .  t - time at which to evaluate
2452 .  X - state at which to evaluate
2453 -  ctx - context
2454 
2455    Output Arguments:
2456 +  A - pointer to operator
2457 .  B - pointer to preconditioning matrix
2458 -  flg - matrix structure flag
2459 
2460    Level: intermediate
2461 
2462    Notes:
2463    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.
2464 
2465 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear()
2466 @*/
2467 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec X,Mat *A,Mat *B,MatStructure *flg,void *ctx)
2468 {
2469 
2470   PetscFunctionBegin;
2471   *flg = SAME_PRECONDITIONER;
2472   PetscFunctionReturn(0);
2473 }
2474 
2475 #undef __FUNCT__
2476 #define __FUNCT__ "TSComputeIFunctionLinear"
2477 /*@C
2478    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
2479 
2480    Collective on TS
2481 
2482    Input Arguments:
2483 +  ts - time stepping context
2484 .  t - time at which to evaluate
2485 .  X - state at which to evaluate
2486 .  Xdot - time derivative of state vector
2487 -  ctx - context
2488 
2489    Output Arguments:
2490 .  F - left hand side
2491 
2492    Level: intermediate
2493 
2494    Notes:
2495    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
2496    user is required to write their own TSComputeIFunction.
2497    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
2498    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().
2499 
2500 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant()
2501 @*/
2502 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec X,Vec Xdot,Vec F,void *ctx)
2503 {
2504   PetscErrorCode ierr;
2505   Mat A,B;
2506   MatStructure flg2;
2507 
2508   PetscFunctionBegin;
2509   ierr = TSGetIJacobian(ts,&A,&B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2510   ierr = TSComputeIJacobian(ts,t,X,Xdot,1.0,&A,&B,&flg2,PETSC_TRUE);CHKERRQ(ierr);
2511   ierr = MatMult(A,Xdot,F);CHKERRQ(ierr);
2512   PetscFunctionReturn(0);
2513 }
2514 
2515 #undef __FUNCT__
2516 #define __FUNCT__ "TSComputeIJacobianConstant"
2517 /*@C
2518    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
2519 
2520    Collective on TS
2521 
2522    Input Arguments:
2523 +  ts - time stepping context
2524 .  t - time at which to evaluate
2525 .  X - state at which to evaluate
2526 .  Xdot - time derivative of state vector
2527 .  shift - shift to apply
2528 -  ctx - context
2529 
2530    Output Arguments:
2531 +  A - pointer to operator
2532 .  B - pointer to preconditioning matrix
2533 -  flg - matrix structure flag
2534 
2535    Level: intermediate
2536 
2537    Notes:
2538    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.
2539 
2540 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear()
2541 @*/
2542 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flg,void *ctx)
2543 {
2544 
2545   PetscFunctionBegin;
2546   *flg = SAME_PRECONDITIONER;
2547   PetscFunctionReturn(0);
2548 }
2549 
2550 
2551 #undef __FUNCT__
2552 #define __FUNCT__ "TSGetConvergedReason"
2553 /*@
2554    TSGetConvergedReason - Gets the reason the TS iteration was stopped.
2555 
2556    Not Collective
2557 
2558    Input Parameter:
2559 .  ts - the TS context
2560 
2561    Output Parameter:
2562 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
2563             manual pages for the individual convergence tests for complete lists
2564 
2565    Level: intermediate
2566 
2567    Notes:
2568    Can only be called after the call to TSSolve() is complete.
2569 
2570 .keywords: TS, nonlinear, set, convergence, test
2571 
2572 .seealso: TSSetConvergenceTest(), TSConvergedReason
2573 @*/
2574 PetscErrorCode  TSGetConvergedReason(TS ts,TSConvergedReason *reason)
2575 {
2576   PetscFunctionBegin;
2577   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2578   PetscValidPointer(reason,2);
2579   *reason = ts->reason;
2580   PetscFunctionReturn(0);
2581 }
2582 
2583 #if defined(PETSC_HAVE_MATLAB_ENGINE)
2584 #include <mex.h>
2585 
2586 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext;
2587 
2588 #undef __FUNCT__
2589 #define __FUNCT__ "TSComputeFunction_Matlab"
2590 /*
2591    TSComputeFunction_Matlab - Calls the function that has been set with
2592                          TSSetFunctionMatlab().
2593 
2594    Collective on TS
2595 
2596    Input Parameters:
2597 +  snes - the TS context
2598 -  x - input vector
2599 
2600    Output Parameter:
2601 .  y - function vector, as set by TSSetFunction()
2602 
2603    Notes:
2604    TSComputeFunction() is typically used within nonlinear solvers
2605    implementations, so most users would not generally call this routine
2606    themselves.
2607 
2608    Level: developer
2609 
2610 .keywords: TS, nonlinear, compute, function
2611 
2612 .seealso: TSSetFunction(), TSGetFunction()
2613 */
2614 PetscErrorCode  TSComputeFunction_Matlab(TS snes,PetscReal time,Vec x,Vec xdot,Vec y, void *ctx)
2615 {
2616   PetscErrorCode   ierr;
2617   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
2618   int              nlhs = 1,nrhs = 7;
2619   mxArray          *plhs[1],*prhs[7];
2620   long long int    lx = 0,lxdot = 0,ly = 0,ls = 0;
2621 
2622   PetscFunctionBegin;
2623   PetscValidHeaderSpecific(snes,TS_CLASSID,1);
2624   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
2625   PetscValidHeaderSpecific(xdot,VEC_CLASSID,4);
2626   PetscValidHeaderSpecific(y,VEC_CLASSID,5);
2627   PetscCheckSameComm(snes,1,x,3);
2628   PetscCheckSameComm(snes,1,y,5);
2629 
2630   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
2631   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
2632   ierr = PetscMemcpy(&lxdot,&xdot,sizeof(xdot));CHKERRQ(ierr);
2633   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
2634   prhs[0] =  mxCreateDoubleScalar((double)ls);
2635   prhs[1] =  mxCreateDoubleScalar(time);
2636   prhs[2] =  mxCreateDoubleScalar((double)lx);
2637   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
2638   prhs[4] =  mxCreateDoubleScalar((double)ly);
2639   prhs[5] =  mxCreateString(sctx->funcname);
2640   prhs[6] =  sctx->ctx;
2641   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr);
2642   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
2643   mxDestroyArray(prhs[0]);
2644   mxDestroyArray(prhs[1]);
2645   mxDestroyArray(prhs[2]);
2646   mxDestroyArray(prhs[3]);
2647   mxDestroyArray(prhs[4]);
2648   mxDestroyArray(prhs[5]);
2649   mxDestroyArray(plhs[0]);
2650   PetscFunctionReturn(0);
2651 }
2652 
2653 
2654 #undef __FUNCT__
2655 #define __FUNCT__ "TSSetFunctionMatlab"
2656 /*
2657    TSSetFunctionMatlab - Sets the function evaluation routine and function
2658    vector for use by the TS routines in solving ODEs
2659    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
2660 
2661    Logically Collective on TS
2662 
2663    Input Parameters:
2664 +  ts - the TS context
2665 -  func - function evaluation routine
2666 
2667    Calling sequence of func:
2668 $    func (TS ts,PetscReal time,Vec x,Vec xdot,Vec f,void *ctx);
2669 
2670    Level: beginner
2671 
2672 .keywords: TS, nonlinear, set, function
2673 
2674 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
2675 */
2676 PetscErrorCode  TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx)
2677 {
2678   PetscErrorCode  ierr;
2679   TSMatlabContext *sctx;
2680 
2681   PetscFunctionBegin;
2682   /* currently sctx is memory bleed */
2683   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
2684   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
2685   /*
2686      This should work, but it doesn't
2687   sctx->ctx = ctx;
2688   mexMakeArrayPersistent(sctx->ctx);
2689   */
2690   sctx->ctx = mxDuplicateArray(ctx);
2691   ierr = TSSetIFunction(ts,PETSC_NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr);
2692   PetscFunctionReturn(0);
2693 }
2694 
2695 #undef __FUNCT__
2696 #define __FUNCT__ "TSComputeJacobian_Matlab"
2697 /*
2698    TSComputeJacobian_Matlab - Calls the function that has been set with
2699                          TSSetJacobianMatlab().
2700 
2701    Collective on TS
2702 
2703    Input Parameters:
2704 +  ts - the TS context
2705 .  x - input vector
2706 .  A, B - the matrices
2707 -  ctx - user context
2708 
2709    Output Parameter:
2710 .  flag - structure of the matrix
2711 
2712    Level: developer
2713 
2714 .keywords: TS, nonlinear, compute, function
2715 
2716 .seealso: TSSetFunction(), TSGetFunction()
2717 @*/
2718 PetscErrorCode  TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec x,Vec xdot,PetscReal shift,Mat *A,Mat *B,MatStructure *flag, void *ctx)
2719 {
2720   PetscErrorCode  ierr;
2721   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
2722   int             nlhs = 2,nrhs = 9;
2723   mxArray         *plhs[2],*prhs[9];
2724   long long int   lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0;
2725 
2726   PetscFunctionBegin;
2727   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2728   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
2729 
2730   /* call Matlab function in ctx with arguments x and y */
2731 
2732   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
2733   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
2734   ierr = PetscMemcpy(&lxdot,&xdot,sizeof(x));CHKERRQ(ierr);
2735   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
2736   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
2737   prhs[0] =  mxCreateDoubleScalar((double)ls);
2738   prhs[1] =  mxCreateDoubleScalar((double)time);
2739   prhs[2] =  mxCreateDoubleScalar((double)lx);
2740   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
2741   prhs[4] =  mxCreateDoubleScalar((double)shift);
2742   prhs[5] =  mxCreateDoubleScalar((double)lA);
2743   prhs[6] =  mxCreateDoubleScalar((double)lB);
2744   prhs[7] =  mxCreateString(sctx->funcname);
2745   prhs[8] =  sctx->ctx;
2746   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr);
2747   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
2748   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
2749   mxDestroyArray(prhs[0]);
2750   mxDestroyArray(prhs[1]);
2751   mxDestroyArray(prhs[2]);
2752   mxDestroyArray(prhs[3]);
2753   mxDestroyArray(prhs[4]);
2754   mxDestroyArray(prhs[5]);
2755   mxDestroyArray(prhs[6]);
2756   mxDestroyArray(prhs[7]);
2757   mxDestroyArray(plhs[0]);
2758   mxDestroyArray(plhs[1]);
2759   PetscFunctionReturn(0);
2760 }
2761 
2762 
2763 #undef __FUNCT__
2764 #define __FUNCT__ "TSSetJacobianMatlab"
2765 /*
2766    TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
2767    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
2768 
2769    Logically Collective on TS
2770 
2771    Input Parameters:
2772 +  ts - the TS context
2773 .  A,B - Jacobian matrices
2774 .  func - function evaluation routine
2775 -  ctx - user context
2776 
2777    Calling sequence of func:
2778 $    flag = func (TS ts,PetscReal time,Vec x,Vec xdot,Mat A,Mat B,void *ctx);
2779 
2780 
2781    Level: developer
2782 
2783 .keywords: TS, nonlinear, set, function
2784 
2785 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
2786 */
2787 PetscErrorCode  TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx)
2788 {
2789   PetscErrorCode    ierr;
2790   TSMatlabContext *sctx;
2791 
2792   PetscFunctionBegin;
2793   /* currently sctx is memory bleed */
2794   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
2795   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
2796   /*
2797      This should work, but it doesn't
2798   sctx->ctx = ctx;
2799   mexMakeArrayPersistent(sctx->ctx);
2800   */
2801   sctx->ctx = mxDuplicateArray(ctx);
2802   ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
2803   PetscFunctionReturn(0);
2804 }
2805 
2806 #undef __FUNCT__
2807 #define __FUNCT__ "TSMonitor_Matlab"
2808 /*
2809    TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab().
2810 
2811    Collective on TS
2812 
2813 .seealso: TSSetFunction(), TSGetFunction()
2814 @*/
2815 PetscErrorCode  TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec x, void *ctx)
2816 {
2817   PetscErrorCode  ierr;
2818   TSMatlabContext *sctx = (TSMatlabContext *)ctx;
2819   int             nlhs = 1,nrhs = 6;
2820   mxArray         *plhs[1],*prhs[6];
2821   long long int   lx = 0,ls = 0;
2822 
2823   PetscFunctionBegin;
2824   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2825   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
2826 
2827   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
2828   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
2829   prhs[0] =  mxCreateDoubleScalar((double)ls);
2830   prhs[1] =  mxCreateDoubleScalar((double)it);
2831   prhs[2] =  mxCreateDoubleScalar((double)time);
2832   prhs[3] =  mxCreateDoubleScalar((double)lx);
2833   prhs[4] =  mxCreateString(sctx->funcname);
2834   prhs[5] =  sctx->ctx;
2835   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr);
2836   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
2837   mxDestroyArray(prhs[0]);
2838   mxDestroyArray(prhs[1]);
2839   mxDestroyArray(prhs[2]);
2840   mxDestroyArray(prhs[3]);
2841   mxDestroyArray(prhs[4]);
2842   mxDestroyArray(plhs[0]);
2843   PetscFunctionReturn(0);
2844 }
2845 
2846 
2847 #undef __FUNCT__
2848 #define __FUNCT__ "TSMonitorSetMatlab"
2849 /*
2850    TSMonitorSetMatlab - Sets the monitor function from Matlab
2851 
2852    Level: developer
2853 
2854 .keywords: TS, nonlinear, set, function
2855 
2856 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
2857 */
2858 PetscErrorCode  TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx)
2859 {
2860   PetscErrorCode    ierr;
2861   TSMatlabContext *sctx;
2862 
2863   PetscFunctionBegin;
2864   /* currently sctx is memory bleed */
2865   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
2866   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
2867   /*
2868      This should work, but it doesn't
2869   sctx->ctx = ctx;
2870   mexMakeArrayPersistent(sctx->ctx);
2871   */
2872   sctx->ctx = mxDuplicateArray(ctx);
2873   ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
2874   PetscFunctionReturn(0);
2875 }
2876 
2877 #endif
2878