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