1 #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 2 #include <petscdm.h> 3 #include <petscds.h> 4 #include <petscdmswarm.h> 5 #include <petscdraw.h> 6 7 /*@C 8 TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet() 9 10 Collective on TS 11 12 Input Parameters: 13 + ts - time stepping context obtained from TSCreate() 14 . step - step number that has just completed 15 . ptime - model time of the state 16 - u - state at the current model time 17 18 Notes: 19 TSMonitor() is typically used automatically within the time stepping implementations. 20 Users would almost never call this routine directly. 21 22 A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions 23 24 Level: developer 25 26 @*/ 27 PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u) 28 { 29 DM dm; 30 PetscInt i,n = ts->numbermonitors; 31 32 PetscFunctionBegin; 33 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 34 PetscValidHeaderSpecific(u,VEC_CLASSID,4); 35 36 CHKERRQ(TSGetDM(ts,&dm)); 37 CHKERRQ(DMSetOutputSequenceNumber(dm,step,ptime)); 38 39 CHKERRQ(VecLockReadPush(u)); 40 for (i=0; i<n; i++) { 41 CHKERRQ((*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i])); 42 } 43 CHKERRQ(VecLockReadPop(u)); 44 PetscFunctionReturn(0); 45 } 46 47 /*@C 48 TSMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 49 50 Collective on TS 51 52 Input Parameters: 53 + ts - TS object you wish to monitor 54 . name - the monitor type one is seeking 55 . help - message indicating what monitoring is done 56 . manual - manual page for the monitor 57 . monitor - the monitor function 58 - monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the TS or PetscViewer objects 59 60 Level: developer 61 62 .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 63 PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 64 PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 65 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 66 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 67 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 68 PetscOptionsFList(), PetscOptionsEList() 69 @*/ 70 PetscErrorCode TSMonitorSetFromOptions(TS ts,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(TS,PetscViewerAndFormat*)) 71 { 72 PetscViewer viewer; 73 PetscViewerFormat format; 74 PetscBool flg; 75 76 PetscFunctionBegin; 77 CHKERRQ(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts),((PetscObject) ts)->options,((PetscObject)ts)->prefix,name,&viewer,&format,&flg)); 78 if (flg) { 79 PetscViewerAndFormat *vf; 80 CHKERRQ(PetscViewerAndFormatCreate(viewer,format,&vf)); 81 CHKERRQ(PetscObjectDereference((PetscObject)viewer)); 82 if (monitorsetup) { 83 CHKERRQ((*monitorsetup)(ts,vf)); 84 } 85 CHKERRQ(TSMonitorSet(ts,(PetscErrorCode (*)(TS,PetscInt,PetscReal,Vec,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy)); 86 } 87 PetscFunctionReturn(0); 88 } 89 90 /*@C 91 TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 92 timestep to display the iteration's progress. 93 94 Logically Collective on TS 95 96 Input Parameters: 97 + ts - the TS context obtained from TSCreate() 98 . monitor - monitoring routine 99 . mctx - [optional] user-defined context for private data for the 100 monitor routine (use NULL if no context is desired) 101 - monitordestroy - [optional] routine that frees monitor context 102 (may be NULL) 103 104 Calling sequence of monitor: 105 $ PetscErrorCode monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx) 106 107 + ts - the TS context 108 . steps - iteration number (after the final time step the monitor routine may be called with a step of -1, this indicates the solution has been interpolated to this time) 109 . time - current time 110 . u - current iterate 111 - mctx - [optional] monitoring context 112 113 Notes: 114 This routine adds an additional monitor to the list of monitors that 115 already has been loaded. 116 117 Fortran Notes: 118 Only a single monitor function can be set for each TS object 119 120 Level: intermediate 121 122 .seealso: TSMonitorDefault(), TSMonitorCancel() 123 @*/ 124 PetscErrorCode TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**)) 125 { 126 PetscInt i; 127 PetscBool identical; 128 129 PetscFunctionBegin; 130 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 131 for (i=0; i<ts->numbermonitors;i++) { 132 CHKERRQ(PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical)); 133 if (identical) PetscFunctionReturn(0); 134 } 135 PetscCheck(ts->numbermonitors < MAXTSMONITORS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 136 ts->monitor[ts->numbermonitors] = monitor; 137 ts->monitordestroy[ts->numbermonitors] = mdestroy; 138 ts->monitorcontext[ts->numbermonitors++] = (void*)mctx; 139 PetscFunctionReturn(0); 140 } 141 142 /*@C 143 TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 144 145 Logically Collective on TS 146 147 Input Parameters: 148 . ts - the TS context obtained from TSCreate() 149 150 Notes: 151 There is no way to remove a single, specific monitor. 152 153 Level: intermediate 154 155 .seealso: TSMonitorDefault(), TSMonitorSet() 156 @*/ 157 PetscErrorCode TSMonitorCancel(TS ts) 158 { 159 PetscInt i; 160 161 PetscFunctionBegin; 162 PetscValidHeaderSpecific(ts,TS_CLASSID,1); 163 for (i=0; i<ts->numbermonitors; i++) { 164 if (ts->monitordestroy[i]) { 165 CHKERRQ((*ts->monitordestroy[i])(&ts->monitorcontext[i])); 166 } 167 } 168 ts->numbermonitors = 0; 169 PetscFunctionReturn(0); 170 } 171 172 /*@C 173 TSMonitorDefault - The Default monitor, prints the timestep and time for each step 174 175 Level: intermediate 176 177 .seealso: TSMonitorSet() 178 @*/ 179 PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf) 180 { 181 PetscViewer viewer = vf->viewer; 182 PetscBool iascii,ibinary; 183 184 PetscFunctionBegin; 185 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,5); 186 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 187 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary)); 188 CHKERRQ(PetscViewerPushFormat(viewer,vf->format)); 189 if (iascii) { 190 CHKERRQ(PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel)); 191 if (step == -1) { /* this indicates it is an interpolated solution */ 192 CHKERRQ(PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %D and %D\n",(double)ptime,ts->steps-1,ts->steps)); 193 } else { 194 CHKERRQ(PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n")); 195 } 196 CHKERRQ(PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel)); 197 } else if (ibinary) { 198 PetscMPIInt rank; 199 CHKERRMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank)); 200 if (!rank) { 201 PetscBool skipHeader; 202 PetscInt classid = REAL_FILE_CLASSID; 203 204 CHKERRQ(PetscViewerBinaryGetSkipHeader(viewer,&skipHeader)); 205 if (!skipHeader) { 206 CHKERRQ(PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT)); 207 } 208 CHKERRQ(PetscRealView(1,&ptime,viewer)); 209 } else { 210 CHKERRQ(PetscRealView(0,&ptime,viewer)); 211 } 212 } 213 CHKERRQ(PetscViewerPopFormat(viewer)); 214 PetscFunctionReturn(0); 215 } 216 217 /*@C 218 TSMonitorExtreme - Prints the extreme values of the solution at each timestep 219 220 Level: intermediate 221 222 .seealso: TSMonitorSet() 223 @*/ 224 PetscErrorCode TSMonitorExtreme(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf) 225 { 226 PetscViewer viewer = vf->viewer; 227 PetscBool iascii; 228 PetscReal max,min; 229 230 PetscFunctionBegin; 231 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,5); 232 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 233 CHKERRQ(PetscViewerPushFormat(viewer,vf->format)); 234 if (iascii) { 235 CHKERRQ(VecMax(v,NULL,&max)); 236 CHKERRQ(VecMin(v,NULL,&min)); 237 CHKERRQ(PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel)); 238 CHKERRQ(PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s max %g min %g\n",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)" : "",(double)max,(double)min)); 239 CHKERRQ(PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel)); 240 } 241 CHKERRQ(PetscViewerPopFormat(viewer)); 242 PetscFunctionReturn(0); 243 } 244 245 /*@C 246 TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with 247 TS to monitor the solution process graphically in various ways 248 249 Collective on TS 250 251 Input Parameters: 252 + host - the X display to open, or null for the local machine 253 . label - the title to put in the title bar 254 . x, y - the screen coordinates of the upper left coordinate of the window 255 . m, n - the screen width and height in pixels 256 - howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time 257 258 Output Parameter: 259 . ctx - the context 260 261 Options Database Key: 262 + -ts_monitor_lg_timestep - automatically sets line graph monitor 263 + -ts_monitor_lg_timestep_log - automatically sets line graph monitor 264 . -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables()) 265 . -ts_monitor_lg_error - monitor the error 266 . -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep 267 . -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep 268 - -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true 269 270 Notes: 271 Use TSMonitorLGCtxDestroy() to destroy. 272 273 One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform() 274 275 Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the 276 first argument (if that TS object does not have a TSMonitorLGCtx associated with it the function call is ignored) and the second takes a TSMonitorLGCtx object 277 as the first argument. 278 279 One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames() 280 281 Level: intermediate 282 283 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(), 284 TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 285 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 286 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 287 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 288 289 @*/ 290 PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx) 291 { 292 PetscDraw draw; 293 294 PetscFunctionBegin; 295 CHKERRQ(PetscNew(ctx)); 296 CHKERRQ(PetscDrawCreate(comm,host,label,x,y,m,n,&draw)); 297 CHKERRQ(PetscDrawSetFromOptions(draw)); 298 CHKERRQ(PetscDrawLGCreate(draw,1,&(*ctx)->lg)); 299 CHKERRQ(PetscDrawLGSetFromOptions((*ctx)->lg)); 300 CHKERRQ(PetscDrawDestroy(&draw)); 301 (*ctx)->howoften = howoften; 302 PetscFunctionReturn(0); 303 } 304 305 PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx) 306 { 307 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 308 PetscReal x = ptime,y; 309 310 PetscFunctionBegin; 311 if (step < 0) PetscFunctionReturn(0); /* -1 indicates an interpolated solution */ 312 if (!step) { 313 PetscDrawAxis axis; 314 const char *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step"; 315 CHKERRQ(PetscDrawLGGetAxis(ctx->lg,&axis)); 316 CHKERRQ(PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time",ylabel)); 317 CHKERRQ(PetscDrawLGReset(ctx->lg)); 318 } 319 CHKERRQ(TSGetTimeStep(ts,&y)); 320 if (ctx->semilogy) y = PetscLog10Real(y); 321 CHKERRQ(PetscDrawLGAddPoint(ctx->lg,&x,&y)); 322 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 323 CHKERRQ(PetscDrawLGDraw(ctx->lg)); 324 CHKERRQ(PetscDrawLGSave(ctx->lg)); 325 } 326 PetscFunctionReturn(0); 327 } 328 329 /*@C 330 TSMonitorLGCtxDestroy - Destroys a line graph context that was created 331 with TSMonitorLGCtxCreate(). 332 333 Collective on TSMonitorLGCtx 334 335 Input Parameter: 336 . ctx - the monitor context 337 338 Level: intermediate 339 340 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep(); 341 @*/ 342 PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx) 343 { 344 PetscFunctionBegin; 345 if ((*ctx)->transformdestroy) { 346 CHKERRQ(((*ctx)->transformdestroy)((*ctx)->transformctx)); 347 } 348 CHKERRQ(PetscDrawLGDestroy(&(*ctx)->lg)); 349 CHKERRQ(PetscStrArrayDestroy(&(*ctx)->names)); 350 CHKERRQ(PetscStrArrayDestroy(&(*ctx)->displaynames)); 351 CHKERRQ(PetscFree((*ctx)->displayvariables)); 352 CHKERRQ(PetscFree((*ctx)->displayvalues)); 353 CHKERRQ(PetscFree(*ctx)); 354 PetscFunctionReturn(0); 355 } 356 357 /* Creates a TS Monitor SPCtx for use with DMSwarm particle visualizations */ 358 PetscErrorCode TSMonitorSPCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,PetscInt retain,PetscBool phase,TSMonitorSPCtx *ctx) 359 { 360 PetscDraw draw; 361 362 PetscFunctionBegin; 363 CHKERRQ(PetscNew(ctx)); 364 CHKERRQ(PetscDrawCreate(comm,host,label,x,y,m,n,&draw)); 365 CHKERRQ(PetscDrawSetFromOptions(draw)); 366 CHKERRQ(PetscDrawSPCreate(draw,1,&(*ctx)->sp)); 367 CHKERRQ(PetscDrawDestroy(&draw)); 368 (*ctx)->howoften = howoften; 369 (*ctx)->retain = retain; 370 (*ctx)->phase = phase; 371 PetscFunctionReturn(0); 372 } 373 374 /* 375 Destroys a TSMonitorSPCtx that was created with TSMonitorSPCtxCreate 376 */ 377 PetscErrorCode TSMonitorSPCtxDestroy(TSMonitorSPCtx *ctx) 378 { 379 PetscFunctionBegin; 380 381 CHKERRQ(PetscDrawSPDestroy(&(*ctx)->sp)); 382 CHKERRQ(PetscFree(*ctx)); 383 384 PetscFunctionReturn(0); 385 386 } 387 388 /*@C 389 TSMonitorDrawSolution - Monitors progress of the TS solvers by calling 390 VecView() for the solution at each timestep 391 392 Collective on TS 393 394 Input Parameters: 395 + ts - the TS context 396 . step - current time-step 397 . ptime - current time 398 - dummy - either a viewer or NULL 399 400 Options Database: 401 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 402 403 Notes: 404 the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial 405 will look bad 406 407 Level: intermediate 408 409 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 410 @*/ 411 PetscErrorCode TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 412 { 413 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 414 PetscDraw draw; 415 416 PetscFunctionBegin; 417 if (!step && ictx->showinitial) { 418 if (!ictx->initialsolution) { 419 CHKERRQ(VecDuplicate(u,&ictx->initialsolution)); 420 } 421 CHKERRQ(VecCopy(u,ictx->initialsolution)); 422 } 423 if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 424 425 if (ictx->showinitial) { 426 PetscReal pause; 427 CHKERRQ(PetscViewerDrawGetPause(ictx->viewer,&pause)); 428 CHKERRQ(PetscViewerDrawSetPause(ictx->viewer,0.0)); 429 CHKERRQ(VecView(ictx->initialsolution,ictx->viewer)); 430 CHKERRQ(PetscViewerDrawSetPause(ictx->viewer,pause)); 431 CHKERRQ(PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE)); 432 } 433 CHKERRQ(VecView(u,ictx->viewer)); 434 if (ictx->showtimestepandtime) { 435 PetscReal xl,yl,xr,yr,h; 436 char time[32]; 437 438 CHKERRQ(PetscViewerDrawGetDraw(ictx->viewer,0,&draw)); 439 CHKERRQ(PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime)); 440 CHKERRQ(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr)); 441 h = yl + .95*(yr - yl); 442 CHKERRQ(PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time)); 443 CHKERRQ(PetscDrawFlush(draw)); 444 } 445 446 if (ictx->showinitial) { 447 CHKERRQ(PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE)); 448 } 449 PetscFunctionReturn(0); 450 } 451 452 /*@C 453 TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram 454 455 Collective on TS 456 457 Input Parameters: 458 + ts - the TS context 459 . step - current time-step 460 . ptime - current time 461 - dummy - either a viewer or NULL 462 463 Level: intermediate 464 465 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 466 @*/ 467 PetscErrorCode TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 468 { 469 TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 470 PetscDraw draw; 471 PetscDrawAxis axis; 472 PetscInt n; 473 PetscMPIInt size; 474 PetscReal U0,U1,xl,yl,xr,yr,h; 475 char time[32]; 476 const PetscScalar *U; 477 PetscErrorCode ierr; 478 479 PetscFunctionBegin; 480 CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size)); 481 PetscCheck(size == 1,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs"); 482 CHKERRQ(VecGetSize(u,&n)); 483 PetscCheck(n == 2,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns"); 484 485 CHKERRQ(PetscViewerDrawGetDraw(ictx->viewer,0,&draw)); 486 CHKERRQ(PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis)); 487 CHKERRQ(PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr)); 488 if (!step) { 489 CHKERRQ(PetscDrawClear(draw)); 490 CHKERRQ(PetscDrawAxisDraw(axis)); 491 } 492 493 CHKERRQ(VecGetArrayRead(u,&U)); 494 U0 = PetscRealPart(U[0]); 495 U1 = PetscRealPart(U[1]); 496 CHKERRQ(VecRestoreArrayRead(u,&U)); 497 if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(0); 498 499 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 500 CHKERRQ(PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK)); 501 if (ictx->showtimestepandtime) { 502 CHKERRQ(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr)); 503 CHKERRQ(PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime)); 504 h = yl + .95*(yr - yl); 505 CHKERRQ(PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time)); 506 } 507 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 508 CHKERRQ(PetscDrawFlush(draw)); 509 CHKERRQ(PetscDrawPause(draw)); 510 CHKERRQ(PetscDrawSave(draw)); 511 PetscFunctionReturn(0); 512 } 513 514 /*@C 515 TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution() 516 517 Collective on TS 518 519 Input Parameters: 520 . ctx - the monitor context 521 522 Level: intermediate 523 524 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError() 525 @*/ 526 PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) 527 { 528 PetscFunctionBegin; 529 CHKERRQ(PetscViewerDestroy(&(*ictx)->viewer)); 530 CHKERRQ(VecDestroy(&(*ictx)->initialsolution)); 531 CHKERRQ(PetscFree(*ictx)); 532 PetscFunctionReturn(0); 533 } 534 535 /*@C 536 TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx 537 538 Collective on TS 539 540 Input Parameter: 541 . ts - time-step context 542 543 Output Patameter: 544 . ctx - the monitor context 545 546 Options Database: 547 . -ts_monitor_draw_solution_initial - show initial solution as well as current solution 548 549 Level: intermediate 550 551 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx() 552 @*/ 553 PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx) 554 { 555 PetscFunctionBegin; 556 CHKERRQ(PetscNew(ctx)); 557 CHKERRQ(PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer)); 558 CHKERRQ(PetscViewerSetFromOptions((*ctx)->viewer)); 559 560 (*ctx)->howoften = howoften; 561 (*ctx)->showinitial = PETSC_FALSE; 562 CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL)); 563 564 (*ctx)->showtimestepandtime = PETSC_FALSE; 565 CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL)); 566 PetscFunctionReturn(0); 567 } 568 569 /*@C 570 TSMonitorDrawSolutionFunction - Monitors progress of the TS solvers by calling 571 VecView() for the solution provided by TSSetSolutionFunction() at each timestep 572 573 Collective on TS 574 575 Input Parameters: 576 + ts - the TS context 577 . step - current time-step 578 . ptime - current time 579 - dummy - either a viewer or NULL 580 581 Options Database: 582 . -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 583 584 Level: intermediate 585 586 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 587 @*/ 588 PetscErrorCode TSMonitorDrawSolutionFunction(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 589 { 590 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 591 PetscViewer viewer = ctx->viewer; 592 Vec work; 593 594 PetscFunctionBegin; 595 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 596 CHKERRQ(VecDuplicate(u,&work)); 597 CHKERRQ(TSComputeSolutionFunction(ts,ptime,work)); 598 CHKERRQ(VecView(work,viewer)); 599 CHKERRQ(VecDestroy(&work)); 600 PetscFunctionReturn(0); 601 } 602 603 /*@C 604 TSMonitorDrawError - Monitors progress of the TS solvers by calling 605 VecView() for the error at each timestep 606 607 Collective on TS 608 609 Input Parameters: 610 + ts - the TS context 611 . step - current time-step 612 . ptime - current time 613 - dummy - either a viewer or NULL 614 615 Options Database: 616 . -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction() 617 618 Level: intermediate 619 620 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 621 @*/ 622 PetscErrorCode TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 623 { 624 TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 625 PetscViewer viewer = ctx->viewer; 626 Vec work; 627 628 PetscFunctionBegin; 629 if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(0); 630 CHKERRQ(VecDuplicate(u,&work)); 631 CHKERRQ(TSComputeSolutionFunction(ts,ptime,work)); 632 CHKERRQ(VecAXPY(work,-1.0,u)); 633 CHKERRQ(VecView(work,viewer)); 634 CHKERRQ(VecDestroy(&work)); 635 PetscFunctionReturn(0); 636 } 637 638 /*@C 639 TSMonitorSolution - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file or a PetscDraw object 640 641 Collective on TS 642 643 Input Parameters: 644 + ts - the TS context 645 . step - current time-step 646 . ptime - current time 647 . u - current state 648 - vf - viewer and its format 649 650 Level: intermediate 651 652 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 653 @*/ 654 PetscErrorCode TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 655 { 656 PetscFunctionBegin; 657 CHKERRQ(PetscViewerPushFormat(vf->viewer,vf->format)); 658 CHKERRQ(VecView(u,vf->viewer)); 659 CHKERRQ(PetscViewerPopFormat(vf->viewer)); 660 PetscFunctionReturn(0); 661 } 662 663 /*@C 664 TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep. 665 666 Collective on TS 667 668 Input Parameters: 669 + ts - the TS context 670 . step - current time-step 671 . ptime - current time 672 . u - current state 673 - filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 674 675 Level: intermediate 676 677 Notes: 678 The VTK format does not allow writing multiple time steps in the same file, therefore a different file will be written for each time step. 679 These are named according to the file name template. 680 681 This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy(). 682 683 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView() 684 @*/ 685 PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate) 686 { 687 char filename[PETSC_MAX_PATH_LEN]; 688 PetscViewer viewer; 689 690 PetscFunctionBegin; 691 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 692 CHKERRQ(PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step)); 693 CHKERRQ(PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer)); 694 CHKERRQ(VecView(u,viewer)); 695 CHKERRQ(PetscViewerDestroy(&viewer)); 696 PetscFunctionReturn(0); 697 } 698 699 /*@C 700 TSMonitorSolutionVTKDestroy - Destroy context for monitoring 701 702 Collective on TS 703 704 Input Parameters: 705 . filenametemplate - string containing a format specifier for the integer time step (e.g. %03D) 706 707 Level: intermediate 708 709 Note: 710 This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK(). 711 712 .seealso: TSMonitorSet(), TSMonitorSolutionVTK() 713 @*/ 714 PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 715 { 716 PetscFunctionBegin; 717 CHKERRQ(PetscFree(*(char**)filenametemplate)); 718 PetscFunctionReturn(0); 719 } 720 721 /*@C 722 TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector 723 in a time based line graph 724 725 Collective on TS 726 727 Input Parameters: 728 + ts - the TS context 729 . step - current time-step 730 . ptime - current time 731 . u - current solution 732 - dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate() 733 734 Options Database: 735 . -ts_monitor_lg_solution_variables - enable monitor of lg solution variables 736 737 Level: intermediate 738 739 Notes: 740 Each process in a parallel run displays its component solutions in a separate window 741 742 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(), 743 TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(), 744 TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(), 745 TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop() 746 @*/ 747 PetscErrorCode TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 748 { 749 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dctx; 750 const PetscScalar *yy; 751 Vec v; 752 753 PetscFunctionBegin; 754 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 755 if (!step) { 756 PetscDrawAxis axis; 757 PetscInt dim; 758 CHKERRQ(PetscDrawLGGetAxis(ctx->lg,&axis)); 759 CHKERRQ(PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution")); 760 if (!ctx->names) { 761 PetscBool flg; 762 /* user provides names of variables to plot but no names has been set so assume names are integer values */ 763 CHKERRQ(PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg)); 764 if (flg) { 765 PetscInt i,n; 766 char **names; 767 CHKERRQ(VecGetSize(u,&n)); 768 CHKERRQ(PetscMalloc1(n+1,&names)); 769 for (i=0; i<n; i++) { 770 CHKERRQ(PetscMalloc1(5,&names[i])); 771 CHKERRQ(PetscSNPrintf(names[i],5,"%D",i)); 772 } 773 names[n] = NULL; 774 ctx->names = names; 775 } 776 } 777 if (ctx->names && !ctx->displaynames) { 778 char **displaynames; 779 PetscBool flg; 780 CHKERRQ(VecGetLocalSize(u,&dim)); 781 CHKERRQ(PetscCalloc1(dim+1,&displaynames)); 782 CHKERRQ(PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg)); 783 if (flg) { 784 CHKERRQ(TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames)); 785 } 786 CHKERRQ(PetscStrArrayDestroy(&displaynames)); 787 } 788 if (ctx->displaynames) { 789 CHKERRQ(PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables)); 790 CHKERRQ(PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames)); 791 } else if (ctx->names) { 792 CHKERRQ(VecGetLocalSize(u,&dim)); 793 CHKERRQ(PetscDrawLGSetDimension(ctx->lg,dim)); 794 CHKERRQ(PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names)); 795 } else { 796 CHKERRQ(VecGetLocalSize(u,&dim)); 797 CHKERRQ(PetscDrawLGSetDimension(ctx->lg,dim)); 798 } 799 CHKERRQ(PetscDrawLGReset(ctx->lg)); 800 } 801 802 if (!ctx->transform) v = u; 803 else CHKERRQ((*ctx->transform)(ctx->transformctx,u,&v)); 804 CHKERRQ(VecGetArrayRead(v,&yy)); 805 if (ctx->displaynames) { 806 PetscInt i; 807 for (i=0; i<ctx->ndisplayvariables; i++) 808 ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]); 809 CHKERRQ(PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues)); 810 } else { 811 #if defined(PETSC_USE_COMPLEX) 812 PetscInt i,n; 813 PetscReal *yreal; 814 CHKERRQ(VecGetLocalSize(v,&n)); 815 CHKERRQ(PetscMalloc1(n,&yreal)); 816 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 817 CHKERRQ(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal)); 818 CHKERRQ(PetscFree(yreal)); 819 #else 820 CHKERRQ(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy)); 821 #endif 822 } 823 CHKERRQ(VecRestoreArrayRead(v,&yy)); 824 if (ctx->transform) CHKERRQ(VecDestroy(&v)); 825 826 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 827 CHKERRQ(PetscDrawLGDraw(ctx->lg)); 828 CHKERRQ(PetscDrawLGSave(ctx->lg)); 829 } 830 PetscFunctionReturn(0); 831 } 832 833 /*@C 834 TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 835 836 Collective on TS 837 838 Input Parameters: 839 + ts - the TS context 840 - names - the names of the components, final string must be NULL 841 842 Level: intermediate 843 844 Notes: 845 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 846 847 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames() 848 @*/ 849 PetscErrorCode TSMonitorLGSetVariableNames(TS ts,const char * const *names) 850 { 851 PetscInt i; 852 853 PetscFunctionBegin; 854 for (i=0; i<ts->numbermonitors; i++) { 855 if (ts->monitor[i] == TSMonitorLGSolution) { 856 CHKERRQ(TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names)); 857 break; 858 } 859 } 860 PetscFunctionReturn(0); 861 } 862 863 /*@C 864 TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 865 866 Collective on TS 867 868 Input Parameters: 869 + ts - the TS context 870 - names - the names of the components, final string must be NULL 871 872 Level: intermediate 873 874 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames() 875 @*/ 876 PetscErrorCode TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names) 877 { 878 PetscFunctionBegin; 879 CHKERRQ(PetscStrArrayDestroy(&ctx->names)); 880 CHKERRQ(PetscStrArrayallocpy(names,&ctx->names)); 881 PetscFunctionReturn(0); 882 } 883 884 /*@C 885 TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot 886 887 Collective on TS 888 889 Input Parameter: 890 . ts - the TS context 891 892 Output Parameter: 893 . names - the names of the components, final string must be NULL 894 895 Level: intermediate 896 897 Notes: 898 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 899 900 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 901 @*/ 902 PetscErrorCode TSMonitorLGGetVariableNames(TS ts,const char *const **names) 903 { 904 PetscInt i; 905 906 PetscFunctionBegin; 907 *names = NULL; 908 for (i=0; i<ts->numbermonitors; i++) { 909 if (ts->monitor[i] == TSMonitorLGSolution) { 910 TSMonitorLGCtx ctx = (TSMonitorLGCtx) ts->monitorcontext[i]; 911 *names = (const char *const *)ctx->names; 912 break; 913 } 914 } 915 PetscFunctionReturn(0); 916 } 917 918 /*@C 919 TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor 920 921 Collective on TS 922 923 Input Parameters: 924 + ctx - the TSMonitorLG context 925 - displaynames - the names of the components, final string must be NULL 926 927 Level: intermediate 928 929 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 930 @*/ 931 PetscErrorCode TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames) 932 { 933 PetscInt j = 0,k; 934 935 PetscFunctionBegin; 936 if (!ctx->names) PetscFunctionReturn(0); 937 CHKERRQ(PetscStrArrayDestroy(&ctx->displaynames)); 938 CHKERRQ(PetscStrArrayallocpy(displaynames,&ctx->displaynames)); 939 while (displaynames[j]) j++; 940 ctx->ndisplayvariables = j; 941 CHKERRQ(PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables)); 942 CHKERRQ(PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues)); 943 j = 0; 944 while (displaynames[j]) { 945 k = 0; 946 while (ctx->names[k]) { 947 PetscBool flg; 948 CHKERRQ(PetscStrcmp(displaynames[j],ctx->names[k],&flg)); 949 if (flg) { 950 ctx->displayvariables[j] = k; 951 break; 952 } 953 k++; 954 } 955 j++; 956 } 957 PetscFunctionReturn(0); 958 } 959 960 /*@C 961 TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor 962 963 Collective on TS 964 965 Input Parameters: 966 + ts - the TS context 967 - displaynames - the names of the components, final string must be NULL 968 969 Notes: 970 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 971 972 Level: intermediate 973 974 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames() 975 @*/ 976 PetscErrorCode TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames) 977 { 978 PetscInt i; 979 980 PetscFunctionBegin; 981 for (i=0; i<ts->numbermonitors; i++) { 982 if (ts->monitor[i] == TSMonitorLGSolution) { 983 CHKERRQ(TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames)); 984 break; 985 } 986 } 987 PetscFunctionReturn(0); 988 } 989 990 /*@C 991 TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed 992 993 Collective on TS 994 995 Input Parameters: 996 + ts - the TS context 997 . transform - the transform function 998 . destroy - function to destroy the optional context 999 - ctx - optional context used by transform function 1000 1001 Notes: 1002 If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored 1003 1004 Level: intermediate 1005 1006 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform() 1007 @*/ 1008 PetscErrorCode TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 1009 { 1010 PetscInt i; 1011 1012 PetscFunctionBegin; 1013 for (i=0; i<ts->numbermonitors; i++) { 1014 if (ts->monitor[i] == TSMonitorLGSolution) { 1015 CHKERRQ(TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx)); 1016 } 1017 } 1018 PetscFunctionReturn(0); 1019 } 1020 1021 /*@C 1022 TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed 1023 1024 Collective on TSLGCtx 1025 1026 Input Parameters: 1027 + ts - the TS context 1028 . transform - the transform function 1029 . destroy - function to destroy the optional context 1030 - ctx - optional context used by transform function 1031 1032 Level: intermediate 1033 1034 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform() 1035 @*/ 1036 PetscErrorCode TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx) 1037 { 1038 PetscFunctionBegin; 1039 ctx->transform = transform; 1040 ctx->transformdestroy = destroy; 1041 ctx->transformctx = tctx; 1042 PetscFunctionReturn(0); 1043 } 1044 1045 /*@C 1046 TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error 1047 in a time based line graph 1048 1049 Collective on TS 1050 1051 Input Parameters: 1052 + ts - the TS context 1053 . step - current time-step 1054 . ptime - current time 1055 . u - current solution 1056 - dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate() 1057 1058 Level: intermediate 1059 1060 Notes: 1061 Each process in a parallel run displays its component errors in a separate window 1062 1063 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 1064 1065 Options Database Keys: 1066 . -ts_monitor_lg_error - create a graphical monitor of error history 1067 1068 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 1069 @*/ 1070 PetscErrorCode TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy) 1071 { 1072 TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 1073 const PetscScalar *yy; 1074 Vec y; 1075 1076 PetscFunctionBegin; 1077 if (!step) { 1078 PetscDrawAxis axis; 1079 PetscInt dim; 1080 CHKERRQ(PetscDrawLGGetAxis(ctx->lg,&axis)); 1081 CHKERRQ(PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Error")); 1082 CHKERRQ(VecGetLocalSize(u,&dim)); 1083 CHKERRQ(PetscDrawLGSetDimension(ctx->lg,dim)); 1084 CHKERRQ(PetscDrawLGReset(ctx->lg)); 1085 } 1086 CHKERRQ(VecDuplicate(u,&y)); 1087 CHKERRQ(TSComputeSolutionFunction(ts,ptime,y)); 1088 CHKERRQ(VecAXPY(y,-1.0,u)); 1089 CHKERRQ(VecGetArrayRead(y,&yy)); 1090 #if defined(PETSC_USE_COMPLEX) 1091 { 1092 PetscReal *yreal; 1093 PetscInt i,n; 1094 CHKERRQ(VecGetLocalSize(y,&n)); 1095 CHKERRQ(PetscMalloc1(n,&yreal)); 1096 for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]); 1097 CHKERRQ(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal)); 1098 CHKERRQ(PetscFree(yreal)); 1099 } 1100 #else 1101 CHKERRQ(PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy)); 1102 #endif 1103 CHKERRQ(VecRestoreArrayRead(y,&yy)); 1104 CHKERRQ(VecDestroy(&y)); 1105 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 1106 CHKERRQ(PetscDrawLGDraw(ctx->lg)); 1107 CHKERRQ(PetscDrawLGSave(ctx->lg)); 1108 } 1109 PetscFunctionReturn(0); 1110 } 1111 1112 /*@C 1113 TSMonitorSPSwarmSolution - Graphically displays phase plots of DMSwarm particles on a scatter plot 1114 1115 Input Parameters: 1116 + ts - the TS context 1117 . step - current time-step 1118 . ptime - current time 1119 . u - current solution 1120 - dctx - the TSMonitorSPCtx object that contains all the options for the monitoring, this is created with TSMonitorSPCtxCreate() 1121 1122 Options Database: 1123 + -ts_monitor_sp_swarm <n> - Monitor the solution every n steps, or -1 for plotting only the final solution 1124 . -ts_monitor_sp_swarm_retain <n> - Retain n old points so we can see the history, or -1 for all points 1125 - -ts_monitor_sp_swarm_phase <bool> - Plot in phase space, as opposed to coordinate space 1126 1127 Level: intermediate 1128 1129 .seealso: TSMonitoSet() 1130 @*/ 1131 PetscErrorCode TSMonitorSPSwarmSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx) 1132 { 1133 TSMonitorSPCtx ctx = (TSMonitorSPCtx) dctx; 1134 DM dm, cdm; 1135 const PetscScalar *yy; 1136 PetscReal *y, *x; 1137 PetscInt Np, p, dim = 2; 1138 1139 PetscFunctionBegin; 1140 if (step < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 1141 if (!step) { 1142 PetscDrawAxis axis; 1143 PetscReal dmboxlower[2], dmboxupper[2]; 1144 CHKERRQ(TSGetDM(ts, &dm)); 1145 CHKERRQ(DMGetDimension(dm, &dim)); 1146 PetscCheck(dim == 2,PETSC_COMM_SELF, PETSC_ERR_SUP, "Monitor only supports two dimensional fields"); 1147 CHKERRQ(DMSwarmGetCellDM(dm, &cdm)); 1148 CHKERRQ(DMGetBoundingBox(cdm, dmboxlower, dmboxupper)); 1149 CHKERRQ(VecGetLocalSize(u, &Np)); 1150 Np /= dim*2; 1151 CHKERRQ(PetscDrawSPGetAxis(ctx->sp,&axis)); 1152 if (ctx->phase) { 1153 CHKERRQ(PetscDrawAxisSetLabels(axis,"Particles","X","V")); 1154 CHKERRQ(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], -5, 5)); 1155 } else { 1156 CHKERRQ(PetscDrawAxisSetLabels(axis,"Particles","X","Y")); 1157 CHKERRQ(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], dmboxlower[1], dmboxupper[1])); 1158 } 1159 CHKERRQ(PetscDrawAxisSetHoldLimits(axis, PETSC_TRUE)); 1160 CHKERRQ(PetscDrawSPSetDimension(ctx->sp, Np)); 1161 CHKERRQ(PetscDrawSPReset(ctx->sp)); 1162 } 1163 CHKERRQ(VecGetLocalSize(u, &Np)); 1164 Np /= dim*2; 1165 CHKERRQ(VecGetArrayRead(u,&yy)); 1166 CHKERRQ(PetscMalloc2(Np, &x, Np, &y)); 1167 /* get points from solution vector */ 1168 for (p = 0; p < Np; ++p) { 1169 if (ctx->phase) { 1170 x[p] = PetscRealPart(yy[p*dim*2]); 1171 y[p] = PetscRealPart(yy[p*dim*2 + dim]); 1172 } else { 1173 x[p] = PetscRealPart(yy[p*dim*2]); 1174 y[p] = PetscRealPart(yy[p*dim*2 + 1]); 1175 } 1176 } 1177 CHKERRQ(VecRestoreArrayRead(u,&yy)); 1178 if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 1179 PetscDraw draw; 1180 CHKERRQ(PetscDrawSPGetDraw(ctx->sp, &draw)); 1181 if ((ctx->retain == 0) || (ctx->retain > 0 && !(step % ctx->retain))) { 1182 CHKERRQ(PetscDrawClear(draw)); 1183 } 1184 CHKERRQ(PetscDrawFlush(draw)); 1185 CHKERRQ(PetscDrawSPReset(ctx->sp)); 1186 CHKERRQ(PetscDrawSPAddPoint(ctx->sp, x, y)); 1187 CHKERRQ(PetscDrawSPDraw(ctx->sp, PETSC_FALSE)); 1188 CHKERRQ(PetscDrawSPSave(ctx->sp)); 1189 } 1190 CHKERRQ(PetscFree2(x, y)); 1191 PetscFunctionReturn(0); 1192 } 1193 1194 /*@C 1195 TSMonitorError - Monitors progress of the TS solvers by printing the 2 norm of the error at each timestep 1196 1197 Collective on TS 1198 1199 Input Parameters: 1200 + ts - the TS context 1201 . step - current time-step 1202 . ptime - current time 1203 . u - current solution 1204 - dctx - unused context 1205 1206 Level: intermediate 1207 1208 The user must provide the solution using TSSetSolutionFunction() to use this monitor. 1209 1210 Options Database Keys: 1211 . -ts_monitor_error - create a graphical monitor of error history 1212 1213 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction() 1214 @*/ 1215 PetscErrorCode TSMonitorError(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf) 1216 { 1217 DM dm; 1218 PetscDS ds = NULL; 1219 PetscInt Nf = -1, f; 1220 PetscBool flg; 1221 1222 PetscFunctionBegin; 1223 CHKERRQ(TSGetDM(ts, &dm)); 1224 if (dm) CHKERRQ(DMGetDS(dm, &ds)); 1225 if (ds) CHKERRQ(PetscDSGetNumFields(ds, &Nf)); 1226 if (Nf <= 0) { 1227 Vec y; 1228 PetscReal nrm; 1229 1230 CHKERRQ(VecDuplicate(u,&y)); 1231 CHKERRQ(TSComputeSolutionFunction(ts,ptime,y)); 1232 CHKERRQ(VecAXPY(y,-1.0,u)); 1233 CHKERRQ(PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERASCII,&flg)); 1234 if (flg) { 1235 CHKERRQ(VecNorm(y,NORM_2,&nrm)); 1236 CHKERRQ(PetscViewerASCIIPrintf(vf->viewer,"2-norm of error %g\n",(double)nrm)); 1237 } 1238 CHKERRQ(PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERDRAW,&flg)); 1239 if (flg) { 1240 CHKERRQ(VecView(y,vf->viewer)); 1241 } 1242 CHKERRQ(VecDestroy(&y)); 1243 } else { 1244 PetscErrorCode (**exactFuncs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx); 1245 void **ctxs; 1246 Vec v; 1247 PetscReal ferrors[1]; 1248 1249 CHKERRQ(PetscMalloc2(Nf, &exactFuncs, Nf, &ctxs)); 1250 for (f = 0; f < Nf; ++f) CHKERRQ(PetscDSGetExactSolution(ds, f, &exactFuncs[f], &ctxs[f])); 1251 CHKERRQ(DMComputeL2FieldDiff(dm, ptime, exactFuncs, ctxs, u, ferrors)); 1252 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "Timestep: %04d time = %-8.4g \t L_2 Error: [", (int) step, (double) ptime)); 1253 for (f = 0; f < Nf; ++f) { 1254 if (f > 0) CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, ", ")); 1255 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "%2.3g", (double) ferrors[f])); 1256 } 1257 CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "]\n")); 1258 1259 CHKERRQ(VecViewFromOptions(u, NULL, "-sol_vec_view")); 1260 1261 CHKERRQ(PetscOptionsHasName(NULL, NULL, "-exact_vec_view", &flg)); 1262 if (flg) { 1263 CHKERRQ(DMGetGlobalVector(dm, &v)); 1264 CHKERRQ(DMProjectFunction(dm, ptime, exactFuncs, ctxs, INSERT_ALL_VALUES, v)); 1265 CHKERRQ(PetscObjectSetName((PetscObject) v, "Exact Solution")); 1266 CHKERRQ(VecViewFromOptions(v, NULL, "-exact_vec_view")); 1267 CHKERRQ(DMRestoreGlobalVector(dm, &v)); 1268 } 1269 CHKERRQ(PetscFree2(exactFuncs, ctxs)); 1270 } 1271 PetscFunctionReturn(0); 1272 } 1273 1274 PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 1275 { 1276 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 1277 PetscReal x = ptime,y; 1278 PetscInt its; 1279 1280 PetscFunctionBegin; 1281 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 1282 if (!n) { 1283 PetscDrawAxis axis; 1284 CHKERRQ(PetscDrawLGGetAxis(ctx->lg,&axis)); 1285 CHKERRQ(PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations")); 1286 CHKERRQ(PetscDrawLGReset(ctx->lg)); 1287 ctx->snes_its = 0; 1288 } 1289 CHKERRQ(TSGetSNESIterations(ts,&its)); 1290 y = its - ctx->snes_its; 1291 CHKERRQ(PetscDrawLGAddPoint(ctx->lg,&x,&y)); 1292 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 1293 CHKERRQ(PetscDrawLGDraw(ctx->lg)); 1294 CHKERRQ(PetscDrawLGSave(ctx->lg)); 1295 } 1296 ctx->snes_its = its; 1297 PetscFunctionReturn(0); 1298 } 1299 1300 PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx) 1301 { 1302 TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx; 1303 PetscReal x = ptime,y; 1304 PetscInt its; 1305 1306 PetscFunctionBegin; 1307 if (n < 0) PetscFunctionReturn(0); /* -1 indicates interpolated solution */ 1308 if (!n) { 1309 PetscDrawAxis axis; 1310 CHKERRQ(PetscDrawLGGetAxis(ctx->lg,&axis)); 1311 CHKERRQ(PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations")); 1312 CHKERRQ(PetscDrawLGReset(ctx->lg)); 1313 ctx->ksp_its = 0; 1314 } 1315 CHKERRQ(TSGetKSPIterations(ts,&its)); 1316 y = its - ctx->ksp_its; 1317 CHKERRQ(PetscDrawLGAddPoint(ctx->lg,&x,&y)); 1318 if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 1319 CHKERRQ(PetscDrawLGDraw(ctx->lg)); 1320 CHKERRQ(PetscDrawLGSave(ctx->lg)); 1321 } 1322 ctx->ksp_its = its; 1323 PetscFunctionReturn(0); 1324 } 1325 1326 /*@C 1327 TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope() 1328 1329 Collective on TS 1330 1331 Input Parameters: 1332 . ts - the ODE solver object 1333 1334 Output Parameter: 1335 . ctx - the context 1336 1337 Level: intermediate 1338 1339 .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError() 1340 1341 @*/ 1342 PetscErrorCode TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx) 1343 { 1344 PetscFunctionBegin; 1345 CHKERRQ(PetscNew(ctx)); 1346 PetscFunctionReturn(0); 1347 } 1348 1349 /*@C 1350 TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution 1351 1352 Collective on TS 1353 1354 Input Parameters: 1355 + ts - the TS context 1356 . step - current time-step 1357 . ptime - current time 1358 . u - current solution 1359 - dctx - the envelope context 1360 1361 Options Database: 1362 . -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time 1363 1364 Level: intermediate 1365 1366 Notes: 1367 after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope 1368 1369 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate() 1370 @*/ 1371 PetscErrorCode TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx) 1372 { 1373 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx; 1374 1375 PetscFunctionBegin; 1376 if (!ctx->max) { 1377 CHKERRQ(VecDuplicate(u,&ctx->max)); 1378 CHKERRQ(VecDuplicate(u,&ctx->min)); 1379 CHKERRQ(VecCopy(u,ctx->max)); 1380 CHKERRQ(VecCopy(u,ctx->min)); 1381 } else { 1382 CHKERRQ(VecPointwiseMax(ctx->max,u,ctx->max)); 1383 CHKERRQ(VecPointwiseMin(ctx->min,u,ctx->min)); 1384 } 1385 PetscFunctionReturn(0); 1386 } 1387 1388 /*@C 1389 TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution 1390 1391 Collective on TS 1392 1393 Input Parameter: 1394 . ts - the TS context 1395 1396 Output Parameters: 1397 + max - the maximum values 1398 - min - the minimum values 1399 1400 Notes: 1401 If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored 1402 1403 Level: intermediate 1404 1405 .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables() 1406 @*/ 1407 PetscErrorCode TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min) 1408 { 1409 PetscInt i; 1410 1411 PetscFunctionBegin; 1412 if (max) *max = NULL; 1413 if (min) *min = NULL; 1414 for (i=0; i<ts->numbermonitors; i++) { 1415 if (ts->monitor[i] == TSMonitorEnvelope) { 1416 TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i]; 1417 if (max) *max = ctx->max; 1418 if (min) *min = ctx->min; 1419 break; 1420 } 1421 } 1422 PetscFunctionReturn(0); 1423 } 1424 1425 /*@C 1426 TSMonitorEnvelopeCtxDestroy - Destroys a context that was created with TSMonitorEnvelopeCtxCreate(). 1427 1428 Collective on TSMonitorEnvelopeCtx 1429 1430 Input Parameter: 1431 . ctx - the monitor context 1432 1433 Level: intermediate 1434 1435 .seealso: TSMonitorLGCtxCreate(), TSMonitorSet(), TSMonitorLGTimeStep() 1436 @*/ 1437 PetscErrorCode TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx) 1438 { 1439 PetscFunctionBegin; 1440 CHKERRQ(VecDestroy(&(*ctx)->min)); 1441 CHKERRQ(VecDestroy(&(*ctx)->max)); 1442 CHKERRQ(PetscFree(*ctx)); 1443 PetscFunctionReturn(0); 1444 } 1445 1446 /*@C 1447 TSDMSwarmMonitorMoments - Monitors the first three moments of a DMSarm being evolved by the TS 1448 1449 Not collective 1450 1451 Input Parameters: 1452 + ts - the TS context 1453 . step - current timestep 1454 . t - current time 1455 . u - current solution 1456 - ctx - not used 1457 1458 Options Database: 1459 . -ts_dmswarm_monitor_moments - Monitor moments of particle distribution 1460 1461 Level: intermediate 1462 1463 Notes: 1464 This requires a DMSwarm be attached to the TS. 1465 1466 .seealso: TSMonitorSet(), TSMonitorDefault(), DMSWARM 1467 @*/ 1468 PetscErrorCode TSDMSwarmMonitorMoments(TS ts, PetscInt step, PetscReal t, Vec U, PetscViewerAndFormat *vf) 1469 { 1470 DM sw; 1471 const PetscScalar *u; 1472 PetscReal m = 1.0, totE = 0., totMom[3] = {0., 0., 0.}; 1473 PetscInt dim, d, Np, p; 1474 MPI_Comm comm; 1475 1476 PetscFunctionBeginUser; 1477 CHKERRQ(TSGetDM(ts, &sw)); 1478 if (!sw || step%ts->monitorFrequency != 0) PetscFunctionReturn(0); 1479 CHKERRQ(PetscObjectGetComm((PetscObject) ts, &comm)); 1480 CHKERRQ(DMGetDimension(sw, &dim)); 1481 CHKERRQ(VecGetLocalSize(U, &Np)); 1482 Np /= dim; 1483 CHKERRQ(VecGetArrayRead(U, &u)); 1484 for (p = 0; p < Np; ++p) { 1485 for (d = 0; d < dim; ++d) { 1486 totE += PetscRealPart(u[p*dim+d]*u[p*dim+d]); 1487 totMom[d] += PetscRealPart(u[p*dim+d]); 1488 } 1489 } 1490 CHKERRQ(VecRestoreArrayRead(U, &u)); 1491 for (d = 0; d < dim; ++d) totMom[d] *= m; 1492 totE *= 0.5*m; 1493 CHKERRQ(PetscPrintf(comm, "Step %4D Total Energy: %10.8lf", step, (double) totE)); 1494 for (d = 0; d < dim; ++d) CHKERRQ(PetscPrintf(comm, " Total Momentum %c: %10.8lf", 'x'+d, (double) totMom[d])); 1495 CHKERRQ(PetscPrintf(comm, "\n")); 1496 PetscFunctionReturn(0); 1497 } 1498