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