1 | /***************************************
2 | $Header: /cvsroot/petscgraphics/petsc.c,v 1.8 2003/05/20 13:58:11 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 |
53 | int DATriangulate
54 | (DA theda, Vec globalX, int this, PetscScalar *minmax, int n_quants,
55 | PetscScalar *isoquants, PetscScalar *colors)
56 | {
57 | Vec localX;
58 | PetscScalar isoquantdefaults[4],
59 | colordefaults[16] = { 1,0,0,.5, 1,1,0,.5, 0,1,0,.5, 0,0,1,.5 };
60 | PetscReal themax, themin;
61 | int ierr;
62 |
63 | /* Default isoquants */
64 | if (n_quants == PETSC_DECIDE) {
65 | ierr = VecStrideMin (globalX, this, PETSC_NULL, &themin); CHKERRQ (ierr);
66 | ierr = VecStrideMax (globalX, this, PETSC_NULL, &themax); CHKERRQ (ierr);
67 | /* Red, yellow, green, blue at 0.2, 0.4, 0.6, 0.8, all with alpha=0.5 */
68 | n_quants = 4;
69 | isoquantdefaults[0] = themin + 0.2*(themax-themin);
70 | isoquantdefaults[1] = themin + 0.4*(themax-themin);
71 | isoquantdefaults[2] = themin + 0.6*(themax-themin);
72 | isoquantdefaults[3] = themin + 0.8*(themax-themin);
73 | isoquants = isoquantdefaults;
74 | colors = colordefaults;
75 | }
76 |
77 | /* Get the local array of points, with ghosts */
78 | ierr = DACreateLocalVector (theda, &localX); CHKERRQ (ierr);
79 | ierr = DAGlobalToLocalBegin (theda, globalX, INSERT_VALUES, localX); CHKERRQ(ierr);
80 | ierr = DAGlobalToLocalEnd (theda, globalX, INSERT_VALUES, localX); CHKERRQ (ierr);
81 |
82 | /* Use DATriangulateLocal() to do the work */
83 | ierr = DATriangulateLocal (theda, localX, this, minmax, n_quants, isoquants,
84 | colors); CHKERRQ (ierr);
85 |
86 | ierr = VecDestroy (localX); CHKERRQ (ierr);
87 |
88 | return 0;
89 | }
90 |
91 |
92 | #undef __FUNCT__
93 | #define __FUNCT__ "DATriangulateLocal"
94 |
95 | /*++++++++++++++++++++++++++++++++++++++
96 | Calculate vertices of isoquant triangles in a 3-D distributed array. This
97 | takes a PETSc DA object, does some sanity checks, calculates array sizes, and
98 | then gets array and passes it to Draw3DBlock for triangulation.
99 |
100 | int DATriangulateLocal Returns 0 or an error code.
101 |
102 | DA theda The PETSc distributed array object.
103 |
104 | Vec localX PETSc local vector object associated with the DA with data we'd
105 | like to graph.
106 |
107 | int this Index of the field we'd like to draw.
108 |
109 | PetscScalar *minmax Position of block corners: xmin, xmax, ymin, ymax, zmin,
110 | zmax.
111 |
112 | int n_quants Number of isoquant surfaces to draw (isoquant values). Note
113 | +latex+{\tt PETSC\_DECIDE}
114 | +html+ <tt>PETSC\_DECIDE</tt>
115 | is not a valid option here, because it's impossible to know the global
116 | maximum and minimum and have consistent contours without user-supplied
117 | information.
118 |
119 | PetscScalar *isoquants Array of function values at which to draw isoquants.
120 |
121 | PetscScalar *colors Array of color R,G,B,A quads for each isoquant.
122 | ++++++++++++++++++++++++++++++++++++++*/
123 |
124 | int DATriangulateLocal
125 | (DA theda, Vec localX, int this, PetscScalar *minmax, int n_quants,
126 | PetscScalar *isoquants, PetscScalar *colors)
127 | {
128 | PetscScalar *x, isoquantdefaults[4], localminmax[6],
129 | colordefaults[16] = { 1,0,0,.5, 1,1,0,.5, 0,1,0,.5, 0,0,1,.5 };
130 | DAStencilType stencil;
131 | int i, ierr, fields, xw,yw,zw, xs,ys,zs, xm,ym,zm, gxs,gys,gzs, gxm,gym,gzm;
132 |
133 | /* Default isoquant error */
134 | if (n_quants == PETSC_DECIDE)
135 | {
136 | SETERRQ (PETSC_ERR_ARG_WRONGSTATE, "Can't get default isoquants for local array");
137 | }
138 |
139 | /* Get global and local grid boundaries */
140 | ierr = DAGetInfo (theda, &i, &xw,&yw,&zw, PETSC_NULL,PETSC_NULL,PETSC_NULL,
141 | &fields, PETSC_NULL, PETSC_NULL, &stencil);CHKERRQ(ierr);
142 | if (i!=3)
143 | {
144 | SETERRQ (PETSC_ERR_ARG_WRONGSTATE, "DA must be 3-dimensional");
145 | }
146 | if (stencil!=DA_STENCIL_BOX)
147 | {
148 | SETERRQ (PETSC_ERR_ARG_WRONGSTATE, "DA must have a box stencil");
149 | }
150 | ierr = DAGetCorners (theda, &xs,&ys,&zs, &xm,&ym,&zm); CHKERRQ (ierr);
151 | ierr = DAGetGhostCorners (theda, &gxs,&gys,&gzs, &gxm,&gym,&gzm);
152 | CHKERRQ (ierr);
153 |
154 | /* Get the local array of points, with ghosts */
155 | ierr = VecGetArray (localX, &x); CHKERRQ (ierr);
156 |
157 | /* Calculate local physical size */
158 | localminmax[0] = minmax[0] + (minmax[1]-minmax[0])*xs/xw;
159 | localminmax[1] = minmax[0] + (minmax[1]-minmax[0])*(xs+xm)/xw;
160 | localminmax[2] = minmax[2] + (minmax[3]-minmax[2])*ys/yw;
161 | localminmax[3] = minmax[2] + (minmax[3]-minmax[2])*(ys+ym)/yw;
162 | localminmax[4] = minmax[4] + (minmax[5]-minmax[4])*zs/zw;
163 | localminmax[5] = minmax[4] + (minmax[5]-minmax[4])*(zs+zm)/zw;
164 |
165 | /* If the array is too big, cut it down to size */
166 | if (gxm <= xs-gxs+xm)
167 | xm = gxm-xs+gxs-1;
168 | if (gym <= ys-gys+ym)
169 | ym = gym-ys+gys-1;
170 | if (gzm <= zs-gzs+zm)
171 | zm = gzm-zs+gzs-1;
172 |
173 | /* Let 'er rip! */
174 | ierr = Draw3DBlock (gxm,gym,gzm, xs-gxs,ys-gys,zs-gzs, xm,ym,zm, localminmax,
175 | x+this, fields, n_quants, isoquants, colors);
176 | CHKERRQ (ierr);
177 | ierr = VecRestoreArray (localX, &x); CHKERRQ (ierr);
178 |
179 | /* This debugging information may be useful to someone at some point;
180 | note that it requires "extern int num_triangles;" somewhere above. */
181 | /* {
182 | int rank;
183 | ierr = MPI_Comm_rank (PETSC_COMM_WORLD, &rank); CHKERRQ (ierr);
184 | ierr = PetscSynchronizedPrintf
185 | (PETSC_COMM_WORLD, "[%d] zs=%d, zm=%d, zmin=%g, zmax=%g\n",
186 | rank, zs, zm, localminmax[4], localminmax[5]); CHKERRQ (ierr);
187 | ierr = PetscSynchronizedFlush (PETSC_COMM_WORLD); CHKERRQ (ierr);
188 | ierr = PetscSynchronizedPrintf (PETSC_COMM_WORLD, "[%d] Triangles: %d\n",
189 | rank, num_triangles); CHKERRQ (ierr);
190 | ierr = PetscSynchronizedFlush (PETSC_COMM_WORLD); CHKERRQ (ierr);
191 | } */
192 |
193 | return 0;
194 | }
195 |
196 |
197 | #undef __FUNCT__
198 | #define __FUNCT__ "IllErrorHandler"
199 |
200 | /*++++++++++++++++++++++++++++++++++++++
201 | Handle errors, in this case the PETSc way.
202 |
203 | int IllErrorHandler Returns the error code supplied.
204 |
205 | int id Index of the error, defined in petscerror.h.
206 |
207 | char *message Text of the error message.
208 | ++++++++++++++++++++++++++++++++++++++*/
209 |
210 | int IllErrorHandler (int id, char *message)
211 | {
212 | SETERRQ (id, message);
213 | exit (1);
214 | }