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