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 /*@ 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 // Try not to freak out the axis 448 if (ymax - ymin < PETSC_SMALL) { 449 ymin -= 0.1 * ymax; 450 ymax += 0.1 * ymax; 451 } 452 PetscCall(PetscDrawAxisSetLimits(lg->axis, xmin, xmax, ymin, ymax)); 453 PetscCall(PetscDrawAxisDraw(lg->axis)); 454 455 PetscDrawCollectiveBegin(draw); 456 if (rank == 0) { 457 int i, j, dim = lg->dim, nopts = lg->nopts, cl; 458 for (i = 0; i < dim; i++) { 459 for (j = 1; j < nopts; j++) { 460 cl = lg->colors ? lg->colors[i] : ((PETSC_DRAW_BLACK + i) % PETSC_DRAW_MAXCOLOR); 461 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)); 462 if (lg->use_markers) PetscCall(PetscDrawMarker(draw, lg->x[j * dim + i], lg->y[j * dim + i], cl)); 463 } 464 } 465 } 466 if (rank == 0 && lg->legend) { 467 PetscBool right = PETSC_FALSE; 468 int i, dim = lg->dim, cl; 469 PetscReal xl, yl, xr, yr, tw, th; 470 size_t slen, len = 0; 471 472 PetscCall(PetscDrawAxisGetLimits(lg->axis, &xl, &xr, &yl, &yr)); 473 PetscCall(PetscDrawStringGetSize(draw, &tw, &th)); 474 for (i = 0; i < dim; i++) { 475 PetscCall(PetscStrlen(lg->legend[i], &slen)); 476 len = PetscMax(len, slen); 477 } 478 if (right) { 479 xr = xr - 1.5 * tw; 480 xl = xr - ((PetscReal)len + 7) * tw; 481 } else { 482 xl = xl + 1.5 * tw; 483 xr = xl + ((PetscReal)len + 7) * tw; 484 } 485 yr = yr - 1.0 * th; 486 yl = yr - (dim + 1) * th; 487 PetscCall(PetscDrawLine(draw, xl, yl, xr, yl, PETSC_DRAW_BLACK)); 488 PetscCall(PetscDrawLine(draw, xr, yl, xr, yr, PETSC_DRAW_BLACK)); 489 PetscCall(PetscDrawLine(draw, xr, yr, xl, yr, PETSC_DRAW_BLACK)); 490 PetscCall(PetscDrawLine(draw, xl, yr, xl, yl, PETSC_DRAW_BLACK)); 491 for (i = 0; i < dim; i++) { 492 cl = lg->colors ? lg->colors[i] : (PETSC_DRAW_BLACK + i); 493 PetscCall(PetscDrawLine(draw, xl + 1 * tw, yr - (i + 1) * th, xl + 5 * tw, yr - (i + 1) * th, cl)); 494 PetscCall(PetscDrawString(draw, xl + 6 * tw, yr - (i + 1.5) * th, PETSC_DRAW_BLACK, lg->legend[i])); 495 } 496 } 497 PetscDrawCollectiveEnd(draw); 498 499 PetscCall(PetscDrawFlush(draw)); 500 PetscCall(PetscDrawPause(draw)); 501 PetscFunctionReturn(PETSC_SUCCESS); 502 } 503 504 /*@ 505 PetscDrawLGSave - Saves a drawn image 506 507 Collective 508 509 Input Parameter: 510 . lg - The line graph context 511 512 Level: intermediate 513 514 .seealso: `PetscDrawLG`, `PetscDrawSave()`, `PetscDrawLGCreate()`, `PetscDrawLGGetDraw()`, `PetscDrawSetSave()` 515 @*/ 516 PetscErrorCode PetscDrawLGSave(PetscDrawLG lg) 517 { 518 PetscFunctionBegin; 519 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 520 PetscCall(PetscDrawSave(lg->win)); 521 PetscFunctionReturn(PETSC_SUCCESS); 522 } 523 524 /*@ 525 PetscDrawLGView - Prints a line graph. 526 527 Collective 528 529 Input Parameters: 530 + lg - the line graph context 531 - viewer - the viewer to view it with 532 533 Level: beginner 534 535 .seealso: `PetscDrawLG`, `PetscDrawLGCreate()` 536 @*/ 537 PetscErrorCode PetscDrawLGView(PetscDrawLG lg, PetscViewer viewer) 538 { 539 PetscReal xmin = lg->xmin, xmax = lg->xmax, ymin = lg->ymin, ymax = lg->ymax; 540 PetscInt i, j, dim = lg->dim, nopts = lg->nopts; 541 542 PetscFunctionBegin; 543 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 544 545 if (nopts < 1) PetscFunctionReturn(PETSC_SUCCESS); 546 if (xmin > xmax || ymin > ymax) PetscFunctionReturn(PETSC_SUCCESS); 547 548 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg), &viewer)); 549 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)lg, viewer)); 550 for (i = 0; i < dim; i++) { 551 PetscCall(PetscViewerASCIIPrintf(viewer, "Line %" PetscInt_FMT ">\n", i)); 552 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])); 553 } 554 PetscFunctionReturn(PETSC_SUCCESS); 555 } 556 557 /*@ 558 PetscDrawLGSetOptionsPrefix - Sets the prefix used for searching for all 559 `PetscDrawLG` options in the database. 560 561 Logically Collective 562 563 Input Parameters: 564 + lg - the line graph context 565 - prefix - the prefix to prepend to all option names 566 567 Level: advanced 568 569 .seealso: `PetscDrawLG`, `PetscDrawLGSetFromOptions()`, `PetscDrawLGCreate()` 570 @*/ 571 PetscErrorCode PetscDrawLGSetOptionsPrefix(PetscDrawLG lg, const char prefix[]) 572 { 573 PetscFunctionBegin; 574 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 575 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)lg, prefix)); 576 PetscFunctionReturn(PETSC_SUCCESS); 577 } 578 579 /*@ 580 PetscDrawLGSetFromOptions - Sets options related to the line graph object 581 582 Collective 583 584 Input Parameters: 585 . lg - the line graph context 586 587 Options Database Key: 588 . -lg_use_markers <true,false> - true means it draws a marker for each point 589 590 Level: intermediate 591 592 .seealso: `PetscDrawLG`, `PetscDrawLGDestroy()`, `PetscDrawLGCreate()` 593 @*/ 594 PetscErrorCode PetscDrawLGSetFromOptions(PetscDrawLG lg) 595 { 596 PetscBool usemarkers, set; 597 PetscDrawMarkerType markertype; 598 599 PetscFunctionBegin; 600 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 1); 601 602 PetscCall(PetscDrawGetMarkerType(lg->win, &markertype)); 603 PetscCall(PetscOptionsGetEnum(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_marker_type", PetscDrawMarkerTypes, (PetscEnum *)&markertype, &set)); 604 if (set) { 605 PetscCall(PetscDrawLGSetUseMarkers(lg, PETSC_TRUE)); 606 PetscCall(PetscDrawSetMarkerType(lg->win, markertype)); 607 } 608 usemarkers = lg->use_markers; 609 PetscCall(PetscOptionsGetBool(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_use_markers", &usemarkers, &set)); 610 if (set) PetscCall(PetscDrawLGSetUseMarkers(lg, usemarkers)); 611 PetscFunctionReturn(PETSC_SUCCESS); 612 } 613