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