1 | /*************************************** 2 | $Header: /cvsroot/petscgraphics/petsc.c,v 1.12 2004/07/02 20:51:08 hazelsct Exp $ 3 | 4 | This is the petsc.c main file. It has all of the PETSc-dependent functions. 5 | ***************************************/ 6 | 7 | 8 | #include <petscda.h> 9 | #include "config.h" /* esp. for inline */ 10 | #include "illuminator.h" /* Just to make sure the interface is "right" */ 11 | 12 | extern int num_triangles; 13 | 14 | 15 | #undef __FUNCT__ 16 | #define __FUNCT__ "DATriangulateRange" 17 | 18 | /*++++++++++++++++++++++++++++++++++++++ 19 | Calculate vertices of isoquant triangles in a 3-D distributed array. This 20 | takes a PETSc DA object, does some sanity checks, calculates array sizes, 21 | gets the local vector and array, and then calls 22 | +latex+{\tt DATriangulateLocal()} 23 | +html+ <tt>DATriangulateLocal()</tt> 24 | to do the rest. Note that global array access (i.e. this function) is 25 | necessary for using default isoquant values, since we need to be able to 26 | calculate the maximum and minimum on the global array. 27 | 28 | int DATriangulateRange Returns 0 or an error code. 29 | 30 | DA theda The PETSc distributed array object. 31 | 32 | Vec globalX PETSc global vector object associated with the DA with data we'd 33 | like to graph. 34 | 35 | int this Index of the field we'd like to draw. 36 | 37 | PetscScalar *minmax Position of block corners: xmin, xmax, ymin, ymax, zmin, 38 | zmax. 39 | 40 | int n_quants Number of isoquant surfaces to draw (isoquant values), or 41 | +latex+{\tt PETSC\_DECIDE} 42 | +html+ <tt>PETSC_DECIDE</tt> 43 | to use red, yellow, green, blue at 0.2, 0.4, 0.6 and 0.8 between the vector's 44 | global minimum and maximum values. 45 | 46 | PetscScalar *isoquants Array of function values at which to draw isoquants, 47 | +latex+or {\tt PETSC\_NULL} if {\tt n\_quants=PETSC\_DECIDE}. 48 | +html+ or <tt>PETSC_NULL</tt> if <tt>n_quants=PETSC\_DECIDE</tt>. 49 | 50 | PetscScalar *colors Array of color R,G,B,A quads for each isoquant, or 51 | +latex+{\tt PETSC\_NULL} if {\tt n\_quants=PETSC\_DECIDE}. 52 | +html+ <tt>PETSC_NULL</tt> if <tt>n_quants=PETSC\_DECIDE</tt>. 53 | 54 | int xmin Smallest grid x-coordinate to render. 55 | 56 | int xmax Largest grid x-coordinate to render, -1 goes to full x maximum, -2 57 | in periodic systems goes to one short of x maximum. 58 | 59 | int ymin Smallest grid y-coordinate to render. 60 | 61 | int ymax Largest grid y-coordinate to render, -1 goes to full y maximum, -2 62 | in periodic systems goes to one short of y maximum. 63 | 64 | int zmin Smallest grid z-coordinate to render. 65 | 66 | int zmax Largest grid z-coordinate to render, -1 goes to full z maximum, -2 67 | in periodic systems goes to one short of z maximum. 68 | ++++++++++++++++++++++++++++++++++++++*/ 69 | 70 | int DATriangulateRange 71 | (DA theda, Vec globalX, int this, PetscScalar *minmax, int n_quants, 72 | PetscScalar *isoquants, PetscScalar *colors, int xmin,int xmax, int ymin, 73 | int ymax, int zmin,int zmax) 74 | { 75 | Vec localX; 76 | PetscScalar isoquantdefaults[4], 77 | colordefaults[16] = { 1,0,0,.5, 1,1,0,.5, 0,1,0,.5, 0,0,1,.5 }; 78 | PetscReal themax, themin; 79 | int ierr; 80 | 81 | /* Default isoquants */ 82 | if (n_quants == PETSC_DECIDE) { 83 | ierr = VecStrideMin (globalX, this, PETSC_NULL, &themin); CHKERRQ (ierr); 84 | ierr = VecStrideMax (globalX, this, PETSC_NULL, &themax); CHKERRQ (ierr); 85 | /* Red, yellow, green, blue at 0.2, 0.4, 0.6, 0.8, all with alpha=0.5 */ 86 | n_quants = 4; 87 | isoquantdefaults[0] = themin + 0.2*(themax-themin); 88 | isoquantdefaults[1] = themin + 0.4*(themax-themin); 89 | isoquantdefaults[2] = themin + 0.6*(themax-themin); 90 | isoquantdefaults[3] = themin + 0.8*(themax-themin); 91 | isoquants = isoquantdefaults; 92 | colors = colordefaults; 93 | } 94 | 95 | /* Get the local array of points, with ghosts */ 96 | ierr = DACreateLocalVector (theda, &localX); CHKERRQ (ierr); 97 | ierr = DAGlobalToLocalBegin (theda, globalX, INSERT_VALUES, localX); CHKERRQ(ierr); 98 | ierr = DAGlobalToLocalEnd (theda, globalX, INSERT_VALUES, localX); CHKERRQ (ierr); 99 | 100 | /* Use DATriangulateLocalRange() to do the work */ 101 | ierr = DATriangulateLocalRange (theda, localX, this, minmax, n_quants, 102 | isoquants, colors, xmin,xmax, ymin,ymax, 103 | zmin,zmax); CHKERRQ (ierr); 104 | 105 | ierr = VecDestroy (localX); CHKERRQ (ierr); 106 | 107 | return 0; 108 | } 109 | 110 | 111 | #undef __FUNCT__ 112 | #define __FUNCT__ "DATriangulateLocalRange" 113 | 114 | /*++++++++++++++++++++++++++++++++++++++ 115 | Calculate vertices of isoquant triangles in a 3-D distributed array. This 116 | takes a PETSc DA object, does some sanity checks, calculates array sizes, and 117 | then gets array and passes it to Draw3DBlock for triangulation. 118 | 119 | int DATriangulateLocalRange Returns 0 or an error code. 120 | 121 | DA theda The PETSc distributed array object. 122 | 123 | Vec localX PETSc local vector object associated with the DA with data we'd 124 | like to graph. 125 | 126 | int this Index of the field we'd like to draw. 127 | 128 | PetscScalar *minmax Position of block corners: xmin, xmax, ymin, ymax, zmin, 129 | zmax. 130 | 131 | int n_quants Number of isoquant surfaces to draw (isoquant values). Note 132 | +latex+{\tt PETSC\_DECIDE} 133 | +html+ <tt>PETSC_DECIDE</tt> 134 | is not a valid option here, because it's impossible to know the global 135 | maximum and minimum and have consistent contours without user-supplied 136 | information. 137 | 138 | PetscScalar *isoquants Array of function values at which to draw isoquants. 139 | 140 | PetscScalar *colors Array of color R,G,B,A quads for each isoquant. 141 | 142 | int xmin Smallest grid x-coordinate to render. 143 | 144 | int xmax Largest grid x-coordinate to render, -1 goes to full x maximum, -2 145 | in periodic systems goes to one short of x maximum. 146 | 147 | int ymin Smallest grid y-coordinate to render. 148 | 149 | int ymax Largest grid y-coordinate to render, -1 goes to full y maximum, -2 150 | in periodic systems goes to one short of y maximum. 151 | 152 | int zmin Smallest grid z-coordinate to render. 153 | 154 | int zmax Largest grid z-coordinate to render, -1 goes to full z maximum, -2 155 | in periodic systems goes to one short of z maximum. 156 | ++++++++++++++++++++++++++++++++++++++*/ 157 | 158 | int DATriangulateLocalRange 159 | (DA theda, Vec localX, int this, PetscScalar *minmax, int n_quants, 160 | PetscScalar *isoquants, PetscScalar *colors, int xmin,int xmax, int ymin, 161 | int ymax, int zmin,int zmax) 162 | { 163 | PetscScalar *x, isoquantdefaults[4], localminmax[6], 164 | colordefaults[16] = { 1,0,0,.5, 1,1,0,.5, 0,1,0,.5, 0,0,1,.5 }; 165 | DAStencilType stencil; 166 | int i, ierr, fields, xw,yw,zw, xs,ys,zs, xm,ym,zm, gxs,gys,gzs, gxm,gym,gzm; 167 | 168 | /* Default isoquant error */ 169 | if (n_quants == PETSC_DECIDE) 170 | SETERRQ (PETSC_ERR_ARG_WRONGSTATE, "Can't get default isoquants for local array"); 171 | 172 | /* Get global and local grid boundaries */ 173 | ierr = DAGetInfo (theda, &i, &xw,&yw,&zw, PETSC_NULL,PETSC_NULL,PETSC_NULL, 174 | &fields, PETSC_NULL, PETSC_NULL, &stencil);CHKERRQ(ierr); 175 | if (i!=3) 176 | SETERRQ (PETSC_ERR_ARG_WRONGSTATE, "DA must be 3-dimensional"); 177 | if (stencil!=DA_STENCIL_BOX) 178 | SETERRQ (PETSC_ERR_ARG_WRONGSTATE, "DA must have a box stencil"); 179 | 180 | ierr = DAGetCorners (theda, &xs,&ys,&zs, &xm,&ym,&zm); CHKERRQ (ierr); 181 | ierr = DAGetGhostCorners (theda, &gxs,&gys,&gzs, &gxm,&gym,&gzm); 182 | CHKERRQ (ierr); 183 | 184 | /* Get the local array of points, with ghosts */ 185 | ierr = VecGetArray (localX, &x); CHKERRQ (ierr); 186 | 187 | /* If the array is too big, cut it down to size */ 188 | if (gxm <= xs-gxs+xm) 189 | xm = gxm-xs+gxs-1; 190 | if (gym <= ys-gys+ym) 191 | ym = gym-ys+gys-1; 192 | if (gzm <= zs-gzs+zm) 193 | zm = gzm-zs+gzs-1; 194 | /* Eliminate final rows/planes if *cut and periodic. */ 195 | if (xmax == -2 && xs+xm>=xw) 196 | xm--; 197 | if (ymax == -2 && ys+ym>=yw) 198 | ym--; 199 | if (zmax == -2 && zs+zm>=zw) 200 | zm--; 201 | 202 | /* Reframe to range */ 203 | xs = PetscMax (xs, xmin); 204 | ys = PetscMax (ys, xmin); 205 | zs = PetscMax (zs, xmin); 206 | xm = (xmax > 0) ? PetscMin (xm, xmax-xs) : xm; 207 | ym = (ymax > 0) ? PetscMin (ym, ymax-ys) : ym; 208 | zm = (zmax > 0) ? PetscMin (zm, zmax-zs) : zm; 209 | 210 | /* Calculate local physical size */ 211 | localminmax[0] = minmax[0] + (minmax[1]-minmax[0])*xs/xw; 212 | localminmax[1] = minmax[2] + (minmax[1]-minmax[0])*(xs+xm)/xw; 213 | localminmax[2] = minmax[2] + (minmax[3]-minmax[2])*ys/yw; 214 | localminmax[3] = minmax[2] + (minmax[3]-minmax[2])*(ys+ym)/yw; 215 | localminmax[4] = minmax[4] + (minmax[5]-minmax[4])*zs/zw; 216 | localminmax[5] = minmax[4] + (minmax[5]-minmax[4])*(zs+zm)/zw; 217 | 218 | /* Let 'er rip! */ 219 | ierr = Draw3DBlock (gxm,gym,gzm, xs-gxs,ys-gys,zs-gzs, xm,ym,zm, localminmax, 220 | x+this, fields, n_quants, isoquants, colors); 221 | CHKERRQ (ierr); 222 | ierr = VecRestoreArray (localX, &x); CHKERRQ (ierr); 223 | 224 | /* Prints the number of triangles on all CPUs */ 225 | #ifdef DEBUG 226 | { 227 | int rank; 228 | ierr = MPI_Comm_rank (PETSC_COMM_WORLD, &rank); CHKERRQ (ierr); 229 | ierr = PetscSynchronizedPrintf 230 | (PETSC_COMM_WORLD, "[%d] zs=%d, zm=%d, zmin=%g, zmax=%g\n", 231 | rank, zs, zm, localminmax[4], localminmax[5]); CHKERRQ (ierr); 232 | ierr = PetscSynchronizedFlush (PETSC_COMM_WORLD); CHKERRQ (ierr); 233 | ierr = PetscSynchronizedPrintf (PETSC_COMM_WORLD, "[%d] Triangles: %d\n", 234 | rank, num_triangles); CHKERRQ (ierr); 235 | ierr = PetscSynchronizedFlush (PETSC_COMM_WORLD); CHKERRQ (ierr); 236 | } 237 | #endif 238 | 239 | return 0; 240 | } 241 | 242 | 243 | #undef __FUNCT__ 244 | #define __FUNCT__ "IllErrorHandler" 245 | 246 | /*++++++++++++++++++++++++++++++++++++++ 247 | Handle errors, in this case the PETSc way. 248 | 249 | int IllErrorHandler Returns the error code supplied. 250 | 251 | int id Index of the error, defined in petscerror.h. 252 | 253 | char *message Text of the error message. 254 | ++++++++++++++++++++++++++++++++++++++*/ 255 | 256 | int IllErrorHandler (int id, char *message) 257 | { 258 | SETERRQ (id, message); 259 | exit (1); 260 | }