Actual source code: draw.c


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

  5: PetscClassId PETSC_DRAW_CLASSID;

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

 12:   Level: developer

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

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

 30:   Level: developer

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

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

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

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

 84:    Collective

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

 91:    Level: intermediate

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

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

108:    Not Collective

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

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

117:    Level: intermediate

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

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

135:    Collective

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

140:    Level: advanced

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

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

155:    Not Collective

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

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

163:    Level: intermediate

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

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

179:    Collective

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

185:    Level: intermediate

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

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

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

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

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

212:    Collective

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

218:    Level: advanced

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

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

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

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

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

264:    Collective

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

269:    Level: beginner

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

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

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

288:   PetscCall(PetscDrawDestroy_Private(*draw));

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

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

305:    Collective

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

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

313:    Level: advanced

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

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

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

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

342:   Level: advanced

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

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

357:    Logically Collective

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

362:    Level: intermediate

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

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

378:    Collective

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

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

386:    Level: advanced

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

394:   PetscFunctionBegin;

398:   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
399:   if (size == 1) {
400:     PetscCall(PetscObjectReference((PetscObject)draw));
401:     *sdraw = draw;
402:   } else {
403:     if (draw->ops->getsingleton) {
404:       PetscUseTypeMethod(draw, getsingleton, sdraw);
405:     } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot get singleton for this type %s of draw object", ((PetscObject)draw)->type_name);
406:   }
407:   PetscFunctionReturn(PETSC_SUCCESS);
408: }

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

414:    Collective

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

420:    Level: advanced

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

428:   PetscFunctionBegin;

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

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

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

450:   Level: intermediate

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