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