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  | }