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 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 @*/ 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 @*/ 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 @*/ 86 PetscErrorCode TSTrajectoryGetNumSteps(TSTrajectory tj, PetscInt *steps) 87 { 88 PetscFunctionBegin; 89 PetscValidHeaderSpecific(tj, TSTRAJECTORY_CLASSID, 1); 90 PetscValidIntPointer(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 @*/ 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 PetscValidRealPointer(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 @*/ 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 PetscValidRealPointer(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 /*@C 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 @*/ 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 /*@C 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 @*/ 304 PetscErrorCode TSTrajectoryView(TSTrajectory tj, PetscViewer viewer) 305 { 306 PetscBool iascii; 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, &iascii)); 315 if (iascii) { 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 + tr - the trajectory context 334 - names - the names of the components, final string must be NULL 335 336 Level: intermediate 337 338 Fortran Note: 339 Fortran interface is not possible because of the string array argument 340 341 .seealso: [](ch_ts), `TSTrajectory`, `TSGetTrajectory()` 342 @*/ 343 PetscErrorCode TSTrajectorySetVariableNames(TSTrajectory ctx, const char *const *names) 344 { 345 PetscFunctionBegin; 346 PetscValidHeaderSpecific(ctx, TSTRAJECTORY_CLASSID, 1); 347 PetscValidPointer(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 - ctx - optional context used by transform function 363 364 Level: intermediate 365 366 .seealso: [](ch_ts), `TSTrajectorySetVariableNames()`, `TSTrajectory`, `TSMonitorLGSetTransform()` 367 @*/ 368 PetscErrorCode TSTrajectorySetTransform(TSTrajectory tj, PetscErrorCode (*transform)(void *, Vec, Vec *), PetscErrorCode (*destroy)(void *), 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 @*/ 396 PetscErrorCode TSTrajectoryCreate(MPI_Comm comm, TSTrajectory *tj) 397 { 398 TSTrajectory t; 399 400 PetscFunctionBegin; 401 PetscValidPointer(tj, 2); 402 *tj = NULL; 403 PetscCall(TSInitializePackage()); 404 405 PetscCall(PetscHeaderCreate(t, TSTRAJECTORY_CLASSID, "TSTrajectory", "Time stepping", "TS", comm, TSTrajectoryDestroy, TSTrajectoryView)); 406 t->setupcalled = PETSC_FALSE; 407 PetscCall(TSHistoryCreate(comm, &t->tsh)); 408 409 t->lag.order = 1; 410 t->lag.L = NULL; 411 t->lag.T = NULL; 412 t->lag.W = NULL; 413 t->lag.WW = NULL; 414 t->lag.TW = NULL; 415 t->lag.TT = NULL; 416 t->lag.caching = PETSC_TRUE; 417 t->lag.Ucached.id = 0; 418 t->lag.Ucached.state = -1; 419 t->lag.Ucached.time = PETSC_MIN_REAL; 420 t->lag.Ucached.step = PETSC_MAX_INT; 421 t->lag.Udotcached.id = 0; 422 t->lag.Udotcached.state = -1; 423 t->lag.Udotcached.time = PETSC_MIN_REAL; 424 t->lag.Udotcached.step = PETSC_MAX_INT; 425 t->adjoint_solve_mode = PETSC_TRUE; 426 t->solution_only = PETSC_FALSE; 427 t->keepfiles = PETSC_FALSE; 428 t->usehistory = PETSC_TRUE; 429 *tj = t; 430 PetscCall(TSTrajectorySetFiletemplate(t, "TS-%06" PetscInt_FMT ".bin")); 431 PetscFunctionReturn(PETSC_SUCCESS); 432 } 433 434 /*@C 435 TSTrajectorySetType - Sets the storage method to be used as in a trajectory 436 437 Collective 438 439 Input Parameters: 440 + tj - the `TSTrajectory` context 441 . ts - the `TS` context 442 - type - a known method 443 444 Options Database Key: 445 . -ts_trajectory_type <type> - Sets the method; use -help for a list of available methods (for instance, basic) 446 447 Level: developer 448 449 Developer Note: 450 Why does this option require access to the `TS` 451 452 .seealso: [](ch_ts), `TSTrajectory`, `TS`, `TSTrajectoryCreate()`, `TSTrajectorySetFromOptions()`, `TSTrajectoryDestroy()`, `TSTrajectoryGetType()` 453 @*/ 454 PetscErrorCode TSTrajectorySetType(TSTrajectory tj, TS ts, TSTrajectoryType type) 455 { 456 PetscErrorCode (*r)(TSTrajectory, TS); 457 PetscBool match; 458 459 PetscFunctionBegin; 460 PetscValidHeaderSpecific(tj, TSTRAJECTORY_CLASSID, 1); 461 PetscCall(PetscObjectTypeCompare((PetscObject)tj, type, &match)); 462 if (match) PetscFunctionReturn(PETSC_SUCCESS); 463 464 PetscCall(PetscFunctionListFind(TSTrajectoryList, type, &r)); 465 PetscCheck(r, PetscObjectComm((PetscObject)tj), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown TSTrajectory type: %s", type); 466 if (tj->ops->destroy) { 467 PetscCall((*(tj)->ops->destroy)(tj)); 468 469 tj->ops->destroy = NULL; 470 } 471 PetscCall(PetscMemzero(tj->ops, sizeof(*tj->ops))); 472 473 PetscCall(PetscObjectChangeTypeName((PetscObject)tj, type)); 474 PetscCall((*r)(tj, ts)); 475 PetscFunctionReturn(PETSC_SUCCESS); 476 } 477 478 /*@C 479 TSTrajectoryGetType - Gets the trajectory type 480 481 Collective 482 483 Input Parameters: 484 + tj - the `TSTrajectory` context 485 - ts - the `TS` context 486 487 Output Parameter: 488 . type - a known method 489 490 Level: developer 491 492 .seealso: [](ch_ts), `TS`, `TSTrajectory`, `TSTrajectoryCreate()`, `TSTrajectorySetFromOptions()`, `TSTrajectoryDestroy()`, `TSTrajectorySetType()` 493 @*/ 494 PetscErrorCode TSTrajectoryGetType(TSTrajectory tj, TS ts, TSTrajectoryType *type) 495 { 496 PetscFunctionBegin; 497 PetscValidHeaderSpecific(tj, TSTRAJECTORY_CLASSID, 1); 498 if (type) *type = ((PetscObject)tj)->type_name; 499 PetscFunctionReturn(PETSC_SUCCESS); 500 } 501 502 PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Basic(TSTrajectory, TS); 503 PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Singlefile(TSTrajectory, TS); 504 PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Memory(TSTrajectory, TS); 505 PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Visualization(TSTrajectory, TS); 506 507 /*@C 508 TSTrajectoryRegisterAll - Registers all of the `TSTrajectory` storage schecmes in the `TS` package. 509 510 Not Collective 511 512 Level: developer 513 514 .seealso: [](ch_ts), `TSTrajectory`, `TSTrajectoryRegister()` 515 @*/ 516 PetscErrorCode TSTrajectoryRegisterAll(void) 517 { 518 PetscFunctionBegin; 519 if (TSTrajectoryRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS); 520 TSTrajectoryRegisterAllCalled = PETSC_TRUE; 521 522 PetscCall(TSTrajectoryRegister(TSTRAJECTORYBASIC, TSTrajectoryCreate_Basic)); 523 PetscCall(TSTrajectoryRegister(TSTRAJECTORYSINGLEFILE, TSTrajectoryCreate_Singlefile)); 524 PetscCall(TSTrajectoryRegister(TSTRAJECTORYMEMORY, TSTrajectoryCreate_Memory)); 525 PetscCall(TSTrajectoryRegister(TSTRAJECTORYVISUALIZATION, TSTrajectoryCreate_Visualization)); 526 PetscFunctionReturn(PETSC_SUCCESS); 527 } 528 529 /*@ 530 TSTrajectoryReset - Resets a trajectory context 531 532 Collective 533 534 Input Parameter: 535 . tj - the `TSTrajectory` context obtained from `TSGetTrajectory()` 536 537 Level: developer 538 539 .seealso: [](ch_ts), `TS`, `TSTrajectory`, `TSTrajectoryCreate()`, `TSTrajectorySetUp()` 540 @*/ 541 PetscErrorCode TSTrajectoryReset(TSTrajectory tj) 542 { 543 PetscFunctionBegin; 544 if (!tj) PetscFunctionReturn(PETSC_SUCCESS); 545 PetscValidHeaderSpecific(tj, TSTRAJECTORY_CLASSID, 1); 546 PetscTryTypeMethod(tj, reset); 547 PetscCall(PetscFree(tj->dirfiletemplate)); 548 PetscCall(TSHistoryDestroy(&tj->tsh)); 549 PetscCall(TSHistoryCreate(PetscObjectComm((PetscObject)tj), &tj->tsh)); 550 tj->setupcalled = PETSC_FALSE; 551 PetscFunctionReturn(PETSC_SUCCESS); 552 } 553 554 /*@ 555 TSTrajectoryDestroy - Destroys a trajectory context 556 557 Collective 558 559 Input Parameter: 560 . tj - the `TSTrajectory` context obtained from `TSTrajectoryCreate()` 561 562 Level: developer 563 564 .seealso: [](ch_ts), `TSTrajectory`, `TSTrajectoryCreate()`, `TSTrajectorySetUp()` 565 @*/ 566 PetscErrorCode TSTrajectoryDestroy(TSTrajectory *tj) 567 { 568 PetscFunctionBegin; 569 if (!*tj) PetscFunctionReturn(PETSC_SUCCESS); 570 PetscValidHeaderSpecific((*tj), TSTRAJECTORY_CLASSID, 1); 571 if (--((PetscObject)(*tj))->refct > 0) { 572 *tj = NULL; 573 PetscFunctionReturn(PETSC_SUCCESS); 574 } 575 576 PetscCall(TSTrajectoryReset(*tj)); 577 PetscCall(TSHistoryDestroy(&(*tj)->tsh)); 578 PetscCall(VecDestroyVecs((*tj)->lag.order + 1, &(*tj)->lag.W)); 579 PetscCall(PetscFree5((*tj)->lag.L, (*tj)->lag.T, (*tj)->lag.WW, (*tj)->lag.TT, (*tj)->lag.TW)); 580 PetscCall(VecDestroy(&(*tj)->U)); 581 PetscCall(VecDestroy(&(*tj)->Udot)); 582 583 if ((*tj)->transformdestroy) PetscCall((*(*tj)->transformdestroy)((*tj)->transformctx)); 584 PetscTryTypeMethod((*tj), destroy); 585 if (!((*tj)->keepfiles)) { 586 PetscMPIInt rank; 587 MPI_Comm comm; 588 589 PetscCall(PetscObjectGetComm((PetscObject)(*tj), &comm)); 590 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 591 if (rank == 0 && (*tj)->dirname) { /* we own the directory, so we run PetscRMTree on it */ 592 PetscCall(PetscRMTree((*tj)->dirname)); 593 } 594 } 595 PetscCall(PetscStrArrayDestroy(&(*tj)->names)); 596 PetscCall(PetscFree((*tj)->dirname)); 597 PetscCall(PetscFree((*tj)->filetemplate)); 598 PetscCall(PetscHeaderDestroy(tj)); 599 PetscFunctionReturn(PETSC_SUCCESS); 600 } 601 602 /* 603 TSTrajectorySetTypeFromOptions_Private - Sets the type of `TSTrajectory` from user options. 604 605 Collective 606 607 Input Parameter: 608 + tj - the `TSTrajectory` context 609 - ts - the TS context 610 611 Options Database Key: 612 . -ts_trajectory_type <type> - TSTRAJECTORYBASIC, TSTRAJECTORYMEMORY, TSTRAJECTORYSINGLEFILE, TSTRAJECTORYVISUALIZATION 613 614 Level: developer 615 616 .seealso: [](ch_ts), `TSTrajectory`, `TSTrajectoryType`, `TSTrajectorySetFromOptions()`, `TSTrajectorySetType()` 617 */ 618 static PetscErrorCode TSTrajectorySetTypeFromOptions_Private(PetscOptionItems *PetscOptionsObject, TSTrajectory tj, TS ts) 619 { 620 PetscBool opt; 621 const char *defaultType; 622 char typeName[256]; 623 624 PetscFunctionBegin; 625 if (((PetscObject)tj)->type_name) defaultType = ((PetscObject)tj)->type_name; 626 else defaultType = TSTRAJECTORYBASIC; 627 628 PetscCall(TSTrajectoryRegisterAll()); 629 PetscCall(PetscOptionsFList("-ts_trajectory_type", "TSTrajectory method", "TSTrajectorySetType", TSTrajectoryList, defaultType, typeName, 256, &opt)); 630 if (opt) { 631 PetscCall(TSTrajectorySetType(tj, ts, typeName)); 632 } else { 633 PetscCall(TSTrajectorySetType(tj, ts, defaultType)); 634 } 635 PetscFunctionReturn(PETSC_SUCCESS); 636 } 637 638 /*@ 639 TSTrajectorySetUseHistory - Use `TSHistory` in `TSTrajectory` 640 641 Collective 642 643 Input Parameters: 644 + tj - the `TSTrajectory` context 645 - flg - `PETSC_TRUE` to save, `PETSC_FALSE` to disable 646 647 Options Database Key: 648 . -ts_trajectory_use_history - have it use `TSHistory` 649 650 Level: advanced 651 652 .seealso: [](ch_ts), `TSTrajectory`, `TSTrajectoryCreate()`, `TSTrajectoryDestroy()`, `TSTrajectorySetUp()` 653 @*/ 654 PetscErrorCode TSTrajectorySetUseHistory(TSTrajectory tj, PetscBool flg) 655 { 656 PetscFunctionBegin; 657 PetscValidHeaderSpecific(tj, TSTRAJECTORY_CLASSID, 1); 658 PetscValidLogicalCollectiveBool(tj, flg, 2); 659 tj->usehistory = flg; 660 PetscFunctionReturn(PETSC_SUCCESS); 661 } 662 663 /*@ 664 TSTrajectorySetMonitor - Monitor the schedules generated by the `TSTrajectory` checkpointing controller 665 666 Collective 667 668 Input Parameters: 669 + tj - the `TSTrajectory` context 670 - flg - `PETSC_TRUE` to active a monitor, `PETSC_FALSE` to disable 671 672 Options Database Key: 673 . -ts_trajectory_monitor - print `TSTrajectory` information 674 675 Level: developer 676 677 .seealso: [](ch_ts), `TSTrajectory`, `TSTrajectoryCreate()`, `TSTrajectoryDestroy()`, `TSTrajectorySetUp()` 678 @*/ 679 PetscErrorCode TSTrajectorySetMonitor(TSTrajectory tj, PetscBool flg) 680 { 681 PetscFunctionBegin; 682 PetscValidHeaderSpecific(tj, TSTRAJECTORY_CLASSID, 1); 683 PetscValidLogicalCollectiveBool(tj, flg, 2); 684 if (flg) tj->monitor = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)tj)); 685 else tj->monitor = NULL; 686 PetscFunctionReturn(PETSC_SUCCESS); 687 } 688 689 /*@ 690 TSTrajectorySetKeepFiles - Keep the files generated by the `TSTrajectory` once the program is done 691 692 Collective 693 694 Input Parameters: 695 + tj - the `TSTrajectory` context 696 - flg - `PETSC_TRUE` to save, `PETSC_FALSE` to disable 697 698 Options Database Key: 699 . -ts_trajectory_keep_files - have it keep the files 700 701 Level: advanced 702 703 Note: 704 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. 705 706 .seealso: [](ch_ts), `TSTrajectoryCreate()`, `TSTrajectoryDestroy()`, `TSTrajectorySetUp()`, `TSTrajectorySetMonitor()` 707 @*/ 708 PetscErrorCode TSTrajectorySetKeepFiles(TSTrajectory tj, PetscBool flg) 709 { 710 PetscFunctionBegin; 711 PetscValidHeaderSpecific(tj, TSTRAJECTORY_CLASSID, 1); 712 PetscValidLogicalCollectiveBool(tj, flg, 2); 713 tj->keepfiles = flg; 714 PetscFunctionReturn(PETSC_SUCCESS); 715 } 716 717 /*@C 718 TSTrajectorySetDirname - Specify the name of the directory where `TSTrajectory` disk checkpoints are stored. 719 720 Collective 721 722 Input Parameters: 723 + tj - the `TSTrajectory` context 724 - dirname - the directory name 725 726 Options Database Key: 727 . -ts_trajectory_dirname - set the directory name 728 729 Level: developer 730 731 Notes: 732 The final location of the files is determined by dirname/filetemplate where filetemplate was provided by `TSTrajectorySetFiletemplate()` 733 734 If this is not called `TSTrajectory` selects a unique new name for the directory 735 736 .seealso: [](ch_ts), `TSTrajectory`, `TSTrajectorySetFiletemplate()`, `TSTrajectorySetUp()` 737 @*/ 738 PetscErrorCode TSTrajectorySetDirname(TSTrajectory tj, const char dirname[]) 739 { 740 PetscBool flg; 741 742 PetscFunctionBegin; 743 PetscValidHeaderSpecific(tj, TSTRAJECTORY_CLASSID, 1); 744 PetscCall(PetscStrcmp(tj->dirname, dirname, &flg)); 745 PetscCheck(flg || !tj->dirfiletemplate, PetscObjectComm((PetscObject)tj), PETSC_ERR_ARG_WRONGSTATE, "Cannot set directoryname after TSTrajectory has been setup"); 746 PetscCall(PetscFree(tj->dirname)); 747 PetscCall(PetscStrallocpy(dirname, &tj->dirname)); 748 PetscFunctionReturn(PETSC_SUCCESS); 749 } 750 751 /*@C 752 TSTrajectorySetFiletemplate - Specify the name template for the files storing `TSTrajectory` checkpoints. 753 754 Collective 755 756 Input Parameters: 757 + tj - the `TSTrajectory` context 758 - filetemplate - the template 759 760 Options Database Key: 761 . -ts_trajectory_file_template - set the file name template 762 763 Level: developer 764 765 Notes: 766 The name template should be of the form, for example filename-%06" PetscInt_FMT ".bin It should not begin with a leading / 767 768 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 769 timestep counter 770 771 .seealso: [](ch_ts), `TSTrajectory`, `TSTrajectorySetDirname()`, `TSTrajectorySetUp()` 772 @*/ 773 PetscErrorCode TSTrajectorySetFiletemplate(TSTrajectory tj, const char filetemplate[]) 774 { 775 const char *ptr = NULL, *ptr2 = NULL; 776 777 PetscFunctionBegin; 778 PetscValidHeaderSpecific(tj, TSTRAJECTORY_CLASSID, 1); 779 PetscValidCharPointer(filetemplate, 2); 780 PetscCheck(!tj->dirfiletemplate, PetscObjectComm((PetscObject)tj), PETSC_ERR_ARG_WRONGSTATE, "Cannot set filetemplate after TSTrajectory has been setup"); 781 782 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"); 783 /* Do some cursory validation of the input. */ 784 PetscCall(PetscStrstr(filetemplate, "%", (char **)&ptr)); 785 PetscCheck(ptr, PetscObjectComm((PetscObject)tj), PETSC_ERR_USER, "-ts_trajectory_file_template requires a file name template, e.g. filename-%%06" PetscInt_FMT ".bin"); 786 for (ptr++; ptr && *ptr; ptr++) { 787 PetscCall(PetscStrchr(PetscInt_FMT "DiouxX", *ptr, (char **)&ptr2)); 788 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"); 789 if (ptr2) break; 790 } 791 PetscCall(PetscFree(tj->filetemplate)); 792 PetscCall(PetscStrallocpy(filetemplate, &tj->filetemplate)); 793 PetscFunctionReturn(PETSC_SUCCESS); 794 } 795 796 /*@ 797 TSTrajectorySetFromOptions - Sets various `TSTrajectory` parameters from user options. 798 799 Collective 800 801 Input Parameters: 802 + tj - the `TSTrajectory` context obtained from `TSGetTrajectory()` 803 - ts - the `TS` context 804 805 Options Database Keys: 806 + -ts_trajectory_type <type> - basic, memory, singlefile, visualization 807 . -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 808 - -ts_trajectory_monitor - print `TSTrajectory` information 809 810 Level: developer 811 812 Note: 813 This is not normally called directly by users 814 815 .seealso: [](ch_ts), `TSTrajectory`, `TSSetSaveTrajectory()`, `TSTrajectorySetUp()` 816 @*/ 817 PetscErrorCode TSTrajectorySetFromOptions(TSTrajectory tj, TS ts) 818 { 819 PetscBool set, flg; 820 char dirname[PETSC_MAX_PATH_LEN], filetemplate[PETSC_MAX_PATH_LEN]; 821 822 PetscFunctionBegin; 823 PetscValidHeaderSpecific(tj, TSTRAJECTORY_CLASSID, 1); 824 if (ts) PetscValidHeaderSpecific(ts, TS_CLASSID, 2); 825 PetscObjectOptionsBegin((PetscObject)tj); 826 PetscCall(TSTrajectorySetTypeFromOptions_Private(PetscOptionsObject, tj, ts)); 827 PetscCall(PetscOptionsBool("-ts_trajectory_use_history", "Turn on/off usage of TSHistory", NULL, tj->usehistory, &tj->usehistory, NULL)); 828 PetscCall(PetscOptionsBool("-ts_trajectory_monitor", "Print checkpointing schedules", "TSTrajectorySetMonitor", tj->monitor ? PETSC_TRUE : PETSC_FALSE, &flg, &set)); 829 if (set) PetscCall(TSTrajectorySetMonitor(tj, flg)); 830 PetscCall(PetscOptionsInt("-ts_trajectory_reconstruction_order", "Interpolation order for reconstruction", NULL, tj->lag.order, &tj->lag.order, NULL)); 831 PetscCall(PetscOptionsBool("-ts_trajectory_reconstruction_caching", "Turn on/off caching of TSTrajectoryGetVecs input", NULL, tj->lag.caching, &tj->lag.caching, NULL)); 832 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)); 833 PetscCall(PetscOptionsBool("-ts_trajectory_solution_only", "Checkpoint solution only", "TSTrajectorySetSolutionOnly", tj->solution_only, &tj->solution_only, NULL)); 834 PetscCall(PetscOptionsBool("-ts_trajectory_keep_files", "Keep any trajectory files generated during the run", "TSTrajectorySetKeepFiles", tj->keepfiles, &flg, &set)); 835 if (set) PetscCall(TSTrajectorySetKeepFiles(tj, flg)); 836 837 PetscCall(PetscOptionsString("-ts_trajectory_dirname", "Directory name for TSTrajectory file", "TSTrajectorySetDirname", NULL, dirname, sizeof(dirname) - 14, &set)); 838 if (set) PetscCall(TSTrajectorySetDirname(tj, dirname)); 839 840 PetscCall(PetscOptionsString("-ts_trajectory_file_template", "Template for TSTrajectory file name, use filename-%06" PetscInt_FMT ".bin", "TSTrajectorySetFiletemplate", NULL, filetemplate, sizeof(filetemplate), &set)); 841 if (set) PetscCall(TSTrajectorySetFiletemplate(tj, filetemplate)); 842 843 /* Handle specific TSTrajectory options */ 844 PetscTryTypeMethod(tj, setfromoptions, PetscOptionsObject); 845 PetscOptionsEnd(); 846 PetscFunctionReturn(PETSC_SUCCESS); 847 } 848 849 /*@ 850 TSTrajectorySetUp - Sets up the internal data structures, e.g. stacks, for the later use 851 of a `TS` `TSTrajectory`. 852 853 Collective 854 855 Input Parameters: 856 + tj - the `TSTrajectory` context 857 - ts - the TS context obtained from `TSCreate()` 858 859 Level: developer 860 861 .seealso: [](ch_ts), `TSTrajectory`, `TSSetSaveTrajectory()`, `TSTrajectoryCreate()`, `TSTrajectoryDestroy()` 862 @*/ 863 PetscErrorCode TSTrajectorySetUp(TSTrajectory tj, TS ts) 864 { 865 size_t s1, s2; 866 867 PetscFunctionBegin; 868 if (!tj) PetscFunctionReturn(PETSC_SUCCESS); 869 PetscValidHeaderSpecific(tj, TSTRAJECTORY_CLASSID, 1); 870 if (ts) PetscValidHeaderSpecific(ts, TS_CLASSID, 2); 871 if (tj->setupcalled) PetscFunctionReturn(PETSC_SUCCESS); 872 873 PetscCall(PetscLogEventBegin(TSTrajectory_SetUp, tj, ts, 0, 0)); 874 if (!((PetscObject)tj)->type_name) PetscCall(TSTrajectorySetType(tj, ts, TSTRAJECTORYBASIC)); 875 PetscTryTypeMethod(tj, setup, ts); 876 877 tj->setupcalled = PETSC_TRUE; 878 879 /* Set the counters to zero */ 880 tj->recomps = 0; 881 tj->diskreads = 0; 882 tj->diskwrites = 0; 883 PetscCall(PetscStrlen(tj->dirname, &s1)); 884 PetscCall(PetscStrlen(tj->filetemplate, &s2)); 885 PetscCall(PetscFree(tj->dirfiletemplate)); 886 PetscCall(PetscMalloc((s1 + s2 + 10) * sizeof(char), &tj->dirfiletemplate)); 887 PetscCall(PetscSNPrintf(tj->dirfiletemplate, s1 + s2 + 10, "%s/%s", tj->dirname, tj->filetemplate)); 888 PetscCall(PetscLogEventEnd(TSTrajectory_SetUp, tj, ts, 0, 0)); 889 PetscFunctionReturn(PETSC_SUCCESS); 890 } 891 892 /*@ 893 TSTrajectorySetSolutionOnly - Tells the trajectory to store just the solution, and not any intermediate stage information 894 895 Collective 896 897 Input Parameters: 898 + tj - the `TSTrajectory` context obtained with `TSGetTrajectory()` 899 - flg - the boolean flag 900 901 Level: developer 902 903 .seealso: [](ch_ts), `TSTrajectory`, `TSSetSaveTrajectory()`, `TSTrajectoryCreate()`, `TSTrajectoryDestroy()`, `TSTrajectoryGetSolutionOnly()` 904 @*/ 905 PetscErrorCode TSTrajectorySetSolutionOnly(TSTrajectory tj, PetscBool solution_only) 906 { 907 PetscFunctionBegin; 908 PetscValidHeaderSpecific(tj, TSTRAJECTORY_CLASSID, 1); 909 PetscValidLogicalCollectiveBool(tj, solution_only, 2); 910 tj->solution_only = solution_only; 911 PetscFunctionReturn(PETSC_SUCCESS); 912 } 913 914 /*@ 915 TSTrajectoryGetSolutionOnly - Gets the value set with `TSTrajectorySetSolutionOnly()`. 916 917 Logically Collective 918 919 Input Parameter: 920 . tj - the `TSTrajectory` context 921 922 Output Parameter: 923 . flg - the boolean flag 924 925 Level: developer 926 927 .seealso: [](ch_ts), `TSTrajectory`, `TSSetSaveTrajectory()`, `TSTrajectoryCreate()`, `TSTrajectoryDestroy()`, `TSTrajectorySetSolutionOnly()` 928 @*/ 929 PetscErrorCode TSTrajectoryGetSolutionOnly(TSTrajectory tj, PetscBool *solution_only) 930 { 931 PetscFunctionBegin; 932 PetscValidHeaderSpecific(tj, TSTRAJECTORY_CLASSID, 1); 933 PetscValidBoolPointer(solution_only, 2); 934 *solution_only = tj->solution_only; 935 PetscFunctionReturn(PETSC_SUCCESS); 936 } 937 938 /*@ 939 TSTrajectoryGetUpdatedHistoryVecs - Get updated state and time-derivative history vectors. 940 941 Collective 942 943 Input Parameters: 944 + tj - the `TSTrajectory` context 945 . ts - the `TS` solver context 946 - time - the requested time 947 948 Output Parameters: 949 + U - state vector at given time (can be interpolated) 950 - Udot - time-derivative vector at given time (can be interpolated) 951 952 Level: developer 953 954 Notes: 955 The vectors are interpolated if time does not match any time step stored in the `TSTrajectory()`. Pass NULL to not request a vector. 956 957 This function differs from `TSTrajectoryGetVecs()` since the vectors obtained cannot be modified, and they need to be returned by 958 calling `TSTrajectoryRestoreUpdatedHistoryVecs()`. 959 960 .seealso: [](ch_ts), `TSTrajectory`, `TSSetSaveTrajectory()`, `TSTrajectoryCreate()`, `TSTrajectoryDestroy()`, `TSTrajectoryRestoreUpdatedHistoryVecs()`, `TSTrajectoryGetVecs()` 961 @*/ 962 PetscErrorCode TSTrajectoryGetUpdatedHistoryVecs(TSTrajectory tj, TS ts, PetscReal time, Vec *U, Vec *Udot) 963 { 964 PetscFunctionBegin; 965 PetscValidHeaderSpecific(tj, TSTRAJECTORY_CLASSID, 1); 966 PetscValidHeaderSpecific(ts, TS_CLASSID, 2); 967 PetscValidLogicalCollectiveReal(tj, time, 3); 968 if (U) PetscValidPointer(U, 4); 969 if (Udot) PetscValidPointer(Udot, 5); 970 if (U && !tj->U) { 971 DM dm; 972 973 PetscCall(TSGetDM(ts, &dm)); 974 PetscCall(DMCreateGlobalVector(dm, &tj->U)); 975 } 976 if (Udot && !tj->Udot) { 977 DM dm; 978 979 PetscCall(TSGetDM(ts, &dm)); 980 PetscCall(DMCreateGlobalVector(dm, &tj->Udot)); 981 } 982 PetscCall(TSTrajectoryGetVecs(tj, ts, PETSC_DECIDE, &time, U ? tj->U : NULL, Udot ? tj->Udot : NULL)); 983 if (U) { 984 PetscCall(VecLockReadPush(tj->U)); 985 *U = tj->U; 986 } 987 if (Udot) { 988 PetscCall(VecLockReadPush(tj->Udot)); 989 *Udot = tj->Udot; 990 } 991 PetscFunctionReturn(PETSC_SUCCESS); 992 } 993 994 /*@ 995 TSTrajectoryRestoreUpdatedHistoryVecs - Restores updated state and time-derivative history vectors obtained with `TSTrajectoryGetUpdatedHistoryVecs()`. 996 997 Collective 998 999 Input Parameters: 1000 + tj - the `TSTrajectory` context 1001 . U - state vector at given time (can be interpolated) 1002 - Udot - time-derivative vector at given time (can be interpolated) 1003 1004 Level: developer 1005 1006 .seealso: [](ch_ts), `TSTrajectory`, `TSTrajectoryGetUpdatedHistoryVecs()` 1007 @*/ 1008 PetscErrorCode TSTrajectoryRestoreUpdatedHistoryVecs(TSTrajectory tj, Vec *U, Vec *Udot) 1009 { 1010 PetscFunctionBegin; 1011 PetscValidHeaderSpecific(tj, TSTRAJECTORY_CLASSID, 1); 1012 if (U) PetscValidHeaderSpecific(*U, VEC_CLASSID, 2); 1013 if (Udot) PetscValidHeaderSpecific(*Udot, VEC_CLASSID, 3); 1014 PetscCheck(!U || *U == tj->U, PetscObjectComm((PetscObject)*U), PETSC_ERR_USER, "U was not obtained from TSTrajectoryGetUpdatedHistoryVecs()"); 1015 PetscCheck(!Udot || *Udot == tj->Udot, PetscObjectComm((PetscObject)*Udot), PETSC_ERR_USER, "Udot was not obtained from TSTrajectoryGetUpdatedHistoryVecs()"); 1016 if (U) { 1017 PetscCall(VecLockReadPop(tj->U)); 1018 *U = NULL; 1019 } 1020 if (Udot) { 1021 PetscCall(VecLockReadPop(tj->Udot)); 1022 *Udot = NULL; 1023 } 1024 PetscFunctionReturn(PETSC_SUCCESS); 1025 } 1026