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