Date: 2026-03-31T05:46:28+00:00

Actual source code: draw.c

      1: #include <petsc/private/drawimpl.h>
      2: #include <petscviewer.h>

      4: PetscClassId PETSC_DRAW_CLASSID;

      6: static PetscBool PetscDrawPackageInitialized = PETSC_FALSE;
      7: /*@C
      8:   PetscDrawFinalizePackage - This function destroys everything in the PETSc interface to the `PetscDraw` package. It is
      9:   called from `PetscFinalize()`.

     11:   Level: developer

     13: .seealso: `PetscDraw`, `PetscFinalize()`
     14: @*/
     15: PetscErrorCode PetscDrawFinalizePackage(void)
     16: {
     17:   PetscFunctionBegin;
     18:   PetscCall(PetscFunctionListDestroy(&PetscDrawList));
     19:   PetscDrawPackageInitialized = PETSC_FALSE;
     20:   PetscDrawRegisterAllCalled  = PETSC_FALSE;
     21:   PetscFunctionReturn(PETSC_SUCCESS);
     22: }

     24: /*@C
     25:   PetscDrawInitializePackage - This function initializes everything in the `PetscDraw` package. It is called
     26:   from PetscDLLibraryRegister_petsc() when using dynamic libraries, and on the call to `PetscInitialize()`
     27:   when using shared or static libraries.

     29:   Level: developer

     31: .seealso: `PetscDraw`, `PetscInitialize()`
     32: @*/
     33: PetscErrorCode PetscDrawInitializePackage(void)
     34: {
     35:   char      logList[256];
     36:   PetscBool opt, pkg;

     38:   PetscFunctionBegin;
     39:   if (PetscDrawPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
     40:   PetscDrawPackageInitialized = PETSC_TRUE;
     41:   /* Register Classes */
     42:   PetscCall(PetscClassIdRegister("Draw", &PETSC_DRAW_CLASSID));
     43:   PetscCall(PetscClassIdRegister("Draw Axis", &PETSC_DRAWAXIS_CLASSID));
     44:   PetscCall(PetscClassIdRegister("Line Graph", &PETSC_DRAWLG_CLASSID));
     45:   PetscCall(PetscClassIdRegister("Histogram", &PETSC_DRAWHG_CLASSID));
     46:   PetscCall(PetscClassIdRegister("Bar Graph", &PETSC_DRAWBAR_CLASSID));
     47:   PetscCall(PetscClassIdRegister("Scatter Plot", &PETSC_DRAWSP_CLASSID));
     48:   /* Register Constructors */
     49:   PetscCall(PetscDrawRegisterAll());
     50:   /* Process Info */
     51:   {
     52:     PetscClassId classids[6];

     54:     classids[0] = PETSC_DRAW_CLASSID;
     55:     classids[1] = PETSC_DRAWAXIS_CLASSID;
     56:     classids[2] = PETSC_DRAWLG_CLASSID;
     57:     classids[3] = PETSC_DRAWHG_CLASSID;
     58:     classids[4] = PETSC_DRAWBAR_CLASSID;
     59:     classids[5] = PETSC_DRAWSP_CLASSID;
     60:     PetscCall(PetscInfoProcessClass("draw", 6, classids));
     61:   }
     62:   /* Process summary exclusions */
     63:   PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt));
     64:   if (opt) {
     65:     PetscCall(PetscStrInList("draw", logList, ',', &pkg));
     66:     if (pkg) {
     67:       PetscCall(PetscLogEventExcludeClass(PETSC_DRAW_CLASSID));
     68:       PetscCall(PetscLogEventExcludeClass(PETSC_DRAWAXIS_CLASSID));
     69:       PetscCall(PetscLogEventExcludeClass(PETSC_DRAWLG_CLASSID));
     70:       PetscCall(PetscLogEventExcludeClass(PETSC_DRAWHG_CLASSID));
     71:       PetscCall(PetscLogEventExcludeClass(PETSC_DRAWBAR_CLASSID));
     72:       PetscCall(PetscLogEventExcludeClass(PETSC_DRAWSP_CLASSID));
     73:     }
     74:   }
     75:   /* Register package finalizer */
     76:   PetscCall(PetscRegisterFinalize(PetscDrawFinalizePackage));
     77:   PetscFunctionReturn(PETSC_SUCCESS);
     78: }

     80: /*@
     81:   PetscDrawResizeWindow - Allows one to resize a window from a program.

     83:   Collective

     85:   Input Parameters:
     86: + draw - the window
     87: . w    - the new width of the window
     88: - h    - the new height of the window

     90:   Level: intermediate

     92: .seealso: `PetscDraw`, `PetscDrawCheckResizedWindow()`
     93: @*/
     94: PetscErrorCode PetscDrawResizeWindow(PetscDraw draw, int w, int h)
     95: {
     96:   PetscFunctionBegin;
    100:   PetscTryTypeMethod(draw, resizewindow, w, h);
    101:   PetscFunctionReturn(PETSC_SUCCESS);
    102: }

    104: /*@
    105:   PetscDrawGetWindowSize - Gets the size of the window.

    107:   Not Collective

    109:   Input Parameter:
    110: . draw - the window

    112:   Output Parameters:
    113: + w - the window width
    114: - h - the window height

    116:   Level: intermediate

    118: .seealso: `PetscDraw`, `PetscDrawResizeWindow()`, `PetscDrawCheckResizedWindow()`
    119: @*/
    120: PetscErrorCode PetscDrawGetWindowSize(PetscDraw draw, int *w, int *h)
    121: {
    122:   PetscFunctionBegin;
    124:   if (w) PetscAssertPointer(w, 2);
    125:   if (h) PetscAssertPointer(h, 3);
    126:   if (w) *w = draw->w;
    127:   if (h) *h = draw->h;
    128:   PetscFunctionReturn(PETSC_SUCCESS);
    129: }

    131: /*@
    132:   PetscDrawCheckResizedWindow - Checks if the user has resized the window.

    134:   Collective

    136:   Input Parameter:
    137: . draw - the window

    139:   Level: advanced

    141: .seealso: `PetscDraw`, `PetscDrawResizeWindow()`
    142: @*/
    143: PetscErrorCode PetscDrawCheckResizedWindow(PetscDraw draw)
    144: {
    145:   PetscFunctionBegin;
    147:   PetscTryTypeMethod(draw, checkresizedwindow);
    148:   PetscFunctionReturn(PETSC_SUCCESS);
    149: }

    151: /*@
    152:   PetscDrawGetTitle - Gets pointer to title of a `PetscDraw` context.

    154:   Not Collective

    156:   Input Parameter:
    157: . draw - the graphics context

    159:   Output Parameter:
    160: . title - the title

    162:   Level: intermediate

    164: .seealso: `PetscDraw`, `PetscDrawSetTitle()`
    165: @*/
    166: PetscErrorCode PetscDrawGetTitle(PetscDraw draw, const char *title[])
    167: {
    168:   PetscFunctionBegin;
    170:   PetscAssertPointer(title, 2);
    171:   *title = draw->title;
    172:   PetscFunctionReturn(PETSC_SUCCESS);
    173: }

    175: /*@
    176:   PetscDrawSetTitle - Sets the title of a `PetscDraw` context.

    178:   Collective

    180:   Input Parameters:
    181: + draw  - the graphics context
    182: - title - the title

    184:   Level: intermediate

    186:   Notes:
    187:   The title is positioned in the windowing system title bar for the window. Hence it will not be saved with -draw_save
    188:   in the image.

    190:   A copy of the string is made, so you may destroy the
    191:   title string after calling this routine.

    193:   You can use `PetscDrawAxisSetLabels()` to indicate a title within the window

    195: .seealso: `PetscDraw`, `PetscDrawGetTitle()`, `PetscDrawAppendTitle()`
    196: @*/
    197: PetscErrorCode PetscDrawSetTitle(PetscDraw draw, const char title[])
    198: {
    199:   PetscFunctionBegin;
    201:   PetscAssertPointer(title, 2);
    202:   PetscCall(PetscFree(draw->title));
    203:   PetscCall(PetscStrallocpy(title, &draw->title));
    204:   PetscTryTypeMethod(draw, settitle, draw->title);
    205:   PetscFunctionReturn(PETSC_SUCCESS);
    206: }

    208: /*@
    209:   PetscDrawAppendTitle - Appends to the title of a `PetscDraw` context.

    211:   Collective

    213:   Input Parameters:
    214: + draw  - the graphics context
    215: - title - the title

    217:   Level: advanced

    219:   Note:
    220:   A copy of the string is made, so you may destroy the
    221:   title string after calling this routine.

    223: .seealso: `PetscDraw`, `PetscDrawSetTitle()`, `PetscDrawGetTitle()`
    224: @*/
    225: PetscErrorCode PetscDrawAppendTitle(PetscDraw draw, const char title[])
    226: {
    227:   PetscFunctionBegin;
    229:   if (title) PetscAssertPointer(title, 2);
    230:   if (!title || !title[0]) PetscFunctionReturn(PETSC_SUCCESS);

    232:   if (draw->title) {
    233:     size_t len1, len2, new_len;
    234:     PetscCall(PetscStrlen(draw->title, &len1));
    235:     PetscCall(PetscStrlen(title, &len2));
    236:     new_len = len1 + len2 + 1;
    237:     PetscCall(PetscRealloc(new_len * sizeof(*draw->title), &draw->title));
    238:     PetscCall(PetscStrncpy(draw->title + len1, title, len2 + 1));
    239:   } else {
    240:     PetscCall(PetscStrallocpy(title, &draw->title));
    241:   }
    242:   PetscTryTypeMethod(draw, settitle, draw->title);
    243:   PetscFunctionReturn(PETSC_SUCCESS);
    244: }

    246: static PetscErrorCode PetscDrawDestroy_Private(PetscDraw draw)
    247: {
    248:   PetscFunctionBegin;
    249:   if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(PETSC_SUCCESS);
    250:   PetscCall(PetscDrawSaveMovie(draw));
    251:   if (draw->savefinalfilename) {
    252:     draw->savesinglefile = PETSC_TRUE;
    253:     PetscCall(PetscDrawSetSave(draw, draw->savefinalfilename));
    254:     PetscCall(PetscDrawSave(draw));
    255:   }
    256:   PetscCall(PetscBarrier((PetscObject)draw));
    257:   PetscFunctionReturn(PETSC_SUCCESS);
    258: }

    260: /*@
    261:   PetscDrawDestroy - Deletes a draw context.

    263:   Collective

    265:   Input Parameter:
    266: . draw - the drawing context

    268:   Level: beginner

    270: .seealso: `PetscDraw`, `PetscDrawCreate()`
    271: @*/
    272: PetscErrorCode PetscDrawDestroy(PetscDraw *draw)
    273: {
    274:   PetscFunctionBegin;
    275:   if (!*draw) PetscFunctionReturn(PETSC_SUCCESS);
    277:   if (--((PetscObject)*draw)->refct > 0) PetscFunctionReturn(PETSC_SUCCESS);

    279:   if ((*draw)->pause == -2) {
    280:     (*draw)->pause = -1;
    281:     PetscCall(PetscDrawPause(*draw));
    282:   }

    284:   /* if memory was published then destroy it */
    285:   PetscCall(PetscObjectSAWsViewOff((PetscObject)*draw));

    287:   PetscCall(PetscDrawDestroy_Private(*draw));

    289:   PetscTryTypeMethod(*draw, destroy);
    290:   PetscCall(PetscDrawDestroy(&(*draw)->popup));
    291:   PetscCall(PetscFree((*draw)->title));
    292:   PetscCall(PetscFree((*draw)->display));
    293:   PetscCall(PetscFree((*draw)->savefilename));
    294:   PetscCall(PetscFree((*draw)->saveimageext));
    295:   PetscCall(PetscFree((*draw)->savemovieext));
    296:   PetscCall(PetscFree((*draw)->savefinalfilename));
    297:   PetscCall(PetscHeaderDestroy(draw));
    298:   PetscFunctionReturn(PETSC_SUCCESS);
    299: }

    301: /*@
    302:   PetscDrawGetPopup - Creates a popup window associated with a `PetscDraw` window.

    304:   Collective

    306:   Input Parameter:
    307: . draw - the original window

    309:   Output Parameter:
    310: . popup - the new popup window

    312:   Level: advanced

    314: .seealso: `PetscDraw`, `PetscDrawScalePopup()`, `PetscDrawCreate()`
    315: @*/
    316: PetscErrorCode PetscDrawGetPopup(PetscDraw draw, PetscDraw *popup)
    317: {
    318:   PetscFunctionBegin;
    320:   PetscAssertPointer(popup, 2);

    322:   if (draw->popup) *popup = draw->popup;
    323:   else if (draw->ops->getpopup) {
    324:     PetscUseTypeMethod(draw, getpopup, popup);
    325:     if (*popup) {
    326:       PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_"));
    327:       (*popup)->pause = 0.0;
    328:       PetscCall(PetscDrawSetFromOptions(*popup));
    329:     }
    330:   } else *popup = NULL;
    331:   PetscFunctionReturn(PETSC_SUCCESS);
    332: }

    334: /*@
    335:   PetscDrawSetDisplay - Sets the display where a `PetscDraw` object will be displayed

    337:   Input Parameters:
    338: + draw    - the drawing context
    339: - display - the X windows display

    341:   Level: advanced

    343: .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()`
    344: @*/
    345: PetscErrorCode PetscDrawSetDisplay(PetscDraw draw, const char display[])
    346: {
    347:   PetscFunctionBegin;
    348:   PetscCall(PetscFree(draw->display));
    349:   PetscCall(PetscStrallocpy(display, &draw->display));
    350:   PetscFunctionReturn(PETSC_SUCCESS);
    351: }

    353: /*@
    354:   PetscDrawSetDoubleBuffer - Sets a window to be double buffered.

    356:   Logically Collective

    358:   Input Parameter:
    359: . draw - the drawing context

    361:   Level: intermediate

    363: .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawCreate()`
    364: @*/
    365: PetscErrorCode PetscDrawSetDoubleBuffer(PetscDraw draw)
    366: {
    367:   PetscFunctionBegin;
    369:   PetscTryTypeMethod(draw, setdoublebuffer);
    370:   PetscFunctionReturn(PETSC_SUCCESS);
    371: }

    373: /*@
    374:   PetscDrawGetSingleton - Gain access to a `PetscDraw` object as if it were owned
    375:   by the one process.

    377:   Collective

    379:   Input Parameter:
    380: . draw - the original window

    382:   Output Parameter:
    383: . sdraw - the singleton window

    385:   Level: advanced

    387: .seealso: `PetscDraw`, `PetscDrawRestoreSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()`
    388: @*/
    389: PetscErrorCode PetscDrawGetSingleton(PetscDraw draw, PetscDraw *sdraw)
    390: {
    391:   PetscMPIInt size;

    393:   PetscFunctionBegin;
    395:   PetscAssertPointer(sdraw, 2);

    397:   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
    398:   if (size == 1) {
    399:     PetscCall(PetscObjectReference((PetscObject)draw));
    400:     *sdraw = draw;
    401:   } else PetscUseTypeMethod(draw, getsingleton, sdraw);
    402:   PetscFunctionReturn(PETSC_SUCCESS);
    403: }

    405: /*@
    406:   PetscDrawRestoreSingleton - Remove access to a `PetscDraw` object obtained with `PetscDrawGetSingleton()`
    407:   by the one process.

    409:   Collective

    411:   Input Parameters:
    412: + draw  - the original window
    413: - sdraw - the singleton window

    415:   Level: advanced

    417: .seealso: `PetscDraw`, `PetscDrawGetSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()`
    418: @*/
    419: PetscErrorCode PetscDrawRestoreSingleton(PetscDraw draw, PetscDraw *sdraw)
    420: {
    421:   PetscMPIInt size;

    423:   PetscFunctionBegin;
    425:   PetscAssertPointer(sdraw, 2);

    428:   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
    429:   if (size == 1) {
    430:     PetscCheck(draw == *sdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot restore singleton, it is not the parent draw");
    431:     PetscCall(PetscObjectDereference((PetscObject)draw));
    432:     *sdraw = NULL;
    433:   } else PetscUseTypeMethod(draw, restoresingleton, sdraw);
    434:   PetscFunctionReturn(PETSC_SUCCESS);
    435: }

    437: /*@
    438:   PetscDrawSetVisible - Sets if the drawing surface (the 'window') is visible on its display.

    440:   Input Parameters:
    441: + draw    - the drawing window
    442: - visible - if the surface should be visible

    444:   Level: intermediate

    446: .seealso: `PetscDraw`
    447: @*/
    448: PetscErrorCode PetscDrawSetVisible(PetscDraw draw, PetscBool visible)
    449: {
    450:   PetscFunctionBegin;
    452:   PetscTryTypeMethod(draw, setvisible, visible);
    453:   PetscFunctionReturn(PETSC_SUCCESS);
    454: }