-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path2DIsing.cpp
232 lines (197 loc) · 6.84 KB
/
2DIsing.cpp
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/*
This Program perform a single spin flip Glauber Dynamics simulation of the Ising
Magnetic system, by the technique of Monte Carlo
Andres Henao Aristizabal
Physics Engineer- Universidad Nacional de Colombia
Studying Master in Computational Physics- Universitat Politecnica Catalunya, Unversitat Barcelona
*/
#include <iostream>
#include <fstream> //Contiene la función para escribir ficheros .txt
#include <cmath>
#include <ctime> // define time()
#include "randomc.h" //Library with the Random Number Generators
/*To compile put in the same directory of the .cpp the library randomc.h, mersenne.o, userintf.o
and write:
g++ 2DIsing_principal.cpp -o 2DIsing mersenne.o usernintf.o
The codes mersenne.cpp and userintf.cpp are constructed as .o to avoid the warnings on the differences between C and C++*/
using namespace std;
void usage ( void )
{
cout<<"\n--------------------------------------------------------------------------------"<<endl;
cout<<"\t\t\tMonte Carlo Simulation of\n\t\t\t the Ising Model\n";
cout<<"\n\t\t\t Written by Andres Henao";
cout<<"\n\t Master in Computational and Applied Physics\n\t\t\t UPC-UB June 2011\n\n";
cout<<"./2DIsing usage:\n";
cout<<">> 2DIsing [options]\n\n";
cout<<"Options:\n";
cout<<"\t-d\t[integer]\tDimension\n";
cout<<"\t-L\t[integer]\tLinear Size\n";
cout<<"\t-T\t[real]\t\tTemperature\n";
cout<<"\t-nmcs\t[integer]\tNumber of MonteCarlo steps\n";
cout<<"\t-nmeas\t[integer]\tNumber of MC steps between successive measures\n";
cout<<"\t-seed\t[integer]\tSeed of the random number generator\n";
cout<<"\t-h \t\t\tPrint this info\n";
cout<<"--------------------------------------------------------------------------------\n"<<endl;
}
/********************Initialization of Variables****************/
int qq,kk;//The random spin to change
float r,p,J=1,h=0;//Random number, probability, exchange constant, external field
double Hd,delta;//To measure delta of energy
int d=2;
double L=20;
float T=2.0;
double nmcs=1e5;
int nmeas=1;
int seed=0;
double N;
int n;
double energy=0,magnet=0;
ofstream a1("Energy.txt"); //Put here the name of the energy output
ofstream a2("Magnet.txt"); //Put here the name of the Magnet output
/****************************************************************/
/******Here we parse the command line arguments; If you add an option, document it in the usage() function!****/
void read(int argc, char *argv[])
{
for (int i = 1; i < argc; i++) {
if (!strcmp(argv[i],"-d")) d = atoi(argv[++i]);
else if (!strcmp(argv[i],"-L")) L = atof(argv[++i]);
else if (!strcmp(argv[i],"-T")) T = atof(argv[++i]);
else if (!strcmp(argv[i],"-nmcs")) nmcs = atof(argv[++i]);
else if (!strcmp(argv[i],"-nmeas")) nmeas = atoi(argv[++i]);
else if (!strcmp(argv[i],"-seed")) seed = atoi(argv[++i]);
else if (!strcmp(argv[i],"-h"))
{
usage();
exit(0);
}
else {
fprintf(stderr,"Error: Command-line argument '%s' not recognized.\n",
argv[i]);
exit(-1);
}
}
}
/****************************************************************/
CRandomMersenne RanGen(seed); // make instance of random number generator
/****************Initialize the Lattice***************************/
void initialize_square(int *spinij[],int n)
{
for(int i=1;i<=n;i++) //Initial Configuration
{
for(int j=1;j<=n;j++)
{
r= RanGen.Random();
if(r<0.5)
{
spinij[i][j]=1;
magnet+=1;
}
else
{
spinij[i][j]=-1;
magnet-=1;
}
if(i==1){spinij[n+1][j]=spinij[1][j];}//Boundary neighbours
if(i==n){spinij[0][j]=spinij[n][j];}
if(j==1){spinij[i][n+1]=spinij[i][1];}
if(j==n){spinij[i][0]=spinij[i][n];}
}
}
for(int i = 1; i <= n; i++) //Measuring Initial energy
{
for(int j = 1; j <= n; j++)
{
energy=energy-h*spinij[i][j];
if(spinij[i][j]==spinij[i-1][j])
{energy=energy-J;}
else
{energy=energy+J;}
if(spinij[i][j]==spinij[i+1][j])
{energy=energy-J;}
else
{energy=energy+J;}
if(spinij[i][j]==spinij[i][j-1])
{energy=energy-J;}
else
{energy=energy+J;}
if(spinij[i][j]==spinij[i][j+1])
{energy=energy-J;}
else
{energy=energy+J;}
}
}
energy*=0.5;
}
/********************************************************************/
/********************Monte Carlo Update******************************/
void Monte_Carlo(int *spinij[],int n,double N)
{
for(int m = 1; m <= n; m++)
{
for(int o = 1; o <=n; o++)
{
//------------------Chosing a random spin to flip--------------------------//
//qq=RanGen.IRandom(1,n);
//kk=RanGen.IRandom(1,n);//Vamos a cambiar el spin qq,kk
qq=m;
kk=o;
//--------------------Finding the new Hamiltonian--------------------------//
Hd=0;delta=0;
Hd=spinij[qq-1][kk]+spinij[qq+1][kk]+spinij[qq][kk-1]+spinij[qq][kk+1];
delta=2*Hd*spinij[qq][kk]*J + 2*h*spinij[qq][kk];
r= RanGen.Random();
//p=(exp(-(delta)/T));//Metropolis
p=1.0/(1+exp((delta)/T));//Glauber Dynamics
if(r<=p)
{
spinij[qq][kk]=-1*spinij[qq][kk];
magnet+=spinij[qq][kk];
energy+=delta;
if(qq==1&&kk!=1&&kk!=n){spinij[n+1][kk]=-spinij[n+1][kk];}
if(qq==n&&kk!=1&&kk!=n){spinij[0][kk]=-spinij[0][kk];}
if(qq==1&&kk==1){spinij[n+1][n+1]=-spinij[n+1][n+1];}
if(qq==n&&kk==n){spinij[0][0]=-spinij[0][0];}
if(qq==1&&kk==n){spinij[n+1][0]=-spinij[n+1][0];}
if(qq==n&&kk==1){spinij[0][n+1]=-spinij[0][n+1];}
if(kk==1&&qq!=1&&qq!=n){spinij[qq][n+1]=-spinij[qq][n+1];}
if(kk==n&&qq!=1&&qq!=n){spinij[qq][0]=-spinij[qq][0];}
}
}
}
}
/*******************************************************************/
/************************Output Files***************************/
void write(int k, double NN)
{
a1<<k<<"\t"<<"\t"<<energy<<"\t"<<energy/NN<<endl;
a2<<k<<"\t"<<magnet<<"\t"<<magnet/NN<<endl;
}
/**************************************************************/
int main( int argc, char * argv[] )
{
read(argc,&argv[0]);//Reads the Input
N=pow(L,d);
n=int(L);
int **spinij;
spinij=new int*[n+2];
for(int i = 0; i <= n+2; i++)
{
spinij[i]=new int[n+2];
}
initialize_square(spinij,n); //Initialize the Lattice and measures the Initial Conditions
for(int k = 1; k <= nmcs; k++)
{
Monte_Carlo(spinij,n,N);
if(k%nmeas==0){
write(k,N);}
}
a1.close();
a2.close();
//*****Release the memory*********//
for(int i = 0; i <= n; i++){
delete [] spinij[i];}
delete [] spinij;
//********************************//
return 0;
}