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 189 190 Level: intermediate 191 192 .seealso: `PetscDrawLG`, `PetscDrawLGCreate()` 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 /*@ 300 PetscDrawLGSetLimits - Sets the axis limits for a line graph. If more 301 points are added after this call, the limits will be adjusted to 302 include those additional points. 303 304 Logically Collective 305 306 Input Parameters: 307 + lg - the line graph context 308 . x_min - the horizontal lower limit 309 . x_max - the horizontal upper limit 310 . y_min - the vertical lower limit 311 - y_max - the vertical upper limit 312 313 Level: intermediate 314 315 .seealso: `PetscDrawLGCreate()`, `PetscDrawLG`, `PetscDrawAxis` 316 @*/ 317 PetscErrorCode PetscDrawLGSetLimits(PetscDrawLG lg, PetscReal x_min, PetscReal x_max, PetscReal y_min, PetscReal y_max) 318 { 319 PetscFunctionBegin; 320 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 321 322 (lg)->xmin = x_min; 323 (lg)->xmax = x_max; 324 (lg)->ymin = y_min; 325 (lg)->ymax = y_max; 326 PetscFunctionReturn(PETSC_SUCCESS); 327 } 328 329 /*@ 330 PetscDrawLGReset - Clears line graph to allow for reuse with new data. 331 332 Logically Collective 333 334 Input Parameter: 335 . lg - the line graph context. 336 337 Level: intermediate 338 339 .seealso: `PetscDrawLG`, `PetscDrawLGCreate()` 340 @*/ 341 PetscErrorCode PetscDrawLGReset(PetscDrawLG lg) 342 { 343 PetscFunctionBegin; 344 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 345 lg->xmin = 1.e20; 346 lg->ymin = 1.e20; 347 lg->xmax = -1.e20; 348 lg->ymax = -1.e20; 349 lg->loc = 0; 350 lg->nopts = 0; 351 PetscFunctionReturn(PETSC_SUCCESS); 352 } 353 354 /*@ 355 PetscDrawLGDestroy - Frees all space taken up by line graph data structure. 356 357 Collective 358 359 Input Parameter: 360 . lg - the line graph context 361 362 Level: intermediate 363 364 .seealso: `PetscDrawLG`, `PetscDrawLGCreate()` 365 @*/ 366 PetscErrorCode PetscDrawLGDestroy(PetscDrawLG *lg) 367 { 368 PetscInt i; 369 370 PetscFunctionBegin; 371 if (!*lg) PetscFunctionReturn(PETSC_SUCCESS); 372 PetscValidHeaderSpecific(*lg, PETSC_DRAWLG_CLASSID, 1); 373 if (--((PetscObject)*lg)->refct > 0) { 374 *lg = NULL; 375 PetscFunctionReturn(PETSC_SUCCESS); 376 } 377 378 if ((*lg)->legend) { 379 for (i = 0; i < (*lg)->dim; i++) PetscCall(PetscFree((*lg)->legend[i])); 380 PetscCall(PetscFree((*lg)->legend)); 381 } 382 PetscCall(PetscFree((*lg)->colors)); 383 PetscCall(PetscFree2((*lg)->x, (*lg)->y)); 384 PetscCall(PetscDrawAxisDestroy(&(*lg)->axis)); 385 PetscCall(PetscDrawDestroy(&(*lg)->win)); 386 PetscCall(PetscHeaderDestroy(lg)); 387 PetscFunctionReturn(PETSC_SUCCESS); 388 } 389 /*@ 390 PetscDrawLGSetUseMarkers - Causes the line graph object to draw a marker for each data-point. 391 392 Logically Collective 393 394 Input Parameters: 395 + lg - the linegraph context 396 - flg - should mark each data point 397 398 Options Database Key: 399 . -lg_use_markers <true,false> - true means it draws a marker for each point 400 401 Level: intermediate 402 403 .seealso: `PetscDrawLG`, `PetscDrawLGCreate()` 404 @*/ 405 PetscErrorCode PetscDrawLGSetUseMarkers(PetscDrawLG lg, PetscBool flg) 406 { 407 PetscFunctionBegin; 408 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 409 PetscValidLogicalCollectiveBool(lg, flg, 2); 410 lg->use_markers = flg; 411 PetscFunctionReturn(PETSC_SUCCESS); 412 } 413 414 /*@ 415 PetscDrawLGDraw - Redraws a line graph. 416 417 Collective 418 419 Input Parameter: 420 . lg - the line graph context 421 422 Level: intermediate 423 424 .seealso: `PetscDrawLG`, `PetscDrawSPDraw()`, `PetscDrawLGSPDraw()`, `PetscDrawLGReset()` 425 @*/ 426 PetscErrorCode PetscDrawLGDraw(PetscDrawLG lg) 427 { 428 PetscReal xmin, xmax, ymin, ymax; 429 PetscMPIInt rank; 430 PetscDraw draw; 431 PetscBool isnull; 432 433 PetscFunctionBegin; 434 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 435 PetscCall(PetscDrawIsNull(lg->win, &isnull)); 436 if (isnull) PetscFunctionReturn(PETSC_SUCCESS); 437 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)lg), &rank)); 438 439 draw = lg->win; 440 PetscCall(PetscDrawCheckResizedWindow(draw)); 441 PetscCall(PetscDrawClear(draw)); 442 443 xmin = lg->xmin; 444 xmax = lg->xmax; 445 ymin = lg->ymin; 446 ymax = lg->ymax; 447 PetscCall(PetscDrawAxisSetLimits(lg->axis, xmin, xmax, ymin, ymax)); 448 PetscCall(PetscDrawAxisDraw(lg->axis)); 449 450 PetscDrawCollectiveBegin(draw); 451 if (rank == 0) { 452 int i, j, dim = lg->dim, nopts = lg->nopts, cl; 453 for (i = 0; i < dim; i++) { 454 for (j = 1; j < nopts; j++) { 455 cl = lg->colors ? lg->colors[i] : ((PETSC_DRAW_BLACK + i) % PETSC_DRAW_MAXCOLOR); 456 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)); 457 if (lg->use_markers) PetscCall(PetscDrawMarker(draw, lg->x[j * dim + i], lg->y[j * dim + i], cl)); 458 } 459 } 460 } 461 if (rank == 0 && lg->legend) { 462 PetscBool right = PETSC_FALSE; 463 int i, dim = lg->dim, cl; 464 PetscReal xl, yl, xr, yr, tw, th; 465 size_t slen, len = 0; 466 467 PetscCall(PetscDrawAxisGetLimits(lg->axis, &xl, &xr, &yl, &yr)); 468 PetscCall(PetscDrawStringGetSize(draw, &tw, &th)); 469 for (i = 0; i < dim; i++) { 470 PetscCall(PetscStrlen(lg->legend[i], &slen)); 471 len = PetscMax(len, slen); 472 } 473 if (right) { 474 xr = xr - 1.5 * tw; 475 xl = xr - ((PetscReal)len + 7) * tw; 476 } else { 477 xl = xl + 1.5 * tw; 478 xr = xl + ((PetscReal)len + 7) * tw; 479 } 480 yr = yr - 1.0 * th; 481 yl = yr - (dim + 1) * th; 482 PetscCall(PetscDrawLine(draw, xl, yl, xr, yl, PETSC_DRAW_BLACK)); 483 PetscCall(PetscDrawLine(draw, xr, yl, xr, yr, PETSC_DRAW_BLACK)); 484 PetscCall(PetscDrawLine(draw, xr, yr, xl, yr, PETSC_DRAW_BLACK)); 485 PetscCall(PetscDrawLine(draw, xl, yr, xl, yl, PETSC_DRAW_BLACK)); 486 for (i = 0; i < dim; i++) { 487 cl = lg->colors ? lg->colors[i] : (PETSC_DRAW_BLACK + i); 488 PetscCall(PetscDrawLine(draw, xl + 1 * tw, yr - (i + 1) * th, xl + 5 * tw, yr - (i + 1) * th, cl)); 489 PetscCall(PetscDrawString(draw, xl + 6 * tw, yr - (i + 1.5) * th, PETSC_DRAW_BLACK, lg->legend[i])); 490 } 491 } 492 PetscDrawCollectiveEnd(draw); 493 494 PetscCall(PetscDrawFlush(draw)); 495 PetscCall(PetscDrawPause(draw)); 496 PetscFunctionReturn(PETSC_SUCCESS); 497 } 498 499 /*@ 500 PetscDrawLGSave - Saves a drawn image 501 502 Collective 503 504 Input Parameter: 505 . lg - The line graph context 506 507 Level: intermediate 508 509 .seealso: `PetscDrawLG`, `PetscDrawSave()`, `PetscDrawLGCreate()`, `PetscDrawLGGetDraw()`, `PetscDrawSetSave()` 510 @*/ 511 PetscErrorCode PetscDrawLGSave(PetscDrawLG lg) 512 { 513 PetscFunctionBegin; 514 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 515 PetscCall(PetscDrawSave(lg->win)); 516 PetscFunctionReturn(PETSC_SUCCESS); 517 } 518 519 /*@ 520 PetscDrawLGView - Prints a line graph. 521 522 Collective 523 524 Input Parameters: 525 + lg - the line graph context 526 - viewer - the viewer to view it with 527 528 Level: beginner 529 530 .seealso: `PetscDrawLG`, `PetscDrawLGCreate()` 531 @*/ 532 PetscErrorCode PetscDrawLGView(PetscDrawLG lg, PetscViewer viewer) 533 { 534 PetscReal xmin = lg->xmin, xmax = lg->xmax, ymin = lg->ymin, ymax = lg->ymax; 535 PetscInt i, j, dim = lg->dim, nopts = lg->nopts; 536 537 PetscFunctionBegin; 538 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 539 540 if (nopts < 1) PetscFunctionReturn(PETSC_SUCCESS); 541 if (xmin > xmax || ymin > ymax) PetscFunctionReturn(PETSC_SUCCESS); 542 543 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg), &viewer)); 544 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)lg, viewer)); 545 for (i = 0; i < dim; i++) { 546 PetscCall(PetscViewerASCIIPrintf(viewer, "Line %" PetscInt_FMT ">\n", i)); 547 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])); 548 } 549 PetscFunctionReturn(PETSC_SUCCESS); 550 } 551 552 /*@ 553 PetscDrawLGSetOptionsPrefix - Sets the prefix used for searching for all 554 `PetscDrawLG` options in the database. 555 556 Logically Collective 557 558 Input Parameters: 559 + lg - the line graph context 560 - prefix - the prefix to prepend to all option names 561 562 Level: advanced 563 564 .seealso: `PetscDrawLG`, `PetscDrawLGSetFromOptions()`, `PetscDrawLGCreate()` 565 @*/ 566 PetscErrorCode PetscDrawLGSetOptionsPrefix(PetscDrawLG lg, const char prefix[]) 567 { 568 PetscFunctionBegin; 569 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 570 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)lg, prefix)); 571 PetscFunctionReturn(PETSC_SUCCESS); 572 } 573 574 /*@ 575 PetscDrawLGSetFromOptions - Sets options related to the line graph object 576 577 Collective 578 579 Input Parameters: 580 . lg - the line graph context 581 582 Options Database Key: 583 . -lg_use_markers <true,false> - true means it draws a marker for each point 584 585 Level: intermediate 586 587 .seealso: `PetscDrawLG`, `PetscDrawLGDestroy()`, `PetscDrawLGCreate()` 588 @*/ 589 PetscErrorCode PetscDrawLGSetFromOptions(PetscDrawLG lg) 590 { 591 PetscBool usemarkers, set; 592 PetscDrawMarkerType markertype; 593 594 PetscFunctionBegin; 595 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 596 597 PetscCall(PetscDrawGetMarkerType(lg->win, &markertype)); 598 PetscCall(PetscOptionsGetEnum(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_marker_type", PetscDrawMarkerTypes, (PetscEnum *)&markertype, &set)); 599 if (set) { 600 PetscCall(PetscDrawLGSetUseMarkers(lg, PETSC_TRUE)); 601 PetscCall(PetscDrawSetMarkerType(lg->win, markertype)); 602 } 603 usemarkers = lg->use_markers; 604 PetscCall(PetscOptionsGetBool(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_use_markers", &usemarkers, &set)); 605 if (set) PetscCall(PetscDrawLGSetUseMarkers(lg, usemarkers)); 606 PetscFunctionReturn(PETSC_SUCCESS); 607 } 608