File: utility.c

package info (click to toggle)
illuminator 0.10.0-4
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 2,488 kB
  • ctags: 671
  • sloc: sh: 8,903; ansic: 6,285; makefile: 252
file content (194 lines) | stat: -rw-r--r-- 6,315 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/***************************************
  $Header: /cvsroot/petscgraphics/utility.c,v 1.6 2005/04/19 01:35:14 hazelsct Exp $

  This file contains small utility functions for various aspects of
  visualization and storage.
  ***************************************/


#include "config.h" /* esp. for inline */
#include "illuminator.h" /* Just to make sure the interface is "right" */

/* Build with -DDEBUG for debugging output */
#undef DPRINTF
#ifdef DEBUG
#define DPRINTF(fmt, args...) PetscPrintf (PETSC_COMM_WORLD, "%s: " fmt, __FUNCT__, args)
#else
#define DPRINTF(fmt, args...)
#endif


#undef __FUNCT__
#define __FUNCT__ "auto_scale"

/*++++++++++++++++++++++++++++++++++++++
  Determine a sensible scale for plotting, returned in *scale.  If a scalar
  field, returns the minimum and maximum; if a vector field, returns the
  minimum and maximum magnitudes (in 1-D, just plain minimum and maximum); if a
  ternary, returns the corners of the smallest equilateral triangle in ternary
  space in which all of the data fit.

  int auto_scale Returns zero or an error code.

  PetscScalar *global_array Array with values to scan for scale.

  int points Number of points in array to scan.

  int num_fields Number of fields in array.

  int display_field This display field (at least the start).

  field_plot_type fieldtype Type of field.

  int dimensions Number of dimensions.

  PetscScalar *scale Array in which to return the minimum/maximum values.
  ++++++++++++++++++++++++++++++++++++++*/

int auto_scale
(PetscScalar *global_array, int points, int num_fields, int display_field,
 field_plot_type fieldtype, int dimensions, PetscScalar *scale)
{
  int i;

  if (scale == NULL)
    SETERRQ (PETSC_ERR_ARG_BADPTR, "Invalid null pointer");

  if ((fieldtype == FIELD_VECTOR || fieldtype == FIELD_VECTOR+1) &&
      dimensions == 1)
    fieldtype = FIELD_SCALAR;

  switch (fieldtype)
    {
    case FIELD_SCALAR:
    case FIELD_SCALAR+1:
      {
	scale [0] = scale [1] = global_array [display_field];
	for (i=1; i<points; i++)
	  {
	    scale [0] = PetscMin
	      (scale [0], global_array [i*num_fields + display_field]);
	    scale [1] = PetscMax
	      (scale [1], global_array [i*num_fields + display_field]);
	  }
	return 0;
      }
    case FIELD_TERNARY:
      {
	/* Find the minimum x and y, and maximum sum, then fill in corners. */
	PetscScalar maxxpy =
	  global_array [display_field] + global_array [display_field+1];
	scale[0] = global_array [display_field];
	scale[1] = global_array [display_field+1];
	for (i=1; i<points; i++)
	  {
	    scale [0] = PetscMin
	      (scale[0], global_array [i*num_fields + display_field]);
	    scale [1] = PetscMin
	      (scale[1], global_array [i*num_fields + display_field+1]);
	    maxxpy = PetscMax
	      (maxxpy, global_array [i*num_fields + display_field] +
	       global_array [i*num_fields + display_field+1]);
	  }
	scale [2] = maxxpy - scale [1];
	scale [3] = scale [1];
	scale [4] = scale [0];
	scale [5] = maxxpy - scale [0];
	return 0;
      }
    case FIELD_TERNARY_SQUARE:
      {
	scale [0] = scale [1] = global_array [display_field];
	scale [2] = scale [3] = global_array [display_field+1];
	for (i=1; i<points; i++)
	  {
	    scale [0] = PetscMin
	      (scale [0], global_array [i*num_fields + display_field]);
	    scale [1] = PetscMax
	      (scale [1], global_array [i*num_fields + display_field]);
	    scale [2] = PetscMin
	      (scale [2], global_array [i*num_fields + display_field+1]);
	    scale [3] = PetscMax
	      (scale [3], global_array [i*num_fields + display_field+1]);
	  }
	return 0;
      }
    case FIELD_VECTOR:
    case FIELD_VECTOR+1:
      scale++;
    case FIELD_TENSOR_SHEAR:
      {
	/* Find the maximum square magnitude, then sqrt it. */
	scale[0] =
	  global_array [display_field] * global_array [display_field] +
	  global_array [display_field+1] * global_array [display_field+1] +
	  ((dimensions < 3) ? 0. :
	   global_array [display_field+2] * global_array [display_field+2]);
	for (i=1; i<points; i++)
	  {
	    scale[0] = PetscMax 
	      (scale [0], global_array [i*num_fields + display_field] *
	       global_array [i*num_fields + display_field] +
	       global_array [i*num_fields + display_field+1] *
	       global_array [i*num_fields + display_field+1] +
	       ((dimensions < 3) ? 0. :
		global_array [i*num_fields + display_field+2] *
		global_array [i*num_fields + display_field+2]));
	  }
	scale [0] = sqrt (scale [0]);
	return 0;
      }
    }
  SETERRQ (PETSC_ERR_ARG_OUTOFRANGE, "Field type not yet supported");
}


#undef __FUNCT__
#define __FUNCT__ "field_indices"

/*++++++++++++++++++++++++++++++++++++++
  Given an array of
  +latex+{\tt field\_plot\_type} enums, fill (part of) the {\tt indices}
  +html+ <tt>field_plot_type</tt> enums, fill (part of) the <tt>indices</tt>
  array with integers pointing to the true variable starts.  For example, in
  2-D with a vector field (two fields), a scalar field (one field), a symmetric
  tensor field (three fields) and a ternary composition field (two fields) for
  a total of 8 fields, this will fill the indices array with the values 0, 2,
  3, 6 and pad the rest of indices with -1, indicating when those true field
  variables start in the overall set of field variables.

  int nfields Total number of fields.

  int ds Dimensionality of the space (used to determine the number of fields
  used for a vector or tensor field).

  field_plot_type *plottypes Array of
  +latex+{\tt field\_plot\_type} enums with length {\tt nfields}.
  +html+ <tt>field_plot_type</tt> enums with length <tt>nfields</tt>.

  int *indices Array to hold the return values.
  ++++++++++++++++++++++++++++++++++++++*/

void field_indices (int nfields, int ds, field_plot_type *plottypes,
		    int *indices)
{
  int i, j;
  for (i=0, j=0; i<nfields; i++, j++)
    {
      indices [j] = i;
      if (plottypes [i] == FIELD_VECTOR ||
	  plottypes [i] == FIELD_VECTOR+1)
	i += ds-1;
      else if (plottypes [i] == FIELD_TERNARY ||
	       plottypes [i] == FIELD_TERNARY_SQUARE)
	i += 1;
      else if (plottypes [i] == FIELD_TENSOR_FULL)
	i += ds*ds-1;
      else if (plottypes [i] == FIELD_TENSOR_SYMMETRIC)
	i += ds*(ds+1)/2 -1;
      else if (plottypes [i] == FIELD_TENSOR_SHEAR)
	i += ds*(ds+1)/2 -2;
    }
  while (j<i)
    indices [j++] = -1;
}