1 2 /* 3 Provides the calling sequences for all the basic PetscDraw routines. 4 */ 5 #include <petsc/private/drawimpl.h> /*I "petscdraw.h" I*/ 6 7 /*@ 8 PetscDrawSetViewPort - Sets the portion of the window (page) to which draw 9 routines will write. 10 11 Collective on PetscDraw 12 13 Input Parameters: 14 + xl - the horizontal coordinate of the lower left corner of the subwindow. 15 . yl - the vertical coordinate of the lower left corner of the subwindow. 16 . xr - the horizontal coordinate of the upper right corner of the subwindow. 17 . yr - the vertical coordinate of the upper right corner of the subwindow. 18 - draw - the drawing context 19 20 Notes: 21 These numbers must always be between 0.0 and 1.0. 22 Lower left corner is (0,0). 23 24 Level: advanced 25 26 @*/ 27 PetscErrorCode PetscDrawSetViewPort(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr) 28 { 29 PetscFunctionBegin; 30 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 31 PetscCheck(xl >= 0.0 && xr <= 1.0 && yl >= 0.0 && yr <= 1.0 && xr > xl && yr > yl,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"ViewPort values must be >= 0 and <= 1: Instead %g %g %g %g",(double)xl,(double)yl,(double)xr,(double)yr); 32 draw->port_xl = xl; draw->port_yl = yl; 33 draw->port_xr = xr; draw->port_yr = yr; 34 if (draw->ops->setviewport) { 35 CHKERRQ((*draw->ops->setviewport)(draw,xl,yl,xr,yr)); 36 } 37 PetscFunctionReturn(0); 38 } 39 40 /*@ 41 PetscDrawGetViewPort - Gets the portion of the window (page) to which draw 42 routines will write. 43 44 Collective on PetscDraw 45 46 Input Parameter: 47 . draw - the drawing context 48 49 Output Parameters: 50 + xl - the horizontal coordinate of the lower left corner of the subwindow. 51 . yl - the vertical coordinate of the lower left corner of the subwindow. 52 . xr - the horizontal coordinate of the upper right corner of the subwindow. 53 - yr - the vertical coordinate of the upper right corner of the subwindow. 54 55 Notes: 56 These numbers must always be between 0.0 and 1.0. 57 Lower left corner is (0,0). 58 59 Level: advanced 60 61 @*/ 62 PetscErrorCode PetscDrawGetViewPort(PetscDraw draw,PetscReal *xl,PetscReal *yl,PetscReal *xr,PetscReal *yr) 63 { 64 PetscFunctionBegin; 65 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 66 PetscValidRealPointer(xl,2); 67 PetscValidRealPointer(yl,3); 68 PetscValidRealPointer(xr,4); 69 PetscValidRealPointer(yr,5); 70 *xl = draw->port_xl; 71 *yl = draw->port_yl; 72 *xr = draw->port_xr; 73 *yr = draw->port_yr; 74 PetscFunctionReturn(0); 75 } 76 77 /*@ 78 PetscDrawSplitViewPort - Splits a window shared by several processes into smaller 79 view ports. One for each process. 80 81 Collective on PetscDraw 82 83 Input Parameter: 84 . draw - the drawing context 85 86 Level: advanced 87 88 .seealso: PetscDrawDivideViewPort(), PetscDrawSetViewPort() 89 90 @*/ 91 PetscErrorCode PetscDrawSplitViewPort(PetscDraw draw) 92 { 93 PetscMPIInt rank,size; 94 PetscInt n; 95 PetscBool isnull; 96 PetscReal xl,xr,yl,yr,h; 97 PetscErrorCode ierr; 98 99 PetscFunctionBegin; 100 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 101 CHKERRQ(PetscDrawIsNull(draw,&isnull)); 102 if (isnull) PetscFunctionReturn(0); 103 CHKERRMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank)); 104 CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size)); 105 106 n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)size)); 107 while (n*n < size) n++; 108 109 h = 1.0/n; 110 xl = (rank % n)*h; 111 xr = xl + h; 112 yl = (rank / n)*h; 113 yr = yl + h; 114 115 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 116 CHKERRQ(PetscDrawLine(draw,xl,yl,xl,yr,PETSC_DRAW_BLACK)); 117 CHKERRQ(PetscDrawLine(draw,xl,yr,xr,yr,PETSC_DRAW_BLACK)); 118 CHKERRQ(PetscDrawLine(draw,xr,yr,xr,yl,PETSC_DRAW_BLACK)); 119 CHKERRQ(PetscDrawLine(draw,xr,yl,xl,yl,PETSC_DRAW_BLACK)); 120 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 121 CHKERRQ(PetscDrawFlush(draw)); 122 123 draw->port_xl = xl + .05*h; 124 draw->port_xr = xr - .05*h; 125 draw->port_yl = yl + .05*h; 126 draw->port_yr = yr - .05*h; 127 128 if (draw->ops->setviewport) CHKERRQ((*draw->ops->setviewport)(draw,xl,yl,xr,yr)); 129 PetscFunctionReturn(0); 130 } 131 132 /*@C 133 PetscDrawViewPortsCreate - Splits a window into smaller view ports. Each processor shares all the viewports. 134 135 Collective on PetscDraw 136 137 Input Parameters: 138 + draw - the drawing context 139 - nports - the number of ports 140 141 Output Parameter: 142 . ports - a PetscDrawViewPorts context (C structure) 143 144 Options Database: 145 . -draw_ports - display multiple fields in the same window with PetscDrawPorts() instead of in separate windows 146 147 Level: advanced 148 149 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy() 150 151 @*/ 152 PetscErrorCode PetscDrawViewPortsCreate(PetscDraw draw,PetscInt nports,PetscDrawViewPorts **newports) 153 { 154 PetscDrawViewPorts *ports; 155 PetscInt i,n; 156 PetscBool isnull; 157 PetscMPIInt rank; 158 PetscReal *xl,*xr,*yl,*yr,h; 159 PetscErrorCode ierr; 160 161 PetscFunctionBegin; 162 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 163 PetscCheck(nports >= 1,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %" PetscInt_FMT, nports); 164 PetscValidPointer(newports,3); 165 CHKERRQ(PetscDrawIsNull(draw,&isnull)); 166 if (isnull) {*newports = NULL; PetscFunctionReturn(0);} 167 CHKERRMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank)); 168 169 CHKERRQ(PetscNew(&ports)); *newports = ports; 170 ports->draw = draw; 171 ports->nports = nports; 172 CHKERRQ(PetscObjectReference((PetscObject)draw)); 173 /* save previous drawport of window */ 174 CHKERRQ(PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr)); 175 176 n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)nports)); 177 while (n*n < nports) n++; 178 h = 1.0/n; 179 180 CHKERRQ(PetscMalloc4(n*n,&xl,n*n,&xr,n*n,&yl,n*n,&yr)); 181 ports->xl = xl; 182 ports->xr = xr; 183 ports->yl = yl; 184 ports->yr = yr; 185 186 CHKERRQ(PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0)); 187 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 188 for (i=0; i<n*n; i++) { 189 xl[i] = (i % n)*h; 190 xr[i] = xl[i] + h; 191 yl[i] = (i / n)*h; 192 yr[i] = yl[i] + h; 193 194 if (rank == 0) { 195 CHKERRQ(PetscDrawLine(draw,xl[i],yl[i],xl[i],yr[i],PETSC_DRAW_BLACK)); 196 CHKERRQ(PetscDrawLine(draw,xl[i],yr[i],xr[i],yr[i],PETSC_DRAW_BLACK)); 197 CHKERRQ(PetscDrawLine(draw,xr[i],yr[i],xr[i],yl[i],PETSC_DRAW_BLACK)); 198 CHKERRQ(PetscDrawLine(draw,xr[i],yl[i],xl[i],yl[i],PETSC_DRAW_BLACK)); 199 } 200 201 xl[i] += .05*h; 202 xr[i] -= .05*h; 203 yl[i] += .05*h; 204 yr[i] -= .05*h; 205 } 206 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 207 CHKERRQ(PetscDrawFlush(draw)); 208 PetscFunctionReturn(0); 209 } 210 211 /*@C 212 PetscDrawViewPortsCreateRect - Splits a window into smaller 213 view ports. Each processor shares all the viewports. The number 214 of views in the x- and y-directions is specified. 215 216 Collective on PetscDraw 217 218 Input Parameters: 219 + draw - the drawing context 220 . nx - the number of x divisions 221 - ny - the number of y divisions 222 223 Output Parameter: 224 . ports - a PetscDrawViewPorts context (C structure) 225 226 Level: advanced 227 228 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy() 229 230 @*/ 231 PetscErrorCode PetscDrawViewPortsCreateRect(PetscDraw draw,PetscInt nx,PetscInt ny,PetscDrawViewPorts **newports) 232 { 233 PetscDrawViewPorts *ports; 234 PetscReal *xl,*xr,*yl,*yr,hx,hy; 235 PetscInt i,j,k,n; 236 PetscBool isnull; 237 PetscMPIInt rank; 238 PetscErrorCode ierr; 239 240 PetscFunctionBegin; 241 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 242 PetscCheck(nx >= 1 && ny >= 1,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %" PetscInt_FMT " x %" PetscInt_FMT, nx, ny); 243 PetscValidPointer(newports,4); 244 CHKERRQ(PetscDrawIsNull(draw,&isnull)); 245 if (isnull) {*newports = NULL; PetscFunctionReturn(0);} 246 CHKERRMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank)); 247 248 n = nx*ny; 249 hx = 1.0/nx; 250 hy = 1.0/ny; 251 CHKERRQ(PetscNew(&ports)); *newports = ports; 252 ports->draw = draw; 253 ports->nports = n; 254 CHKERRQ(PetscObjectReference((PetscObject) draw)); 255 /* save previous drawport of window */ 256 CHKERRQ(PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr)); 257 258 CHKERRQ(PetscMalloc4(n,&xl,n,&xr,n,&yl,n,&yr)); 259 ports->xr = xr; 260 ports->xl = xl; 261 ports->yl = yl; 262 ports->yr = yr; 263 264 CHKERRQ(PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0)); 265 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 266 for (i = 0; i < nx; i++) { 267 for (j = 0; j < ny; j++) { 268 k = j*nx+i; 269 270 xl[k] = i*hx; 271 xr[k] = xl[k] + hx; 272 yl[k] = j*hy; 273 yr[k] = yl[k] + hy; 274 275 if (rank == 0) { 276 CHKERRQ(PetscDrawLine(draw,xl[k],yl[k],xl[k],yr[k],PETSC_DRAW_BLACK)); 277 CHKERRQ(PetscDrawLine(draw,xl[k],yr[k],xr[k],yr[k],PETSC_DRAW_BLACK)); 278 CHKERRQ(PetscDrawLine(draw,xr[k],yr[k],xr[k],yl[k],PETSC_DRAW_BLACK)); 279 CHKERRQ(PetscDrawLine(draw,xr[k],yl[k],xl[k],yl[k],PETSC_DRAW_BLACK)); 280 } 281 282 xl[k] += .05*hx; 283 xr[k] -= .05*hx; 284 yl[k] += .05*hy; 285 yr[k] -= .05*hy; 286 } 287 } 288 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 289 CHKERRQ(PetscDrawFlush(draw)); 290 PetscFunctionReturn(0); 291 } 292 293 /*@C 294 PetscDrawViewPortsDestroy - frees a PetscDrawViewPorts object 295 296 Collective on PetscDraw inside PetscDrawViewPorts 297 298 Input Parameter: 299 . ports - the PetscDrawViewPorts object 300 301 Level: advanced 302 303 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsCreate() 304 305 @*/ 306 PetscErrorCode PetscDrawViewPortsDestroy(PetscDrawViewPorts *ports) 307 { 308 PetscFunctionBegin; 309 if (!ports) PetscFunctionReturn(0); 310 PetscValidPointer(ports,1); 311 /* reset Drawport of Window back to previous value */ 312 CHKERRQ(PetscDrawSetViewPort(ports->draw,ports->port_xl,ports->port_yl,ports->port_xr,ports->port_yr)); 313 CHKERRQ(PetscDrawDestroy(&ports->draw)); 314 CHKERRQ(PetscFree4(ports->xl,ports->xr,ports->yl,ports->yr)); 315 CHKERRQ(PetscFree(ports)); 316 PetscFunctionReturn(0); 317 } 318 319 /*@C 320 PetscDrawViewPortsSet - sets a draw object to use a particular subport 321 322 Logically Collective on PetscDraw inside PetscDrawViewPorts 323 324 Input Parameters: 325 + ports - the PetscDrawViewPorts object 326 - port - the port number, from 0 to nports-1 327 328 Level: advanced 329 330 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsDestroy(), PetscDrawViewPortsCreate() 331 332 @*/ 333 PetscErrorCode PetscDrawViewPortsSet(PetscDrawViewPorts *ports,PetscInt port) 334 { 335 PetscFunctionBegin; 336 if (!ports) PetscFunctionReturn(0); 337 PetscValidPointer(ports,1); 338 PetscCheck(port >= 0 && (port <= ports->nports-1),PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Port is out of range requested %" PetscInt_FMT " from 0 to %" PetscInt_FMT,port,ports->nports-1); 339 CHKERRQ(PetscDrawSetViewPort(ports->draw,ports->xl[port],ports->yl[port],ports->xr[port],ports->yr[port])); 340 PetscFunctionReturn(0); 341 } 342