xref: /petsc/src/ts/trajectory/interface/traj.c (revision 64e38db7c5aae0ecdbe282bf3dcdf34c98cb00d9)
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 .keywords: TS, TSTrajectory, vector, monitor, view
129 
130 .seealso: TSTrajectory, TSGetTrajectory()
131 @*/
132 PetscErrorCode  TSTrajectorySetVariableNames(TSTrajectory ctx,const char * const *names)
133 {
134   PetscErrorCode    ierr;
135 
136   PetscFunctionBegin;
137   ierr = PetscStrArrayDestroy(&ctx->names);CHKERRQ(ierr);
138   ierr = PetscStrArrayallocpy(names,&ctx->names);CHKERRQ(ierr);
139   PetscFunctionReturn(0);
140 }
141 
142 /*@C
143    TSTrjactorySetTransform - Solution vector will be transformed by provided function before being saved to disk
144 
145    Collective on TSLGCtx
146 
147    Input Parameters:
148 +  tj - the TSTrajectory context
149 .  transform - the transform function
150 .  destroy - function to destroy the optional context
151 -  ctx - optional context used by transform function
152 
153    Level: intermediate
154 
155 .keywords: TSTrajectory,  vector, monitor, view
156 
157 .seealso:  TSTrajectorySetVariableNames(), TSTrajectory, TSMonitorLGSetTransform()
158 @*/
159 PetscErrorCode  TSTrajectorySetTransform(TSTrajectory tj,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
160 {
161   PetscFunctionBegin;
162   tj->transform        = transform;
163   tj->transformdestroy = destroy;
164   tj->transformctx     = tctx;
165   PetscFunctionReturn(0);
166 }
167 
168 
169 /*@C
170   TSTrajectoryCreate - This function creates an empty trajectory object used to store the time dependent solution of an ODE/DAE
171 
172   Collective on MPI_Comm
173 
174   Input Parameter:
175 . comm - the communicator
176 
177   Output Parameter:
178 . tj   - the trajectory object
179 
180   Level: developer
181 
182   Notes: Usually one does not call this routine, it is called automatically when one calls TSSetSaveTrajectory().
183 
184 .keywords: TS, trajectory, create
185 
186 .seealso: TSTrajectorySetUp(), TSTrajectoryDestroy(), TSTrajectorySetType(), TSTrajectorySetVariableNames(), TSGetTrajectory(), TSTrajectorySetKeepFiles()
187 @*/
188 PetscErrorCode  TSTrajectoryCreate(MPI_Comm comm,TSTrajectory *tj)
189 {
190   TSTrajectory   t;
191   PetscErrorCode ierr;
192 
193   PetscFunctionBegin;
194   PetscValidPointer(tj,2);
195   *tj = NULL;
196   ierr = TSInitializePackage();CHKERRQ(ierr);
197 
198   ierr = PetscHeaderCreate(t,TSTRAJECTORY_CLASSID,"TSTrajectory","Time stepping","TS",comm,TSTrajectoryDestroy,TSTrajectoryView);CHKERRQ(ierr);
199   t->setupcalled = PETSC_FALSE;
200   t->keepfiles   = PETSC_TRUE;
201   *tj = t;
202   PetscFunctionReturn(0);
203 }
204 
205 /*@C
206   TSTrajectorySetType - Sets the storage method to be used as in a trajectory
207 
208   Collective on TS
209 
210   Input Parameters:
211 + tj   - the TSTrajectory context
212 . ts   - the TS context
213 - type - a known method
214 
215   Options Database Command:
216 . -ts_trajectory_type <type> - Sets the method; use -help for a list of available methods (for instance, basic)
217 
218    Level: developer
219 
220 .keywords: TS, trajectory, timestep, set, type
221 
222 .seealso: TS, TSTrajectoryCreate(), TSTrajectorySetFromOptions(), TSTrajectoryDestroy()
223 
224 @*/
225 PetscErrorCode  TSTrajectorySetType(TSTrajectory tj,TS ts,const TSTrajectoryType type)
226 {
227   PetscErrorCode (*r)(TSTrajectory,TS);
228   PetscBool      match;
229   PetscErrorCode ierr;
230 
231   PetscFunctionBegin;
232   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
233   ierr = PetscObjectTypeCompare((PetscObject)tj,type,&match);CHKERRQ(ierr);
234   if (match) PetscFunctionReturn(0);
235 
236   ierr = PetscFunctionListFind(TSTrajectoryList,type,&r);CHKERRQ(ierr);
237   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown TSTrajectory type: %s",type);
238   if (tj->ops->destroy) {
239     ierr = (*(tj)->ops->destroy)(tj);CHKERRQ(ierr);
240 
241     tj->ops->destroy = NULL;
242   }
243   ierr = PetscMemzero(tj->ops,sizeof(*tj->ops));CHKERRQ(ierr);
244 
245   ierr = PetscObjectChangeTypeName((PetscObject)tj,type);CHKERRQ(ierr);
246   ierr = (*r)(tj,ts);CHKERRQ(ierr);
247   PetscFunctionReturn(0);
248 }
249 
250 PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Basic(TSTrajectory,TS);
251 PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Singlefile(TSTrajectory,TS);
252 PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Memory(TSTrajectory,TS);
253 PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Visualization(TSTrajectory,TS);
254 
255 /*@C
256   TSTrajectoryRegisterAll - Registers all of the trajectory storage schecmes in the TS package.
257 
258   Not Collective
259 
260   Level: developer
261 
262 .keywords: TS, trajectory, register, all
263 
264 .seealso: TSTrajectoryRegister()
265 @*/
266 PetscErrorCode  TSTrajectoryRegisterAll(void)
267 {
268   PetscErrorCode ierr;
269 
270   PetscFunctionBegin;
271   if (TSTrajectoryRegisterAllCalled) PetscFunctionReturn(0);
272   TSTrajectoryRegisterAllCalled = PETSC_TRUE;
273 
274   ierr = TSTrajectoryRegister(TSTRAJECTORYBASIC,TSTrajectoryCreate_Basic);CHKERRQ(ierr);
275   ierr = TSTrajectoryRegister(TSTRAJECTORYSINGLEFILE,TSTrajectoryCreate_Singlefile);CHKERRQ(ierr);
276   ierr = TSTrajectoryRegister(TSTRAJECTORYMEMORY,TSTrajectoryCreate_Memory);CHKERRQ(ierr);
277   ierr = TSTrajectoryRegister(TSTRAJECTORYVISUALIZATION,TSTrajectoryCreate_Visualization);CHKERRQ(ierr);
278   PetscFunctionReturn(0);
279 }
280 
281 /*@
282    TSTrajectoryDestroy - Destroys a trajectory context
283 
284    Collective on TSTrajectory
285 
286    Input Parameter:
287 .  tj - the TSTrajectory context obtained from TSTrajectoryCreate()
288 
289    Level: developer
290 
291 .keywords: TS, trajectory, timestep, destroy
292 
293 .seealso: TSTrajectoryCreate(), TSTrajectorySetUp()
294 @*/
295 PetscErrorCode  TSTrajectoryDestroy(TSTrajectory *tj)
296 {
297   PetscErrorCode ierr;
298 
299   PetscFunctionBegin;
300   if (!*tj) PetscFunctionReturn(0);
301   PetscValidHeaderSpecific((*tj),TSTRAJECTORY_CLASSID,1);
302   if (--((PetscObject)(*tj))->refct > 0) {*tj = 0; PetscFunctionReturn(0);}
303 
304   if ((*tj)->transformdestroy) {ierr = (*(*tj)->transformdestroy)((*tj)->transformctx);CHKERRQ(ierr);}
305   if ((*tj)->ops->destroy) {ierr = (*(*tj)->ops->destroy)((*tj));CHKERRQ(ierr);}
306   ierr = PetscViewerDestroy(&(*tj)->monitor);CHKERRQ(ierr);
307   ierr = PetscStrArrayDestroy(&(*tj)->names);CHKERRQ(ierr);
308   ierr = PetscFree((*tj)->dirname);CHKERRQ(ierr);
309   ierr = PetscFree((*tj)->filetemplate);CHKERRQ(ierr);
310   ierr = PetscHeaderDestroy(tj);CHKERRQ(ierr);
311   PetscFunctionReturn(0);
312 }
313 
314 /*
315   TSTrajectorySetTypeFromOptions_Private - Sets the type of ts from user options.
316 
317   Collective on TSTrajectory
318 
319   Input Parameter:
320 + tj - the TSTrajectory context
321 - ts - the TS context
322 
323   Options Database Keys:
324 . -ts_trajectory_type <type> - TSTRAJECTORYBASIC, TSTRAJECTORYMEMORY, TSTRAJECTORYSINGLEFILE, TSTRAJECTORYVISUALIZATION
325 
326   Level: developer
327 
328 .keywords: TS, trajectory, set, options, type
329 
330 .seealso: TSTrajectorySetFromOptions(), TSTrajectorySetType()
331 */
332 static PetscErrorCode TSTrajectorySetTypeFromOptions_Private(PetscOptionItems *PetscOptionsObject,TSTrajectory tj,TS ts)
333 {
334   PetscBool      opt;
335   const char     *defaultType;
336   char           typeName[256];
337   PetscBool      flg;
338   PetscErrorCode ierr;
339 
340   PetscFunctionBegin;
341   if (((PetscObject)tj)->type_name) defaultType = ((PetscObject)tj)->type_name;
342   else defaultType = TSTRAJECTORYBASIC;
343 
344   ierr = TSTrajectoryRegisterAll();CHKERRQ(ierr);
345   ierr = PetscOptionsFList("-ts_trajectory_type","TSTrajectory method","TSTrajectorySetType",TSTrajectoryList,defaultType,typeName,256,&opt);CHKERRQ(ierr);
346   if (opt) {
347     ierr = PetscStrcmp(typeName,TSTRAJECTORYMEMORY,&flg);CHKERRQ(ierr);
348     ierr = TSTrajectorySetType(tj,ts,typeName);CHKERRQ(ierr);
349   } else {
350     ierr = TSTrajectorySetType(tj,ts,defaultType);CHKERRQ(ierr);
351   }
352   PetscFunctionReturn(0);
353 }
354 
355 /*@
356    TSTrajectorySetMonitor - Monitor the schedules generated by the checkpointing controller
357 
358    Collective on TSTrajectory
359 
360    Input Arguments:
361 +  tj - the TSTrajectory context
362 -  flg - PETSC_TRUE to active a monitor, PETSC_FALSE to disable
363 
364    Options Database Keys:
365 .  -ts_trajectory_monitor - print TSTrajectory information
366 
367    Level: developer
368 
369 .keywords: TS, trajectory, set, monitor
370 
371 .seealso: TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectorySetUp()
372 @*/
373 PetscErrorCode TSTrajectorySetMonitor(TSTrajectory tj,PetscBool flg)
374 {
375   PetscErrorCode ierr;
376 
377   PetscFunctionBegin;
378   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
379   PetscValidLogicalCollectiveBool(tj,flg,2);
380   if (flg) {
381     if (!tj->monitor) {ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)tj),"stdout",&tj->monitor);CHKERRQ(ierr);}
382   } else {
383     ierr = PetscViewerDestroy(&tj->monitor);CHKERRQ(ierr);
384   }
385   PetscFunctionReturn(0);
386 }
387 
388 /*@
389    TSTrajectorySetKeepFiles - Keep the files generated by the TSTrajectory
390 
391    Collective on TSTrajectory
392 
393    Input Arguments:
394 +  tj - the TSTrajectory context
395 -  flg - PETSC_TRUE to save, PETSC_FALSE to disable
396 
397    Options Database Keys:
398 .  -ts_trajectory_keep_files - have it keep the files
399 
400    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.
401 
402    Level: advanced
403 
404 .keywords: TS, trajectory, set, monitor
405 
406 .seealso: TSTrajectoryCreate(), TSTrajectoryDestroy(), TSTrajectorySetUp(), TSTrajectorySetMonitor()
407 @*/
408 PetscErrorCode TSTrajectorySetKeepFiles(TSTrajectory tj,PetscBool flg)
409 {
410   PetscFunctionBegin;
411   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
412   PetscValidLogicalCollectiveBool(tj,flg,2);
413   tj->keepfiles = flg;
414   PetscFunctionReturn(0);
415 }
416 
417 /*@
418    TSTrajectorySetDirname - Specify the name of the directory where disk checkpoints are stored.
419 
420    Collective on TSTrajectory
421 
422    Input Arguments:
423 +  tj      - the TSTrajectory context
424 -  dirname - the directory name
425 
426    Options Database Keys:
427 .  -ts_trajectory_dirname - set the directory name
428 
429    Level: developer
430 
431 .keywords: TS, trajectory, set
432 
433 .seealso: TSTrajectorySetFiletemplate(),TSTrajectorySetUp()
434 @*/
435 PetscErrorCode TSTrajectorySetDirname(TSTrajectory tj,const char dirname[])
436 {
437   PetscErrorCode ierr;
438   PetscFunctionBegin;
439   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
440   ierr = PetscStrallocpy(dirname,&tj->dirname);CHKERRQ(ierr);
441   PetscFunctionReturn(0);
442 }
443 
444 /*@
445    TSTrajectorySetFiletemplate - Specify the name template for the files storing checkpoints.
446 
447    Collective on TSTrajectory
448 
449    Input Arguments:
450 +  tj      - the TSTrajectory context
451 -  filetemplate - the directory name
452 
453    Options Database Keys:
454 .  -ts_trajectory_file - set the file name template
455 
456    Level: developer
457 
458 .keywords: TS, trajectory, set
459 
460 .seealso: TSTrajectorySetFiletemplate(),TSTrajectorySetUp()
461 @*/
462 PetscErrorCode TSTrajectorySetFiletemplate(TSTrajectory tj,const char filetemplate[])
463 {
464   PetscErrorCode ierr;
465   PetscFunctionBegin;
466   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
467   ierr = PetscStrallocpy(filetemplate,&tj->filetemplate);CHKERRQ(ierr);
468   PetscFunctionReturn(0);
469 }
470 
471 /*@
472    TSTrajectorySetFromOptions - Sets various TSTrajectory parameters from user options.
473 
474    Collective on TSTrajectory
475 
476    Input Parameter:
477 +  tj - the TSTrajectory context obtained from TSTrajectoryCreate()
478 -  ts - the TS context
479 
480    Options Database Keys:
481 +  -ts_trajectory_type <type> - TSTRAJECTORYBASIC, TSTRAJECTORYMEMORY, TSTRAJECTORYSINGLEFILE, TSTRAJECTORYVISUALIZATION
482 .  -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
483 -  -ts_trajectory_monitor - print TSTrajectory information
484 
485    Level: developer
486 
487    Notes: This is not normally called directly by users
488 
489 .keywords: TS, trajectory, timestep, set, options, database
490 
491 .seealso: TSSetSaveTrajectory(), TSTrajectorySetUp()
492 @*/
493 PetscErrorCode  TSTrajectorySetFromOptions(TSTrajectory tj,TS ts)
494 {
495   PetscBool      set,flg;
496   char           dirname[PETSC_MAX_PATH_LEN],filetemplate[PETSC_MAX_PATH_LEN];
497   PetscErrorCode ierr;
498 
499   PetscFunctionBegin;
500   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
501   PetscValidHeaderSpecific(ts,TS_CLASSID,2);
502   ierr = PetscObjectOptionsBegin((PetscObject)tj);CHKERRQ(ierr);
503   ierr = TSTrajectorySetTypeFromOptions_Private(PetscOptionsObject,tj,ts);CHKERRQ(ierr);
504   ierr = PetscOptionsBool("-ts_trajectory_monitor","Print checkpointing schedules","TSTrajectorySetMonitor",tj->monitor ? PETSC_TRUE:PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
505   if (set) {ierr = TSTrajectorySetMonitor(tj,flg);CHKERRQ(ierr);}
506 
507   ierr = PetscOptionsBool("-ts_trajectory_keep_files","Keep any trajectory files generated during the run","TSTrajectorySetKeepFiles",tj->keepfiles,&flg,&set);CHKERRQ(ierr);
508   if (set) {ierr = TSTrajectorySetKeepFiles(tj,flg);CHKERRQ(ierr);}
509 
510   ierr = PetscOptionsString("-ts_trajectory_dirname","Directory name for TSTrajectory file","TSTrajectorySetDirname",0,dirname,PETSC_MAX_PATH_LEN-14,&set);CHKERRQ(ierr);
511   if (!set) {
512     ierr = PetscStrcpy(dirname,"SA-data");CHKERRQ(ierr);
513   }
514   ierr = TSTrajectorySetDirname(tj,dirname);CHKERRQ(ierr);
515 
516   ierr = PetscOptionsString("-ts_trajectory_file","Template for TSTrajectory file name, use filename-%06D.bin","TSTrajectorySetFiletemplate",0,filetemplate,PETSC_MAX_PATH_LEN,&set);CHKERRQ(ierr);
517   if (set) {
518     size_t len;
519     const char *ptr,*ptr2;
520     if (!filetemplate[0]) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_trajectory_file requires a file name template, e.g. filename-%%06D.bin");
521     /* Do some cursory validation of the input. */
522     ierr = PetscStrstr(filetemplate,"%",(char**)&ptr);CHKERRQ(ierr);
523     if (!ptr) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_trajectory_file requires a file name template, e.g. filename-%%06D.bin");
524     for (ptr++; ptr && *ptr; ptr++) {
525       ierr = PetscStrchr("DdiouxX",*ptr,(char**)&ptr2);CHKERRQ(ierr);
526       if (!ptr2 && (*ptr < '0' || '9' < *ptr)) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Invalid file template argument to -ts_trajectory_file, should look like filename-%%06D.bin");
527       if (ptr2) break;
528     }
529     ierr = PetscStrcat(dirname,"/");CHKERRQ(ierr);
530     ierr = PetscStrlen(filetemplate,&len);CHKERRQ(ierr);
531     ierr = PetscStrncat(dirname,filetemplate,PETSC_MAX_PATH_LEN-len-1);CHKERRQ(ierr);
532   } else {
533     ierr = PetscStrcat(dirname,"/SA-%06D.bin");CHKERRQ(ierr);
534   }
535   ierr = TSTrajectorySetFiletemplate(tj,dirname);CHKERRQ(ierr);
536 
537   /* Handle specific TSTrajectory options */
538   if (tj->ops->setfromoptions) {
539     ierr = (*tj->ops->setfromoptions)(PetscOptionsObject,tj);CHKERRQ(ierr);
540   }
541   ierr = PetscOptionsEnd();CHKERRQ(ierr);
542   PetscFunctionReturn(0);
543 }
544 
545 /*@
546    TSTrajectorySetUp - Sets up the internal data structures, e.g. stacks, for the later use
547    of a TS trajectory.
548 
549    Collective on TS
550 
551    Input Parameter:
552 +  ts - the TS context obtained from TSCreate()
553 -  tj - the TS trajectory context
554 
555    Level: developer
556 
557 .keywords: TS, trajectory, setup
558 
559 .seealso: TSSetSaveTrajectory(), TSTrajectoryCreate(), TSTrajectoryDestroy()
560 @*/
561 PetscErrorCode  TSTrajectorySetUp(TSTrajectory tj,TS ts)
562 {
563   PetscErrorCode ierr;
564 
565   PetscFunctionBegin;
566   if (!tj) PetscFunctionReturn(0);
567   PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1);
568   PetscValidHeaderSpecific(ts,TS_CLASSID,2);
569   if (tj->setupcalled) PetscFunctionReturn(0);
570 
571   if (!((PetscObject)tj)->type_name) {
572     ierr = TSTrajectorySetType(tj,ts,TSTRAJECTORYBASIC);CHKERRQ(ierr);
573   }
574   if (tj->ops->setup) {
575     ierr = (*tj->ops->setup)(tj,ts);CHKERRQ(ierr);
576   }
577 
578   tj->setupcalled = PETSC_TRUE;
579 
580   /* Set the counters to zero */
581   tj->recomps    = 0;
582   tj->diskreads  = 0;
583   tj->diskwrites = 0;
584   PetscFunctionReturn(0);
585 }
586