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