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