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 if (!flg && tj->dirfiletemplate) { 745 SETERRQ(PetscObjectComm((PetscObject)tj),PETSC_ERR_ARG_WRONGSTATE,"Cannot set directoryname after TSTrajectory has been setup"); 746 } 747 PetscCall(PetscFree(tj->dirname)); 748 PetscCall(PetscStrallocpy(dirname,&tj->dirname)); 749 PetscFunctionReturn(0); 750 } 751 752 /*@C 753 TSTrajectorySetFiletemplate - Specify the name template for the files storing checkpoints. 754 755 Collective on TSTrajectory 756 757 Input Parameters: 758 + tj - the TSTrajectory context 759 - filetemplate - the template 760 761 Options Database Keys: 762 . -ts_trajectory_file_template - set the file name template 763 764 Notes: 765 The name template should be of the form, for example filename-%06" PetscInt_FMT ".bin It should not begin with a leading / 766 767 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 768 timestep counter 769 770 Level: developer 771 772 .seealso: `TSTrajectorySetDirname()`, `TSTrajectorySetUp()` 773 @*/ 774 PetscErrorCode TSTrajectorySetFiletemplate(TSTrajectory tj,const char filetemplate[]) 775 { 776 const char *ptr,*ptr2; 777 778 PetscFunctionBegin; 779 PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1); 780 PetscValidCharPointer(filetemplate,2); 781 PetscCheck(!tj->dirfiletemplate,PetscObjectComm((PetscObject)tj),PETSC_ERR_ARG_WRONGSTATE,"Cannot set filetemplate after TSTrajectory has been setup"); 782 783 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"); 784 /* Do some cursory validation of the input. */ 785 PetscCall(PetscStrstr(filetemplate,"%",(char**)&ptr)); 786 PetscCheck(ptr,PetscObjectComm((PetscObject)tj),PETSC_ERR_USER,"-ts_trajectory_file_template requires a file name template, e.g. filename-%%06" PetscInt_FMT ".bin"); 787 for (ptr++; ptr && *ptr; ptr++) { 788 PetscCall(PetscStrchr(PetscInt_FMT "DiouxX",*ptr,(char**)&ptr2)); 789 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"); 790 if (ptr2) break; 791 } 792 PetscCall(PetscFree(tj->filetemplate)); 793 PetscCall(PetscStrallocpy(filetemplate,&tj->filetemplate)); 794 PetscFunctionReturn(0); 795 } 796 797 /*@ 798 TSTrajectorySetFromOptions - Sets various TSTrajectory parameters from user options. 799 800 Collective on TSTrajectory 801 802 Input Parameters: 803 + tj - the TSTrajectory context obtained from TSTrajectoryCreate() 804 - ts - the TS context 805 806 Options Database Keys: 807 + -ts_trajectory_type <type> - TSTRAJECTORYBASIC, TSTRAJECTORYMEMORY, TSTRAJECTORYSINGLEFILE, TSTRAJECTORYVISUALIZATION 808 . -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 809 - -ts_trajectory_monitor - print TSTrajectory information 810 811 Level: developer 812 813 Notes: 814 This is not normally called directly by users 815 816 .seealso: `TSSetSaveTrajectory()`, `TSTrajectorySetUp()` 817 @*/ 818 PetscErrorCode TSTrajectorySetFromOptions(TSTrajectory tj,TS ts) 819 { 820 PetscBool set,flg; 821 char dirname[PETSC_MAX_PATH_LEN],filetemplate[PETSC_MAX_PATH_LEN]; 822 823 PetscFunctionBegin; 824 PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1); 825 if (ts) PetscValidHeaderSpecific(ts,TS_CLASSID,2); 826 PetscObjectOptionsBegin((PetscObject)tj); 827 PetscCall(TSTrajectorySetTypeFromOptions_Private(PetscOptionsObject,tj,ts)); 828 PetscCall(PetscOptionsBool("-ts_trajectory_use_history","Turn on/off usage of TSHistory",NULL,tj->usehistory,&tj->usehistory,NULL)); 829 PetscCall(PetscOptionsBool("-ts_trajectory_monitor","Print checkpointing schedules","TSTrajectorySetMonitor",tj->monitor ? PETSC_TRUE:PETSC_FALSE,&flg,&set)); 830 if (set) PetscCall(TSTrajectorySetMonitor(tj,flg)); 831 PetscCall(PetscOptionsInt("-ts_trajectory_reconstruction_order","Interpolation order for reconstruction",NULL,tj->lag.order,&tj->lag.order,NULL)); 832 PetscCall(PetscOptionsBool("-ts_trajectory_reconstruction_caching","Turn on/off caching of TSTrajectoryGetVecs input",NULL,tj->lag.caching,&tj->lag.caching,NULL)); 833 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)); 834 PetscCall(PetscOptionsBool("-ts_trajectory_solution_only","Checkpoint solution only","TSTrajectorySetSolutionOnly",tj->solution_only,&tj->solution_only,NULL)); 835 PetscCall(PetscOptionsBool("-ts_trajectory_keep_files","Keep any trajectory files generated during the run","TSTrajectorySetKeepFiles",tj->keepfiles,&flg,&set)); 836 if (set) PetscCall(TSTrajectorySetKeepFiles(tj,flg)); 837 838 PetscCall(PetscOptionsString("-ts_trajectory_dirname","Directory name for TSTrajectory file","TSTrajectorySetDirname",NULL,dirname,sizeof(dirname)-14,&set)); 839 if (set) PetscCall(TSTrajectorySetDirname(tj,dirname)); 840 841 PetscCall(PetscOptionsString("-ts_trajectory_file_template","Template for TSTrajectory file name, use filename-%06" PetscInt_FMT ".bin","TSTrajectorySetFiletemplate",NULL,filetemplate,sizeof(filetemplate),&set)); 842 if (set) PetscCall(TSTrajectorySetFiletemplate(tj,filetemplate)); 843 844 /* Handle specific TSTrajectory options */ 845 if (tj->ops->setfromoptions) PetscCall((*tj->ops->setfromoptions)(PetscOptionsObject,tj)); 846 PetscOptionsEnd(); 847 PetscFunctionReturn(0); 848 } 849 850 /*@ 851 TSTrajectorySetUp - Sets up the internal data structures, e.g. stacks, for the later use 852 of a TS trajectory. 853 854 Collective on TS 855 856 Input Parameters: 857 + ts - the TS context obtained from TSCreate() 858 - tj - the TS trajectory context 859 860 Level: developer 861 862 .seealso: `TSSetSaveTrajectory()`, `TSTrajectoryCreate()`, `TSTrajectoryDestroy()` 863 @*/ 864 PetscErrorCode TSTrajectorySetUp(TSTrajectory tj,TS ts) 865 { 866 size_t s1,s2; 867 868 PetscFunctionBegin; 869 if (!tj) PetscFunctionReturn(0); 870 PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1); 871 if (ts) PetscValidHeaderSpecific(ts,TS_CLASSID,2); 872 if (tj->setupcalled) PetscFunctionReturn(0); 873 874 PetscCall(PetscLogEventBegin(TSTrajectory_SetUp,tj,ts,0,0)); 875 if (!((PetscObject)tj)->type_name) { 876 PetscCall(TSTrajectorySetType(tj,ts,TSTRAJECTORYBASIC)); 877 } 878 if (tj->ops->setup) PetscCall((*tj->ops->setup)(tj,ts)); 879 880 tj->setupcalled = PETSC_TRUE; 881 882 /* Set the counters to zero */ 883 tj->recomps = 0; 884 tj->diskreads = 0; 885 tj->diskwrites = 0; 886 PetscCall(PetscStrlen(tj->dirname,&s1)); 887 PetscCall(PetscStrlen(tj->filetemplate,&s2)); 888 PetscCall(PetscFree(tj->dirfiletemplate)); 889 PetscCall(PetscMalloc((s1 + s2 + 10)*sizeof(char),&tj->dirfiletemplate)); 890 PetscCall(PetscSNPrintf(tj->dirfiletemplate,s1+s2+10,"%s/%s",tj->dirname,tj->filetemplate)); 891 PetscCall(PetscLogEventEnd(TSTrajectory_SetUp,tj,ts,0,0)); 892 PetscFunctionReturn(0); 893 } 894 895 /*@ 896 TSTrajectorySetSolutionOnly - Tells the trajectory to store just the solution, and not any intermediate stage also. 897 898 Collective on TSTrajectory 899 900 Input Parameters: 901 + tj - the TS trajectory context 902 - flg - the boolean flag 903 904 Level: developer 905 906 .seealso: `TSSetSaveTrajectory()`, `TSTrajectoryCreate()`, `TSTrajectoryDestroy()`, `TSTrajectoryGetSolutionOnly()` 907 @*/ 908 PetscErrorCode TSTrajectorySetSolutionOnly(TSTrajectory tj,PetscBool solution_only) 909 { 910 PetscFunctionBegin; 911 PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1); 912 PetscValidLogicalCollectiveBool(tj,solution_only,2); 913 tj->solution_only = solution_only; 914 PetscFunctionReturn(0); 915 } 916 917 /*@ 918 TSTrajectoryGetSolutionOnly - Gets the value set with TSTrajectorySetSolutionOnly. 919 920 Logically collective on TSTrajectory 921 922 Input Parameter: 923 . tj - the TS trajectory context 924 925 Output Parameter: 926 . flg - the boolean flag 927 928 Level: developer 929 930 .seealso: `TSSetSaveTrajectory()`, `TSTrajectoryCreate()`, `TSTrajectoryDestroy()`, `TSTrajectorySetSolutionOnly()` 931 @*/ 932 PetscErrorCode TSTrajectoryGetSolutionOnly(TSTrajectory tj,PetscBool *solution_only) 933 { 934 PetscFunctionBegin; 935 PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1); 936 PetscValidBoolPointer(solution_only,2); 937 *solution_only = tj->solution_only; 938 PetscFunctionReturn(0); 939 } 940 941 /*@ 942 TSTrajectoryGetUpdatedHistoryVecs - Get updated state and time-derivative history vectors. 943 944 Collective on TSTrajectory 945 946 Input Parameters: 947 + tj - the TS trajectory context 948 . ts - the TS solver context 949 - time - the requested time 950 951 Output Parameters: 952 + U - state vector at given time (can be interpolated) 953 - Udot - time-derivative vector at given time (can be interpolated) 954 955 Level: developer 956 957 Notes: The vectors are interpolated if time does not match any time step stored in the TSTrajectory(). Pass NULL to not request a vector. 958 This function differs from TSTrajectoryGetVecs since the vectors obtained cannot be modified, and they need to be returned by 959 calling TSTrajectoryRestoreUpdatedHistoryVecs(). 960 961 .seealso: `TSSetSaveTrajectory()`, `TSTrajectoryCreate()`, `TSTrajectoryDestroy()`, `TSTrajectoryRestoreUpdatedHistoryVecs()`, `TSTrajectoryGetVecs()` 962 @*/ 963 PetscErrorCode TSTrajectoryGetUpdatedHistoryVecs(TSTrajectory tj, TS ts, PetscReal time, Vec *U, Vec *Udot) 964 { 965 PetscFunctionBegin; 966 PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1); 967 PetscValidHeaderSpecific(ts,TS_CLASSID,2); 968 PetscValidLogicalCollectiveReal(tj,time,3); 969 if (U) PetscValidPointer(U,4); 970 if (Udot) PetscValidPointer(Udot,5); 971 if (U && !tj->U) { 972 DM dm; 973 974 PetscCall(TSGetDM(ts,&dm)); 975 PetscCall(DMCreateGlobalVector(dm,&tj->U)); 976 } 977 if (Udot && !tj->Udot) { 978 DM dm; 979 980 PetscCall(TSGetDM(ts,&dm)); 981 PetscCall(DMCreateGlobalVector(dm,&tj->Udot)); 982 } 983 PetscCall(TSTrajectoryGetVecs(tj,ts,PETSC_DECIDE,&time,U ? tj->U : NULL,Udot ? tj->Udot : NULL)); 984 if (U) { 985 PetscCall(VecLockReadPush(tj->U)); 986 *U = tj->U; 987 } 988 if (Udot) { 989 PetscCall(VecLockReadPush(tj->Udot)); 990 *Udot = tj->Udot; 991 } 992 PetscFunctionReturn(0); 993 } 994 995 /*@ 996 TSTrajectoryRestoreUpdatedHistoryVecs - Restores updated state and time-derivative history vectors obtained with TSTrajectoryGetUpdatedHistoryVecs(). 997 998 Collective on TSTrajectory 999 1000 Input Parameters: 1001 + tj - the TS trajectory context 1002 . U - state vector at given time (can be interpolated) 1003 - Udot - time-derivative vector at given time (can be interpolated) 1004 1005 Level: developer 1006 1007 .seealso: `TSTrajectoryGetUpdatedHistoryVecs()` 1008 @*/ 1009 PetscErrorCode TSTrajectoryRestoreUpdatedHistoryVecs(TSTrajectory tj, Vec *U, Vec *Udot) 1010 { 1011 PetscFunctionBegin; 1012 PetscValidHeaderSpecific(tj,TSTRAJECTORY_CLASSID,1); 1013 if (U) PetscValidHeaderSpecific(*U,VEC_CLASSID,2); 1014 if (Udot) PetscValidHeaderSpecific(*Udot,VEC_CLASSID,3); 1015 PetscCheck(!U || *U == tj->U,PetscObjectComm((PetscObject)*U),PETSC_ERR_USER,"U was not obtained from TSTrajectoryGetUpdatedHistoryVecs()"); 1016 PetscCheck(!Udot || *Udot == tj->Udot,PetscObjectComm((PetscObject)*Udot),PETSC_ERR_USER,"Udot was not obtained from TSTrajectoryGetUpdatedHistoryVecs()"); 1017 if (U) { 1018 PetscCall(VecLockReadPop(tj->U)); 1019 *U = NULL; 1020 } 1021 if (Udot) { 1022 PetscCall(VecLockReadPop(tj->Udot)); 1023 *Udot = NULL; 1024 } 1025 PetscFunctionReturn(0); 1026 } 1027