xref: /petsc/src/ts/trajectory/interface/traj.c (revision fccb18fbb4825433b897d8c2cb64f0bcfabccc52)
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    TSTrajectorySetUseHistory - Use TSHistory in TSTrajectory
679 
680    Collective on TSTrajectory
681 
682    Input Arguments:
683 +  tj - the TSTrajectory context
684 -  flg - PETSC_TRUE to save, PETSC_FALSE to disable
685 
686    Options Database Keys:
687 .  -ts_trajectory_use_history - have it use TSHistory
688 
689    Level: advanced
690 
691 .keywords: TS, trajectory, set, TSHistory
692 
693 .seealso: TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectorySetUp()
694 @*/
695 PetscErrorCode TSTrajectorySetUseHistory(TSTrajectory tj,PetscBool flg)
696 {
697   PetscFunctionBegin;
698   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
699   PetscValidLogicalCollectiveBool(tj,flg,2);
700   tj->usehistory = flg;
701   PetscFunctionReturn(0);
702 }
703 
704 /*@
705    TSTrajectorySetMonitor - Monitor the schedules generated by the checkpointing controller
706 
707    Collective on TSTrajectory
708 
709    Input Arguments:
710 +  tj - the TSTrajectory context
711 -  flg - PETSC_TRUE to active a monitor, PETSC_FALSE to disable
712 
713    Options Database Keys:
714 .  -ts_trajectory_monitor - print TSTrajectory information
715 
716    Level: developer
717 
718 .keywords: TS, trajectory, set, monitor
719 
720 .seealso: TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectorySetUp()
721 @*/
722 PetscErrorCode TSTrajectorySetMonitor(TSTrajectory tj,PetscBool flg)
723 {
724   PetscFunctionBegin;
725   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
726   PetscValidLogicalCollectiveBool(tj,flg,2);
727   if (flg) tj->monitor = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)tj));
728   else tj->monitor = NULL;
729   PetscFunctionReturn(0);
730 }
731 
732 /*@
733    TSTrajectorySetKeepFiles - Keep the files generated by the TSTrajectory
734 
735    Collective on TSTrajectory
736 
737    Input Arguments:
738 +  tj - the TSTrajectory context
739 -  flg - PETSC_TRUE to save, PETSC_FALSE to disable
740 
741    Options Database Keys:
742 .  -ts_trajectory_keep_files - have it keep the files
743 
744    Notes:
745     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.
746 
747    Level: advanced
748 
749 .keywords: TS, trajectory, set, monitor
750 
751 .seealso: TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectorySetUp(), TSTrajectorySetMonitor()
752 @*/
753 PetscErrorCode TSTrajectorySetKeepFiles(TSTrajectory tj,PetscBool flg)
754 {
755   PetscFunctionBegin;
756   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
757   PetscValidLogicalCollectiveBool(tj,flg,2);
758   tj->keepfiles = flg;
759   PetscFunctionReturn(0);
760 }
761 
762 /*@C
763    TSTrajectorySetDirname - Specify the name of the directory where disk checkpoints are stored.
764 
765    Collective on TSTrajectory
766 
767    Input Arguments:
768 +  tj      - the TSTrajectory context
769 -  dirname - the directory name
770 
771    Options Database Keys:
772 .  -ts_trajectory_dirname - set the directory name
773 
774    Notes:
775     The final location of the files is determined by dirname/filetemplate where filetemplate was provided by TSTrajectorySetFiletemplate()
776 
777    Level: developer
778 
779 .keywords: TS, trajectory, set
780 
781 .seealso: TSTrajectorySetFiletemplate(),TSTrajectorySetUp()
782 @*/
783 PetscErrorCode TSTrajectorySetDirname(TSTrajectory tj,const char dirname[])
784 {
785   PetscErrorCode ierr;
786   PetscBool      flg;
787 
788   PetscFunctionBegin;
789   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
790   ierr = PetscStrcmp(tj->dirname,dirname,&flg);CHKERRQ(ierr);
791   if (!flg && tj->dirfiletemplate) {
792     SETERRQ(PetscObjectComm((PetscObject)tj),PETSC_ERR_ARG_WRONGSTATE,"Cannot set directoryname after TSTrajectory has been setup");
793   }
794   ierr = PetscFree(tj->dirname);CHKERRQ(ierr);
795   ierr = PetscStrallocpy(dirname,&tj->dirname);CHKERRQ(ierr);
796   PetscFunctionReturn(0);
797 }
798 
799 /*@C
800    TSTrajectorySetFiletemplate - Specify the name template for the files storing checkpoints.
801 
802    Collective on TSTrajectory
803 
804    Input Arguments:
805 +  tj      - the TSTrajectory context
806 -  filetemplate - the template
807 
808    Options Database Keys:
809 .  -ts_trajectory_file_template - set the file name template
810 
811    Notes:
812     The name template should be of the form, for example filename-%06D.bin It should not begin with a leading /
813 
814    The final location of the files is determined by dirname/filetemplate where dirname was provided by TSTrajectorySetDirname(). The %06D is replaced by the
815    timestep counter
816 
817    Level: developer
818 
819 .keywords: TS, trajectory, set
820 
821 .seealso: TSTrajectorySetDirname(),TSTrajectorySetUp()
822 @*/
823 PetscErrorCode TSTrajectorySetFiletemplate(TSTrajectory tj,const char filetemplate[])
824 {
825   PetscErrorCode ierr;
826   const char     *ptr,*ptr2;
827 
828   PetscFunctionBegin;
829   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
830   if (tj->dirfiletemplate) SETERRQ(PetscObjectComm((PetscObject)tj),PETSC_ERR_ARG_WRONGSTATE,"Cannot set filetemplate after TSTrajectory has been setup");
831 
832   if (!filetemplate[0]) SETERRQ(PetscObjectComm((PetscObject)tj),PETSC_ERR_USER,"-ts_trajectory_file_template requires a file name template, e.g. filename-%%06D.bin");
833   /* Do some cursory validation of the input. */
834   ierr = PetscStrstr(filetemplate,"%",(char**)&ptr);CHKERRQ(ierr);
835   if (!ptr) SETERRQ(PetscObjectComm((PetscObject)tj),PETSC_ERR_USER,"-ts_trajectory_file_template requires a file name template, e.g. filename-%%06D.bin");
836   for (ptr++; ptr && *ptr; ptr++) {
837     ierr = PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);CHKERRQ(ierr);
838     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");
839     if (ptr2) break;
840   }
841   ierr = PetscFree(tj->filetemplate);CHKERRQ(ierr);
842   ierr = PetscStrallocpy(filetemplate,&tj->filetemplate);CHKERRQ(ierr);
843   PetscFunctionReturn(0);
844 }
845 
846 /*@
847    TSTrajectorySetFromOptions - Sets various TSTrajectory parameters from user options.
848 
849    Collective on TSTrajectory
850 
851    Input Parameter:
852 +  tj - the TSTrajectory context obtained from TSTrajectoryCreate()
853 -  ts - the TS context
854 
855    Options Database Keys:
856 +  -ts_trajectory_type <type> - TSTRAJECTORYBASIC, TSTRAJECTORYMEMORY, TSTRAJECTORYSINGLEFILE, TSTRAJECTORYVISUALIZATION
857 .  -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
858 -  -ts_trajectory_monitor - print TSTrajectory information
859 
860    Level: developer
861 
862    Notes:
863     This is not normally called directly by users
864 
865 .keywords: TS, trajectory, timestep, set, options, database
866 
867 .seealso: TSSetSaveTrajectory(), TSTrajectorySetUp()
868 @*/
869 PetscErrorCode  TSTrajectorySetFromOptions(TSTrajectory tj,TS ts)
870 {
871   PetscBool      set,flg;
872   char           dirname[PETSC_MAX_PATH_LEN],filetemplate[PETSC_MAX_PATH_LEN];
873   PetscErrorCode ierr;
874 
875   PetscFunctionBegin;
876   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
877   if (ts) PetscValidHeaderSpecific(ts,TS_CLASSID,2);
878   ierr = PetscObjectOptionsBegin((PetscObject)tj);CHKERRQ(ierr);
879   ierr = TSTrajectorySetTypeFromOptions_Private(PetscOptionsObject,tj,ts);CHKERRQ(ierr);
880   ierr = PetscOptionsBool("-ts_trajectory_use_history","Turn on/off usage of TSHistory",NULL,tj->usehistory,&tj->usehistory,NULL);CHKERRQ(ierr);
881   ierr = PetscOptionsBool("-ts_trajectory_monitor","Print checkpointing schedules","TSTrajectorySetMonitor",tj->monitor ? PETSC_TRUE:PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
882   if (set) {ierr = TSTrajectorySetMonitor(tj,flg);CHKERRQ(ierr);}
883   ierr = PetscOptionsInt("-ts_trajectory_reconstruction_order","Interpolation order for reconstruction",NULL,tj->lag.order,&tj->lag.order,NULL);CHKERRQ(ierr);
884   ierr = PetscOptionsBool("-ts_trajectory_reconstruction_caching","Turn on/off caching of TSTrajectoryGetVecs input",NULL,tj->lag.caching,&tj->lag.caching,NULL);CHKERRQ(ierr);
885   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);
886   ierr = PetscOptionsBool("-ts_trajectory_solution_only","Checkpoint solution only","TSTrajectorySetSolutionOnly",tj->solution_only,&tj->solution_only,NULL);CHKERRQ(ierr);
887   ierr = PetscOptionsBool("-ts_trajectory_keep_files","Keep any trajectory files generated during the run","TSTrajectorySetKeepFiles",tj->keepfiles,&flg,&set);CHKERRQ(ierr);
888   if (set) {ierr = TSTrajectorySetKeepFiles(tj,flg);CHKERRQ(ierr);}
889 
890   ierr = PetscOptionsString("-ts_trajectory_dirname","Directory name for TSTrajectory file","TSTrajectorySetDirname",0,dirname,PETSC_MAX_PATH_LEN-14,&set);CHKERRQ(ierr);
891   if (set) {
892     ierr = TSTrajectorySetDirname(tj,dirname);CHKERRQ(ierr);
893   }
894 
895   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);
896   if (set) {
897     ierr = TSTrajectorySetFiletemplate(tj,filetemplate);CHKERRQ(ierr);
898   }
899 
900   /* Handle specific TSTrajectory options */
901   if (tj->ops->setfromoptions) {
902     ierr = (*tj->ops->setfromoptions)(PetscOptionsObject,tj);CHKERRQ(ierr);
903   }
904   ierr = PetscOptionsEnd();CHKERRQ(ierr);
905   PetscFunctionReturn(0);
906 }
907 
908 /*@
909    TSTrajectorySetUp - Sets up the internal data structures, e.g. stacks, for the later use
910    of a TS trajectory.
911 
912    Collective on TS
913 
914    Input Parameter:
915 +  ts - the TS context obtained from TSCreate()
916 -  tj - the TS trajectory context
917 
918    Level: developer
919 
920 .keywords: TS, trajectory, setup
921 
922 .seealso: TSSetSaveTrajectory(), TSTrajectoryCreate(), TSTrajectoryDestroy()
923 @*/
924 PetscErrorCode  TSTrajectorySetUp(TSTrajectory tj,TS ts)
925 {
926   PetscErrorCode ierr;
927   size_t         s1,s2;
928 
929   PetscFunctionBegin;
930   if (!tj) PetscFunctionReturn(0);
931   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
932   if (ts) PetscValidHeaderSpecific(ts,TS_CLASSID,2);
933   if (tj->setupcalled) PetscFunctionReturn(0);
934 
935   if (!((PetscObject)tj)->type_name) {
936     ierr = TSTrajectorySetType(tj,ts,TSTRAJECTORYBASIC);CHKERRQ(ierr);
937   }
938   if (tj->ops->setup) {
939     ierr = (*tj->ops->setup)(tj,ts);CHKERRQ(ierr);
940   }
941 
942   tj->setupcalled = PETSC_TRUE;
943 
944   /* Set the counters to zero */
945   tj->recomps    = 0;
946   tj->diskreads  = 0;
947   tj->diskwrites = 0;
948   ierr = PetscStrlen(tj->dirname,&s1);CHKERRQ(ierr);
949   ierr = PetscStrlen(tj->filetemplate,&s2);CHKERRQ(ierr);
950   ierr = PetscFree(tj->dirfiletemplate);CHKERRQ(ierr);
951   ierr = PetscMalloc((s1 + s2 + 10)*sizeof(char),&tj->dirfiletemplate);CHKERRQ(ierr);
952   ierr = PetscSNPrintf(tj->dirfiletemplate,s1+s2+10,"%s/%s",tj->dirname,tj->filetemplate);CHKERRQ(ierr);
953   PetscFunctionReturn(0);
954 }
955 
956 /*@
957    TSTrajectorySetSolutionOnly - Tells the trajectory to store just the solution, and not any intermediate stage also.
958 
959    Collective on TSTrajectory
960 
961    Input Parameter:
962 +  tj  - the TS trajectory context
963 -  flg - the boolean flag
964 
965    Level: developer
966 
967 .keywords: trajectory
968 
969 .seealso: TSSetSaveTrajectory(), TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectoryGetSolutionOnly()
970 @*/
971 PetscErrorCode TSTrajectorySetSolutionOnly(TSTrajectory tj,PetscBool solution_only)
972 {
973   PetscFunctionBegin;
974   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
975   PetscValidLogicalCollectiveBool(tj,solution_only,2);
976   tj->solution_only = solution_only;
977   PetscFunctionReturn(0);
978 }
979 
980 /*@
981    TSTrajectoryGetSolutionOnly - Gets the value set with TSTrajectorySetSolutionOnly.
982 
983    Logically collective on TSTrajectory
984 
985    Input Parameter:
986 .  tj  - the TS trajectory context
987 
988    Output Parameter:
989 -  flg - the boolean flag
990 
991    Level: developer
992 
993 .keywords: trajectory
994 
995 .seealso: TSSetSaveTrajectory(), TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectorySetSolutionOnly()
996 @*/
997 PetscErrorCode TSTrajectoryGetSolutionOnly(TSTrajectory tj,PetscBool *solution_only)
998 {
999   PetscFunctionBegin;
1000   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
1001   PetscValidPointer(solution_only,2);
1002   *solution_only = tj->solution_only;
1003   PetscFunctionReturn(0);
1004 }
1005 
1006 /*@
1007    TSTrajectoryGetUpdatedHistoryVecs - Get updated state and time-derivative history vectors.
1008 
1009    Collective on TSTrajectory
1010 
1011    Input Parameter:
1012 +  tj   - the TS trajectory context
1013 .  ts   - the TS solver context
1014 -  time - the requested time
1015 
1016    Output Parameter:
1017 +  U    - state vector at given time (can be interpolated)
1018 -  Udot - time-derivative vector at given time (can be interpolated)
1019 
1020    Level: developer
1021 
1022    Notes: The vectors are interpolated if time does not match any time step stored in the TSTrajectory(). Pass NULL to not request a vector.
1023           This function differs from TSTrajectoryGetVecs since the vectors obtained cannot be modified, and they need to be returned by
1024           calling TSTrajectoryRestoreUpdatedHistoryVecs().
1025 
1026 .keywords: trajectory
1027 
1028 .seealso: TSSetSaveTrajectory(), TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectoryRestoreUpdatedHistoryVecs(), TSTrajectoryGetVecs()
1029 @*/
1030 PetscErrorCode TSTrajectoryGetUpdatedHistoryVecs(TSTrajectory tj, TS ts, PetscReal time, Vec *U, Vec *Udot)
1031 {
1032   PetscErrorCode ierr;
1033 
1034   PetscFunctionBegin;
1035   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
1036   PetscValidHeaderSpecific(ts,TS_CLASSID,2);
1037   PetscValidLogicalCollectiveReal(tj,time,3);
1038   if (U) PetscValidPointer(U,4);
1039   if (Udot) PetscValidPointer(Udot,5);
1040   if (U && !tj->U) {
1041     DM dm;
1042 
1043     ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1044     ierr = DMCreateGlobalVector(dm,&tj->U);CHKERRQ(ierr);
1045   }
1046   if (Udot && !tj->Udot) {
1047     DM dm;
1048 
1049     ierr = TSGetDM(ts,&dm);CHKERRQ(ierr);
1050     ierr = DMCreateGlobalVector(dm,&tj->Udot);CHKERRQ(ierr);
1051   }
1052   ierr = TSTrajectoryGetVecs(tj,ts,PETSC_DECIDE,&time,U ? tj->U : NULL,Udot ? tj->Udot : NULL);CHKERRQ(ierr);
1053   if (U) {
1054     ierr = VecLockReadPush(tj->U);CHKERRQ(ierr);
1055     *U   = tj->U;
1056   }
1057   if (Udot) {
1058     ierr  = VecLockReadPush(tj->Udot);CHKERRQ(ierr);
1059     *Udot = tj->Udot;
1060   }
1061   PetscFunctionReturn(0);
1062 }
1063 
1064 /*@
1065    TSTrajectoryRestoreUpdatedHistoryVecs - Restores updated state and time-derivative history vectors obtained with TSTrajectoryGetUpdatedHistoryVecs().
1066 
1067    Collective on TSTrajectory
1068 
1069    Input Parameter:
1070 +  tj   - the TS trajectory context
1071 .  U    - state vector at given time (can be interpolated)
1072 -  Udot - time-derivative vector at given time (can be interpolated)
1073 
1074    Level: developer
1075 
1076 .keywords: trajectory
1077 
1078 .seealso: TSTrajectoryGetUpdatedHistoryVecs()
1079 @*/
1080 PetscErrorCode TSTrajectoryRestoreUpdatedHistoryVecs(TSTrajectory tj, Vec *U, Vec *Udot)
1081 {
1082   PetscErrorCode ierr;
1083 
1084   PetscFunctionBegin;
1085   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
1086   if (U) PetscValidHeaderSpecific(*U,VEC_CLASSID,2);
1087   if (Udot) PetscValidHeaderSpecific(*Udot,VEC_CLASSID,3);
1088   if (U && *U != tj->U) SETERRQ(PetscObjectComm((PetscObject)*U),PETSC_ERR_USER,"U was not obtained from TSTrajectoryGetUpdatedHistoryVecs()");
1089   if (Udot && *Udot != tj->Udot) SETERRQ(PetscObjectComm((PetscObject)*Udot),PETSC_ERR_USER,"Udot was not obtained from TSTrajectoryGetUpdatedHistoryVecs()");
1090   if (U) {
1091     ierr = VecLockReadPop(tj->U);CHKERRQ(ierr);
1092     *U   = NULL;
1093   }
1094   if (Udot) {
1095     ierr  = VecLockReadPop(tj->Udot);CHKERRQ(ierr);
1096     *Udot = NULL;
1097   }
1098   PetscFunctionReturn(0);
1099 }
1100