xref: /petsc/src/ts/trajectory/interface/traj.c (revision 1585b412e7c6b7ee6aa5ae176d2b968a64b94bf2)
1 
2 #include <petsc/private/tsimpl.h>        /*I "petscts.h"  I*/
3 
4 PetscFunctionList TSTrajectoryList              = NULL;
5 PetscBool         TSTrajectoryRegisterAllCalled = PETSC_FALSE;
6 PetscClassId      TSTRAJECTORY_CLASSID;
7 PetscLogEvent     TSTrajectory_Set, TSTrajectory_Get;
8 
9 /*@C
10   TSTrajectoryRegister - Adds a way of storing trajectories to the TS package
11 
12   Not Collective
13 
14   Input Parameters:
15 + name        - the name of a new user-defined creation routine
16 - create_func - the creation routine itself
17 
18   Notes:
19   TSTrajectoryRegister() may be called multiple times to add several user-defined tses.
20 
21   Level: developer
22 
23 .keywords: TS, trajectory, timestep, register
24 
25 .seealso: TSTrajectoryRegisterAll()
26 @*/
27 PetscErrorCode TSTrajectoryRegister(const char sname[],PetscErrorCode (*function)(TSTrajectory,TS))
28 {
29   PetscErrorCode ierr;
30 
31   PetscFunctionBegin;
32   ierr = PetscFunctionListAdd(&TSTrajectoryList,sname,function);CHKERRQ(ierr);
33   PetscFunctionReturn(0);
34 }
35 
36 PetscErrorCode TSTrajectorySet(TSTrajectory tj,TS ts,PetscInt stepnum,PetscReal time,Vec X)
37 {
38   PetscErrorCode ierr;
39 
40   PetscFunctionBegin;
41   if (!tj) PetscFunctionReturn(0);
42   ierr = PetscLogEventBegin(TSTrajectory_Set,tj,ts,0,0);CHKERRQ(ierr);
43   ierr = (*tj->ops->set)(tj,ts,stepnum,time,X);CHKERRQ(ierr);
44   ierr = PetscLogEventEnd(TSTrajectory_Set,tj,ts,0,0);CHKERRQ(ierr);
45   PetscFunctionReturn(0);
46 }
47 
48 PetscErrorCode TSTrajectoryGet(TSTrajectory tj,TS ts,PetscInt stepnum,PetscReal *time)
49 {
50   PetscErrorCode ierr;
51 
52   PetscFunctionBegin;
53   if (!tj) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TS solver did not save trajectory");
54   ierr = PetscLogEventBegin(TSTrajectory_Get,tj,ts,0,0);CHKERRQ(ierr);
55   ierr = (*tj->ops->get)(tj,ts,stepnum,time);CHKERRQ(ierr);
56   ierr = PetscLogEventEnd(TSTrajectory_Get,tj,ts,0,0);CHKERRQ(ierr);
57   PetscFunctionReturn(0);
58 }
59 
60 /*@C
61     TSTrajectoryView - Prints information about the trajectory object
62 
63     Collective on TSTrajectory
64 
65     Input Parameters:
66 +   tj - the TSTrajectory context obtained from TSTrajectoryCreate()
67 -   viewer - visualization context
68 
69     Options Database Key:
70 .   -ts_trajectory_view - calls TSTrajectoryView() at end of TSAdjointStep()
71 
72     Notes:
73     The available visualization contexts include
74 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
75 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
76          output where only the first processor opens
77          the file.  All other processors send their
78          data to the first processor to print.
79 
80     The user can open an alternative visualization context with
81     PetscViewerASCIIOpen() - output to a specified file.
82 
83     Level: developer
84 
85 .keywords: TS, trajectory, timestep, view
86 
87 .seealso: PetscViewerASCIIOpen()
88 @*/
89 PetscErrorCode  TSTrajectoryView(TSTrajectory tj,PetscViewer viewer)
90 {
91   PetscErrorCode ierr;
92   PetscBool      iascii;
93 
94   PetscFunctionBegin;
95   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
96   if (!viewer) {
97     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)tj),&viewer);CHKERRQ(ierr);
98   }
99   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
100   PetscCheckSameComm(tj,1,viewer,2);
101 
102   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
103   if (iascii) {
104     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)tj,viewer);CHKERRQ(ierr);
105     ierr = PetscViewerASCIIPrintf(viewer,"  total number of recomputations for adjoint calculation = %D\n",tj->recomps);CHKERRQ(ierr);
106     ierr = PetscViewerASCIIPrintf(viewer,"  disk checkpoint reads = %D\n",tj->diskreads);CHKERRQ(ierr);
107     ierr = PetscViewerASCIIPrintf(viewer,"  disk checkpoint writes = %D\n",tj->diskwrites);CHKERRQ(ierr);
108     if (tj->ops->view) {
109       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
110       ierr = (*tj->ops->view)(tj,viewer);CHKERRQ(ierr);
111       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
112     }
113   }
114   PetscFunctionReturn(0);
115 }
116 
117 /*@C
118    TSTrajectorySetVariableNames - Sets the name of each component in the solution vector so that it may be saved with the trajectory
119 
120    Collective on TSTrajectory
121 
122    Input Parameters:
123 +  tr - the trajectory context
124 -  names - the names of the components, final string must be NULL
125 
126    Level: intermediate
127 
128    Note: Fortran interface is not possible because of the string array argument
129 
130 .keywords: TS, TSTrajectory, vector, monitor, view
131 
132 .seealso: TSTrajectory, TSGetTrajectory()
133 @*/
134 PetscErrorCode  TSTrajectorySetVariableNames(TSTrajectory ctx,const char * const *names)
135 {
136   PetscErrorCode    ierr;
137 
138   PetscFunctionBegin;
139   ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr);
140   ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr);
141   PetscFunctionReturn(0);
142 }
143 
144 /*@C
145    TSTrjactorySetTransform - Solution vector will be transformed by provided function before being saved to disk
146 
147    Collective on TSLGCtx
148 
149    Input Parameters:
150 +  tj - the TSTrajectory context
151 .  transform - the transform function
152 .  destroy - function to destroy the optional context
153 -  ctx - optional context used by transform function
154 
155    Level: intermediate
156 
157 .keywords: TSTrajectory,  vector, monitor, view
158 
159 .seealso:  TSTrajectorySetVariableNames(), TSTrajectory, TSMonitorLGSetTransform()
160 @*/
161 PetscErrorCode  TSTrajectorySetTransform(TSTrajectory tj,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
162 {
163   PetscFunctionBegin;
164   tj->transform        = transform;
165   tj->transformdestroy = destroy;
166   tj->transformctx     = tctx;
167   PetscFunctionReturn(0);
168 }
169 
170 
171 /*@
172   TSTrajectoryCreate - This function creates an empty trajectory object used to store the time dependent solution of an ODE/DAE
173 
174   Collective on MPI_Comm
175 
176   Input Parameter:
177 . comm - the communicator
178 
179   Output Parameter:
180 . tj   - the trajectory object
181 
182   Level: developer
183 
184   Notes: Usually one does not call this routine, it is called automatically when one calls TSSetSaveTrajectory().
185 
186 .keywords: TS, trajectory, create
187 
188 .seealso: TSTrajectorySetUp(), TSTrajectoryDestroy(), TSTrajectorySetType(), TSTrajectorySetVariableNames(), TSGetTrajectory(), TSTrajectorySetKeepFiles()
189 @*/
190 PetscErrorCode  TSTrajectoryCreate(MPI_Comm comm,TSTrajectory *tj)
191 {
192   TSTrajectory   t;
193   PetscErrorCode ierr;
194 
195   PetscFunctionBegin;
196   PetscValidPointer(tj,2);
197   *tj = NULL;
198   ierr = TSInitializePackage();CHKERRQ(ierr);
199 
200   ierr = PetscHeaderCreate(t,TSTRAJECTORY_CLASSID,"TSTrajectory","Time stepping","TS",comm,TSTrajectoryDestroy,TSTrajectoryView);CHKERRQ(ierr);
201   t->setupcalled = PETSC_FALSE;
202   t->keepfiles   = PETSC_TRUE;
203   *tj  = t;
204   ierr = TSTrajectorySetDirname(t,"SA-data");CHKERRQ(ierr);
205   ierr = TSTrajectorySetFiletemplate(t,"/SA-%06D.bin");CHKERRQ(ierr);
206   PetscFunctionReturn(0);
207 }
208 
209 /*@C
210   TSTrajectorySetType - Sets the storage method to be used as in a trajectory
211 
212   Collective on TS
213 
214   Input Parameters:
215 + tj   - the TSTrajectory context
216 . ts   - the TS context
217 - type - a known method
218 
219   Options Database Command:
220 . -ts_trajectory_type <type> - Sets the method; use -help for a list of available methods (for instance, basic)
221 
222    Level: developer
223 
224 .keywords: TS, trajectory, timestep, set, type
225 
226 .seealso: TS, TSTrajectoryCreate(), TSTrajectorySetFromOptions(), TSTrajectoryDestroy()
227 
228 @*/
229 PetscErrorCode  TSTrajectorySetType(TSTrajectory tj,TS ts,const TSTrajectoryType type)
230 {
231   PetscErrorCode (*r)(TSTrajectory,TS);
232   PetscBool      match;
233   PetscErrorCode ierr;
234 
235   PetscFunctionBegin;
236   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
237   ierr = PetscObjectTypeCompare((PetscObject)tj,type,&match);CHKERRQ(ierr);
238   if (match) PetscFunctionReturn(0);
239 
240   ierr = PetscFunctionListFind(TSTrajectoryList,type,&r);CHKERRQ(ierr);
241   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown TSTrajectory type: %s",type);
242   if (tj->ops->destroy) {
243     ierr = (*(tj)->ops->destroy)(tj);CHKERRQ(ierr);
244 
245     tj->ops->destroy = NULL;
246   }
247   ierr = PetscMemzero(tj->ops,sizeof(*tj->ops));CHKERRQ(ierr);
248 
249   ierr = PetscObjectChangeTypeName((PetscObject)tj,type);CHKERRQ(ierr);
250   ierr = (*r)(tj,ts);CHKERRQ(ierr);
251   PetscFunctionReturn(0);
252 }
253 
254 PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Basic(TSTrajectory,TS);
255 PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Singlefile(TSTrajectory,TS);
256 PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Memory(TSTrajectory,TS);
257 PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Visualization(TSTrajectory,TS);
258 
259 /*@C
260   TSTrajectoryRegisterAll - Registers all of the trajectory storage schecmes in the TS package.
261 
262   Not Collective
263 
264   Level: developer
265 
266 .keywords: TS, trajectory, register, all
267 
268 .seealso: TSTrajectoryRegister()
269 @*/
270 PetscErrorCode  TSTrajectoryRegisterAll(void)
271 {
272   PetscErrorCode ierr;
273 
274   PetscFunctionBegin;
275   if (TSTrajectoryRegisterAllCalled) PetscFunctionReturn(0);
276   TSTrajectoryRegisterAllCalled = PETSC_TRUE;
277 
278   ierr = TSTrajectoryRegister(TSTRAJECTORYBASIC,TSTrajectoryCreate_Basic);CHKERRQ(ierr);
279   ierr = TSTrajectoryRegister(TSTRAJECTORYSINGLEFILE,TSTrajectoryCreate_Singlefile);CHKERRQ(ierr);
280   ierr = TSTrajectoryRegister(TSTRAJECTORYMEMORY,TSTrajectoryCreate_Memory);CHKERRQ(ierr);
281   ierr = TSTrajectoryRegister(TSTRAJECTORYVISUALIZATION,TSTrajectoryCreate_Visualization);CHKERRQ(ierr);
282   PetscFunctionReturn(0);
283 }
284 
285 /*@
286    TSTrajectoryDestroy - Destroys a trajectory context
287 
288    Collective on TSTrajectory
289 
290    Input Parameter:
291 .  tj - the TSTrajectory context obtained from TSTrajectoryCreate()
292 
293    Level: developer
294 
295 .keywords: TS, trajectory, timestep, destroy
296 
297 .seealso: TSTrajectoryCreate(), TSTrajectorySetUp()
298 @*/
299 PetscErrorCode  TSTrajectoryDestroy(TSTrajectory *tj)
300 {
301   PetscErrorCode ierr;
302 
303   PetscFunctionBegin;
304   if (!*tj) PetscFunctionReturn(0);
305   PetscValidHeaderSpecific((*tj),TSTRAJECTORY_CLASSID,1);
306   if (--((PetscObject)(*tj))->refct > 0) {*tj = 0; PetscFunctionReturn(0);}
307 
308   if ((*tj)->transformdestroy) {ierr = (*(*tj)->transformdestroy)((*tj)->transformctx);CHKERRQ(ierr);}
309   if ((*tj)->ops->destroy) {ierr = (*(*tj)->ops->destroy)((*tj));CHKERRQ(ierr);}
310   ierr = PetscViewerDestroy(&(*tj)->monitor);CHKERRQ(ierr);
311   ierr = PetscStrArrayDestroy(&(*tj)->names);CHKERRQ(ierr);
312   ierr = PetscFree((*tj)->dirname);CHKERRQ(ierr);
313   ierr = PetscFree((*tj)->filetemplate);CHKERRQ(ierr);
314   ierr = PetscHeaderDestroy(tj);CHKERRQ(ierr);
315   PetscFunctionReturn(0);
316 }
317 
318 /*
319   TSTrajectorySetTypeFromOptions_Private - Sets the type of ts from user options.
320 
321   Collective on TSTrajectory
322 
323   Input Parameter:
324 + tj - the TSTrajectory context
325 - ts - the TS context
326 
327   Options Database Keys:
328 . -ts_trajectory_type <type> - TSTRAJECTORYBASIC, TSTRAJECTORYMEMORY, TSTRAJECTORYSINGLEFILE, TSTRAJECTORYVISUALIZATION
329 
330   Level: developer
331 
332 .keywords: TS, trajectory, set, options, type
333 
334 .seealso: TSTrajectorySetFromOptions(), TSTrajectorySetType()
335 */
336 static PetscErrorCode TSTrajectorySetTypeFromOptions_Private(PetscOptionItems *PetscOptionsObject,TSTrajectory tj,TS ts)
337 {
338   PetscBool      opt;
339   const char     *defaultType;
340   char           typeName[256];
341   PetscBool      flg;
342   PetscErrorCode ierr;
343 
344   PetscFunctionBegin;
345   if (((PetscObject)tj)->type_name) defaultType = ((PetscObject)tj)->type_name;
346   else defaultType = TSTRAJECTORYBASIC;
347 
348   ierr = TSTrajectoryRegisterAll();CHKERRQ(ierr);
349   ierr = PetscOptionsFList("-ts_trajectory_type","TSTrajectory method","TSTrajectorySetType",TSTrajectoryList,defaultType,typeName,256,&opt);CHKERRQ(ierr);
350   if (opt) {
351     ierr = PetscStrcmp(typeName,TSTRAJECTORYMEMORY,&flg);CHKERRQ(ierr);
352     ierr = TSTrajectorySetType(tj,ts,typeName);CHKERRQ(ierr);
353   } else {
354     ierr = TSTrajectorySetType(tj,ts,defaultType);CHKERRQ(ierr);
355   }
356   PetscFunctionReturn(0);
357 }
358 
359 /*@
360    TSTrajectorySetMonitor - Monitor the schedules generated by the checkpointing controller
361 
362    Collective on TSTrajectory
363 
364    Input Arguments:
365 +  tj - the TSTrajectory context
366 -  flg - PETSC_TRUE to active a monitor, PETSC_FALSE to disable
367 
368    Options Database Keys:
369 .  -ts_trajectory_monitor - print TSTrajectory information
370 
371    Level: developer
372 
373 .keywords: TS, trajectory, set, monitor
374 
375 .seealso: TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectorySetUp()
376 @*/
377 PetscErrorCode TSTrajectorySetMonitor(TSTrajectory tj,PetscBool flg)
378 {
379   PetscErrorCode ierr;
380 
381   PetscFunctionBegin;
382   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
383   PetscValidLogicalCollectiveBool(tj,flg,2);
384   if (flg) {
385     if (!tj->monitor) {ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)tj),"stdout",&tj->monitor);CHKERRQ(ierr);}
386   } else {
387     ierr = PetscViewerDestroy(&tj->monitor);CHKERRQ(ierr);
388   }
389   PetscFunctionReturn(0);
390 }
391 
392 /*@
393    TSTrajectorySetKeepFiles - Keep the files generated by the TSTrajectory
394 
395    Collective on TSTrajectory
396 
397    Input Arguments:
398 +  tj - the TSTrajectory context
399 -  flg - PETSC_TRUE to save, PETSC_FALSE to disable
400 
401    Options Database Keys:
402 .  -ts_trajectory_keep_files - have it keep the files
403 
404    Notes: 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.
405 
406    Level: advanced
407 
408 .keywords: TS, trajectory, set, monitor
409 
410 .seealso: TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectorySetUp(), TSTrajectorySetMonitor()
411 @*/
412 PetscErrorCode TSTrajectorySetKeepFiles(TSTrajectory tj,PetscBool flg)
413 {
414   PetscFunctionBegin;
415   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
416   PetscValidLogicalCollectiveBool(tj,flg,2);
417   tj->keepfiles = flg;
418   PetscFunctionReturn(0);
419 }
420 
421 /*@C
422    TSTrajectorySetDirname - Specify the name of the directory where disk checkpoints are stored.
423 
424    Collective on TSTrajectory
425 
426    Input Arguments:
427 +  tj      - the TSTrajectory context
428 -  dirname - the directory name
429 
430    Options Database Keys:
431 .  -ts_trajectory_dirname - set the directory name
432 
433    Notes: The final location of the files is determined by dirname/filetemplate where filetemplate was provided by TSTrajectorySetFiletemplate()
434 
435    Level: developer
436 
437 .keywords: TS, trajectory, set
438 
439 .seealso: TSTrajectorySetFiletemplate(),TSTrajectorySetUp()
440 @*/
441 PetscErrorCode TSTrajectorySetDirname(TSTrajectory tj,const char dirname[])
442 {
443   PetscErrorCode ierr;
444   PetscFunctionBegin;
445   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
446   ierr = PetscFree(tj->dirname);CHKERRQ(ierr);
447   ierr = PetscStrallocpy(dirname,&tj->dirname);CHKERRQ(ierr);
448   PetscFunctionReturn(0);
449 }
450 
451 /*@C
452    TSTrajectorySetFiletemplate - Specify the name template for the files storing checkpoints.
453 
454    Collective on TSTrajectory
455 
456    Input Arguments:
457 +  tj      - the TSTrajectory context
458 -  filetemplate - the template
459 
460    Options Database Keys:
461 .  -ts_trajectory_file_template - set the file name template
462 
463    Notes: The name template should be of the form, for example filename-%06D.bin
464 
465    The final location of the files is determined by dirname/filetemplate where dirname was provided by TSTrajectorySetDirname(). The %06D is replaced by the
466    timestep counter
467 
468    Level: developer
469 
470 .keywords: TS, trajectory, set
471 
472 .seealso: TSTrajectorySetDirname(),TSTrajectorySetUp()
473 @*/
474 PetscErrorCode TSTrajectorySetFiletemplate(TSTrajectory tj,const char filetemplate[])
475 {
476   PetscErrorCode ierr;
477   PetscFunctionBegin;
478   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
479   ierr = PetscFree(tj->filetemplate);CHKERRQ(ierr);
480   ierr = PetscStrallocpy(filetemplate,&tj->filetemplate);CHKERRQ(ierr);
481   PetscFunctionReturn(0);
482 }
483 
484 /*@
485    TSTrajectorySetFromOptions - Sets various TSTrajectory parameters from user options.
486 
487    Collective on TSTrajectory
488 
489    Input Parameter:
490 +  tj - the TSTrajectory context obtained from TSTrajectoryCreate()
491 -  ts - the TS context
492 
493    Options Database Keys:
494 +  -ts_trajectory_type <type> - TSTRAJECTORYBASIC, TSTRAJECTORYMEMORY, TSTRAJECTORYSINGLEFILE, TSTRAJECTORYVISUALIZATION
495 .  -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
496 -  -ts_trajectory_monitor - print TSTrajectory information
497 
498    Level: developer
499 
500    Notes: This is not normally called directly by users
501 
502 .keywords: TS, trajectory, timestep, set, options, database
503 
504 .seealso: TSSetSaveTrajectory(), TSTrajectorySetUp()
505 @*/
506 PetscErrorCode  TSTrajectorySetFromOptions(TSTrajectory tj,TS ts)
507 {
508   PetscBool      set,flg;
509   char           dirname[PETSC_MAX_PATH_LEN],filetemplate[PETSC_MAX_PATH_LEN];
510   PetscErrorCode ierr;
511 
512   PetscFunctionBegin;
513   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
514   PetscValidHeaderSpecific(ts,TS_CLASSID,2);
515   ierr = PetscObjectOptionsBegin((PetscObject)tj);CHKERRQ(ierr);
516   ierr = TSTrajectorySetTypeFromOptions_Private(PetscOptionsObject,tj,ts);CHKERRQ(ierr);
517   ierr = PetscOptionsBool("-ts_trajectory_monitor","Print checkpointing schedules","TSTrajectorySetMonitor",tj->monitor ? PETSC_TRUE:PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
518   if (set) {ierr = TSTrajectorySetMonitor(tj,flg);CHKERRQ(ierr);}
519 
520   ierr = PetscOptionsBool("-ts_trajectory_keep_files","Keep any trajectory files generated during the run","TSTrajectorySetKeepFiles",tj->keepfiles,&flg,&set);CHKERRQ(ierr);
521   if (set) {ierr = TSTrajectorySetKeepFiles(tj,flg);CHKERRQ(ierr);}
522 
523   ierr = PetscOptionsString("-ts_trajectory_dirname","Directory name for TSTrajectory file","TSTrajectorySetDirname",0,dirname,PETSC_MAX_PATH_LEN-14,&set);CHKERRQ(ierr);
524   if (set) {
525     ierr = TSTrajectorySetDirname(tj,dirname);CHKERRQ(ierr);
526   }
527 
528   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);
529   if (set) {
530     const char *ptr,*ptr2;
531     size_t     len;
532 
533     if (!filetemplate[0]) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_trajectory_file_template requires a file name template, e.g. filename-%%06D.bin");
534     /* Do some cursory validation of the input. */
535     ierr = PetscStrstr(filetemplate,"%",(char**)&ptr);CHKERRQ(ierr);
536     if (!ptr) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_trajectory_file_template requires a file name template, e.g. filename-%%06D.bin");
537     for (ptr++; ptr && *ptr; ptr++) {
538       ierr = PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);CHKERRQ(ierr);
539       if (!ptr2 && (*ptr < '0' || '9' < *ptr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Invalid file template argument to -ts_trajectory_file_template, should look like filename-%%06D.bin");
540       if (ptr2) break;
541     }
542     ierr = PetscStrcat(dirname,"/");CHKERRQ(ierr);
543     ierr = PetscStrlen(filetemplate,&len);CHKERRQ(ierr);
544     ierr = PetscStrncat(dirname,filetemplate,PETSC_MAX_PATH_LEN-len-1);CHKERRQ(ierr);
545     ierr = TSTrajectorySetFiletemplate(tj,filetemplate);CHKERRQ(ierr);
546   }
547 
548   /* Handle specific TSTrajectory options */
549   if (tj->ops->setfromoptions) {
550     ierr = (*tj->ops->setfromoptions)(PetscOptionsObject,tj);CHKERRQ(ierr);
551   }
552   ierr = PetscOptionsEnd();CHKERRQ(ierr);
553   PetscFunctionReturn(0);
554 }
555 
556 /*@
557    TSTrajectorySetUp - Sets up the internal data structures, e.g. stacks, for the later use
558    of a TS trajectory.
559 
560    Collective on TS
561 
562    Input Parameter:
563 +  ts - the TS context obtained from TSCreate()
564 -  tj - the TS trajectory context
565 
566    Level: developer
567 
568 .keywords: TS, trajectory, setup
569 
570 .seealso: TSSetSaveTrajectory(), TSTrajectoryCreate(), TSTrajectoryDestroy()
571 @*/
572 PetscErrorCode  TSTrajectorySetUp(TSTrajectory tj,TS ts)
573 {
574   PetscErrorCode ierr;
575 
576   PetscFunctionBegin;
577   if (!tj) PetscFunctionReturn(0);
578   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
579   PetscValidHeaderSpecific(ts,TS_CLASSID,2);
580   if (tj->setupcalled) PetscFunctionReturn(0);
581 
582   if (!((PetscObject)tj)->type_name) {
583     ierr = TSTrajectorySetType(tj,ts,TSTRAJECTORYBASIC);CHKERRQ(ierr);
584   }
585   if (tj->ops->setup) {
586     ierr = (*tj->ops->setup)(tj,ts);CHKERRQ(ierr);
587   }
588 
589   tj->setupcalled = PETSC_TRUE;
590 
591   /* Set the counters to zero */
592   tj->recomps    = 0;
593   tj->diskreads  = 0;
594   tj->diskwrites = 0;
595   PetscFunctionReturn(0);
596 }
597