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