1 #include <../src/sys/classes/viewer/impls/draw/vdraw.h> /*I "petscdraw.h" I*/ 2 #include <petscviewer.h> /*I "petscviewer.h" I*/ 3 4 /*@ 5 PetscViewerDrawGetDraw - Returns `PetscDraw` object from `PETSCVIEWERDRAW` `PetscViewer` object. 6 This `PetscDraw` object may then be used to perform graphics using `PetscDraw` commands. 7 8 Collective 9 10 Input Parameters: 11 + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()` of type `PETSCVIEWERDRAW`) 12 - windownumber - indicates which subwindow (usually 0) to obtain 13 14 Output Parameter: 15 . draw - the draw object 16 17 Level: intermediate 18 19 .seealso: [](sec_viewers), `PETSCVIEWERDRAW`, `PetscViewerDrawGetLG()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()` 20 @*/ 21 PetscErrorCode PetscViewerDrawGetDraw(PetscViewer viewer, PetscInt windownumber, PetscDraw *draw) 22 { 23 PetscViewer_Draw *vdraw; 24 PetscBool isdraw; 25 26 PetscFunctionBegin; 27 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 28 PetscValidLogicalCollectiveInt(viewer, windownumber, 2); 29 if (draw) PetscAssertPointer(draw, 3); 30 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 31 PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer"); 32 PetscCheck(windownumber >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Window number cannot be negative"); 33 vdraw = (PetscViewer_Draw *)viewer->data; 34 35 windownumber += vdraw->draw_base; 36 if (windownumber >= vdraw->draw_max) { 37 /* allocate twice as many slots as needed */ 38 PetscInt draw_max = vdraw->draw_max; 39 PetscDraw *tdraw = vdraw->draw; 40 PetscDrawLG *drawlg = vdraw->drawlg; 41 PetscDrawAxis *drawaxis = vdraw->drawaxis; 42 43 vdraw->draw_max = 2 * windownumber; 44 45 PetscCall(PetscCalloc3(vdraw->draw_max, &vdraw->draw, vdraw->draw_max, &vdraw->drawlg, vdraw->draw_max, &vdraw->drawaxis)); 46 PetscCall(PetscArraycpy(vdraw->draw, tdraw, draw_max)); 47 PetscCall(PetscArraycpy(vdraw->drawlg, drawlg, draw_max)); 48 PetscCall(PetscArraycpy(vdraw->drawaxis, drawaxis, draw_max)); 49 PetscCall(PetscFree3(tdraw, drawlg, drawaxis)); 50 } 51 52 if (!vdraw->draw[windownumber]) { 53 char *title = vdraw->title, tmp_str[128]; 54 if (windownumber) { 55 PetscCall(PetscSNPrintf(tmp_str, sizeof(tmp_str), "%s:%" PetscInt_FMT, vdraw->title ? vdraw->title : "", windownumber)); 56 title = tmp_str; 57 } 58 PetscCall(PetscDrawCreate(PetscObjectComm((PetscObject)viewer), vdraw->display, title, PETSC_DECIDE, PETSC_DECIDE, vdraw->w, vdraw->h, &vdraw->draw[windownumber])); 59 if (vdraw->drawtype) PetscCall(PetscDrawSetType(vdraw->draw[windownumber], vdraw->drawtype)); 60 PetscCall(PetscDrawSetPause(vdraw->draw[windownumber], vdraw->pause)); 61 PetscCall(PetscDrawSetOptionsPrefix(vdraw->draw[windownumber], ((PetscObject)viewer)->prefix)); 62 PetscCall(PetscDrawSetFromOptions(vdraw->draw[windownumber])); 63 } 64 if (draw) *draw = vdraw->draw[windownumber]; 65 if (draw) PetscValidHeaderSpecific(*draw, PETSC_DRAW_CLASSID, 3); 66 PetscFunctionReturn(PETSC_SUCCESS); 67 } 68 69 /*@ 70 PetscViewerDrawGetDrawLG - Returns a `PetscDrawLG` object from `PetscViewer` object of type `PETSCVIEWERDRAW`. 71 This `PetscDrawLG` object may then be used to perform graphics using `PetscDrawLG` commands. 72 73 Collective 74 75 Input Parameters: 76 + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`) 77 - windownumber - indicates which subwindow (usually 0) 78 79 Output Parameter: 80 . drawlg - the draw line graph object 81 82 Level: intermediate 83 84 Note: 85 A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows 86 87 .seealso: [](sec_viewers), `PetscDrawLG`, `PetscViewerDrawGetDraw()`, `PetscViewerDrawGetAxis()`, `PetscViewerDrawOpen()` 88 @*/ 89 PetscErrorCode PetscViewerDrawGetDrawLG(PetscViewer viewer, PetscInt windownumber, PetscDrawLG *drawlg) 90 { 91 PetscBool isdraw; 92 PetscViewer_Draw *vdraw; 93 94 PetscFunctionBegin; 95 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 96 PetscValidLogicalCollectiveInt(viewer, windownumber, 2); 97 PetscAssertPointer(drawlg, 3); 98 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 99 PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer"); 100 PetscCheck(windownumber >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Window number cannot be negative"); 101 vdraw = (PetscViewer_Draw *)viewer->data; 102 103 if (windownumber + vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber + vdraw->draw_base]) PetscCall(PetscViewerDrawGetDraw(viewer, windownumber, NULL)); 104 if (!vdraw->drawlg[windownumber + vdraw->draw_base]) { 105 PetscCall(PetscDrawLGCreate(vdraw->draw[windownumber + vdraw->draw_base], 1, &vdraw->drawlg[windownumber + vdraw->draw_base])); 106 PetscCall(PetscDrawLGSetFromOptions(vdraw->drawlg[windownumber + vdraw->draw_base])); 107 } 108 *drawlg = vdraw->drawlg[windownumber + vdraw->draw_base]; 109 PetscFunctionReturn(PETSC_SUCCESS); 110 } 111 112 /*@ 113 PetscViewerDrawGetDrawAxis - Returns a `PetscDrawAxis` object from a `PetscViewer` object of type `PETSCVIEWERDRAW`. 114 This `PetscDrawAxis` object may then be used to perform graphics using `PetscDrawAxis` commands. 115 116 Collective 117 118 Input Parameters: 119 + viewer - the `PetscViewer` (created with `PetscViewerDrawOpen()`) 120 - windownumber - indicates which subwindow (usually 0) 121 122 Output Parameter: 123 . drawaxis - the draw axis object 124 125 Level: advanced 126 127 Note: 128 A `PETSCVIEWERDRAW` may have multiple `PetscDraw` subwindows 129 130 .seealso: [](sec_viewers), `PetscViewerDrawGetDraw()`, `PetscViewerDrawGetLG()`, `PetscViewerDrawOpen()` 131 @*/ 132 PetscErrorCode PetscViewerDrawGetDrawAxis(PetscViewer viewer, PetscInt windownumber, PetscDrawAxis *drawaxis) 133 { 134 PetscBool isdraw; 135 PetscViewer_Draw *vdraw; 136 137 PetscFunctionBegin; 138 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 139 PetscValidLogicalCollectiveInt(viewer, windownumber, 2); 140 PetscAssertPointer(drawaxis, 3); 141 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 142 PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer"); 143 PetscCheck(windownumber >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Window number cannot be negative"); 144 vdraw = (PetscViewer_Draw *)viewer->data; 145 146 if (windownumber + vdraw->draw_base >= vdraw->draw_max || !vdraw->draw[windownumber + vdraw->draw_base]) PetscCall(PetscViewerDrawGetDraw(viewer, windownumber, NULL)); 147 if (!vdraw->drawaxis[windownumber + vdraw->draw_base]) PetscCall(PetscDrawAxisCreate(vdraw->draw[windownumber + vdraw->draw_base], &vdraw->drawaxis[windownumber + vdraw->draw_base])); 148 *drawaxis = vdraw->drawaxis[windownumber + vdraw->draw_base]; 149 PetscFunctionReturn(PETSC_SUCCESS); 150 } 151 152 PetscErrorCode PetscViewerDrawSetDrawType(PetscViewer v, PetscDrawType drawtype) 153 { 154 PetscViewer_Draw *vdraw; 155 PetscBool isdraw; 156 157 PetscFunctionBegin; 158 PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1); 159 PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw)); 160 if (!isdraw) PetscFunctionReturn(PETSC_SUCCESS); 161 vdraw = (PetscViewer_Draw *)v->data; 162 163 PetscCall(PetscFree(vdraw->drawtype)); 164 PetscCall(PetscStrallocpy(drawtype, (char **)&vdraw->drawtype)); 165 PetscFunctionReturn(PETSC_SUCCESS); 166 } 167 168 PetscErrorCode PetscViewerDrawGetDrawType(PetscViewer v, PetscDrawType *drawtype) 169 { 170 PetscViewer_Draw *vdraw; 171 PetscBool isdraw; 172 173 PetscFunctionBegin; 174 PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 1); 175 PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERDRAW, &isdraw)); 176 PetscCheck(isdraw, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Must be draw type PetscViewer"); 177 vdraw = (PetscViewer_Draw *)v->data; 178 179 *drawtype = vdraw->drawtype; 180 PetscFunctionReturn(PETSC_SUCCESS); 181 } 182