1 | /***************************************
2 | $Header: /cvsroot/petscgraphics/utility.c,v 1.5 2004/11/04 22:47:45 hazelsct Exp $
3 |
4 | This file contains small utility functions for various aspects of
5 | visualization and storage.
6 | ***************************************/
7 |
8 |
9 | #include "config.h" /* esp. for inline */
10 | #include "illuminator.h" /* Just to make sure the interface is "right" */
11 |
12 | /* Build with -DDEBUG for debugging output */
13 | #undef DPRINTF
14 | #ifdef DEBUG
15 | #define DPRINTF(fmt, args...) PetscPrintf (PETSC_COMM_WORLD, "%s: " fmt, __FUNCT__, args)
16 | #else
17 | #define DPRINTF(fmt, args...)
18 | #endif
19 |
20 |
21 | #undef __FUNCT__
22 | #define __FUNCT__ "auto_scale"
23 |
24 | /*++++++++++++++++++++++++++++++++++++++
25 | Determine a sensible scale for plotting, returned in *scale. If a scalar
26 | field, returns the minimum and maximum; if a vector field, returns the
27 | minimum and maximum magnitudes (in 1-D, just plain minimum and maximum); if a
28 | ternary, returns the corners of the smallest equilateral triangle in ternary
29 | space in which all of the data fit.
30 |
31 | int auto_scale Returns zero or an error code.
32 |
33 | PetscScalar *global_array Array with values to scan for scale.
34 |
35 | int points Number of points in array to scan.
36 |
37 | int num_fields Number of fields in array.
38 |
39 | int display_field This display field (at least the start).
40 |
41 | field_plot_type fieldtype Type of field.
42 |
43 | int dimensions Number of dimensions.
44 |
45 | PetscScalar *scale Array in which to return the minimum/maximum values.
46 | ++++++++++++++++++++++++++++++++++++++*/
47 |
48 | int auto_scale
49 | (PetscScalar *global_array, int points, int num_fields, int display_field,
50 | field_plot_type fieldtype, int dimensions, PetscScalar *scale)
51 | {
52 | int i;
53 |
54 | if (scale == NULL)
55 | SETERRQ (PETSC_ERR_ARG_BADPTR, "Invalid null pointer");
56 |
57 | if ((fieldtype == FIELD_VECTOR || fieldtype == FIELD_VECTOR+1) &&
58 | dimensions == 1)
59 | fieldtype = FIELD_SCALAR;
60 |
61 | switch (fieldtype)
62 | {
63 | case FIELD_SCALAR:
64 | case FIELD_SCALAR+1:
65 | {
66 | scale [0] = scale [1] = global_array [display_field];
67 | for (i=1; i<points; i++)
68 | {
69 | scale [0] = PetscMin
70 | (scale [0], global_array [i*num_fields + display_field]);
71 | scale [1] = PetscMax
72 | (scale [1], global_array [i*num_fields + display_field]);
73 | }
74 | return 0;
75 | }
76 | case FIELD_TERNARY:
77 | {
78 | /* Find the minimum x and y, and maximum sum, then fill in corners. */
79 | PetscScalar maxxpy =
80 | global_array [display_field] + global_array [display_field+1];
81 | scale[0] = global_array [display_field];
82 | scale[1] = global_array [display_field+1];
83 | for (i=1; i<points; i++)
84 | {
85 | scale [0] = PetscMin
86 | (scale[0], global_array [i*num_fields + display_field]);
87 | scale [1] = PetscMin
88 | (scale[1], global_array [i*num_fields + display_field+1]);
89 | maxxpy = PetscMax
90 | (maxxpy, global_array [i*num_fields + display_field] +
91 | global_array [i*num_fields + display_field+1]);
92 | }
93 | scale [2] = maxxpy - scale [1];
94 | scale [3] = scale [1];
95 | scale [4] = scale [0];
96 | scale [5] = maxxpy - scale [0];
97 | return 0;
98 | }
99 | case FIELD_VECTOR:
100 | case FIELD_VECTOR+1:
101 | scale++;
102 | case FIELD_TENSOR_SHEAR:
103 | {
104 | /* Find the maximum square magnitude, then sqrt it. */
105 | scale[0] =
106 | global_array [display_field] * global_array [display_field] +
107 | global_array [display_field+1] * global_array [display_field+1] +
108 | ((dimensions < 3) ? 0. :
109 | global_array [display_field+2] * global_array [display_field+2]);
110 | for (i=1; i<points; i++)
111 | {
112 | scale[0] = PetscMax
113 | (scale [0], global_array [i*num_fields + display_field] *
114 | global_array [i*num_fields + display_field] +
115 | global_array [i*num_fields + display_field+1] *
116 | global_array [i*num_fields + display_field+1] +
117 | ((dimensions < 3) ? 0. :
118 | global_array [i*num_fields + display_field+2] *
119 | global_array [i*num_fields + display_field+2]));
120 | }
121 | scale [0] = sqrt (scale [0]);
122 | return 0;
123 | }
124 | }
125 | SETERRQ (PETSC_ERR_ARG_OUTOFRANGE, "Field type not yet supported");
126 | }
127 |
128 |
129 | #undef __FUNCT__
130 | #define __FUNCT__ "field_indices"
131 |
132 | /*++++++++++++++++++++++++++++++++++++++
133 | Given an array of
134 | +latex+{\tt field\_plot\_type} enums, fill (part of) the {\tt indices}
135 | +html+ <tt>field_plot_type</tt> enums, fill (part of) the <tt>indices</tt>
136 | array with integers pointing to the true variable starts. For example, in
137 | 2-D with a vector field (two fields), a scalar field (one field), a symmetric
138 | tensor field (three fields) and a ternary composition field (two fields) for
139 | a total of 8 fields, this will fill the indices array with the values 0, 2,
140 | 3, 6 and pad the rest of indices with -1, indicating when those true field
141 | variables start in the overall set of field variables.
142 |
143 | int nfields Total number of fields.
144 |
145 | int ds Dimensionality of the space (used to determine the number of fields
146 | used for a vector or tensor field).
147 |
148 | field_plot_type *plottypes Array of
149 | +latex+{\tt field\_plot\_type} enums with length {\tt nfields}.
150 | +html+ <tt>field_plot_type</tt> enums with length <tt>nfields</tt>.
151 |
152 | int *indices Array to hold the return values.
153 | ++++++++++++++++++++++++++++++++++++++*/
154 |
155 | void field_indices (int nfields, int ds, field_plot_type *plottypes,
156 | int *indices)
157 | {
158 | int i, j;
159 | for (i=0, j=0; i<nfields; i++, j++)
160 | {
161 | indices [j] = i;
162 | if (plottypes [i] == FIELD_VECTOR ||
163 | plottypes [i] == FIELD_VECTOR+1)
164 | i += ds-1;
165 | else if (plottypes [i] == FIELD_TERNARY)
166 | i += 1;
167 | else if (plottypes [i] == FIELD_TENSOR_FULL)
168 | i += ds*ds-1;
169 | else if (plottypes [i] == FIELD_TENSOR_SYMMETRIC)
170 | i += ds*(ds+1)/2 -1;
171 | else if (plottypes [i] == FIELD_TENSOR_SHEAR)
172 | i += ds*(ds+1)/2 -2;
173 | }
174 | while (j<i)
175 | indices [j++] = -1;
176 | }