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