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