0% found this document useful (0 votes)
579 views

An Example of A Simulation 2d Ising Model With C++ PDF

The document describes simulations of the 2D Ising model using a heat bath algorithm on square lattices of varying sizes. It initializes the spins in ordered or disordered configurations, runs simulations for different numbers of loops and measurement intervals, and measures the energy and magnetization over time. It also analyzes the behavior near the critical beta value by running longer simulations and constructing histograms of the magnetization.

Uploaded by

Frans Madah Wau
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
579 views

An Example of A Simulation 2d Ising Model With C++ PDF

The document describes simulations of the 2D Ising model using a heat bath algorithm on square lattices of varying sizes. It initializes the spins in ordered or disordered configurations, runs simulations for different numbers of loops and measurement intervals, and measures the energy and magnetization over time. It also analyzes the behavior near the critical beta value by running longer simulations and constructing histograms of the magnetization.

Uploaded by

Frans Madah Wau
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

An example of a simulation: 2d Ising model

/*
* Slightly adapted from a code (c) Kari Rummukainen.
* Simple 2d Ising model simulation program in c.
* Uses heat bath update.
* Prints out measurements of energy and magnetization.
*
* Needs files: ising_sim.c mersenne.h mersenne_inline.c
*/
#include
#include
#include
#include

<stdio.h>
<stdlib.h>
<math.h>
<sys/time.h>

/* Mersenne twister random number generator */


#include "mersenne.h"
/* Lattice size, adjust */
#define NX 32
#define NY 32
/* How many iterations before each measurement */
#define N_MEASURE 10
/* spin storage and coupling constant*/
static int s[NX][NY];
static double beta;
The variable s[NX][NY] corresponds to x = 1.
/* 2 options to search for the neighbouring locations:
* i - current location, xup(i) - location up to x-dir.
* xup(i) is defined either
* a) as an index array (which is filled at the beginning) or
* b) as a modulo ((i+1) % NX)
* option a) is OK for all lattice sizes; option b) is fast
* only for lattice sizes which are powers of 2! Modulo
* to other powers is very slow.
* a) : define USE_ARRAY
*/

46

#define USE_ARRAY
#ifdef USE_ARRAY
static int x_up[NX],y_up[NY],x_dn[NX],y_dn[NY];
#define xup(i) x_up[i]
#define xdn(i) x_dn[i]
#define yup(i) y_up[i]
#define ydn(i) y_dn[i]

The above is what we use: the arrays will be defined presently.

#else
#define
#define
#define
#define
#endif

xup(i)
xdn(i)
yup(i)
ydn(i)

((i+1) % NX)
((i-1+NX) % NX)
((i+1) % NY)
((i-1+NY) % NY)

char usage[] = "Usage: ising_sim N_LOOPS\n";


void update(void);
void measure(int iter);

The main subroutines.

int main(int argc, char* argv[])


{
struct timeval tv;
struct timezone tz;
int i,x,y,n_loops;
/* require correct number of input arguments
*/
if (argc != 3) {
fprintf(stderr,usage);
exit(0);
}

47

n_loops = atoi(argv[1]);
beta = atof(argv[2]);

/* number of loops */
/* value of beta */

gettimeofday( &tv, &tz );


/* seed the random numbers, using current time */
/* seed_mersenne( tv.tv_sec + tv.tv_usec ); */
/* seed the random numbers, in a reproducible way: */
seed_mersenne( 2003 );
/* critical beta
beta = log(1+sqrt(2.0))/2.0 = 0.4406868; */
#ifdef USE_ARRAY
/* fill up the index array */
for (i=0; i<NX; i++) {
x_up[i] = (i+1) % NX;
x_dn[i] = (i-1+NX) % NX;
}
for (i=0; i<NY; i++) {
y_up[i] = (i+1) % NY;
y_dn[i] = (i-1+NY) % NY;
}
#endif
/* Initial spins - completely ordered, "cold" */
for (x=0; x<NX; x++) for (y=0; y<NY; y++) s[x][y] = 1;
/* Initial spins - completely disordered, "hot"
for (x=0; x<NX; x++) for (y=0; y<NY; y++) {
if (mersenne() < 0.5) s[x][y] = 1; else s[x][y] = -1;
}
*/

The main loop:

for (i=0; i<n_loops; i++) {


update();
if (i % N_MEASURE == 0) measure(i);
}
}

48

void update()
{
int sum,x,y;
double p_plus,p_minus;

/* sum over the neighbour sites - typewriter fashion */


for (x=0; x<NX; x++) for (y=0; y<NY; y++) {
sum = s[xup(x)][y] + s[xdn(x)][y]
+ s[x][yup(y)] + s[x][ydn(y)];
/* Heat
p_plus
p_minus
p_plus

bath update - calculate probability of +-1 */


= exp( (beta) * sum );
/* prob. of +1, unnormalized */
= 1.0/p_plus;
/* and -1 */
= p_plus/(p_plus + p_minus); /* normalized prob of +1 */

/* and choose the state appropriately */


if (mersenne() < p_plus) s[x][y] = 1; else s[x][y] = -1;
}
}

Recall:

0
p(z )


... z

+ + +
z+
1
z+2
z1
z2
h
i
exp Sz (z0 )
.
exp [Sz (+1)] + exp [Sz (1)]

