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 Concepts: drawing^in subset of window 22 Concepts: graphics^in subset of window 23 24 @*/ 25 PetscErrorCode PetscDrawSetViewPort(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr) 26 { 27 PetscErrorCode ierr; 28 29 PetscFunctionBegin; 30 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 31 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); 32 draw->port_xl = xl; draw->port_yl = yl; 33 draw->port_xr = xr; draw->port_yr = yr; 34 if (draw->ops->setviewport) { 35 ierr = (*draw->ops->setviewport)(draw,xl,yl,xr,yr);CHKERRQ(ierr); 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 Parameter: 50 . xl,yl,xr,yr - upper right and lower left corners of subwindow 51 These numbers must always be between 0.0 and 1.0. 52 Lower left corner is (0,0). 53 54 Level: advanced 55 56 Concepts: drawing^in subset of window 57 Concepts: graphics^in subset of window 58 59 @*/ 60 PetscErrorCode PetscDrawGetViewPort(PetscDraw draw,PetscReal *xl,PetscReal *yl,PetscReal *xr,PetscReal *yr) 61 { 62 PetscFunctionBegin; 63 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 64 PetscValidRealPointer(xl,2); 65 PetscValidRealPointer(yl,3); 66 PetscValidRealPointer(xr,4); 67 PetscValidRealPointer(yr,5); 68 *xl = draw->port_xl; 69 *yl = draw->port_yl; 70 *xr = draw->port_xr; 71 *yr = draw->port_yr; 72 PetscFunctionReturn(0); 73 } 74 75 /*@ 76 PetscDrawSplitViewPort - Splits a window shared by several processes into smaller 77 view ports. One for each process. 78 79 Collective on PetscDraw 80 81 Input Parameter: 82 . draw - the drawing context 83 84 Level: advanced 85 86 Concepts: drawing^in subset of window 87 88 .seealso: PetscDrawDivideViewPort(), PetscDrawSetViewPort() 89 90 @*/ 91 PetscErrorCode PetscDrawSplitViewPort(PetscDraw draw) 92 { 93 PetscErrorCode ierr; 94 PetscMPIInt rank,size; 95 PetscInt n; 96 PetscBool isnull; 97 PetscReal xl,xr,yl,yr,h; 98 99 PetscFunctionBegin; 100 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 101 ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 102 if (isnull) PetscFunctionReturn(0); 103 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr); 104 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);CHKERRQ(ierr); 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 ierr = PetscDrawLine(draw,xl,yl,xl,yr,PETSC_DRAW_BLACK);CHKERRQ(ierr); 117 ierr = PetscDrawLine(draw,xl,yr,xr,yr,PETSC_DRAW_BLACK);CHKERRQ(ierr); 118 ierr = PetscDrawLine(draw,xr,yr,xr,yl,PETSC_DRAW_BLACK);CHKERRQ(ierr); 119 ierr = PetscDrawLine(draw,xr,yl,xl,yl,PETSC_DRAW_BLACK);CHKERRQ(ierr); 120 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 121 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 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) { 129 ierr = (*draw->ops->setviewport)(draw,xl,yl,xr,yr);CHKERRQ(ierr); 130 } 131 PetscFunctionReturn(0); 132 } 133 134 /*@C 135 PetscDrawViewPortsCreate - Splits a window into smaller view ports. Each processor shares all the viewports. 136 137 Collective on PetscDraw 138 139 Input Parameters: 140 + draw - the drawing context 141 - nports - the number of ports 142 143 Output Parameter: 144 . ports - a PetscDrawViewPorts context (C structure) 145 146 Options Database: 147 . -draw_ports - display multiple fields in the same window with PetscDrawPorts instead of in seperate windows 148 149 Level: advanced 150 151 Concepts: drawing^in subset of window 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);CHKERRQ(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) { 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 Concepts: drawing^in subset of window 233 234 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy() 235 236 @*/ 237 PetscErrorCode PetscDrawViewPortsCreateRect(PetscDraw draw,PetscInt nx,PetscInt ny,PetscDrawViewPorts **newports) 238 { 239 PetscDrawViewPorts *ports; 240 PetscReal *xl,*xr,*yl,*yr,hx,hy; 241 PetscInt i,j,k,n; 242 PetscBool isnull; 243 PetscMPIInt rank; 244 PetscErrorCode ierr; 245 246 PetscFunctionBegin; 247 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 248 if ((nx < 1) || (ny < 1)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d x %d", nx, ny); 249 PetscValidPointer(newports,3); 250 ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 251 if (isnull) {*newports = NULL; PetscFunctionReturn(0);} 252 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr); 253 254 n = nx*ny; 255 hx = 1.0/nx; 256 hy = 1.0/ny; 257 ierr = PetscNew(&ports);CHKERRQ(ierr); *newports = ports; 258 ports->draw = draw; 259 ports->nports = n; 260 ierr = PetscObjectReference((PetscObject) draw);CHKERRQ(ierr); 261 /* save previous drawport of window */ 262 ierr = PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);CHKERRQ(ierr); 263 264 ierr = PetscMalloc4(n,&xl,n,&xr,n,&yl,n,&yr);CHKERRQ(ierr); 265 ports->xr = xr; 266 ports->xl = xl; 267 ports->yl = yl; 268 ports->yr = yr; 269 270 ierr = PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);CHKERRQ(ierr); 271 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 272 for (i = 0; i < nx; i++) { 273 for (j = 0; j < ny; j++) { 274 k = j*nx+i; 275 276 xl[k] = i*hx; 277 xr[k] = xl[k] + hx; 278 yl[k] = j*hy; 279 yr[k] = yl[k] + hy; 280 281 if (!rank) { 282 ierr = PetscDrawLine(draw,xl[k],yl[k],xl[k],yr[k],PETSC_DRAW_BLACK);CHKERRQ(ierr); 283 ierr = PetscDrawLine(draw,xl[k],yr[k],xr[k],yr[k],PETSC_DRAW_BLACK);CHKERRQ(ierr); 284 ierr = PetscDrawLine(draw,xr[k],yr[k],xr[k],yl[k],PETSC_DRAW_BLACK);CHKERRQ(ierr); 285 ierr = PetscDrawLine(draw,xr[k],yl[k],xl[k],yl[k],PETSC_DRAW_BLACK);CHKERRQ(ierr); 286 } 287 288 xl[k] += .05*hx; 289 xr[k] -= .05*hx; 290 yl[k] += .05*hy; 291 yr[k] -= .05*hy; 292 } 293 } 294 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 295 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 296 PetscFunctionReturn(0); 297 } 298 299 /*@C 300 PetscDrawViewPortsDestroy - frees a PetscDrawViewPorts object 301 302 Collective on PetscDraw inside PetscDrawViewPorts 303 304 Input Parameter: 305 . ports - the PetscDrawViewPorts object 306 307 Level: advanced 308 309 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsCreate() 310 311 @*/ 312 PetscErrorCode PetscDrawViewPortsDestroy(PetscDrawViewPorts *ports) 313 { 314 PetscErrorCode ierr; 315 316 PetscFunctionBegin; 317 if (!ports) PetscFunctionReturn(0); 318 PetscValidPointer(ports,1); 319 /* reset Drawport of Window back to previous value */ 320 ierr = PetscDrawSetViewPort(ports->draw,ports->port_xl,ports->port_yl,ports->port_xr,ports->port_yr);CHKERRQ(ierr); 321 ierr = PetscDrawDestroy(&ports->draw);CHKERRQ(ierr); 322 ierr = PetscFree4(ports->xl,ports->xr,ports->yl,ports->yr);CHKERRQ(ierr); 323 ierr = PetscFree(ports);CHKERRQ(ierr); 324 PetscFunctionReturn(0); 325 } 326 327 /*@C 328 PetscDrawViewPortsSet - sets a draw object to use a particular subport 329 330 Logically Collective on PetscDraw inside PetscDrawViewPorts 331 332 Input Parameter: 333 + ports - the PetscDrawViewPorts object 334 - port - the port number, from 0 to nports-1 335 336 Level: advanced 337 338 Concepts: drawing^in subset of window 339 340 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsDestroy(), PetscDrawViewPortsCreate() 341 342 @*/ 343 PetscErrorCode PetscDrawViewPortsSet(PetscDrawViewPorts *ports,PetscInt port) 344 { 345 PetscErrorCode ierr; 346 347 PetscFunctionBegin; 348 if (!ports) PetscFunctionReturn(0); 349 PetscValidPointer(ports,1); 350 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); 351 ierr = PetscDrawSetViewPort(ports->draw,ports->xl[port],ports->yl[port],ports->xr[port],ports->yr[port]);CHKERRQ(ierr); 352 PetscFunctionReturn(0); 353 } 354