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