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