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 {
402:     if (draw->ops->getsingleton) {
403:       PetscUseTypeMethod(draw, getsingleton, sdraw);
404:     } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot get singleton for this type %s of draw object", ((PetscObject)draw)->type_name);
405:   }
406:   PetscFunctionReturn(PETSC_SUCCESS);
407: }

409: /*@
410:   PetscDrawRestoreSingleton - Remove access to a `PetscDraw` object obtained with `PetscDrawGetSingleton()`
411:   by the one process.

413:   Collective

415:   Input Parameters:
416: + draw  - the original window
417: - sdraw - the singleton window

419:   Level: advanced

421: .seealso: `PetscDraw`, `PetscDrawGetSingleton()`, `PetscViewerGetSingleton()`, `PetscViewerRestoreSingleton()`
422: @*/
423: PetscErrorCode PetscDrawRestoreSingleton(PetscDraw draw, PetscDraw *sdraw)
424: {
425:   PetscMPIInt size;

427:   PetscFunctionBegin;
429:   PetscAssertPointer(sdraw, 2);

432:   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
433:   if (size == 1) {
434:     if (draw == *sdraw) {
435:       PetscCall(PetscObjectDereference((PetscObject)draw));
436:       *sdraw = NULL;
437:     } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cannot restore singleton, it is not the parent draw");
438:   } else PetscUseTypeMethod(draw, restoresingleton, sdraw);
439:   PetscFunctionReturn(PETSC_SUCCESS);
440: }

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

445:   Input Parameters:
446: + draw    - the drawing window
447: - visible - if the surface should be visible

449:   Level: intermediate

451: .seealso: `PetscDraw`
452: @*/
453: PetscErrorCode PetscDrawSetVisible(PetscDraw draw, PetscBool visible)
454: {
455:   PetscFunctionBegin;
457:   PetscTryTypeMethod(draw, setvisible, visible);
458:   PetscFunctionReturn(PETSC_SUCCESS);
459: }