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