... + Sz (z ) ,

49

void measure(int iter)


{
/* measure energy and magnetization, and print out
*/
int sum,x,y;
double e,m;
/* sum over the neighbour sites - typewriter fashion */
e = m = 0.0;
for (x=0; x<NX; x++) for (y=0; y<NY; y++) {
e += - s[x][y] * (s[xup(x)][y] + s[x][yup(y)]);
m += s[x][y];
}
printf("%d %f %f\n", iter, e/NX/NY, m/NX/NY);
}
/*
*
* To compile:
*
cc -O2 -o ising_sim ising_sim.c mersenne_inline.c -lm
*
* To use:
*
ising_sim #_loops beta > result_file
* (e.g. #_loops = 3000, beta = 0.44)
*
*/

50

NX = NY = 32, n loops = 3000, N MEASURE = 10, hot and cold start.


1

1
32_20_hot.dat using 1:3

= 0.20

32_20_cold.dat using 1:3

0.5

0.5

-0.5

-0.5

-1

-1
0

500

1000

1500

2000

2500

3000

500

1000

1500

32_30_hot.dat using 1:3

= 0.30

0.5

0.5

-0.5

-0.5

-1
500

1000

1500

2000

2500

3000

500

1000

1500

2000

2500

3000

1
32_40_cold.dat using 1:3

0.5

0.5

-0.5

-0.5

-1

-1
0

500

1000

1500

2000

2500

3000

500

1000

1500

2000

2500

3000

1
32_50_hot.dat using 1:3

32_50_cold.dat using 1:3

0.5

0.5

-0.5

-0.5

-1

-1
0

500

1000

1500

2000

2500

3000

500

1000

1500

2000

2500

3000

1
32_60_hot.dat using 1:3

= 0.60

3000

-1
0

32_40_hot.dat using 1:3

= 0.50

2500

32_30_cold.dat using 1:3

= 0.40

2000

32_60_cold.dat using 1:3

0.5

0.5

-0.5

-0.5

-1

-1
0

500

1000

1500

2000

2500

3000

500

1000

1500

2000

2500

3000

51

NX = NY = 64, n loops = 3000, N MEASURE = 10, hot and cold start.


1

1
64_30_hot.dat using 1:3

= 0.30

64_30_cold.dat using 1:3

0.5

0.5

-0.5

-0.5

-1

-1
0

500

1000

1500

2000

2500

3000

500

1000

1500

3000

64_40_cold.dat using 1:3

0.5

0.5

-0.5

-0.5

-1

-1
0

500

1000

1500

2000

2500

3000

500

1000

1500

2000

2500

3000

1
64_50_hot.dat using 1:3

= 0.50

2500

1
64_40_hot.dat using 1:3

= 0.40

2000

64_50_cold.dat using 1:3

0.5

0.5

-0.5

-0.5

-1

-1
0

500

1000

1500

2000

2500

3000

500

1000

1500

2000

2500

3000

52

NX = NY = 64, n loops = 300, N MEASURE = 1, hot and cold start.


1

1
64_44_hot_every.dat using 1:3

= 0.44

64_44_cold_every.dat using 1:3

0.5

0.5

-0.5

-0.5

-1

-1
0

50

100

150

200

250

300

50

100

150

200

250

300

NX = NY = 64, n loops = 30000, N MEASURE = 100, hot and cold start.


1

1
64_44_hot_100.dat using 1:3

= 0.44

64_44_cold_100.dat using 1:3

0.5

0.5

-0.5

-0.5

-1

-1
0

5000

10000

15000

20000

25000

30000

5000

10000

15000

20000

25000

30000

53

NX = NY = 64, n loops = 60000, N MEASURE = 100, cold start; c = 0.4406868 at inf.vol.


1
64_435_cold_big.dat using 1:3

0.5

-0.5

= 0.435

-1
0

10000

20000

30000

40000

50000

60000

1
64_438_cold_big.dat using 1:3

0.5

-0.5

= 0.438

-1
0

10000

20000

30000

40000

50000

60000

1
64_439_cold_big.dat using 1:3

0.5

-0.5

= 0.439

-1
0

10000

20000

30000

40000

50000

60000

1
64_4400_cold_big.dat using 1:3

0.5

-0.5

= 0.440

-1
0

10000

20000

30000

40000

50000

60000

1
64_4410_cold_big.dat using 1:3

0.5

-0.5

= 0.441

-1
0

10000

20000

30000

40000

50000

60000

54

The corresponding histograms:


0.12
64_435_cold_big.histo using 1:2

0.1

0.08

0.06

0.04

0.02

= 0.435

0
-1

-0.5

0.5

0.16
64_438_cold_big.histo using 1:2
0.14

0.12

0.1

0.08

0.06

0.04

0.02

= 0.438

0
-1

-0.5

0.5

0.3
64_439_cold_big.histo using 1:2

0.25

0.2

0.15

0.1

0.05

= 0.439

0
-1

-0.5

0.5

0.2
64_440_cold_big.histo using 1:2
0.18
0.16
0.14
0.12
0.1
0.08
0.06
0.04
0.02

= 0.440

0
-1

-0.5

0.5

0.25
64_441_cold_big.histo using 1:2

0.2

0.15

0.1

0.05

= 0.441

0
-1

-0.5

0.5

55

You might also like