//This program is an implementation of the Metropolis Algorithm for a 2D Ising lattice //50x50 with J=1, k=1, and periodic boundary condition //physical grid is [0,Nmax-1]x[0,Nmax-1] //spins are either -1 or 1 #include #include #define Nmax 5 //max size of lattice /*constants for ran1(long *)*/ #define IA 16807 #define IM 2147483647 #define AM (1.0/IM) #define IQ 127773 #define IR 2836 #define NTAB 32 #define NDIV (1+(IM-1)/NTAB) #define EPS 1.2e-7 #define RNMX (1.0-EPS) int lattice[Nmax][Nmax];//lattice[0..Nmax-1][0..Nmax-1] int endi=Nmax-1; double eng[5];//lookup table for energy changes long seed1,seed2,seed3;//seed for ran1() void metropolis(double ttemp,double *m, double *c); int moveforward(int x_i,int x_j,double *delE); void getboltzfactor(double bbeta); int totalmag(void); double hamiltonian(void); void initialize_lattice(int choice); double ran1(long *); // //stuffs for dianogistic // void printflattice(int); void printfm(double, double); FILE *digfile2; void printlattice(int index) { int i,j; char filename[25]; sprintf(filename,"lattice%d.dat",index); digfile2=fopen(filename,"w"); for(i=0;i0) M+=2;//if new spin is up else M-=2;//if new spin is down } //collecting statistics //avg magnetization Msum+=fabs((double)M); //for specific heat, we need to calculate and Esum+=E; E2sum+=E*E; } Esum/=N; E2sum/=N; *m=Msum/N/(Nmax*Nmax);//average magnetization per spin *c=beta*beta*(E2sum-Esum*Esum)/(Nmax*Nmax);//specific heat of the lattice at temperature ttemp } int moveforward(int x_i,int x_j,double *delE) //if step taken, spin will be flipped here //other output is delE and the count for the Metro step { int nn_i,nn_j; int spinsum; // //calculate E_x-E_x' // //finding energy change from interaction with neighbors of (x_i,x_j) //nn of (i,j) are (i+-1,j+-1) with periodic boundary //left if(!x_i) nn_i=Nmax-1; else nn_i=x_i-1; spinsum=lattice[nn_i][x_j]; //right if(x_i==Nmax-1) nn_i=0; else nn_i=x_i+1; spinsum+=lattice[nn_i][x_j]; //top if(!x_j) nn_j=Nmax-1; else nn_j=x_j-1; spinsum+=lattice[x_i][nn_j]; //bottom if(x_j==Nmax-1) nn_j=0; else nn_j=x_j+1; spinsum+=lattice[x_i][nn_j]; //Now, we take the Metropolis step //delE=2J*s_x*SUM(nn) *delE=2*lattice[x_i][x_j]*spinsum; if(*delE>0) { //delE>0 take the Metropolis step only with prob e^(-beta*delE) if(ran1(&seed1)0.5) lattice[i][j]=1; else lattice[i][j]=-1; } } else { //lattice at T=0 will have all spins in the same direction for(i=0;i delE=2J*2 eng[4]=exp(-bbeta*8.0);//e^(-beta*delE) -> delE=2J*4 } //random number generators double ran1(long *idum) { int j; long k; static long iy=0; static long iv[NTAB]; double temp; if(*idum <= 0 || !iy) { if(-(*idum) < 1) *idum = 1; else *idum = -(*idum); for(j=NTAB+7;j>=0;j--) { k=(*idum)/IQ; *idum=IA*(*idum-k*IQ)-IR*k; if(*idum<0) *idum += IM; if(jRNMX) return RNMX; else return temp; }