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 view ports. Each processor shares all the viewports. 144 145 Collective on PetscDraw 146 147 Input Parameters: 148 + draw - the drawing context 149 - nports - the number of ports 150 151 Output Parameter: 152 . ports - a PetscDrawViewPorts context (C structure) 153 154 Options Database: 155 . -draw_ports - display multiple fields in the same window with PetscDrawPorts instead of in seperate windows 156 157 Level: advanced 158 159 Concepts: drawing^in subset of window 160 161 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy() 162 163 @*/ 164 PetscErrorCode PetscDrawViewPortsCreate(PetscDraw draw,PetscInt nports,PetscDrawViewPorts **newports) 165 { 166 PetscDrawViewPorts *ports; 167 PetscInt i,n; 168 PetscBool isnull; 169 PetscMPIInt rank; 170 PetscReal *xl,*xr,*yl,*yr,h; 171 PetscErrorCode ierr; 172 173 PetscFunctionBegin; 174 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 175 if (nports < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d", nports); 176 PetscValidPointer(newports,3); 177 ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 178 if (isnull) {*newports = NULL; PetscFunctionReturn(0);} 179 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr); 180 181 ierr = PetscNew(&ports);CHKERRQ(ierr); *newports = ports; 182 ports->draw = draw; 183 ports->nports = nports; 184 ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr); 185 /* save previous drawport of window */ 186 ierr = PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);CHKERRQ(ierr); 187 188 n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)nports)); 189 while (n*n < nports) n++; 190 h = 1.0/n; 191 192 ierr = PetscMalloc4(n*n,&xl,n*n,&xr,n*n,&yl,n*n,&yr);CHKERRQ(ierr); 193 ports->xl = xl; 194 ports->xr = xr; 195 ports->yl = yl; 196 ports->yr = yr; 197 198 ierr = PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);CHKERRQ(ierr); 199 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 200 for (i=0; i<n*n; i++) { 201 xl[i] = (i % n)*h; 202 xr[i] = xl[i] + h; 203 yl[i] = (i / n)*h; 204 yr[i] = yl[i] + h; 205 206 if (!rank) { 207 ierr = PetscDrawLine(draw,xl[i],yl[i],xl[i],yr[i],PETSC_DRAW_BLACK);CHKERRQ(ierr); 208 ierr = PetscDrawLine(draw,xl[i],yr[i],xr[i],yr[i],PETSC_DRAW_BLACK);CHKERRQ(ierr); 209 ierr = PetscDrawLine(draw,xr[i],yr[i],xr[i],yl[i],PETSC_DRAW_BLACK);CHKERRQ(ierr); 210 ierr = PetscDrawLine(draw,xr[i],yl[i],xl[i],yl[i],PETSC_DRAW_BLACK);CHKERRQ(ierr); 211 } 212 213 xl[i] += .05*h; 214 xr[i] -= .05*h; 215 yl[i] += .05*h; 216 yr[i] -= .05*h; 217 } 218 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 219 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 220 PetscFunctionReturn(0); 221 } 222 223 #undef __FUNCT__ 224 #define __FUNCT__ "PetscDrawViewPortsCreateRect" 225 /*@C 226 PetscDrawViewPortsCreateRect - Splits a window into smaller 227 view ports. Each processor shares all the viewports. The number 228 of views in the x- and y-directions is specified. 229 230 Collective on PetscDraw 231 232 Input Parameters: 233 + draw - the drawing context 234 . nx - the number of x divisions 235 - ny - the number of y divisions 236 237 Output Parameter: 238 . ports - a PetscDrawViewPorts context (C structure) 239 240 Level: advanced 241 242 Concepts: drawing^in subset of window 243 244 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy() 245 246 @*/ 247 PetscErrorCode PetscDrawViewPortsCreateRect(PetscDraw draw,PetscInt nx,PetscInt ny,PetscDrawViewPorts **newports) 248 { 249 PetscDrawViewPorts *ports; 250 PetscReal *xl,*xr,*yl,*yr,hx,hy; 251 PetscInt i,j,k,n; 252 PetscBool isnull; 253 PetscMPIInt rank; 254 PetscErrorCode ierr; 255 256 PetscFunctionBegin; 257 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 258 if ((nx < 1) || (ny < 1)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d x %d", nx, ny); 259 PetscValidPointer(newports,3); 260 ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 261 if (isnull) {*newports = NULL; PetscFunctionReturn(0);} 262 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr); 263 264 n = nx*ny; 265 hx = 1.0/nx; 266 hy = 1.0/ny; 267 ierr = PetscNew(&ports);CHKERRQ(ierr); *newports = ports; 268 ports->draw = draw; 269 ports->nports = n; 270 ierr = PetscObjectReference((PetscObject) draw);CHKERRQ(ierr); 271 /* save previous drawport of window */ 272 ierr = PetscDrawGetViewPort(draw,&ports->port_xl,&ports->port_yl,&ports->port_xr,&ports->port_yr);CHKERRQ(ierr); 273 274 ierr = PetscMalloc4(n,&xl,n,&xr,n,&yl,n,&yr);CHKERRQ(ierr); 275 ports->xr = xr; 276 ports->xl = xl; 277 ports->yl = yl; 278 ports->yr = yr; 279 280 ierr = PetscDrawSetCoordinates(draw,0.0,0.0,1.0,1.0);CHKERRQ(ierr); 281 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 282 for (i = 0; i < nx; i++) { 283 for (j = 0; j < ny; j++) { 284 k = j*nx+i; 285 286 xl[k] = i*hx; 287 xr[k] = xl[k] + hx; 288 yl[k] = j*hy; 289 yr[k] = yl[k] + hy; 290 291 if (!rank) { 292 ierr = PetscDrawLine(draw,xl[k],yl[k],xl[k],yr[k],PETSC_DRAW_BLACK);CHKERRQ(ierr); 293 ierr = PetscDrawLine(draw,xl[k],yr[k],xr[k],yr[k],PETSC_DRAW_BLACK);CHKERRQ(ierr); 294 ierr = PetscDrawLine(draw,xr[k],yr[k],xr[k],yl[k],PETSC_DRAW_BLACK);CHKERRQ(ierr); 295 ierr = PetscDrawLine(draw,xr[k],yl[k],xl[k],yl[k],PETSC_DRAW_BLACK);CHKERRQ(ierr); 296 } 297 298 xl[k] += .05*hx; 299 xr[k] -= .05*hx; 300 yl[k] += .05*hy; 301 yr[k] -= .05*hy; 302 } 303 } 304 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 305 ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 306 PetscFunctionReturn(0); 307 } 308 309 #undef __FUNCT__ 310 #define __FUNCT__ "PetscDrawViewPortsDestroy" 311 /*@C 312 PetscDrawViewPortsDestroy - frees a PetscDrawViewPorts object 313 314 Collective on PetscDraw inside PetscDrawViewPorts 315 316 Input Parameter: 317 . ports - the PetscDrawViewPorts object 318 319 Level: advanced 320 321 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsCreate() 322 323 @*/ 324 PetscErrorCode PetscDrawViewPortsDestroy(PetscDrawViewPorts *ports) 325 { 326 PetscErrorCode ierr; 327 328 PetscFunctionBegin; 329 if (!ports) PetscFunctionReturn(0); 330 PetscValidPointer(ports,1); 331 /* reset Drawport of Window back to previous value */ 332 ierr = PetscDrawSetViewPort(ports->draw,ports->port_xl,ports->port_yl,ports->port_xr,ports->port_yr);CHKERRQ(ierr); 333 ierr = PetscDrawDestroy(&ports->draw);CHKERRQ(ierr); 334 ierr = PetscFree4(ports->xl,ports->xr,ports->yl,ports->yr);CHKERRQ(ierr); 335 ierr = PetscFree(ports);CHKERRQ(ierr); 336 PetscFunctionReturn(0); 337 } 338 339 #undef __FUNCT__ 340 #define __FUNCT__ "PetscDrawViewPortsSet" 341 /*@C 342 PetscDrawViewPortsSet - sets a draw object to use a particular subport 343 344 Logically Collective on PetscDraw inside PetscDrawViewPorts 345 346 Input Parameter: 347 + ports - the PetscDrawViewPorts object 348 - port - the port number, from 0 to nports-1 349 350 Level: advanced 351 352 Concepts: drawing^in subset of window 353 354 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsDestroy(), PetscDrawViewPortsCreate() 355 356 @*/ 357 PetscErrorCode PetscDrawViewPortsSet(PetscDrawViewPorts *ports,PetscInt port) 358 { 359 PetscErrorCode ierr; 360 361 PetscFunctionBegin; 362 if (!ports) PetscFunctionReturn(0); 363 PetscValidPointer(ports,1); 364 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); 365 ierr = PetscDrawSetViewPort(ports->draw,ports->xl[port],ports->yl[port],ports->xr[port],ports->yr[port]);CHKERRQ(ierr); 366 PetscFunctionReturn(0); 367 } 368