1 | /***************************************
2 | $Header$
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_TERNARY_SQUARE:
100 | {
101 | scale [0] = scale [1] = global_array [display_field];
102 | scale [2] = scale [3] = global_array [display_field+1];
103 | for (i=1; i<points; i++)
104 | {
105 | scale [0] = PetscMin
106 | (scale [0], global_array [i*num_fields + display_field]);
107 | scale [1] = PetscMax
108 | (scale [1], global_array [i*num_fields + display_field]);
109 | scale [2] = PetscMin
110 | (scale [2], global_array [i*num_fields + display_field+1]);
111 | scale [3] = PetscMax
112 | (scale [3], global_array [i*num_fields + display_field+1]);
113 | }
114 | return 0;
115 | }
116 | case FIELD_VECTOR:
117 | case FIELD_VECTOR+1:
118 | scale++;
119 | case FIELD_TENSOR_SHEAR:
120 | {
121 | /* Find the maximum square magnitude, then sqrt it. */
122 | scale[0] =
123 | global_array [display_field] * global_array [display_field] +
124 | global_array [display_field+1] * global_array [display_field+1] +
125 | ((dimensions < 3) ? 0. :
126 | global_array [display_field+2] * global_array [display_field+2]);
127 | for (i=1; i<points; i++)
128 | {
129 | scale[0] = PetscMax
130 | (scale [0], global_array [i*num_fields + display_field] *
131 | global_array [i*num_fields + display_field] +
132 | global_array [i*num_fields + display_field+1] *
133 | global_array [i*num_fields + display_field+1] +
134 | ((dimensions < 3) ? 0. :
135 | global_array [i*num_fields + display_field+2] *
136 | global_array [i*num_fields + display_field+2]));
137 | }
138 | scale [0] = sqrt (scale [0]);
139 | return 0;
140 | }
141 | }
142 | SETERRQ (PETSC_ERR_ARG_OUTOFRANGE, "Field type not yet supported");
143 | }
144 |
145 |
146 | #undef __FUNCT__
147 | #define __FUNCT__ "field_indices"
148 |
149 | /*++++++++++++++++++++++++++++++++++++++
150 | Given an array of
151 | +latex+{\tt field\_plot\_type} enums, fill (part of) the {\tt indices}
152 | +html+ <tt>field_plot_type</tt> enums, fill (part of) the <tt>indices</tt>
153 | array with integers pointing to the true variable starts. For example, in
154 | 2-D with a vector field (two fields), a scalar field (one field), a symmetric
155 | tensor field (three fields) and a ternary composition field (two fields) for
156 | a total of 8 fields, this will fill the indices array with the values 0, 2,
157 | 3, 6 and pad the rest of indices with -1, indicating when those true field
158 | variables start in the overall set of field variables.
159 |
160 | int nfields Total number of fields.
161 |
162 | int ds Dimensionality of the space (used to determine the number of fields
163 | used for a vector or tensor field).
164 |
165 | field_plot_type *plottypes Array of
166 | +latex+{\tt field\_plot\_type} enums with length {\tt nfields}.
167 | +html+ <tt>field_plot_type</tt> enums with length <tt>nfields</tt>.
168 |
169 | int *indices Array to hold the return values.
170 | ++++++++++++++++++++++++++++++++++++++*/
171 |
172 | void field_indices (int nfields, int ds, field_plot_type *plottypes,
173 | int *indices)
174 | {
175 | int i, j;
176 | for (i=0, j=0; i<nfields; i++, j++)
177 | {
178 | indices [j] = i;
179 | if (plottypes [i] == FIELD_VECTOR ||
180 | plottypes [i] == FIELD_VECTOR+1)
181 | i += ds-1;
182 | else if (plottypes [i] == FIELD_TERNARY ||
183 | plottypes [i] == FIELD_TERNARY_SQUARE)
184 | i += 1;
185 | else if (plottypes [i] == FIELD_TENSOR_FULL)
186 | i += ds*ds-1;
187 | else if (plottypes [i] == FIELD_TENSOR_SYMMETRIC)
188 | i += ds*(ds+1)/2 -1;
189 | else if (plottypes [i] == FIELD_TENSOR_SHEAR)
190 | i += ds*(ds+1)/2 -2;
191 | }
192 | while (j<i)
193 | indices [j++] = -1;
194 | }