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