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