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 *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 #undef __FUNCT__ 76 #define __FUNCT__ "PetscDrawSplitViewPort" 77 /*@ 78 PetscDrawSplitViewPort - Splits a window shared by several processes into smaller 79 view ports. One for each process. 80 81 Collective on PetscDraw 82 83 Input Parameter: 84 . draw - the drawing context 85 86 Level: advanced 87 88 Concepts: drawing^in subset of window 89 90 .seealso: PetscDrawDivideViewPort(), PetscDrawSetViewPort() 91 92 @*/ 93 PetscErrorCode PetscDrawSplitViewPort(PetscDraw draw) 94 { 95 PetscErrorCode ierr; 96 PetscMPIInt rank,size; 97 PetscInt n; 98 PetscBool isnull; 99 PetscReal xl,xr,yl,yr,h; 100 101 PetscFunctionBegin; 102 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 103 ierr = PetscObjectTypeCompare((PetscObject)draw,PETSC_DRAW_NULL,&isnull);CHKERRQ(ierr); 104 if (isnull) PetscFunctionReturn(0); 105 106 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr); 107 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);CHKERRQ(ierr); 108 109 n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)size)); 110 while (n*n < size) n++; 111 112 h = 1.0/n; 113 xl = (rank % n)*h; 114 xr = xl + h; 115 yl = (rank/n)*h; 116 yr = yl + h; 117 118 ierr = PetscDrawLine(draw,xl,yl,xl,yr,PETSC_DRAW_BLACK);CHKERRQ(ierr); 119 ierr = PetscDrawLine(draw,xl,yr,xr,yr,PETSC_DRAW_BLACK);CHKERRQ(ierr); 120 ierr = PetscDrawLine(draw,xr,yr,xr,yl,PETSC_DRAW_BLACK);CHKERRQ(ierr); 121 ierr = PetscDrawLine(draw,xr,yl,xl,yl,PETSC_DRAW_BLACK);CHKERRQ(ierr); 122 ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr); 123 124 draw->port_xl = xl + .1*h; 125 draw->port_xr = xr - .1*h; 126 draw->port_yl = yl + .1*h; 127 draw->port_yr = yr - .1*h; 128 129 if (draw->ops->setviewport) { 130 ierr = (*draw->ops->setviewport)(draw,xl,yl,xr,yr);CHKERRQ(ierr); 131 } 132 PetscFunctionReturn(0); 133 } 134 135 #undef __FUNCT__ 136 #define __FUNCT__ "PetscDrawViewPortsCreate" 137 /*@C 138 PetscDrawViewPortsCreate - Splits a window into smaller 139 view ports. Each processor shares all the viewports. 140 141 Collective on PetscDraw 142 143 Input Parameters: 144 + draw - the drawing context 145 - nports - the number of ports 146 147 Output Parameter: 148 . ports - a PetscDrawViewPorts context (C structure) 149 150 Level: advanced 151 152 Concepts: drawing^in subset of window 153 154 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy() 155 156 @*/ 157 PetscErrorCode PetscDrawViewPortsCreate(PetscDraw draw,PetscInt nports,PetscDrawViewPorts **ports) 158 { 159 PetscInt i,n; 160 PetscErrorCode ierr; 161 PetscBool isnull; 162 PetscReal *xl,*xr,*yl,*yr,h; 163 164 PetscFunctionBegin; 165 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 166 PetscValidPointer(ports,3); 167 ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 168 if (isnull) {*ports = NULL; PetscFunctionReturn(0);} 169 170 ierr = PetscNew(ports);CHKERRQ(ierr); 171 (*ports)->draw = draw; 172 (*ports)->nports = nports; 173 174 ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr); 175 176 n = (PetscInt)(.1 + PetscSqrtReal((PetscReal)nports)); 177 while (n*n < nports) n++; 178 179 ierr = PetscMalloc1(n*n,&xl);CHKERRQ(ierr);(*ports)->xl = xl; 180 ierr = PetscMalloc1(n*n,&xr);CHKERRQ(ierr);(*ports)->xr = xr; 181 ierr = PetscMalloc1(n*n,&yl);CHKERRQ(ierr);(*ports)->yl = yl; 182 ierr = PetscMalloc1(n*n,&yr);CHKERRQ(ierr);(*ports)->yr = yr; 183 184 h = 1.0/n; 185 186 for (i=0; i<n*n; i++) { 187 xl[i] = (i % n)*h; 188 xr[i] = xl[i] + h; 189 yl[i] = (i/n)*h; 190 yr[i] = yl[i] + h; 191 192 ierr = PetscDrawLine(draw,xl[i],yl[i],xl[i],yr[i],PETSC_DRAW_BLACK);CHKERRQ(ierr); 193 ierr = PetscDrawLine(draw,xl[i],yr[i],xr[i],yr[i],PETSC_DRAW_BLACK);CHKERRQ(ierr); 194 ierr = PetscDrawLine(draw,xr[i],yr[i],xr[i],yl[i],PETSC_DRAW_BLACK);CHKERRQ(ierr); 195 ierr = PetscDrawLine(draw,xr[i],yl[i],xl[i],yl[i],PETSC_DRAW_BLACK);CHKERRQ(ierr); 196 197 xl[i] += .1*h; 198 xr[i] -= .1*h; 199 yl[i] += .1*h; 200 yr[i] -= .1*h; 201 } 202 /* save previous drawport of window */ 203 ierr = PetscDrawGetViewPort(draw,&(*ports)->port_xl,&(*ports)->port_yl,&(*ports)->port_xr,&(*ports)->port_yr);CHKERRQ(ierr); 204 /* ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr);*/ /* this causes flicker */ 205 PetscFunctionReturn(0); 206 } 207 208 #undef __FUNCT__ 209 #define __FUNCT__ "PetscDrawViewPortsCreateRect" 210 /*@C 211 PetscDrawViewPortsCreateRect - Splits a window into smaller 212 view ports. Each processor shares all the viewports. The number 213 of views in the x- and y-directions is specified. 214 215 Collective on PetscDraw 216 217 Input Parameters: 218 + draw - the drawing context 219 . nx - the number of x divisions 220 - ny - the number of y divisions 221 222 Output Parameter: 223 . ports - a PetscDrawViewPorts context (C structure) 224 225 Level: advanced 226 227 Concepts: drawing^in subset of window 228 229 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsDestroy() 230 231 @*/ 232 PetscErrorCode PetscDrawViewPortsCreateRect(PetscDraw draw,PetscInt nx,PetscInt ny,PetscDrawViewPorts **ports) 233 { 234 PetscReal *xl, *xr, *yl, *yr, hx, hy; 235 PetscBool isnull; 236 PetscInt i, j, n; 237 PetscErrorCode ierr; 238 239 PetscFunctionBegin; 240 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 241 if ((nx < 1) || (ny < 1)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Number of divisions must be positive: %d x %d", nx, ny); 242 ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 243 if (isnull) {*ports = NULL; PetscFunctionReturn(0);} 244 245 n = nx*ny; 246 hx = 1.0/nx; 247 hy = 1.0/ny; 248 ierr = PetscNew(ports);CHKERRQ(ierr); 249 250 (*ports)->draw = draw; 251 (*ports)->nports = n; 252 253 ierr = PetscObjectReference((PetscObject) draw);CHKERRQ(ierr); 254 ierr = PetscMalloc1(n, &xl);CHKERRQ(ierr);(*ports)->xl = xl; 255 ierr = PetscMalloc1(n, &xr);CHKERRQ(ierr);(*ports)->xr = xr; 256 ierr = PetscMalloc1(n, &yl);CHKERRQ(ierr);(*ports)->yl = yl; 257 ierr = PetscMalloc1(n, &yr);CHKERRQ(ierr);(*ports)->yr = yr; 258 for (i = 0; i < nx; i++) { 259 for (j = 0; j < ny; j++) { 260 PetscInt k = j*nx+i; 261 262 xl[k] = i*hx; 263 xr[k] = xl[k] + hx; 264 yl[k] = j*hy; 265 yr[k] = yl[k] + hy; 266 267 ierr = PetscDrawLine(draw,xl[k],yl[k],xl[k],yr[k],PETSC_DRAW_BLACK);CHKERRQ(ierr); 268 ierr = PetscDrawLine(draw,xl[k],yr[k],xr[k],yr[k],PETSC_DRAW_BLACK);CHKERRQ(ierr); 269 ierr = PetscDrawLine(draw,xr[k],yr[k],xr[k],yl[k],PETSC_DRAW_BLACK);CHKERRQ(ierr); 270 ierr = PetscDrawLine(draw,xr[k],yl[k],xl[k],yl[k],PETSC_DRAW_BLACK);CHKERRQ(ierr); 271 272 xl[k] += .01*hx; 273 xr[k] -= .01*hx; 274 yl[k] += .01*hy; 275 yr[k] -= .01*hy; 276 } 277 } 278 ierr = PetscDrawGetViewPort(draw,&(*ports)->port_xl,&(*ports)->port_yl,&(*ports)->port_xr,&(*ports)->port_yr);CHKERRQ(ierr); 279 /* ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr); */ /* this causes flicker */ 280 PetscFunctionReturn(0); 281 } 282 283 #undef __FUNCT__ 284 #define __FUNCT__ "PetscDrawViewPortsDestroy" 285 /*@C 286 PetscDrawViewPortsDestroy - frees a PetscDrawViewPorts object 287 288 Collective on PetscDraw inside PetscDrawViewPorts 289 290 Input Parameter: 291 . ports - the PetscDrawViewPorts object 292 293 Level: advanced 294 295 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsSet(), PetscDrawViewPortsCreate() 296 297 @*/ 298 PetscErrorCode PetscDrawViewPortsDestroy(PetscDrawViewPorts *ports) 299 { 300 PetscErrorCode ierr; 301 302 PetscFunctionBegin; 303 if (!ports) PetscFunctionReturn(0); 304 /* reset Drawport of Window back to previous value */ 305 ierr = PetscDrawSetViewPort(ports->draw,ports->port_xl,ports->port_yl,ports->port_xr,ports->port_yr);CHKERRQ(ierr); 306 ierr = PetscDrawDestroy(&ports->draw);CHKERRQ(ierr); 307 ierr = PetscFree(ports->xl);CHKERRQ(ierr); 308 ierr = PetscFree(ports->xr);CHKERRQ(ierr); 309 ierr = PetscFree(ports->yl);CHKERRQ(ierr); 310 ierr = PetscFree(ports->yr);CHKERRQ(ierr); 311 ierr = PetscFree(ports);CHKERRQ(ierr); 312 PetscFunctionReturn(0); 313 } 314 315 #undef __FUNCT__ 316 #define __FUNCT__ "PetscDrawViewPortsSet" 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 Concepts: drawing^in subset of window 329 330 .seealso: PetscDrawSplitViewPort(), PetscDrawSetViewPort(), PetscDrawViewPortsDestroy(), PetscDrawViewPortsCreate() 331 332 @*/ 333 PetscErrorCode PetscDrawViewPortsSet(PetscDrawViewPorts *ports,PetscInt port) 334 { 335 PetscErrorCode ierr; 336 337 PetscFunctionBegin; 338 if (ports) { 339 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); 340 ierr = PetscDrawSetViewPort(ports->draw,ports->xl[port],ports->yl[port],ports->xr[port],ports->yr[port]);CHKERRQ(ierr); 341 } 342 PetscFunctionReturn(0); 343 } 344