xref: /petsc/src/ts/trajectory/interface/traj.c (revision b1e111eb0d8a8c8f79792012adb4e9519947d865)
1 #include <petsc/private/tsimpl.h>        /*I "petscts.h"  I*/
2 #include <petsc/private/tshistoryimpl.h>
3 #include <petscdm.h>
4 
5 PetscFunctionList TSTrajectoryList              = NULL;
6 PetscBool         TSTrajectoryRegisterAllCalled = PETSC_FALSE;
7 PetscClassId      TSTRAJECTORY_CLASSID;
8 PetscLogEvent     TSTrajectory_Set, TSTrajectory_Get, TSTrajectory_GetVecs;
9 
10 /*@C
11   TSTrajectoryRegister - Adds a way of storing trajectories to the TS package
12 
13   Not Collective
14 
15   Input Parameters:
16 + name        - the name of a new user-defined creation routine
17 - create_func - the creation routine itself
18 
19   Notes:
20   TSTrajectoryRegister() may be called multiple times to add several user-defined tses.
21 
22   Level: developer
23 
24 .keywords: TS, trajectory, timestep, register
25 
26 .seealso: TSTrajectoryRegisterAll()
27 @*/
28 PetscErrorCode TSTrajectoryRegister(const char sname[],PetscErrorCode (*function)(TSTrajectory,TS))
29 {
30   PetscErrorCode ierr;
31 
32   PetscFunctionBegin;
33   ierr = PetscFunctionListAdd(&TSTrajectoryList,sname,function);CHKERRQ(ierr);
34   PetscFunctionReturn(0);
35 }
36 
37 /*@
38   TSTrajectorySet - Sets a vector of state in the trajectory object
39 
40   Collective on TSTrajectory
41 
42   Input Parameters:
43 + tj      - the trajectory object
44 . ts      - the time stepper object (optional)
45 . stepnum - the step number
46 . time    - the current time
47 - X       - the current solution
48 
49   Level: developer
50 
51   Notes: Usually one does not call this routine, it is called automatically during TSSolve()
52 
53 .keywords: TS, trajectory, create
54 
55 .seealso: TSTrajectorySetUp(), TSTrajectoryDestroy(), TSTrajectorySetType(), TSTrajectorySetVariableNames(), TSGetTrajectory(), TSTrajectoryGet(), TSTrajectoryGetVecs()
56 @*/
57 PetscErrorCode TSTrajectorySet(TSTrajectory tj,TS ts,PetscInt stepnum,PetscReal time,Vec X)
58 {
59   PetscErrorCode ierr;
60 
61   PetscFunctionBegin;
62   if (!tj) PetscFunctionReturn(0);
63   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
64   if (ts) PetscValidHeaderSpecific(ts,TS_CLASSID,2);
65   PetscValidLogicalCollectiveInt(tj,stepnum,3);
66   PetscValidLogicalCollectiveReal(tj,time,4);
67   PetscValidHeaderSpecific(X,VEC_CLASSID,5);
68   if (!tj->ops->set) SETERRQ1(PetscObjectComm((PetscObject)tj),PETSC_ERR_SUP,"TSTrajectory type %s",((PetscObject)tj)->type_name);
69   if (!tj->setupcalled) SETERRQ(PetscObjectComm((PetscObject)tj),PETSC_ERR_ORDER,"TSTrajectorySetUp should be called first");
70   if (tj->monitor) {
71     ierr = PetscViewerASCIIPrintf(tj->monitor,"TSTrajectorySet: stepnum %D, time %g (stages %D)\n",stepnum,(double)time,(PetscInt)!tj->solution_only);CHKERRQ(ierr);
72   }
73   ierr = PetscLogEventBegin(TSTrajectory_Set,tj,ts,0,0);CHKERRQ(ierr);
74   ierr = (*tj->ops->set)(tj,ts,stepnum,time,X);CHKERRQ(ierr);
75   ierr = PetscLogEventEnd(TSTrajectory_Set,tj,ts,0,0);CHKERRQ(ierr);
76   if (tj->usehistory) {
77     ierr = TSHistoryUpdate(tj->tsh,stepnum,time);CHKERRQ(ierr);
78   }
79   if (tj->lag.caching) tj->lag.Udotcached.time = PETSC_MIN_REAL;
80   PetscFunctionReturn(0);
81 }
82 
83 /*@
84   TSTrajectoryGetNumSteps - Return the number of steps registered in the TSTrajectory via TSTrajectorySet().
85 
86   Not collective.
87 
88   Input Parameters:
89 . tj - the trajectory object
90 
91   Output Parameter:
92 . steps - the number of steps
93 
94   Level: developer
95 
96 .keywords: TS, trajectory, create
97 
98 .seealso: TSTrajectorySet()
99 @*/
100 PetscErrorCode TSTrajectoryGetNumSteps(TSTrajectory tj, PetscInt *steps)
101 {
102   PetscErrorCode ierr;
103 
104   PetscFunctionBegin;
105   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
106   PetscValidIntPointer(steps,2);
107   ierr = TSHistoryGetNumSteps(tj->tsh,steps);CHKERRQ(ierr);
108   PetscFunctionReturn(0);
109 }
110 
111 /*@
112   TSTrajectoryGet - Updates the solution vector of a time stepper object by inquiring the TSTrajectory
113 
114   Collective on TS
115 
116   Input Parameters:
117 + tj      - the trajectory object
118 . ts      - the time stepper object
119 - stepnum - the step number
120 
121   Output Parameter:
122 . time    - the time associated with the step number
123 
124   Level: developer
125 
126   Notes: Usually one does not call this routine, it is called automatically during TSSolve()
127 
128 .keywords: TS, trajectory, create
129 
130 .seealso: TSTrajectorySetUp(), TSTrajectoryDestroy(), TSTrajectorySetType(), TSTrajectorySetVariableNames(), TSGetTrajectory(), TSTrajectorySet(), TSTrajectoryGetVecs(), TSGetSolution()
131 @*/
132 PetscErrorCode TSTrajectoryGet(TSTrajectory tj,TS ts,PetscInt stepnum,PetscReal *time)
133 {
134   PetscErrorCode ierr;
135 
136   PetscFunctionBegin;
137   if (!tj) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TS solver did not save trajectory");
138   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
139   PetscValidHeaderSpecific(ts,TS_CLASSID,2);
140   PetscValidLogicalCollectiveInt(tj,stepnum,3);
141   PetscValidPointer(time,4);
142   if (!tj->ops->get) SETERRQ1(PetscObjectComm((PetscObject)tj),PETSC_ERR_SUP,"TSTrajectory type %s",((PetscObject)tj)->type_name);
143   if (!tj->setupcalled) SETERRQ(PetscObjectComm((PetscObject)tj),PETSC_ERR_ORDER,"TSTrajectorySetUp should be called first");
144   if (stepnum < 0) SETERRQ(PetscObjectComm((PetscObject)tj),PETSC_ERR_PLIB,"Requesting negative step number");
145   if (tj->monitor) {
146     ierr = PetscViewerASCIIPrintf(tj->monitor,"TSTrajectoryGet: stepnum %D, stages %D\n",stepnum,(PetscInt)!tj->solution_only);CHKERRQ(ierr);
147     ierr = PetscViewerFlush(tj->monitor);CHKERRQ(ierr);
148   }
149   ierr = PetscLogEventBegin(TSTrajectory_Get,tj,ts,0,0);CHKERRQ(ierr);
150   ierr = (*tj->ops->get)(tj,ts,stepnum,time);CHKERRQ(ierr);
151   ierr = PetscLogEventEnd(TSTrajectory_Get,tj,ts,0,0);CHKERRQ(ierr);
152   PetscFunctionReturn(0);
153 }
154 
155 /*@
156   TSTrajectoryGetVecs - Reconstructs the vector of state and its time derivative using information from the TSTrajectory and, possibly, from the TS
157 
158   Collective on TS
159 
160   Input Parameters:
161 + tj      - the trajectory object
162 . ts      - the time stepper object (optional)
163 - stepnum - the requested step number
164 
165   Input/Output Parameters:
166 . time - the time associated with the step number
167 
168   Output Parameters:
169 + U       - state vector (can be NULL)
170 - Udot    - time derivative of state vector (can be NULL)
171 
172   Level: developer
173 
174   Notes: If the step number is PETSC_DECIDE, the time argument is used to inquire the trajectory.
175          If the requested time does not match any in the trajectory, Lagrangian interpolations are returned.
176 
177 .keywords: TS, trajectory, create
178 
179 .seealso: TSTrajectorySetUp(), TSTrajectoryDestroy(), TSTrajectorySetType(), TSTrajectorySetVariableNames(), TSGetTrajectory(), TSTrajectorySet(), TSTrajectoryGet()
180 @*/
181 PetscErrorCode TSTrajectoryGetVecs(TSTrajectory tj,TS ts,PetscInt stepnum,PetscReal *time,Vec U,Vec Udot)
182 {
183   PetscErrorCode ierr;
184 
185   PetscFunctionBegin;
186   if (!tj) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TS solver did not save trajectory");
187   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
188   if (ts) PetscValidHeaderSpecific(ts,TS_CLASSID,2);
189   PetscValidLogicalCollectiveInt(tj,stepnum,3);
190   PetscValidPointer(time,4);
191   if (U) PetscValidHeaderSpecific(U,VEC_CLASSID,5);
192   if (Udot) PetscValidHeaderSpecific(Udot,VEC_CLASSID,6);
193   if (!U && !Udot) PetscFunctionReturn(0);
194   if (!tj->setupcalled) SETERRQ(PetscObjectComm((PetscObject)tj),PETSC_ERR_ORDER,"TSTrajectorySetUp should be called first");
195   ierr = PetscLogEventBegin(TSTrajectory_GetVecs,tj,ts,0,0);CHKERRQ(ierr);
196   if (tj->monitor) {
197     PetscInt pU,pUdot;
198     pU    = U ? 1 : 0;
199     pUdot = Udot ? 1 : 0;
200     ierr  = PetscViewerASCIIPrintf(tj->monitor,"Requested by GetVecs %D %D: stepnum %D, time %g\n",pU,pUdot,stepnum,(double)*time);CHKERRQ(ierr);
201     ierr = PetscViewerFlush(tj->monitor);CHKERRQ(ierr);
202   }
203   if (U && tj->lag.caching) {
204     PetscObjectId    id;
205     PetscObjectState state;
206 
207     ierr = PetscObjectStateGet((PetscObject)U,&state);CHKERRQ(ierr);
208     ierr = PetscObjectGetId((PetscObject)U,&id);CHKERRQ(ierr);
209     if (stepnum == PETSC_DECIDE) {
210       if (id == tj->lag.Ucached.id && *time == tj->lag.Ucached.time && state == tj->lag.Ucached.state) U = NULL;
211     } else {
212       if (id == tj->lag.Ucached.id && stepnum == tj->lag.Ucached.step && state == tj->lag.Ucached.state) U = NULL;
213     }
214     if (tj->monitor && !U) {
215       ierr = PetscViewerASCIIPushTab(tj->monitor);CHKERRQ(ierr);
216       ierr = PetscViewerASCIIPrintf(tj->monitor,"State vector cached\n");CHKERRQ(ierr);
217       ierr = PetscViewerASCIIPopTab(tj->monitor);CHKERRQ(ierr);
218       ierr = PetscViewerFlush(tj->monitor);CHKERRQ(ierr);
219     }
220   }
221   if (Udot && tj->lag.caching) {
222     PetscObjectId    id;
223     PetscObjectState state;
224 
225     ierr = PetscObjectStateGet((PetscObject)Udot,&state);CHKERRQ(ierr);
226     ierr = PetscObjectGetId((PetscObject)Udot,&id);CHKERRQ(ierr);
227     if (stepnum == PETSC_DECIDE) {
228       if (id == tj->lag.Udotcached.id && *time == tj->lag.Udotcached.time && state == tj->lag.Udotcached.state) Udot = NULL;
229     } else {
230       if (id == tj->lag.Udotcached.id && stepnum == tj->lag.Udotcached.step && state == tj->lag.Udotcached.state) Udot = NULL;
231     }
232     if (tj->monitor && !Udot) {
233       ierr = PetscViewerASCIIPushTab(tj->monitor);CHKERRQ(ierr);
234       ierr = PetscViewerASCIIPrintf(tj->monitor,"Derivative vector cached\n");CHKERRQ(ierr);
235       ierr = PetscViewerASCIIPopTab(tj->monitor);CHKERRQ(ierr);
236       ierr = PetscViewerFlush(tj->monitor);CHKERRQ(ierr);
237     }
238   }
239   if (!U && !Udot) {
240     ierr = PetscLogEventEnd(TSTrajectory_GetVecs,tj,ts,0,0);CHKERRQ(ierr);
241     PetscFunctionReturn(0);
242   }
243 
244   if (stepnum == PETSC_DECIDE || Udot) { /* reverse search for requested time in TSHistory */
245     if (tj->monitor) {
246       ierr = PetscViewerASCIIPushTab(tj->monitor);CHKERRQ(ierr);
247     }
248     /* cached states will be updated in the function */
249     ierr = TSTrajectoryReconstruct_Private(tj,ts,*time,U,Udot);CHKERRQ(ierr);
250     if (tj->monitor) {
251       ierr = PetscViewerASCIIPopTab(tj->monitor);CHKERRQ(ierr);
252       ierr = PetscViewerFlush(tj->monitor);CHKERRQ(ierr);
253     }
254   } else if (U) { /* we were asked to load from stepnum, use TSTrajectoryGet */
255     TS  fakets = ts;
256     Vec U2;
257 
258     /* use a fake TS if ts is missing */
259     if (!ts) {
260       ierr = PetscObjectQuery((PetscObject)tj,"__fake_ts",(PetscObject*)&fakets);CHKERRQ(ierr);
261       if (!fakets) {
262         ierr = TSCreate(PetscObjectComm((PetscObject)tj),&fakets);CHKERRQ(ierr);
263         ierr = PetscObjectCompose((PetscObject)tj,"__fake_ts",(PetscObject)fakets);CHKERRQ(ierr);
264         ierr = PetscObjectDereference((PetscObject)fakets);CHKERRQ(ierr);
265         ierr = VecDuplicate(U,&U2);CHKERRQ(ierr);
266         ierr = TSSetSolution(fakets,U2);CHKERRQ(ierr);
267         ierr = PetscObjectDereference((PetscObject)U2);CHKERRQ(ierr);
268       }
269     }
270     ierr = TSTrajectoryGet(tj,fakets,stepnum,time);CHKERRQ(ierr);
271     ierr = TSGetSolution(fakets,&U2);CHKERRQ(ierr);
272     ierr = VecCopy(U2,U);CHKERRQ(ierr);
273     ierr = PetscObjectStateGet((PetscObject)U,&tj->lag.Ucached.state);CHKERRQ(ierr);
274     ierr = PetscObjectGetId((PetscObject)U,&tj->lag.Ucached.id);CHKERRQ(ierr);
275     tj->lag.Ucached.time = *time;
276     tj->lag.Ucached.step = stepnum;
277   }
278   ierr = PetscLogEventEnd(TSTrajectory_GetVecs,tj,ts,0,0);CHKERRQ(ierr);
279   PetscFunctionReturn(0);
280 }
281 
282 /*@C
283     TSTrajectoryView - Prints information about the trajectory object
284 
285     Collective on TSTrajectory
286 
287     Input Parameters:
288 +   tj - the TSTrajectory context obtained from TSTrajectoryCreate()
289 -   viewer - visualization context
290 
291     Options Database Key:
292 .   -ts_trajectory_view - calls TSTrajectoryView() at end of TSAdjointStep()
293 
294     Notes:
295     The available visualization contexts include
296 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
297 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
298          output where only the first processor opens
299          the file.  All other processors send their
300          data to the first processor to print.
301 
302     The user can open an alternative visualization context with
303     PetscViewerASCIIOpen() - output to a specified file.
304 
305     Level: developer
306 
307 .keywords: TS, trajectory, timestep, view
308 
309 .seealso: PetscViewerASCIIOpen()
310 @*/
311 PetscErrorCode  TSTrajectoryView(TSTrajectory tj,PetscViewer viewer)
312 {
313   PetscErrorCode ierr;
314   PetscBool      iascii;
315 
316   PetscFunctionBegin;
317   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
318   if (!viewer) {
319     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)tj),&viewer);CHKERRQ(ierr);
320   }
321   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
322   PetscCheckSameComm(tj,1,viewer,2);
323 
324   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
325   if (iascii) {
326     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)tj,viewer);CHKERRQ(ierr);
327     ierr = PetscViewerASCIIPrintf(viewer,"  total number of recomputations for adjoint calculation = %D\n",tj->recomps);CHKERRQ(ierr);
328     ierr = PetscViewerASCIIPrintf(viewer,"  disk checkpoint reads = %D\n",tj->diskreads);CHKERRQ(ierr);
329     ierr = PetscViewerASCIIPrintf(viewer,"  disk checkpoint writes = %D\n",tj->diskwrites);CHKERRQ(ierr);
330     if (tj->ops->view) {
331       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
332       ierr = (*tj->ops->view)(tj,viewer);CHKERRQ(ierr);
333       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
334     }
335   }
336   PetscFunctionReturn(0);
337 }
338 
339 /*@C
340    TSTrajectorySetVariableNames - Sets the name of each component in the solution vector so that it may be saved with the trajectory
341 
342    Collective on TSTrajectory
343 
344    Input Parameters:
345 +  tr - the trajectory context
346 -  names - the names of the components, final string must be NULL
347 
348    Level: intermediate
349 
350    Note: Fortran interface is not possible because of the string array argument
351 
352 .keywords: TS, TSTrajectory, vector, monitor, view
353 
354 .seealso: TSTrajectory, TSGetTrajectory()
355 @*/
356 PetscErrorCode  TSTrajectorySetVariableNames(TSTrajectory ctx,const char * const *names)
357 {
358   PetscErrorCode    ierr;
359 
360   PetscFunctionBegin;
361   PetscValidHeaderSpecific(ctx,TSTRAJECTORY_CLASSID,1);
362   PetscValidPointer(names,2);
363   ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr);
364   ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr);
365   PetscFunctionReturn(0);
366 }
367 
368 /*@C
369    TSTrajectorySetTransform - Solution vector will be transformed by provided function before being saved to disk
370 
371    Collective on TSLGCtx
372 
373    Input Parameters:
374 +  tj - the TSTrajectory context
375 .  transform - the transform function
376 .  destroy - function to destroy the optional context
377 -  ctx - optional context used by transform function
378 
379    Level: intermediate
380 
381 .keywords: TSTrajectory,  vector, monitor, view
382 
383 .seealso:  TSTrajectorySetVariableNames(), TSTrajectory, TSMonitorLGSetTransform()
384 @*/
385 PetscErrorCode  TSTrajectorySetTransform(TSTrajectory tj,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
386 {
387   PetscFunctionBegin;
388   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
389   tj->transform        = transform;
390   tj->transformdestroy = destroy;
391   tj->transformctx     = tctx;
392   PetscFunctionReturn(0);
393 }
394 
395 /*@
396   TSTrajectoryCreate - This function creates an empty trajectory object used to store the time dependent solution of an ODE/DAE
397 
398   Collective on MPI_Comm
399 
400   Input Parameter:
401 . comm - the communicator
402 
403   Output Parameter:
404 . tj   - the trajectory object
405 
406   Level: developer
407 
408   Notes:
409     Usually one does not call this routine, it is called automatically when one calls TSSetSaveTrajectory().
410 
411 .keywords: TS, trajectory, create
412 
413 .seealso: TSTrajectorySetUp(), TSTrajectoryDestroy(), TSTrajectorySetType(), TSTrajectorySetVariableNames(), TSGetTrajectory(), TSTrajectorySetKeepFiles()
414 @*/
415 PetscErrorCode  TSTrajectoryCreate(MPI_Comm comm,TSTrajectory *tj)
416 {
417   TSTrajectory   t;
418   PetscErrorCode ierr;
419 
420   PetscFunctionBegin;
421   PetscValidPointer(tj,2);
422   *tj = NULL;
423   ierr = TSInitializePackage();CHKERRQ(ierr);
424 
425   ierr = PetscHeaderCreate(t,TSTRAJECTORY_CLASSID,"TSTrajectory","Time stepping","TS",comm,TSTrajectoryDestroy,TSTrajectoryView);CHKERRQ(ierr);
426   t->setupcalled = PETSC_FALSE;
427   ierr = TSHistoryCreate(comm,&t->tsh);CHKERRQ(ierr);
428 
429   t->lag.order            = 1;
430   t->lag.L                = NULL;
431   t->lag.T                = NULL;
432   t->lag.W                = NULL;
433   t->lag.WW               = NULL;
434   t->lag.TW               = NULL;
435   t->lag.TT               = NULL;
436   t->lag.caching          = PETSC_TRUE;
437   t->lag.Ucached.id       = 0;
438   t->lag.Ucached.state    = -1;
439   t->lag.Ucached.time     = PETSC_MIN_REAL;
440   t->lag.Ucached.step     = PETSC_MAX_INT;
441   t->lag.Udotcached.id    = 0;
442   t->lag.Udotcached.state = -1;
443   t->lag.Udotcached.time  = PETSC_MIN_REAL;
444   t->lag.Udotcached.step  = PETSC_MAX_INT;
445   t->adjoint_solve_mode   = PETSC_TRUE;
446   t->solution_only        = PETSC_FALSE;
447   t->keepfiles            = PETSC_FALSE;
448   t->usehistory           = PETSC_TRUE;
449   *tj  = t;
450   ierr = TSTrajectorySetDirname(t,"SA-data");CHKERRQ(ierr);
451   ierr = TSTrajectorySetFiletemplate(t,"SA-%06D.bin");CHKERRQ(ierr);
452   PetscFunctionReturn(0);
453 }
454 
455 /*@C
456   TSTrajectorySetType - Sets the storage method to be used as in a trajectory
457 
458   Collective on TS
459 
460   Input Parameters:
461 + tj   - the TSTrajectory context
462 . ts   - the TS context
463 - type - a known method
464 
465   Options Database Command:
466 . -ts_trajectory_type <type> - Sets the method; use -help for a list of available methods (for instance, basic)
467 
468    Level: developer
469 
470 .keywords: TS, trajectory, timestep, set, type
471 
472 .seealso: TS, TSTrajectoryCreate(), TSTrajectorySetFromOptions(), TSTrajectoryDestroy(), TSTrajectoryGetType()
473 
474 @*/
475 PetscErrorCode  TSTrajectorySetType(TSTrajectory tj,TS ts,TSTrajectoryType type)
476 {
477   PetscErrorCode (*r)(TSTrajectory,TS);
478   PetscBool      match;
479   PetscErrorCode ierr;
480 
481   PetscFunctionBegin;
482   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
483   ierr = PetscObjectTypeCompare((PetscObject)tj,type,&match);CHKERRQ(ierr);
484   if (match) PetscFunctionReturn(0);
485 
486   ierr = PetscFunctionListFind(TSTrajectoryList,type,&r);CHKERRQ(ierr);
487   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown TSTrajectory type: %s",type);
488   if (tj->ops->destroy) {
489     ierr = (*(tj)->ops->destroy)(tj);CHKERRQ(ierr);
490 
491     tj->ops->destroy = NULL;
492   }
493   ierr = PetscMemzero(tj->ops,sizeof(*tj->ops));CHKERRQ(ierr);
494 
495   ierr = PetscObjectChangeTypeName((PetscObject)tj,type);CHKERRQ(ierr);
496   ierr = (*r)(tj,ts);CHKERRQ(ierr);
497   PetscFunctionReturn(0);
498 }
499 
500 /*@C
501   TSTrajectoryGetType - Gets the trajectory type
502 
503   Collective on TS
504 
505   Input Parameters:
506 + tj   - the TSTrajectory context
507 - ts   - the TS context
508 
509   Output Parameters:
510 . type - a known method
511 
512   Level: developer
513 
514 .keywords: TS, trajectory, timestep, get, type
515 
516 .seealso: TS, TSTrajectoryCreate(), TSTrajectorySetFromOptions(), TSTrajectoryDestroy(), TSTrajectorySetType()
517 
518 @*/
519 PetscErrorCode TSTrajectoryGetType(TSTrajectory tj,TS ts,TSTrajectoryType *type)
520 {
521   PetscFunctionBegin;
522   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
523   if (type) *type = ((PetscObject)tj)->type_name;
524   PetscFunctionReturn(0);
525 }
526 
527 PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Basic(TSTrajectory,TS);
528 PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Singlefile(TSTrajectory,TS);
529 PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Memory(TSTrajectory,TS);
530 PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Visualization(TSTrajectory,TS);
531 
532 /*@C
533   TSTrajectoryRegisterAll - Registers all of the trajectory storage schecmes in the TS package.
534 
535   Not Collective
536 
537   Level: developer
538 
539 .keywords: TS, trajectory, register, all
540 
541 .seealso: TSTrajectoryRegister()
542 @*/
543 PetscErrorCode  TSTrajectoryRegisterAll(void)
544 {
545   PetscErrorCode ierr;
546 
547   PetscFunctionBegin;
548   if (TSTrajectoryRegisterAllCalled) PetscFunctionReturn(0);
549   TSTrajectoryRegisterAllCalled = PETSC_TRUE;
550 
551   ierr = TSTrajectoryRegister(TSTRAJECTORYBASIC,TSTrajectoryCreate_Basic);CHKERRQ(ierr);
552   ierr = TSTrajectoryRegister(TSTRAJECTORYSINGLEFILE,TSTrajectoryCreate_Singlefile);CHKERRQ(ierr);
553   ierr = TSTrajectoryRegister(TSTRAJECTORYMEMORY,TSTrajectoryCreate_Memory);CHKERRQ(ierr);
554   ierr = TSTrajectoryRegister(TSTRAJECTORYVISUALIZATION,TSTrajectoryCreate_Visualization);CHKERRQ(ierr);
555   PetscFunctionReturn(0);
556 }
557 
558 /*@
559    TSTrajectoryReset - Resets a trajectory context
560 
561    Collective on TSTrajectory
562 
563    Input Parameter:
564 .  tj - the TSTrajectory context obtained from TSTrajectoryCreate()
565 
566    Level: developer
567 
568 .keywords: TS, trajectory, timestep, reset
569 
570 .seealso: TSTrajectoryCreate(), TSTrajectorySetUp()
571 @*/
572 PetscErrorCode TSTrajectoryReset(TSTrajectory tj)
573 {
574   PetscErrorCode ierr;
575 
576   PetscFunctionBegin;
577   if (!tj) PetscFunctionReturn(0);
578   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
579   if (tj->ops->reset) {
580     ierr = (*tj->ops->reset)(tj);CHKERRQ(ierr);
581   }
582   ierr = PetscFree(tj->dirfiletemplate);CHKERRQ(ierr);
583   ierr = TSHistoryDestroy(&tj->tsh);CHKERRQ(ierr);
584   ierr = TSHistoryCreate(PetscObjectComm((PetscObject)tj),&tj->tsh);CHKERRQ(ierr);
585   tj->setupcalled = PETSC_FALSE;
586   PetscFunctionReturn(0);
587 }
588 
589 /*@
590    TSTrajectoryDestroy - Destroys a trajectory context
591 
592    Collective on TSTrajectory
593 
594    Input Parameter:
595 .  tj - the TSTrajectory context obtained from TSTrajectoryCreate()
596 
597    Level: developer
598 
599 .keywords: TS, trajectory, timestep, destroy
600 
601 .seealso: TSTrajectoryCreate(), TSTrajectorySetUp()
602 @*/
603 PetscErrorCode TSTrajectoryDestroy(TSTrajectory *tj)
604 {
605   PetscErrorCode ierr;
606 
607   PetscFunctionBegin;
608   if (!*tj) PetscFunctionReturn(0);
609   PetscValidHeaderSpecific((*tj),TSTRAJECTORY_CLASSID,1);
610   if (--((PetscObject)(*tj))->refct > 0) {*tj = 0; PetscFunctionReturn(0);}
611 
612   ierr = TSTrajectoryReset(*tj);CHKERRQ(ierr);
613   ierr = TSHistoryDestroy(&(*tj)->tsh);CHKERRQ(ierr);
614   ierr = VecDestroyVecs((*tj)->lag.order+1,&(*tj)->lag.W);CHKERRQ(ierr);
615   ierr = PetscFree5((*tj)->lag.L,(*tj)->lag.T,(*tj)->lag.WW,(*tj)->lag.TT,(*tj)->lag.TW);CHKERRQ(ierr);
616   ierr = VecDestroy(&(*tj)->U);CHKERRQ(ierr);
617   ierr = VecDestroy(&(*tj)->Udot);CHKERRQ(ierr);
618 
619   if ((*tj)->transformdestroy) {ierr = (*(*tj)->transformdestroy)((*tj)->transformctx);CHKERRQ(ierr);}
620   if ((*tj)->ops->destroy) {ierr = (*(*tj)->ops->destroy)((*tj));CHKERRQ(ierr);}
621   if (!((*tj)->keepfiles)) {
622     PetscMPIInt rank;
623     MPI_Comm    comm;
624 
625     ierr = PetscObjectGetComm((PetscObject)(*tj),&comm);CHKERRQ(ierr);
626     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
627     if (!rank) { /* we own the directory, so we run PetscRMTree on it */
628       ierr = PetscRMTree((*tj)->dirname);CHKERRQ(ierr);
629     }
630   }
631   ierr = PetscStrArrayDestroy(&(*tj)->names);CHKERRQ(ierr);
632   ierr = PetscFree((*tj)->dirname);CHKERRQ(ierr);
633   ierr = PetscFree((*tj)->filetemplate);CHKERRQ(ierr);
634   ierr = PetscHeaderDestroy(tj);CHKERRQ(ierr);
635   PetscFunctionReturn(0);
636 }
637 
638 /*
639   TSTrajectorySetTypeFromOptions_Private - Sets the type of ts from user options.
640 
641   Collective on TSTrajectory
642 
643   Input Parameter:
644 + tj - the TSTrajectory context
645 - ts - the TS context
646 
647   Options Database Keys:
648 . -ts_trajectory_type <type> - TSTRAJECTORYBASIC, TSTRAJECTORYMEMORY, TSTRAJECTORYSINGLEFILE, TSTRAJECTORYVISUALIZATION
649 
650   Level: developer
651 
652 .keywords: TS, trajectory, set, options, type
653 
654 .seealso: TSTrajectorySetFromOptions(), TSTrajectorySetType()
655 */
656 static PetscErrorCode TSTrajectorySetTypeFromOptions_Private(PetscOptionItems *PetscOptionsObject,TSTrajectory tj,TS ts)
657 {
658   PetscBool      opt;
659   const char     *defaultType;
660   char           typeName[256];
661   PetscErrorCode ierr;
662 
663   PetscFunctionBegin;
664   if (((PetscObject)tj)->type_name) defaultType = ((PetscObject)tj)->type_name;
665   else defaultType = TSTRAJECTORYBASIC;
666 
667   ierr = TSTrajectoryRegisterAll();CHKERRQ(ierr);
668   ierr = PetscOptionsFList("-ts_trajectory_type","TSTrajectory method","TSTrajectorySetType",TSTrajectoryList,defaultType,typeName,256,&opt);CHKERRQ(ierr);
669   if (opt) {
670     ierr = TSTrajectorySetType(tj,ts,typeName);CHKERRQ(ierr);
671   } else {
672     ierr = TSTrajectorySetType(tj,ts,defaultType);CHKERRQ(ierr);
673   }
674   PetscFunctionReturn(0);
675 }
676 
677 /*@
678    TSTrajectorySetMonitor - Monitor the schedules generated by the checkpointing controller
679 
680    Collective on TSTrajectory
681 
682    Input Arguments:
683 +  tj - the TSTrajectory context
684 -  flg - PETSC_TRUE to active a monitor, PETSC_FALSE to disable
685 
686    Options Database Keys:
687 .  -ts_trajectory_monitor - print TSTrajectory information
688 
689    Level: developer
690 
691 .keywords: TS, trajectory, set, monitor
692 
693 .seealso: TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectorySetUp()
694 @*/
695 PetscErrorCode TSTrajectorySetMonitor(TSTrajectory tj,PetscBool flg)
696 {
697   PetscFunctionBegin;
698   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
699   PetscValidLogicalCollectiveBool(tj,flg,2);
700   if (flg) tj->monitor = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)tj));
701   else tj->monitor = NULL;
702   PetscFunctionReturn(0);
703 }
704 
705 /*@
706    TSTrajectorySetKeepFiles - Keep the files generated by the TSTrajectory
707 
708    Collective on TSTrajectory
709 
710    Input Arguments:
711 +  tj - the TSTrajectory context
712 -  flg - PETSC_TRUE to save, PETSC_FALSE to disable
713 
714    Options Database Keys:
715 .  -ts_trajectory_keep_files - have it keep the files
716 
717    Notes:
718     By default the TSTrajectory used for adjoint computations, TSTRAJECTORYBASIC, removes the files it generates at the end of the run. This causes the files to be kept.
719 
720    Level: advanced
721 
722 .keywords: TS, trajectory, set, monitor
723 
724 .seealso: TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectorySetUp(), TSTrajectorySetMonitor()
725 @*/
726 PetscErrorCode TSTrajectorySetKeepFiles(TSTrajectory tj,PetscBool flg)
727 {
728   PetscFunctionBegin;
729   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
730   PetscValidLogicalCollectiveBool(tj,flg,2);
731   tj->keepfiles = flg;
732   PetscFunctionReturn(0);
733 }
734 
735 /*@C
736    TSTrajectorySetDirname - Specify the name of the directory where disk checkpoints are stored.
737 
738    Collective on TSTrajectory
739 
740    Input Arguments:
741 +  tj      - the TSTrajectory context
742 -  dirname - the directory name
743 
744    Options Database Keys:
745 .  -ts_trajectory_dirname - set the directory name
746 
747    Notes:
748     The final location of the files is determined by dirname/filetemplate where filetemplate was provided by TSTrajectorySetFiletemplate()
749 
750    Level: developer
751 
752 .keywords: TS, trajectory, set
753 
754 .seealso: TSTrajectorySetFiletemplate(),TSTrajectorySetUp()
755 @*/
756 PetscErrorCode TSTrajectorySetDirname(TSTrajectory tj,const char dirname[])
757 {
758   PetscErrorCode ierr;
759   PetscBool      flg;
760 
761   PetscFunctionBegin;
762   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
763   ierr = PetscStrcmp(tj->dirname,dirname,&flg);CHKERRQ(ierr);
764   if (!flg && tj->dirfiletemplate) {
765     SETERRQ(PetscObjectComm((PetscObject)tj),PETSC_ERR_ARG_WRONGSTATE,"Cannot set directoryname after TSTrajectory has been setup");
766   }
767   ierr = PetscFree(tj->dirname);CHKERRQ(ierr);
768   ierr = PetscStrallocpy(dirname,&tj->dirname);CHKERRQ(ierr);
769   PetscFunctionReturn(0);
770 }
771 
772 /*@C
773    TSTrajectorySetFiletemplate - Specify the name template for the files storing checkpoints.
774 
775    Collective on TSTrajectory
776 
777    Input Arguments:
778 +  tj      - the TSTrajectory context
779 -  filetemplate - the template
780 
781    Options Database Keys:
782 .  -ts_trajectory_file_template - set the file name template
783 
784    Notes:
785     The name template should be of the form, for example filename-%06D.bin It should not begin with a leading /
786 
787    The final location of the files is determined by dirname/filetemplate where dirname was provided by TSTrajectorySetDirname(). The %06D is replaced by the
788    timestep counter
789 
790    Level: developer
791 
792 .keywords: TS, trajectory, set
793 
794 .seealso: TSTrajectorySetDirname(),TSTrajectorySetUp()
795 @*/
796 PetscErrorCode TSTrajectorySetFiletemplate(TSTrajectory tj,const char filetemplate[])
797 {
798   PetscErrorCode ierr;
799   const char     *ptr,*ptr2;
800 
801   PetscFunctionBegin;
802   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
803   if (tj->dirfiletemplate) SETERRQ(PetscObjectComm((PetscObject)tj),PETSC_ERR_ARG_WRONGSTATE,"Cannot set filetemplate after TSTrajectory has been setup");
804 
805   if (!filetemplate[0]) SETERRQ(PetscObjectComm((PetscObject)tj),PETSC_ERR_USER,"-ts_trajectory_file_template requires a file name template, e.g. filename-%%06D.bin");
806   /* Do some cursory validation of the input. */
807   ierr = PetscStrstr(filetemplate,"%",(char**)&ptr);CHKERRQ(ierr);
808   if (!ptr) SETERRQ(PetscObjectComm((PetscObject)tj),PETSC_ERR_USER,"-ts_trajectory_file_template requires a file name template, e.g. filename-%%06D.bin");
809   for (ptr++; ptr && *ptr; ptr++) {
810     ierr = PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);CHKERRQ(ierr);
811     if (!ptr2 && (*ptr < '0' || '9' < *ptr)) SETERRQ(PetscObjectComm((PetscObject)tj),PETSC_ERR_USER,"Invalid file template argument to -ts_trajectory_file_template, should look like filename-%%06D.bin");
812     if (ptr2) break;
813   }
814   ierr = PetscFree(tj->filetemplate);CHKERRQ(ierr);
815   ierr = PetscStrallocpy(filetemplate,&tj->filetemplate);CHKERRQ(ierr);
816   PetscFunctionReturn(0);
817 }
818 
819 /*@
820    TSTrajectorySetFromOptions - Sets various TSTrajectory parameters from user options.
821 
822    Collective on TSTrajectory
823 
824    Input Parameter:
825 +  tj - the TSTrajectory context obtained from TSTrajectoryCreate()
826 -  ts - the TS context
827 
828    Options Database Keys:
829 +  -ts_trajectory_type <type> - TSTRAJECTORYBASIC, TSTRAJECTORYMEMORY, TSTRAJECTORYSINGLEFILE, TSTRAJECTORYVISUALIZATION
830 .  -ts_trajectory_keep_files <true,false> - keep the files generated by the code after the program ends. This is true by default for TSTRAJECTORYSINGLEFILE, TSTRAJECTORYVISUALIZATION
831 -  -ts_trajectory_monitor - print TSTrajectory information
832 
833    Level: developer
834 
835    Notes:
836     This is not normally called directly by users
837 
838 .keywords: TS, trajectory, timestep, set, options, database
839 
840 .seealso: TSSetSaveTrajectory(), TSTrajectorySetUp()
841 @*/
842 PetscErrorCode  TSTrajectorySetFromOptions(TSTrajectory tj,TS ts)
843 {
844   PetscBool      set,flg;
845   char           dirname[PETSC_MAX_PATH_LEN],filetemplate[PETSC_MAX_PATH_LEN];
846   PetscErrorCode ierr;
847 
848   PetscFunctionBegin;
849   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
850   if (ts) PetscValidHeaderSpecific(ts,TS_CLASSID,2);
851   ierr = PetscObjectOptionsBegin((PetscObject)tj);CHKERRQ(ierr);
852   ierr = TSTrajectorySetTypeFromOptions_Private(PetscOptionsObject,tj,ts);CHKERRQ(ierr);
853   ierr = PetscOptionsBool("-ts_trajectory_use_history","Turn on/off usage of TSHistory",NULL,tj->usehistory,&tj->usehistory,NULL);CHKERRQ(ierr);
854   ierr = PetscOptionsBool("-ts_trajectory_monitor","Print checkpointing schedules","TSTrajectorySetMonitor",tj->monitor ? PETSC_TRUE:PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
855   if (set) {ierr = TSTrajectorySetMonitor(tj,flg);CHKERRQ(ierr);}
856   ierr = PetscOptionsInt("-ts_trajectory_reconstruction_order","Interpolation order for reconstruction",NULL,tj->lag.order,&tj->lag.order,NULL);CHKERRQ(ierr);
857   ierr = PetscOptionsBool("-ts_trajectory_reconstruction_caching","Turn on/off caching of TSTrajectoryGetVecs input",NULL,tj->lag.caching,&tj->lag.caching,NULL);CHKERRQ(ierr);
858   ierr = PetscOptionsBool("-ts_trajectory_adjointmode","Instruct the trajectory that will be used in a TSAdjointSolve()",NULL,tj->adjoint_solve_mode,&tj->adjoint_solve_mode,NULL);CHKERRQ(ierr);
859   ierr = PetscOptionsBool("-ts_trajectory_solution_only","Checkpoint solution only","TSTrajectorySetSolutionOnly",tj->solution_only,&tj->solution_only,NULL);CHKERRQ(ierr);
860   ierr = PetscOptionsBool("-ts_trajectory_keep_files","Keep any trajectory files generated during the run","TSTrajectorySetKeepFiles",tj->keepfiles,&flg,&set);CHKERRQ(ierr);
861   if (set) {ierr = TSTrajectorySetKeepFiles(tj,flg);CHKERRQ(ierr);}
862 
863   ierr = PetscOptionsString("-ts_trajectory_dirname","Directory name for TSTrajectory file","TSTrajectorySetDirname",0,dirname,PETSC_MAX_PATH_LEN-14,&set);CHKERRQ(ierr);
864   if (set) {
865     ierr = TSTrajectorySetDirname(tj,dirname);CHKERRQ(ierr);
866   }
867 
868   ierr = PetscOptionsString("-ts_trajectory_file_template","Template for TSTrajectory file name, use filename-%06D.bin","TSTrajectorySetFiletemplate",0,filetemplate,PETSC_MAX_PATH_LEN,&set);CHKERRQ(ierr);
869   if (set) {
870     ierr = TSTrajectorySetFiletemplate(tj,filetemplate);CHKERRQ(ierr);
871   }
872 
873   /* Handle specific TSTrajectory options */
874   if (tj->ops->setfromoptions) {
875     ierr = (*tj->ops->setfromoptions)(PetscOptionsObject,tj);CHKERRQ(ierr);
876   }
877   ierr = PetscOptionsEnd();CHKERRQ(ierr);
878   PetscFunctionReturn(0);
879 }
880 
881 /*@
882    TSTrajectorySetUp - Sets up the internal data structures, e.g. stacks, for the later use
883    of a TS trajectory.
884 
885    Collective on TS
886 
887    Input Parameter:
888 +  ts - the TS context obtained from TSCreate()
889 -  tj - the TS trajectory context
890 
891    Level: developer
892 
893 .keywords: TS, trajectory, setup
894 
895 .seealso: TSSetSaveTrajectory(), TSTrajectoryCreate(), TSTrajectoryDestroy()
896 @*/
897 PetscErrorCode  TSTrajectorySetUp(TSTrajectory tj,TS ts)
898 {
899   PetscErrorCode ierr;
900   size_t         s1,s2;
901 
902   PetscFunctionBegin;
903   if (!tj) PetscFunctionReturn(0);
904   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
905   if (ts) PetscValidHeaderSpecific(ts,TS_CLASSID,2);
906   if (tj->setupcalled) PetscFunctionReturn(0);
907 
908   if (!((PetscObject)tj)->type_name) {
909     ierr = TSTrajectorySetType(tj,ts,TSTRAJECTORYBASIC);CHKERRQ(ierr);
910   }
911   if (tj->ops->setup) {
912     ierr = (*tj->ops->setup)(tj,ts);CHKERRQ(ierr);
913   }
914 
915   tj->setupcalled = PETSC_TRUE;
916 
917   /* Set the counters to zero */
918   tj->recomps    = 0;
919   tj->diskreads  = 0;
920   tj->diskwrites = 0;
921   ierr = PetscStrlen(tj->dirname,&s1);CHKERRQ(ierr);
922   ierr = PetscStrlen(tj->filetemplate,&s2);CHKERRQ(ierr);
923   ierr = PetscFree(tj->dirfiletemplate);CHKERRQ(ierr);
924   ierr = PetscMalloc((s1 + s2 + 10)*sizeof(char),&tj->dirfiletemplate);CHKERRQ(ierr);
925   ierr = PetscSNPrintf(tj->dirfiletemplate,s1+s2+10,"%s/%s",tj->dirname,tj->filetemplate);CHKERRQ(ierr);
926   PetscFunctionReturn(0);
927 }
928 
929 /*@
930    TSTrajectorySetSolutionOnly - Tells the trajectory to store just the solution, and not any intermediate stage also.
931 
932    Collective on TSTrajectory
933 
934    Input Parameter:
935 +  tj  - the TS trajectory context
936 -  flg - the boolean flag
937 
938    Level: developer
939 
940 .keywords: trajectory
941 
942 .seealso: TSSetSaveTrajectory(), TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectoryGetSolutionOnly()
943 @*/
944 PetscErrorCode TSTrajectorySetSolutionOnly(TSTrajectory tj,PetscBool solution_only)
945 {
946   PetscFunctionBegin;
947   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
948   PetscValidLogicalCollectiveBool(tj,solution_only,2);
949   tj->solution_only = solution_only;
950   PetscFunctionReturn(0);
951 }
952 
953 /*@
954    TSTrajectoryGetSolutionOnly - Gets the value set with TSTrajectorySetSolutionOnly.
955 
956    Logically collective on TSTrajectory
957 
958    Input Parameter:
959 .  tj  - the TS trajectory context
960 
961    Output Parameter:
962 -  flg - the boolean flag
963 
964    Level: developer
965 
966 .keywords: trajectory
967 
968 .seealso: TSSetSaveTrajectory(), TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectorySetSolutionOnly()
969 @*/
970 PetscErrorCode TSTrajectoryGetSolutionOnly(TSTrajectory tj,PetscBool *solution_only)
971 {
972   PetscFunctionBegin;
973   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
974   PetscValidPointer(solution_only,2);
975   *solution_only = tj->solution_only;
976   PetscFunctionReturn(0);
977 }
978 
979 /*@
980    TSTrajectoryGetUpdatedHistoryVecs - Get updated state and time-derivative history vectors.
981 
982    Collective on TSTrajectory
983 
984    Input Parameter:
985 +  tj   - the TS trajectory context
986 .  ts   - the TS solver context
987 -  time - the requested time
988 
989    Output Parameter:
990 +  U    - state vector at given time (can be interpolated)
991 -  Udot - time-derivative vector at given time (can be interpolated)
992 
993    Level: developer
994 
995    Notes: The vectors are interpolated if time does not match any time step stored in the TSTrajectory(). Pass NULL to not request a vector.
996           This function differs from TSTrajectoryGetVecs since the vectors obtained cannot be modified, and they need to be returned by
997           calling TSTrajectoryRestoreUpdatedHistoryVecs().
998 
999 .keywords: trajectory
1000 
1001 .seealso: TSSetSaveTrajectory(), TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectoryRestoreUpdatedHistoryVecs(), TSTrajectoryGetVecs()
1002 @*/
1003 PetscErrorCode TSTrajectoryGetUpdatedHistoryVecs(TSTrajectory tj, TS ts, PetscReal time, Vec *U, Vec *Udot)
1004 {
1005   PetscErrorCode ierr;
1006 
1007   PetscFunctionBegin;
1008   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
1009   PetscValidHeaderSpecific(ts,TS_CLASSID,2);
1010   PetscValidLogicalCollectiveReal(tj,time,3);
1011   if (U) PetscValidPointer(U,4);
1012   if (Udot) PetscValidPointer(Udot,5);
1013   if (U && !tj->U) {
1014     DM dm;
1015 
1016     ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1017     ierr = DMCreateGlobalVector(dm,&tj->U);CHKERRQ(ierr);
1018   }
1019   if (Udot && !tj->Udot) {
1020     DM dm;
1021 
1022     ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1023     ierr = DMCreateGlobalVector(dm,&tj->Udot);CHKERRQ(ierr);
1024   }
1025   ierr = TSTrajectoryGetVecs(tj,ts,PETSC_DECIDE,&time,U ? tj->U : NULL,Udot ? tj->Udot : NULL);CHKERRQ(ierr);
1026   if (U) {
1027     ierr = VecLockReadPush(tj->U);CHKERRQ(ierr);
1028     *U   = tj->U;
1029   }
1030   if (Udot) {
1031     ierr  = VecLockReadPush(tj->Udot);CHKERRQ(ierr);
1032     *Udot = tj->Udot;
1033   }
1034   PetscFunctionReturn(0);
1035 }
1036 
1037 /*@
1038    TSTrajectoryRestoreUpdatedHistoryVecs - Restores updated state and time-derivative history vectors obtained with TSTrajectoryGetUpdatedHistoryVecs().
1039 
1040    Collective on TSTrajectory
1041 
1042    Input Parameter:
1043 +  tj   - the TS trajectory context
1044 .  U    - state vector at given time (can be interpolated)
1045 -  Udot - time-derivative vector at given time (can be interpolated)
1046 
1047    Level: developer
1048 
1049 .keywords: trajectory
1050 
1051 .seealso: TSTrajectoryGetUpdatedHistoryVecs()
1052 @*/
1053 PetscErrorCode TSTrajectoryRestoreUpdatedHistoryVecs(TSTrajectory tj, Vec *U, Vec *Udot)
1054 {
1055   PetscErrorCode ierr;
1056 
1057   PetscFunctionBegin;
1058   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
1059   if (U) PetscValidHeaderSpecific(*U,VEC_CLASSID,2);
1060   if (Udot) PetscValidHeaderSpecific(*Udot,VEC_CLASSID,3);
1061   if (U && *U != tj->U) SETERRQ(PetscObjectComm((PetscObject)*U),PETSC_ERR_USER,"U was not obtained from TSTrajectoryGetUpdatedHistoryVecs()");
1062   if (Udot && *Udot != tj->Udot) SETERRQ(PetscObjectComm((PetscObject)*Udot),PETSC_ERR_USER,"Udot was not obtained from TSTrajectoryGetUpdatedHistoryVecs()");
1063   if (U) {
1064     ierr = VecLockReadPop(tj->U);CHKERRQ(ierr);
1065     *U   = NULL;
1066   }
1067   if (Udot) {
1068     ierr  = VecLockReadPop(tj->Udot);CHKERRQ(ierr);
1069     *Udot = NULL;
1070   }
1071   PetscFunctionReturn(0);
1072 }
1073