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