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