root/trunk/matml/src/ternary/book.c

Revision 492, 10.0 kB (checked in by powell, 2 years ago)

Change from free-malloc to realloc should help a bit.

  • Property svn:eol-style set to native
Line 
1/***************************************
2  $Header$
3
4  This function contains "bookkeeping" functions, such as setting up the
5  initial triangle array of compositions, scaling things to reasonable x,y,z,
6  etc.
7  ***************************************/
8
9
10#include "freenergy.h" /*+ Free energy prototypes, typedefs, etc. +*/
11#include "gibbs.h" /*+ Ternary prototypes, typedefs, etc. +*/
12#include <math.h>    /*+ For sqrt(), fmin()/fmax() +*/
13#include <stdlib.h>  /*+ For malloc and free +*/
14
15
16/*+ Macro returning the start of a row in a triangle array +*/
17#define ROWSTART(row) ((row)*(resolution+1) - ((row)*((row)-1))/2)
18
19
20/*++++++++++++++++++++++++++++++++++++++
21  This initializes the compositions
22  +latex+$C_2$ and $C_3$
23  -latex-C2 and C3
24  in an array of points filling a triangle between (A2,A3), (B2,B3) and (C2,C3)
25  in composition space.  It also sets the
26  +latex+{\tt efunc}, $T$ and $P$
27  +html+ <tt>efunc</tt>, <i>T</i> and <i>P</i>
28  fields of each point to -1 to indicate that free energies and derivatives are
29  not yet calculated.
30
31  int init_triangle_array It returns zero or an error code.
32
33  int resolution Resolution of the discretization (number of intervals on a
34  side).
35
36  energy_point *points Array of energy points of size
37  +latex+$(N+1)(N+2)/2$, where $N$ is the resolution.
38  -latex-(N+1)(N+2)/2, where N is the resolution.
39
40  int efunc Energy function index indicating which energy curve this point will
41  be on.
42
43  double A2 First corner C2 value.
44
45  double A3 First corner C3 value.
46
47  double B2 Second corner C2 value.
48
49  double B3 Second corner C3 value.
50
51  double C2 Third corner C2 value.
52
53  double C3 Third corner C3 value.
54  ++++++++++++++++++++++++++++++++++++++*/
55
56int init_triangle_array
57(int resolution, energy_point *points, int efunc,
58 double A2, double A3, double B2, double B3, double C2, double C3)
59{
60  int i,j, index;
61
62  for (i=0; i<resolution; i++)
63    {
64      for (j=0; j<resolution-i; j++)
65        {
66          index = ROWSTART (i) + j;
67          points[index].C2 = A2 + (B2-A2) * ((double) i/resolution) +
68            (C2-A2) * ((double) j/resolution);
69          points[index].C3 = A3 + (B3-A3) * ((double) i/resolution) +
70            (C3-A3) * ((double) j/resolution);
71          points[index].efunc = efunc;
72          points[index].T = points[index].P = -1;
73        }
74      /* Make sure these are exactly on the C2+C3=1 boundary */
75      index = ROWSTART (i) + j;
76      points[index].C2 = A2 + (B2-A2) * ((double) i/resolution) +
77        (C2-A2) * (1.-((double) i/resolution));
78      points[index].C3 = A3 + (B3-A3) * ((double) i/resolution) +
79        (C3-A3) * (1.-((double) i/resolution));
80    }
81  index = (resolution+1)*(resolution+2)/2-1;
82  points[index].C2 = B2;
83  points[index].C3 = B3;
84
85  return 0;
86}
87
88
89/*++++++++++++++++++++++++++++++++++++++
90  This initializes the compositions
91  +latex+$C_2$ and $C_3$
92  -latex-C2 and C3
93  in an array of points filling a rectangle between (A2,A3), (B2,B3) in
94  composition space.  It also sets the
95  +latex+{\tt efunc}, $T$ and $P$
96  +html+ <tt>efunc</tt>, <i>T</i> and <i>P</i>
97  fields of each point to -1 to indicate that free energies and derivatives are
98  not yet calculated.  This is of course trivial compared with the triangle
99  case.
100
101  int init_rect_array It returns zero or an error code.
102
103  int res2 Resolution of the discretization (number of intervals) in the
104  +latex+$C_2$-direction.
105  -latex-C2-direction.
106
107  int res3 Resolution of the discretization (number of intervals) in the
108  +latex+$C_3$-direction.
109  -latex-C3-direction.
110
111  energy_point *points Array of energy points of size
112  +latex+({\tt res2}+1)$\times$({\tt res3}+1).
113  -latex-(res2+1) * (res3+1).
114
115  int efunc Energy function index indicating which energy curve this point will
116  be on.
117
118  double A2 Minimum value of
119  +latex+$C_2$.
120  -latex-C2.
121
122  double A3 Minimum value of
123  +latex+$C_3$.
124  -latex-C3.
125
126  double B2 Maximum value of
127  +latex+$C_2$.
128  -latex-C2.
129
130  double B3 Maximum value of
131  +latex+$C_3$.
132  -latex-C3.
133  ++++++++++++++++++++++++++++++++++++++*/
134
135int init_rectangle_array
136(int res2, int res3, energy_point *points, int efunc,
137 double A2, double A3, double B2, double B3)
138{
139  int i,j;
140
141  for (i=0; i<=res2; i++)
142    for (j=0; j<=res3; j++)
143      {
144        points [j*(res2+1)+i].C2 = A2 + (B2-A2) * ((double) i/res2);
145        points [j*(res2+1)+i].C3 = A3 + (B3-A3) * ((double) j/res3);
146        points [j*(res2+1)+i].efunc = efunc;
147        points [j*(res2+1)+i].T = points [j*res2+i].P = -1;
148      }
149
150  return 0;
151}
152
153
154/*++++++++++++++++++++++++++++++++++++++
155  This function fills an array with vertex indices.
156
157  int init_triangle_vertices It returns zero or an error code.
158
159  int resolution Resolution of the discretization (number of intervals on a
160  side).
161
162  int *vertex_array Array of triangle indices of size
163  +latex+$N^2$, where $N$ is the resolution.
164  +html+ <i>N</i><sup>2</sup>, where <i>N</i> is the resolution.
165
166  int offset Constant to add to vertex indices, usually 0.
167  ++++++++++++++++++++++++++++++++++++++*/
168
169int init_triangle_vertices (int resolution, int *vertex_array, int offset)
170{
171  int i,j, index;
172
173  for (i=0, index=0; i<resolution-1; i++)
174    {
175      for (j=0; j<resolution-i-1; j++)
176        {
177          vertex_array [3*index]   = offset + ROWSTART(i)+j;
178          vertex_array [3*index+1] = offset + ROWSTART(i)+j+1;
179          vertex_array [3*index+2] = offset + ROWSTART(i+1)+j;
180          index++;
181
182          vertex_array [3*index]   = offset + ROWSTART(i)+j+1;
183          vertex_array [3*index+1] = offset + ROWSTART(i+1)+j+1;
184          vertex_array [3*index+2] = offset + ROWSTART(i+1)+j;
185          index++;
186        }
187      vertex_array [3*index]   = offset + ROWSTART(i)+resolution-i-1;
188      vertex_array [3*index+1] = offset + ROWSTART(i)+resolution-i;
189      vertex_array [3*index+2] = offset + ROWSTART(i+1)+resolution-i-1;
190      index++;
191    }
192  vertex_array [3*index]   = offset + ROWSTART(resolution-1);
193  vertex_array [3*index+1] = offset + ROWSTART(resolution-1)+1;
194  vertex_array [3*index+2] = offset + ROWSTART(resolution);
195
196  return 0;
197}
198
199
200/*++++++++++++++++++++++++++++++++++++++
201  This function fills an array with triangle vertex indices, two triangles per
202  rectangular cell.
203
204  int init_rectangle_vertices It returns zero or an error code.
205
206  int res2 Resolution of the discretization (number of intervals) in the
207  +latex+$C_2$-direction.
208  -latex-C2-direction.
209
210  int res3 Resolution of the discretization (number of intervals) in the
211  +latex+$C_3$-direction.
212  -latex-C3-direction.
213
214  int *vertex_array Array of triangle indices of size
215  +latex+2$\times${\tt res2$\times$res3}.
216  -latex-2 * res2 * res3.
217
218  int offset Constant to add to vertex indices, usually 0.
219  ++++++++++++++++++++++++++++++++++++++*/
220
221int init_rectangle_vertices (int res2, int res3, int *vertex_array, int offset)
222{
223  int i,j;
224
225  for (i=0; i<res2; i++)
226    for (j=0; j<res3; j++)
227      {
228        vertex_array [(j*res2+i)*6]   = offset + j*(res2+1)+i;
229        vertex_array [(j*res2+i)*6+1] = offset + j*(res2+1)+i+1;
230        vertex_array [(j*res2+i)*6+2] = offset + (j+1)*(res2+1)+i;
231
232        vertex_array [(j*res2+i)*6+3] = offset + j*(res2+1)+i+1;
233        vertex_array [(j*res2+i)*6+4] = offset + (j+1)*(res2+1)+i+1;
234        vertex_array [(j*res2+i)*6+5] = offset + (j+1)*(res2+1)+i;
235      }
236
237  return 0;
238}
239
240
241/*++++++++++++++++++++++++++++++++++++++
242  This scales the free energy of an array of ternary points to the
243  +latex+$y$-coordinate
244  -latex-y-coordinate
245  and colors the points according to free energy as well.
246
247  int energy_to_visual_array It returns zero or an error code.
248
249  int num_points Number of points in the array
250
251  energy_point *epoints Array of energy points of size
252  +latex+$(N+1)(N+2)/2$, where $N$ is the resolution.
253  -latex-(N+1)(N+2)/2, where N is the resolution.
254
255  visual_point **tpoints Pointer to array of ternary points of size
256  +latex+$(N+1)(N+2)/2$, where $N$ is the resolution.
257  -latex-(N+1)(N+2)/2, where N is the resolution.
258  This is changed by realloc() each time the function is called, so it should
259  be NULL or a valid array.
260
261  double y0 Reference (minimum)
262  +latex+$y$-coordinate value.
263  -latex-y-coordinate value.
264
265  double G0 Free energy corresponding to reference
266  +latex+$y$-coordinate value.
267  -latex-y-coordinate value.
268
269  double y1 Second (maximum)
270  +latex+$y$-coordinate value.
271  -latex-y-coordinate value.
272
273  double G1 Free energy corresponding to second
274  +latex+$y$-coordinate value.
275  -latex-y-coordinate value.
276
277  double *Gmin Optional address to store the minimum free energy in the array
278  on return (NULL if unwanted), used as G0 if both G0 and G1 are zero.
279
280  double *Gmax Optional address to store the maximum free energy in the array
281  on return (NULL if unwanted), used as G1 if both G0 and G1 are zero.
282
283  int square Flag: zero for triangle composition representation, non-zero for
284  square.
285  ++++++++++++++++++++++++++++++++++++++*/
286
287int energy_to_visual_array
288(int num_points, energy_point *epoints, visual_point **tpoints, double y0,
289 double G0, double y1, double G1, double *Gmin, double *Gmax, int square)
290{
291  int i;
292
293  if (!(*tpoints = (visual_point *) realloc
294        (*tpoints, num_points * sizeof (visual_point))))
295    return -1;
296
297  if (G0==0. && G1==0.)
298    {
299      G0 = G1 = epoints[0].G;
300      for (i=0; i<num_points; i++)
301        {
302          G0 = fmin (epoints[i].G, G0);
303          G1 = fmax (epoints[i].G, G1);
304        }
305      if (Gmin)
306        *Gmin = G0;
307      if (Gmax)
308        *Gmax = G1;
309    }
310  else
311    {
312      if (Gmin)
313        {
314          *Gmin = epoints[0].G;
315          for (i=0; i<num_points; i++)
316            *Gmin = fmin (epoints[i].G, *Gmin);
317        }
318      if (Gmax)
319        {
320          *Gmax = epoints[0].G;
321          for (i=0; i<num_points; i++)
322            *Gmax = fmax (epoints[i].G, *Gmax);
323        }
324    }
325
326#define Grel(G) (y0 + (y1-y0) * ((G)-G0) / (G1-G0))
327#define RED(G) (((G)<.25) ? 1. : (((G)<.5) ? 2.-4.*(G) : 0.))
328#define GREEN(G) (((G)<.25) ? 4.*(G) : (((G)<.75) ? 1. : 4.-4.*(G)))
329#define BLUE(G) (((G)<.5) ? 0. : (((G)<.75) ? 4.*(G)-2. : 1.))
330
331  for (i=0; i<num_points; i++)
332    {
333      if (square)
334        {
335          (*tpoints)[i].x = epoints[i].C2;
336          (*tpoints)[i].z = 1.-epoints[i].C3;
337        }
338      else
339        {
340          (*tpoints)[i].x = epoints[i].C2 + 0.5*epoints[i].C3;
341          (*tpoints)[i].z = (1. - epoints[i].C3) * sqrt(3)/2.;
342        }
343      (*tpoints)[i].y = Grel(epoints[i].G);
344      (*tpoints)[i].red   = RED   (Grel (epoints[i].G));
345      (*tpoints)[i].green = GREEN (Grel (epoints[i].G));
346      (*tpoints)[i].blue  = BLUE  (Grel (epoints[i].G));
347      (*tpoints)[i].alpha = 1.;
348    }
349
350  return 0;
351}
Note: See TracBrowser for help on using the browser.