added display rate & max_T -> 3.0 * S
[physik/ising.git] / ising.c
1 /*
2  * ising.c - visualization of ising spins in an N x N lattice
3  *
4  * ... actually N x M
5  *
6  * author: hackbard@hackdaworld.dyndns.org
7  *
8  */
9
10 #define _GNU_SOURCE
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <math.h>
15 #include <time.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <fcntl.h>
19 #include <unistd.h>
20
21 #include "dfbapi.h"
22
23 #define X 200
24 #define Y 200
25 #define I 20
26 #define S 1
27
28 int usage(void)
29 {
30  puts("usage:");
31  puts("");
32  puts("-h \t show this help");
33  puts("-o <file> \t save T - M values to file");
34  puts("-i <value> \t specify itteration value");
35  puts("-x <value> \t # x lattice sites");
36  puts("-y <value> \t # y lattice sites");
37  puts("-s <value> \t spin interaction strength");
38  puts("-r \t run in interactive mode (still in work)");
39  puts("-d <value> \t refresh display rate");
40
41  return 1;
42 }
43
44 int main(int argc, char **argv)
45 {
46  unsigned char *atom;
47  char *arg_v[7];
48  char m_text[64];
49  char t_text[64];
50  char b_text[64];
51  char s_text[64];
52  char output_file[64];
53  int of_fd=0;
54  int max_x,x_c,max_y,y_c;
55  int i;
56  int itt;
57  int count_p;
58  double T;
59  double s;
60  int M=0;
61  double beta;
62  double delta_e;
63  int runfree=0;
64  double max_T;
65  int dr=1;
66
67  /* random stuff*/
68  srand(time(0));
69
70  /* display stuff */
71  d2_lattice d2_l;
72
73  max_x=X;
74  max_y=Y;
75  itt=I;
76  s=S;
77  strcpy(output_file,"");
78  /* parse argv */
79  for(i=1;i<argc;i++)
80  {
81   if(argv[i][0]=='-')
82   {
83    switch(argv[i][1])
84    {
85     case 'x':
86      max_x=atoi(argv[++i]);
87      break;
88     case 'y':
89      max_y=atoi(argv[++i]);
90      break;
91     case 'i':
92      itt=atoi(argv[++i]);
93      break;
94     case 's':
95      s=atof(argv[++i]);
96      break;
97     case 'o':
98      strcpy(output_file,argv[++i]);
99      break;
100     case 'r':
101      runfree=1;
102      break;
103     case 'd':
104      dr=atoi(argv[++i]);
105      break;
106     default:
107      usage();
108      return -1;
109    }
110   } else usage();
111  }
112  
113  /* prepare lattice */          
114  d2_lattice_init(&argc,argv,&d2_l,max_x,max_y);
115  atom=(unsigned char *)(malloc(max_x*max_y*sizeof(unsigned char)));
116  d2_l.status=atom;
117
118  if(strcmp(output_file,""))
119  {
120   of_fd=open(output_file,O_WRONLY|O_CREAT);
121   if(of_fd<1)
122   {
123    puts("can't open output file ...");
124    return -1;
125   }
126  }
127
128  /* begin at T=0 M=1 situation */
129  memset(atom,0,max_x*max_y*sizeof(unsigned char));
130  
131  max_T=3.0*s;
132
133  for(T=.05;T<max_T;T+=.05)
134  {
135   beta=1.0/T; /* k_B = 1 */
136   for(i=0;i<itt;i++)
137   {
138
139  M=0;
140  for(x_c=0;x_c<max_x;x_c++)
141  {
142   for(y_c=0;y_c<max_y;y_c++)
143   {
144    count_p=0;
145    if((*(atom+x_c+((y_c+max_y+1)%max_y)*max_x))&1) ++count_p;
146    if((*(atom+x_c+((y_c+max_y-1)%max_y)*max_x))&1) ++count_p;
147    if((*(atom+((max_x+x_c+1)%max_x)+y_c*max_x))&1) ++count_p;
148    if((*(atom+((max_x+x_c-1)%max_x)+y_c*max_x))&1) ++count_p;
149    if(((*(atom+x_c+y_c*max_x))&1)==0) count_p=4-count_p;
150    delta_e=(2*count_p-4)*s;
151    if(delta_e<0) *(atom+x_c+y_c*max_x)=(*(atom+x_c+y_c*max_x)+1)&1;
152    else
153    {
154     if(1.0*rand()/RAND_MAX<exp(-1.0*delta_e*beta))
155      *(atom+x_c+y_c*max_x)=(*(atom+x_c+y_c*max_x)+1)&1;
156    }
157    if((*(atom+x_c+y_c*max_x))&1) ++M;
158   }
159  }
160  
161  if(i%dr==0)
162  {
163   sprintf(t_text," temp: %.3f",T);
164   arg_v[1]=t_text;
165   sprintf(b_text," beta: %.3f",beta);
166   arg_v[2]=b_text;
167   arg_v[3]=NULL;
168   sprintf(s_text," interaction strength: %.3f",s);
169   arg_v[4]=s_text;
170   arg_v[5]=NULL;
171   sprintf(m_text," magnetization: %.3f",1.0-2.0*M/(max_x*max_y));
172   arg_v[6]=m_text;
173   d2_lattice_draw(&d2_l,0,0,6,arg_v);
174  }
175
176   }
177   if(of_fd) dprintf(of_fd,"%f %f\n",T,1.0-2.0*M/(max_x*max_y));
178  }
179
180  for(T=max_T;T>0;T-=.05)
181  {
182   beta=1.0/T; /* k_B = 1 */
183   for(i=0;i<itt;i++)
184   {
185
186  M=0;
187  for(x_c=0;x_c<max_x;x_c++)
188  {
189   for(y_c=0;y_c<max_y;y_c++)
190   {
191    count_p=0;
192    if((*(atom+x_c+((y_c+max_y+1)%max_y)*max_x))&1) ++count_p;
193    if((*(atom+x_c+((y_c+max_y-1)%max_y)*max_x))&1) ++count_p;
194    if((*(atom+((max_x+x_c+1)%max_x)+y_c*max_x))&1) ++count_p;
195    if((*(atom+((max_x+x_c-1)%max_x)+y_c*max_x))&1) ++count_p;
196    if(((*(atom+x_c+y_c*max_x))&1)==0) count_p=4-count_p;
197    delta_e=(2*count_p-4)*s;
198    if(delta_e<0) *(atom+x_c+y_c*max_x)=(*(atom+x_c+y_c*max_x)+1)&1;
199    else
200    {
201     if(1.0*rand()/RAND_MAX<exp(-1.0*delta_e*beta))
202      *(atom+x_c+y_c*max_x)=(*(atom+x_c+y_c*max_x)+1)&1;
203    }
204    if((*(atom+x_c+y_c*max_x))&1) ++M;
205   }
206  }
207
208  if(i%dr==0)
209  {
210   sprintf(t_text," temp = %.3f",T);
211   arg_v[1]=t_text;
212   sprintf(b_text," beta = %.3f",beta);
213   arg_v[2]=b_text;
214   arg_v[3]=NULL;
215   sprintf(s_text," interaction strength: %.3f",s);
216   arg_v[4]=s_text;
217   arg_v[5]=NULL;
218   sprintf(m_text," magnetization: %.3f",1.0-2.0*M/(max_x*max_y));
219   arg_v[6]=m_text;
220   d2_lattice_draw(&d2_l,0,0,6,arg_v);
221  }
222   
223   }
224   if(of_fd) dprintf(of_fd,"%f %f\n",T,1.0-2.0*M/(max_x*max_y));
225  }
226
227  if(of_fd) close(of_fd);
228
229  getchar();
230
231  return 1;
232 }