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