1 #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 2 #include <petscsys.h> 3 #ifdef PETSC_HAVE_REVOLVE 4 #include <revolve_c.h> 5 #endif 6 7 PetscLogEvent Disk_Write, Disk_Read; 8 9 typedef enum {NONE,TWO_LEVEL_NOREVOLVE,TWO_LEVEL_REVOLVE,TWO_LEVEL_TWO_REVOLVE,REVOLVE_OFFLINE,REVOLVE_ONLINE,REVOLVE_MULTISTAGE} SchedulerType; 10 11 typedef struct _StackElement { 12 PetscInt stepnum; 13 Vec X; 14 Vec *Y; 15 PetscReal time; 16 PetscReal timeprev; 17 } *StackElement; 18 19 #ifdef PETSC_HAVE_REVOLVE 20 typedef struct _RevolveCTX { 21 PetscBool reverseonestep; 22 PetscInt where; 23 PetscInt snaps_in; 24 PetscInt stepsleft; 25 PetscInt check; 26 PetscInt oldcapo; 27 PetscInt capo; 28 PetscInt fine; 29 PetscInt info; 30 } RevolveCTX; 31 #endif 32 33 typedef struct _Stack { 34 PetscInt stacksize; 35 PetscInt top; 36 StackElement *container; 37 PetscInt numY; 38 PetscBool solution_only; 39 } Stack; 40 41 typedef struct _DiskStack { 42 PetscInt stacksize; 43 PetscInt top; 44 PetscInt *container; 45 } DiskStack; 46 47 typedef struct _TJScheduler { 48 SchedulerType stype; 49 #ifdef PETSC_HAVE_REVOLVE 50 RevolveCTX *rctx,*rctx2; 51 PetscBool use_online; 52 PetscInt store_stride; 53 #endif 54 PetscBool recompute; 55 PetscBool skip_trajectory; 56 PetscBool save_stack; 57 MPI_Comm comm; 58 PetscInt max_cps_ram; /* maximum checkpoints in RAM */ 59 PetscInt max_cps_disk; /* maximum checkpoints on disk */ 60 PetscInt stride; 61 PetscInt total_steps; /* total number of steps */ 62 Stack stack; 63 DiskStack diskstack; 64 } TJScheduler; 65 66 #undef __FUNCT__ 67 #define __FUNCT__ "StackCreate" 68 static PetscErrorCode StackCreate(Stack *stack,PetscInt size,PetscInt ny) 69 { 70 PetscErrorCode ierr; 71 72 PetscFunctionBegin; 73 stack->top = -1; 74 stack->numY = ny; 75 76 ierr = PetscMalloc1(size*sizeof(StackElement),&stack->container);CHKERRQ(ierr); 77 PetscFunctionReturn(0); 78 } 79 80 #undef __FUNCT__ 81 #define __FUNCT__ "StackDestroy" 82 static PetscErrorCode StackDestroy(Stack *stack) 83 { 84 PetscInt i; 85 PetscErrorCode ierr; 86 87 PetscFunctionBegin; 88 if (stack->top > -1) { 89 for (i=0;i<=stack->top;i++) { 90 ierr = VecDestroy(&stack->container[i]->X);CHKERRQ(ierr); 91 if (!stack->solution_only) { 92 ierr = VecDestroyVecs(stack->numY,&stack->container[i]->Y);CHKERRQ(ierr); 93 } 94 ierr = PetscFree(stack->container[i]);CHKERRQ(ierr); 95 } 96 } 97 ierr = PetscFree(stack->container);CHKERRQ(ierr); 98 PetscFunctionReturn(0); 99 } 100 101 #undef __FUNCT__ 102 #define __FUNCT__ "StackPush" 103 static PetscErrorCode StackPush(Stack *stack,StackElement e) 104 { 105 PetscFunctionBegin; 106 if (stack->top+1 >= stack->stacksize) SETERRQ1(PETSC_COMM_WORLD,PETSC_ERR_MEMC,"Maximum stack size (%D) exceeded",stack->stacksize); 107 stack->container[++stack->top] = e; 108 PetscFunctionReturn(0); 109 } 110 111 #undef __FUNCT__ 112 #define __FUNCT__ "StackPop" 113 static PetscErrorCode StackPop(Stack *stack,StackElement *e) 114 { 115 PetscFunctionBegin; 116 if (stack->top == -1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_MEMC,"Empty stack"); 117 *e = stack->container[stack->top--]; 118 PetscFunctionReturn(0); 119 } 120 121 #undef __FUNCT__ 122 #define __FUNCT__ "StackTop" 123 static PetscErrorCode StackTop(Stack *stack,StackElement *e) 124 { 125 PetscFunctionBegin; 126 *e = stack->container[stack->top]; 127 PetscFunctionReturn(0); 128 } 129 130 #ifdef PETSC_HAVE_REVOLVE 131 #undef __FUNCT__ 132 #define __FUNCT__ "StackFind" 133 static PetscErrorCode StackFind(Stack *stack,StackElement *e,PetscInt index) 134 { 135 PetscFunctionBegin; 136 *e = stack->container[index]; 137 PetscFunctionReturn(0); 138 } 139 #endif 140 141 #undef __FUNCT__ 142 #define __FUNCT__ "OutputBIN" 143 static PetscErrorCode OutputBIN(const char *filename,PetscViewer *viewer) 144 { 145 PetscErrorCode ierr; 146 147 PetscFunctionBegin; 148 ierr = PetscViewerCreate(PETSC_COMM_WORLD,viewer);CHKERRQ(ierr); 149 ierr = PetscViewerSetType(*viewer,PETSCVIEWERBINARY);CHKERRQ(ierr); 150 ierr = PetscViewerFileSetMode(*viewer,FILE_MODE_WRITE);CHKERRQ(ierr); 151 ierr = PetscViewerFileSetName(*viewer,filename);CHKERRQ(ierr); 152 PetscFunctionReturn(0); 153 } 154 155 #undef __FUNCT__ 156 #define __FUNCT__ "WriteToDisk" 157 static PetscErrorCode WriteToDisk(PetscInt stepnum,PetscReal time,PetscReal timeprev,Vec X,Vec *Y,PetscInt numY,PetscBool solution_only,PetscViewer viewer) 158 { 159 PetscInt i; 160 PetscErrorCode ierr; 161 162 PetscFunctionBegin; 163 ierr = PetscViewerBinaryWrite(viewer,&stepnum,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 164 ierr = VecView(X,viewer);CHKERRQ(ierr); 165 for (i=0;!solution_only && i<numY;i++) { 166 ierr = VecView(Y[i],viewer);CHKERRQ(ierr); 167 } 168 ierr = PetscViewerBinaryWrite(viewer,&time,1,PETSC_REAL,PETSC_FALSE);CHKERRQ(ierr); 169 ierr = PetscViewerBinaryWrite(viewer,&timeprev,1,PETSC_REAL,PETSC_FALSE);CHKERRQ(ierr); 170 PetscFunctionReturn(0); 171 } 172 173 #undef __FUNCT__ 174 #define __FUNCT__ "ReadFromDisk" 175 static PetscErrorCode ReadFromDisk(PetscInt *stepnum,PetscReal *time,PetscReal *timeprev,Vec X,Vec *Y,PetscInt numY,PetscBool solution_only,PetscViewer viewer) 176 { 177 PetscInt i; 178 PetscErrorCode ierr; 179 180 PetscFunctionBegin; 181 ierr = PetscViewerBinaryRead(viewer,stepnum,1,NULL,PETSC_INT);CHKERRQ(ierr); 182 ierr = VecLoad(X,viewer);CHKERRQ(ierr); 183 for (i=0;!solution_only && i<numY;i++) { 184 ierr = VecLoad(Y[i],viewer);CHKERRQ(ierr); 185 } 186 ierr = PetscViewerBinaryRead(viewer,time,1,NULL,PETSC_REAL);CHKERRQ(ierr); 187 ierr = PetscViewerBinaryRead(viewer,timeprev,1,NULL,PETSC_REAL);CHKERRQ(ierr); 188 PetscFunctionReturn(0); 189 } 190 191 #undef __FUNCT__ 192 #define __FUNCT__ "StackDumpAll" 193 static PetscErrorCode StackDumpAll(TS ts,Stack *stack,PetscInt id) 194 { 195 Vec *Y; 196 PetscInt i; 197 StackElement e; 198 PetscViewer viewer; 199 char filename[PETSC_MAX_PATH_LEN]; 200 PetscErrorCode ierr; 201 202 PetscFunctionBegin; 203 if (id == 1) { 204 PetscMPIInt rank; 205 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)ts),&rank);CHKERRQ(ierr); 206 if (!rank) { 207 ierr = PetscRMTree("SA-data");CHKERRQ(ierr); 208 ierr = PetscMkdir("SA-data");CHKERRQ(ierr); 209 } 210 } 211 ierr = PetscSNPrintf(filename,sizeof(filename),"SA-data/SA-STACK%06d.bin",id);CHKERRQ(ierr); 212 ierr = OutputBIN(filename,&viewer);CHKERRQ(ierr); 213 for (i=0;i<stack->stacksize;i++) { 214 e = stack->container[i]; 215 ierr = WriteToDisk(e->stepnum,e->time,e->timeprev,e->X,e->Y,stack->numY,stack->solution_only,viewer);CHKERRQ(ierr); 216 } 217 /* save the last step for restart, the last step is in memory when using single level schemes, but not necessarily the case for multi level schemes */ 218 ierr = TSGetStages(ts,&stack->numY,&Y);CHKERRQ(ierr); 219 ierr = WriteToDisk(ts->total_steps,ts->ptime,ts->ptime_prev,ts->vec_sol,Y,stack->numY,stack->solution_only,viewer);CHKERRQ(ierr); 220 for (i=0;i<stack->stacksize;i++) { 221 ierr = StackPop(stack,&e);CHKERRQ(ierr); 222 ierr = VecDestroy(&e->X);CHKERRQ(ierr); 223 if (!stack->solution_only) { 224 ierr = VecDestroyVecs(stack->numY,&e->Y);CHKERRQ(ierr); 225 } 226 ierr = PetscFree(e);CHKERRQ(ierr); 227 } 228 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 229 PetscFunctionReturn(0); 230 } 231 232 #undef __FUNCT__ 233 #define __FUNCT__ "StackLoadAll" 234 static PetscErrorCode StackLoadAll(TS ts,Stack *stack,PetscInt id) 235 { 236 Vec *Y; 237 PetscInt i; 238 StackElement e; 239 PetscViewer viewer; 240 char filename[PETSC_MAX_PATH_LEN]; 241 PetscErrorCode ierr; 242 243 PetscFunctionBegin; 244 ierr = PetscSNPrintf(filename,sizeof filename,"SA-data/SA-STACK%06d.bin",id);CHKERRQ(ierr); 245 ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,filename,FILE_MODE_READ,&viewer);CHKERRQ(ierr); 246 for (i=0;i<stack->stacksize;i++) { 247 ierr = PetscCalloc1(1,&e); 248 ierr = TSGetStages(ts,&stack->numY,&Y);CHKERRQ(ierr); 249 ierr = VecDuplicate(Y[0],&e->X);CHKERRQ(ierr); 250 if (!stack->solution_only && stack->numY>0) { 251 ierr = VecDuplicateVecs(Y[0],stack->numY,&e->Y);CHKERRQ(ierr); 252 } 253 ierr = StackPush(stack,e);CHKERRQ(ierr); 254 } 255 for (i=0;i<stack->stacksize;i++) { 256 e = stack->container[i]; 257 ierr = ReadFromDisk(&e->stepnum,&e->time,&e->timeprev,e->X,e->Y,stack->numY,stack->solution_only,viewer);CHKERRQ(ierr); 258 } 259 /* load the last step into TS */ 260 ierr = TSGetStages(ts,&stack->numY,&Y);CHKERRQ(ierr); 261 ierr = ReadFromDisk(&ts->total_steps,&ts->ptime,&ts->ptime_prev,ts->vec_sol,Y,stack->numY,stack->solution_only,viewer);CHKERRQ(ierr); 262 ierr = TSSetTimeStep(ts,ts->ptime_prev-ts->ptime);CHKERRQ(ierr); 263 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 264 PetscFunctionReturn(0); 265 } 266 267 #undef __FUNCT__ 268 #define __FUNCT__ "DumpSingle" 269 static PetscErrorCode DumpSingle(TS ts,Stack *stack,PetscInt id) 270 { 271 Vec *Y; 272 PetscInt stepnum; 273 PetscViewer viewer; 274 char filename[PETSC_MAX_PATH_LEN]; 275 PetscErrorCode ierr; 276 277 PetscFunctionBegin; 278 ierr = TSGetTotalSteps(ts,&stepnum);CHKERRQ(ierr); 279 if (id == 1) { 280 PetscMPIInt rank; 281 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)ts),&rank);CHKERRQ(ierr); 282 if (!rank) { 283 ierr = PetscRMTree("SA-data");CHKERRQ(ierr); 284 ierr = PetscMkdir("SA-data");CHKERRQ(ierr); 285 } 286 } 287 ierr = PetscSNPrintf(filename,sizeof(filename),"SA-data/SA-CPS%06d.bin",id);CHKERRQ(ierr); 288 ierr = OutputBIN(filename,&viewer);CHKERRQ(ierr); 289 290 ierr = PetscLogEventBegin(Disk_Write,ts,0,0,0);CHKERRQ(ierr); 291 ierr = TSGetStages(ts,&stack->numY,&Y);CHKERRQ(ierr); 292 ierr = WriteToDisk(stepnum,ts->ptime,ts->ptime_prev,ts->vec_sol,Y,stack->numY,stack->solution_only,viewer);CHKERRQ(ierr); 293 ierr = PetscLogEventEnd(Disk_Write,ts,0,0,0);CHKERRQ(ierr); 294 295 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 296 PetscFunctionReturn(0); 297 } 298 299 #undef __FUNCT__ 300 #define __FUNCT__ "LoadSingle" 301 static PetscErrorCode LoadSingle(TS ts,Stack *stack,PetscInt id) 302 { 303 Vec *Y; 304 PetscViewer viewer; 305 char filename[PETSC_MAX_PATH_LEN]; 306 PetscErrorCode ierr; 307 308 PetscFunctionBegin; 309 ierr = PetscSNPrintf(filename,sizeof filename,"SA-data/SA-CPS%06d.bin",id);CHKERRQ(ierr); 310 ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,filename,FILE_MODE_READ,&viewer);CHKERRQ(ierr); 311 312 ierr = PetscLogEventBegin(Disk_Read,ts,0,0,0);CHKERRQ(ierr); 313 ierr = TSGetStages(ts,&stack->numY,&Y);CHKERRQ(ierr); 314 ierr = ReadFromDisk(&ts->total_steps,&ts->ptime,&ts->ptime_prev,ts->vec_sol,Y,stack->numY,stack->solution_only,viewer);CHKERRQ(ierr); 315 ierr = PetscLogEventEnd(Disk_Read,ts,0,0,0);CHKERRQ(ierr); 316 317 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 318 PetscFunctionReturn(0); 319 } 320 321 #undef __FUNCT__ 322 #define __FUNCT__ "ElementCreate" 323 static PetscErrorCode ElementCreate(TS ts,Stack *stack,StackElement *e,PetscInt stepnum,PetscReal time,Vec X) 324 { 325 Vec *Y; 326 PetscInt i; 327 PetscReal timeprev; 328 PetscErrorCode ierr; 329 330 PetscFunctionBegin; 331 ierr = PetscCalloc1(1,e);CHKERRQ(ierr); 332 ierr = VecDuplicate(X,&(*e)->X);CHKERRQ(ierr); 333 ierr = VecCopy(X,(*e)->X);CHKERRQ(ierr); 334 if (stack->numY > 0 && !stack->solution_only) { 335 ierr = TSGetStages(ts,&stack->numY,&Y);CHKERRQ(ierr); 336 ierr = VecDuplicateVecs(Y[0],stack->numY,&(*e)->Y);CHKERRQ(ierr); 337 for (i=0;i<stack->numY;i++) { 338 ierr = VecCopy(Y[i],(*e)->Y[i]);CHKERRQ(ierr); 339 } 340 } 341 (*e)->stepnum = stepnum; 342 (*e)->time = time; 343 /* for consistency */ 344 if (stepnum == 0) { 345 (*e)->timeprev = (*e)->time - ts->time_step; 346 } else { 347 ierr = TSGetPrevTime(ts,&timeprev);CHKERRQ(ierr); 348 (*e)->timeprev = timeprev; 349 } 350 PetscFunctionReturn(0); 351 } 352 353 #undef __FUNCT__ 354 #define __FUNCT__ "ElementDestroy" 355 static PetscErrorCode ElementDestroy(Stack *stack,StackElement e) 356 { 357 PetscErrorCode ierr; 358 359 PetscFunctionBegin; 360 ierr = VecDestroy(&e->X);CHKERRQ(ierr); 361 if (!stack->solution_only) { 362 ierr = VecDestroyVecs(stack->numY,&e->Y);CHKERRQ(ierr); 363 } 364 ierr = PetscFree(e);CHKERRQ(ierr); 365 PetscFunctionReturn(0); 366 } 367 368 #undef __FUNCT__ 369 #define __FUNCT__ "UpdateTS" 370 static PetscErrorCode UpdateTS(TS ts,Stack *stack,StackElement e) 371 { 372 Vec *Y; 373 PetscInt i; 374 PetscErrorCode ierr; 375 376 PetscFunctionBegin; 377 ierr = VecCopy(e->X,ts->vec_sol);CHKERRQ(ierr); 378 if (!stack->solution_only) { 379 ierr = TSGetStages(ts,&stack->numY,&Y);CHKERRQ(ierr); 380 for (i=0;i<stack->numY;i++) { 381 ierr = VecCopy(e->Y[i],Y[i]);CHKERRQ(ierr); 382 } 383 } 384 ierr = TSSetTimeStep(ts,e->timeprev-e->time);CHKERRQ(ierr); /* stepsize will be negative */ 385 ts->ptime = e->time; 386 ts->ptime_prev = e->timeprev; 387 PetscFunctionReturn(0); 388 } 389 390 #undef __FUNCT__ 391 #define __FUNCT__ "ReCompute" 392 static PetscErrorCode ReCompute(TS ts,TJScheduler *tjsch,PetscInt stepnumbegin,PetscInt stepnumend) 393 { 394 Stack *stack = &tjsch->stack; 395 PetscInt i,adjsteps; 396 PetscReal stepsize; 397 PetscErrorCode ierr; 398 399 PetscFunctionBegin; 400 adjsteps = ts->steps; 401 /* reset ts context */ 402 ierr = TSGetTimeStep(ts,&stepsize);CHKERRQ(ierr); 403 ierr = TSSetTimeStep(ts,-stepsize);CHKERRQ(ierr); 404 ts->steps = stepnumbegin; /* global step number */ 405 for (i=ts->steps;i<stepnumend;i++) { /* assume fixed step size */ 406 if (stack->solution_only && !tjsch->skip_trajectory) { /* revolve online need this */ 407 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 408 } 409 ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 410 ierr = TSStep(ts);CHKERRQ(ierr); 411 if (!stack->solution_only && !tjsch->skip_trajectory) { 412 ierr = TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 413 } 414 if (ts->event) { 415 ierr = TSEventMonitor(ts);CHKERRQ(ierr); 416 } 417 if (!ts->steprollback) { 418 ierr = TSPostStep(ts);CHKERRQ(ierr); 419 } 420 } 421 ierr = TSGetTimeStep(ts,&stepsize);CHKERRQ(ierr); 422 ierr = TSSetTimeStep(ts,-stepsize);CHKERRQ(ierr); 423 ts->steps = adjsteps; 424 ts->total_steps = stepnumend; 425 PetscFunctionReturn(0); 426 } 427 428 #undef __FUNCT__ 429 #define __FUNCT__ "TopLevelStore" 430 static PetscErrorCode TopLevelStore(TS ts,TJScheduler *tjsch,PetscInt stepnum,PetscInt localstepnum,PetscInt laststridesize,PetscBool *done) 431 { 432 Stack *stack = &tjsch->stack; 433 DiskStack *diskstack = &tjsch->diskstack; 434 PetscInt stridenum; 435 PetscErrorCode ierr; 436 437 PetscFunctionBegin; 438 *done = PETSC_FALSE; 439 stridenum = stepnum/tjsch->stride; 440 /* make sure saved checkpoint id starts from 1 441 skip last stride when using stridenum+1 442 skip first stride when using stridenum */ 443 if (stack->solution_only) { 444 if (tjsch->save_stack) { 445 if (localstepnum == tjsch->stride-1 && stepnum < tjsch->total_steps-laststridesize) { /* current step will be saved without going through stack */ 446 ierr = StackDumpAll(ts,stack,stridenum+1);CHKERRQ(ierr); 447 if (tjsch->stype == TWO_LEVEL_TWO_REVOLVE) diskstack->container[++diskstack->top] = stridenum+1; 448 PetscPrintf(PETSC_COMM_WORLD,"\x1B[33mDump stack to file\033[0m\n"); 449 *done = PETSC_TRUE; 450 } 451 } else { 452 if (localstepnum == 0 && stepnum < tjsch->total_steps-laststridesize) { 453 ierr = DumpSingle(ts,stack,stridenum+1);CHKERRQ(ierr); 454 if (tjsch->stype == TWO_LEVEL_TWO_REVOLVE) diskstack->container[++diskstack->top] = stridenum+1; 455 PetscPrintf(PETSC_COMM_WORLD,"\x1B[33mDump a single point (solution) to file\033[0m\n"); 456 *done = PETSC_TRUE; 457 } 458 } 459 } else { 460 if (tjsch->save_stack) { 461 if (localstepnum == 0 && stepnum < tjsch->total_steps && stepnum != 0) { /* skip the first stride */ 462 ierr = StackDumpAll(ts,stack,stridenum);CHKERRQ(ierr); 463 if (tjsch->stype == TWO_LEVEL_TWO_REVOLVE) diskstack->container[++diskstack->top] = stridenum; 464 PetscPrintf(PETSC_COMM_WORLD,"\x1B[33mDump stack to file\033[0m\n"); 465 *done = PETSC_TRUE; 466 } 467 } else { 468 if (localstepnum == 1 && stepnum < tjsch->total_steps-laststridesize) { 469 ierr = DumpSingle(ts,stack,stridenum+1);CHKERRQ(ierr); 470 if (tjsch->stype == TWO_LEVEL_TWO_REVOLVE) diskstack->container[++diskstack->top] = stridenum+1; 471 PetscPrintf(PETSC_COMM_WORLD,"\x1B[33mDump a single point (solution+stages) to file\033[0m\n"); 472 *done = PETSC_TRUE; 473 } 474 } 475 } 476 PetscFunctionReturn(0); 477 } 478 479 #undef __FUNCT__ 480 #define __FUNCT__ "SetTrajN" 481 static PetscErrorCode SetTrajN(TS ts,TJScheduler *tjsch,PetscInt stepnum,PetscReal time,Vec X) 482 { 483 Stack *stack = &tjsch->stack; 484 StackElement e; 485 PetscErrorCode ierr; 486 487 PetscFunctionBegin; 488 /* skip the last two steps of each stride or the whole interval */ 489 if (stack->solution_only && (stepnum >= tjsch->total_steps-1 || tjsch->recompute)) PetscFunctionReturn(0); //? 490 /* skip the first and the last steps of each stride or the whole interval */ 491 if (!stack->solution_only && (stepnum == 0 || stepnum == tjsch->total_steps)) PetscFunctionReturn(0); 492 493 if (stepnum < stack->top) SETERRQ(tjsch->comm,PETSC_ERR_MEMC,"Illegal modification of a non-top stack element"); 494 ierr = ElementCreate(ts,stack,&e,stepnum,time,X);CHKERRQ(ierr); 495 ierr = StackPush(stack,e);CHKERRQ(ierr); 496 PetscFunctionReturn(0); 497 } 498 499 #undef __FUNCT__ 500 #define __FUNCT__ "GetTrajN" 501 static PetscErrorCode GetTrajN(TS ts,TJScheduler *tjsch,PetscInt stepnum) 502 { 503 Stack *stack = &tjsch->stack; 504 PetscReal stepsize; 505 StackElement e; 506 PetscErrorCode ierr; 507 508 PetscFunctionBegin; 509 if (stepnum == tjsch->total_steps) { 510 ierr = TSGetTimeStep(ts,&stepsize);CHKERRQ(ierr); 511 ierr = TSSetTimeStep(ts,-stepsize);CHKERRQ(ierr); 512 PetscFunctionReturn(0); 513 } 514 /* restore a checkpoint */ 515 ierr = StackTop(stack,&e);CHKERRQ(ierr); 516 ierr = UpdateTS(ts,stack,e);CHKERRQ(ierr); 517 if (stack->solution_only) {/* recompute one step */ 518 tjsch->recompute = PETSC_TRUE; 519 ierr = ReCompute(ts,tjsch,e->stepnum,stepnum);CHKERRQ(ierr); 520 } 521 ierr = StackPop(stack,&e);CHKERRQ(ierr); 522 ierr = ElementDestroy(stack,e);CHKERRQ(ierr); 523 PetscFunctionReturn(0); 524 } 525 526 #undef __FUNCT__ 527 #define __FUNCT__ "SetTrajTLNR" 528 static PetscErrorCode SetTrajTLNR(TS ts,TJScheduler *tjsch,PetscInt stepnum,PetscReal time,Vec X) 529 { 530 Stack *stack = &tjsch->stack; 531 PetscInt localstepnum,laststridesize; 532 StackElement e; 533 PetscBool done; 534 PetscErrorCode ierr; 535 536 PetscFunctionBegin; 537 if (!stack->solution_only && stepnum == 0) PetscFunctionReturn(0); 538 if (stack->solution_only && stepnum == tjsch->total_steps) PetscFunctionReturn(0); 539 if (tjsch->save_stack && tjsch->recompute) PetscFunctionReturn(0); 540 541 localstepnum = stepnum%tjsch->stride; 542 /* (stride size-1) checkpoints are saved in each stride; an extra point is added by StackDumpAll() */ 543 laststridesize = tjsch->total_steps%tjsch->stride; 544 if (!laststridesize) laststridesize = tjsch->stride; 545 546 if (!tjsch->recompute) { 547 ierr = TopLevelStore(ts,tjsch,stepnum,localstepnum,laststridesize,&done);CHKERRQ(ierr); 548 if (!tjsch->save_stack && stepnum < tjsch->total_steps-laststridesize) PetscFunctionReturn(0); 549 } 550 if (!stack->solution_only && localstepnum == 0) PetscFunctionReturn(0); /* skip last point in each stride at recompute stage or last stride */ 551 if (stack->solution_only && localstepnum == tjsch->stride-1) PetscFunctionReturn(0); /* skip last step in each stride at recompute stage or last stride */ 552 553 ierr = ElementCreate(ts,stack,&e,stepnum,time,X);CHKERRQ(ierr); 554 ierr = StackPush(stack,e);CHKERRQ(ierr); 555 PetscFunctionReturn(0); 556 } 557 558 #undef __FUNCT__ 559 #define __FUNCT__ "GetTrajTLNR" 560 static PetscErrorCode GetTrajTLNR(TS ts,TJScheduler *tjsch,PetscInt stepnum) 561 { 562 Stack *stack = &tjsch->stack; 563 PetscInt id,localstepnum,laststridesize; 564 PetscReal stepsize; 565 StackElement e; 566 PetscErrorCode ierr; 567 568 PetscFunctionBegin; 569 if (stepnum == tjsch->total_steps) { 570 ierr = TSGetTimeStep(ts,&stepsize);CHKERRQ(ierr); 571 ierr = TSSetTimeStep(ts,-stepsize);CHKERRQ(ierr); 572 PetscFunctionReturn(0); 573 } 574 575 localstepnum = stepnum%tjsch->stride; 576 laststridesize = tjsch->total_steps%tjsch->stride; 577 if (!laststridesize) laststridesize = tjsch->stride; 578 if (stack->solution_only) { 579 /* fill stack with info */ 580 if (localstepnum == 0 && tjsch->total_steps-stepnum >= laststridesize) { 581 id = stepnum/tjsch->stride; 582 if (tjsch->save_stack) { 583 ierr = StackLoadAll(ts,stack,id);CHKERRQ(ierr); 584 tjsch->recompute = PETSC_TRUE; 585 tjsch->skip_trajectory = PETSC_TRUE; 586 ierr = ReCompute(ts,tjsch,id*tjsch->stride-1,id*tjsch->stride);CHKERRQ(ierr); 587 tjsch->skip_trajectory = PETSC_FALSE; 588 } else { 589 ierr = LoadSingle(ts,stack,id);CHKERRQ(ierr); 590 tjsch->recompute = PETSC_TRUE; 591 ierr = ReCompute(ts,tjsch,(id-1)*tjsch->stride,id*tjsch->stride);CHKERRQ(ierr); 592 } 593 PetscFunctionReturn(0); 594 } 595 /* restore a checkpoint */ 596 ierr = StackPop(stack,&e);CHKERRQ(ierr); 597 ierr = UpdateTS(ts,stack,e);CHKERRQ(ierr); 598 tjsch->recompute = PETSC_TRUE; 599 tjsch->skip_trajectory = PETSC_TRUE; 600 ierr = ReCompute(ts,tjsch,e->stepnum,stepnum);CHKERRQ(ierr); 601 tjsch->skip_trajectory = PETSC_FALSE; 602 ierr = ElementDestroy(stack,e);CHKERRQ(ierr); 603 } else { 604 /* fill stack with info */ 605 if (localstepnum == 0 && tjsch->total_steps-stepnum >= laststridesize) { 606 id = stepnum/tjsch->stride; 607 if (tjsch->save_stack) { 608 ierr = StackLoadAll(ts,stack,id);CHKERRQ(ierr); 609 } else { 610 ierr = LoadSingle(ts,stack,id);CHKERRQ(ierr); 611 ierr = ElementCreate(ts,stack,&e,(id-1)*tjsch->stride+1,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 612 ierr = StackPush(stack,e);CHKERRQ(ierr); 613 tjsch->recompute = PETSC_TRUE; 614 ierr = ReCompute(ts,tjsch,e->stepnum,id*tjsch->stride);CHKERRQ(ierr); 615 } 616 PetscFunctionReturn(0); 617 } 618 /* restore a checkpoint */ 619 ierr = StackPop(stack,&e);CHKERRQ(ierr); 620 ierr = UpdateTS(ts,stack,e);CHKERRQ(ierr); 621 ierr = ElementDestroy(stack,e);CHKERRQ(ierr); 622 } 623 PetscFunctionReturn(0); 624 } 625 626 #ifdef PETSC_HAVE_REVOLVE 627 static void printwhattodo(PetscInt whattodo,RevolveCTX *rctx,PetscInt shift) 628 { 629 switch(whattodo) { 630 case 1: 631 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35mAdvance from %D to %D\033[0m\n",rctx->oldcapo+shift,rctx->capo+shift); 632 break; 633 case 2: 634 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35mStore in checkpoint number %D (located in RAM)\033[0m\n",rctx->check); 635 break; 636 case 3: 637 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35mFirst turn: Initialize adjoints and reverse first step\033[0m\n"); 638 break; 639 case 4: 640 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35mForward and reverse one step\033[0m\n"); 641 break; 642 case 5: 643 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35mRestore in checkpoint number %D (located in RAM)\033[0m\n",rctx->check); 644 break; 645 case 7: 646 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35mStore in checkpoint number %D (located on disk)\033[0m\n",rctx->check); 647 break; 648 case 8: 649 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35mRestore in checkpoint number %D (located on disk)\033[0m\n",rctx->check); 650 break; 651 case -1: 652 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35mError!"); 653 break; 654 } 655 } 656 657 static void printwhattodo2(PetscInt whattodo,RevolveCTX *rctx,PetscInt shift) 658 { 659 switch(whattodo) { 660 case 1: 661 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35m[Top Level] Advance from stride %D to stride %D\033[0m\n",rctx->oldcapo+shift,rctx->capo+shift); 662 break; 663 case 2: 664 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35m[Top Level] Store in checkpoint number %D\033[0m\n",rctx->check); 665 break; 666 case 3: 667 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35m[Top Level] First turn: Initialize adjoints and reverse first stride\033[0m\n"); 668 break; 669 case 4: 670 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35m[Top Level] Forward and reverse one stride\033[0m\n"); 671 break; 672 case 5: 673 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35m[Top Level] Restore in checkpoint number %D\033[0m\n",rctx->check); 674 break; 675 case 7: 676 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35m[Top Level] Store in top-level checkpoint number %D\033[0m\n",rctx->check); 677 break; 678 case 8: 679 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35m[Top Level] Restore in top-level checkpoint number %D\033[0m\n",rctx->check); 680 break; 681 case -1: 682 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35m[Top Level] Error!"); 683 break; 684 } 685 } 686 687 #undef __FUNCT__ 688 #define __FUNCT__ "ApplyRevolve" 689 static PetscErrorCode ApplyRevolve(SchedulerType stype,RevolveCTX *rctx,PetscInt total_steps,PetscInt stepnum,PetscInt localstepnum,PetscBool toplevel,PetscInt *store) 690 { 691 PetscInt shift,whattodo; 692 693 PetscFunctionBegin; 694 *store = 0; 695 // if (rctx->reverseonestep && stepnum == total_steps) { /* intermediate information is ready inside TS, this happens at last time step */ 696 // rctx->reverseonestep = PETSC_FALSE; 697 // PetscFunctionReturn(0); 698 // } 699 if (rctx->stepsleft > 0) { /* advance the solution without checkpointing anything as Revolve requires */ 700 rctx->stepsleft--; 701 PetscFunctionReturn(0); 702 } 703 /* let Revolve determine what to do next */ 704 shift = stepnum-localstepnum; 705 rctx->oldcapo = rctx->capo; 706 rctx->capo = localstepnum; 707 708 if (!toplevel) whattodo = revolve_action(&rctx->check,&rctx->capo,&rctx->fine,rctx->snaps_in,&rctx->info,&rctx->where); 709 else whattodo = revolve2_action(&rctx->check,&rctx->capo,&rctx->fine,rctx->snaps_in,&rctx->info,&rctx->where); 710 if (stype == REVOLVE_ONLINE && whattodo == 8) whattodo = 5; 711 if (stype == REVOLVE_ONLINE && whattodo == 7) whattodo = 2; 712 if (!toplevel) printwhattodo(whattodo,rctx,shift); 713 else printwhattodo2(whattodo,rctx,shift); 714 if (whattodo == -1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_LIB,"Error in the Revolve library"); 715 if (whattodo == 1) { /* advance some time steps */ 716 if (stype == REVOLVE_ONLINE && rctx->capo >= total_steps-1) { 717 revolve_turn(total_steps,&rctx->capo,&rctx->fine); 718 if (!toplevel) printwhattodo(whattodo,rctx,shift); 719 else printwhattodo2(whattodo,rctx,shift); 720 } 721 rctx->stepsleft = rctx->capo-rctx->oldcapo-1; 722 } 723 if (whattodo == 3 || whattodo == 4) { /* ready for a reverse step */ 724 rctx->reverseonestep = PETSC_TRUE; 725 } 726 if (whattodo == 5) { /* restore a checkpoint and ask Revolve what to do next */ 727 rctx->oldcapo = rctx->capo; 728 if (!toplevel) whattodo = revolve_action(&rctx->check,&rctx->capo,&rctx->fine,rctx->snaps_in,&rctx->info,&rctx->where); /* must return 1 or 3 or 4*/ 729 else whattodo = revolve2_action(&rctx->check,&rctx->capo,&rctx->fine,rctx->snaps_in,&rctx->info,&rctx->where); 730 if (!toplevel) printwhattodo(whattodo,rctx,shift); 731 else printwhattodo2(whattodo,rctx,shift); 732 if (whattodo == 3 || whattodo == 4) rctx->reverseonestep = PETSC_TRUE; 733 if (whattodo == 1) rctx->stepsleft = rctx->capo-rctx->oldcapo; 734 } 735 if (whattodo == 7) { /* save the checkpoint to disk */ 736 *store = 2; 737 rctx->oldcapo = rctx->capo; 738 whattodo = revolve_action(&rctx->check,&rctx->capo,&rctx->fine,rctx->snaps_in,&rctx->info,&rctx->where); /* must return 1 */ 739 printwhattodo(whattodo,rctx,shift); 740 rctx->stepsleft = rctx->capo-rctx->oldcapo-1; 741 } 742 if (whattodo == 2) { /* store a checkpoint to RAM and ask Revolve how many time steps to advance next */ 743 *store = 1; 744 rctx->oldcapo = rctx->capo; 745 if (!toplevel) whattodo = revolve_action(&rctx->check,&rctx->capo,&rctx->fine,rctx->snaps_in,&rctx->info,&rctx->where); /* must return 1 */ 746 else whattodo = revolve2_action(&rctx->check,&rctx->capo,&rctx->fine,rctx->snaps_in,&rctx->info,&rctx->where); 747 if (!toplevel) printwhattodo(whattodo,rctx,shift); 748 else printwhattodo2(whattodo,rctx,shift); 749 if (stype == REVOLVE_ONLINE && rctx->capo >= total_steps-1) { 750 revolve_turn(total_steps,&rctx->capo,&rctx->fine); 751 printwhattodo(whattodo,rctx,shift); 752 } 753 rctx->stepsleft = rctx->capo-rctx->oldcapo-1; 754 } 755 PetscFunctionReturn(0); 756 } 757 758 #undef __FUNCT__ 759 #define __FUNCT__ "SetTrajROF" 760 static PetscErrorCode SetTrajROF(TS ts,TJScheduler *tjsch,PetscInt stepnum,PetscReal time,Vec X) 761 { 762 Stack *stack = &tjsch->stack; 763 PetscInt store; 764 StackElement e; 765 PetscErrorCode ierr; 766 767 PetscFunctionBegin; 768 if (!stack->solution_only && stepnum == 0) PetscFunctionReturn(0); 769 if (stack->solution_only && stepnum == tjsch->total_steps) PetscFunctionReturn(0); 770 ierr = ApplyRevolve(tjsch->stype,tjsch->rctx,tjsch->total_steps,stepnum,stepnum,PETSC_FALSE,&store);CHKERRQ(ierr); 771 if (store == 1) { 772 if (stepnum < stack->top) SETERRQ(tjsch->comm,PETSC_ERR_MEMC,"Illegal modification of a non-top stack element"); 773 ierr = ElementCreate(ts,stack,&e,stepnum,time,X);CHKERRQ(ierr); 774 ierr = StackPush(stack,e);CHKERRQ(ierr); 775 } 776 PetscFunctionReturn(0); 777 } 778 779 #undef __FUNCT__ 780 #define __FUNCT__ "GetTrajROF" 781 static PetscErrorCode GetTrajROF(TS ts,TJScheduler *tjsch,PetscInt stepnum) 782 { 783 Stack *stack = &tjsch->stack; 784 PetscInt whattodo,shift,store; 785 PetscReal stepsize; 786 StackElement e; 787 PetscErrorCode ierr; 788 789 PetscFunctionBegin; 790 if (stepnum == 0 || stepnum == tjsch->total_steps) { 791 ierr = TSGetTimeStep(ts,&stepsize);CHKERRQ(ierr); 792 ierr = TSSetTimeStep(ts,-stepsize);CHKERRQ(ierr); 793 if (tjsch->rctx->reverseonestep) tjsch->rctx->reverseonestep = PETSC_FALSE; 794 PetscFunctionReturn(0); 795 } 796 /* restore a checkpoint */ 797 ierr = StackTop(stack,&e);CHKERRQ(ierr); 798 ierr = UpdateTS(ts,stack,e);CHKERRQ(ierr); 799 if (stack->solution_only) { /* start with restoring a checkpoint */ 800 tjsch->rctx->capo = stepnum; 801 tjsch->rctx->oldcapo = tjsch->rctx->capo; 802 shift = 0; 803 whattodo = revolve_action(&tjsch->rctx->check,&tjsch->rctx->capo,&tjsch->rctx->fine,tjsch->rctx->snaps_in,&tjsch->rctx->info,&tjsch->rctx->where); 804 printwhattodo(whattodo,tjsch->rctx,shift); 805 } else { /* 2 revolve actions: restore a checkpoint and then advance */ 806 ierr = ApplyRevolve(tjsch->stype,tjsch->rctx,tjsch->total_steps,stepnum,stepnum,PETSC_FALSE,&store);CHKERRQ(ierr); 807 if (!tjsch->rctx->reverseonestep && tjsch->rctx->stepsleft > 0) { 808 tjsch->rctx->stepsleft--; 809 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35mSkip the step from %D to %D (already checkpointed)\033[0m\n",tjsch->rctx->oldcapo,tjsch->rctx->oldcapo+1); 810 } 811 } 812 if (stack->solution_only || (!stack->solution_only && e->stepnum < stepnum)) { 813 tjsch->recompute = PETSC_TRUE; 814 ierr = ReCompute(ts,tjsch,e->stepnum,stepnum);CHKERRQ(ierr); 815 } 816 if ((stack->solution_only && e->stepnum+1 == stepnum) || (!stack->solution_only && e->stepnum == stepnum)) { 817 ierr = StackPop(stack,&e);CHKERRQ(ierr); 818 ierr = ElementDestroy(stack,e);CHKERRQ(ierr); 819 } 820 if (tjsch->rctx->reverseonestep) tjsch->rctx->reverseonestep = PETSC_FALSE; 821 PetscFunctionReturn(0); 822 } 823 824 #undef __FUNCT__ 825 #define __FUNCT__ "SetTrajRON" 826 static PetscErrorCode SetTrajRON(TS ts,TJScheduler *tjsch,PetscInt stepnum,PetscReal time,Vec X) 827 { 828 Stack *stack = &tjsch->stack; 829 Vec *Y; 830 PetscInt i,store; 831 PetscReal timeprev; 832 StackElement e; 833 RevolveCTX *rctx = tjsch->rctx; 834 PetscErrorCode ierr; 835 836 PetscFunctionBegin; 837 if (!stack->solution_only && stepnum == 0) PetscFunctionReturn(0); 838 if (stack->solution_only && stepnum == tjsch->total_steps) PetscFunctionReturn(0); 839 ierr = ApplyRevolve(tjsch->stype,rctx,tjsch->total_steps,stepnum,stepnum,PETSC_FALSE,&store);CHKERRQ(ierr); 840 if (store == 1) { 841 if (rctx->check != stack->top+1) { /* overwrite some non-top checkpoint in the stack */ 842 ierr = StackFind(stack,&e,rctx->check);CHKERRQ(ierr); 843 ierr = VecCopy(X,e->X);CHKERRQ(ierr); 844 if (stack->numY > 0 && !stack->solution_only) { 845 ierr = TSGetStages(ts,&stack->numY,&Y);CHKERRQ(ierr); 846 for (i=0;i<stack->numY;i++) { 847 ierr = VecCopy(Y[i],e->Y[i]);CHKERRQ(ierr); 848 } 849 } 850 e->stepnum = stepnum; 851 e->time = time; 852 ierr = TSGetPrevTime(ts,&timeprev);CHKERRQ(ierr); 853 e->timeprev = timeprev; 854 } else { 855 if (stepnum < stack->top) SETERRQ(tjsch->comm,PETSC_ERR_MEMC,"Illegal modification of a non-top stack element"); 856 ierr = ElementCreate(ts,stack,&e,stepnum,time,X);CHKERRQ(ierr); 857 ierr = StackPush(stack,e);CHKERRQ(ierr); 858 } 859 } 860 PetscFunctionReturn(0); 861 } 862 863 #undef __FUNCT__ 864 #define __FUNCT__ "GetTrajRON" 865 static PetscErrorCode GetTrajRON(TS ts,TJScheduler *tjsch,PetscInt stepnum) 866 { 867 Stack *stack = &tjsch->stack; 868 PetscInt whattodo,shift; 869 PetscReal stepsize; 870 StackElement e; 871 PetscErrorCode ierr; 872 873 PetscFunctionBegin; 874 if (stepnum == 0 || stepnum == tjsch->total_steps) { 875 ierr = TSGetTimeStep(ts,&stepsize);CHKERRQ(ierr); 876 ierr = TSSetTimeStep(ts,-stepsize);CHKERRQ(ierr); 877 if (tjsch->rctx->reverseonestep) tjsch->rctx->reverseonestep = PETSC_FALSE; 878 PetscFunctionReturn(0); 879 } 880 tjsch->rctx->capo = stepnum; 881 tjsch->rctx->oldcapo = tjsch->rctx->capo; 882 shift = 0; 883 whattodo = revolve_action(&tjsch->rctx->check,&tjsch->rctx->capo,&tjsch->rctx->fine,tjsch->rctx->snaps_in,&tjsch->rctx->info,&tjsch->rctx->where); /* whattodo=restore */ 884 if (whattodo == 8) whattodo = 5; 885 printwhattodo(whattodo,tjsch->rctx,shift); 886 /* restore a checkpoint */ 887 ierr = StackFind(stack,&e,tjsch->rctx->check);CHKERRQ(ierr); 888 ierr = UpdateTS(ts,stack,e);CHKERRQ(ierr); 889 if (!stack->solution_only) { /* whattodo must be 5 */ 890 /* ask Revolve what to do next */ 891 tjsch->rctx->oldcapo = tjsch->rctx->capo; 892 whattodo = revolve_action(&tjsch->rctx->check,&tjsch->rctx->capo,&tjsch->rctx->fine,tjsch->rctx->snaps_in,&tjsch->rctx->info,&tjsch->rctx->where); /* must return 1 or 3 or 4*/ 893 printwhattodo(whattodo,tjsch->rctx,shift); 894 if (whattodo == 3 || whattodo == 4) tjsch->rctx->reverseonestep = PETSC_TRUE; 895 if (whattodo == 1) tjsch->rctx->stepsleft = tjsch->rctx->capo-tjsch->rctx->oldcapo; 896 if (!tjsch->rctx->reverseonestep && tjsch->rctx->stepsleft > 0) { 897 tjsch->rctx->stepsleft--; 898 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35mSkip the step from %D to %D (already checkpointed)\033[0m\n",tjsch->rctx->oldcapo,tjsch->rctx->oldcapo+1); 899 } 900 } 901 if (stack->solution_only || (!stack->solution_only && e->stepnum < stepnum)) { 902 tjsch->recompute = PETSC_TRUE; 903 ierr = ReCompute(ts,tjsch,e->stepnum,stepnum);CHKERRQ(ierr); 904 } 905 if (tjsch->rctx->reverseonestep) tjsch->rctx->reverseonestep = PETSC_FALSE; 906 PetscFunctionReturn(0); 907 } 908 909 #undef __FUNCT__ 910 #define __FUNCT__ "SetTrajTLR" 911 static PetscErrorCode SetTrajTLR(TS ts,TJScheduler *tjsch,PetscInt stepnum,PetscReal time,Vec X) 912 { 913 Stack *stack = &tjsch->stack; 914 PetscInt store,localstepnum,laststridesize; 915 StackElement e; 916 RevolveCTX *rctx = tjsch->rctx; 917 PetscBool done = PETSC_FALSE; 918 PetscErrorCode ierr; 919 920 PetscFunctionBegin; 921 if (!stack->solution_only && stepnum == 0) PetscFunctionReturn(0); 922 if (stack->solution_only && stepnum == tjsch->total_steps) PetscFunctionReturn(0); 923 924 localstepnum = stepnum%tjsch->stride; 925 laststridesize = tjsch->total_steps%tjsch->stride; 926 if (!laststridesize) laststridesize = tjsch->stride; 927 928 if (!tjsch->recompute) { /* skip last stride */ 929 ierr = TopLevelStore(ts,tjsch,stepnum,localstepnum,laststridesize,&done);CHKERRQ(ierr); 930 /* different starting points for last stride between solutin_only and !solutin_only */ 931 if (!stack->solution_only && !tjsch->save_stack && stepnum <= tjsch->total_steps-laststridesize) PetscFunctionReturn(0); 932 if (stack->solution_only && !tjsch->save_stack && stepnum < tjsch->total_steps-laststridesize) PetscFunctionReturn(0); 933 } 934 935 if (tjsch->save_stack && done) { 936 revolve_reset(); 937 revolve_create_offline(tjsch->stride,tjsch->max_cps_ram); 938 rctx = tjsch->rctx; 939 rctx->check = 0; 940 rctx->capo = 0; 941 rctx->fine = tjsch->stride; 942 tjsch->rctx->reverseonestep = PETSC_FALSE; 943 PetscFunctionReturn(0); 944 } 945 ierr = ApplyRevolve(tjsch->stype,tjsch->rctx,tjsch->total_steps,stepnum,localstepnum,PETSC_FALSE,&store);CHKERRQ(ierr); 946 if (store == 1) { 947 if (localstepnum < stack->top) SETERRQ(tjsch->comm,PETSC_ERR_MEMC,"Illegal modification of a non-top stack element"); 948 ierr = ElementCreate(ts,stack,&e,stepnum,time,X);CHKERRQ(ierr); 949 ierr = StackPush(stack,e);CHKERRQ(ierr); 950 } 951 952 PetscFunctionReturn(0); 953 } 954 955 #undef __FUNCT__ 956 #define __FUNCT__ "GetTrajTLR" 957 static PetscErrorCode GetTrajTLR(TS ts,TJScheduler *tjsch,PetscInt stepnum) 958 { 959 Stack *stack = &tjsch->stack; 960 PetscInt whattodo,shift; 961 PetscInt localstepnum,stridenum,laststridesize,store; 962 PetscReal stepsize; 963 StackElement e; 964 PetscErrorCode ierr; 965 966 PetscFunctionBegin; 967 localstepnum = stepnum%tjsch->stride; 968 stridenum = stepnum/tjsch->stride; 969 if (stepnum == tjsch->total_steps) { 970 ierr = TSGetTimeStep(ts,&stepsize);CHKERRQ(ierr); 971 ierr = TSSetTimeStep(ts,-stepsize);CHKERRQ(ierr); 972 if ( tjsch->rctx->reverseonestep) tjsch->rctx->reverseonestep = PETSC_FALSE; 973 PetscFunctionReturn(0); 974 } 975 laststridesize = tjsch->total_steps%tjsch->stride; 976 if (!laststridesize) laststridesize = tjsch->stride; 977 if (stack->solution_only) { 978 /* fill stack */ 979 if (localstepnum == 0 && stepnum <= tjsch->total_steps-laststridesize) { 980 if (tjsch->save_stack) { 981 PetscPrintf(PETSC_COMM_WORLD,"\x1B[33mLoad stack from file\033[0m\n"); 982 ierr = StackLoadAll(ts,stack,stridenum);CHKERRQ(ierr); 983 revolve_reset(); 984 revolve_create_offline(tjsch->stride,tjsch->max_cps_ram); 985 tjsch->rctx->check = 0; 986 tjsch->rctx->capo = 0; 987 tjsch->rctx->fine = tjsch->stride; 988 whattodo = 0; 989 while(whattodo!=3) { /* stupid revolve */ 990 whattodo = revolve_action(&tjsch->rctx->check,&tjsch->rctx->capo,&tjsch->rctx->fine,tjsch->rctx->snaps_in,&tjsch->rctx->info,&tjsch->rctx->where); 991 } 992 tjsch->recompute = PETSC_TRUE; 993 tjsch->skip_trajectory = PETSC_TRUE; 994 ierr = ReCompute(ts,tjsch,stridenum*tjsch->stride-1,stridenum*tjsch->stride);CHKERRQ(ierr); 995 tjsch->skip_trajectory = PETSC_FALSE; 996 } else { 997 PetscPrintf(PETSC_COMM_WORLD,"\x1B[33mLoad a single point from file\033[0m\n"); 998 ierr = LoadSingle(ts,stack,stridenum);CHKERRQ(ierr); 999 revolve_reset(); 1000 revolve_create_offline(tjsch->stride,tjsch->max_cps_ram); 1001 tjsch->rctx->check = 0; 1002 tjsch->rctx->capo = 0; 1003 tjsch->rctx->fine = tjsch->stride; 1004 tjsch->recompute = PETSC_TRUE; 1005 ierr = ReCompute(ts,tjsch,(stridenum-1)*tjsch->stride,stridenum*tjsch->stride);CHKERRQ(ierr); 1006 } 1007 PetscFunctionReturn(0); 1008 } 1009 /* restore a checkpoint */ 1010 ierr = StackTop(stack,&e);CHKERRQ(ierr); 1011 ierr = UpdateTS(ts,stack,e);CHKERRQ(ierr); 1012 /* start with restoring a checkpoint */ 1013 tjsch->rctx->capo = stepnum; 1014 tjsch->rctx->oldcapo = tjsch->rctx->capo; 1015 shift = stepnum-localstepnum; 1016 whattodo = revolve_action(&tjsch->rctx->check,&tjsch->rctx->capo,&tjsch->rctx->fine,tjsch->rctx->snaps_in,&tjsch->rctx->info,&tjsch->rctx->where); 1017 printwhattodo(whattodo,tjsch->rctx,shift); 1018 tjsch->recompute = PETSC_TRUE; 1019 ierr = ReCompute(ts,tjsch,e->stepnum,stepnum);CHKERRQ(ierr); 1020 if (e->stepnum+1 == stepnum) { 1021 ierr = StackPop(stack,&e);CHKERRQ(ierr); 1022 ierr = ElementDestroy(stack,e);CHKERRQ(ierr); 1023 } 1024 } else { 1025 /* fill stack with info */ 1026 if (localstepnum == 0 && tjsch->total_steps-stepnum >= laststridesize) { 1027 if (tjsch->save_stack) { 1028 PetscPrintf(PETSC_COMM_WORLD,"\x1B[33mLoad stack from file\033[0m\n"); 1029 ierr = StackLoadAll(ts,stack,stridenum);CHKERRQ(ierr); 1030 revolve_reset(); 1031 revolve_create_offline(tjsch->stride,tjsch->max_cps_ram); 1032 tjsch->rctx->check = 0; 1033 tjsch->rctx->capo = 0; 1034 tjsch->rctx->fine = tjsch->stride; 1035 whattodo = 0; 1036 while(whattodo!=3) { /* stupid revolve */ 1037 whattodo = revolve_action(&tjsch->rctx->check,&tjsch->rctx->capo,&tjsch->rctx->fine,tjsch->rctx->snaps_in,&tjsch->rctx->info,&tjsch->rctx->where); 1038 } 1039 } else { 1040 PetscPrintf(PETSC_COMM_WORLD,"\x1B[33mLoad a single point from file\033[0m\n"); 1041 ierr = LoadSingle(ts,stack,stridenum);CHKERRQ(ierr); 1042 revolve_reset(); 1043 revolve_create_offline(tjsch->stride,tjsch->max_cps_ram); 1044 tjsch->rctx->stepsleft = 0; 1045 tjsch->rctx->check = 0; 1046 tjsch->rctx->capo = 0; 1047 tjsch->rctx->fine = tjsch->stride; 1048 ierr = ApplyRevolve(tjsch->stype,tjsch->rctx,tjsch->total_steps,(stridenum-1)*tjsch->stride+1,1,PETSC_FALSE,&store);CHKERRQ(ierr); 1049 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35mSkip the step from %D to %D (already checkpointed)\033[0m\n",(stridenum-1)*tjsch->stride+tjsch->rctx->oldcapo,(stridenum-1)*tjsch->stride+tjsch->rctx->oldcapo+1); 1050 ierr = ElementCreate(ts,stack,&e,(stridenum-1)*tjsch->stride+1,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 1051 ierr = StackPush(stack,e);CHKERRQ(ierr); 1052 tjsch->recompute = PETSC_TRUE; 1053 ierr = ReCompute(ts,tjsch,e->stepnum,stridenum*tjsch->stride);CHKERRQ(ierr); 1054 } 1055 PetscFunctionReturn(0); 1056 } 1057 /* restore a checkpoint */ 1058 ierr = StackTop(stack,&e);CHKERRQ(ierr); 1059 ierr = UpdateTS(ts,stack,e);CHKERRQ(ierr); 1060 /* 2 revolve actions: restore a checkpoint and then advance */ 1061 ierr = ApplyRevolve(tjsch->stype,tjsch->rctx,tjsch->total_steps,stepnum,localstepnum,PETSC_FALSE,&store);CHKERRQ(ierr); 1062 if (!tjsch->rctx->reverseonestep && tjsch->rctx->stepsleft > 0) { 1063 tjsch->rctx->stepsleft--; 1064 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35mSkip the step from %D to %D (already checkpointed)\033[0m\n",stepnum-localstepnum+tjsch->rctx->oldcapo,stepnum-localstepnum+tjsch->rctx->oldcapo+1); 1065 } 1066 if (e->stepnum < stepnum) { 1067 tjsch->recompute = PETSC_TRUE; 1068 ierr = ReCompute(ts,tjsch,e->stepnum,stepnum);CHKERRQ(ierr); 1069 } 1070 if (e->stepnum == stepnum) { 1071 ierr = StackPop(stack,&e);CHKERRQ(ierr); 1072 ierr = ElementDestroy(stack,e);CHKERRQ(ierr); 1073 } 1074 } 1075 if (tjsch->rctx->reverseonestep) tjsch->rctx->reverseonestep = PETSC_FALSE; 1076 PetscFunctionReturn(0); 1077 } 1078 1079 #undef __FUNCT__ 1080 #define __FUNCT__ "SetTrajTLTR" 1081 static PetscErrorCode SetTrajTLTR(TS ts,TJScheduler *tjsch,PetscInt stepnum,PetscReal time,Vec X) 1082 { 1083 Stack *stack = &tjsch->stack; 1084 PetscInt store,localstepnum,stridenum,laststridesize; 1085 StackElement e; 1086 RevolveCTX *rctx = tjsch->rctx; 1087 PetscBool done = PETSC_FALSE; 1088 PetscErrorCode ierr; 1089 1090 PetscFunctionBegin; 1091 //if (!stack->solution_only && stepnum == 0) PetscFunctionReturn(0); 1092 if (stack->solution_only && stepnum == tjsch->total_steps) PetscFunctionReturn(0); 1093 1094 localstepnum = stepnum%tjsch->stride; /* index at the bottom level (inside a stride) */ 1095 stridenum = stepnum/tjsch->stride; /* index at the top level */ 1096 laststridesize = tjsch->total_steps%tjsch->stride; 1097 if (!laststridesize) laststridesize = tjsch->stride; 1098 if (stack->solution_only && localstepnum == 0 && !tjsch->rctx2->reverseonestep) { 1099 ierr = ApplyRevolve(tjsch->stype,tjsch->rctx2,(tjsch->total_steps+tjsch->stride-1)/tjsch->stride,stridenum,stridenum,PETSC_TRUE,&tjsch->store_stride);CHKERRQ(ierr); 1100 } 1101 if (!stack->solution_only && localstepnum == 1 && !tjsch->rctx2->reverseonestep) { 1102 ierr = ApplyRevolve(tjsch->stype,tjsch->rctx2,(tjsch->total_steps+tjsch->stride-1)/tjsch->stride,stridenum,stridenum,PETSC_TRUE,&tjsch->store_stride);CHKERRQ(ierr); 1103 } 1104 if (tjsch->store_stride) { 1105 ierr = TopLevelStore(ts,tjsch,stepnum,localstepnum,laststridesize,&done);CHKERRQ(ierr); 1106 if (done) { 1107 revolve_reset(); 1108 revolve_create_offline(tjsch->stride,tjsch->max_cps_ram); 1109 rctx = tjsch->rctx; 1110 rctx->check = 0; 1111 rctx->capo = 0; 1112 rctx->fine = tjsch->stride; 1113 tjsch->rctx->reverseonestep = PETSC_FALSE; 1114 PetscFunctionReturn(0); 1115 } 1116 } 1117 if (stepnum < tjsch->total_steps-laststridesize) { 1118 if (tjsch->save_stack && !tjsch->store_stride && !tjsch->rctx2->reverseonestep) PetscFunctionReturn(0); 1119 if (!tjsch->save_stack && !tjsch->rctx2->reverseonestep) PetscFunctionReturn(0); 1120 } 1121 if (!stack->solution_only && localstepnum == 0 && stepnum != tjsch->total_steps && !tjsch->recompute) PetscFunctionReturn(0); 1122 ierr = ApplyRevolve(tjsch->stype,tjsch->rctx,tjsch->total_steps,stepnum,localstepnum,PETSC_FALSE,&store);CHKERRQ(ierr); 1123 if (store == 1) { 1124 if (localstepnum < stack->top) SETERRQ(tjsch->comm,PETSC_ERR_MEMC,"Illegal modification of a non-top stack element"); 1125 ierr = ElementCreate(ts,stack,&e,stepnum,time,X);CHKERRQ(ierr); 1126 ierr = StackPush(stack,e);CHKERRQ(ierr); 1127 } 1128 PetscFunctionReturn(0); 1129 } 1130 1131 #undef __FUNCT__ 1132 #define __FUNCT__ "GetTrajTLTR" 1133 static PetscErrorCode GetTrajTLTR(TS ts,TJScheduler *tjsch,PetscInt stepnum) 1134 { 1135 Stack *stack = &tjsch->stack; 1136 DiskStack *diskstack = &tjsch->diskstack; 1137 PetscInt i,whattodo,shift; 1138 PetscInt localstepnum,stridenum,restoredstridenum,laststridesize,store; 1139 PetscReal stepsize; 1140 StackElement e; 1141 PetscErrorCode ierr; 1142 1143 PetscFunctionBegin; 1144 localstepnum = stepnum%tjsch->stride; 1145 stridenum = stepnum/tjsch->stride; 1146 if (stepnum == tjsch->total_steps) { 1147 ierr = TSGetTimeStep(ts,&stepsize);CHKERRQ(ierr); 1148 ierr = TSSetTimeStep(ts,-stepsize);CHKERRQ(ierr); 1149 if ( tjsch->rctx->reverseonestep) tjsch->rctx->reverseonestep = PETSC_FALSE; 1150 PetscFunctionReturn(0); 1151 } 1152 laststridesize = tjsch->total_steps%tjsch->stride; 1153 if (!laststridesize) laststridesize = tjsch->stride; 1154 /* 1155 Last stride can be adjoined directly. All the other strides require that the stack in memory be ready before an adjoint step is taken (at the end of each stride). The following two cases need to be addressed differently: 1156 Case 1 (save_stack) 1157 Restore a disk checkpoint; update TS with the last element in the restored data; recompute to the current point. 1158 Case 2 (!save_stack) 1159 Restore a disk checkpoint; update TS with the restored point; recompute to the current point. 1160 */ 1161 if (localstepnum == 0 && stepnum <= tjsch->total_steps-laststridesize) { 1162 /* restore the top element in the stack for disk checkpoints */ 1163 restoredstridenum = diskstack->container[diskstack->top]; 1164 if (tjsch->rctx2->reverseonestep) tjsch->rctx2->reverseonestep = PETSC_FALSE; 1165 /* second-level revolve must be applied before current step, like the solution_only mode for single-level revolve */ 1166 if (!tjsch->save_stack) { /* start with restoring a checkpoint */ 1167 tjsch->rctx2->capo = stridenum; 1168 tjsch->rctx2->oldcapo = tjsch->rctx2->capo; 1169 shift = 0; 1170 whattodo = revolve2_action(&tjsch->rctx2->check,&tjsch->rctx2->capo,&tjsch->rctx2->fine,tjsch->rctx2->snaps_in,&tjsch->rctx2->info,&tjsch->rctx2->where); 1171 printwhattodo2(whattodo,tjsch->rctx2,shift); 1172 } else { /* 2 revolve actions: restore a checkpoint and then advance */ 1173 ierr = ApplyRevolve(tjsch->stype,tjsch->rctx2,(tjsch->total_steps+tjsch->stride-1)/tjsch->stride,stridenum,stridenum,PETSC_TRUE,&tjsch->store_stride);CHKERRQ(ierr); 1174 if (!tjsch->rctx2->reverseonestep && tjsch->rctx2->stepsleft > 0) { 1175 tjsch->rctx2->stepsleft--; 1176 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35m[Top Level] Skip the stride from %D to %D (already checkpointed)\033[0m\n",tjsch->rctx2->oldcapo,tjsch->rctx2->oldcapo+1); 1177 } 1178 } 1179 /* fill stack */ 1180 if (stack->solution_only) { 1181 if (tjsch->save_stack) { 1182 PetscPrintf(PETSC_COMM_WORLD,"\x1B[33mLoad stack from file\033[0m\n"); 1183 ierr = StackLoadAll(ts,stack,restoredstridenum);CHKERRQ(ierr); 1184 /* recompute one step ahead */ 1185 tjsch->recompute = PETSC_TRUE; 1186 tjsch->skip_trajectory = PETSC_TRUE; 1187 ierr = ReCompute(ts,tjsch,stridenum*tjsch->stride-1,stridenum*tjsch->stride);CHKERRQ(ierr); 1188 tjsch->skip_trajectory = PETSC_FALSE; 1189 if (restoredstridenum < stridenum) { 1190 revolve_reset(); 1191 revolve_create_offline(tjsch->stride,tjsch->max_cps_ram); 1192 tjsch->rctx->check = 0; 1193 tjsch->rctx->capo = 0; 1194 tjsch->rctx->fine = tjsch->stride; 1195 /* clear the stack */ 1196 if (stack->top > -1) { 1197 for (i=0;i<=stack->top;i++) { 1198 ierr = VecDestroy(&stack->container[i]->X);CHKERRQ(ierr); 1199 ierr = PetscFree(stack->container[i]);CHKERRQ(ierr); 1200 } 1201 stack->top = -1; 1202 } 1203 tjsch->recompute = PETSC_TRUE; 1204 ierr = ReCompute(ts,tjsch,restoredstridenum*tjsch->stride,stepnum);CHKERRQ(ierr); 1205 } else { /* stack ready, fast forward revolve status */ 1206 revolve_reset(); 1207 revolve_create_offline(tjsch->stride,tjsch->max_cps_ram); 1208 tjsch->rctx->check = 0; 1209 tjsch->rctx->capo = 0; 1210 tjsch->rctx->fine = tjsch->stride; 1211 whattodo = 0; 1212 while(whattodo!=3) { /* stupid revolve */ 1213 whattodo = revolve_action(&tjsch->rctx->check,&tjsch->rctx->capo,&tjsch->rctx->fine,tjsch->rctx->snaps_in,&tjsch->rctx->info,&tjsch->rctx->where); 1214 } 1215 } 1216 } else { 1217 PetscPrintf(PETSC_COMM_WORLD,"\x1B[33mLoad a single point from file\033[0m\n"); 1218 ierr = LoadSingle(ts,stack,restoredstridenum);CHKERRQ(ierr); 1219 revolve_reset(); 1220 revolve_create_offline(tjsch->stride,tjsch->max_cps_ram); 1221 tjsch->rctx->check = 0; 1222 tjsch->rctx->capo = 0; 1223 tjsch->rctx->fine = tjsch->stride; 1224 tjsch->recompute = PETSC_TRUE; 1225 ierr = ReCompute(ts,tjsch,(restoredstridenum-1)*tjsch->stride,stepnum);CHKERRQ(ierr); 1226 } 1227 } else { 1228 if (tjsch->save_stack) { 1229 PetscPrintf(PETSC_COMM_WORLD,"\x1B[33mLoad stack from file\033[0m\n"); 1230 ierr = StackLoadAll(ts,stack,restoredstridenum);CHKERRQ(ierr); 1231 if (restoredstridenum < stridenum) { 1232 /* reset revolve */ 1233 revolve_reset(); 1234 revolve_create_offline(tjsch->stride,tjsch->max_cps_ram); 1235 tjsch->rctx->check = 0; 1236 tjsch->rctx->capo = 0; 1237 tjsch->rctx->fine = tjsch->stride; 1238 /* clear the stack */ 1239 if (stack->top > -1) { 1240 for (i=0;i<=stack->top;i++) { 1241 ierr = VecDestroy(&stack->container[i]->X);CHKERRQ(ierr); 1242 ierr = VecDestroyVecs(stack->numY,&stack->container[i]->Y);CHKERRQ(ierr); 1243 ierr = PetscFree(stack->container[i]);CHKERRQ(ierr); 1244 } 1245 stack->top = -1; 1246 } 1247 tjsch->recompute = PETSC_TRUE; 1248 ierr = ReCompute(ts,tjsch,restoredstridenum*tjsch->stride,stepnum);CHKERRQ(ierr); 1249 } else { /* stack ready, fast forward revolve status */ 1250 revolve_reset(); 1251 revolve_create_offline(tjsch->stride,tjsch->max_cps_ram); 1252 tjsch->rctx->check = 0; 1253 tjsch->rctx->capo = 0; 1254 tjsch->rctx->fine = tjsch->stride; 1255 whattodo = 0; 1256 while(whattodo!=3) { /* stupid revolve */ 1257 whattodo = revolve_action(&tjsch->rctx->check,&tjsch->rctx->capo,&tjsch->rctx->fine,tjsch->rctx->snaps_in,&tjsch->rctx->info,&tjsch->rctx->where); 1258 } 1259 } 1260 } else { 1261 PetscPrintf(PETSC_COMM_WORLD,"\x1B[33mLoad a single point from file\033[0m\n"); 1262 ierr = LoadSingle(ts,stack,restoredstridenum);CHKERRQ(ierr); 1263 revolve_reset(); 1264 revolve_create_offline(tjsch->stride,tjsch->max_cps_ram); 1265 tjsch->rctx->check = 0; 1266 tjsch->rctx->capo = 0; 1267 tjsch->rctx->fine = tjsch->stride; 1268 /* push first element to stack */ 1269 if (tjsch->store_stride || tjsch->rctx2->reverseonestep) { 1270 shift = (restoredstridenum-1)*tjsch->stride-localstepnum; 1271 ierr = ApplyRevolve(tjsch->stype,tjsch->rctx,tjsch->total_steps,(restoredstridenum-1)*tjsch->stride+1,1,PETSC_FALSE,&store);CHKERRQ(ierr); 1272 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35mSkip the step from %D to %D (already checkpointed)\033[0m\n",(restoredstridenum-1)*tjsch->stride,(restoredstridenum-1)*tjsch->stride+1); 1273 ierr = ElementCreate(ts,stack,&e,(restoredstridenum-1)*tjsch->stride+1,ts->ptime,ts->vec_sol);CHKERRQ(ierr); 1274 ierr = StackPush(stack,e);CHKERRQ(ierr); 1275 } 1276 tjsch->recompute = PETSC_TRUE; 1277 ierr = ReCompute(ts,tjsch,(restoredstridenum-1)*tjsch->stride+1,stepnum);CHKERRQ(ierr); 1278 } 1279 } 1280 if (restoredstridenum == stridenum) diskstack->top--; 1281 PetscFunctionReturn(0); 1282 } 1283 1284 if (stack->solution_only) { 1285 /* restore a checkpoint */ 1286 ierr = StackTop(stack,&e);CHKERRQ(ierr); 1287 ierr = UpdateTS(ts,stack,e);CHKERRQ(ierr); 1288 /* start with restoring a checkpoint */ 1289 tjsch->rctx->capo = stepnum; 1290 tjsch->rctx->oldcapo = tjsch->rctx->capo; 1291 shift = stepnum-localstepnum; 1292 whattodo = revolve_action(&tjsch->rctx->check,&tjsch->rctx->capo,&tjsch->rctx->fine,tjsch->rctx->snaps_in,&tjsch->rctx->info,&tjsch->rctx->where); 1293 printwhattodo(whattodo,tjsch->rctx,shift); 1294 tjsch->recompute = PETSC_TRUE; 1295 ierr = ReCompute(ts,tjsch,e->stepnum,stepnum);CHKERRQ(ierr); 1296 if (e->stepnum+1 == stepnum) { 1297 ierr = StackPop(stack,&e);CHKERRQ(ierr); 1298 ierr = ElementDestroy(stack,e);CHKERRQ(ierr); 1299 } 1300 } else { 1301 /* restore a checkpoint */ 1302 ierr = StackTop(stack,&e);CHKERRQ(ierr); 1303 ierr = UpdateTS(ts,stack,e);CHKERRQ(ierr); 1304 /* 2 revolve actions: restore a checkpoint and then advance */ 1305 ierr = ApplyRevolve(tjsch->stype,tjsch->rctx,tjsch->total_steps,stepnum,localstepnum,PETSC_FALSE,&store);CHKERRQ(ierr); 1306 if (!tjsch->rctx->reverseonestep && tjsch->rctx->stepsleft > 0) { 1307 tjsch->rctx->stepsleft--; 1308 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35mSkip the step from %D to %D (already checkpointed)\033[0m\n",stepnum-localstepnum+tjsch->rctx->oldcapo,stepnum-localstepnum+tjsch->rctx->oldcapo+1); 1309 } 1310 if (e->stepnum < stepnum) { 1311 tjsch->recompute = PETSC_TRUE; 1312 ierr = ReCompute(ts,tjsch,e->stepnum,stepnum);CHKERRQ(ierr); 1313 } 1314 if (e->stepnum == stepnum) { 1315 ierr = StackPop(stack,&e);CHKERRQ(ierr); 1316 ierr = ElementDestroy(stack,e);CHKERRQ(ierr); 1317 } 1318 } 1319 if (tjsch->rctx->reverseonestep) tjsch->rctx->reverseonestep = PETSC_FALSE; 1320 PetscFunctionReturn(0); 1321 } 1322 1323 #undef __FUNCT__ 1324 #define __FUNCT__ "SetTrajRMS" 1325 static PetscErrorCode SetTrajRMS(TS ts,TJScheduler *tjsch,PetscInt stepnum,PetscReal time,Vec X) 1326 { 1327 Stack *stack = &tjsch->stack; 1328 PetscInt store; 1329 StackElement e; 1330 PetscErrorCode ierr; 1331 1332 PetscFunctionBegin; 1333 if (!stack->solution_only && stepnum == 0) PetscFunctionReturn(0); 1334 if (stack->solution_only && stepnum == tjsch->total_steps) PetscFunctionReturn(0); 1335 ierr = ApplyRevolve(tjsch->stype,tjsch->rctx,tjsch->total_steps,stepnum,stepnum,PETSC_FALSE,&store);CHKERRQ(ierr); 1336 if (store == 1){ 1337 if (stepnum < stack->top) SETERRQ(tjsch->comm,PETSC_ERR_MEMC,"Illegal modification of a non-top stack element"); 1338 ierr = ElementCreate(ts,stack,&e,stepnum,time,X);CHKERRQ(ierr); 1339 ierr = StackPush(stack,e);CHKERRQ(ierr); 1340 } else if (store == 2) { 1341 ierr = DumpSingle(ts,stack,tjsch->rctx->check+1);CHKERRQ(ierr); 1342 } 1343 PetscFunctionReturn(0); 1344 } 1345 1346 #undef __FUNCT__ 1347 #define __FUNCT__ "GetTrajRMS" 1348 static PetscErrorCode GetTrajRMS(TS ts,TJScheduler *tjsch,PetscInt stepnum) 1349 { 1350 Stack *stack = &tjsch->stack; 1351 PetscInt whattodo,shift; 1352 PetscInt restart; 1353 PetscBool ondisk; 1354 PetscReal stepsize; 1355 StackElement e; 1356 PetscErrorCode ierr; 1357 1358 PetscFunctionBegin; 1359 if (stepnum == 0 || stepnum == tjsch->total_steps) { 1360 ierr = TSGetTimeStep(ts,&stepsize);CHKERRQ(ierr); 1361 ierr = TSSetTimeStep(ts,-stepsize);CHKERRQ(ierr); 1362 if (tjsch->rctx->reverseonestep) tjsch->rctx->reverseonestep = PETSC_FALSE; 1363 PetscFunctionReturn(0); 1364 } 1365 tjsch->rctx->capo = stepnum; 1366 tjsch->rctx->oldcapo = tjsch->rctx->capo; 1367 shift = 0; 1368 whattodo = revolve_action(&tjsch->rctx->check,&tjsch->rctx->capo,&tjsch->rctx->fine,tjsch->rctx->snaps_in,&tjsch->rctx->info,&tjsch->rctx->where); /* whattodo=restore */ 1369 printwhattodo(whattodo,tjsch->rctx,shift); 1370 /* restore a checkpoint */ 1371 restart = tjsch->rctx->capo; 1372 if (!tjsch->rctx->where) { 1373 ondisk = PETSC_TRUE; 1374 ierr = LoadSingle(ts,stack,tjsch->rctx->check+1);CHKERRQ(ierr); 1375 ierr = TSSetTimeStep(ts,ts->ptime_prev-ts->ptime);CHKERRQ(ierr); 1376 } else { 1377 ondisk = PETSC_FALSE; 1378 ierr = StackTop(stack,&e);CHKERRQ(ierr); 1379 ierr = UpdateTS(ts,stack,e);CHKERRQ(ierr); 1380 } 1381 if (!stack->solution_only) { /* whattodo must be 5 or 8 */ 1382 /* ask Revolve what to do next */ 1383 tjsch->rctx->oldcapo = tjsch->rctx->capo; 1384 whattodo = revolve_action(&tjsch->rctx->check,&tjsch->rctx->capo,&tjsch->rctx->fine,tjsch->rctx->snaps_in,&tjsch->rctx->info,&tjsch->rctx->where); /* must return 1 or 3 or 4*/ 1385 printwhattodo(whattodo,tjsch->rctx,shift); 1386 if (whattodo == 3 || whattodo == 4) tjsch->rctx->reverseonestep = PETSC_TRUE; 1387 if (whattodo == 1) tjsch->rctx->stepsleft = tjsch->rctx->capo-tjsch->rctx->oldcapo; 1388 if (!tjsch->rctx->reverseonestep && tjsch->rctx->stepsleft > 0) { 1389 tjsch->rctx->stepsleft--; 1390 PetscPrintf(PETSC_COMM_WORLD,"\x1B[35mSkip the step from %D to %D (already checkpointed)\033[0m\n",tjsch->rctx->oldcapo,tjsch->rctx->oldcapo+1); 1391 } 1392 restart++; /* skip one step */ 1393 } 1394 if (stack->solution_only || (!stack->solution_only && restart < stepnum)) { 1395 tjsch->recompute = PETSC_TRUE; 1396 ierr = ReCompute(ts,tjsch,restart,stepnum);CHKERRQ(ierr); 1397 } 1398 if (!ondisk && ( (stack->solution_only && e->stepnum+1 == stepnum) || (!stack->solution_only && e->stepnum == stepnum) )) { 1399 ierr = StackPop(stack,&e);CHKERRQ(ierr); 1400 ierr = ElementDestroy(stack,e);CHKERRQ(ierr); 1401 } 1402 if (tjsch->rctx->reverseonestep) tjsch->rctx->reverseonestep = PETSC_FALSE; 1403 PetscFunctionReturn(0); 1404 } 1405 #endif 1406 1407 #undef __FUNCT__ 1408 #define __FUNCT__ "TSTrajectorySet_Memory" 1409 PetscErrorCode TSTrajectorySet_Memory(TSTrajectory tj,TS ts,PetscInt stepnum,PetscReal time,Vec X) 1410 { 1411 TJScheduler *tjsch = (TJScheduler*)tj->data; 1412 PetscErrorCode ierr; 1413 1414 PetscFunctionBegin; 1415 if (!tjsch->recompute) { /* use global stepnum in the forward sweep */ 1416 ierr = TSGetTotalSteps(ts,&stepnum);CHKERRQ(ierr); 1417 } 1418 /* for consistency */ 1419 if (!tjsch->recompute && stepnum == 0) ts->ptime_prev = ts->ptime-ts->time_step; 1420 switch (tjsch->stype) { 1421 case NONE: 1422 ierr = SetTrajN(ts,tjsch,stepnum,time,X);CHKERRQ(ierr); 1423 break; 1424 case TWO_LEVEL_NOREVOLVE: 1425 ierr = SetTrajTLNR(ts,tjsch,stepnum,time,X);CHKERRQ(ierr); 1426 break; 1427 #ifdef PETSC_HAVE_REVOLVE 1428 case TWO_LEVEL_REVOLVE: 1429 ierr = SetTrajTLR(ts,tjsch,stepnum,time,X);CHKERRQ(ierr); 1430 break; 1431 case TWO_LEVEL_TWO_REVOLVE: 1432 ierr = SetTrajTLTR(ts,tjsch,stepnum,time,X);CHKERRQ(ierr); 1433 break; 1434 case REVOLVE_OFFLINE: 1435 ierr = SetTrajROF(ts,tjsch,stepnum,time,X);CHKERRQ(ierr); 1436 break; 1437 case REVOLVE_ONLINE: 1438 ierr = SetTrajRON(ts,tjsch,stepnum,time,X);CHKERRQ(ierr); 1439 break; 1440 case REVOLVE_MULTISTAGE: 1441 ierr = SetTrajRMS(ts,tjsch,stepnum,time,X);CHKERRQ(ierr); 1442 break; 1443 #endif 1444 default: 1445 break; 1446 } 1447 PetscFunctionReturn(0); 1448 } 1449 1450 #undef __FUNCT__ 1451 #define __FUNCT__ "TSTrajectoryGet_Memory" 1452 PetscErrorCode TSTrajectoryGet_Memory(TSTrajectory tj,TS ts,PetscInt stepnum,PetscReal *t) 1453 { 1454 TJScheduler *tjsch = (TJScheduler*)tj->data; 1455 PetscErrorCode ierr; 1456 1457 PetscFunctionBegin; 1458 ierr = TSGetTotalSteps(ts,&stepnum);CHKERRQ(ierr); 1459 if (stepnum == 0) PetscFunctionReturn(0); 1460 switch (tjsch->stype) { 1461 case NONE: 1462 ierr = GetTrajN(ts,tjsch,stepnum);CHKERRQ(ierr); 1463 break; 1464 case TWO_LEVEL_NOREVOLVE: 1465 ierr = GetTrajTLNR(ts,tjsch,stepnum);CHKERRQ(ierr); 1466 break; 1467 #ifdef PETSC_HAVE_REVOLVE 1468 case TWO_LEVEL_REVOLVE: 1469 ierr = GetTrajTLR(ts,tjsch,stepnum);CHKERRQ(ierr); 1470 break; 1471 case TWO_LEVEL_TWO_REVOLVE: 1472 ierr = GetTrajTLTR(ts,tjsch,stepnum);CHKERRQ(ierr); 1473 break; 1474 case REVOLVE_OFFLINE: 1475 ierr = GetTrajROF(ts,tjsch,stepnum);CHKERRQ(ierr); 1476 break; 1477 case REVOLVE_ONLINE: 1478 ierr = GetTrajRON(ts,tjsch,stepnum);CHKERRQ(ierr); 1479 break; 1480 case REVOLVE_MULTISTAGE: 1481 ierr = GetTrajRMS(ts,tjsch,stepnum);CHKERRQ(ierr); 1482 break; 1483 #endif 1484 default: 1485 break; 1486 } 1487 PetscFunctionReturn(0); 1488 } 1489 1490 #undef __FUNCT__ 1491 #define __FUNCT__ "TSTrajectorySetStride_Memory" 1492 PetscErrorCode TSTrajectorySetStride_Memory(TSTrajectory tj,TS ts,PetscInt stride) 1493 { 1494 TJScheduler *tjsch = (TJScheduler*)tj->data; 1495 1496 PetscFunctionBegin; 1497 tjsch->stride = stride; 1498 PetscFunctionReturn(0); 1499 } 1500 1501 #undef __FUNCT__ 1502 #define __FUNCT__ "TSTrajectorySetMaxCpsRAM_Memory" 1503 PetscErrorCode TSTrajectorySetMaxCpsRAM_Memory(TSTrajectory tj,TS ts,PetscInt max_cps_ram) 1504 { 1505 TJScheduler *tjsch = (TJScheduler*)tj->data; 1506 1507 PetscFunctionBegin; 1508 tjsch->max_cps_ram = max_cps_ram; 1509 PetscFunctionReturn(0); 1510 } 1511 1512 #undef __FUNCT__ 1513 #define __FUNCT__ "TSTrajectorySetMaxCpsDisk_Memory" 1514 PetscErrorCode TSTrajectorySetMaxCpsDisk_Memory(TSTrajectory tj,TS ts,PetscInt max_cps_disk) 1515 { 1516 TJScheduler *tjsch = (TJScheduler*)tj->data; 1517 1518 PetscFunctionBegin; 1519 tjsch->max_cps_disk = max_cps_disk; 1520 PetscFunctionReturn(0); 1521 } 1522 1523 #ifdef PETSC_HAVE_REVOLVE 1524 #undef __FUNCT__ 1525 #define __FUNCT__ "TSTrajectorySetRevolveOnline" 1526 PetscErrorCode TSTrajectorySetRevolveOnline(TSTrajectory tj,PetscBool use_online) 1527 { 1528 TJScheduler *tjsch = (TJScheduler*)tj->data; 1529 1530 PetscFunctionBegin; 1531 tjsch->use_online = use_online; 1532 PetscFunctionReturn(0); 1533 } 1534 #endif 1535 1536 #undef __FUNCT__ 1537 #define __FUNCT__ "TSTrajectorySetSaveStack" 1538 PetscErrorCode TSTrajectorySetSaveStack(TSTrajectory tj,PetscBool save_stack) 1539 { 1540 TJScheduler *tjsch = (TJScheduler*)tj->data; 1541 1542 PetscFunctionBegin; 1543 tjsch->save_stack = save_stack; 1544 PetscFunctionReturn(0); 1545 } 1546 1547 #undef __FUNCT__ 1548 #define __FUNCT__ "TSTrajectorySetSolutionOnly" 1549 PetscErrorCode TSTrajectorySetSolutionOnly(TSTrajectory tj,PetscBool solution_only) 1550 { 1551 TJScheduler *tjsch = (TJScheduler*)tj->data; 1552 Stack *stack = &tjsch->stack; 1553 1554 PetscFunctionBegin; 1555 stack->solution_only = solution_only; 1556 PetscFunctionReturn(0); 1557 } 1558 1559 #undef __FUNCT__ 1560 #define __FUNCT__ "TSTrajectorySetFromOptions_Memory" 1561 PetscErrorCode TSTrajectorySetFromOptions_Memory(PetscOptions *PetscOptionsObject,TSTrajectory tj) 1562 { 1563 TJScheduler *tjsch = (TJScheduler*)tj->data; 1564 PetscErrorCode ierr; 1565 1566 PetscFunctionBegin; 1567 ierr = PetscOptionsHead(PetscOptionsObject,"Memory based TS trajectory options");CHKERRQ(ierr); 1568 { 1569 ierr = PetscOptionsInt("-tstrajectory_max_cps_ram","Maximum number of checkpoints in RAM","TSTrajectorySetMaxCpsRAM_Memory",tjsch->max_cps_ram,&tjsch->max_cps_ram,NULL);CHKERRQ(ierr); 1570 ierr = PetscOptionsInt("-tstrajectory_max_cps_disk","Maximum number of checkpoints on disk","TSTrajectorySetMaxCpsDisk_Memory",tjsch->max_cps_disk,&tjsch->max_cps_disk,NULL);CHKERRQ(ierr); 1571 ierr = PetscOptionsInt("-tstrajectory_stride","Stride to save checkpoints to file","TSTrajectorySetStride_Memory",tjsch->stride,&tjsch->stride,NULL);CHKERRQ(ierr); 1572 #ifdef PETSC_HAVE_REVOLVE 1573 ierr = PetscOptionsBool("-tstrajectory_revolve_online","Trick TS trajectory into using online mode of revolve","TSTrajectorySetRevolveOnline",tjsch->use_online,&tjsch->use_online,NULL);CHKERRQ(ierr); 1574 #endif 1575 ierr = PetscOptionsBool("-tstrajectory_save_stack","Save all stack to disk","TSTrajectorySetSaveStack",tjsch->save_stack,&tjsch->save_stack,NULL);CHKERRQ(ierr); 1576 ierr = PetscOptionsBool("-tstrajectory_solution_only","Checkpoint solution only","TSTrajectorySetSolutionOnly",tjsch->stack.solution_only,&tjsch->stack.solution_only,NULL);CHKERRQ(ierr); 1577 } 1578 ierr = PetscOptionsTail();CHKERRQ(ierr); 1579 PetscFunctionReturn(0); 1580 } 1581 1582 #undef __FUNCT__ 1583 #define __FUNCT__ "TSTrajectorySetUp_Memory" 1584 PetscErrorCode TSTrajectorySetUp_Memory(TSTrajectory tj,TS ts) 1585 { 1586 TJScheduler *tjsch = (TJScheduler*)tj->data; 1587 Stack *stack = &tjsch->stack; 1588 DiskStack *diskstack = &tjsch->diskstack; 1589 #ifdef PETSC_HAVE_REVOLVE 1590 RevolveCTX *rctx,*rctx2; 1591 #endif 1592 PetscInt numY; 1593 PetscBool flg; 1594 PetscErrorCode ierr; 1595 1596 PetscFunctionBegin; 1597 PetscStrcmp(((PetscObject)ts->adapt)->type_name,TSADAPTNONE,&flg); 1598 if (flg) { /* fixed time step */ 1599 tjsch->total_steps = PetscMin(ts->max_steps,(PetscInt)(ceil(ts->max_time/ts->time_step))); 1600 } 1601 if (tjsch->max_cps_ram > 1) stack->stacksize = tjsch->max_cps_ram; 1602 if (tjsch->stride > 1) { /* two level mode works for both fixed time step and adaptive time step */ 1603 if (tjsch->max_cps_disk <= 1 && tjsch->max_cps_ram > 1 && tjsch->max_cps_ram < tjsch->stride-1) { /* use revolve_offline for each stride */ 1604 tjsch->stype = TWO_LEVEL_REVOLVE; 1605 } 1606 if (tjsch->max_cps_disk > 1 && tjsch->max_cps_ram > 1 && tjsch->max_cps_ram <= tjsch->stride-1) { /* use revolve_offline for each stride */ 1607 tjsch->stype = TWO_LEVEL_TWO_REVOLVE; 1608 diskstack->stacksize = tjsch->max_cps_disk; 1609 } 1610 if (tjsch->max_cps_disk <= 1 && (tjsch->max_cps_ram >= tjsch->stride || tjsch->max_cps_ram == -1)) { /* checkpoint all for each stride */ 1611 tjsch->stype = TWO_LEVEL_NOREVOLVE; /* can also be handled by TWO_LEVEL_REVOLVE */ 1612 stack->stacksize = tjsch->stride-1; /* need tjsch->stride-1 at most */ 1613 } 1614 } else { 1615 if (flg) { /* fixed time step */ 1616 if (tjsch->max_cps_ram >= tjsch->total_steps-1 || tjsch->max_cps_ram < 1) { /* checkpoint all */ 1617 tjsch->stype = NONE; 1618 stack->stacksize = stack->solution_only ? tjsch->total_steps : tjsch->total_steps-1; 1619 } else { 1620 if (tjsch->max_cps_disk > 1) { /* disk can be used */ 1621 tjsch->stype = REVOLVE_MULTISTAGE; 1622 } else { /* memory only */ 1623 tjsch->stype = REVOLVE_OFFLINE; 1624 } 1625 } 1626 } else { /* adaptive time step */ 1627 tjsch->stype = REVOLVE_ONLINE; 1628 } 1629 #ifdef PETSC_HAVE_REVOLVE 1630 if (tjsch->use_online) { /* trick into online */ 1631 tjsch->stype = REVOLVE_ONLINE; 1632 stack->stacksize = tjsch->max_cps_ram; 1633 } 1634 #endif 1635 } 1636 1637 if (tjsch->stype > TWO_LEVEL_NOREVOLVE) { 1638 #ifndef PETSC_HAVE_REVOLVE 1639 SETERRQ(tjsch->comm,PETSC_ERR_SUP,"revolve is needed when there is not enough memory to checkpoint all time steps according to the user's settings, please reconfigure with the additional option --download-revolve."); 1640 #else 1641 if (tjsch->stype == TWO_LEVEL_REVOLVE) revolve_create_offline(tjsch->stride,tjsch->max_cps_ram); 1642 else if (tjsch->stype == TWO_LEVEL_TWO_REVOLVE) { 1643 revolve_create_offline(tjsch->stride,tjsch->max_cps_ram); 1644 revolve2_create_offline((tjsch->total_steps+tjsch->stride-1)/tjsch->stride,tjsch->max_cps_disk); 1645 ierr = PetscCalloc1(1,&rctx2);CHKERRQ(ierr); 1646 rctx2->snaps_in = tjsch->max_cps_disk; 1647 rctx2->reverseonestep = PETSC_FALSE; 1648 rctx2->check = 0; 1649 rctx2->oldcapo = 0; 1650 rctx2->capo = 0; 1651 rctx2->info = 2; 1652 rctx2->fine = (tjsch->total_steps+tjsch->stride-1)/tjsch->stride; 1653 tjsch->rctx2 = rctx2; 1654 diskstack->top = -1; 1655 ierr = PetscMalloc1(diskstack->stacksize*sizeof(PetscInt),&diskstack->container);CHKERRQ(ierr); 1656 } else if (tjsch->stype == REVOLVE_OFFLINE) revolve_create_offline(tjsch->total_steps,tjsch->max_cps_ram); 1657 else if (tjsch->stype == REVOLVE_ONLINE) revolve_create_online(tjsch->max_cps_ram); 1658 else if (tjsch->stype == REVOLVE_MULTISTAGE) revolve_create_multistage(tjsch->total_steps,tjsch->max_cps_ram+tjsch->max_cps_disk,tjsch->max_cps_ram); 1659 1660 ierr = PetscCalloc1(1,&rctx);CHKERRQ(ierr); 1661 rctx->snaps_in = tjsch->max_cps_ram; /* for theta methods snaps_in=2*max_cps_ram */ 1662 rctx->reverseonestep = PETSC_FALSE; 1663 rctx->check = 0; 1664 rctx->oldcapo = 0; 1665 rctx->capo = 0; 1666 rctx->info = 2; 1667 rctx->fine = (tjsch->stride > 1) ? tjsch->stride : tjsch->total_steps; 1668 tjsch->rctx = rctx; 1669 if (tjsch->stype == REVOLVE_ONLINE) rctx->fine = -1; 1670 #endif 1671 } 1672 1673 tjsch->recompute = PETSC_FALSE; 1674 tjsch->comm = PetscObjectComm((PetscObject)ts); 1675 ierr = TSGetStages(ts,&numY,PETSC_IGNORE);CHKERRQ(ierr); 1676 ierr = StackCreate(stack,stack->stacksize,numY);CHKERRQ(ierr); 1677 PetscFunctionReturn(0); 1678 } 1679 1680 #undef __FUNCT__ 1681 #define __FUNCT__ "TSTrajectoryDestroy_Memory" 1682 PETSC_EXTERN PetscErrorCode TSTrajectoryDestroy_Memory(TSTrajectory tj) 1683 { 1684 TJScheduler *tjsch = (TJScheduler*)tj->data; 1685 PetscErrorCode ierr; 1686 1687 PetscFunctionBegin; 1688 if (tjsch->stype > TWO_LEVEL_NOREVOLVE) { 1689 #ifdef PETSC_HAVE_REVOLVE 1690 revolve_reset(); 1691 if (tjsch->stype == TWO_LEVEL_TWO_REVOLVE) { 1692 revolve2_reset(); 1693 ierr = PetscFree(tjsch->diskstack.container);CHKERRQ(ierr); 1694 } 1695 #endif 1696 } 1697 ierr = StackDestroy(&tjsch->stack);CHKERRQ(ierr); 1698 #ifdef PETSC_HAVE_REVOLVE 1699 if (tjsch->stype > TWO_LEVEL_NOREVOLVE) { 1700 ierr = PetscFree(tjsch->rctx);CHKERRQ(ierr); 1701 ierr = PetscFree(tjsch->rctx2);CHKERRQ(ierr); 1702 } 1703 #endif 1704 ierr = PetscFree(tjsch);CHKERRQ(ierr); 1705 PetscFunctionReturn(0); 1706 } 1707 1708 /*MC 1709 TSTRAJECTORYMEMORY - Stores each solution of the ODE/ADE in memory 1710 1711 Level: intermediate 1712 1713 .seealso: TSTrajectoryCreate(), TS, TSTrajectorySetType() 1714 1715 M*/ 1716 #undef __FUNCT__ 1717 #define __FUNCT__ "TSTrajectoryCreate_Memory" 1718 PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Memory(TSTrajectory tj,TS ts) 1719 { 1720 TJScheduler *tjsch; 1721 PetscErrorCode ierr; 1722 1723 PetscFunctionBegin; 1724 tj->ops->set = TSTrajectorySet_Memory; 1725 tj->ops->get = TSTrajectoryGet_Memory; 1726 tj->ops->setup = TSTrajectorySetUp_Memory; 1727 tj->ops->destroy = TSTrajectoryDestroy_Memory; 1728 tj->ops->setfromoptions = TSTrajectorySetFromOptions_Memory; 1729 1730 ierr = PetscCalloc1(1,&tjsch);CHKERRQ(ierr); 1731 tjsch->stype = NONE; 1732 tjsch->max_cps_ram = -1; /* -1 indicates that it is not set */ 1733 tjsch->max_cps_disk = -1; /* -1 indicates that it is not set */ 1734 tjsch->stride = 0; /* if not zero, two-level checkpointing will be used */ 1735 #ifdef PETSC_HAVE_REVOLVE 1736 tjsch->use_online = PETSC_FALSE; 1737 #endif 1738 tjsch->save_stack = PETSC_TRUE; 1739 1740 tjsch->stack.solution_only = PETSC_TRUE; 1741 1742 tj->data = tjsch; 1743 1744 PetscFunctionReturn(0); 1745 } 1746