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