1 #include <petscviewer.h> 2 #include <petsc/private/drawimpl.h> /*I "petscdraw.h" I*/ 3 PetscClassId PETSC_DRAWLG_CLASSID = 0; 4 5 /*@ 6 PetscDrawLGGetAxis - Gets the axis context associated with a line graph. 7 This is useful if one wants to change some axis property, such as 8 labels, color, etc. The axis context should not be destroyed by the 9 application code. 10 11 Not Collective, if lg is parallel then axis is parallel 12 13 Input Parameter: 14 . lg - the line graph context 15 16 Output Parameter: 17 . axis - the axis context 18 19 Level: advanced 20 21 .seealso: `PetscDrawLGCreate()`, `PetscDrawAxis`, `PetscDrawLG` 22 @*/ 23 PetscErrorCode PetscDrawLGGetAxis(PetscDrawLG lg, PetscDrawAxis *axis) 24 { 25 PetscFunctionBegin; 26 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 27 PetscAssertPointer(axis, 2); 28 *axis = lg->axis; 29 PetscFunctionReturn(PETSC_SUCCESS); 30 } 31 32 /*@ 33 PetscDrawLGGetDraw - Gets the draw context associated with a line graph. 34 35 Not Collective, if lg is parallel then draw is parallel 36 37 Input Parameter: 38 . lg - the line graph context 39 40 Output Parameter: 41 . draw - the draw context 42 43 Level: intermediate 44 45 .seealso: `PetscDrawLGCreate()`, `PetscDraw`, `PetscDrawLG` 46 @*/ 47 PetscErrorCode PetscDrawLGGetDraw(PetscDrawLG lg, PetscDraw *draw) 48 { 49 PetscFunctionBegin; 50 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 51 PetscAssertPointer(draw, 2); 52 *draw = lg->win; 53 PetscFunctionReturn(PETSC_SUCCESS); 54 } 55 56 /*@ 57 PetscDrawLGSPDraw - Redraws a line graph and a scatter plot on the same `PetscDraw` they must share 58 59 Collective 60 61 Input Parameters: 62 + lg - the line graph context 63 - spin - the scatter plot 64 65 Level: intermediate 66 67 Developer Notes: 68 This code cheats and uses the fact that the `PetscDrawLG` and `PetscDrawSP` structs are the same 69 70 .seealso: `PetscDrawLGDraw()`, `PetscDrawSPDraw()` 71 @*/ 72 PetscErrorCode PetscDrawLGSPDraw(PetscDrawLG lg, PetscDrawSP spin) 73 { 74 PetscDrawLG sp = (PetscDrawLG)spin; 75 PetscReal xmin, xmax, ymin, ymax; 76 PetscBool isnull; 77 PetscMPIInt rank; 78 PetscDraw draw; 79 80 PetscFunctionBegin; 81 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 82 PetscValidHeaderSpecific(sp, PETSC_DRAWLG_CLASSID, 2); 83 PetscCall(PetscDrawIsNull(lg->win, &isnull)); 84 if (isnull) PetscFunctionReturn(PETSC_SUCCESS); 85 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)lg), &rank)); 86 87 draw = lg->win; 88 PetscCall(PetscDrawCheckResizedWindow(draw)); 89 PetscCall(PetscDrawClear(draw)); 90 91 xmin = PetscMin(lg->xmin, sp->xmin); 92 ymin = PetscMin(lg->ymin, sp->ymin); 93 xmax = PetscMax(lg->xmax, sp->xmax); 94 ymax = PetscMax(lg->ymax, sp->ymax); 95 PetscCall(PetscDrawAxisSetLimits(lg->axis, xmin, xmax, ymin, ymax)); 96 PetscCall(PetscDrawAxisDraw(lg->axis)); 97 98 PetscDrawCollectiveBegin(draw); 99 if (rank == 0) { 100 int i, j, dim, nopts; 101 dim = lg->dim; 102 nopts = lg->nopts; 103 for (i = 0; i < dim; i++) { 104 for (j = 1; j < nopts; j++) { 105 PetscCall(PetscDrawLine(draw, lg->x[(j - 1) * dim + i], lg->y[(j - 1) * dim + i], lg->x[j * dim + i], lg->y[j * dim + i], PETSC_DRAW_BLACK + i)); 106 if (lg->use_markers) PetscCall(PetscDrawMarker(draw, lg->x[j * dim + i], lg->y[j * dim + i], PETSC_DRAW_RED)); 107 } 108 } 109 dim = sp->dim; 110 nopts = sp->nopts; 111 for (i = 0; i < dim; i++) { 112 for (j = 0; j < nopts; j++) PetscCall(PetscDrawMarker(draw, sp->x[j * dim + i], sp->y[j * dim + i], PETSC_DRAW_RED)); 113 } 114 } 115 PetscDrawCollectiveEnd(draw); 116 117 PetscCall(PetscDrawFlush(draw)); 118 PetscCall(PetscDrawPause(draw)); 119 PetscFunctionReturn(PETSC_SUCCESS); 120 } 121 122 /*@ 123 PetscDrawLGCreate - Creates a line graph data structure. 124 125 Collective 126 127 Input Parameters: 128 + draw - the window where the graph will be made. 129 - dim - the number of curves which will be drawn 130 131 Output Parameter: 132 . outlg - the line graph context 133 134 Level: intermediate 135 136 Notes: 137 The MPI communicator that owns the `PetscDraw` owns this `PetscDrawLG`, but the calls to set options and add points are ignored on all processes except the 138 zeroth MPI process in the communicator. 139 140 All MPI ranks in the communicator must call `PetscDrawLGDraw()` to display the updated graph. 141 142 .seealso: `PetscDrawLGDestroy()`, `PetscDrawLGAddPoint()`, `PetscDrawLGAddCommonPoint()`, `PetscDrawLGAddPoints()`, `PetscDrawLGDraw()`, `PetscDrawLGSave()`, 143 `PetscDrawLGView()`, `PetscDrawLGReset()`, `PetscDrawLGSetDimension()`, `PetscDrawLGGetDimension()`, `PetscDrawLGSetLegend()`, `PetscDrawLGGetAxis()`, 144 `PetscDrawLGGetDraw()`, `PetscDrawLGSetUseMarkers()`, `PetscDrawLGSetLimits()`, `PetscDrawLGSetColors()`, `PetscDrawLGSetOptionsPrefix()`, `PetscDrawLGSetFromOptions()` 145 @*/ 146 PetscErrorCode PetscDrawLGCreate(PetscDraw draw, PetscInt dim, PetscDrawLG *outlg) 147 { 148 PetscDrawLG lg; 149 150 PetscFunctionBegin; 151 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 152 PetscValidLogicalCollectiveInt(draw, dim, 2); 153 PetscAssertPointer(outlg, 3); 154 155 PetscCall(PetscHeaderCreate(lg, PETSC_DRAWLG_CLASSID, "DrawLG", "Line Graph", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawLGDestroy, NULL)); 156 PetscCall(PetscDrawLGSetOptionsPrefix(lg, ((PetscObject)draw)->prefix)); 157 158 PetscCall(PetscObjectReference((PetscObject)draw)); 159 lg->win = draw; 160 161 lg->view = NULL; 162 lg->destroy = NULL; 163 lg->nopts = 0; 164 lg->xmin = 1.e20; 165 lg->ymin = 1.e20; 166 lg->xmax = -1.e20; 167 lg->ymax = -1.e20; 168 PetscCall(PetscCIntCast(dim, &lg->dim)); 169 PetscCall(PetscMalloc2(dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->x, dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->y)); 170 171 lg->len = lg->dim * PETSC_DRAW_LG_CHUNK_SIZE; 172 lg->loc = 0; 173 lg->use_markers = PETSC_FALSE; 174 175 PetscCall(PetscDrawAxisCreate(draw, &lg->axis)); 176 177 *outlg = lg; 178 PetscFunctionReturn(PETSC_SUCCESS); 179 } 180 181 /*@ 182 PetscDrawLGSetColors - Sets the color of each line graph drawn 183 184 Logically Collective 185 186 Input Parameters: 187 + lg - the line graph context. 188 - colors - the colors, an array of length the value set with `PetscDrawLGSetDimension()` 189 190 Level: intermediate 191 192 .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`, `PetscDrawLGSetDimension()`, `PetscDrawLGGetDimension()` 193 @*/ 194 PetscErrorCode PetscDrawLGSetColors(PetscDrawLG lg, const int colors[]) 195 { 196 PetscFunctionBegin; 197 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 198 if (lg->dim) PetscAssertPointer(colors, 2); 199 200 PetscCall(PetscFree(lg->colors)); 201 PetscCall(PetscMalloc1(lg->dim, &lg->colors)); 202 PetscCall(PetscArraycpy(lg->colors, colors, lg->dim)); 203 PetscFunctionReturn(PETSC_SUCCESS); 204 } 205 206 /*@C 207 PetscDrawLGSetLegend - sets the names of each curve plotted 208 209 Logically Collective 210 211 Input Parameters: 212 + lg - the line graph context. 213 - names - the names for each curve 214 215 Level: intermediate 216 217 Note: 218 Call `PetscDrawLGGetAxis()` and then change properties of the `PetscDrawAxis` for detailed control of the plot 219 220 .seealso: `PetscDrawLGGetAxis()`, `PetscDrawAxis`, `PetscDrawAxisSetColors()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetHoldLimits()` 221 @*/ 222 PetscErrorCode PetscDrawLGSetLegend(PetscDrawLG lg, const char *const names[]) 223 { 224 PetscInt i; 225 226 PetscFunctionBegin; 227 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 228 if (names) PetscAssertPointer(names, 2); 229 230 if (lg->legend) { 231 for (i = 0; i < lg->dim; i++) PetscCall(PetscFree(lg->legend[i])); 232 PetscCall(PetscFree(lg->legend)); 233 } 234 if (names) { 235 PetscCall(PetscMalloc1(lg->dim, &lg->legend)); 236 for (i = 0; i < lg->dim; i++) PetscCall(PetscStrallocpy(names[i], &lg->legend[i])); 237 } 238 PetscFunctionReturn(PETSC_SUCCESS); 239 } 240 241 /*@ 242 PetscDrawLGGetDimension - Get the number of curves that are to be drawn. 243 244 Not Collective 245 246 Input Parameter: 247 . lg - the line graph context. 248 249 Output Parameter: 250 . dim - the number of curves. 251 252 Level: intermediate 253 254 .seealso: `PetscDrawLGC`, `PetscDrawLGCreate()`, `PetscDrawLGSetDimension()` 255 @*/ 256 PetscErrorCode PetscDrawLGGetDimension(PetscDrawLG lg, PetscInt *dim) 257 { 258 PetscFunctionBegin; 259 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 260 PetscAssertPointer(dim, 2); 261 *dim = lg->dim; 262 PetscFunctionReturn(PETSC_SUCCESS); 263 } 264 265 /*@ 266 PetscDrawLGSetDimension - Change the number of curves that are to be drawn. 267 268 Logically Collective 269 270 Input Parameters: 271 + lg - the line graph context. 272 - dim - the number of curves. 273 274 Level: intermediate 275 276 .seealso: `PetscDrawLGCreate()`, `PetscDrawLGGetDimension()` 277 @*/ 278 PetscErrorCode PetscDrawLGSetDimension(PetscDrawLG lg, PetscInt dim) 279 { 280 PetscInt i; 281 282 PetscFunctionBegin; 283 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 284 PetscValidLogicalCollectiveInt(lg, dim, 2); 285 if (lg->dim == dim) PetscFunctionReturn(PETSC_SUCCESS); 286 287 PetscCall(PetscFree2(lg->x, lg->y)); 288 if (lg->legend) { 289 for (i = 0; i < lg->dim; i++) PetscCall(PetscFree(lg->legend[i])); 290 PetscCall(PetscFree(lg->legend)); 291 } 292 PetscCall(PetscFree(lg->colors)); 293 PetscCall(PetscCIntCast(dim, &lg->dim)); 294 PetscCall(PetscMalloc2(dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->x, dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->y)); 295 lg->len = lg->dim * PETSC_DRAW_LG_CHUNK_SIZE; 296 PetscFunctionReturn(PETSC_SUCCESS); 297 } 298 299 /*@C 300 PetscDrawLGGetData - Get the data being plotted. 301 302 Not Collective 303 304 Input Parameter: 305 . lg - the line graph context 306 307 Output Parameters: 308 + dim - the number of curves 309 . n - the number of points on each line 310 . x - The x-value of each point, x[p * dim + c] 311 - y - The y-value of each point, y[p * dim + c] 312 313 Level: intermediate 314 315 .seealso: `PetscDrawLGC`, `PetscDrawLGCreate()`, `PetscDrawLGGetDimension()` 316 @*/ 317 PetscErrorCode PetscDrawLGGetData(PetscDrawLG lg, PetscInt *dim, PetscInt *n, const PetscReal *x[], const PetscReal *y[]) 318 { 319 PetscFunctionBegin; 320 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 321 if (dim) { 322 PetscAssertPointer(dim, 2); 323 *dim = lg->dim; 324 } 325 if (n) { 326 PetscAssertPointer(n, 3); 327 *n = lg->nopts; 328 } 329 if (x) { 330 PetscAssertPointer(x, 4); 331 *x = lg->x; 332 } 333 if (y) { 334 PetscAssertPointer(y, 5); 335 *y = lg->y; 336 } 337 PetscFunctionReturn(PETSC_SUCCESS); 338 } 339 340 /*@ 341 PetscDrawLGSetLimits - Sets the axis limits for a line graph. If more 342 points are added after this call, the limits will be adjusted to 343 include those additional points. 344 345 Logically Collective 346 347 Input Parameters: 348 + lg - the line graph context 349 . x_min - the horizontal lower limit 350 . x_max - the horizontal upper limit 351 . y_min - the vertical lower limit 352 - y_max - the vertical upper limit 353 354 Level: intermediate 355 356 .seealso: `PetscDrawLGCreate()`, `PetscDrawLG`, `PetscDrawAxis` 357 @*/ 358 PetscErrorCode PetscDrawLGSetLimits(PetscDrawLG lg, PetscReal x_min, PetscReal x_max, PetscReal y_min, PetscReal y_max) 359 { 360 PetscFunctionBegin; 361 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 362 363 (lg)->xmin = x_min; 364 (lg)->xmax = x_max; 365 (lg)->ymin = y_min; 366 (lg)->ymax = y_max; 367 PetscFunctionReturn(PETSC_SUCCESS); 368 } 369 370 /*@ 371 PetscDrawLGReset - Clears line graph to allow for reuse with new data. 372 373 Logically Collective 374 375 Input Parameter: 376 . lg - the line graph context. 377 378 Level: intermediate 379 380 .seealso: `PetscDrawLG`, `PetscDrawLGCreate()` 381 @*/ 382 PetscErrorCode PetscDrawLGReset(PetscDrawLG lg) 383 { 384 PetscFunctionBegin; 385 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 386 lg->xmin = 1.e20; 387 lg->ymin = 1.e20; 388 lg->xmax = -1.e20; 389 lg->ymax = -1.e20; 390 lg->loc = 0; 391 lg->nopts = 0; 392 PetscFunctionReturn(PETSC_SUCCESS); 393 } 394 395 /*@ 396 PetscDrawLGDestroy - Frees all space taken up by line graph data structure. 397 398 Collective 399 400 Input Parameter: 401 . lg - the line graph context 402 403 Level: intermediate 404 405 .seealso: `PetscDrawLG`, `PetscDrawLGCreate()` 406 @*/ 407 PetscErrorCode PetscDrawLGDestroy(PetscDrawLG *lg) 408 { 409 PetscInt i; 410 411 PetscFunctionBegin; 412 if (!*lg) PetscFunctionReturn(PETSC_SUCCESS); 413 PetscValidHeaderSpecific(*lg, PETSC_DRAWLG_CLASSID, 1); 414 if (--((PetscObject)*lg)->refct > 0) { 415 *lg = NULL; 416 PetscFunctionReturn(PETSC_SUCCESS); 417 } 418 419 if ((*lg)->legend) { 420 for (i = 0; i < (*lg)->dim; i++) PetscCall(PetscFree((*lg)->legend[i])); 421 PetscCall(PetscFree((*lg)->legend)); 422 } 423 PetscCall(PetscFree((*lg)->colors)); 424 PetscCall(PetscFree2((*lg)->x, (*lg)->y)); 425 PetscCall(PetscDrawAxisDestroy(&(*lg)->axis)); 426 PetscCall(PetscDrawDestroy(&(*lg)->win)); 427 PetscCall(PetscHeaderDestroy(lg)); 428 PetscFunctionReturn(PETSC_SUCCESS); 429 } 430 /*@ 431 PetscDrawLGSetUseMarkers - Causes the line graph object to draw a marker for each data-point. 432 433 Logically Collective 434 435 Input Parameters: 436 + lg - the linegraph context 437 - flg - should mark each data point 438 439 Options Database Key: 440 . -lg_use_markers <true,false> - true means it draws a marker for each point 441 442 Level: intermediate 443 444 .seealso: `PetscDrawLG`, `PetscDrawLGCreate()` 445 @*/ 446 PetscErrorCode PetscDrawLGSetUseMarkers(PetscDrawLG lg, PetscBool flg) 447 { 448 PetscFunctionBegin; 449 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 450 PetscValidLogicalCollectiveBool(lg, flg, 2); 451 lg->use_markers = flg; 452 PetscFunctionReturn(PETSC_SUCCESS); 453 } 454 455 /*@ 456 PetscDrawLGDraw - Redraws a line graph. 457 458 Collective 459 460 Input Parameter: 461 . lg - the line graph context 462 463 Level: intermediate 464 465 .seealso: `PetscDrawLG`, `PetscDrawSPDraw()`, `PetscDrawLGSPDraw()`, `PetscDrawLGReset()` 466 @*/ 467 PetscErrorCode PetscDrawLGDraw(PetscDrawLG lg) 468 { 469 PetscReal xmin, xmax, ymin, ymax; 470 PetscMPIInt rank; 471 PetscDraw draw; 472 PetscBool isnull; 473 474 PetscFunctionBegin; 475 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 476 PetscCall(PetscDrawIsNull(lg->win, &isnull)); 477 if (isnull) PetscFunctionReturn(PETSC_SUCCESS); 478 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)lg), &rank)); 479 480 draw = lg->win; 481 PetscCall(PetscDrawCheckResizedWindow(draw)); 482 PetscCall(PetscDrawClear(draw)); 483 484 xmin = lg->xmin; 485 xmax = lg->xmax; 486 ymin = lg->ymin; 487 ymax = lg->ymax; 488 // Try not to freak out the axis 489 if (ymax - ymin < PETSC_SMALL) { 490 ymin -= 0.1 * ymax; 491 ymax += 0.1 * ymax; 492 } 493 PetscCall(PetscDrawAxisSetLimits(lg->axis, xmin, xmax, ymin, ymax)); 494 PetscCall(PetscDrawAxisDraw(lg->axis)); 495 496 PetscDrawCollectiveBegin(draw); 497 if (rank == 0) { 498 int i, j, dim = lg->dim, nopts = lg->nopts, cl; 499 for (i = 0; i < dim; i++) { 500 for (j = 1; j < nopts; j++) { 501 cl = lg->colors ? lg->colors[i] : ((PETSC_DRAW_BLACK + i) % PETSC_DRAW_MAXCOLOR); 502 PetscCall(PetscDrawLine(draw, lg->x[(j - 1) * dim + i], lg->y[(j - 1) * dim + i], lg->x[j * dim + i], lg->y[j * dim + i], cl)); 503 if (lg->use_markers) PetscCall(PetscDrawMarker(draw, lg->x[j * dim + i], lg->y[j * dim + i], cl)); 504 } 505 } 506 } 507 if (rank == 0 && lg->legend) { 508 PetscBool right = PETSC_FALSE; 509 int i, dim = lg->dim, cl; 510 PetscReal xl, yl, xr, yr, tw, th; 511 size_t slen, len = 0; 512 513 PetscCall(PetscDrawAxisGetLimits(lg->axis, &xl, &xr, &yl, &yr)); 514 PetscCall(PetscDrawStringGetSize(draw, &tw, &th)); 515 for (i = 0; i < dim; i++) { 516 PetscCall(PetscStrlen(lg->legend[i], &slen)); 517 len = PetscMax(len, slen); 518 } 519 if (right) { 520 xr = xr - 1.5 * tw; 521 xl = xr - ((PetscReal)len + 7) * tw; 522 } else { 523 xl = xl + 1.5 * tw; 524 xr = xl + ((PetscReal)len + 7) * tw; 525 } 526 yr = yr - 1.0 * th; 527 yl = yr - (dim + 1) * th; 528 PetscCall(PetscDrawLine(draw, xl, yl, xr, yl, PETSC_DRAW_BLACK)); 529 PetscCall(PetscDrawLine(draw, xr, yl, xr, yr, PETSC_DRAW_BLACK)); 530 PetscCall(PetscDrawLine(draw, xr, yr, xl, yr, PETSC_DRAW_BLACK)); 531 PetscCall(PetscDrawLine(draw, xl, yr, xl, yl, PETSC_DRAW_BLACK)); 532 for (i = 0; i < dim; i++) { 533 cl = lg->colors ? lg->colors[i] : (PETSC_DRAW_BLACK + i); 534 PetscCall(PetscDrawLine(draw, xl + 1 * tw, yr - (i + 1) * th, xl + 5 * tw, yr - (i + 1) * th, cl)); 535 PetscCall(PetscDrawString(draw, xl + 6 * tw, yr - (i + 1.5) * th, PETSC_DRAW_BLACK, lg->legend[i])); 536 } 537 } 538 PetscDrawCollectiveEnd(draw); 539 540 PetscCall(PetscDrawFlush(draw)); 541 PetscCall(PetscDrawPause(draw)); 542 PetscFunctionReturn(PETSC_SUCCESS); 543 } 544 545 /*@ 546 PetscDrawLGSave - Saves a drawn image 547 548 Collective 549 550 Input Parameter: 551 . lg - The line graph context 552 553 Level: intermediate 554 555 .seealso: `PetscDrawLG`, `PetscDrawSave()`, `PetscDrawLGCreate()`, `PetscDrawLGGetDraw()`, `PetscDrawSetSave()` 556 @*/ 557 PetscErrorCode PetscDrawLGSave(PetscDrawLG lg) 558 { 559 PetscFunctionBegin; 560 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 561 PetscCall(PetscDrawSave(lg->win)); 562 PetscFunctionReturn(PETSC_SUCCESS); 563 } 564 565 /*@ 566 PetscDrawLGView - Prints a line graph. 567 568 Collective 569 570 Input Parameters: 571 + lg - the line graph context 572 - viewer - the viewer to view it with 573 574 Level: beginner 575 576 .seealso: `PetscDrawLG`, `PetscDrawLGCreate()` 577 @*/ 578 PetscErrorCode PetscDrawLGView(PetscDrawLG lg, PetscViewer viewer) 579 { 580 PetscReal xmin = lg->xmin, xmax = lg->xmax, ymin = lg->ymin, ymax = lg->ymax; 581 PetscInt i, j, dim = lg->dim, nopts = lg->nopts; 582 583 PetscFunctionBegin; 584 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 585 586 if (nopts < 1) PetscFunctionReturn(PETSC_SUCCESS); 587 if (xmin > xmax || ymin > ymax) PetscFunctionReturn(PETSC_SUCCESS); 588 589 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg), &viewer)); 590 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)lg, viewer)); 591 for (i = 0; i < dim; i++) { 592 PetscCall(PetscViewerASCIIPrintf(viewer, "Line %" PetscInt_FMT ">\n", i)); 593 for (j = 0; j < nopts; j++) PetscCall(PetscViewerASCIIPrintf(viewer, " X: %g Y: %g\n", (double)lg->x[j * dim + i], (double)lg->y[j * dim + i])); 594 } 595 PetscFunctionReturn(PETSC_SUCCESS); 596 } 597 598 /*@ 599 PetscDrawLGSetOptionsPrefix - Sets the prefix used for searching for all 600 `PetscDrawLG` options in the database. 601 602 Logically Collective 603 604 Input Parameters: 605 + lg - the line graph context 606 - prefix - the prefix to prepend to all option names 607 608 Level: advanced 609 610 .seealso: `PetscDrawLG`, `PetscDrawLGSetFromOptions()`, `PetscDrawLGCreate()` 611 @*/ 612 PetscErrorCode PetscDrawLGSetOptionsPrefix(PetscDrawLG lg, const char prefix[]) 613 { 614 PetscFunctionBegin; 615 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 616 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)lg, prefix)); 617 PetscFunctionReturn(PETSC_SUCCESS); 618 } 619 620 /*@ 621 PetscDrawLGSetFromOptions - Sets options related to the line graph object 622 623 Collective 624 625 Input Parameters: 626 . lg - the line graph context 627 628 Options Database Key: 629 . -lg_use_markers <true,false> - true means it draws a marker for each point 630 631 Level: intermediate 632 633 .seealso: `PetscDrawLG`, `PetscDrawLGDestroy()`, `PetscDrawLGCreate()` 634 @*/ 635 PetscErrorCode PetscDrawLGSetFromOptions(PetscDrawLG lg) 636 { 637 PetscBool usemarkers, set; 638 PetscDrawMarkerType markertype; 639 640 PetscFunctionBegin; 641 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 642 643 PetscCall(PetscDrawGetMarkerType(lg->win, &markertype)); 644 PetscCall(PetscOptionsGetEnum(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_marker_type", PetscDrawMarkerTypes, (PetscEnum *)&markertype, &set)); 645 if (set) { 646 PetscCall(PetscDrawLGSetUseMarkers(lg, PETSC_TRUE)); 647 PetscCall(PetscDrawSetMarkerType(lg->win, markertype)); 648 } 649 usemarkers = lg->use_markers; 650 PetscCall(PetscOptionsGetBool(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_use_markers", &usemarkers, &set)); 651 if (set) PetscCall(PetscDrawLGSetUseMarkers(lg, usemarkers)); 652 PetscFunctionReturn(PETSC_SUCCESS); 653 } 654