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