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