Actual source code: draw.c

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

  3: PetscClassId PETSC_DRAW_CLASSID;

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

 10:   Level: developer

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

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

 28:   Level: developer

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

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

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

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

 82:   Collective

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

 89:   Level: intermediate

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

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

106:   Not Collective

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

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

115:   Level: intermediate

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

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

133:   Collective

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

138:   Level: advanced

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

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

153:   Not Collective

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

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

161:   Level: intermediate

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

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

177:   Collective

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

183:   Level: intermediate

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

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

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

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

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

210:   Collective

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

216:   Level: advanced

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

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

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

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

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

262:   Collective

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

267:   Level: beginner

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

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

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

286:   PetscCall(PetscDrawDestroy_Private(*draw));

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

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

303:   Collective

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

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

311:   Level: advanced

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

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

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

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

340:   Level: advanced

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

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

355:   Logically Collective

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

360:   Level: intermediate

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

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

376:   Collective

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

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

384:   Level: advanced

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

392:   PetscFunctionBegin;
394:   PetscAssertPointer(sdraw, 2);

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

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

408:   Collective

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

414:   Level: advanced

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

422:   PetscFunctionBegin;
424:   PetscAssertPointer(sdraw, 2);

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

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

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

443:   Level: intermediate

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