xref: /petsc/src/ts/interface/ts.c (revision 2bce29e67bc05373b46c5d2f6f764fcb5a64afb5)
1 
2 #include <petsc/private/tsimpl.h>        /*I "petscts.h"  I*/
3 #include <petscdmshell.h>
4 #include <petscdmda.h>
5 #include <petscviewer.h>
6 #include <petscdraw.h>
7 
8 /* Logging support */
9 PetscClassId  TS_CLASSID, DMTS_CLASSID;
10 PetscLogEvent TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval;
11 
12 const char *const TSExactFinalTimeOptions[] = {"STEPOVER","INTERPOLATE","MATCHSTEP","TSExactFinalTimeOption","TS_EXACTFINALTIME_",0};
13 
14 struct _n_TSMonitorDrawCtx {
15   PetscViewer   viewer;
16   PetscDrawAxis axis;
17   Vec           initialsolution;
18   PetscBool     showinitial;
19   PetscInt      howoften;  /* when > 0 uses step % howoften, when negative only final solution plotted */
20   PetscBool     showtimestepandtime;
21   int           color;
22 };
23 
24 #undef __FUNCT__
25 #define __FUNCT__ "TSSetFromOptions"
26 /*@
27    TSSetFromOptions - Sets various TS parameters from user options.
28 
29    Collective on TS
30 
31    Input Parameter:
32 .  ts - the TS context obtained from TSCreate()
33 
34    Options Database Keys:
35 +  -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSGL, TSSSP
36 .  -ts_save_trajectory - checkpoint the solution at each time-step
37 .  -ts_max_steps <maxsteps> - maximum number of time-steps to take
38 .  -ts_final_time <time> - maximum time to compute to
39 .  -ts_dt <dt> - initial time step
40 .  -ts_exact_final_time <stepover,interpolate,matchstep> whether to stop at the exact given final time and how to compute the solution at that ti,e
41 .  -ts_max_snes_failures <maxfailures> - Maximum number of nonlinear solve failures allowed
42 .  -ts_max_reject <maxrejects> - Maximum number of step rejections before step fails
43 .  -ts_error_if_step_fails <true,false> - Error if no step succeeds
44 .  -ts_rtol <rtol> - relative tolerance for local truncation error
45 .  -ts_atol <atol> Absolute tolerance for local truncation error
46 .  -ts_adjoint_solve <yes,no> After solving the ODE/DAE solve the adjoint problem (requires -ts_save_trajectory)
47 .  -ts_fd_color - Use finite differences with coloring to compute IJacobian
48 .  -ts_monitor - print information at each timestep
49 .  -ts_monitor_lg_timestep - Monitor timestep size graphically
50 .  -ts_monitor_lg_solution - Monitor solution graphically
51 .  -ts_monitor_lg_error - Monitor error graphically
52 .  -ts_monitor_lg_snes_iterations - Monitor number nonlinear iterations for each timestep graphically
53 .  -ts_monitor_lg_ksp_iterations - Monitor number nonlinear iterations for each timestep graphically
54 .  -ts_monitor_sp_eig - Monitor eigenvalues of linearized operator graphically
55 .  -ts_monitor_draw_solution - Monitor solution graphically
56 .  -ts_monitor_draw_solution_phase  <xleft,yleft,xright,yright> - Monitor solution graphically with phase diagram, requires problem with exactly 2 degrees of freedom
57 .  -ts_monitor_draw_error - Monitor error graphically, requires use to have provided TSSetSolutionFunction()
58 .  -ts_monitor_solution_binary <filename> - Save each solution to a binary file
59 .  -ts_monitor_solution_vtk <filename.vts> - Save each time step to a binary file, use filename-%%03D.vts
60 -  -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time
61 
62    Developer Note: We should unify all the -ts_monitor options in the way that -xxx_view has been unified
63 
64    Level: beginner
65 
66 .keywords: TS, timestep, set, options, database
67 
68 .seealso: TSGetType()
69 @*/
70 PetscErrorCode  TSSetFromOptions(TS ts)
71 {
72   PetscBool              opt,flg,tflg;
73   PetscErrorCode         ierr;
74   PetscViewer            monviewer;
75   char                   monfilename[PETSC_MAX_PATH_LEN];
76   SNES                   snes;
77   TSAdapt                adapt;
78   PetscReal              time_step;
79   TSExactFinalTimeOption eftopt;
80   char                   dir[16];
81   const char             *defaultType;
82   char                   typeName[256];
83 
84   PetscFunctionBegin;
85   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
86   ierr = PetscObjectOptionsBegin((PetscObject)ts);CHKERRQ(ierr);
87   if (((PetscObject)ts)->type_name) defaultType = ((PetscObject)ts)->type_name;
88   else defaultType = TSEULER;
89 
90   ierr = TSRegisterAll();CHKERRQ(ierr);
91   ierr = PetscOptionsFList("-ts_type", "TS method"," TSSetType", TSList, defaultType, typeName, 256, &opt);CHKERRQ(ierr);
92   if (opt) {
93     ierr = TSSetType(ts, typeName);CHKERRQ(ierr);
94   } else {
95     ierr = TSSetType(ts, defaultType);CHKERRQ(ierr);
96   }
97 
98   /* Handle generic TS options */
99   ierr = PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetDuration",ts->max_steps,&ts->max_steps,NULL);CHKERRQ(ierr);
100   ierr = PetscOptionsReal("-ts_final_time","Time to run to","TSSetDuration",ts->max_time,&ts->max_time,NULL);CHKERRQ(ierr);
101   ierr = PetscOptionsReal("-ts_init_time","Initial time","TSSetTime",ts->ptime,&ts->ptime,NULL);CHKERRQ(ierr);
102   ierr = PetscOptionsReal("-ts_dt","Initial time step","TSSetTimeStep",ts->time_step,&time_step,&flg);CHKERRQ(ierr);
103   if (flg) {
104     ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr);
105   }
106   ierr = PetscOptionsEnum("-ts_exact_final_time","Option for handling of final time step","TSSetExactFinalTime",TSExactFinalTimeOptions,(PetscEnum)ts->exact_final_time,(PetscEnum*)&eftopt,&flg);CHKERRQ(ierr);
107   if (flg) {ierr = TSSetExactFinalTime(ts,eftopt);CHKERRQ(ierr);}
108   ierr = PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","TSSetMaxSNESFailures",ts->max_snes_failures,&ts->max_snes_failures,NULL);CHKERRQ(ierr);
109   ierr = PetscOptionsInt("-ts_max_reject","Maximum number of step rejections before step fails","TSSetMaxStepRejections",ts->max_reject,&ts->max_reject,NULL);CHKERRQ(ierr);
110   ierr = PetscOptionsBool("-ts_error_if_step_fails","Error if no step succeeds","TSSetErrorIfStepFails",ts->errorifstepfailed,&ts->errorifstepfailed,NULL);CHKERRQ(ierr);
111   ierr = PetscOptionsReal("-ts_rtol","Relative tolerance for local truncation error","TSSetTolerances",ts->rtol,&ts->rtol,NULL);CHKERRQ(ierr);
112   ierr = PetscOptionsReal("-ts_atol","Absolute tolerance for local truncation error","TSSetTolerances",ts->atol,&ts->atol,NULL);CHKERRQ(ierr);
113 
114 #if defined(PETSC_HAVE_SAWS)
115   {
116   PetscBool set;
117   flg  = PETSC_FALSE;
118   ierr = PetscOptionsBool("-ts_saws_block","Block for SAWs memory snooper at end of TSSolve","PetscObjectSAWsBlock",((PetscObject)ts)->amspublishblock,&flg,&set);CHKERRQ(ierr);
119   if (set) {
120     ierr = PetscObjectSAWsSetBlock((PetscObject)ts,flg);CHKERRQ(ierr);
121   }
122   }
123 #endif
124 
125   /* Monitor options */
126   ierr = PetscOptionsString("-ts_monitor","Monitor timestep size","TSMonitorDefault","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
127   if (flg) {
128     ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ts),monfilename,&monviewer);CHKERRQ(ierr);
129     ierr = TSMonitorSet(ts,TSMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
130   }
131   ierr = PetscOptionsString("-ts_monitor_python","Use Python function","TSMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
132   if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ts,monfilename);CHKERRQ(ierr);}
133 
134   ierr = PetscOptionsName("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",&opt);CHKERRQ(ierr);
135   if (opt) {
136     TSMonitorLGCtx ctx;
137     PetscInt       howoften = 1;
138 
139     ierr = PetscOptionsInt("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",howoften,&howoften,NULL);CHKERRQ(ierr);
140     ierr = TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr);
141     ierr = TSMonitorSet(ts,TSMonitorLGTimeStep,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
142   }
143   ierr = PetscOptionsName("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",&opt);CHKERRQ(ierr);
144   if (opt) {
145     TSMonitorLGCtx ctx;
146     PetscInt       howoften = 1;
147 
148     ierr = PetscOptionsInt("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",howoften,&howoften,NULL);CHKERRQ(ierr);
149     ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr);
150     ierr = TSMonitorSet(ts,TSMonitorLGSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
151   }
152   ierr = PetscOptionsName("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",&opt);CHKERRQ(ierr);
153   if (opt) {
154     TSMonitorLGCtx ctx;
155     PetscInt       howoften = 1;
156 
157     ierr = PetscOptionsInt("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",howoften,&howoften,NULL);CHKERRQ(ierr);
158     ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr);
159     ierr = TSMonitorSet(ts,TSMonitorLGError,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
160   }
161   ierr = PetscOptionsName("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",&opt);CHKERRQ(ierr);
162   if (opt) {
163     TSMonitorLGCtx ctx;
164     PetscInt       howoften = 1;
165 
166     ierr = PetscOptionsInt("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",howoften,&howoften,NULL);CHKERRQ(ierr);
167     ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr);
168     ierr = TSMonitorSet(ts,TSMonitorLGSNESIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
169   }
170   ierr = PetscOptionsName("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",&opt);CHKERRQ(ierr);
171   if (opt) {
172     TSMonitorLGCtx ctx;
173     PetscInt       howoften = 1;
174 
175     ierr = PetscOptionsInt("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",howoften,&howoften,NULL);CHKERRQ(ierr);
176     ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx);CHKERRQ(ierr);
177     ierr = TSMonitorSet(ts,TSMonitorLGKSPIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr);
178   }
179   ierr = PetscOptionsName("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",&opt);CHKERRQ(ierr);
180   if (opt) {
181     TSMonitorSPEigCtx ctx;
182     PetscInt          howoften = 1;
183 
184     ierr = PetscOptionsInt("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",howoften,&howoften,NULL);CHKERRQ(ierr);
185     ierr = TSMonitorSPEigCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr);
186     ierr = TSMonitorSet(ts,TSMonitorSPEig,ctx,(PetscErrorCode (*)(void**))TSMonitorSPEigCtxDestroy);CHKERRQ(ierr);
187   }
188   opt  = PETSC_FALSE;
189   ierr = PetscOptionsName("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",&opt);CHKERRQ(ierr);
190   if (opt) {
191     TSMonitorDrawCtx ctx;
192     PetscInt         howoften = 1;
193 
194     ierr = PetscOptionsInt("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",howoften,&howoften,NULL);CHKERRQ(ierr);
195     ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr);
196     ierr = TSMonitorSet(ts,TSMonitorDrawSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr);
197   }
198   opt  = PETSC_FALSE;
199   ierr = PetscOptionsName("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",&opt);CHKERRQ(ierr);
200   if (opt) {
201     TSMonitorDrawCtx ctx;
202     PetscReal        bounds[4];
203     PetscInt         n = 4;
204     PetscDraw        draw;
205 
206     ierr = PetscOptionsRealArray("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",bounds,&n,NULL);CHKERRQ(ierr);
207     if (n != 4) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Must provide bounding box of phase field");
208     ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,1,&ctx);CHKERRQ(ierr);
209     ierr = PetscViewerDrawGetDraw(ctx->viewer,0,&draw);CHKERRQ(ierr);
210     ierr = PetscDrawClear(draw);CHKERRQ(ierr);
211     ierr = PetscDrawAxisCreate(draw,&ctx->axis);CHKERRQ(ierr);
212     ierr = PetscDrawAxisSetLimits(ctx->axis,bounds[0],bounds[2],bounds[1],bounds[3]);CHKERRQ(ierr);
213     ierr = PetscDrawAxisSetLabels(ctx->axis,"Phase Diagram","Variable 1","Variable 2");CHKERRQ(ierr);
214     ierr = PetscDrawAxisDraw(ctx->axis);CHKERRQ(ierr);
215     /* ierr = PetscDrawSetCoordinates(draw,bounds[0],bounds[1],bounds[2],bounds[3]);CHKERRQ(ierr); */
216     ierr = TSMonitorSet(ts,TSMonitorDrawSolutionPhase,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr);
217   }
218   opt  = PETSC_FALSE;
219   ierr = PetscOptionsName("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",&opt);CHKERRQ(ierr);
220   if (opt) {
221     TSMonitorDrawCtx ctx;
222     PetscInt         howoften = 1;
223 
224     ierr = PetscOptionsInt("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",howoften,&howoften,NULL);CHKERRQ(ierr);
225     ierr = TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx);CHKERRQ(ierr);
226     ierr = TSMonitorSet(ts,TSMonitorDrawError,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy);CHKERRQ(ierr);
227   }
228   opt  = PETSC_FALSE;
229   ierr = PetscOptionsString("-ts_monitor_solution_binary","Save each solution to a binary file","TSMonitorSolutionBinary",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
230   if (flg) {
231     PetscViewer ctx;
232     if (monfilename[0]) {
233       ierr = PetscViewerBinaryOpen(PetscObjectComm((PetscObject)ts),monfilename,FILE_MODE_WRITE,&ctx);CHKERRQ(ierr);
234       ierr = TSMonitorSet(ts,TSMonitorSolutionBinary,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
235     } else {
236       ctx = PETSC_VIEWER_BINARY_(PetscObjectComm((PetscObject)ts));
237       ierr = TSMonitorSet(ts,TSMonitorSolutionBinary,ctx,(PetscErrorCode (*)(void**))NULL);CHKERRQ(ierr);
238     }
239   }
240   opt  = PETSC_FALSE;
241   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);
242   if (flg) {
243     const char *ptr,*ptr2;
244     char       *filetemplate;
245     if (!monfilename[0]) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts");
246     /* Do some cursory validation of the input. */
247     ierr = PetscStrstr(monfilename,"%",(char**)&ptr);CHKERRQ(ierr);
248     if (!ptr) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03D.vts");
249     for (ptr++; ptr && *ptr; ptr++) {
250       ierr = PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);CHKERRQ(ierr);
251       if (!ptr2 && (*ptr < '0' || '9' < *ptr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Invalid file template argument to -ts_monitor_solution_vtk, should look like filename-%%03D.vts");
252       if (ptr2) break;
253     }
254     ierr = PetscStrallocpy(monfilename,&filetemplate);CHKERRQ(ierr);
255     ierr = TSMonitorSet(ts,TSMonitorSolutionVTK,filetemplate,(PetscErrorCode (*)(void**))TSMonitorSolutionVTKDestroy);CHKERRQ(ierr);
256   }
257 
258   ierr = PetscOptionsString("-ts_monitor_dmda_ray","Display a ray of the solution","None","y=0",dir,16,&flg);CHKERRQ(ierr);
259   if (flg) {
260     TSMonitorDMDARayCtx *rayctx;
261     int                  ray = 0;
262     DMDADirection        ddir;
263     DM                   da;
264     PetscMPIInt          rank;
265 
266     if (dir[1] != '=') SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir);
267     if (dir[0] == 'x') ddir = DMDA_X;
268     else if (dir[0] == 'y') ddir = DMDA_Y;
269     else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir);
270     sscanf(dir+2,"%d",&ray);
271 
272     ierr = PetscInfo2(((PetscObject)ts),"Displaying DMDA ray %c = %D\n",dir[0],ray);CHKERRQ(ierr);
273     ierr = PetscNew(&rayctx);CHKERRQ(ierr);
274     ierr = TSGetDM(ts,&da);CHKERRQ(ierr);
275     ierr = DMDAGetRay(da,ddir,ray,&rayctx->ray,&rayctx->scatter);CHKERRQ(ierr);
276     ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)ts),&rank);CHKERRQ(ierr);
277     if (!rank) {
278       ierr = PetscViewerDrawOpen(PETSC_COMM_SELF,0,0,0,0,600,300,&rayctx->viewer);CHKERRQ(ierr);
279     }
280     rayctx->lgctx = NULL;
281     ierr = TSMonitorSet(ts,TSMonitorDMDARay,rayctx,TSMonitorDMDARayDestroy);CHKERRQ(ierr);
282   }
283   ierr = PetscOptionsString("-ts_monitor_lg_dmda_ray","Display a ray of the solution","None","x=0",dir,16,&flg);CHKERRQ(ierr);
284   if (flg) {
285     TSMonitorDMDARayCtx *rayctx;
286     int                 ray = 0;
287     DMDADirection       ddir;
288     DM                  da;
289     PetscInt            howoften = 1;
290 
291     if (dir[1] != '=') SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_WRONG, "Malformed ray %s", dir);
292     if      (dir[0] == 'x') ddir = DMDA_X;
293     else if (dir[0] == 'y') ddir = DMDA_Y;
294     else SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_WRONG, "Unknown ray direction %s", dir);
295     sscanf(dir+2, "%d", &ray);
296 
297     ierr = PetscInfo2(((PetscObject) ts),"Displaying LG DMDA ray %c = %D\n", dir[0], ray);CHKERRQ(ierr);
298     ierr = PetscNew(&rayctx);CHKERRQ(ierr);
299     ierr = TSGetDM(ts, &da);CHKERRQ(ierr);
300     ierr = DMDAGetRay(da, ddir, ray, &rayctx->ray, &rayctx->scatter);CHKERRQ(ierr);
301     ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,0,0,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&rayctx->lgctx);CHKERRQ(ierr);
302     ierr = TSMonitorSet(ts, TSMonitorLGDMDARay, rayctx, TSMonitorDMDARayDestroy);CHKERRQ(ierr);
303   }
304 
305   ierr = PetscOptionsName("-ts_monitor_envelope","Monitor maximum and minimum value of each component of the solution","TSMonitorEnvelope",&opt);CHKERRQ(ierr);
306   if (opt) {
307     TSMonitorEnvelopeCtx ctx;
308 
309     ierr = TSMonitorEnvelopeCtxCreate(ts,&ctx);CHKERRQ(ierr);
310     ierr = TSMonitorSet(ts,TSMonitorEnvelope,ctx,(PetscErrorCode (*)(void**))TSMonitorEnvelopeCtxDestroy);CHKERRQ(ierr);
311   }
312 
313   flg  = PETSC_FALSE;
314   ierr = PetscOptionsBool("-ts_fd_color", "Use finite differences with coloring to compute IJacobian", "TSComputeJacobianDefaultColor", flg, &flg, NULL);CHKERRQ(ierr);
315   if (flg) {
316     DM   dm;
317     DMTS tdm;
318 
319     ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
320     ierr = DMGetDMTS(dm, &tdm);CHKERRQ(ierr);
321     tdm->ijacobianctx = NULL;
322     ierr = TSSetIJacobian(ts, NULL, NULL, TSComputeIJacobianDefaultColor, 0);CHKERRQ(ierr);
323     ierr = PetscInfo(ts, "Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr);
324   }
325 
326   /*
327      This code is all wrong. One is creating objects inside the TSSetFromOptions() so if run with the options gui
328      will bleed memory. Also one is using a PetscOptionsBegin() inside a PetscOptionsBegin()
329   */
330   ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr);
331   ierr = TSAdaptSetFromOptions(PetscOptionsObject,adapt);CHKERRQ(ierr);
332 
333     /* Handle specific TS options */
334   if (ts->ops->setfromoptions) {
335     ierr = (*ts->ops->setfromoptions)(PetscOptionsObject,ts);CHKERRQ(ierr);
336   }
337   /* TS trajectory must be set after TS, since it may use some TS options above */
338   if (ts->trajectory) tflg = PETSC_TRUE;
339   else tflg = PETSC_FALSE;
340   ierr = PetscOptionsBool("-ts_save_trajectory","Save the solution at each timestep","TSSetSaveTrajectory",tflg,&tflg,NULL);CHKERRQ(ierr);
341   if (tflg) {
342     ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr);
343   }
344   if (ts->adjoint_solve) tflg = PETSC_TRUE;
345   else tflg = PETSC_FALSE;
346   ierr = PetscOptionsBool("-ts_adjoint_solve","Solve the adjoint problem immediately after solving the forward problem","",tflg,&tflg,&flg);CHKERRQ(ierr);
347   if (flg) {
348     ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr);
349     ts->adjoint_solve = tflg;
350   }
351   if (ts->trajectory) {
352     ierr = TSTrajectorySetFromOptions(ts->trajectory,ts);CHKERRQ(ierr);
353   }
354   ierr = PetscOptionsEnd();CHKERRQ(ierr);
355 
356   /* process any options handlers added with PetscObjectAddOptionsHandler() */
357   ierr = PetscObjectProcessOptionsHandlers((PetscObject)ts);CHKERRQ(ierr);
358 
359   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
360   if (snes) {
361     if (ts->problem_type == TS_LINEAR) {ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);}
362     ierr = SNESSetFromOptions(ts->snes);CHKERRQ(ierr);
363   }
364 
365   PetscFunctionReturn(0);
366 }
367 
368 #undef __FUNCT__
369 #define __FUNCT__ "TSSetSaveTrajectory"
370 /*@
371    TSSetSaveTrajectory - Causes the TS to save its solutions as it iterates forward in time in a TSTrajectory object
372 
373    Collective on TS
374 
375    Input Parameters:
376 .  ts - the TS context obtained from TSCreate()
377 
378 Note: This routine should be called after all TS options have been set
379 
380    Level: intermediate
381 
382 .seealso: TSGetTrajectory(), TSAdjointSolve()
383 
384 .keywords: TS, set, checkpoint,
385 @*/
386 PetscErrorCode  TSSetSaveTrajectory(TS ts)
387 {
388   PetscErrorCode ierr;
389 
390   PetscFunctionBegin;
391   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
392   if (!ts->trajectory) {
393     ierr = TSTrajectoryCreate(PetscObjectComm((PetscObject)ts),&ts->trajectory);CHKERRQ(ierr);
394     ierr = TSTrajectorySetFromOptions(ts->trajectory,ts);CHKERRQ(ierr);
395   }
396   PetscFunctionReturn(0);
397 }
398 
399 #undef __FUNCT__
400 #define __FUNCT__ "TSComputeRHSJacobian"
401 /*@
402    TSComputeRHSJacobian - Computes the Jacobian matrix that has been
403       set with TSSetRHSJacobian().
404 
405    Collective on TS and Vec
406 
407    Input Parameters:
408 +  ts - the TS context
409 .  t - current timestep
410 -  U - input vector
411 
412    Output Parameters:
413 +  A - Jacobian matrix
414 .  B - optional preconditioning matrix
415 -  flag - flag indicating matrix structure
416 
417    Notes:
418    Most users should not need to explicitly call this routine, as it
419    is used internally within the nonlinear solvers.
420 
421    See KSPSetOperators() for important information about setting the
422    flag parameter.
423 
424    Level: developer
425 
426 .keywords: SNES, compute, Jacobian, matrix
427 
428 .seealso:  TSSetRHSJacobian(), KSPSetOperators()
429 @*/
430 PetscErrorCode  TSComputeRHSJacobian(TS ts,PetscReal t,Vec U,Mat A,Mat B)
431 {
432   PetscErrorCode ierr;
433   PetscObjectState Ustate;
434   DM             dm;
435   DMTS           tsdm;
436   TSRHSJacobian  rhsjacobianfunc;
437   void           *ctx;
438   TSIJacobian    ijacobianfunc;
439   TSRHSFunction  rhsfunction;
440 
441   PetscFunctionBegin;
442   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
443   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
444   PetscCheckSameComm(ts,1,U,3);
445   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
446   ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr);
447   ierr = DMTSGetRHSJacobian(dm,&rhsjacobianfunc,&ctx);CHKERRQ(ierr);
448   ierr = DMTSGetIJacobian(dm,&ijacobianfunc,NULL);CHKERRQ(ierr);
449   ierr = DMTSGetRHSFunction(dm,&rhsfunction,&ctx);CHKERRQ(ierr);
450   ierr = PetscObjectStateGet((PetscObject)U,&Ustate);CHKERRQ(ierr);
451   if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.X == U && ts->rhsjacobian.Xstate == Ustate)) && (rhsfunction != TSComputeRHSFunctionLinear)) {
452     PetscFunctionReturn(0);
453   }
454 
455   if (!rhsjacobianfunc && !ijacobianfunc) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()");
456 
457   if (ts->rhsjacobian.reuse) {
458     ierr = MatShift(A,-ts->rhsjacobian.shift);CHKERRQ(ierr);
459     ierr = MatScale(A,1./ts->rhsjacobian.scale);CHKERRQ(ierr);
460     if (A != B) {
461       ierr = MatShift(B,-ts->rhsjacobian.shift);CHKERRQ(ierr);
462       ierr = MatScale(B,1./ts->rhsjacobian.scale);CHKERRQ(ierr);
463     }
464     ts->rhsjacobian.shift = 0;
465     ts->rhsjacobian.scale = 1.;
466   }
467 
468   if (rhsjacobianfunc) {
469     ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr);
470     PetscStackPush("TS user Jacobian function");
471     ierr = (*rhsjacobianfunc)(ts,t,U,A,B,ctx);CHKERRQ(ierr);
472     PetscStackPop;
473     ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr);
474     /* make sure user returned a correct Jacobian and preconditioner */
475     PetscValidHeaderSpecific(A,MAT_CLASSID,4);
476     PetscValidHeaderSpecific(B,MAT_CLASSID,5);
477   } else {
478     ierr = MatZeroEntries(A);CHKERRQ(ierr);
479     if (A != B) {ierr = MatZeroEntries(B);CHKERRQ(ierr);}
480   }
481   ts->rhsjacobian.time       = t;
482   ts->rhsjacobian.X          = U;
483   ierr                       = PetscObjectStateGet((PetscObject)U,&ts->rhsjacobian.Xstate);CHKERRQ(ierr);
484   PetscFunctionReturn(0);
485 }
486 
487 #undef __FUNCT__
488 #define __FUNCT__ "TSComputeRHSFunction"
489 /*@
490    TSComputeRHSFunction - Evaluates the right-hand-side function.
491 
492    Collective on TS and Vec
493 
494    Input Parameters:
495 +  ts - the TS context
496 .  t - current time
497 -  U - state vector
498 
499    Output Parameter:
500 .  y - right hand side
501 
502    Note:
503    Most users should not need to explicitly call this routine, as it
504    is used internally within the nonlinear solvers.
505 
506    Level: developer
507 
508 .keywords: TS, compute
509 
510 .seealso: TSSetRHSFunction(), TSComputeIFunction()
511 @*/
512 PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec U,Vec y)
513 {
514   PetscErrorCode ierr;
515   TSRHSFunction  rhsfunction;
516   TSIFunction    ifunction;
517   void           *ctx;
518   DM             dm;
519 
520   PetscFunctionBegin;
521   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
522   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
523   PetscValidHeaderSpecific(y,VEC_CLASSID,4);
524   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
525   ierr = DMTSGetRHSFunction(dm,&rhsfunction,&ctx);CHKERRQ(ierr);
526   ierr = DMTSGetIFunction(dm,&ifunction,NULL);CHKERRQ(ierr);
527 
528   if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()");
529 
530   ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr);
531   if (rhsfunction) {
532     PetscStackPush("TS user right-hand-side function");
533     ierr = (*rhsfunction)(ts,t,U,y,ctx);CHKERRQ(ierr);
534     PetscStackPop;
535   } else {
536     ierr = VecZeroEntries(y);CHKERRQ(ierr);
537   }
538 
539   ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,y,0);CHKERRQ(ierr);
540   PetscFunctionReturn(0);
541 }
542 
543 #undef __FUNCT__
544 #define __FUNCT__ "TSComputeSolutionFunction"
545 /*@
546    TSComputeSolutionFunction - Evaluates the solution function.
547 
548    Collective on TS and Vec
549 
550    Input Parameters:
551 +  ts - the TS context
552 -  t - current time
553 
554    Output Parameter:
555 .  U - the solution
556 
557    Note:
558    Most users should not need to explicitly call this routine, as it
559    is used internally within the nonlinear solvers.
560 
561    Level: developer
562 
563 .keywords: TS, compute
564 
565 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction()
566 @*/
567 PetscErrorCode TSComputeSolutionFunction(TS ts,PetscReal t,Vec U)
568 {
569   PetscErrorCode     ierr;
570   TSSolutionFunction solutionfunction;
571   void               *ctx;
572   DM                 dm;
573 
574   PetscFunctionBegin;
575   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
576   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
577   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
578   ierr = DMTSGetSolutionFunction(dm,&solutionfunction,&ctx);CHKERRQ(ierr);
579 
580   if (solutionfunction) {
581     PetscStackPush("TS user solution function");
582     ierr = (*solutionfunction)(ts,t,U,ctx);CHKERRQ(ierr);
583     PetscStackPop;
584   }
585   PetscFunctionReturn(0);
586 }
587 #undef __FUNCT__
588 #define __FUNCT__ "TSComputeForcingFunction"
589 /*@
590    TSComputeForcingFunction - Evaluates the forcing function.
591 
592    Collective on TS and Vec
593 
594    Input Parameters:
595 +  ts - the TS context
596 -  t - current time
597 
598    Output Parameter:
599 .  U - the function value
600 
601    Note:
602    Most users should not need to explicitly call this routine, as it
603    is used internally within the nonlinear solvers.
604 
605    Level: developer
606 
607 .keywords: TS, compute
608 
609 .seealso: TSSetSolutionFunction(), TSSetRHSFunction(), TSComputeIFunction()
610 @*/
611 PetscErrorCode TSComputeForcingFunction(TS ts,PetscReal t,Vec U)
612 {
613   PetscErrorCode     ierr, (*forcing)(TS,PetscReal,Vec,void*);
614   void               *ctx;
615   DM                 dm;
616 
617   PetscFunctionBegin;
618   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
619   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
620   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
621   ierr = DMTSGetForcingFunction(dm,&forcing,&ctx);CHKERRQ(ierr);
622 
623   if (forcing) {
624     PetscStackPush("TS user forcing function");
625     ierr = (*forcing)(ts,t,U,ctx);CHKERRQ(ierr);
626     PetscStackPop;
627   }
628   PetscFunctionReturn(0);
629 }
630 
631 #undef __FUNCT__
632 #define __FUNCT__ "TSGetRHSVec_Private"
633 static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs)
634 {
635   Vec            F;
636   PetscErrorCode ierr;
637 
638   PetscFunctionBegin;
639   *Frhs = NULL;
640   ierr  = TSGetIFunction(ts,&F,NULL,NULL);CHKERRQ(ierr);
641   if (!ts->Frhs) {
642     ierr = VecDuplicate(F,&ts->Frhs);CHKERRQ(ierr);
643   }
644   *Frhs = ts->Frhs;
645   PetscFunctionReturn(0);
646 }
647 
648 #undef __FUNCT__
649 #define __FUNCT__ "TSGetRHSMats_Private"
650 static PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs)
651 {
652   Mat            A,B;
653   PetscErrorCode ierr;
654 
655   PetscFunctionBegin;
656   if (Arhs) *Arhs = NULL;
657   if (Brhs) *Brhs = NULL;
658   ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr);
659   if (Arhs) {
660     if (!ts->Arhs) {
661       ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs);CHKERRQ(ierr);
662     }
663     *Arhs = ts->Arhs;
664   }
665   if (Brhs) {
666     if (!ts->Brhs) {
667       if (A != B) {
668         ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs);CHKERRQ(ierr);
669       } else {
670         ts->Brhs = ts->Arhs;
671         ierr = PetscObjectReference((PetscObject)ts->Arhs);CHKERRQ(ierr);
672       }
673     }
674     *Brhs = ts->Brhs;
675   }
676   PetscFunctionReturn(0);
677 }
678 
679 #undef __FUNCT__
680 #define __FUNCT__ "TSComputeIFunction"
681 /*@
682    TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,U,Udot)=0
683 
684    Collective on TS and Vec
685 
686    Input Parameters:
687 +  ts - the TS context
688 .  t - current time
689 .  U - state vector
690 .  Udot - time derivative of state vector
691 -  imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate
692 
693    Output Parameter:
694 .  Y - right hand side
695 
696    Note:
697    Most users should not need to explicitly call this routine, as it
698    is used internally within the nonlinear solvers.
699 
700    If the user did did not write their equations in implicit form, this
701    function recasts them in implicit form.
702 
703    Level: developer
704 
705 .keywords: TS, compute
706 
707 .seealso: TSSetIFunction(), TSComputeRHSFunction()
708 @*/
709 PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec U,Vec Udot,Vec Y,PetscBool imex)
710 {
711   PetscErrorCode ierr;
712   TSIFunction    ifunction;
713   TSRHSFunction  rhsfunction;
714   void           *ctx;
715   DM             dm;
716 
717   PetscFunctionBegin;
718   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
719   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
720   PetscValidHeaderSpecific(Udot,VEC_CLASSID,4);
721   PetscValidHeaderSpecific(Y,VEC_CLASSID,5);
722 
723   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
724   ierr = DMTSGetIFunction(dm,&ifunction,&ctx);CHKERRQ(ierr);
725   ierr = DMTSGetRHSFunction(dm,&rhsfunction,NULL);CHKERRQ(ierr);
726 
727   if (!rhsfunction && !ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()");
728 
729   ierr = PetscLogEventBegin(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr);
730   if (ifunction) {
731     PetscStackPush("TS user implicit function");
732     ierr = (*ifunction)(ts,t,U,Udot,Y,ctx);CHKERRQ(ierr);
733     PetscStackPop;
734   }
735   if (imex) {
736     if (!ifunction) {
737       ierr = VecCopy(Udot,Y);CHKERRQ(ierr);
738     }
739   } else if (rhsfunction) {
740     if (ifunction) {
741       Vec Frhs;
742       ierr = TSGetRHSVec_Private(ts,&Frhs);CHKERRQ(ierr);
743       ierr = TSComputeRHSFunction(ts,t,U,Frhs);CHKERRQ(ierr);
744       ierr = VecAXPY(Y,-1,Frhs);CHKERRQ(ierr);
745     } else {
746       ierr = TSComputeRHSFunction(ts,t,U,Y);CHKERRQ(ierr);
747       ierr = VecAYPX(Y,-1,Udot);CHKERRQ(ierr);
748     }
749   }
750   ierr = PetscLogEventEnd(TS_FunctionEval,ts,U,Udot,Y);CHKERRQ(ierr);
751   PetscFunctionReturn(0);
752 }
753 
754 #undef __FUNCT__
755 #define __FUNCT__ "TSComputeIJacobian"
756 /*@
757    TSComputeIJacobian - Evaluates the Jacobian of the DAE
758 
759    Collective on TS and Vec
760 
761    Input
762       Input Parameters:
763 +  ts - the TS context
764 .  t - current timestep
765 .  U - state vector
766 .  Udot - time derivative of state vector
767 .  shift - shift to apply, see note below
768 -  imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate
769 
770    Output Parameters:
771 +  A - Jacobian matrix
772 .  B - optional preconditioning matrix
773 -  flag - flag indicating matrix structure
774 
775    Notes:
776    If F(t,U,Udot)=0 is the DAE, the required Jacobian is
777 
778    dF/dU + shift*dF/dUdot
779 
780    Most users should not need to explicitly call this routine, as it
781    is used internally within the nonlinear solvers.
782 
783    Level: developer
784 
785 .keywords: TS, compute, Jacobian, matrix
786 
787 .seealso:  TSSetIJacobian()
788 @*/
789 PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,PetscBool imex)
790 {
791   PetscErrorCode ierr;
792   TSIJacobian    ijacobian;
793   TSRHSJacobian  rhsjacobian;
794   DM             dm;
795   void           *ctx;
796 
797   PetscFunctionBegin;
798   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
799   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
800   PetscValidHeaderSpecific(Udot,VEC_CLASSID,4);
801   PetscValidPointer(A,6);
802   PetscValidHeaderSpecific(A,MAT_CLASSID,6);
803   PetscValidPointer(B,7);
804   PetscValidHeaderSpecific(B,MAT_CLASSID,7);
805 
806   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
807   ierr = DMTSGetIJacobian(dm,&ijacobian,&ctx);CHKERRQ(ierr);
808   ierr = DMTSGetRHSJacobian(dm,&rhsjacobian,NULL);CHKERRQ(ierr);
809 
810   if (!rhsjacobian && !ijacobian) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()");
811 
812   ierr = PetscLogEventBegin(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr);
813   if (ijacobian) {
814     PetscStackPush("TS user implicit Jacobian");
815     ierr = (*ijacobian)(ts,t,U,Udot,shift,A,B,ctx);CHKERRQ(ierr);
816     PetscStackPop;
817     /* make sure user returned a correct Jacobian and preconditioner */
818     PetscValidHeaderSpecific(A,MAT_CLASSID,4);
819     PetscValidHeaderSpecific(B,MAT_CLASSID,5);
820   }
821   if (imex) {
822     if (!ijacobian) {  /* system was written as Udot = G(t,U) */
823       ierr = MatZeroEntries(A);CHKERRQ(ierr);
824       ierr = MatShift(A,shift);CHKERRQ(ierr);
825       if (A != B) {
826         ierr = MatZeroEntries(B);CHKERRQ(ierr);
827         ierr = MatShift(B,shift);CHKERRQ(ierr);
828       }
829     }
830   } else {
831     Mat Arhs = NULL,Brhs = NULL;
832     if (rhsjacobian) {
833       if (ijacobian) {
834         ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
835       } else {
836         ierr = TSGetIJacobian(ts,&Arhs,&Brhs,NULL,NULL);CHKERRQ(ierr);
837       }
838       ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr);
839     }
840     if (Arhs == A) {           /* No IJacobian, so we only have the RHS matrix */
841       ts->rhsjacobian.scale = -1;
842       ts->rhsjacobian.shift = shift;
843       ierr = MatScale(A,-1);CHKERRQ(ierr);
844       ierr = MatShift(A,shift);CHKERRQ(ierr);
845       if (A != B) {
846         ierr = MatScale(B,-1);CHKERRQ(ierr);
847         ierr = MatShift(B,shift);CHKERRQ(ierr);
848       }
849     } else if (Arhs) {          /* Both IJacobian and RHSJacobian */
850       MatStructure axpy = DIFFERENT_NONZERO_PATTERN;
851       if (!ijacobian) {         /* No IJacobian provided, but we have a separate RHS matrix */
852         ierr = MatZeroEntries(A);CHKERRQ(ierr);
853         ierr = MatShift(A,shift);CHKERRQ(ierr);
854         if (A != B) {
855           ierr = MatZeroEntries(B);CHKERRQ(ierr);
856           ierr = MatShift(B,shift);CHKERRQ(ierr);
857         }
858       }
859       ierr = MatAXPY(A,-1,Arhs,axpy);CHKERRQ(ierr);
860       if (A != B) {
861         ierr = MatAXPY(B,-1,Brhs,axpy);CHKERRQ(ierr);
862       }
863     }
864   }
865   ierr = PetscLogEventEnd(TS_JacobianEval,ts,U,A,B);CHKERRQ(ierr);
866   PetscFunctionReturn(0);
867 }
868 
869 #undef __FUNCT__
870 #define __FUNCT__ "TSSetRHSFunction"
871 /*@C
872     TSSetRHSFunction - Sets the routine for evaluating the function,
873     where U_t = G(t,u).
874 
875     Logically Collective on TS
876 
877     Input Parameters:
878 +   ts - the TS context obtained from TSCreate()
879 .   r - vector to put the computed right hand side (or NULL to have it created)
880 .   f - routine for evaluating the right-hand-side function
881 -   ctx - [optional] user-defined context for private data for the
882           function evaluation routine (may be NULL)
883 
884     Calling sequence of func:
885 $     func (TS ts,PetscReal t,Vec u,Vec F,void *ctx);
886 
887 +   t - current timestep
888 .   u - input vector
889 .   F - function vector
890 -   ctx - [optional] user-defined function context
891 
892     Level: beginner
893 
894     Notes: You must call this function or TSSetIFunction() to define your ODE. You cannot use this function when solving a DAE.
895 
896 .keywords: TS, timestep, set, right-hand-side, function
897 
898 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSSetIFunction()
899 @*/
900 PetscErrorCode  TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx)
901 {
902   PetscErrorCode ierr;
903   SNES           snes;
904   Vec            ralloc = NULL;
905   DM             dm;
906 
907   PetscFunctionBegin;
908   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
909   if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2);
910 
911   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
912   ierr = DMTSSetRHSFunction(dm,f,ctx);CHKERRQ(ierr);
913   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
914   if (!r && !ts->dm && ts->vec_sol) {
915     ierr = VecDuplicate(ts->vec_sol,&ralloc);CHKERRQ(ierr);
916     r    = ralloc;
917   }
918   ierr = SNESSetFunction(snes,r,SNESTSFormFunction,ts);CHKERRQ(ierr);
919   ierr = VecDestroy(&ralloc);CHKERRQ(ierr);
920   PetscFunctionReturn(0);
921 }
922 
923 #undef __FUNCT__
924 #define __FUNCT__ "TSSetSolutionFunction"
925 /*@C
926     TSSetSolutionFunction - Provide a function that computes the solution of the ODE or DAE
927 
928     Logically Collective on TS
929 
930     Input Parameters:
931 +   ts - the TS context obtained from TSCreate()
932 .   f - routine for evaluating the solution
933 -   ctx - [optional] user-defined context for private data for the
934           function evaluation routine (may be NULL)
935 
936     Calling sequence of func:
937 $     func (TS ts,PetscReal t,Vec u,void *ctx);
938 
939 +   t - current timestep
940 .   u - output vector
941 -   ctx - [optional] user-defined function context
942 
943     Notes:
944     This routine is used for testing accuracy of time integration schemes when you already know the solution.
945     If analytic solutions are not known for your system, consider using the Method of Manufactured Solutions to
946     create closed-form solutions with non-physical forcing terms.
947 
948     For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history.
949 
950     Level: beginner
951 
952 .keywords: TS, timestep, set, right-hand-side, function
953 
954 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetForcingFunction()
955 @*/
956 PetscErrorCode  TSSetSolutionFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx)
957 {
958   PetscErrorCode ierr;
959   DM             dm;
960 
961   PetscFunctionBegin;
962   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
963   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
964   ierr = DMTSSetSolutionFunction(dm,f,ctx);CHKERRQ(ierr);
965   PetscFunctionReturn(0);
966 }
967 
968 #undef __FUNCT__
969 #define __FUNCT__ "TSSetForcingFunction"
970 /*@C
971     TSSetForcingFunction - Provide a function that computes a forcing term for a ODE or PDE
972 
973     Logically Collective on TS
974 
975     Input Parameters:
976 +   ts - the TS context obtained from TSCreate()
977 .   f - routine for evaluating the forcing function
978 -   ctx - [optional] user-defined context for private data for the
979           function evaluation routine (may be NULL)
980 
981     Calling sequence of func:
982 $     func (TS ts,PetscReal t,Vec u,void *ctx);
983 
984 +   t - current timestep
985 .   u - output vector
986 -   ctx - [optional] user-defined function context
987 
988     Notes:
989     This routine is useful for testing accuracy of time integration schemes when using the Method of Manufactured Solutions to
990     create closed-form solutions with a non-physical forcing term.
991 
992     For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history.
993 
994     Level: beginner
995 
996 .keywords: TS, timestep, set, right-hand-side, function
997 
998 .seealso: TSSetRHSJacobian(), TSSetIJacobian(), TSComputeSolutionFunction(), TSSetSolutionFunction()
999 @*/
1000 PetscErrorCode  TSSetForcingFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx)
1001 {
1002   PetscErrorCode ierr;
1003   DM             dm;
1004 
1005   PetscFunctionBegin;
1006   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1007   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1008   ierr = DMTSSetForcingFunction(dm,f,ctx);CHKERRQ(ierr);
1009   PetscFunctionReturn(0);
1010 }
1011 
1012 #undef __FUNCT__
1013 #define __FUNCT__ "TSSetRHSJacobian"
1014 /*@C
1015    TSSetRHSJacobian - Sets the function to compute the Jacobian of G,
1016    where U_t = G(U,t), as well as the location to store the matrix.
1017 
1018    Logically Collective on TS
1019 
1020    Input Parameters:
1021 +  ts  - the TS context obtained from TSCreate()
1022 .  Amat - (approximate) Jacobian matrix
1023 .  Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat)
1024 .  f   - the Jacobian evaluation routine
1025 -  ctx - [optional] user-defined context for private data for the
1026          Jacobian evaluation routine (may be NULL)
1027 
1028    Calling sequence of f:
1029 $     func (TS ts,PetscReal t,Vec u,Mat A,Mat B,void *ctx);
1030 
1031 +  t - current timestep
1032 .  u - input vector
1033 .  Amat - (approximate) Jacobian matrix
1034 .  Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat)
1035 -  ctx - [optional] user-defined context for matrix evaluation routine
1036 
1037 
1038    Level: beginner
1039 
1040 .keywords: TS, timestep, set, right-hand-side, Jacobian
1041 
1042 .seealso: SNESComputeJacobianDefaultColor(), TSSetRHSFunction(), TSRHSJacobianSetReuse(), TSSetIJacobian()
1043 
1044 @*/
1045 PetscErrorCode  TSSetRHSJacobian(TS ts,Mat Amat,Mat Pmat,TSRHSJacobian f,void *ctx)
1046 {
1047   PetscErrorCode ierr;
1048   SNES           snes;
1049   DM             dm;
1050   TSIJacobian    ijacobian;
1051 
1052   PetscFunctionBegin;
1053   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1054   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
1055   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3);
1056   if (Amat) PetscCheckSameComm(ts,1,Amat,2);
1057   if (Pmat) PetscCheckSameComm(ts,1,Pmat,3);
1058 
1059   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1060   ierr = DMTSSetRHSJacobian(dm,f,ctx);CHKERRQ(ierr);
1061   if (f == TSComputeRHSJacobianConstant) {
1062     /* Handle this case automatically for the user; otherwise user should call themselves. */
1063     ierr = TSRHSJacobianSetReuse(ts,PETSC_TRUE);CHKERRQ(ierr);
1064   }
1065   ierr = DMTSGetIJacobian(dm,&ijacobian,NULL);CHKERRQ(ierr);
1066   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1067   if (!ijacobian) {
1068     ierr = SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts);CHKERRQ(ierr);
1069   }
1070   if (Amat) {
1071     ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr);
1072     ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr);
1073 
1074     ts->Arhs = Amat;
1075   }
1076   if (Pmat) {
1077     ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr);
1078     ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr);
1079 
1080     ts->Brhs = Pmat;
1081   }
1082   PetscFunctionReturn(0);
1083 }
1084 
1085 
1086 #undef __FUNCT__
1087 #define __FUNCT__ "TSSetIFunction"
1088 /*@C
1089    TSSetIFunction - Set the function to compute F(t,U,U_t) where F() = 0 is the DAE to be solved.
1090 
1091    Logically Collective on TS
1092 
1093    Input Parameters:
1094 +  ts  - the TS context obtained from TSCreate()
1095 .  r   - vector to hold the residual (or NULL to have it created internally)
1096 .  f   - the function evaluation routine
1097 -  ctx - user-defined context for private data for the function evaluation routine (may be NULL)
1098 
1099    Calling sequence of f:
1100 $  f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx);
1101 
1102 +  t   - time at step/stage being solved
1103 .  u   - state vector
1104 .  u_t - time derivative of state vector
1105 .  F   - function vector
1106 -  ctx - [optional] user-defined context for matrix evaluation routine
1107 
1108    Important:
1109    The user MUST call either this routine or TSSetRHSFunction() to define the ODE.  When solving DAEs you must use this function.
1110 
1111    Level: beginner
1112 
1113 .keywords: TS, timestep, set, DAE, Jacobian
1114 
1115 .seealso: TSSetRHSJacobian(), TSSetRHSFunction(), TSSetIJacobian()
1116 @*/
1117 PetscErrorCode  TSSetIFunction(TS ts,Vec res,TSIFunction f,void *ctx)
1118 {
1119   PetscErrorCode ierr;
1120   SNES           snes;
1121   Vec            resalloc = NULL;
1122   DM             dm;
1123 
1124   PetscFunctionBegin;
1125   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1126   if (res) PetscValidHeaderSpecific(res,VEC_CLASSID,2);
1127 
1128   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1129   ierr = DMTSSetIFunction(dm,f,ctx);CHKERRQ(ierr);
1130 
1131   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1132   if (!res && !ts->dm && ts->vec_sol) {
1133     ierr = VecDuplicate(ts->vec_sol,&resalloc);CHKERRQ(ierr);
1134     res  = resalloc;
1135   }
1136   ierr = SNESSetFunction(snes,res,SNESTSFormFunction,ts);CHKERRQ(ierr);
1137   ierr = VecDestroy(&resalloc);CHKERRQ(ierr);
1138   PetscFunctionReturn(0);
1139 }
1140 
1141 #undef __FUNCT__
1142 #define __FUNCT__ "TSGetIFunction"
1143 /*@C
1144    TSGetIFunction - Returns the vector where the implicit residual is stored and the function/contex to compute it.
1145 
1146    Not Collective
1147 
1148    Input Parameter:
1149 .  ts - the TS context
1150 
1151    Output Parameter:
1152 +  r - vector to hold residual (or NULL)
1153 .  func - the function to compute residual (or NULL)
1154 -  ctx - the function context (or NULL)
1155 
1156    Level: advanced
1157 
1158 .keywords: TS, nonlinear, get, function
1159 
1160 .seealso: TSSetIFunction(), SNESGetFunction()
1161 @*/
1162 PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx)
1163 {
1164   PetscErrorCode ierr;
1165   SNES           snes;
1166   DM             dm;
1167 
1168   PetscFunctionBegin;
1169   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1170   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1171   ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr);
1172   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1173   ierr = DMTSGetIFunction(dm,func,ctx);CHKERRQ(ierr);
1174   PetscFunctionReturn(0);
1175 }
1176 
1177 #undef __FUNCT__
1178 #define __FUNCT__ "TSGetRHSFunction"
1179 /*@C
1180    TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it.
1181 
1182    Not Collective
1183 
1184    Input Parameter:
1185 .  ts - the TS context
1186 
1187    Output Parameter:
1188 +  r - vector to hold computed right hand side (or NULL)
1189 .  func - the function to compute right hand side (or NULL)
1190 -  ctx - the function context (or NULL)
1191 
1192    Level: advanced
1193 
1194 .keywords: TS, nonlinear, get, function
1195 
1196 .seealso: TSSetRHSFunction(), SNESGetFunction()
1197 @*/
1198 PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx)
1199 {
1200   PetscErrorCode ierr;
1201   SNES           snes;
1202   DM             dm;
1203 
1204   PetscFunctionBegin;
1205   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1206   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1207   ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr);
1208   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1209   ierr = DMTSGetRHSFunction(dm,func,ctx);CHKERRQ(ierr);
1210   PetscFunctionReturn(0);
1211 }
1212 
1213 #undef __FUNCT__
1214 #define __FUNCT__ "TSSetIJacobian"
1215 /*@C
1216    TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function
1217         provided with TSSetIFunction().
1218 
1219    Logically Collective on TS
1220 
1221    Input Parameters:
1222 +  ts  - the TS context obtained from TSCreate()
1223 .  Amat - (approximate) Jacobian matrix
1224 .  Pmat - matrix used to compute preconditioner (usually the same as Amat)
1225 .  f   - the Jacobian evaluation routine
1226 -  ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL)
1227 
1228    Calling sequence of f:
1229 $  f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat Amat,Mat Pmat,void *ctx);
1230 
1231 +  t    - time at step/stage being solved
1232 .  U    - state vector
1233 .  U_t  - time derivative of state vector
1234 .  a    - shift
1235 .  Amat - (approximate) Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t
1236 .  Pmat - matrix used for constructing preconditioner, usually the same as Amat
1237 -  ctx  - [optional] user-defined context for matrix evaluation routine
1238 
1239    Notes:
1240    The matrices Amat and Pmat are exactly the matrices that are used by SNES for the nonlinear solve.
1241 
1242    If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null
1243    space to Amat and the KSP solvers will automatically use that null space as needed during the solution process.
1244 
1245    The matrix dF/dU + a*dF/dU_t you provide turns out to be
1246    the Jacobian of F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved.
1247    The time integrator internally approximates U_t by W+a*U where the positive "shift"
1248    a and vector W depend on the integration method, step size, and past states. For example with
1249    the backward Euler method a = 1/dt and W = -a*U(previous timestep) so
1250    W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt
1251 
1252    Level: beginner
1253 
1254 .keywords: TS, timestep, DAE, Jacobian
1255 
1256 .seealso: TSSetIFunction(), TSSetRHSJacobian(), SNESComputeJacobianDefaultColor(), SNESComputeJacobianDefault(), TSSetRHSFunction()
1257 
1258 @*/
1259 PetscErrorCode  TSSetIJacobian(TS ts,Mat Amat,Mat Pmat,TSIJacobian f,void *ctx)
1260 {
1261   PetscErrorCode ierr;
1262   SNES           snes;
1263   DM             dm;
1264 
1265   PetscFunctionBegin;
1266   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1267   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
1268   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3);
1269   if (Amat) PetscCheckSameComm(ts,1,Amat,2);
1270   if (Pmat) PetscCheckSameComm(ts,1,Pmat,3);
1271 
1272   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1273   ierr = DMTSSetIJacobian(dm,f,ctx);CHKERRQ(ierr);
1274 
1275   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1276   ierr = SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts);CHKERRQ(ierr);
1277   PetscFunctionReturn(0);
1278 }
1279 
1280 #undef __FUNCT__
1281 #define __FUNCT__ "TSRHSJacobianSetReuse"
1282 /*@
1283    TSRHSJacobianSetReuse - restore RHS Jacobian before re-evaluating.  Without this flag, TS will change the sign and
1284    shift the RHS Jacobian for a finite-time-step implicit solve, in which case the user function will need to recompute
1285    the entire Jacobian.  The reuse flag must be set if the evaluation function will assume that the matrix entries have
1286    not been changed by the TS.
1287 
1288    Logically Collective
1289 
1290    Input Arguments:
1291 +  ts - TS context obtained from TSCreate()
1292 -  reuse - PETSC_TRUE if the RHS Jacobian
1293 
1294    Level: intermediate
1295 
1296 .seealso: TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
1297 @*/
1298 PetscErrorCode TSRHSJacobianSetReuse(TS ts,PetscBool reuse)
1299 {
1300   PetscFunctionBegin;
1301   ts->rhsjacobian.reuse = reuse;
1302   PetscFunctionReturn(0);
1303 }
1304 
1305 #undef __FUNCT__
1306 #define __FUNCT__ "TSLoad"
1307 /*@C
1308   TSLoad - Loads a KSP that has been stored in binary  with KSPView().
1309 
1310   Collective on PetscViewer
1311 
1312   Input Parameters:
1313 + newdm - the newly loaded TS, this needs to have been created with TSCreate() or
1314            some related function before a call to TSLoad().
1315 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen()
1316 
1317    Level: intermediate
1318 
1319   Notes:
1320    The type is determined by the data in the file, any type set into the TS before this call is ignored.
1321 
1322   Notes for advanced users:
1323   Most users should not need to know the details of the binary storage
1324   format, since TSLoad() and TSView() completely hide these details.
1325   But for anyone who's interested, the standard binary matrix storage
1326   format is
1327 .vb
1328      has not yet been determined
1329 .ve
1330 
1331 .seealso: PetscViewerBinaryOpen(), TSView(), MatLoad(), VecLoad()
1332 @*/
1333 PetscErrorCode  TSLoad(TS ts, PetscViewer viewer)
1334 {
1335   PetscErrorCode ierr;
1336   PetscBool      isbinary;
1337   PetscInt       classid;
1338   char           type[256];
1339   DMTS           sdm;
1340   DM             dm;
1341 
1342   PetscFunctionBegin;
1343   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1344   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1345   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1346   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
1347 
1348   ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr);
1349   if (classid != TS_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Not TS next in file");
1350   ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr);
1351   ierr = TSSetType(ts, type);CHKERRQ(ierr);
1352   if (ts->ops->load) {
1353     ierr = (*ts->ops->load)(ts,viewer);CHKERRQ(ierr);
1354   }
1355   ierr = DMCreate(PetscObjectComm((PetscObject)ts),&dm);CHKERRQ(ierr);
1356   ierr = DMLoad(dm,viewer);CHKERRQ(ierr);
1357   ierr = TSSetDM(ts,dm);CHKERRQ(ierr);
1358   ierr = DMCreateGlobalVector(ts->dm,&ts->vec_sol);CHKERRQ(ierr);
1359   ierr = VecLoad(ts->vec_sol,viewer);CHKERRQ(ierr);
1360   ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr);
1361   ierr = DMTSLoad(sdm,viewer);CHKERRQ(ierr);
1362   PetscFunctionReturn(0);
1363 }
1364 
1365 #include <petscdraw.h>
1366 #if defined(PETSC_HAVE_SAWS)
1367 #include <petscviewersaws.h>
1368 #endif
1369 #undef __FUNCT__
1370 #define __FUNCT__ "TSView"
1371 /*@C
1372     TSView - Prints the TS data structure.
1373 
1374     Collective on TS
1375 
1376     Input Parameters:
1377 +   ts - the TS context obtained from TSCreate()
1378 -   viewer - visualization context
1379 
1380     Options Database Key:
1381 .   -ts_view - calls TSView() at end of TSStep()
1382 
1383     Notes:
1384     The available visualization contexts include
1385 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
1386 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
1387          output where only the first processor opens
1388          the file.  All other processors send their
1389          data to the first processor to print.
1390 
1391     The user can open an alternative visualization context with
1392     PetscViewerASCIIOpen() - output to a specified file.
1393 
1394     Level: beginner
1395 
1396 .keywords: TS, timestep, view
1397 
1398 .seealso: PetscViewerASCIIOpen()
1399 @*/
1400 PetscErrorCode  TSView(TS ts,PetscViewer viewer)
1401 {
1402   PetscErrorCode ierr;
1403   TSType         type;
1404   PetscBool      iascii,isstring,isundials,isbinary,isdraw;
1405   DMTS           sdm;
1406 #if defined(PETSC_HAVE_SAWS)
1407   PetscBool      issaws;
1408 #endif
1409 
1410   PetscFunctionBegin;
1411   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1412   if (!viewer) {
1413     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ts),&viewer);CHKERRQ(ierr);
1414   }
1415   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1416   PetscCheckSameComm(ts,1,viewer,2);
1417 
1418   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1419   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
1420   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1421   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
1422 #if defined(PETSC_HAVE_SAWS)
1423   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
1424 #endif
1425   if (iascii) {
1426     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer);CHKERRQ(ierr);
1427     ierr = PetscViewerASCIIPrintf(viewer,"  maximum steps=%D\n",ts->max_steps);CHKERRQ(ierr);
1428     ierr = PetscViewerASCIIPrintf(viewer,"  maximum time=%g\n",(double)ts->max_time);CHKERRQ(ierr);
1429     if (ts->problem_type == TS_NONLINEAR) {
1430       ierr = PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solver iterations=%D\n",ts->snes_its);CHKERRQ(ierr);
1431       ierr = PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solve failures=%D\n",ts->num_snes_failures);CHKERRQ(ierr);
1432     }
1433     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",ts->ksp_its);CHKERRQ(ierr);
1434     ierr = PetscViewerASCIIPrintf(viewer,"  total number of rejected steps=%D\n",ts->reject);CHKERRQ(ierr);
1435     ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr);
1436     ierr = DMTSView(sdm,viewer);CHKERRQ(ierr);
1437     if (ts->ops->view) {
1438       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1439       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1440       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1441     }
1442   } else if (isstring) {
1443     ierr = TSGetType(ts,&type);CHKERRQ(ierr);
1444     ierr = PetscViewerStringSPrintf(viewer," %-7.7s",type);CHKERRQ(ierr);
1445   } else if (isbinary) {
1446     PetscInt    classid = TS_FILE_CLASSID;
1447     MPI_Comm    comm;
1448     PetscMPIInt rank;
1449     char        type[256];
1450 
1451     ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr);
1452     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
1453     if (!rank) {
1454       ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
1455       ierr = PetscStrncpy(type,((PetscObject)ts)->type_name,256);CHKERRQ(ierr);
1456       ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
1457     }
1458     if (ts->ops->view) {
1459       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1460     }
1461     ierr = DMView(ts->dm,viewer);CHKERRQ(ierr);
1462     ierr = VecView(ts->vec_sol,viewer);CHKERRQ(ierr);
1463     ierr = DMGetDMTS(ts->dm,&sdm);CHKERRQ(ierr);
1464     ierr = DMTSView(sdm,viewer);CHKERRQ(ierr);
1465   } else if (isdraw) {
1466     PetscDraw draw;
1467     char      str[36];
1468     PetscReal x,y,bottom,h;
1469 
1470     ierr   = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1471     ierr   = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
1472     ierr   = PetscStrcpy(str,"TS: ");CHKERRQ(ierr);
1473     ierr   = PetscStrcat(str,((PetscObject)ts)->type_name);CHKERRQ(ierr);
1474     ierr   = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLACK,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr);
1475     bottom = y - h;
1476     ierr   = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
1477     if (ts->ops->view) {
1478       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1479     }
1480     ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr);
1481 #if defined(PETSC_HAVE_SAWS)
1482   } else if (issaws) {
1483     PetscMPIInt rank;
1484     const char  *name;
1485 
1486     ierr = PetscObjectGetName((PetscObject)ts,&name);CHKERRQ(ierr);
1487     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1488     if (!((PetscObject)ts)->amsmem && !rank) {
1489       char       dir[1024];
1490 
1491       ierr = PetscObjectViewSAWs((PetscObject)ts,viewer);CHKERRQ(ierr);
1492       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time_step",name);CHKERRQ(ierr);
1493       PetscStackCallSAWs(SAWs_Register,(dir,&ts->steps,1,SAWs_READ,SAWs_INT));
1494       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time",name);CHKERRQ(ierr);
1495       PetscStackCallSAWs(SAWs_Register,(dir,&ts->ptime,1,SAWs_READ,SAWs_DOUBLE));
1496     }
1497     if (ts->ops->view) {
1498       ierr = (*ts->ops->view)(ts,viewer);CHKERRQ(ierr);
1499     }
1500 #endif
1501   }
1502 
1503   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1504   ierr = PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials);CHKERRQ(ierr);
1505   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1506   PetscFunctionReturn(0);
1507 }
1508 
1509 
1510 #undef __FUNCT__
1511 #define __FUNCT__ "TSSetApplicationContext"
1512 /*@
1513    TSSetApplicationContext - Sets an optional user-defined context for
1514    the timesteppers.
1515 
1516    Logically Collective on TS
1517 
1518    Input Parameters:
1519 +  ts - the TS context obtained from TSCreate()
1520 -  usrP - optional user context
1521 
1522    Level: intermediate
1523 
1524 .keywords: TS, timestep, set, application, context
1525 
1526 .seealso: TSGetApplicationContext()
1527 @*/
1528 PetscErrorCode  TSSetApplicationContext(TS ts,void *usrP)
1529 {
1530   PetscFunctionBegin;
1531   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1532   ts->user = usrP;
1533   PetscFunctionReturn(0);
1534 }
1535 
1536 #undef __FUNCT__
1537 #define __FUNCT__ "TSGetApplicationContext"
1538 /*@
1539     TSGetApplicationContext - Gets the user-defined context for the
1540     timestepper.
1541 
1542     Not Collective
1543 
1544     Input Parameter:
1545 .   ts - the TS context obtained from TSCreate()
1546 
1547     Output Parameter:
1548 .   usrP - user context
1549 
1550     Level: intermediate
1551 
1552 .keywords: TS, timestep, get, application, context
1553 
1554 .seealso: TSSetApplicationContext()
1555 @*/
1556 PetscErrorCode  TSGetApplicationContext(TS ts,void *usrP)
1557 {
1558   PetscFunctionBegin;
1559   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1560   *(void**)usrP = ts->user;
1561   PetscFunctionReturn(0);
1562 }
1563 
1564 #undef __FUNCT__
1565 #define __FUNCT__ "TSGetTimeStepNumber"
1566 /*@
1567    TSGetTimeStepNumber - Gets the number of time steps completed.
1568 
1569    Not Collective
1570 
1571    Input Parameter:
1572 .  ts - the TS context obtained from TSCreate()
1573 
1574    Output Parameter:
1575 .  iter - number of steps completed so far
1576 
1577    Level: intermediate
1578 
1579 .keywords: TS, timestep, get, iteration, number
1580 .seealso: TSGetTime(), TSGetTimeStep(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSSetPostStep()
1581 @*/
1582 PetscErrorCode  TSGetTimeStepNumber(TS ts,PetscInt *iter)
1583 {
1584   PetscFunctionBegin;
1585   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1586   PetscValidIntPointer(iter,2);
1587   *iter = ts->steps;
1588   PetscFunctionReturn(0);
1589 }
1590 
1591 #undef __FUNCT__
1592 #define __FUNCT__ "TSSetInitialTimeStep"
1593 /*@
1594    TSSetInitialTimeStep - Sets the initial timestep to be used,
1595    as well as the initial time.
1596 
1597    Logically Collective on TS
1598 
1599    Input Parameters:
1600 +  ts - the TS context obtained from TSCreate()
1601 .  initial_time - the initial time
1602 -  time_step - the size of the timestep
1603 
1604    Level: intermediate
1605 
1606 .seealso: TSSetTimeStep(), TSGetTimeStep()
1607 
1608 .keywords: TS, set, initial, timestep
1609 @*/
1610 PetscErrorCode  TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step)
1611 {
1612   PetscErrorCode ierr;
1613 
1614   PetscFunctionBegin;
1615   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1616   ierr = TSSetTimeStep(ts,time_step);CHKERRQ(ierr);
1617   ierr = TSSetTime(ts,initial_time);CHKERRQ(ierr);
1618   PetscFunctionReturn(0);
1619 }
1620 
1621 #undef __FUNCT__
1622 #define __FUNCT__ "TSSetTimeStep"
1623 /*@
1624    TSSetTimeStep - Allows one to reset the timestep at any time,
1625    useful for simple pseudo-timestepping codes.
1626 
1627    Logically Collective on TS
1628 
1629    Input Parameters:
1630 +  ts - the TS context obtained from TSCreate()
1631 -  time_step - the size of the timestep
1632 
1633    Level: intermediate
1634 
1635 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
1636 
1637 .keywords: TS, set, timestep
1638 @*/
1639 PetscErrorCode  TSSetTimeStep(TS ts,PetscReal time_step)
1640 {
1641   PetscFunctionBegin;
1642   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1643   PetscValidLogicalCollectiveReal(ts,time_step,2);
1644   ts->time_step      = time_step;
1645   ts->time_step_orig = time_step;
1646   PetscFunctionReturn(0);
1647 }
1648 
1649 #undef __FUNCT__
1650 #define __FUNCT__ "TSSetExactFinalTime"
1651 /*@
1652    TSSetExactFinalTime - Determines whether to adapt the final time step to
1653      match the exact final time, interpolate solution to the exact final time,
1654      or just return at the final time TS computed.
1655 
1656   Logically Collective on TS
1657 
1658    Input Parameter:
1659 +   ts - the time-step context
1660 -   eftopt - exact final time option
1661 
1662    Level: beginner
1663 
1664 .seealso: TSExactFinalTimeOption
1665 @*/
1666 PetscErrorCode  TSSetExactFinalTime(TS ts,TSExactFinalTimeOption eftopt)
1667 {
1668   PetscFunctionBegin;
1669   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1670   PetscValidLogicalCollectiveEnum(ts,eftopt,2);
1671   ts->exact_final_time = eftopt;
1672   PetscFunctionReturn(0);
1673 }
1674 
1675 #undef __FUNCT__
1676 #define __FUNCT__ "TSGetTimeStep"
1677 /*@
1678    TSGetTimeStep - Gets the current timestep size.
1679 
1680    Not Collective
1681 
1682    Input Parameter:
1683 .  ts - the TS context obtained from TSCreate()
1684 
1685    Output Parameter:
1686 .  dt - the current timestep size
1687 
1688    Level: intermediate
1689 
1690 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
1691 
1692 .keywords: TS, get, timestep
1693 @*/
1694 PetscErrorCode  TSGetTimeStep(TS ts,PetscReal *dt)
1695 {
1696   PetscFunctionBegin;
1697   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1698   PetscValidRealPointer(dt,2);
1699   *dt = ts->time_step;
1700   PetscFunctionReturn(0);
1701 }
1702 
1703 #undef __FUNCT__
1704 #define __FUNCT__ "TSGetSolution"
1705 /*@
1706    TSGetSolution - Returns the solution at the present timestep. It
1707    is valid to call this routine inside the function that you are evaluating
1708    in order to move to the new timestep. This vector not changed until
1709    the solution at the next timestep has been calculated.
1710 
1711    Not Collective, but Vec returned is parallel if TS is parallel
1712 
1713    Input Parameter:
1714 .  ts - the TS context obtained from TSCreate()
1715 
1716    Output Parameter:
1717 .  v - the vector containing the solution
1718 
1719    Level: intermediate
1720 
1721 .seealso: TSGetTimeStep()
1722 
1723 .keywords: TS, timestep, get, solution
1724 @*/
1725 PetscErrorCode  TSGetSolution(TS ts,Vec *v)
1726 {
1727   PetscFunctionBegin;
1728   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1729   PetscValidPointer(v,2);
1730   *v = ts->vec_sol;
1731   PetscFunctionReturn(0);
1732 }
1733 
1734 #undef __FUNCT__
1735 #define __FUNCT__ "TSGetCostGradients"
1736 /*@
1737    TSGetCostGradients - Returns the gradients from the TSAdjointSolve()
1738 
1739    Not Collective, but Vec returned is parallel if TS is parallel
1740 
1741    Input Parameter:
1742 .  ts - the TS context obtained from TSCreate()
1743 
1744    Output Parameter:
1745 +  lambda - vectors containing the gradients of the cost functions with respect to the ODE/DAE solution variables
1746 -  mu - vectors containing the gradients of the cost functions with respect to the problem parameters
1747 
1748    Level: intermediate
1749 
1750 .seealso: TSGetTimeStep()
1751 
1752 .keywords: TS, timestep, get, sensitivity
1753 @*/
1754 PetscErrorCode  TSGetCostGradients(TS ts,PetscInt *numcost,Vec **lambda,Vec **mu)
1755 {
1756   PetscFunctionBegin;
1757   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1758   if (numcost) *numcost = ts->numcost;
1759   if (lambda)  *lambda  = ts->vecs_sensi;
1760   if (mu)      *mu      = ts->vecs_sensip;
1761   PetscFunctionReturn(0);
1762 }
1763 
1764 /* ----- Routines to initialize and destroy a timestepper ---- */
1765 #undef __FUNCT__
1766 #define __FUNCT__ "TSSetProblemType"
1767 /*@
1768   TSSetProblemType - Sets the type of problem to be solved.
1769 
1770   Not collective
1771 
1772   Input Parameters:
1773 + ts   - The TS
1774 - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1775 .vb
1776          U_t - A U = 0      (linear)
1777          U_t - A(t) U = 0   (linear)
1778          F(t,U,U_t) = 0     (nonlinear)
1779 .ve
1780 
1781    Level: beginner
1782 
1783 .keywords: TS, problem type
1784 .seealso: TSSetUp(), TSProblemType, TS
1785 @*/
1786 PetscErrorCode  TSSetProblemType(TS ts, TSProblemType type)
1787 {
1788   PetscErrorCode ierr;
1789 
1790   PetscFunctionBegin;
1791   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1792   ts->problem_type = type;
1793   if (type == TS_LINEAR) {
1794     SNES snes;
1795     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1796     ierr = SNESSetType(snes,SNESKSPONLY);CHKERRQ(ierr);
1797   }
1798   PetscFunctionReturn(0);
1799 }
1800 
1801 #undef __FUNCT__
1802 #define __FUNCT__ "TSGetProblemType"
1803 /*@C
1804   TSGetProblemType - Gets the type of problem to be solved.
1805 
1806   Not collective
1807 
1808   Input Parameter:
1809 . ts   - The TS
1810 
1811   Output Parameter:
1812 . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
1813 .vb
1814          M U_t = A U
1815          M(t) U_t = A(t) U
1816          F(t,U,U_t)
1817 .ve
1818 
1819    Level: beginner
1820 
1821 .keywords: TS, problem type
1822 .seealso: TSSetUp(), TSProblemType, TS
1823 @*/
1824 PetscErrorCode  TSGetProblemType(TS ts, TSProblemType *type)
1825 {
1826   PetscFunctionBegin;
1827   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
1828   PetscValidIntPointer(type,2);
1829   *type = ts->problem_type;
1830   PetscFunctionReturn(0);
1831 }
1832 
1833 #undef __FUNCT__
1834 #define __FUNCT__ "TSSetUp"
1835 /*@
1836    TSSetUp - Sets up the internal data structures for the later use
1837    of a timestepper.
1838 
1839    Collective on TS
1840 
1841    Input Parameter:
1842 .  ts - the TS context obtained from TSCreate()
1843 
1844    Notes:
1845    For basic use of the TS solvers the user need not explicitly call
1846    TSSetUp(), since these actions will automatically occur during
1847    the call to TSStep().  However, if one wishes to control this
1848    phase separately, TSSetUp() should be called after TSCreate()
1849    and optional routines of the form TSSetXXX(), but before TSStep().
1850 
1851    Level: advanced
1852 
1853 .keywords: TS, timestep, setup
1854 
1855 .seealso: TSCreate(), TSStep(), TSDestroy()
1856 @*/
1857 PetscErrorCode  TSSetUp(TS ts)
1858 {
1859   PetscErrorCode ierr;
1860   DM             dm;
1861   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
1862   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
1863   TSIJacobian    ijac;
1864   TSRHSJacobian  rhsjac;
1865 
1866   PetscFunctionBegin;
1867   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1868   if (ts->setupcalled) PetscFunctionReturn(0);
1869 
1870   ts->total_steps = 0;
1871   if (!((PetscObject)ts)->type_name) {
1872     ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr);
1873   }
1874 
1875   if (!ts->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first");
1876 
1877 
1878   ierr = TSGetAdapt(ts,&ts->adapt);CHKERRQ(ierr);
1879 
1880   if (ts->rhsjacobian.reuse) {
1881     Mat Amat,Pmat;
1882     SNES snes;
1883     ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
1884     ierr = SNESGetJacobian(snes,&Amat,&Pmat,NULL,NULL);CHKERRQ(ierr);
1885     /* Matching matrices implies that an IJacobian is NOT set, because if it had been set, the IJacobian's matrix would
1886      * have displaced the RHS matrix */
1887     if (Amat == ts->Arhs) {
1888       ierr = MatDuplicate(ts->Arhs,MAT_DO_NOT_COPY_VALUES,&Amat);CHKERRQ(ierr);
1889       ierr = SNESSetJacobian(snes,Amat,NULL,NULL,NULL);CHKERRQ(ierr);
1890       ierr = MatDestroy(&Amat);CHKERRQ(ierr);
1891     }
1892     if (Pmat == ts->Brhs) {
1893       ierr = MatDuplicate(ts->Brhs,MAT_DO_NOT_COPY_VALUES,&Pmat);CHKERRQ(ierr);
1894       ierr = SNESSetJacobian(snes,NULL,Pmat,NULL,NULL);CHKERRQ(ierr);
1895       ierr = MatDestroy(&Pmat);CHKERRQ(ierr);
1896     }
1897   }
1898   if (ts->ops->setup) {
1899     ierr = (*ts->ops->setup)(ts);CHKERRQ(ierr);
1900   }
1901 
1902   /* in the case where we've set a DMTSFunction or what have you, we need the default SNESFunction
1903    to be set right but can't do it elsewhere due to the overreliance on ctx=ts.
1904    */
1905   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1906   ierr = DMSNESGetFunction(dm,&func,NULL);CHKERRQ(ierr);
1907   if (!func) {
1908     ierr =DMSNESSetFunction(dm,SNESTSFormFunction,ts);CHKERRQ(ierr);
1909   }
1910   /* if the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it.
1911      Otherwise, the SNES will use coloring internally to form the Jacobian.
1912    */
1913   ierr = DMSNESGetJacobian(dm,&jac,NULL);CHKERRQ(ierr);
1914   ierr = DMTSGetIJacobian(dm,&ijac,NULL);CHKERRQ(ierr);
1915   ierr = DMTSGetRHSJacobian(dm,&rhsjac,NULL);CHKERRQ(ierr);
1916   if (!jac && (ijac || rhsjac)) {
1917     ierr = DMSNESSetJacobian(dm,SNESTSFormJacobian,ts);CHKERRQ(ierr);
1918   }
1919   ts->setupcalled = PETSC_TRUE;
1920   PetscFunctionReturn(0);
1921 }
1922 
1923 #undef __FUNCT__
1924 #define __FUNCT__ "TSAdjointSetUp"
1925 /*@
1926    TSAdjointSetUp - Sets up the internal data structures for the later use
1927    of an adjoint solver
1928 
1929    Collective on TS
1930 
1931    Input Parameter:
1932 .  ts - the TS context obtained from TSCreate()
1933 
1934    Level: advanced
1935 
1936 .keywords: TS, timestep, setup
1937 
1938 .seealso: TSCreate(), TSAdjointStep(), TSSetCostGradients()
1939 @*/
1940 PetscErrorCode  TSAdjointSetUp(TS ts)
1941 {
1942   PetscErrorCode ierr;
1943 
1944   PetscFunctionBegin;
1945   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1946   if (ts->adjointsetupcalled) PetscFunctionReturn(0);
1947   if (!ts->vecs_sensi) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetCostGradients() first");
1948 
1949   if (ts->vec_costintegral) { /* if there is integral in the cost function*/
1950     ierr = VecDuplicateVecs(ts->vecs_sensi[0],ts->numcost,&ts->vecs_drdy);CHKERRQ(ierr);
1951     if (ts->vecs_sensip){
1952       ierr = VecDuplicateVecs(ts->vecs_sensip[0],ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr);
1953     }
1954   }
1955 
1956   if (ts->ops->adjointsetup) {
1957     ierr = (*ts->ops->adjointsetup)(ts);CHKERRQ(ierr);
1958   }
1959   ts->adjointsetupcalled = PETSC_TRUE;
1960   PetscFunctionReturn(0);
1961 }
1962 
1963 #undef __FUNCT__
1964 #define __FUNCT__ "TSReset"
1965 /*@
1966    TSReset - Resets a TS context and removes any allocated Vecs and Mats.
1967 
1968    Collective on TS
1969 
1970    Input Parameter:
1971 .  ts - the TS context obtained from TSCreate()
1972 
1973    Level: beginner
1974 
1975 .keywords: TS, timestep, reset
1976 
1977 .seealso: TSCreate(), TSSetup(), TSDestroy()
1978 @*/
1979 PetscErrorCode  TSReset(TS ts)
1980 {
1981   PetscErrorCode ierr;
1982 
1983   PetscFunctionBegin;
1984   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1985 
1986   if (ts->ops->reset) {
1987     ierr = (*ts->ops->reset)(ts);CHKERRQ(ierr);
1988   }
1989   if (ts->snes) {ierr = SNESReset(ts->snes);CHKERRQ(ierr);}
1990   if (ts->adapt) {ierr = TSAdaptReset(ts->adapt);CHKERRQ(ierr);}
1991 
1992   ierr = MatDestroy(&ts->Arhs);CHKERRQ(ierr);
1993   ierr = MatDestroy(&ts->Brhs);CHKERRQ(ierr);
1994   ierr = VecDestroy(&ts->Frhs);CHKERRQ(ierr);
1995   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
1996   ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
1997   ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
1998   ierr = VecDestroyVecs(ts->nwork,&ts->work);CHKERRQ(ierr);
1999 
2000  if (ts->vec_costintegral) {
2001     ierr = VecDestroyVecs(ts->numcost,&ts->vecs_drdy);CHKERRQ(ierr);
2002     if (ts->vecs_drdp){
2003       ierr = VecDestroyVecs(ts->numcost,&ts->vecs_drdp);CHKERRQ(ierr);
2004     }
2005   }
2006   ts->vecs_sensi  = NULL;
2007   ts->vecs_sensip = NULL;
2008   ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr);
2009   ierr = VecDestroy(&ts->vec_costintegral);CHKERRQ(ierr);
2010   ierr = VecDestroy(&ts->vec_costintegrand);CHKERRQ(ierr);
2011   ts->setupcalled = PETSC_FALSE;
2012   PetscFunctionReturn(0);
2013 }
2014 
2015 #undef __FUNCT__
2016 #define __FUNCT__ "TSDestroy"
2017 /*@
2018    TSDestroy - Destroys the timestepper context that was created
2019    with TSCreate().
2020 
2021    Collective on TS
2022 
2023    Input Parameter:
2024 .  ts - the TS context obtained from TSCreate()
2025 
2026    Level: beginner
2027 
2028 .keywords: TS, timestepper, destroy
2029 
2030 .seealso: TSCreate(), TSSetUp(), TSSolve()
2031 @*/
2032 PetscErrorCode  TSDestroy(TS *ts)
2033 {
2034   PetscErrorCode ierr;
2035 
2036   PetscFunctionBegin;
2037   if (!*ts) PetscFunctionReturn(0);
2038   PetscValidHeaderSpecific((*ts),TS_CLASSID,1);
2039   if (--((PetscObject)(*ts))->refct > 0) {*ts = 0; PetscFunctionReturn(0);}
2040 
2041   ierr = TSReset((*ts));CHKERRQ(ierr);
2042 
2043   /* if memory was published with SAWs then destroy it */
2044   ierr = PetscObjectSAWsViewOff((PetscObject)*ts);CHKERRQ(ierr);
2045   if ((*ts)->ops->destroy) {ierr = (*(*ts)->ops->destroy)((*ts));CHKERRQ(ierr);}
2046 
2047   ierr = TSTrajectoryDestroy(&(*ts)->trajectory);CHKERRQ(ierr);
2048 
2049   ierr = TSAdaptDestroy(&(*ts)->adapt);CHKERRQ(ierr);
2050   if ((*ts)->event) {
2051     ierr = TSEventMonitorDestroy(&(*ts)->event);CHKERRQ(ierr);
2052   }
2053   ierr = SNESDestroy(&(*ts)->snes);CHKERRQ(ierr);
2054   ierr = DMDestroy(&(*ts)->dm);CHKERRQ(ierr);
2055   ierr = TSMonitorCancel((*ts));CHKERRQ(ierr);
2056 
2057   ierr = PetscHeaderDestroy(ts);CHKERRQ(ierr);
2058   PetscFunctionReturn(0);
2059 }
2060 
2061 #undef __FUNCT__
2062 #define __FUNCT__ "TSGetSNES"
2063 /*@
2064    TSGetSNES - Returns the SNES (nonlinear solver) associated with
2065    a TS (timestepper) context. Valid only for nonlinear problems.
2066 
2067    Not Collective, but SNES is parallel if TS is parallel
2068 
2069    Input Parameter:
2070 .  ts - the TS context obtained from TSCreate()
2071 
2072    Output Parameter:
2073 .  snes - the nonlinear solver context
2074 
2075    Notes:
2076    The user can then directly manipulate the SNES context to set various
2077    options, etc.  Likewise, the user can then extract and manipulate the
2078    KSP, KSP, and PC contexts as well.
2079 
2080    TSGetSNES() does not work for integrators that do not use SNES; in
2081    this case TSGetSNES() returns NULL in snes.
2082 
2083    Level: beginner
2084 
2085 .keywords: timestep, get, SNES
2086 @*/
2087 PetscErrorCode  TSGetSNES(TS ts,SNES *snes)
2088 {
2089   PetscErrorCode ierr;
2090 
2091   PetscFunctionBegin;
2092   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2093   PetscValidPointer(snes,2);
2094   if (!ts->snes) {
2095     ierr = SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes);CHKERRQ(ierr);
2096     ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr);
2097     ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->snes);CHKERRQ(ierr);
2098     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1);CHKERRQ(ierr);
2099     if (ts->dm) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
2100     if (ts->problem_type == TS_LINEAR) {
2101       ierr = SNESSetType(ts->snes,SNESKSPONLY);CHKERRQ(ierr);
2102     }
2103   }
2104   *snes = ts->snes;
2105   PetscFunctionReturn(0);
2106 }
2107 
2108 #undef __FUNCT__
2109 #define __FUNCT__ "TSSetSNES"
2110 /*@
2111    TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context
2112 
2113    Collective
2114 
2115    Input Parameter:
2116 +  ts - the TS context obtained from TSCreate()
2117 -  snes - the nonlinear solver context
2118 
2119    Notes:
2120    Most users should have the TS created by calling TSGetSNES()
2121 
2122    Level: developer
2123 
2124 .keywords: timestep, set, SNES
2125 @*/
2126 PetscErrorCode TSSetSNES(TS ts,SNES snes)
2127 {
2128   PetscErrorCode ierr;
2129   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
2130 
2131   PetscFunctionBegin;
2132   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2133   PetscValidHeaderSpecific(snes,SNES_CLASSID,2);
2134   ierr = PetscObjectReference((PetscObject)snes);CHKERRQ(ierr);
2135   ierr = SNESDestroy(&ts->snes);CHKERRQ(ierr);
2136 
2137   ts->snes = snes;
2138 
2139   ierr = SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts);CHKERRQ(ierr);
2140   ierr = SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL);CHKERRQ(ierr);
2141   if (func == SNESTSFormJacobian) {
2142     ierr = SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts);CHKERRQ(ierr);
2143   }
2144   PetscFunctionReturn(0);
2145 }
2146 
2147 #undef __FUNCT__
2148 #define __FUNCT__ "TSGetKSP"
2149 /*@
2150    TSGetKSP - Returns the KSP (linear solver) associated with
2151    a TS (timestepper) context.
2152 
2153    Not Collective, but KSP is parallel if TS is parallel
2154 
2155    Input Parameter:
2156 .  ts - the TS context obtained from TSCreate()
2157 
2158    Output Parameter:
2159 .  ksp - the nonlinear solver context
2160 
2161    Notes:
2162    The user can then directly manipulate the KSP context to set various
2163    options, etc.  Likewise, the user can then extract and manipulate the
2164    KSP and PC contexts as well.
2165 
2166    TSGetKSP() does not work for integrators that do not use KSP;
2167    in this case TSGetKSP() returns NULL in ksp.
2168 
2169    Level: beginner
2170 
2171 .keywords: timestep, get, KSP
2172 @*/
2173 PetscErrorCode  TSGetKSP(TS ts,KSP *ksp)
2174 {
2175   PetscErrorCode ierr;
2176   SNES           snes;
2177 
2178   PetscFunctionBegin;
2179   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2180   PetscValidPointer(ksp,2);
2181   if (!((PetscObject)ts)->type_name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first");
2182   if (ts->problem_type != TS_LINEAR) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()");
2183   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
2184   ierr = SNESGetKSP(snes,ksp);CHKERRQ(ierr);
2185   PetscFunctionReturn(0);
2186 }
2187 
2188 /* ----------- Routines to set solver parameters ---------- */
2189 
2190 #undef __FUNCT__
2191 #define __FUNCT__ "TSGetDuration"
2192 /*@
2193    TSGetDuration - Gets the maximum number of timesteps to use and
2194    maximum time for iteration.
2195 
2196    Not Collective
2197 
2198    Input Parameters:
2199 +  ts       - the TS context obtained from TSCreate()
2200 .  maxsteps - maximum number of iterations to use, or NULL
2201 -  maxtime  - final time to iterate to, or NULL
2202 
2203    Level: intermediate
2204 
2205 .keywords: TS, timestep, get, maximum, iterations, time
2206 @*/
2207 PetscErrorCode  TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
2208 {
2209   PetscFunctionBegin;
2210   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2211   if (maxsteps) {
2212     PetscValidIntPointer(maxsteps,2);
2213     *maxsteps = ts->max_steps;
2214   }
2215   if (maxtime) {
2216     PetscValidScalarPointer(maxtime,3);
2217     *maxtime = ts->max_time;
2218   }
2219   PetscFunctionReturn(0);
2220 }
2221 
2222 #undef __FUNCT__
2223 #define __FUNCT__ "TSSetDuration"
2224 /*@
2225    TSSetDuration - Sets the maximum number of timesteps to use and
2226    maximum time for iteration.
2227 
2228    Logically Collective on TS
2229 
2230    Input Parameters:
2231 +  ts - the TS context obtained from TSCreate()
2232 .  maxsteps - maximum number of iterations to use
2233 -  maxtime - final time to iterate to
2234 
2235    Options Database Keys:
2236 .  -ts_max_steps <maxsteps> - Sets maxsteps
2237 .  -ts_final_time <maxtime> - Sets maxtime
2238 
2239    Notes:
2240    The default maximum number of iterations is 5000. Default time is 5.0
2241 
2242    Level: intermediate
2243 
2244 .keywords: TS, timestep, set, maximum, iterations
2245 
2246 .seealso: TSSetExactFinalTime()
2247 @*/
2248 PetscErrorCode  TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime)
2249 {
2250   PetscFunctionBegin;
2251   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2252   PetscValidLogicalCollectiveInt(ts,maxsteps,2);
2253   PetscValidLogicalCollectiveReal(ts,maxtime,2);
2254   if (maxsteps >= 0) ts->max_steps = maxsteps;
2255   if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime;
2256   PetscFunctionReturn(0);
2257 }
2258 
2259 #undef __FUNCT__
2260 #define __FUNCT__ "TSSetSolution"
2261 /*@
2262    TSSetSolution - Sets the initial solution vector
2263    for use by the TS routines.
2264 
2265    Logically Collective on TS and Vec
2266 
2267    Input Parameters:
2268 +  ts - the TS context obtained from TSCreate()
2269 -  u - the solution vector
2270 
2271    Level: beginner
2272 
2273 .keywords: TS, timestep, set, solution, initial conditions
2274 @*/
2275 PetscErrorCode  TSSetSolution(TS ts,Vec u)
2276 {
2277   PetscErrorCode ierr;
2278   DM             dm;
2279 
2280   PetscFunctionBegin;
2281   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2282   PetscValidHeaderSpecific(u,VEC_CLASSID,2);
2283   ierr = PetscObjectReference((PetscObject)u);CHKERRQ(ierr);
2284   ierr = VecDestroy(&ts->vec_sol);CHKERRQ(ierr);
2285 
2286   ts->vec_sol = u;
2287 
2288   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
2289   ierr = DMShellSetGlobalVector(dm,u);CHKERRQ(ierr);
2290   PetscFunctionReturn(0);
2291 }
2292 
2293 #undef __FUNCT__
2294 #define __FUNCT__ "TSAdjointSetSteps"
2295 /*@
2296    TSAdjointSetSteps - Sets the number of steps the adjoint solver should take backward in time
2297 
2298    Logically Collective on TS
2299 
2300    Input Parameters:
2301 +  ts - the TS context obtained from TSCreate()
2302 .  steps - number of steps to use
2303 
2304    Level: intermediate
2305 
2306    Notes: Normally one does not call this and TSAdjointSolve() integrates back to the original timestep. One can call this
2307           so as to integrate back to less than the original timestep
2308 
2309 .keywords: TS, timestep, set, maximum, iterations
2310 
2311 .seealso: TSSetExactFinalTime()
2312 @*/
2313 PetscErrorCode  TSAdjointSetSteps(TS ts,PetscInt steps)
2314 {
2315   PetscFunctionBegin;
2316   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2317   PetscValidLogicalCollectiveInt(ts,steps,2);
2318   if (steps < 0) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back a negative number of steps");
2319   if (steps > ts->total_steps) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Cannot step back more than the total number of forward steps");
2320   ts->adjoint_max_steps = steps;
2321   PetscFunctionReturn(0);
2322 }
2323 
2324 #undef __FUNCT__
2325 #define __FUNCT__ "TSSetCostGradients"
2326 /*@
2327    TSSetCostGradients - Sets the initial value of the gradients of the cost function w.r.t. initial conditions and w.r.t. the problem parameters
2328       for use by the TSAdjoint routines.
2329 
2330    Logically Collective on TS and Vec
2331 
2332    Input Parameters:
2333 +  ts - the TS context obtained from TSCreate()
2334 .  lambda - gradients with respect to the initial condition variables, the dimension and parallel layout of these vectors is the same as the ODE solution vector
2335 -  mu - gradients with respect to the parameters, the number of entries in these vectors is the same as the number of parameters
2336 
2337    Level: beginner
2338 
2339    Notes: the entries in these vectors must be correctly initialized with the values lamda_i = df/dy|finaltime  mu_i = df/dp|finaltime
2340 
2341 .keywords: TS, timestep, set, sensitivity, initial conditions
2342 @*/
2343 PetscErrorCode  TSSetCostGradients(TS ts,PetscInt numcost,Vec *lambda,Vec *mu)
2344 {
2345   PetscFunctionBegin;
2346   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2347   PetscValidPointer(lambda,2);
2348   ts->vecs_sensi  = lambda;
2349   ts->vecs_sensip = mu;
2350   if (ts->numcost && ts->numcost!=numcost) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"The number of cost functions (2rd parameter of TSSetCostIntegrand()) is inconsistent with the one set by TSSetCostIntegrand");
2351   ts->numcost  = numcost;
2352   PetscFunctionReturn(0);
2353 }
2354 
2355 #undef __FUNCT__
2356 #define __FUNCT__ "TSAdjointSetRHSJacobian"
2357 /*@C
2358   TSAdjointSetRHSJacobian - Sets the function that computes the Jacobian of G w.r.t. the parameters p where y_t = G(y,p,t), as well as the location to store the matrix.
2359 
2360   Logically Collective on TS
2361 
2362   Input Parameters:
2363 + ts   - The TS context obtained from TSCreate()
2364 - func - The function
2365 
2366   Calling sequence of func:
2367 $ func (TS ts,PetscReal t,Vec y,Mat A,void *ctx);
2368 +   t - current timestep
2369 .   y - input vector (current ODE solution)
2370 .   A - output matrix
2371 -   ctx - [optional] user-defined function context
2372 
2373   Level: intermediate
2374 
2375   Notes: Amat has the same number of rows and the same row parallel layout as u, Amat has the same number of columns and parallel layout as p
2376 
2377 .keywords: TS, sensitivity
2378 .seealso:
2379 @*/
2380 PetscErrorCode  TSAdjointSetRHSJacobian(TS ts,Mat Amat,PetscErrorCode (*func)(TS,PetscReal,Vec,Mat,void*),void *ctx)
2381 {
2382   PetscErrorCode ierr;
2383 
2384   PetscFunctionBegin;
2385   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2386   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
2387 
2388   ts->rhsjacobianp    = func;
2389   ts->rhsjacobianpctx = ctx;
2390   if(Amat) {
2391     ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr);
2392     ierr = MatDestroy(&ts->Jacp);CHKERRQ(ierr);
2393     ts->Jacp = Amat;
2394   }
2395   PetscFunctionReturn(0);
2396 }
2397 
2398 #undef __FUNCT__
2399 #define __FUNCT__ "TSAdjointComputeRHSJacobian"
2400 /*@C
2401   TSAdjointComputeRHSJacobian - Runs the user-defined Jacobian function.
2402 
2403   Collective on TS
2404 
2405   Input Parameters:
2406 . ts   - The TS context obtained from TSCreate()
2407 
2408   Level: developer
2409 
2410 .keywords: TS, sensitivity
2411 .seealso: TSAdjointSetRHSJacobian()
2412 @*/
2413 PetscErrorCode  TSAdjointComputeRHSJacobian(TS ts,PetscReal t,Vec X,Mat Amat)
2414 {
2415   PetscErrorCode ierr;
2416 
2417   PetscFunctionBegin;
2418   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2419   PetscValidHeaderSpecific(X,VEC_CLASSID,3);
2420   PetscValidPointer(Amat,4);
2421 
2422   PetscStackPush("TS user JacobianP function for sensitivity analysis");
2423   ierr = (*ts->rhsjacobianp)(ts,t,X,Amat,ts->rhsjacobianpctx); CHKERRQ(ierr);
2424   PetscStackPop;
2425   PetscFunctionReturn(0);
2426 }
2427 
2428 #undef __FUNCT__
2429 #define __FUNCT__ "TSSetCostIntegrand"
2430 /*@C
2431     TSSetCostIntegrand - Sets the routine for evaluating the integral term in one or more cost functions
2432 
2433     Logically Collective on TS
2434 
2435     Input Parameters:
2436 +   ts - the TS context obtained from TSCreate()
2437 .   numcost - number of gradients to be computed, this is the number of cost functions
2438 .   rf - routine for evaluating the integrand function
2439 .   drdyf - function that computes the gradients of the r's with respect to y,NULL if not a function y
2440 .   drdpf - function that computes the gradients of the r's with respect to p, NULL if not a function of p
2441 -   ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
2442 
2443     Calling sequence of rf:
2444 $     rf(TS ts,PetscReal t,Vec y,Vec f[],void *ctx);
2445 
2446 +   t - current timestep
2447 .   y - input vector
2448 .   f - function result; one vector entry for each cost function
2449 -   ctx - [optional] user-defined function context
2450 
2451    Calling sequence of drdyf:
2452 $    PetscErroCode drdyf(TS ts,PetscReal t,Vec y,Vec *drdy,void *ctx);
2453 
2454    Calling sequence of drdpf:
2455 $    PetscErroCode drdpf(TS ts,PetscReal t,Vec y,Vec *drdp,void *ctx);
2456 
2457     Level: intermediate
2458 
2459     Notes: For optimization there is generally a single cost function, numcost = 1. For sensitivities there may be multiple cost functions
2460 
2461 .keywords: TS, sensitivity analysis, timestep, set, quadrature, function
2462 
2463 .seealso: TSAdjointSetRHSJacobian(),TSGetCostGradients(), TSSetCostGradients()
2464 @*/
2465 PetscErrorCode  TSSetCostIntegrand(TS ts,PetscInt numcost, PetscErrorCode (*rf)(TS,PetscReal,Vec,Vec,void*),
2466                                                                   PetscErrorCode (*drdyf)(TS,PetscReal,Vec,Vec*,void*),
2467                                                                   PetscErrorCode (*drdpf)(TS,PetscReal,Vec,Vec*,void*),void *ctx)
2468 {
2469   PetscErrorCode ierr;
2470 
2471   PetscFunctionBegin;
2472   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2473   if (ts->numcost && ts->numcost!=numcost) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"The number of cost functions (2rd parameter of TSSetCostIntegrand()) is inconsistent with the one set by TSSetCostGradients()");
2474   if (!ts->numcost) ts->numcost=numcost;
2475 
2476   ierr                 = VecCreateSeq(PETSC_COMM_SELF,numcost,&ts->vec_costintegral);CHKERRQ(ierr);
2477   ierr                 = VecDuplicate(ts->vec_costintegral,&ts->vec_costintegrand);CHKERRQ(ierr);
2478   ts->costintegrand    = rf;
2479   ts->costintegrandctx = ctx;
2480   ts->drdyfunction     = drdyf;
2481   ts->drdpfunction     = drdpf;
2482   PetscFunctionReturn(0);
2483 }
2484 
2485 #undef __FUNCT__
2486 #define __FUNCT__ "TSGetCostIntegral"
2487 /*@
2488    TSGetCostIntegral - Returns the values of the integral term in the cost functions.
2489    It is valid to call the routine after a backward run.
2490 
2491    Not Collective
2492 
2493    Input Parameter:
2494 .  ts - the TS context obtained from TSCreate()
2495 
2496    Output Parameter:
2497 .  v - the vector containing the integrals for each cost function
2498 
2499    Level: intermediate
2500 
2501 .seealso: TSSetCostIntegrand()
2502 
2503 .keywords: TS, sensitivity analysis
2504 @*/
2505 PetscErrorCode  TSGetCostIntegral(TS ts,Vec *v)
2506 {
2507   PetscFunctionBegin;
2508   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2509   PetscValidPointer(v,2);
2510   *v = ts->vec_costintegral;
2511   PetscFunctionReturn(0);
2512 }
2513 
2514 #undef __FUNCT__
2515 #define __FUNCT__ "TSAdjointComputeCostIntegrand"
2516 /*@
2517    TSAdjointComputeCostIntegrand - Evaluates the integral function in the cost functions.
2518 
2519    Input Parameters:
2520 +  ts - the TS context
2521 .  t - current time
2522 -  y - state vector, i.e. current solution
2523 
2524    Output Parameter:
2525 .  q - vector of size numcost to hold the outputs
2526 
2527    Note:
2528    Most users should not need to explicitly call this routine, as it
2529    is used internally within the sensitivity analysis context.
2530 
2531    Level: developer
2532 
2533 .keywords: TS, compute
2534 
2535 .seealso: TSSetCostIntegrand()
2536 @*/
2537 PetscErrorCode TSAdjointComputeCostIntegrand(TS ts,PetscReal t,Vec y,Vec q)
2538 {
2539   PetscErrorCode ierr;
2540 
2541   PetscFunctionBegin;
2542   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2543   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2544   PetscValidHeaderSpecific(q,VEC_CLASSID,4);
2545 
2546   ierr = PetscLogEventBegin(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr);
2547   if (ts->costintegrand) {
2548     PetscStackPush("TS user integrand in the cost function");
2549     ierr = (*ts->costintegrand)(ts,t,y,q,ts->costintegrandctx);CHKERRQ(ierr);
2550     PetscStackPop;
2551   } else {
2552     ierr = VecZeroEntries(q);CHKERRQ(ierr);
2553   }
2554 
2555   ierr = PetscLogEventEnd(TS_FunctionEval,ts,y,q,0);CHKERRQ(ierr);
2556   PetscFunctionReturn(0);
2557 }
2558 
2559 #undef __FUNCT__
2560 #define __FUNCT__ "TSAdjointComputeDRDYFunction"
2561 /*@
2562   TSAdjointComputeDRDYFunction - Runs the user-defined DRDY function.
2563 
2564   Collective on TS
2565 
2566   Input Parameters:
2567 . ts   - The TS context obtained from TSCreate()
2568 
2569   Notes:
2570   TSAdjointComputeDRDYFunction() is typically used for sensitivity implementation,
2571   so most users would not generally call this routine themselves.
2572 
2573   Level: developer
2574 
2575 .keywords: TS, sensitivity
2576 .seealso: TSAdjointComputeDRDYFunction()
2577 @*/
2578 PetscErrorCode  TSAdjointComputeDRDYFunction(TS ts,PetscReal t,Vec y,Vec *drdy)
2579 {
2580   PetscErrorCode ierr;
2581 
2582   PetscFunctionBegin;
2583   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2584   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2585 
2586   PetscStackPush("TS user DRDY function for sensitivity analysis");
2587   ierr = (*ts->drdyfunction)(ts,t,y,drdy,ts->costintegrandctx); CHKERRQ(ierr);
2588   PetscStackPop;
2589   PetscFunctionReturn(0);
2590 }
2591 
2592 #undef __FUNCT__
2593 #define __FUNCT__ "TSAdjointComputeDRDPFunction"
2594 /*@
2595   TSAdjointComputeDRDPFunction - Runs the user-defined DRDP function.
2596 
2597   Collective on TS
2598 
2599   Input Parameters:
2600 . ts   - The TS context obtained from TSCreate()
2601 
2602   Notes:
2603   TSDRDPFunction() is typically used for sensitivity implementation,
2604   so most users would not generally call this routine themselves.
2605 
2606   Level: developer
2607 
2608 .keywords: TS, sensitivity
2609 .seealso: TSAdjointSetDRDPFunction()
2610 @*/
2611 PetscErrorCode  TSAdjointComputeDRDPFunction(TS ts,PetscReal t,Vec y,Vec *drdp)
2612 {
2613   PetscErrorCode ierr;
2614 
2615   PetscFunctionBegin;
2616   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2617   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2618 
2619   PetscStackPush("TS user DRDP function for sensitivity analysis");
2620   ierr = (*ts->drdpfunction)(ts,t,y,drdp,ts->costintegrandctx); CHKERRQ(ierr);
2621   PetscStackPop;
2622   PetscFunctionReturn(0);
2623 }
2624 
2625 #undef __FUNCT__
2626 #define __FUNCT__ "TSSetPreStep"
2627 /*@C
2628   TSSetPreStep - Sets the general-purpose function
2629   called once at the beginning of each time step.
2630 
2631   Logically Collective on TS
2632 
2633   Input Parameters:
2634 + ts   - The TS context obtained from TSCreate()
2635 - func - The function
2636 
2637   Calling sequence of func:
2638 . func (TS ts);
2639 
2640   Level: intermediate
2641 
2642   Note:
2643   If a step is rejected, TSStep() will call this routine again before each attempt.
2644   The last completed time step number can be queried using TSGetTimeStepNumber(), the
2645   size of the step being attempted can be obtained using TSGetTimeStep().
2646 
2647 .keywords: TS, timestep
2648 .seealso: TSSetPreStage(), TSSetPostStage(), TSSetPostStep(), TSStep()
2649 @*/
2650 PetscErrorCode  TSSetPreStep(TS ts, PetscErrorCode (*func)(TS))
2651 {
2652   PetscFunctionBegin;
2653   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2654   ts->prestep = func;
2655   PetscFunctionReturn(0);
2656 }
2657 
2658 #undef __FUNCT__
2659 #define __FUNCT__ "TSPreStep"
2660 /*@
2661   TSPreStep - Runs the user-defined pre-step function.
2662 
2663   Collective on TS
2664 
2665   Input Parameters:
2666 . ts   - The TS context obtained from TSCreate()
2667 
2668   Notes:
2669   TSPreStep() is typically used within time stepping implementations,
2670   so most users would not generally call this routine themselves.
2671 
2672   Level: developer
2673 
2674 .keywords: TS, timestep
2675 .seealso: TSSetPreStep(), TSPreStage(), TSPostStage(), TSPostStep()
2676 @*/
2677 PetscErrorCode  TSPreStep(TS ts)
2678 {
2679   PetscErrorCode ierr;
2680 
2681   PetscFunctionBegin;
2682   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2683   if (ts->prestep) {
2684     PetscStackCallStandard((*ts->prestep),(ts));
2685   }
2686   PetscFunctionReturn(0);
2687 }
2688 
2689 #undef __FUNCT__
2690 #define __FUNCT__ "TSSetPreStage"
2691 /*@C
2692   TSSetPreStage - Sets the general-purpose function
2693   called once at the beginning of each stage.
2694 
2695   Logically Collective on TS
2696 
2697   Input Parameters:
2698 + ts   - The TS context obtained from TSCreate()
2699 - func - The function
2700 
2701   Calling sequence of func:
2702 . PetscErrorCode func(TS ts, PetscReal stagetime);
2703 
2704   Level: intermediate
2705 
2706   Note:
2707   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
2708   The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being
2709   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
2710 
2711 .keywords: TS, timestep
2712 .seealso: TSSetPostStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
2713 @*/
2714 PetscErrorCode  TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal))
2715 {
2716   PetscFunctionBegin;
2717   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2718   ts->prestage = func;
2719   PetscFunctionReturn(0);
2720 }
2721 
2722 #undef __FUNCT__
2723 #define __FUNCT__ "TSSetPostStage"
2724 /*@C
2725   TSSetPostStage - Sets the general-purpose function
2726   called once at the end of each stage.
2727 
2728   Logically Collective on TS
2729 
2730   Input Parameters:
2731 + ts   - The TS context obtained from TSCreate()
2732 - func - The function
2733 
2734   Calling sequence of func:
2735 . PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y);
2736 
2737   Level: intermediate
2738 
2739   Note:
2740   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
2741   The time step number being computed can be queried using TSGetTimeStepNumber() and the total size of the step being
2742   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
2743 
2744 .keywords: TS, timestep
2745 .seealso: TSSetPreStage(), TSSetPreStep(), TSSetPostStep(), TSGetApplicationContext()
2746 @*/
2747 PetscErrorCode  TSSetPostStage(TS ts, PetscErrorCode (*func)(TS,PetscReal,PetscInt,Vec*))
2748 {
2749   PetscFunctionBegin;
2750   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2751   ts->poststage = func;
2752   PetscFunctionReturn(0);
2753 }
2754 
2755 #undef __FUNCT__
2756 #define __FUNCT__ "TSPreStage"
2757 /*@
2758   TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage()
2759 
2760   Collective on TS
2761 
2762   Input Parameters:
2763 . ts          - The TS context obtained from TSCreate()
2764   stagetime   - The absolute time of the current stage
2765 
2766   Notes:
2767   TSPreStage() is typically used within time stepping implementations,
2768   most users would not generally call this routine themselves.
2769 
2770   Level: developer
2771 
2772 .keywords: TS, timestep
2773 .seealso: TSPostStage(), TSSetPreStep(), TSPreStep(), TSPostStep()
2774 @*/
2775 PetscErrorCode  TSPreStage(TS ts, PetscReal stagetime)
2776 {
2777   PetscErrorCode ierr;
2778 
2779   PetscFunctionBegin;
2780   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2781   if (ts->prestage) {
2782     PetscStackCallStandard((*ts->prestage),(ts,stagetime));
2783   }
2784   PetscFunctionReturn(0);
2785 }
2786 
2787 #undef __FUNCT__
2788 #define __FUNCT__ "TSPostStage"
2789 /*@
2790   TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage()
2791 
2792   Collective on TS
2793 
2794   Input Parameters:
2795 . ts          - The TS context obtained from TSCreate()
2796   stagetime   - The absolute time of the current stage
2797   stageindex  - Stage number
2798   Y           - Array of vectors (of size = total number
2799                 of stages) with the stage solutions
2800 
2801   Notes:
2802   TSPostStage() is typically used within time stepping implementations,
2803   most users would not generally call this routine themselves.
2804 
2805   Level: developer
2806 
2807 .keywords: TS, timestep
2808 .seealso: TSPreStage(), TSSetPreStep(), TSPreStep(), TSPostStep()
2809 @*/
2810 PetscErrorCode  TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y)
2811 {
2812   PetscErrorCode ierr;
2813 
2814   PetscFunctionBegin;
2815   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2816   if (ts->poststage) {
2817     PetscStackCallStandard((*ts->poststage),(ts,stagetime,stageindex,Y));
2818   }
2819   PetscFunctionReturn(0);
2820 }
2821 
2822 #undef __FUNCT__
2823 #define __FUNCT__ "TSSetPostStep"
2824 /*@C
2825   TSSetPostStep - Sets the general-purpose function
2826   called once at the end of each time step.
2827 
2828   Logically Collective on TS
2829 
2830   Input Parameters:
2831 + ts   - The TS context obtained from TSCreate()
2832 - func - The function
2833 
2834   Calling sequence of func:
2835 $ func (TS ts);
2836 
2837   Level: intermediate
2838 
2839 .keywords: TS, timestep
2840 .seealso: TSSetPreStep(), TSSetPreStage(), TSGetTimeStep(), TSGetTimeStepNumber(), TSGetTime()
2841 @*/
2842 PetscErrorCode  TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
2843 {
2844   PetscFunctionBegin;
2845   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2846   ts->poststep = func;
2847   PetscFunctionReturn(0);
2848 }
2849 
2850 #undef __FUNCT__
2851 #define __FUNCT__ "TSPostStep"
2852 /*@
2853   TSPostStep - Runs the user-defined post-step function.
2854 
2855   Collective on TS
2856 
2857   Input Parameters:
2858 . ts   - The TS context obtained from TSCreate()
2859 
2860   Notes:
2861   TSPostStep() is typically used within time stepping implementations,
2862   so most users would not generally call this routine themselves.
2863 
2864   Level: developer
2865 
2866 .keywords: TS, timestep
2867 @*/
2868 PetscErrorCode  TSPostStep(TS ts)
2869 {
2870   PetscErrorCode ierr;
2871 
2872   PetscFunctionBegin;
2873   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2874   if (ts->poststep) {
2875     PetscStackCallStandard((*ts->poststep),(ts));
2876   }
2877   PetscFunctionReturn(0);
2878 }
2879 
2880 /* ------------ Routines to set performance monitoring options ----------- */
2881 
2882 #undef __FUNCT__
2883 #define __FUNCT__ "TSMonitorSet"
2884 /*@C
2885    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
2886    timestep to display the iteration's  progress.
2887 
2888    Logically Collective on TS
2889 
2890    Input Parameters:
2891 +  ts - the TS context obtained from TSCreate()
2892 .  monitor - monitoring routine
2893 .  mctx - [optional] user-defined context for private data for the
2894              monitor routine (use NULL if no context is desired)
2895 -  monitordestroy - [optional] routine that frees monitor context
2896           (may be NULL)
2897 
2898    Calling sequence of monitor:
2899 $    int monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)
2900 
2901 +    ts - the TS context
2902 .    steps - iteration number (after the final time step the monitor routine is called with a step of -1, this is at the final time which may have
2903                                been interpolated to)
2904 .    time - current time
2905 .    u - current iterate
2906 -    mctx - [optional] monitoring context
2907 
2908    Notes:
2909    This routine adds an additional monitor to the list of monitors that
2910    already has been loaded.
2911 
2912    Fortran notes: Only a single monitor function can be set for each TS object
2913 
2914    Level: intermediate
2915 
2916 .keywords: TS, timestep, set, monitor
2917 
2918 .seealso: TSMonitorDefault(), TSMonitorCancel()
2919 @*/
2920 PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**))
2921 {
2922   PetscFunctionBegin;
2923   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2924   if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2925   ts->monitor[ts->numbermonitors]          = monitor;
2926   ts->monitordestroy[ts->numbermonitors]   = mdestroy;
2927   ts->monitorcontext[ts->numbermonitors++] = (void*)mctx;
2928   PetscFunctionReturn(0);
2929 }
2930 
2931 #undef __FUNCT__
2932 #define __FUNCT__ "TSMonitorCancel"
2933 /*@C
2934    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.
2935 
2936    Logically Collective on TS
2937 
2938    Input Parameters:
2939 .  ts - the TS context obtained from TSCreate()
2940 
2941    Notes:
2942    There is no way to remove a single, specific monitor.
2943 
2944    Level: intermediate
2945 
2946 .keywords: TS, timestep, set, monitor
2947 
2948 .seealso: TSMonitorDefault(), TSMonitorSet()
2949 @*/
2950 PetscErrorCode  TSMonitorCancel(TS ts)
2951 {
2952   PetscErrorCode ierr;
2953   PetscInt       i;
2954 
2955   PetscFunctionBegin;
2956   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2957   for (i=0; i<ts->numbermonitors; i++) {
2958     if (ts->monitordestroy[i]) {
2959       ierr = (*ts->monitordestroy[i])(&ts->monitorcontext[i]);CHKERRQ(ierr);
2960     }
2961   }
2962   ts->numbermonitors = 0;
2963   PetscFunctionReturn(0);
2964 }
2965 
2966 #undef __FUNCT__
2967 #define __FUNCT__ "TSMonitorDefault"
2968 /*@
2969    TSMonitorDefault - Sets the Default monitor
2970 
2971    Level: intermediate
2972 
2973 .keywords: TS, set, monitor
2974 
2975 .seealso: TSMonitorDefault(), TSMonitorSet()
2976 @*/
2977 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,void *dummy)
2978 {
2979   PetscErrorCode ierr;
2980   PetscViewer    viewer =  (PetscViewer) dummy;
2981 
2982   PetscFunctionBegin;
2983   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
2984   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
2985   ierr = PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");CHKERRQ(ierr);
2986   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);CHKERRQ(ierr);
2987   PetscFunctionReturn(0);
2988 }
2989 
2990 #undef __FUNCT__
2991 #define __FUNCT__ "TSSetRetainStages"
2992 /*@
2993    TSSetRetainStages - Request that all stages in the upcoming step be stored so that interpolation will be available.
2994 
2995    Logically Collective on TS
2996 
2997    Input Argument:
2998 .  ts - time stepping context
2999 
3000    Output Argument:
3001 .  flg - PETSC_TRUE or PETSC_FALSE
3002 
3003    Level: intermediate
3004 
3005 .keywords: TS, set
3006 
3007 .seealso: TSInterpolate(), TSSetPostStep()
3008 @*/
3009 PetscErrorCode TSSetRetainStages(TS ts,PetscBool flg)
3010 {
3011   PetscFunctionBegin;
3012   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3013   ts->retain_stages = flg;
3014   PetscFunctionReturn(0);
3015 }
3016 
3017 #undef __FUNCT__
3018 #define __FUNCT__ "TSInterpolate"
3019 /*@
3020    TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval
3021 
3022    Collective on TS
3023 
3024    Input Argument:
3025 +  ts - time stepping context
3026 -  t - time to interpolate to
3027 
3028    Output Argument:
3029 .  U - state at given time
3030 
3031    Notes:
3032    The user should call TSSetRetainStages() before taking a step in which interpolation will be requested.
3033 
3034    Level: intermediate
3035 
3036    Developer Notes:
3037    TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints.
3038 
3039 .keywords: TS, set
3040 
3041 .seealso: TSSetRetainStages(), TSSetPostStep()
3042 @*/
3043 PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U)
3044 {
3045   PetscErrorCode ierr;
3046 
3047   PetscFunctionBegin;
3048   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3049   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
3050   if (t < ts->ptime - ts->time_step_prev || t > ts->ptime) SETERRQ3(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Requested time %g not in last time steps [%g,%g]",t,(double)(ts->ptime-ts->time_step_prev),(double)ts->ptime);
3051   if (!ts->ops->interpolate) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name);
3052   ierr = (*ts->ops->interpolate)(ts,t,U);CHKERRQ(ierr);
3053   PetscFunctionReturn(0);
3054 }
3055 
3056 #undef __FUNCT__
3057 #define __FUNCT__ "TSStep"
3058 /*@
3059    TSStep - Steps one time step
3060 
3061    Collective on TS
3062 
3063    Input Parameter:
3064 .  ts - the TS context obtained from TSCreate()
3065 
3066    Level: developer
3067 
3068    Notes:
3069    The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine.
3070 
3071    The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may
3072    be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages.
3073 
3074    This may over-step the final time provided in TSSetDuration() depending on the time-step used. TSSolve() interpolates to exactly the
3075    time provided in TSSetDuration(). One can use TSInterpolate() to determine an interpolated solution within the final timestep.
3076 
3077 .keywords: TS, timestep, solve
3078 
3079 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSSetPostStage(), TSInterpolate()
3080 @*/
3081 PetscErrorCode  TSStep(TS ts)
3082 {
3083   DM               dm;
3084   PetscErrorCode   ierr;
3085   static PetscBool cite = PETSC_FALSE;
3086 
3087   PetscFunctionBegin;
3088   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3089   ierr = PetscCitationsRegister("@techreport{tspaper,\n"
3090                                 "  title       = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n"
3091                                 "  author      = {Shrirang Abhyankar and Jed Brown and Emil Constantinescu and Debojyoti Ghosh and Barry F. Smith},\n"
3092                                 "  type        = {Preprint},\n"
3093                                 "  number      = {ANL/MCS-P5061-0114},\n"
3094                                 "  institution = {Argonne National Laboratory},\n"
3095                                 "  year        = {2014}\n}\n",&cite);CHKERRQ(ierr);
3096 
3097   ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
3098   ierr = TSSetUp(ts);CHKERRQ(ierr);
3099   ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr);
3100 
3101   ts->reason = TS_CONVERGED_ITERATING;
3102   ts->ptime_prev = ts->ptime;
3103   ierr = DMSetOutputSequenceNumber(dm, ts->steps, ts->ptime);CHKERRQ(ierr);
3104 
3105   if (!ts->ops->step) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name);
3106   ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr);
3107   ierr = (*ts->ops->step)(ts);CHKERRQ(ierr);
3108   ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr);
3109 
3110   ts->time_step_prev = ts->ptime - ts->ptime_prev;
3111   ierr = DMSetOutputSequenceNumber(dm, ts->steps, ts->ptime);CHKERRQ(ierr);
3112 
3113   if (ts->reason < 0) {
3114     if (ts->errorifstepfailed) {
3115       if (ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s, increase -ts_max_snes_failures or make negative to attempt recovery",TSConvergedReasons[ts->reason]);
3116       else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]);
3117     }
3118   } else if (!ts->reason) {
3119     if (ts->steps >= ts->max_steps)     ts->reason = TS_CONVERGED_ITS;
3120     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
3121   }
3122   ts->total_steps++;
3123   ts->steprollback = PETSC_FALSE;
3124   PetscFunctionReturn(0);
3125 }
3126 
3127 #undef __FUNCT__
3128 #define __FUNCT__ "TSAdjointStep"
3129 /*@
3130    TSAdjointStep - Steps one time step backward in the adjoint run
3131 
3132    Collective on TS
3133 
3134    Input Parameter:
3135 .  ts - the TS context obtained from TSCreate()
3136 
3137    Level: intermediate
3138 
3139 .keywords: TS, adjoint, step
3140 
3141 .seealso: TSAdjointSetUp(), TSAdjointSolve()
3142 @*/
3143 PetscErrorCode  TSAdjointStep(TS ts)
3144 {
3145   DM               dm;
3146   PetscErrorCode   ierr;
3147 
3148   PetscFunctionBegin;
3149   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3150   ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
3151   ierr = TSAdjointSetUp(ts);CHKERRQ(ierr);
3152 
3153   ts->reason = TS_CONVERGED_ITERATING;
3154   ts->ptime_prev = ts->ptime;
3155   ierr = DMSetOutputSequenceNumber(dm, ts->steps, ts->ptime);CHKERRQ(ierr);
3156   ierr = VecViewFromOptions(ts->vec_sol,(PetscObject)ts, "-ts_view_solution");CHKERRQ(ierr);
3157 
3158   ierr = PetscLogEventBegin(TS_Step,ts,0,0,0);CHKERRQ(ierr);
3159   if (!ts->ops->adjointstep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed because the adjoint of  %s has not been implemented, try other time stepping methods for adjoint sensitivity analysis",((PetscObject)ts)->type_name);
3160   ierr = (*ts->ops->adjointstep)(ts);CHKERRQ(ierr);
3161   ierr = PetscLogEventEnd(TS_Step,ts,0,0,0);CHKERRQ(ierr);
3162 
3163   ts->time_step_prev = ts->ptime - ts->ptime_prev;
3164   ierr = DMSetOutputSequenceNumber(dm, ts->steps, ts->ptime);CHKERRQ(ierr);
3165 
3166   if (ts->reason < 0) {
3167     if (ts->errorifstepfailed) {
3168       if (ts->reason == TS_DIVERGED_NONLINEAR_SOLVE) {
3169         SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s, increase -ts_max_snes_failures or make negative to attempt recovery",TSConvergedReasons[ts->reason]);
3170       } else if (ts->reason == TS_DIVERGED_STEP_REJECTED) {
3171         SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s, increase -ts_max_reject or make negative to attempt recovery",TSConvergedReasons[ts->reason]);
3172       } else SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]);
3173     }
3174   } else if (!ts->reason) {
3175     if (ts->steps >= ts->adjoint_max_steps)     ts->reason = TS_CONVERGED_ITS;
3176     else if (ts->ptime >= ts->max_time)         ts->reason = TS_CONVERGED_TIME;
3177   }
3178   ts->total_steps--;
3179   PetscFunctionReturn(0);
3180 }
3181 
3182 #undef __FUNCT__
3183 #define __FUNCT__ "TSEvaluateStep"
3184 /*@
3185    TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy.
3186 
3187    Collective on TS
3188 
3189    Input Arguments:
3190 +  ts - time stepping context
3191 .  order - desired order of accuracy
3192 -  done - whether the step was evaluated at this order (pass NULL to generate an error if not available)
3193 
3194    Output Arguments:
3195 .  U - state at the end of the current step
3196 
3197    Level: advanced
3198 
3199    Notes:
3200    This function cannot be called until all stages have been evaluated.
3201    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.
3202 
3203 .seealso: TSStep(), TSAdapt
3204 @*/
3205 PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done)
3206 {
3207   PetscErrorCode ierr;
3208 
3209   PetscFunctionBegin;
3210   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3211   PetscValidType(ts,1);
3212   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
3213   if (!ts->ops->evaluatestep) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name);
3214   ierr = (*ts->ops->evaluatestep)(ts,order,U,done);CHKERRQ(ierr);
3215   PetscFunctionReturn(0);
3216 }
3217 
3218 
3219 #undef __FUNCT__
3220 #define __FUNCT__ "TSSolve"
3221 /*@
3222    TSSolve - Steps the requested number of timesteps.
3223 
3224    Collective on TS
3225 
3226    Input Parameter:
3227 +  ts - the TS context obtained from TSCreate()
3228 -  u - the solution vector  (can be null if TSSetSolution() was used, otherwise must contain the initial conditions)
3229 
3230    Level: beginner
3231 
3232    Notes:
3233    The final time returned by this function may be different from the time of the internally
3234    held state accessible by TSGetSolution() and TSGetTime() because the method may have
3235    stepped over the final time.
3236 
3237 .keywords: TS, timestep, solve
3238 
3239 .seealso: TSCreate(), TSSetSolution(), TSStep()
3240 @*/
3241 PetscErrorCode TSSolve(TS ts,Vec u)
3242 {
3243   Vec               solution;
3244   PetscErrorCode    ierr;
3245 
3246   PetscFunctionBegin;
3247   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3248   if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2);
3249   if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE) {   /* Need ts->vec_sol to be distinct so it is not overwritten when we interpolate at the end */
3250     PetscValidHeaderSpecific(u,VEC_CLASSID,2);
3251     if (!ts->vec_sol || u == ts->vec_sol) {
3252       ierr = VecDuplicate(u,&solution);CHKERRQ(ierr);
3253       ierr = TSSetSolution(ts,solution);CHKERRQ(ierr);
3254       ierr = VecDestroy(&solution);CHKERRQ(ierr); /* grant ownership */
3255     }
3256     ierr = VecCopy(u,ts->vec_sol);CHKERRQ(ierr);
3257   } else if (u) {
3258     ierr = TSSetSolution(ts,u);CHKERRQ(ierr);
3259   }
3260   ierr = TSSetUp(ts);CHKERRQ(ierr);
3261   ierr = TSTrajectorySetUp(ts->trajectory,ts);CHKERRQ(ierr);
3262   /* reset time step and iteration counters */
3263   ts->steps             = 0;
3264   ts->ksp_its           = 0;
3265   ts->snes_its          = 0;
3266   ts->num_snes_failures = 0;
3267   ts->reject            = 0;
3268   ts->reason            = TS_CONVERGED_ITERATING;
3269 
3270   ierr = TSViewFromOptions(ts,NULL,"-ts_view_pre");CHKERRQ(ierr);
3271   {
3272     DM dm;
3273     ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
3274     ierr = DMSetOutputSequenceNumber(dm, ts->steps, ts->ptime);CHKERRQ(ierr);
3275   }
3276 
3277   if (ts->ops->solve) {         /* This private interface is transitional and should be removed when all implementations are updated. */
3278     ierr = (*ts->ops->solve)(ts);CHKERRQ(ierr);
3279     ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);
3280     ts->solvetime = ts->ptime;
3281   } else {
3282     /* steps the requested number of timesteps. */
3283     if (ts->steps >= ts->max_steps)     ts->reason = TS_CONVERGED_ITS;
3284     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
3285     ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
3286     if (ts->vec_costintegral) ts->costintegralfwd=PETSC_TRUE;
3287     if(ts->event) {
3288       ierr = TSEventMonitorInitialize(ts);CHKERRQ(ierr);
3289     }
3290     while (!ts->reason) {
3291       ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
3292       ierr = TSStep(ts);CHKERRQ(ierr);
3293       if (ts->event) {
3294 	ierr = TSEventMonitor(ts);CHKERRQ(ierr);
3295       }
3296       if(!ts->steprollback) {
3297 	ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
3298 	ierr = TSPostStep(ts);CHKERRQ(ierr);
3299       }
3300     }
3301     if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) {
3302       ierr = TSInterpolate(ts,ts->max_time,u);CHKERRQ(ierr);
3303       ts->solvetime = ts->max_time;
3304       solution = u;
3305     } else {
3306       if (u) {ierr = VecCopy(ts->vec_sol,u);CHKERRQ(ierr);}
3307       ts->solvetime = ts->ptime;
3308       solution = ts->vec_sol;
3309     }
3310     ierr = TSMonitor(ts,ts->steps,ts->solvetime,solution);CHKERRQ(ierr);
3311     ierr = VecViewFromOptions(solution,(PetscObject) ts,"-ts_view_solution");CHKERRQ(ierr);
3312   }
3313 
3314   ierr = TSViewFromOptions(ts,NULL,"-ts_view");CHKERRQ(ierr);
3315   ierr = VecViewFromOptions(ts->vec_sol,NULL,"-ts_view_solution");CHKERRQ(ierr);
3316   ierr = PetscObjectSAWsBlock((PetscObject)ts);CHKERRQ(ierr);
3317   if (ts->adjoint_solve) {
3318     ierr = TSAdjointSolve(ts);CHKERRQ(ierr);
3319   }
3320   PetscFunctionReturn(0);
3321 }
3322 
3323 #undef __FUNCT__
3324 #define __FUNCT__ "TSAdjointSolve"
3325 /*@
3326    TSAdjointSolve - Solves the discrete ajoint problem for an ODE/DAE
3327 
3328    Collective on TS
3329 
3330    Input Parameter:
3331 .  ts - the TS context obtained from TSCreate()
3332 
3333    Options Database:
3334 . -ts_adjoint_view_solution <viewerinfo> - views the first gradient with respect to the initial conditions
3335 
3336    Level: intermediate
3337 
3338    Notes:
3339    This must be called after a call to TSSolve() that solves the forward problem
3340 
3341    By default this will integrate back to the initial time, one can use TSAdjointSetSteps() to step back to a later time
3342 
3343 .keywords: TS, timestep, solve
3344 
3345 .seealso: TSCreate(), TSSetCostGradients(), TSSetSolution(), TSAdjointStep()
3346 @*/
3347 PetscErrorCode TSAdjointSolve(TS ts)
3348 {
3349   PetscErrorCode    ierr;
3350 
3351   PetscFunctionBegin;
3352   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3353   ierr = TSAdjointSetUp(ts);CHKERRQ(ierr);
3354 
3355   /* reset time step and iteration counters */
3356   ts->steps             = 0;
3357   ts->ksp_its           = 0;
3358   ts->snes_its          = 0;
3359   ts->num_snes_failures = 0;
3360   ts->reject            = 0;
3361   ts->reason            = TS_CONVERGED_ITERATING;
3362 
3363   if (!ts->adjoint_max_steps) ts->adjoint_max_steps = ts->total_steps;
3364 
3365   if (ts->steps >= ts->adjoint_max_steps)     ts->reason = TS_CONVERGED_ITS;
3366   while (!ts->reason) {
3367     ierr = TSTrajectoryGet(ts->trajectory,ts,ts->total_steps,&ts->ptime);CHKERRQ(ierr);
3368     ierr = TSMonitor(ts,ts->total_steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
3369     if (ts->event) {
3370       ierr = TSAdjointEventMonitor(ts);CHKERRQ(ierr);
3371     }
3372     ierr = TSAdjointStep(ts);CHKERRQ(ierr);
3373   }
3374   ts->solvetime = ts->ptime;
3375   ierr = VecViewFromOptions(ts->vecs_sensi[0],(PetscObject) ts, "-ts_adjoint_view_solution");CHKERRQ(ierr);
3376   PetscFunctionReturn(0);
3377 }
3378 
3379 #undef __FUNCT__
3380 #define __FUNCT__ "TSMonitor"
3381 /*@
3382    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()
3383 
3384    Collective on TS
3385 
3386    Input Parameters:
3387 +  ts - time stepping context obtained from TSCreate()
3388 .  step - step number that has just completed
3389 .  ptime - model time of the state
3390 -  u - state at the current model time
3391 
3392    Notes:
3393    TSMonitor() is typically used within the time stepping implementations.
3394    Users might call this function when using the TSStep() interface instead of TSSolve().
3395 
3396    Level: advanced
3397 
3398 .keywords: TS, timestep
3399 @*/
3400 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u)
3401 {
3402   PetscErrorCode ierr;
3403   PetscInt       i,n = ts->numbermonitors;
3404 
3405   PetscFunctionBegin;
3406   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3407   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
3408   ierr = VecLockPush(u);CHKERRQ(ierr);
3409   for (i=0; i<n; i++) {
3410     ierr = (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);CHKERRQ(ierr);
3411   }
3412   ierr = VecLockPop(u);CHKERRQ(ierr);
3413   PetscFunctionReturn(0);
3414 }
3415 
3416 /* ------------------------------------------------------------------------*/
3417 #undef __FUNCT__
3418 #define __FUNCT__ "TSMonitorLGCtxCreate"
3419 /*@C
3420    TSMonitorLGCtxCreate - Creates a line graph context for use with
3421    TS to monitor the solution process graphically in various ways
3422 
3423    Collective on TS
3424 
3425    Input Parameters:
3426 +  host - the X display to open, or null for the local machine
3427 .  label - the title to put in the title bar
3428 .  x, y - the screen coordinates of the upper left coordinate of the window
3429 .  m, n - the screen width and height in pixels
3430 -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time
3431 
3432    Output Parameter:
3433 .  ctx - the context
3434 
3435    Options Database Key:
3436 +  -ts_monitor_lg_timestep - automatically sets line graph monitor
3437 .  -ts_monitor_lg_solution -
3438 .  -ts_monitor_lg_error -
3439 .  -ts_monitor_lg_ksp_iterations -
3440 .  -ts_monitor_lg_snes_iterations -
3441 -  -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true
3442 
3443    Notes:
3444    Use TSMonitorLGCtxDestroy() to destroy.
3445 
3446    Level: intermediate
3447 
3448 .keywords: TS, monitor, line graph, residual, seealso
3449 
3450 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError()
3451 
3452 @*/
3453 PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
3454 {
3455   PetscDraw      win;
3456   PetscErrorCode ierr;
3457 
3458   PetscFunctionBegin;
3459   ierr = PetscNew(ctx);CHKERRQ(ierr);
3460   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&win);CHKERRQ(ierr);
3461   ierr = PetscDrawSetFromOptions(win);CHKERRQ(ierr);
3462   ierr = PetscDrawLGCreate(win,1,&(*ctx)->lg);CHKERRQ(ierr);
3463   ierr = PetscLogObjectParent((PetscObject)(*ctx)->lg,(PetscObject)win);CHKERRQ(ierr);
3464   ierr = PetscDrawLGSetUseMarkers((*ctx)->lg,PETSC_TRUE);CHKERRQ(ierr);
3465   ierr = PetscDrawLGSetFromOptions((*ctx)->lg);CHKERRQ(ierr);
3466   (*ctx)->howoften = howoften;
3467   PetscFunctionReturn(0);
3468 }
3469 
3470 #undef __FUNCT__
3471 #define __FUNCT__ "TSMonitorLGTimeStep"
3472 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx)
3473 {
3474   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
3475   PetscReal      x   = ptime,y;
3476   PetscErrorCode ierr;
3477 
3478   PetscFunctionBegin;
3479   if (!step) {
3480     PetscDrawAxis axis;
3481     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
3482     ierr = PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time","Time step");CHKERRQ(ierr);
3483     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
3484   }
3485   ierr = TSGetTimeStep(ts,&y);CHKERRQ(ierr);
3486   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
3487   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
3488     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
3489   }
3490   PetscFunctionReturn(0);
3491 }
3492 
3493 #undef __FUNCT__
3494 #define __FUNCT__ "TSMonitorLGCtxDestroy"
3495 /*@C
3496    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
3497    with TSMonitorLGCtxCreate().
3498 
3499    Collective on TSMonitorLGCtx
3500 
3501    Input Parameter:
3502 .  ctx - the monitor context
3503 
3504    Level: intermediate
3505 
3506 .keywords: TS, monitor, line graph, destroy
3507 
3508 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep();
3509 @*/
3510 PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
3511 {
3512   PetscDraw      draw;
3513   PetscErrorCode ierr;
3514 
3515   PetscFunctionBegin;
3516   if ((*ctx)->transformdestroy) {
3517     ierr = ((*ctx)->transformdestroy)((*ctx)->transformctx);CHKERRQ(ierr);
3518   }
3519   ierr = PetscDrawLGGetDraw((*ctx)->lg,&draw);CHKERRQ(ierr);
3520   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
3521   ierr = PetscDrawLGDestroy(&(*ctx)->lg);CHKERRQ(ierr);
3522   ierr = PetscStrArrayDestroy(&(*ctx)->names);CHKERRQ(ierr);
3523   ierr = PetscStrArrayDestroy(&(*ctx)->displaynames);CHKERRQ(ierr);
3524   ierr = PetscFree((*ctx)->displayvariables);CHKERRQ(ierr);
3525   ierr = PetscFree((*ctx)->displayvalues);CHKERRQ(ierr);
3526   ierr = PetscFree(*ctx);CHKERRQ(ierr);
3527   PetscFunctionReturn(0);
3528 }
3529 
3530 #undef __FUNCT__
3531 #define __FUNCT__ "TSGetTime"
3532 /*@
3533    TSGetTime - Gets the time of the most recently completed step.
3534 
3535    Not Collective
3536 
3537    Input Parameter:
3538 .  ts - the TS context obtained from TSCreate()
3539 
3540    Output Parameter:
3541 .  t  - the current time
3542 
3543    Level: beginner
3544 
3545    Note:
3546    When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(),
3547    TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated.
3548 
3549 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
3550 
3551 .keywords: TS, get, time
3552 @*/
3553 PetscErrorCode  TSGetTime(TS ts,PetscReal *t)
3554 {
3555   PetscFunctionBegin;
3556   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3557   PetscValidRealPointer(t,2);
3558   *t = ts->ptime;
3559   PetscFunctionReturn(0);
3560 }
3561 
3562 #undef __FUNCT__
3563 #define __FUNCT__ "TSGetPrevTime"
3564 /*@
3565    TSGetPrevTime - Gets the starting time of the previously completed step.
3566 
3567    Not Collective
3568 
3569    Input Parameter:
3570 .  ts - the TS context obtained from TSCreate()
3571 
3572    Output Parameter:
3573 .  t  - the previous time
3574 
3575    Level: beginner
3576 
3577 .seealso: TSSetInitialTimeStep(), TSGetTimeStep()
3578 
3579 .keywords: TS, get, time
3580 @*/
3581 PetscErrorCode  TSGetPrevTime(TS ts,PetscReal *t)
3582 {
3583   PetscFunctionBegin;
3584   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3585   PetscValidRealPointer(t,2);
3586   *t = ts->ptime_prev;
3587   PetscFunctionReturn(0);
3588 }
3589 
3590 #undef __FUNCT__
3591 #define __FUNCT__ "TSSetTime"
3592 /*@
3593    TSSetTime - Allows one to reset the time.
3594 
3595    Logically Collective on TS
3596 
3597    Input Parameters:
3598 +  ts - the TS context obtained from TSCreate()
3599 -  time - the time
3600 
3601    Level: intermediate
3602 
3603 .seealso: TSGetTime(), TSSetDuration()
3604 
3605 .keywords: TS, set, time
3606 @*/
3607 PetscErrorCode  TSSetTime(TS ts, PetscReal t)
3608 {
3609   PetscFunctionBegin;
3610   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3611   PetscValidLogicalCollectiveReal(ts,t,2);
3612   ts->ptime = t;
3613   PetscFunctionReturn(0);
3614 }
3615 
3616 #undef __FUNCT__
3617 #define __FUNCT__ "TSSetOptionsPrefix"
3618 /*@C
3619    TSSetOptionsPrefix - Sets the prefix used for searching for all
3620    TS options in the database.
3621 
3622    Logically Collective on TS
3623 
3624    Input Parameter:
3625 +  ts     - The TS context
3626 -  prefix - The prefix to prepend to all option names
3627 
3628    Notes:
3629    A hyphen (-) must NOT be given at the beginning of the prefix name.
3630    The first character of all runtime options is AUTOMATICALLY the
3631    hyphen.
3632 
3633    Level: advanced
3634 
3635 .keywords: TS, set, options, prefix, database
3636 
3637 .seealso: TSSetFromOptions()
3638 
3639 @*/
3640 PetscErrorCode  TSSetOptionsPrefix(TS ts,const char prefix[])
3641 {
3642   PetscErrorCode ierr;
3643   SNES           snes;
3644 
3645   PetscFunctionBegin;
3646   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3647   ierr = PetscObjectSetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
3648   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3649   ierr = SNESSetOptionsPrefix(snes,prefix);CHKERRQ(ierr);
3650   PetscFunctionReturn(0);
3651 }
3652 
3653 
3654 #undef __FUNCT__
3655 #define __FUNCT__ "TSAppendOptionsPrefix"
3656 /*@C
3657    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
3658    TS options in the database.
3659 
3660    Logically Collective on TS
3661 
3662    Input Parameter:
3663 +  ts     - The TS context
3664 -  prefix - The prefix to prepend to all option names
3665 
3666    Notes:
3667    A hyphen (-) must NOT be given at the beginning of the prefix name.
3668    The first character of all runtime options is AUTOMATICALLY the
3669    hyphen.
3670 
3671    Level: advanced
3672 
3673 .keywords: TS, append, options, prefix, database
3674 
3675 .seealso: TSGetOptionsPrefix()
3676 
3677 @*/
3678 PetscErrorCode  TSAppendOptionsPrefix(TS ts,const char prefix[])
3679 {
3680   PetscErrorCode ierr;
3681   SNES           snes;
3682 
3683   PetscFunctionBegin;
3684   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3685   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
3686   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3687   ierr = SNESAppendOptionsPrefix(snes,prefix);CHKERRQ(ierr);
3688   PetscFunctionReturn(0);
3689 }
3690 
3691 #undef __FUNCT__
3692 #define __FUNCT__ "TSGetOptionsPrefix"
3693 /*@C
3694    TSGetOptionsPrefix - Sets the prefix used for searching for all
3695    TS options in the database.
3696 
3697    Not Collective
3698 
3699    Input Parameter:
3700 .  ts - The TS context
3701 
3702    Output Parameter:
3703 .  prefix - A pointer to the prefix string used
3704 
3705    Notes: On the fortran side, the user should pass in a string 'prifix' of
3706    sufficient length to hold the prefix.
3707 
3708    Level: intermediate
3709 
3710 .keywords: TS, get, options, prefix, database
3711 
3712 .seealso: TSAppendOptionsPrefix()
3713 @*/
3714 PetscErrorCode  TSGetOptionsPrefix(TS ts,const char *prefix[])
3715 {
3716   PetscErrorCode ierr;
3717 
3718   PetscFunctionBegin;
3719   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3720   PetscValidPointer(prefix,2);
3721   ierr = PetscObjectGetOptionsPrefix((PetscObject)ts,prefix);CHKERRQ(ierr);
3722   PetscFunctionReturn(0);
3723 }
3724 
3725 #undef __FUNCT__
3726 #define __FUNCT__ "TSGetRHSJacobian"
3727 /*@C
3728    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
3729 
3730    Not Collective, but parallel objects are returned if TS is parallel
3731 
3732    Input Parameter:
3733 .  ts  - The TS context obtained from TSCreate()
3734 
3735    Output Parameters:
3736 +  Amat - The (approximate) Jacobian J of G, where U_t = G(U,t)  (or NULL)
3737 .  Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat  (or NULL)
3738 .  func - Function to compute the Jacobian of the RHS  (or NULL)
3739 -  ctx - User-defined context for Jacobian evaluation routine  (or NULL)
3740 
3741    Notes: You can pass in NULL for any return argument you do not need.
3742 
3743    Level: intermediate
3744 
3745 .seealso: TSGetTimeStep(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
3746 
3747 .keywords: TS, timestep, get, matrix, Jacobian
3748 @*/
3749 PetscErrorCode  TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx)
3750 {
3751   PetscErrorCode ierr;
3752   SNES           snes;
3753   DM             dm;
3754 
3755   PetscFunctionBegin;
3756   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3757   ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
3758   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
3759   ierr = DMTSGetRHSJacobian(dm,func,ctx);CHKERRQ(ierr);
3760   PetscFunctionReturn(0);
3761 }
3762 
3763 #undef __FUNCT__
3764 #define __FUNCT__ "TSGetIJacobian"
3765 /*@C
3766    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
3767 
3768    Not Collective, but parallel objects are returned if TS is parallel
3769 
3770    Input Parameter:
3771 .  ts  - The TS context obtained from TSCreate()
3772 
3773    Output Parameters:
3774 +  Amat  - The (approximate) Jacobian of F(t,U,U_t)
3775 .  Pmat - The matrix from which the preconditioner is constructed, often the same as Amat
3776 .  f   - The function to compute the matrices
3777 - ctx - User-defined context for Jacobian evaluation routine
3778 
3779    Notes: You can pass in NULL for any return argument you do not need.
3780 
3781    Level: advanced
3782 
3783 .seealso: TSGetTimeStep(), TSGetRHSJacobian(), TSGetMatrices(), TSGetTime(), TSGetTimeStepNumber()
3784 
3785 .keywords: TS, timestep, get, matrix, Jacobian
3786 @*/
3787 PetscErrorCode  TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx)
3788 {
3789   PetscErrorCode ierr;
3790   SNES           snes;
3791   DM             dm;
3792 
3793   PetscFunctionBegin;
3794   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
3795   ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
3796   ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
3797   ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
3798   ierr = DMTSGetIJacobian(dm,f,ctx);CHKERRQ(ierr);
3799   PetscFunctionReturn(0);
3800 }
3801 
3802 
3803 #undef __FUNCT__
3804 #define __FUNCT__ "TSMonitorDrawSolution"
3805 /*@C
3806    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
3807    VecView() for the solution at each timestep
3808 
3809    Collective on TS
3810 
3811    Input Parameters:
3812 +  ts - the TS context
3813 .  step - current time-step
3814 .  ptime - current time
3815 -  dummy - either a viewer or NULL
3816 
3817    Options Database:
3818 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
3819 
3820    Notes: the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
3821        will look bad
3822 
3823    Level: intermediate
3824 
3825 .keywords: TS,  vector, monitor, view
3826 
3827 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3828 @*/
3829 PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
3830 {
3831   PetscErrorCode   ierr;
3832   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
3833   PetscDraw        draw;
3834 
3835   PetscFunctionBegin;
3836   if (!step && ictx->showinitial) {
3837     if (!ictx->initialsolution) {
3838       ierr = VecDuplicate(u,&ictx->initialsolution);CHKERRQ(ierr);
3839     }
3840     ierr = VecCopy(u,ictx->initialsolution);CHKERRQ(ierr);
3841   }
3842   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
3843 
3844   if (ictx->showinitial) {
3845     PetscReal pause;
3846     ierr = PetscViewerDrawGetPause(ictx->viewer,&pause);CHKERRQ(ierr);
3847     ierr = PetscViewerDrawSetPause(ictx->viewer,0.0);CHKERRQ(ierr);
3848     ierr = VecView(ictx->initialsolution,ictx->viewer);CHKERRQ(ierr);
3849     ierr = PetscViewerDrawSetPause(ictx->viewer,pause);CHKERRQ(ierr);
3850     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);CHKERRQ(ierr);
3851   }
3852   ierr = VecView(u,ictx->viewer);CHKERRQ(ierr);
3853   if (ictx->showtimestepandtime) {
3854     PetscReal xl,yl,xr,yr,h;
3855     char      time[32];
3856 
3857     ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
3858     ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
3859     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
3860     h    = yl + .95*(yr - yl);
3861     ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
3862     ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
3863   }
3864 
3865   if (ictx->showinitial) {
3866     ierr = PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);CHKERRQ(ierr);
3867   }
3868   PetscFunctionReturn(0);
3869 }
3870 
3871 #undef __FUNCT__
3872 #define __FUNCT__ "TSMonitorDrawSolutionPhase"
3873 /*@C
3874    TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram
3875 
3876    Collective on TS
3877 
3878    Input Parameters:
3879 +  ts - the TS context
3880 .  step - current time-step
3881 .  ptime - current time
3882 -  dummy - either a viewer or NULL
3883 
3884    Level: intermediate
3885 
3886 .keywords: TS,  vector, monitor, view
3887 
3888 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
3889 @*/
3890 PetscErrorCode  TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
3891 {
3892   PetscErrorCode    ierr;
3893   TSMonitorDrawCtx  ictx = (TSMonitorDrawCtx)dummy;
3894   PetscDraw         draw;
3895   MPI_Comm          comm;
3896   PetscInt          n;
3897   PetscMPIInt       size;
3898   PetscReal         xl,yl,xr,yr,h;
3899   char              time[32];
3900   const PetscScalar *U;
3901 
3902   PetscFunctionBegin;
3903   ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr);
3904   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
3905   if (size != 1) SETERRQ(comm,PETSC_ERR_SUP,"Only allowed for sequential runs");
3906   ierr = VecGetSize(u,&n);CHKERRQ(ierr);
3907   if (n != 2) SETERRQ(comm,PETSC_ERR_SUP,"Only for ODEs with two unknowns");
3908 
3909   ierr = PetscViewerDrawGetDraw(ictx->viewer,0,&draw);CHKERRQ(ierr);
3910 
3911   ierr = VecGetArrayRead(u,&U);CHKERRQ(ierr);
3912   ierr = PetscDrawAxisGetLimits(ictx->axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr);
3913   if ((PetscRealPart(U[0]) < xl) || (PetscRealPart(U[1]) < yl) || (PetscRealPart(U[0]) > xr) || (PetscRealPart(U[1]) > yr)) {
3914       ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr);
3915       PetscFunctionReturn(0);
3916   }
3917   if (!step) ictx->color++;
3918   ierr = PetscDrawPoint(draw,PetscRealPart(U[0]),PetscRealPart(U[1]),ictx->color);CHKERRQ(ierr);
3919   ierr = VecRestoreArrayRead(u,&U);CHKERRQ(ierr);
3920 
3921   if (ictx->showtimestepandtime) {
3922     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
3923     ierr = PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);CHKERRQ(ierr);
3924     h    = yl + .95*(yr - yl);
3925     ierr = PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);CHKERRQ(ierr);
3926   }
3927   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
3928   PetscFunctionReturn(0);
3929 }
3930 
3931 
3932 #undef __FUNCT__
3933 #define __FUNCT__ "TSMonitorDrawCtxDestroy"
3934 /*@C
3935    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()
3936 
3937    Collective on TS
3938 
3939    Input Parameters:
3940 .    ctx - the monitor context
3941 
3942    Level: intermediate
3943 
3944 .keywords: TS,  vector, monitor, view
3945 
3946 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError()
3947 @*/
3948 PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
3949 {
3950   PetscErrorCode ierr;
3951 
3952   PetscFunctionBegin;
3953   ierr = PetscDrawAxisDestroy(&(*ictx)->axis);CHKERRQ(ierr);
3954   ierr = PetscViewerDestroy(&(*ictx)->viewer);CHKERRQ(ierr);
3955   ierr = VecDestroy(&(*ictx)->initialsolution);CHKERRQ(ierr);
3956   ierr = PetscFree(*ictx);CHKERRQ(ierr);
3957   PetscFunctionReturn(0);
3958 }
3959 
3960 #undef __FUNCT__
3961 #define __FUNCT__ "TSMonitorDrawCtxCreate"
3962 /*@C
3963    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx
3964 
3965    Collective on TS
3966 
3967    Input Parameter:
3968 .    ts - time-step context
3969 
3970    Output Patameter:
3971 .    ctx - the monitor context
3972 
3973    Options Database:
3974 .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution
3975 
3976    Level: intermediate
3977 
3978 .keywords: TS,  vector, monitor, view
3979 
3980 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx()
3981 @*/
3982 PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
3983 {
3984   PetscErrorCode   ierr;
3985 
3986   PetscFunctionBegin;
3987   ierr = PetscNew(ctx);CHKERRQ(ierr);
3988   ierr = PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);CHKERRQ(ierr);
3989   ierr = PetscViewerSetFromOptions((*ctx)->viewer);CHKERRQ(ierr);
3990 
3991   (*ctx)->howoften    = howoften;
3992   (*ctx)->showinitial = PETSC_FALSE;
3993   ierr = PetscOptionsGetBool(NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);CHKERRQ(ierr);
3994 
3995   (*ctx)->showtimestepandtime = PETSC_FALSE;
3996   ierr = PetscOptionsGetBool(NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);CHKERRQ(ierr);
3997   (*ctx)->color = PETSC_DRAW_WHITE;
3998   PetscFunctionReturn(0);
3999 }
4000 
4001 #undef __FUNCT__
4002 #define __FUNCT__ "TSMonitorDrawError"
4003 /*@C
4004    TSMonitorDrawError - Monitors progress of the TS solvers by calling
4005    VecView() for the error at each timestep
4006 
4007    Collective on TS
4008 
4009    Input Parameters:
4010 +  ts - the TS context
4011 .  step - current time-step
4012 .  ptime - current time
4013 -  dummy - either a viewer or NULL
4014 
4015    Level: intermediate
4016 
4017 .keywords: TS,  vector, monitor, view
4018 
4019 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4020 @*/
4021 PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
4022 {
4023   PetscErrorCode   ierr;
4024   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
4025   PetscViewer      viewer = ctx->viewer;
4026   Vec              work;
4027 
4028   PetscFunctionBegin;
4029   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0);
4030   ierr = VecDuplicate(u,&work);CHKERRQ(ierr);
4031   ierr = TSComputeSolutionFunction(ts,ptime,work);CHKERRQ(ierr);
4032   ierr = VecAXPY(work,-1.0,u);CHKERRQ(ierr);
4033   ierr = VecView(work,viewer);CHKERRQ(ierr);
4034   ierr = VecDestroy(&work);CHKERRQ(ierr);
4035   PetscFunctionReturn(0);
4036 }
4037 
4038 #include <petsc/private/dmimpl.h>
4039 #undef __FUNCT__
4040 #define __FUNCT__ "TSSetDM"
4041 /*@
4042    TSSetDM - Sets the DM that may be used by some preconditioners
4043 
4044    Logically Collective on TS and DM
4045 
4046    Input Parameters:
4047 +  ts - the preconditioner context
4048 -  dm - the dm
4049 
4050    Level: intermediate
4051 
4052 
4053 .seealso: TSGetDM(), SNESSetDM(), SNESGetDM()
4054 @*/
4055 PetscErrorCode  TSSetDM(TS ts,DM dm)
4056 {
4057   PetscErrorCode ierr;
4058   SNES           snes;
4059   DMTS           tsdm;
4060 
4061   PetscFunctionBegin;
4062   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4063   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
4064   if (ts->dm) {               /* Move the DMTS context over to the new DM unless the new DM already has one */
4065     if (ts->dm->dmts && !dm->dmts) {
4066       ierr = DMCopyDMTS(ts->dm,dm);CHKERRQ(ierr);
4067       ierr = DMGetDMTS(ts->dm,&tsdm);CHKERRQ(ierr);
4068       if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */
4069         tsdm->originaldm = dm;
4070       }
4071     }
4072     ierr = DMDestroy(&ts->dm);CHKERRQ(ierr);
4073   }
4074   ts->dm = dm;
4075 
4076   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
4077   ierr = SNESSetDM(snes,dm);CHKERRQ(ierr);
4078   PetscFunctionReturn(0);
4079 }
4080 
4081 #undef __FUNCT__
4082 #define __FUNCT__ "TSGetDM"
4083 /*@
4084    TSGetDM - Gets the DM that may be used by some preconditioners
4085 
4086    Not Collective
4087 
4088    Input Parameter:
4089 . ts - the preconditioner context
4090 
4091    Output Parameter:
4092 .  dm - the dm
4093 
4094    Level: intermediate
4095 
4096 
4097 .seealso: TSSetDM(), SNESSetDM(), SNESGetDM()
4098 @*/
4099 PetscErrorCode  TSGetDM(TS ts,DM *dm)
4100 {
4101   PetscErrorCode ierr;
4102 
4103   PetscFunctionBegin;
4104   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4105   if (!ts->dm) {
4106     ierr = DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm);CHKERRQ(ierr);
4107     if (ts->snes) {ierr = SNESSetDM(ts->snes,ts->dm);CHKERRQ(ierr);}
4108   }
4109   *dm = ts->dm;
4110   PetscFunctionReturn(0);
4111 }
4112 
4113 #undef __FUNCT__
4114 #define __FUNCT__ "SNESTSFormFunction"
4115 /*@
4116    SNESTSFormFunction - Function to evaluate nonlinear residual
4117 
4118    Logically Collective on SNES
4119 
4120    Input Parameter:
4121 + snes - nonlinear solver
4122 . U - the current state at which to evaluate the residual
4123 - ctx - user context, must be a TS
4124 
4125    Output Parameter:
4126 . F - the nonlinear residual
4127 
4128    Notes:
4129    This function is not normally called by users and is automatically registered with the SNES used by TS.
4130    It is most frequently passed to MatFDColoringSetFunction().
4131 
4132    Level: advanced
4133 
4134 .seealso: SNESSetFunction(), MatFDColoringSetFunction()
4135 @*/
4136 PetscErrorCode  SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx)
4137 {
4138   TS             ts = (TS)ctx;
4139   PetscErrorCode ierr;
4140 
4141   PetscFunctionBegin;
4142   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4143   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
4144   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
4145   PetscValidHeaderSpecific(ts,TS_CLASSID,4);
4146   ierr = (ts->ops->snesfunction)(snes,U,F,ts);CHKERRQ(ierr);
4147   PetscFunctionReturn(0);
4148 }
4149 
4150 #undef __FUNCT__
4151 #define __FUNCT__ "SNESTSFormJacobian"
4152 /*@
4153    SNESTSFormJacobian - Function to evaluate the Jacobian
4154 
4155    Collective on SNES
4156 
4157    Input Parameter:
4158 + snes - nonlinear solver
4159 . U - the current state at which to evaluate the residual
4160 - ctx - user context, must be a TS
4161 
4162    Output Parameter:
4163 + A - the Jacobian
4164 . B - the preconditioning matrix (may be the same as A)
4165 - flag - indicates any structure change in the matrix
4166 
4167    Notes:
4168    This function is not normally called by users and is automatically registered with the SNES used by TS.
4169 
4170    Level: developer
4171 
4172 .seealso: SNESSetJacobian()
4173 @*/
4174 PetscErrorCode  SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx)
4175 {
4176   TS             ts = (TS)ctx;
4177   PetscErrorCode ierr;
4178 
4179   PetscFunctionBegin;
4180   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4181   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
4182   PetscValidPointer(A,3);
4183   PetscValidHeaderSpecific(A,MAT_CLASSID,3);
4184   PetscValidPointer(B,4);
4185   PetscValidHeaderSpecific(B,MAT_CLASSID,4);
4186   PetscValidHeaderSpecific(ts,TS_CLASSID,6);
4187   ierr = (ts->ops->snesjacobian)(snes,U,A,B,ts);CHKERRQ(ierr);
4188   PetscFunctionReturn(0);
4189 }
4190 
4191 #undef __FUNCT__
4192 #define __FUNCT__ "TSComputeRHSFunctionLinear"
4193 /*@C
4194    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems only
4195 
4196    Collective on TS
4197 
4198    Input Arguments:
4199 +  ts - time stepping context
4200 .  t - time at which to evaluate
4201 .  U - state at which to evaluate
4202 -  ctx - context
4203 
4204    Output Arguments:
4205 .  F - right hand side
4206 
4207    Level: intermediate
4208 
4209    Notes:
4210    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
4211    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().
4212 
4213 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSJacobianConstant()
4214 @*/
4215 PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx)
4216 {
4217   PetscErrorCode ierr;
4218   Mat            Arhs,Brhs;
4219 
4220   PetscFunctionBegin;
4221   ierr = TSGetRHSMats_Private(ts,&Arhs,&Brhs);CHKERRQ(ierr);
4222   ierr = TSComputeRHSJacobian(ts,t,U,Arhs,Brhs);CHKERRQ(ierr);
4223   ierr = MatMult(Arhs,U,F);CHKERRQ(ierr);
4224   PetscFunctionReturn(0);
4225 }
4226 
4227 #undef __FUNCT__
4228 #define __FUNCT__ "TSComputeRHSJacobianConstant"
4229 /*@C
4230    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
4231 
4232    Collective on TS
4233 
4234    Input Arguments:
4235 +  ts - time stepping context
4236 .  t - time at which to evaluate
4237 .  U - state at which to evaluate
4238 -  ctx - context
4239 
4240    Output Arguments:
4241 +  A - pointer to operator
4242 .  B - pointer to preconditioning matrix
4243 -  flg - matrix structure flag
4244 
4245    Level: intermediate
4246 
4247    Notes:
4248    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.
4249 
4250 .seealso: TSSetRHSFunction(), TSSetRHSJacobian(), TSComputeRHSFunctionLinear()
4251 @*/
4252 PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx)
4253 {
4254   PetscFunctionBegin;
4255   PetscFunctionReturn(0);
4256 }
4257 
4258 #undef __FUNCT__
4259 #define __FUNCT__ "TSComputeIFunctionLinear"
4260 /*@C
4261    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
4262 
4263    Collective on TS
4264 
4265    Input Arguments:
4266 +  ts - time stepping context
4267 .  t - time at which to evaluate
4268 .  U - state at which to evaluate
4269 .  Udot - time derivative of state vector
4270 -  ctx - context
4271 
4272    Output Arguments:
4273 .  F - left hand side
4274 
4275    Level: intermediate
4276 
4277    Notes:
4278    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
4279    user is required to write their own TSComputeIFunction.
4280    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
4281    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().
4282 
4283 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIJacobianConstant()
4284 @*/
4285 PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx)
4286 {
4287   PetscErrorCode ierr;
4288   Mat            A,B;
4289 
4290   PetscFunctionBegin;
4291   ierr = TSGetIJacobian(ts,&A,&B,NULL,NULL);CHKERRQ(ierr);
4292   ierr = TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE);CHKERRQ(ierr);
4293   ierr = MatMult(A,Udot,F);CHKERRQ(ierr);
4294   PetscFunctionReturn(0);
4295 }
4296 
4297 #undef __FUNCT__
4298 #define __FUNCT__ "TSComputeIJacobianConstant"
4299 /*@C
4300    TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE
4301 
4302    Collective on TS
4303 
4304    Input Arguments:
4305 +  ts - time stepping context
4306 .  t - time at which to evaluate
4307 .  U - state at which to evaluate
4308 .  Udot - time derivative of state vector
4309 .  shift - shift to apply
4310 -  ctx - context
4311 
4312    Output Arguments:
4313 +  A - pointer to operator
4314 .  B - pointer to preconditioning matrix
4315 -  flg - matrix structure flag
4316 
4317    Level: advanced
4318 
4319    Notes:
4320    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.
4321 
4322    It is only appropriate for problems of the form
4323 
4324 $     M Udot = F(U,t)
4325 
4326   where M is constant and F is non-stiff.  The user must pass M to TSSetIJacobian().  The current implementation only
4327   works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing
4328   an implicit operator of the form
4329 
4330 $    shift*M + J
4331 
4332   where J is the Jacobian of -F(U).  Support may be added in a future version of PETSc, but for now, the user must store
4333   a copy of M or reassemble it when requested.
4334 
4335 .seealso: TSSetIFunction(), TSSetIJacobian(), TSComputeIFunctionLinear()
4336 @*/
4337 PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx)
4338 {
4339   PetscErrorCode ierr;
4340 
4341   PetscFunctionBegin;
4342   ierr = MatScale(A, shift / ts->ijacobian.shift);CHKERRQ(ierr);
4343   ts->ijacobian.shift = shift;
4344   PetscFunctionReturn(0);
4345 }
4346 
4347 #undef __FUNCT__
4348 #define __FUNCT__ "TSGetEquationType"
4349 /*@
4350    TSGetEquationType - Gets the type of the equation that TS is solving.
4351 
4352    Not Collective
4353 
4354    Input Parameter:
4355 .  ts - the TS context
4356 
4357    Output Parameter:
4358 .  equation_type - see TSEquationType
4359 
4360    Level: beginner
4361 
4362 .keywords: TS, equation type
4363 
4364 .seealso: TSSetEquationType(), TSEquationType
4365 @*/
4366 PetscErrorCode  TSGetEquationType(TS ts,TSEquationType *equation_type)
4367 {
4368   PetscFunctionBegin;
4369   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4370   PetscValidPointer(equation_type,2);
4371   *equation_type = ts->equation_type;
4372   PetscFunctionReturn(0);
4373 }
4374 
4375 #undef __FUNCT__
4376 #define __FUNCT__ "TSSetEquationType"
4377 /*@
4378    TSSetEquationType - Sets the type of the equation that TS is solving.
4379 
4380    Not Collective
4381 
4382    Input Parameter:
4383 +  ts - the TS context
4384 -  equation_type - see TSEquationType
4385 
4386    Level: advanced
4387 
4388 .keywords: TS, equation type
4389 
4390 .seealso: TSGetEquationType(), TSEquationType
4391 @*/
4392 PetscErrorCode  TSSetEquationType(TS ts,TSEquationType equation_type)
4393 {
4394   PetscFunctionBegin;
4395   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4396   ts->equation_type = equation_type;
4397   PetscFunctionReturn(0);
4398 }
4399 
4400 #undef __FUNCT__
4401 #define __FUNCT__ "TSGetConvergedReason"
4402 /*@
4403    TSGetConvergedReason - Gets the reason the TS iteration was stopped.
4404 
4405    Not Collective
4406 
4407    Input Parameter:
4408 .  ts - the TS context
4409 
4410    Output Parameter:
4411 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
4412             manual pages for the individual convergence tests for complete lists
4413 
4414    Level: beginner
4415 
4416    Notes:
4417    Can only be called after the call to TSSolve() is complete.
4418 
4419 .keywords: TS, nonlinear, set, convergence, test
4420 
4421 .seealso: TSSetConvergenceTest(), TSConvergedReason
4422 @*/
4423 PetscErrorCode  TSGetConvergedReason(TS ts,TSConvergedReason *reason)
4424 {
4425   PetscFunctionBegin;
4426   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4427   PetscValidPointer(reason,2);
4428   *reason = ts->reason;
4429   PetscFunctionReturn(0);
4430 }
4431 
4432 #undef __FUNCT__
4433 #define __FUNCT__ "TSSetConvergedReason"
4434 /*@
4435    TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve.
4436 
4437    Not Collective
4438 
4439    Input Parameter:
4440 +  ts - the TS context
4441 .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
4442             manual pages for the individual convergence tests for complete lists
4443 
4444    Level: advanced
4445 
4446    Notes:
4447    Can only be called during TSSolve() is active.
4448 
4449 .keywords: TS, nonlinear, set, convergence, test
4450 
4451 .seealso: TSConvergedReason
4452 @*/
4453 PetscErrorCode  TSSetConvergedReason(TS ts,TSConvergedReason reason)
4454 {
4455   PetscFunctionBegin;
4456   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4457   ts->reason = reason;
4458   PetscFunctionReturn(0);
4459 }
4460 
4461 #undef __FUNCT__
4462 #define __FUNCT__ "TSGetSolveTime"
4463 /*@
4464    TSGetSolveTime - Gets the time after a call to TSSolve()
4465 
4466    Not Collective
4467 
4468    Input Parameter:
4469 .  ts - the TS context
4470 
4471    Output Parameter:
4472 .  ftime - the final time. This time should correspond to the final time set with TSSetDuration()
4473 
4474    Level: beginner
4475 
4476    Notes:
4477    Can only be called after the call to TSSolve() is complete.
4478 
4479 .keywords: TS, nonlinear, set, convergence, test
4480 
4481 .seealso: TSSetConvergenceTest(), TSConvergedReason
4482 @*/
4483 PetscErrorCode  TSGetSolveTime(TS ts,PetscReal *ftime)
4484 {
4485   PetscFunctionBegin;
4486   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4487   PetscValidPointer(ftime,2);
4488   *ftime = ts->solvetime;
4489   PetscFunctionReturn(0);
4490 }
4491 
4492 #undef __FUNCT__
4493 #define __FUNCT__ "TSGetTotalSteps"
4494 /*@
4495    TSGetTotalSteps - Gets the total number of steps done since the last call to TSSetUp() or TSCreate()
4496 
4497    Not Collective
4498 
4499    Input Parameter:
4500 .  ts - the TS context
4501 
4502    Output Parameter:
4503 .  steps - the number of steps
4504 
4505    Level: beginner
4506 
4507    Notes:
4508    Includes the number of steps for all calls to TSSolve() since TSSetUp() was called
4509 
4510 .keywords: TS, nonlinear, set, convergence, test
4511 
4512 .seealso: TSSetConvergenceTest(), TSConvergedReason
4513 @*/
4514 PetscErrorCode  TSGetTotalSteps(TS ts,PetscInt *steps)
4515 {
4516   PetscFunctionBegin;
4517   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4518   PetscValidPointer(steps,2);
4519   *steps = ts->total_steps;
4520   PetscFunctionReturn(0);
4521 }
4522 
4523 #undef __FUNCT__
4524 #define __FUNCT__ "TSGetSNESIterations"
4525 /*@
4526    TSGetSNESIterations - Gets the total number of nonlinear iterations
4527    used by the time integrator.
4528 
4529    Not Collective
4530 
4531    Input Parameter:
4532 .  ts - TS context
4533 
4534    Output Parameter:
4535 .  nits - number of nonlinear iterations
4536 
4537    Notes:
4538    This counter is reset to zero for each successive call to TSSolve().
4539 
4540    Level: intermediate
4541 
4542 .keywords: TS, get, number, nonlinear, iterations
4543 
4544 .seealso:  TSGetKSPIterations()
4545 @*/
4546 PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits)
4547 {
4548   PetscFunctionBegin;
4549   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4550   PetscValidIntPointer(nits,2);
4551   *nits = ts->snes_its;
4552   PetscFunctionReturn(0);
4553 }
4554 
4555 #undef __FUNCT__
4556 #define __FUNCT__ "TSGetKSPIterations"
4557 /*@
4558    TSGetKSPIterations - Gets the total number of linear iterations
4559    used by the time integrator.
4560 
4561    Not Collective
4562 
4563    Input Parameter:
4564 .  ts - TS context
4565 
4566    Output Parameter:
4567 .  lits - number of linear iterations
4568 
4569    Notes:
4570    This counter is reset to zero for each successive call to TSSolve().
4571 
4572    Level: intermediate
4573 
4574 .keywords: TS, get, number, linear, iterations
4575 
4576 .seealso:  TSGetSNESIterations(), SNESGetKSPIterations()
4577 @*/
4578 PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits)
4579 {
4580   PetscFunctionBegin;
4581   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4582   PetscValidIntPointer(lits,2);
4583   *lits = ts->ksp_its;
4584   PetscFunctionReturn(0);
4585 }
4586 
4587 #undef __FUNCT__
4588 #define __FUNCT__ "TSGetStepRejections"
4589 /*@
4590    TSGetStepRejections - Gets the total number of rejected steps.
4591 
4592    Not Collective
4593 
4594    Input Parameter:
4595 .  ts - TS context
4596 
4597    Output Parameter:
4598 .  rejects - number of steps rejected
4599 
4600    Notes:
4601    This counter is reset to zero for each successive call to TSSolve().
4602 
4603    Level: intermediate
4604 
4605 .keywords: TS, get, number
4606 
4607 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetSNESFailures(), TSSetMaxSNESFailures(), TSSetErrorIfStepFails()
4608 @*/
4609 PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects)
4610 {
4611   PetscFunctionBegin;
4612   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4613   PetscValidIntPointer(rejects,2);
4614   *rejects = ts->reject;
4615   PetscFunctionReturn(0);
4616 }
4617 
4618 #undef __FUNCT__
4619 #define __FUNCT__ "TSGetSNESFailures"
4620 /*@
4621    TSGetSNESFailures - Gets the total number of failed SNES solves
4622 
4623    Not Collective
4624 
4625    Input Parameter:
4626 .  ts - TS context
4627 
4628    Output Parameter:
4629 .  fails - number of failed nonlinear solves
4630 
4631    Notes:
4632    This counter is reset to zero for each successive call to TSSolve().
4633 
4634    Level: intermediate
4635 
4636 .keywords: TS, get, number
4637 
4638 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSSetMaxSNESFailures()
4639 @*/
4640 PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails)
4641 {
4642   PetscFunctionBegin;
4643   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4644   PetscValidIntPointer(fails,2);
4645   *fails = ts->num_snes_failures;
4646   PetscFunctionReturn(0);
4647 }
4648 
4649 #undef __FUNCT__
4650 #define __FUNCT__ "TSSetMaxStepRejections"
4651 /*@
4652    TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails
4653 
4654    Not Collective
4655 
4656    Input Parameter:
4657 +  ts - TS context
4658 -  rejects - maximum number of rejected steps, pass -1 for unlimited
4659 
4660    Notes:
4661    The counter is reset to zero for each step
4662 
4663    Options Database Key:
4664  .  -ts_max_reject - Maximum number of step rejections before a step fails
4665 
4666    Level: intermediate
4667 
4668 .keywords: TS, set, maximum, number
4669 
4670 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxSNESFailures(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
4671 @*/
4672 PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects)
4673 {
4674   PetscFunctionBegin;
4675   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4676   ts->max_reject = rejects;
4677   PetscFunctionReturn(0);
4678 }
4679 
4680 #undef __FUNCT__
4681 #define __FUNCT__ "TSSetMaxSNESFailures"
4682 /*@
4683    TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves
4684 
4685    Not Collective
4686 
4687    Input Parameter:
4688 +  ts - TS context
4689 -  fails - maximum number of failed nonlinear solves, pass -1 for unlimited
4690 
4691    Notes:
4692    The counter is reset to zero for each successive call to TSSolve().
4693 
4694    Options Database Key:
4695  .  -ts_max_snes_failures - Maximum number of nonlinear solve failures
4696 
4697    Level: intermediate
4698 
4699 .keywords: TS, set, maximum, number
4700 
4701 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), SNESGetConvergedReason(), TSGetConvergedReason()
4702 @*/
4703 PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails)
4704 {
4705   PetscFunctionBegin;
4706   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4707   ts->max_snes_failures = fails;
4708   PetscFunctionReturn(0);
4709 }
4710 
4711 #undef __FUNCT__
4712 #define __FUNCT__ "TSSetErrorIfStepFails"
4713 /*@
4714    TSSetErrorIfStepFails - Error if no step succeeds
4715 
4716    Not Collective
4717 
4718    Input Parameter:
4719 +  ts - TS context
4720 -  err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure
4721 
4722    Options Database Key:
4723  .  -ts_error_if_step_fails - Error if no step succeeds
4724 
4725    Level: intermediate
4726 
4727 .keywords: TS, set, error
4728 
4729 .seealso:  TSGetSNESIterations(), TSGetKSPIterations(), TSSetMaxStepRejections(), TSGetStepRejections(), TSGetSNESFailures(), TSSetErrorIfStepFails(), TSGetConvergedReason()
4730 @*/
4731 PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err)
4732 {
4733   PetscFunctionBegin;
4734   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4735   ts->errorifstepfailed = err;
4736   PetscFunctionReturn(0);
4737 }
4738 
4739 #undef __FUNCT__
4740 #define __FUNCT__ "TSMonitorSolutionBinary"
4741 /*@C
4742    TSMonitorSolutionBinary - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file
4743 
4744    Collective on TS
4745 
4746    Input Parameters:
4747 +  ts - the TS context
4748 .  step - current time-step
4749 .  ptime - current time
4750 .  u - current state
4751 -  viewer - binary viewer
4752 
4753    Level: intermediate
4754 
4755 .keywords: TS,  vector, monitor, view
4756 
4757 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4758 @*/
4759 PetscErrorCode  TSMonitorSolutionBinary(TS ts,PetscInt step,PetscReal ptime,Vec u,void *viewer)
4760 {
4761   PetscErrorCode ierr;
4762   PetscViewer    v = (PetscViewer)viewer;
4763 
4764   PetscFunctionBegin;
4765   ierr = VecView(u,v);CHKERRQ(ierr);
4766   PetscFunctionReturn(0);
4767 }
4768 
4769 #undef __FUNCT__
4770 #define __FUNCT__ "TSMonitorSolutionVTK"
4771 /*@C
4772    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.
4773 
4774    Collective on TS
4775 
4776    Input Parameters:
4777 +  ts - the TS context
4778 .  step - current time-step
4779 .  ptime - current time
4780 .  u - current state
4781 -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
4782 
4783    Level: intermediate
4784 
4785    Notes:
4786    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.
4787    These are named according to the file name template.
4788 
4789    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().
4790 
4791 .keywords: TS,  vector, monitor, view
4792 
4793 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
4794 @*/
4795 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
4796 {
4797   PetscErrorCode ierr;
4798   char           filename[PETSC_MAX_PATH_LEN];
4799   PetscViewer    viewer;
4800 
4801   PetscFunctionBegin;
4802   ierr = PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);CHKERRQ(ierr);
4803   ierr = PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr);
4804   ierr = VecView(u,viewer);CHKERRQ(ierr);
4805   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
4806   PetscFunctionReturn(0);
4807 }
4808 
4809 #undef __FUNCT__
4810 #define __FUNCT__ "TSMonitorSolutionVTKDestroy"
4811 /*@C
4812    TSMonitorSolutionVTKDestroy - Destroy context for monitoring
4813 
4814    Collective on TS
4815 
4816    Input Parameters:
4817 .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)
4818 
4819    Level: intermediate
4820 
4821    Note:
4822    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().
4823 
4824 .keywords: TS,  vector, monitor, view
4825 
4826 .seealso: TSMonitorSet(), TSMonitorSolutionVTK()
4827 @*/
4828 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
4829 {
4830   PetscErrorCode ierr;
4831 
4832   PetscFunctionBegin;
4833   ierr = PetscFree(*(char**)filenametemplate);CHKERRQ(ierr);
4834   PetscFunctionReturn(0);
4835 }
4836 
4837 #undef __FUNCT__
4838 #define __FUNCT__ "TSGetAdapt"
4839 /*@
4840    TSGetAdapt - Get the adaptive controller context for the current method
4841 
4842    Collective on TS if controller has not been created yet
4843 
4844    Input Arguments:
4845 .  ts - time stepping context
4846 
4847    Output Arguments:
4848 .  adapt - adaptive controller
4849 
4850    Level: intermediate
4851 
4852 .seealso: TSAdapt, TSAdaptSetType(), TSAdaptChoose()
4853 @*/
4854 PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt)
4855 {
4856   PetscErrorCode ierr;
4857 
4858   PetscFunctionBegin;
4859   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4860   PetscValidPointer(adapt,2);
4861   if (!ts->adapt) {
4862     ierr = TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt);CHKERRQ(ierr);
4863     ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt);CHKERRQ(ierr);
4864     ierr = PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1);CHKERRQ(ierr);
4865   }
4866   *adapt = ts->adapt;
4867   PetscFunctionReturn(0);
4868 }
4869 
4870 #undef __FUNCT__
4871 #define __FUNCT__ "TSSetTolerances"
4872 /*@
4873    TSSetTolerances - Set tolerances for local truncation error when using adaptive controller
4874 
4875    Logically Collective
4876 
4877    Input Arguments:
4878 +  ts - time integration context
4879 .  atol - scalar absolute tolerances, PETSC_DECIDE to leave current value
4880 .  vatol - vector of absolute tolerances or NULL, used in preference to atol if present
4881 .  rtol - scalar relative tolerances, PETSC_DECIDE to leave current value
4882 -  vrtol - vector of relative tolerances or NULL, used in preference to atol if present
4883 
4884    Options Database keys:
4885 +  -ts_rtol <rtol> - relative tolerance for local truncation error
4886 -  -ts_atol <atol> Absolute tolerance for local truncation error
4887 
4888    Notes:
4889    With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error
4890    (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be
4891    computed only for the differential or the algebraic part then this can be done using the vector of
4892    tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the
4893    differential part and infinity for the algebraic part, the LTE calculation will include only the
4894    differential variables.
4895 
4896    Level: beginner
4897 
4898 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSGetTolerances()
4899 @*/
4900 PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol)
4901 {
4902   PetscErrorCode ierr;
4903 
4904   PetscFunctionBegin;
4905   if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol;
4906   if (vatol) {
4907     ierr = PetscObjectReference((PetscObject)vatol);CHKERRQ(ierr);
4908     ierr = VecDestroy(&ts->vatol);CHKERRQ(ierr);
4909 
4910     ts->vatol = vatol;
4911   }
4912   if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol;
4913   if (vrtol) {
4914     ierr = PetscObjectReference((PetscObject)vrtol);CHKERRQ(ierr);
4915     ierr = VecDestroy(&ts->vrtol);CHKERRQ(ierr);
4916 
4917     ts->vrtol = vrtol;
4918   }
4919   PetscFunctionReturn(0);
4920 }
4921 
4922 #undef __FUNCT__
4923 #define __FUNCT__ "TSGetTolerances"
4924 /*@
4925    TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
4926 
4927    Logically Collective
4928 
4929    Input Arguments:
4930 .  ts - time integration context
4931 
4932    Output Arguments:
4933 +  atol - scalar absolute tolerances, NULL to ignore
4934 .  vatol - vector of absolute tolerances, NULL to ignore
4935 .  rtol - scalar relative tolerances, NULL to ignore
4936 -  vrtol - vector of relative tolerances, NULL to ignore
4937 
4938    Level: beginner
4939 
4940 .seealso: TS, TSAdapt, TSVecNormWRMS(), TSSetTolerances()
4941 @*/
4942 PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol)
4943 {
4944   PetscFunctionBegin;
4945   if (atol)  *atol  = ts->atol;
4946   if (vatol) *vatol = ts->vatol;
4947   if (rtol)  *rtol  = ts->rtol;
4948   if (vrtol) *vrtol = ts->vrtol;
4949   PetscFunctionReturn(0);
4950 }
4951 
4952 #undef __FUNCT__
4953 #define __FUNCT__ "TSErrorWeightedNorm2"
4954 /*@
4955    TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors
4956 
4957    Collective on TS
4958 
4959    Input Arguments:
4960 +  ts - time stepping context
4961 .  U - state vector, usually ts->vec_sol
4962 -  Y - state vector to be compared to U
4963 
4964    Output Arguments:
4965 .  norm - weighted norm, a value of 1.0 is considered small
4966 
4967    Level: developer
4968 
4969 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNormInfinity()
4970 @*/
4971 PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm)
4972 {
4973   PetscErrorCode    ierr;
4974   PetscInt          i,n,N,rstart;
4975   const PetscScalar *u,*y;
4976   PetscReal         sum,gsum;
4977   PetscReal         tol;
4978 
4979   PetscFunctionBegin;
4980   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4981   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
4982   PetscValidHeaderSpecific(Y,VEC_CLASSID,3);
4983   PetscValidType(U,2);
4984   PetscValidType(Y,3);
4985   PetscCheckSameComm(U,2,Y,3);
4986   PetscValidPointer(norm,4);
4987   if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector");
4988 
4989   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
4990   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
4991   ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr);
4992   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
4993   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
4994   sum  = 0.;
4995   if (ts->vatol && ts->vrtol) {
4996     const PetscScalar *atol,*rtol;
4997     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
4998     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
4999     for (i=0; i<n; i++) {
5000       tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5001       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
5002     }
5003     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5004     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5005   } else if (ts->vatol) {       /* vector atol, scalar rtol */
5006     const PetscScalar *atol;
5007     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5008     for (i=0; i<n; i++) {
5009       tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5010       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
5011     }
5012     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5013   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
5014     const PetscScalar *rtol;
5015     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5016     for (i=0; i<n; i++) {
5017       tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5018       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
5019     }
5020     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5021   } else {                      /* scalar atol, scalar rtol */
5022     for (i=0; i<n; i++) {
5023       tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5024       sum += PetscSqr(PetscAbsScalar(y[i] - u[i]) / tol);
5025     }
5026   }
5027   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
5028   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
5029 
5030   ierr  = MPI_Allreduce(&sum,&gsum,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
5031   *norm = PetscSqrtReal(gsum / N);
5032 
5033   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
5034   PetscFunctionReturn(0);
5035 }
5036 
5037 #undef __FUNCT__
5038 #define __FUNCT__ "TSErrorWeightedNormInfinity"
5039 /*@
5040    TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors
5041 
5042    Collective on TS
5043 
5044    Input Arguments:
5045 +  ts - time stepping context
5046 .  U - state vector, usually ts->vec_sol
5047 -  Y - state vector to be compared to U
5048 
5049    Output Arguments:
5050 .  norm - weighted norm, a value of 1.0 is considered small
5051 
5052    Level: developer
5053 
5054 .seealso: TSErrorWeightedNorm(), TSErrorWeightedNorm2()
5055 @*/
5056 PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm)
5057 {
5058   PetscErrorCode    ierr;
5059   PetscInt          i,n,N,rstart,k;
5060   const PetscScalar *u,*y;
5061   PetscReal         max,gmax;
5062   PetscReal         tol;
5063 
5064   PetscFunctionBegin;
5065   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5066   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
5067   PetscValidHeaderSpecific(Y,VEC_CLASSID,3);
5068   PetscValidType(U,2);
5069   PetscValidType(Y,3);
5070   PetscCheckSameComm(U,2,Y,3);
5071   PetscValidPointer(norm,4);
5072   if (U == Y) SETERRQ(PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector");
5073 
5074   ierr = VecGetSize(U,&N);CHKERRQ(ierr);
5075   ierr = VecGetLocalSize(U,&n);CHKERRQ(ierr);
5076   ierr = VecGetOwnershipRange(U,&rstart,NULL);CHKERRQ(ierr);
5077   ierr = VecGetArrayRead(U,&u);CHKERRQ(ierr);
5078   ierr = VecGetArrayRead(Y,&y);CHKERRQ(ierr);
5079   if (ts->vatol && ts->vrtol) {
5080     const PetscScalar *atol,*rtol;
5081     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5082     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5083     k = 0;
5084     tol = PetscRealPart(atol[k]) + PetscRealPart(rtol[k]) * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k]));
5085     max = PetscAbsScalar(y[k] - u[k]) / tol;
5086     for (i=1; i<n; i++) {
5087       tol = PetscRealPart(atol[i]) + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5088       max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol);
5089     }
5090     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5091     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5092   } else if (ts->vatol) {       /* vector atol, scalar rtol */
5093     const PetscScalar *atol;
5094     ierr = VecGetArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5095     k = 0;
5096     tol = PetscRealPart(atol[k]) + ts->rtol * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k]));
5097     max = PetscAbsScalar(y[k] - u[k]) / tol;
5098     for (i=1; i<n; i++) {
5099       tol = PetscRealPart(atol[i]) + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5100       max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol);
5101     }
5102     ierr = VecRestoreArrayRead(ts->vatol,&atol);CHKERRQ(ierr);
5103   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
5104     const PetscScalar *rtol;
5105     ierr = VecGetArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5106     k = 0;
5107     tol = ts->atol + PetscRealPart(rtol[k]) * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k]));
5108     max = PetscAbsScalar(y[k] - u[k]) / tol;
5109     for (i=1; i<n; i++) {
5110       tol = ts->atol + PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5111       max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol);
5112     }
5113     ierr = VecRestoreArrayRead(ts->vrtol,&rtol);CHKERRQ(ierr);
5114   } else {                      /* scalar atol, scalar rtol */
5115     k = 0;
5116     tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[k]),PetscAbsScalar(y[k]));
5117     max = PetscAbsScalar(y[k] - u[k]) / tol;
5118     for (i=1; i<n; i++) {
5119       tol = ts->atol + ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
5120       max = PetscMax(max,PetscAbsScalar(y[i] - u[i]) / tol);
5121     }
5122   }
5123   ierr = VecRestoreArrayRead(U,&u);CHKERRQ(ierr);
5124   ierr = VecRestoreArrayRead(Y,&y);CHKERRQ(ierr);
5125 
5126   ierr  = MPI_Allreduce(&max,&gmax,1,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
5127   *norm = gmax;
5128 
5129   if (PetscIsInfOrNanScalar(*norm)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
5130   PetscFunctionReturn(0);
5131 }
5132 
5133 #undef __FUNCT__
5134 #define __FUNCT__ "TSErrorWeightedNorm"
5135 /*@
5136    TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors
5137 
5138    Collective on TS
5139 
5140    Input Arguments:
5141 +  ts - time stepping context
5142 .  U - state vector, usually ts->vec_sol
5143 .  Y - state vector to be compared to U
5144 -  wnormtype - norm type, either NORM_2 or NORM_INFINITY
5145 
5146    Output Arguments:
5147 .  norm - weighted norm, a value of 1.0 is considered small
5148 
5149 
5150    Options Database Keys:
5151 .  -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
5152 
5153    Level: developer
5154 
5155 .seealso: TSErrorWeightedNormInfinity(), TSErrorWeightedNorm2()
5156 @*/
5157 PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm)
5158 {
5159   PetscErrorCode ierr;
5160 
5161   PetscFunctionBegin;
5162   if (wnormtype == NORM_2) {
5163     ierr = TSErrorWeightedNorm2(ts,U,Y,norm);CHKERRQ(ierr);
5164   } else if(wnormtype == NORM_INFINITY) {
5165     ierr = TSErrorWeightedNormInfinity(ts,U,Y,norm);CHKERRQ(ierr);
5166   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
5167   PetscFunctionReturn(0);
5168 }
5169 
5170 #undef __FUNCT__
5171 #define __FUNCT__ "TSSetCFLTimeLocal"
5172 /*@
5173    TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
5174 
5175    Logically Collective on TS
5176 
5177    Input Arguments:
5178 +  ts - time stepping context
5179 -  cfltime - maximum stable time step if using forward Euler (value can be different on each process)
5180 
5181    Note:
5182    After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
5183 
5184    Level: intermediate
5185 
5186 .seealso: TSGetCFLTime(), TSADAPTCFL
5187 @*/
5188 PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime)
5189 {
5190   PetscFunctionBegin;
5191   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5192   ts->cfltime_local = cfltime;
5193   ts->cfltime       = -1.;
5194   PetscFunctionReturn(0);
5195 }
5196 
5197 #undef __FUNCT__
5198 #define __FUNCT__ "TSGetCFLTime"
5199 /*@
5200    TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
5201 
5202    Collective on TS
5203 
5204    Input Arguments:
5205 .  ts - time stepping context
5206 
5207    Output Arguments:
5208 .  cfltime - maximum stable time step for forward Euler
5209 
5210    Level: advanced
5211 
5212 .seealso: TSSetCFLTimeLocal()
5213 @*/
5214 PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime)
5215 {
5216   PetscErrorCode ierr;
5217 
5218   PetscFunctionBegin;
5219   if (ts->cfltime < 0) {
5220     ierr = MPI_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts));CHKERRQ(ierr);
5221   }
5222   *cfltime = ts->cfltime;
5223   PetscFunctionReturn(0);
5224 }
5225 
5226 #undef __FUNCT__
5227 #define __FUNCT__ "TSVISetVariableBounds"
5228 /*@
5229    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
5230 
5231    Input Parameters:
5232 .  ts   - the TS context.
5233 .  xl   - lower bound.
5234 .  xu   - upper bound.
5235 
5236    Notes:
5237    If this routine is not called then the lower and upper bounds are set to
5238    PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp().
5239 
5240    Level: advanced
5241 
5242 @*/
5243 PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
5244 {
5245   PetscErrorCode ierr;
5246   SNES           snes;
5247 
5248   PetscFunctionBegin;
5249   ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr);
5250   ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr);
5251   PetscFunctionReturn(0);
5252 }
5253 
5254 #if defined(PETSC_HAVE_MATLAB_ENGINE)
5255 #include <mex.h>
5256 
5257 typedef struct {char *funcname; mxArray *ctx;} TSMatlabContext;
5258 
5259 #undef __FUNCT__
5260 #define __FUNCT__ "TSComputeFunction_Matlab"
5261 /*
5262    TSComputeFunction_Matlab - Calls the function that has been set with
5263                          TSSetFunctionMatlab().
5264 
5265    Collective on TS
5266 
5267    Input Parameters:
5268 +  snes - the TS context
5269 -  u - input vector
5270 
5271    Output Parameter:
5272 .  y - function vector, as set by TSSetFunction()
5273 
5274    Notes:
5275    TSComputeFunction() is typically used within nonlinear solvers
5276    implementations, so most users would not generally call this routine
5277    themselves.
5278 
5279    Level: developer
5280 
5281 .keywords: TS, nonlinear, compute, function
5282 
5283 .seealso: TSSetFunction(), TSGetFunction()
5284 */
5285 PetscErrorCode  TSComputeFunction_Matlab(TS snes,PetscReal time,Vec u,Vec udot,Vec y, void *ctx)
5286 {
5287   PetscErrorCode  ierr;
5288   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
5289   int             nlhs  = 1,nrhs = 7;
5290   mxArray         *plhs[1],*prhs[7];
5291   long long int   lx = 0,lxdot = 0,ly = 0,ls = 0;
5292 
5293   PetscFunctionBegin;
5294   PetscValidHeaderSpecific(snes,TS_CLASSID,1);
5295   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
5296   PetscValidHeaderSpecific(udot,VEC_CLASSID,4);
5297   PetscValidHeaderSpecific(y,VEC_CLASSID,5);
5298   PetscCheckSameComm(snes,1,u,3);
5299   PetscCheckSameComm(snes,1,y,5);
5300 
5301   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
5302   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
5303   ierr = PetscMemcpy(&lxdot,&udot,sizeof(udot));CHKERRQ(ierr);
5304   ierr = PetscMemcpy(&ly,&y,sizeof(u));CHKERRQ(ierr);
5305 
5306   prhs[0] =  mxCreateDoubleScalar((double)ls);
5307   prhs[1] =  mxCreateDoubleScalar(time);
5308   prhs[2] =  mxCreateDoubleScalar((double)lx);
5309   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
5310   prhs[4] =  mxCreateDoubleScalar((double)ly);
5311   prhs[5] =  mxCreateString(sctx->funcname);
5312   prhs[6] =  sctx->ctx;
5313   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeFunctionInternal");CHKERRQ(ierr);
5314   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
5315   mxDestroyArray(prhs[0]);
5316   mxDestroyArray(prhs[1]);
5317   mxDestroyArray(prhs[2]);
5318   mxDestroyArray(prhs[3]);
5319   mxDestroyArray(prhs[4]);
5320   mxDestroyArray(prhs[5]);
5321   mxDestroyArray(plhs[0]);
5322   PetscFunctionReturn(0);
5323 }
5324 
5325 
5326 #undef __FUNCT__
5327 #define __FUNCT__ "TSSetFunctionMatlab"
5328 /*
5329    TSSetFunctionMatlab - Sets the function evaluation routine and function
5330    vector for use by the TS routines in solving ODEs
5331    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
5332 
5333    Logically Collective on TS
5334 
5335    Input Parameters:
5336 +  ts - the TS context
5337 -  func - function evaluation routine
5338 
5339    Calling sequence of func:
5340 $    func (TS ts,PetscReal time,Vec u,Vec udot,Vec f,void *ctx);
5341 
5342    Level: beginner
5343 
5344 .keywords: TS, nonlinear, set, function
5345 
5346 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
5347 */
5348 PetscErrorCode  TSSetFunctionMatlab(TS ts,const char *func,mxArray *ctx)
5349 {
5350   PetscErrorCode  ierr;
5351   TSMatlabContext *sctx;
5352 
5353   PetscFunctionBegin;
5354   /* currently sctx is memory bleed */
5355   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
5356   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
5357   /*
5358      This should work, but it doesn't
5359   sctx->ctx = ctx;
5360   mexMakeArrayPersistent(sctx->ctx);
5361   */
5362   sctx->ctx = mxDuplicateArray(ctx);
5363 
5364   ierr = TSSetIFunction(ts,NULL,TSComputeFunction_Matlab,sctx);CHKERRQ(ierr);
5365   PetscFunctionReturn(0);
5366 }
5367 
5368 #undef __FUNCT__
5369 #define __FUNCT__ "TSComputeJacobian_Matlab"
5370 /*
5371    TSComputeJacobian_Matlab - Calls the function that has been set with
5372                          TSSetJacobianMatlab().
5373 
5374    Collective on TS
5375 
5376    Input Parameters:
5377 +  ts - the TS context
5378 .  u - input vector
5379 .  A, B - the matrices
5380 -  ctx - user context
5381 
5382    Level: developer
5383 
5384 .keywords: TS, nonlinear, compute, function
5385 
5386 .seealso: TSSetFunction(), TSGetFunction()
5387 @*/
5388 PetscErrorCode  TSComputeJacobian_Matlab(TS ts,PetscReal time,Vec u,Vec udot,PetscReal shift,Mat A,Mat B,void *ctx)
5389 {
5390   PetscErrorCode  ierr;
5391   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
5392   int             nlhs  = 2,nrhs = 9;
5393   mxArray         *plhs[2],*prhs[9];
5394   long long int   lx = 0,lxdot = 0,lA = 0,ls = 0, lB = 0;
5395 
5396   PetscFunctionBegin;
5397   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5398   PetscValidHeaderSpecific(u,VEC_CLASSID,3);
5399 
5400   /* call Matlab function in ctx with arguments u and y */
5401 
5402   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
5403   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
5404   ierr = PetscMemcpy(&lxdot,&udot,sizeof(u));CHKERRQ(ierr);
5405   ierr = PetscMemcpy(&lA,A,sizeof(u));CHKERRQ(ierr);
5406   ierr = PetscMemcpy(&lB,B,sizeof(u));CHKERRQ(ierr);
5407 
5408   prhs[0] =  mxCreateDoubleScalar((double)ls);
5409   prhs[1] =  mxCreateDoubleScalar((double)time);
5410   prhs[2] =  mxCreateDoubleScalar((double)lx);
5411   prhs[3] =  mxCreateDoubleScalar((double)lxdot);
5412   prhs[4] =  mxCreateDoubleScalar((double)shift);
5413   prhs[5] =  mxCreateDoubleScalar((double)lA);
5414   prhs[6] =  mxCreateDoubleScalar((double)lB);
5415   prhs[7] =  mxCreateString(sctx->funcname);
5416   prhs[8] =  sctx->ctx;
5417   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSComputeJacobianInternal");CHKERRQ(ierr);
5418   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
5419   mxDestroyArray(prhs[0]);
5420   mxDestroyArray(prhs[1]);
5421   mxDestroyArray(prhs[2]);
5422   mxDestroyArray(prhs[3]);
5423   mxDestroyArray(prhs[4]);
5424   mxDestroyArray(prhs[5]);
5425   mxDestroyArray(prhs[6]);
5426   mxDestroyArray(prhs[7]);
5427   mxDestroyArray(plhs[0]);
5428   mxDestroyArray(plhs[1]);
5429   PetscFunctionReturn(0);
5430 }
5431 
5432 
5433 #undef __FUNCT__
5434 #define __FUNCT__ "TSSetJacobianMatlab"
5435 /*
5436    TSSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
5437    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
5438 
5439    Logically Collective on TS
5440 
5441    Input Parameters:
5442 +  ts - the TS context
5443 .  A,B - Jacobian matrices
5444 .  func - function evaluation routine
5445 -  ctx - user context
5446 
5447    Calling sequence of func:
5448 $    flag = func (TS ts,PetscReal time,Vec u,Vec udot,Mat A,Mat B,void *ctx);
5449 
5450 
5451    Level: developer
5452 
5453 .keywords: TS, nonlinear, set, function
5454 
5455 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
5456 */
5457 PetscErrorCode  TSSetJacobianMatlab(TS ts,Mat A,Mat B,const char *func,mxArray *ctx)
5458 {
5459   PetscErrorCode  ierr;
5460   TSMatlabContext *sctx;
5461 
5462   PetscFunctionBegin;
5463   /* currently sctx is memory bleed */
5464   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
5465   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
5466   /*
5467      This should work, but it doesn't
5468   sctx->ctx = ctx;
5469   mexMakeArrayPersistent(sctx->ctx);
5470   */
5471   sctx->ctx = mxDuplicateArray(ctx);
5472 
5473   ierr = TSSetIJacobian(ts,A,B,TSComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
5474   PetscFunctionReturn(0);
5475 }
5476 
5477 #undef __FUNCT__
5478 #define __FUNCT__ "TSMonitor_Matlab"
5479 /*
5480    TSMonitor_Matlab - Calls the function that has been set with TSMonitorSetMatlab().
5481 
5482    Collective on TS
5483 
5484 .seealso: TSSetFunction(), TSGetFunction()
5485 @*/
5486 PetscErrorCode  TSMonitor_Matlab(TS ts,PetscInt it, PetscReal time,Vec u, void *ctx)
5487 {
5488   PetscErrorCode  ierr;
5489   TSMatlabContext *sctx = (TSMatlabContext*)ctx;
5490   int             nlhs  = 1,nrhs = 6;
5491   mxArray         *plhs[1],*prhs[6];
5492   long long int   lx = 0,ls = 0;
5493 
5494   PetscFunctionBegin;
5495   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5496   PetscValidHeaderSpecific(u,VEC_CLASSID,4);
5497 
5498   ierr = PetscMemcpy(&ls,&ts,sizeof(ts));CHKERRQ(ierr);
5499   ierr = PetscMemcpy(&lx,&u,sizeof(u));CHKERRQ(ierr);
5500 
5501   prhs[0] =  mxCreateDoubleScalar((double)ls);
5502   prhs[1] =  mxCreateDoubleScalar((double)it);
5503   prhs[2] =  mxCreateDoubleScalar((double)time);
5504   prhs[3] =  mxCreateDoubleScalar((double)lx);
5505   prhs[4] =  mxCreateString(sctx->funcname);
5506   prhs[5] =  sctx->ctx;
5507   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscTSMonitorInternal");CHKERRQ(ierr);
5508   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
5509   mxDestroyArray(prhs[0]);
5510   mxDestroyArray(prhs[1]);
5511   mxDestroyArray(prhs[2]);
5512   mxDestroyArray(prhs[3]);
5513   mxDestroyArray(prhs[4]);
5514   mxDestroyArray(plhs[0]);
5515   PetscFunctionReturn(0);
5516 }
5517 
5518 
5519 #undef __FUNCT__
5520 #define __FUNCT__ "TSMonitorSetMatlab"
5521 /*
5522    TSMonitorSetMatlab - Sets the monitor function from Matlab
5523 
5524    Level: developer
5525 
5526 .keywords: TS, nonlinear, set, function
5527 
5528 .seealso: TSGetFunction(), TSComputeFunction(), TSSetJacobian(), TSSetFunction()
5529 */
5530 PetscErrorCode  TSMonitorSetMatlab(TS ts,const char *func,mxArray *ctx)
5531 {
5532   PetscErrorCode  ierr;
5533   TSMatlabContext *sctx;
5534 
5535   PetscFunctionBegin;
5536   /* currently sctx is memory bleed */
5537   ierr = PetscMalloc(sizeof(TSMatlabContext),&sctx);CHKERRQ(ierr);
5538   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
5539   /*
5540      This should work, but it doesn't
5541   sctx->ctx = ctx;
5542   mexMakeArrayPersistent(sctx->ctx);
5543   */
5544   sctx->ctx = mxDuplicateArray(ctx);
5545 
5546   ierr = TSMonitorSet(ts,TSMonitor_Matlab,sctx,NULL);CHKERRQ(ierr);
5547   PetscFunctionReturn(0);
5548 }
5549 #endif
5550 
5551 #undef __FUNCT__
5552 #define __FUNCT__ "TSMonitorLGSolution"
5553 /*@C
5554    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
5555        in a time based line graph
5556 
5557    Collective on TS
5558 
5559    Input Parameters:
5560 +  ts - the TS context
5561 .  step - current time-step
5562 .  ptime - current time
5563 -  lg - a line graph object
5564 
5565    Options Database:
5566 .   -ts_monitor_lg_solution_variables
5567 
5568    Level: intermediate
5569 
5570     Notes: each process in a parallel run displays its component solutions in a separate window
5571 
5572 .keywords: TS,  vector, monitor, view
5573 
5574 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
5575 @*/
5576 PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
5577 {
5578   PetscErrorCode    ierr;
5579   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
5580   const PetscScalar *yy;
5581   PetscInt          dim;
5582   Vec               v;
5583 
5584   PetscFunctionBegin;
5585   if (!step) {
5586     PetscDrawAxis axis;
5587     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
5588     ierr = PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");CHKERRQ(ierr);
5589     if (ctx->names && !ctx->displaynames) {
5590       char      **displaynames;
5591       PetscBool flg;
5592 
5593       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
5594       ierr = PetscMalloc((dim+1)*sizeof(char*),&displaynames);CHKERRQ(ierr);
5595       ierr = PetscMemzero(displaynames,(dim+1)*sizeof(char*));CHKERRQ(ierr);
5596       ierr = PetscOptionsGetStringArray(((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);CHKERRQ(ierr);
5597       if (flg) {
5598         ierr = TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);CHKERRQ(ierr);
5599       }
5600       ierr = PetscStrArrayDestroy(&displaynames);CHKERRQ(ierr);
5601     }
5602     if (ctx->displaynames) {
5603       ierr = PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);CHKERRQ(ierr);
5604       ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);CHKERRQ(ierr);
5605     } else if (ctx->names) {
5606       ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
5607       ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
5608       ierr = PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);CHKERRQ(ierr);
5609     }
5610     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
5611   }
5612   if (ctx->transform) {
5613     ierr = (*ctx->transform)(ctx->transformctx,u,&v);CHKERRQ(ierr);
5614   } else {
5615     v = u;
5616   }
5617   ierr = VecGetArrayRead(v,&yy);CHKERRQ(ierr);
5618 #if defined(PETSC_USE_COMPLEX)
5619   {
5620     PetscReal *yreal;
5621     PetscInt  i,n;
5622     ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
5623     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
5624     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
5625     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
5626     ierr = PetscFree(yreal);CHKERRQ(ierr);
5627   }
5628 #else
5629   if (ctx->displaynames) {
5630     PetscInt i;
5631     for (i=0; i<ctx->ndisplayvariables; i++) {
5632       ctx->displayvalues[i] = yy[ctx->displayvariables[i]];
5633     }
5634     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);CHKERRQ(ierr);
5635   } else {
5636     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
5637   }
5638 #endif
5639   ierr = VecRestoreArrayRead(v,&yy);CHKERRQ(ierr);
5640   if (ctx->transform) {
5641     ierr = VecDestroy(&v);CHKERRQ(ierr);
5642   }
5643   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
5644     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
5645   }
5646   PetscFunctionReturn(0);
5647 }
5648 
5649 
5650 #undef __FUNCT__
5651 #define __FUNCT__ "TSMonitorLGSetVariableNames"
5652 /*@C
5653    TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
5654 
5655    Collective on TS
5656 
5657    Input Parameters:
5658 +  ts - the TS context
5659 -  names - the names of the components, final string must be NULL
5660 
5661    Level: intermediate
5662 
5663 .keywords: TS,  vector, monitor, view
5664 
5665 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames()
5666 @*/
5667 PetscErrorCode  TSMonitorLGSetVariableNames(TS ts,const char * const *names)
5668 {
5669   PetscErrorCode    ierr;
5670   PetscInt          i;
5671 
5672   PetscFunctionBegin;
5673   for (i=0; i<ts->numbermonitors; i++) {
5674     if (ts->monitor[i] == TSMonitorLGSolution) {
5675       ierr = TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);CHKERRQ(ierr);
5676       break;
5677     }
5678   }
5679   PetscFunctionReturn(0);
5680 }
5681 
5682 #undef __FUNCT__
5683 #define __FUNCT__ "TSMonitorLGCtxSetVariableNames"
5684 /*@C
5685    TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot
5686 
5687    Collective on TS
5688 
5689    Input Parameters:
5690 +  ts - the TS context
5691 -  names - the names of the components, final string must be NULL
5692 
5693    Level: intermediate
5694 
5695 .keywords: TS,  vector, monitor, view
5696 
5697 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames()
5698 @*/
5699 PetscErrorCode  TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names)
5700 {
5701   PetscErrorCode    ierr;
5702 
5703   PetscFunctionBegin;
5704   ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr);
5705   ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr);
5706   PetscFunctionReturn(0);
5707 }
5708 
5709 #undef __FUNCT__
5710 #define __FUNCT__ "TSMonitorLGGetVariableNames"
5711 /*@C
5712    TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot
5713 
5714    Collective on TS
5715 
5716    Input Parameter:
5717 .  ts - the TS context
5718 
5719    Output Parameter:
5720 .  names - the names of the components, final string must be NULL
5721 
5722    Level: intermediate
5723 
5724 .keywords: TS,  vector, monitor, view
5725 
5726 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
5727 @*/
5728 PetscErrorCode  TSMonitorLGGetVariableNames(TS ts,const char *const **names)
5729 {
5730   PetscInt       i;
5731 
5732   PetscFunctionBegin;
5733   *names = NULL;
5734   for (i=0; i<ts->numbermonitors; i++) {
5735     if (ts->monitor[i] == TSMonitorLGSolution) {
5736       TSMonitorLGCtx  ctx = (TSMonitorLGCtx) ts->monitorcontext[i];
5737       *names = (const char *const *)ctx->names;
5738       break;
5739     }
5740   }
5741   PetscFunctionReturn(0);
5742 }
5743 
5744 #undef __FUNCT__
5745 #define __FUNCT__ "TSMonitorLGCtxSetDisplayVariables"
5746 /*@C
5747    TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor
5748 
5749    Collective on TS
5750 
5751    Input Parameters:
5752 +  ctx - the TSMonitorLG context
5753 .  displaynames - the names of the components, final string must be NULL
5754 
5755    Level: intermediate
5756 
5757 .keywords: TS,  vector, monitor, view
5758 
5759 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
5760 @*/
5761 PetscErrorCode  TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames)
5762 {
5763   PetscInt          j = 0,k;
5764   PetscErrorCode    ierr;
5765 
5766   PetscFunctionBegin;
5767   if (!ctx->names) PetscFunctionReturn(0);
5768   ierr = PetscStrArrayDestroy(&ctx->displaynames);CHKERRQ(ierr);
5769   ierr = PetscStrArrayallocpy(displaynames,&ctx->displaynames);CHKERRQ(ierr);
5770   while (displaynames[j]) j++;
5771   ctx->ndisplayvariables = j;
5772   ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);CHKERRQ(ierr);
5773   ierr = PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);CHKERRQ(ierr);
5774   j = 0;
5775   while (displaynames[j]) {
5776     k = 0;
5777     while (ctx->names[k]) {
5778       PetscBool flg;
5779       ierr = PetscStrcmp(displaynames[j],ctx->names[k],&flg);CHKERRQ(ierr);
5780       if (flg) {
5781         ctx->displayvariables[j] = k;
5782         break;
5783       }
5784       k++;
5785     }
5786     j++;
5787   }
5788   PetscFunctionReturn(0);
5789 }
5790 
5791 
5792 #undef __FUNCT__
5793 #define __FUNCT__ "TSMonitorLGSetDisplayVariables"
5794 /*@C
5795    TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor
5796 
5797    Collective on TS
5798 
5799    Input Parameters:
5800 +  ts - the TS context
5801 .  displaynames - the names of the components, final string must be NULL
5802 
5803    Level: intermediate
5804 
5805 .keywords: TS,  vector, monitor, view
5806 
5807 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
5808 @*/
5809 PetscErrorCode  TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames)
5810 {
5811   PetscInt          i;
5812   PetscErrorCode    ierr;
5813 
5814   PetscFunctionBegin;
5815   for (i=0; i<ts->numbermonitors; i++) {
5816     if (ts->monitor[i] == TSMonitorLGSolution) {
5817       ierr = TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);CHKERRQ(ierr);
5818       break;
5819     }
5820   }
5821   PetscFunctionReturn(0);
5822 }
5823 
5824 #undef __FUNCT__
5825 #define __FUNCT__ "TSMonitorLGSetTransform"
5826 /*@C
5827    TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed
5828 
5829    Collective on TS
5830 
5831    Input Parameters:
5832 +  ts - the TS context
5833 .  transform - the transform function
5834 .  destroy - function to destroy the optional context
5835 -  ctx - optional context used by transform function
5836 
5837    Level: intermediate
5838 
5839 .keywords: TS,  vector, monitor, view
5840 
5841 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform()
5842 @*/
5843 PetscErrorCode  TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
5844 {
5845   PetscInt          i;
5846   PetscErrorCode    ierr;
5847 
5848   PetscFunctionBegin;
5849   for (i=0; i<ts->numbermonitors; i++) {
5850     if (ts->monitor[i] == TSMonitorLGSolution) {
5851       ierr = TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);CHKERRQ(ierr);
5852     }
5853   }
5854   PetscFunctionReturn(0);
5855 }
5856 
5857 #undef __FUNCT__
5858 #define __FUNCT__ "TSMonitorLGCtxSetTransform"
5859 /*@C
5860    TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed
5861 
5862    Collective on TSLGCtx
5863 
5864    Input Parameters:
5865 +  ts - the TS context
5866 .  transform - the transform function
5867 .  destroy - function to destroy the optional context
5868 -  ctx - optional context used by transform function
5869 
5870    Level: intermediate
5871 
5872 .keywords: TS,  vector, monitor, view
5873 
5874 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform()
5875 @*/
5876 PetscErrorCode  TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
5877 {
5878   PetscFunctionBegin;
5879   ctx->transform    = transform;
5880   ctx->transformdestroy = destroy;
5881   ctx->transformctx = tctx;
5882   PetscFunctionReturn(0);
5883 }
5884 
5885 #undef __FUNCT__
5886 #define __FUNCT__ "TSMonitorLGError"
5887 /*@C
5888    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the solution vector
5889        in a time based line graph
5890 
5891    Collective on TS
5892 
5893    Input Parameters:
5894 +  ts - the TS context
5895 .  step - current time-step
5896 .  ptime - current time
5897 -  lg - a line graph object
5898 
5899    Level: intermediate
5900 
5901    Notes:
5902    Only for sequential solves.
5903 
5904    The user must provide the solution using TSSetSolutionFunction() to use this monitor.
5905 
5906    Options Database Keys:
5907 .  -ts_monitor_lg_error - create a graphical monitor of error history
5908 
5909 .keywords: TS,  vector, monitor, view
5910 
5911 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
5912 @*/
5913 PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
5914 {
5915   PetscErrorCode    ierr;
5916   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
5917   const PetscScalar *yy;
5918   Vec               y;
5919   PetscInt          dim;
5920 
5921   PetscFunctionBegin;
5922   if (!step) {
5923     PetscDrawAxis axis;
5924     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
5925     ierr = PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Solution");CHKERRQ(ierr);
5926     ierr = VecGetLocalSize(u,&dim);CHKERRQ(ierr);
5927     ierr = PetscDrawLGSetDimension(ctx->lg,dim);CHKERRQ(ierr);
5928     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
5929   }
5930   ierr = VecDuplicate(u,&y);CHKERRQ(ierr);
5931   ierr = TSComputeSolutionFunction(ts,ptime,y);CHKERRQ(ierr);
5932   ierr = VecAXPY(y,-1.0,u);CHKERRQ(ierr);
5933   ierr = VecGetArrayRead(y,&yy);CHKERRQ(ierr);
5934 #if defined(PETSC_USE_COMPLEX)
5935   {
5936     PetscReal *yreal;
5937     PetscInt  i,n;
5938     ierr = VecGetLocalSize(y,&n);CHKERRQ(ierr);
5939     ierr = PetscMalloc1(n,&yreal);CHKERRQ(ierr);
5940     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
5941     ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);CHKERRQ(ierr);
5942     ierr = PetscFree(yreal);CHKERRQ(ierr);
5943   }
5944 #else
5945   ierr = PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);CHKERRQ(ierr);
5946 #endif
5947   ierr = VecRestoreArrayRead(y,&yy);CHKERRQ(ierr);
5948   ierr = VecDestroy(&y);CHKERRQ(ierr);
5949   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
5950     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
5951   }
5952   PetscFunctionReturn(0);
5953 }
5954 
5955 #undef __FUNCT__
5956 #define __FUNCT__ "TSMonitorLGSNESIterations"
5957 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
5958 {
5959   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
5960   PetscReal      x   = ptime,y;
5961   PetscErrorCode ierr;
5962   PetscInt       its;
5963 
5964   PetscFunctionBegin;
5965   if (!n) {
5966     PetscDrawAxis axis;
5967 
5968     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
5969     ierr = PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");CHKERRQ(ierr);
5970     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
5971 
5972     ctx->snes_its = 0;
5973   }
5974   ierr = TSGetSNESIterations(ts,&its);CHKERRQ(ierr);
5975   y    = its - ctx->snes_its;
5976   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
5977   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
5978     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
5979   }
5980   ctx->snes_its = its;
5981   PetscFunctionReturn(0);
5982 }
5983 
5984 #undef __FUNCT__
5985 #define __FUNCT__ "TSMonitorLGKSPIterations"
5986 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
5987 {
5988   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
5989   PetscReal      x   = ptime,y;
5990   PetscErrorCode ierr;
5991   PetscInt       its;
5992 
5993   PetscFunctionBegin;
5994   if (!n) {
5995     PetscDrawAxis axis;
5996 
5997     ierr = PetscDrawLGGetAxis(ctx->lg,&axis);CHKERRQ(ierr);
5998     ierr = PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");CHKERRQ(ierr);
5999     ierr = PetscDrawLGReset(ctx->lg);CHKERRQ(ierr);
6000 
6001     ctx->ksp_its = 0;
6002   }
6003   ierr = TSGetKSPIterations(ts,&its);CHKERRQ(ierr);
6004   y    = its - ctx->ksp_its;
6005   ierr = PetscDrawLGAddPoint(ctx->lg,&x,&y);CHKERRQ(ierr);
6006   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
6007     ierr = PetscDrawLGDraw(ctx->lg);CHKERRQ(ierr);
6008   }
6009   ctx->ksp_its = its;
6010   PetscFunctionReturn(0);
6011 }
6012 
6013 #undef __FUNCT__
6014 #define __FUNCT__ "TSComputeLinearStability"
6015 /*@
6016    TSComputeLinearStability - computes the linear stability function at a point
6017 
6018    Collective on TS and Vec
6019 
6020    Input Parameters:
6021 +  ts - the TS context
6022 -  xr,xi - real and imaginary part of input arguments
6023 
6024    Output Parameters:
6025 .  yr,yi - real and imaginary part of function value
6026 
6027    Level: developer
6028 
6029 .keywords: TS, compute
6030 
6031 .seealso: TSSetRHSFunction(), TSComputeIFunction()
6032 @*/
6033 PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi)
6034 {
6035   PetscErrorCode ierr;
6036 
6037   PetscFunctionBegin;
6038   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6039   if (!ts->ops->linearstability) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method");
6040   ierr = (*ts->ops->linearstability)(ts,xr,xi,yr,yi);CHKERRQ(ierr);
6041   PetscFunctionReturn(0);
6042 }
6043 
6044 /* ------------------------------------------------------------------------*/
6045 #undef __FUNCT__
6046 #define __FUNCT__ "TSMonitorEnvelopeCtxCreate"
6047 /*@C
6048    TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope()
6049 
6050    Collective on TS
6051 
6052    Input Parameters:
6053 .  ts  - the ODE solver object
6054 
6055    Output Parameter:
6056 .  ctx - the context
6057 
6058    Level: intermediate
6059 
6060 .keywords: TS, monitor, line graph, residual, seealso
6061 
6062 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError()
6063 
6064 @*/
6065 PetscErrorCode  TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx)
6066 {
6067   PetscErrorCode ierr;
6068 
6069   PetscFunctionBegin;
6070   ierr = PetscNew(ctx);CHKERRQ(ierr);
6071   PetscFunctionReturn(0);
6072 }
6073 
6074 #undef __FUNCT__
6075 #define __FUNCT__ "TSMonitorEnvelope"
6076 /*@C
6077    TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution
6078 
6079    Collective on TS
6080 
6081    Input Parameters:
6082 +  ts - the TS context
6083 .  step - current time-step
6084 .  ptime - current time
6085 -  ctx - the envelope context
6086 
6087    Options Database:
6088 .  -ts_monitor_envelope
6089 
6090    Level: intermediate
6091 
6092    Notes: after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope
6093 
6094 .keywords: TS,  vector, monitor, view
6095 
6096 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds()
6097 @*/
6098 PetscErrorCode  TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
6099 {
6100   PetscErrorCode       ierr;
6101   TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dummy;
6102 
6103   PetscFunctionBegin;
6104   if (!ctx->max) {
6105     ierr = VecDuplicate(u,&ctx->max);CHKERRQ(ierr);
6106     ierr = VecDuplicate(u,&ctx->min);CHKERRQ(ierr);
6107     ierr = VecCopy(u,ctx->max);CHKERRQ(ierr);
6108     ierr = VecCopy(u,ctx->min);CHKERRQ(ierr);
6109   } else {
6110     ierr = VecPointwiseMax(ctx->max,u,ctx->max);CHKERRQ(ierr);
6111     ierr = VecPointwiseMin(ctx->min,u,ctx->min);CHKERRQ(ierr);
6112   }
6113   PetscFunctionReturn(0);
6114 }
6115 
6116 
6117 #undef __FUNCT__
6118 #define __FUNCT__ "TSMonitorEnvelopeGetBounds"
6119 /*@C
6120    TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution
6121 
6122    Collective on TS
6123 
6124    Input Parameter:
6125 .  ts - the TS context
6126 
6127    Output Parameter:
6128 +  max - the maximum values
6129 -  min - the minimum values
6130 
6131    Level: intermediate
6132 
6133 .keywords: TS,  vector, monitor, view
6134 
6135 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
6136 @*/
6137 PetscErrorCode  TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min)
6138 {
6139   PetscInt i;
6140 
6141   PetscFunctionBegin;
6142   if (max) *max = NULL;
6143   if (min) *min = NULL;
6144   for (i=0; i<ts->numbermonitors; i++) {
6145     if (ts->monitor[i] == TSMonitorEnvelope) {
6146       TSMonitorEnvelopeCtx  ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i];
6147       if (max) *max = ctx->max;
6148       if (min) *min = ctx->min;
6149       break;
6150     }
6151   }
6152   PetscFunctionReturn(0);
6153 }
6154 
6155 #undef __FUNCT__
6156 #define __FUNCT__ "TSMonitorEnvelopeCtxDestroy"
6157 /*@C
6158    TSMonitorEnvelopeCtxDestroy - Destroys a context that was created  with TSMonitorEnvelopeCtxCreate().
6159 
6160    Collective on TSMonitorEnvelopeCtx
6161 
6162    Input Parameter:
6163 .  ctx - the monitor context
6164 
6165    Level: intermediate
6166 
6167 .keywords: TS, monitor, line graph, destroy
6168 
6169 .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep();
6170 @*/
6171 PetscErrorCode  TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx)
6172 {
6173   PetscErrorCode ierr;
6174 
6175   PetscFunctionBegin;
6176   ierr = VecDestroy(&(*ctx)->min);CHKERRQ(ierr);
6177   ierr = VecDestroy(&(*ctx)->max);CHKERRQ(ierr);
6178   ierr = PetscFree(*ctx);CHKERRQ(ierr);
6179   PetscFunctionReturn(0);
6180 }
6181 
6182 #undef __FUNCT__
6183 #define __FUNCT__ "TSRollBack"
6184 /*@
6185    TSRollBack - Rolls back one time step
6186 
6187    Collective on TS
6188 
6189    Input Parameter:
6190 .  ts - the TS context obtained from TSCreate()
6191 
6192    Level: advanced
6193 
6194 .keywords: TS, timestep, rollback
6195 
6196 .seealso: TSCreate(), TSSetUp(), TSDestroy(), TSSolve(), TSSetPreStep(), TSSetPreStage(), TSInterpolate()
6197 @*/
6198 PetscErrorCode  TSRollBack(TS ts)
6199 {
6200   PetscErrorCode ierr;
6201 
6202   PetscFunctionBegin;
6203   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
6204 
6205   if (!ts->ops->rollback) SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name);
6206   ierr = (*ts->ops->rollback)(ts);CHKERRQ(ierr);
6207   ts->time_step = ts->ptime - ts->ptime_prev;
6208   ts->ptime = ts->ptime_prev;
6209   ts->steprollback = PETSC_TRUE; /* Flag to indicate that the step is rollbacked */
6210   PetscFunctionReturn(0);
6211 }
6212 
6213 #undef __FUNCT__
6214 #define __FUNCT__ "TSGetStages"
6215 /*@
6216    TSGetStages - Get the number of stages and stage values
6217 
6218    Input Parameter:
6219 .  ts - the TS context obtained from TSCreate()
6220 
6221    Level: advanced
6222 
6223 .keywords: TS, getstages
6224 
6225 .seealso: TSCreate()
6226 @*/
6227 PetscErrorCode  TSGetStages(TS ts,PetscInt *ns, Vec **Y)
6228 {
6229   PetscErrorCode ierr;
6230 
6231   PetscFunctionBegin;
6232   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
6233   PetscValidPointer(ns,2);
6234 
6235   if (!ts->ops->getstages) *ns=0;
6236   else {
6237     ierr = (*ts->ops->getstages)(ts,ns,Y);CHKERRQ(ierr);
6238   }
6239   PetscFunctionReturn(0);
6240 }
6241 
6242 #undef __FUNCT__
6243 #define __FUNCT__ "TSComputeIJacobianDefaultColor"
6244 /*@C
6245   TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity.
6246 
6247   Collective on SNES
6248 
6249   Input Parameters:
6250 + ts - the TS context
6251 . t - current timestep
6252 . U - state vector
6253 . Udot - time derivative of state vector
6254 . shift - shift to apply, see note below
6255 - ctx - an optional user context
6256 
6257   Output Parameters:
6258 + J - Jacobian matrix (not altered in this routine)
6259 - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J)
6260 
6261   Level: intermediate
6262 
6263   Notes:
6264   If F(t,U,Udot)=0 is the DAE, the required Jacobian is
6265 
6266   dF/dU + shift*dF/dUdot
6267 
6268   Most users should not need to explicitly call this routine, as it
6269   is used internally within the nonlinear solvers.
6270 
6271   This will first try to get the coloring from the DM.  If the DM type has no coloring
6272   routine, then it will try to get the coloring from the matrix.  This requires that the
6273   matrix have nonzero entries precomputed.
6274 
6275 .keywords: TS, finite differences, Jacobian, coloring, sparse
6276 .seealso: TSSetIJacobian(), MatFDColoringCreate(), MatFDColoringSetFunction()
6277 @*/
6278 PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx)
6279 {
6280   SNES           snes;
6281   MatFDColoring  color;
6282   PetscBool      hascolor, matcolor = PETSC_FALSE;
6283   PetscErrorCode ierr;
6284 
6285   PetscFunctionBegin;
6286   ierr = PetscOptionsGetBool(((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL);CHKERRQ(ierr);
6287   ierr = PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color);CHKERRQ(ierr);
6288   if (!color) {
6289     DM         dm;
6290     ISColoring iscoloring;
6291 
6292     ierr = TSGetDM(ts, &dm);CHKERRQ(ierr);
6293     ierr = DMHasColoring(dm, &hascolor);CHKERRQ(ierr);
6294     if (hascolor && !matcolor) {
6295       ierr = DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring);CHKERRQ(ierr);
6296       ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr);
6297       ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr);
6298       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
6299       ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr);
6300       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
6301     } else {
6302       MatColoring mc;
6303 
6304       ierr = MatColoringCreate(B, &mc);CHKERRQ(ierr);
6305       ierr = MatColoringSetDistance(mc, 2);CHKERRQ(ierr);
6306       ierr = MatColoringSetType(mc, MATCOLORINGSL);CHKERRQ(ierr);
6307       ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr);
6308       ierr = MatColoringApply(mc, &iscoloring);CHKERRQ(ierr);
6309       ierr = MatColoringDestroy(&mc);CHKERRQ(ierr);
6310       ierr = MatFDColoringCreate(B, iscoloring, &color);CHKERRQ(ierr);
6311       ierr = MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts);CHKERRQ(ierr);
6312       ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr);
6313       ierr = MatFDColoringSetUp(B, iscoloring, color);CHKERRQ(ierr);
6314       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
6315     }
6316     ierr = PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color);CHKERRQ(ierr);
6317     ierr = PetscObjectDereference((PetscObject) color);CHKERRQ(ierr);
6318   }
6319   ierr = TSGetSNES(ts, &snes);CHKERRQ(ierr);
6320   ierr = MatFDColoringApply(B, color, U, snes);CHKERRQ(ierr);
6321   if (J != B) {
6322     ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
6323     ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
6324   }
6325   PetscFunctionReturn(0);
6326 }
6327 
6328 #undef  __FUNCT__
6329 #define __FUNCT__ "TSClone"
6330 /*@C
6331   TSClone - This function clones a time step object.
6332 
6333   Collective on MPI_Comm
6334 
6335   Input Parameter:
6336 . tsin    - The input TS
6337 
6338   Output Parameter:
6339 . tsout   - The output TS (cloned)
6340 
6341   Notes:
6342   This function is used to create a clone of a TS object. It is used in ARKIMEX for initializing the slope for first stage explicit methods. It will likely be replaced in the future with a mechanism of switching methods on the fly.
6343 
6344   When using TSDestroy() on a clone the user has to first reset the correct TS reference in the embedded SNES object: e.g.: by running SNES snes_dup=NULL; TSGetSNES(ts,&snes_dup); ierr = TSSetSNES(ts,snes_dup);
6345 
6346   Level: developer
6347 
6348 .keywords: TS, clone
6349 .seealso: TSCreate(), TSSetType(), TSSetUp(), TSDestroy(), TSSetProblemType()
6350 @*/
6351 PetscErrorCode  TSClone(TS tsin, TS *tsout)
6352 {
6353   TS             t;
6354   PetscErrorCode ierr;
6355   SNES           snes_start;
6356   DM             dm;
6357   TSType         type;
6358 
6359   PetscFunctionBegin;
6360   PetscValidPointer(tsin,1);
6361   *tsout = NULL;
6362 
6363   ierr = PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView);CHKERRQ(ierr);
6364 
6365   /* General TS description */
6366   t->numbermonitors    = 0;
6367   t->setupcalled       = 0;
6368   t->ksp_its           = 0;
6369   t->snes_its          = 0;
6370   t->nwork             = 0;
6371   t->rhsjacobian.time  = -1e20;
6372   t->rhsjacobian.scale = 1.;
6373   t->ijacobian.shift   = 1.;
6374 
6375   ierr = TSGetSNES(tsin,&snes_start);                   CHKERRQ(ierr);
6376   ierr = TSSetSNES(t,snes_start);                       CHKERRQ(ierr);
6377 
6378   ierr = TSGetDM(tsin,&dm);                             CHKERRQ(ierr);
6379   ierr = TSSetDM(t,dm);                                 CHKERRQ(ierr);
6380 
6381   t->adapt=tsin->adapt;
6382   PetscObjectReference((PetscObject)t->adapt);
6383 
6384   t->problem_type      = tsin->problem_type;
6385   t->ptime             = tsin->ptime;
6386   t->time_step         = tsin->time_step;
6387   t->time_step_orig    = tsin->time_step_orig;
6388   t->max_time          = tsin->max_time;
6389   t->steps             = tsin->steps;
6390   t->max_steps         = tsin->max_steps;
6391   t->equation_type     = tsin->equation_type;
6392   t->atol              = tsin->atol;
6393   t->rtol              = tsin->rtol;
6394   t->max_snes_failures = tsin->max_snes_failures;
6395   t->max_reject        = tsin->max_reject;
6396   t->errorifstepfailed = tsin->errorifstepfailed;
6397 
6398   ierr = TSGetType(tsin,&type); CHKERRQ(ierr);
6399   ierr = TSSetType(t,type);     CHKERRQ(ierr);
6400 
6401   t->vec_sol           = NULL;
6402 
6403   t->cfltime          = tsin->cfltime;
6404   t->cfltime_local    = tsin->cfltime_local;
6405   t->exact_final_time = tsin->exact_final_time;
6406 
6407   ierr = PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps));CHKERRQ(ierr);
6408 
6409   *tsout = t;
6410   PetscFunctionReturn(0);
6411 }
6412