-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhydrogen.cpp
131 lines (112 loc) · 2.76 KB
/
hydrogen.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
#include <stdio.h>
#include <cmath>
#include <iostream>
#include <fstream>
#include <cstdlib>
#define N 400
#define thermloops 4000
#define measureloops 30000
#define datainterval 100
#define acceptanceinterval 50
#define minacceptance 0.2
#define maxacceptance 0.4
#define acceptancescale 1.1
double dmax=0.01; //Maximum discplacement
double alpha;
double acceptance=0;
double walker[N][3];
void placewalkers();
int trialmove(int j);
void savedata();
double norm(double particles[]);
using namespace std;
int main(int argc, char * argv[])
{
srand48((long)time(NULL));
if (argc!=2)
{
cout << "There must be an input parameter for alpha\n";
return 1;
}
alpha = atof(argv[1]);
//Create initial data storage file
ofstream file("data.dat");
file.close();
placewalkers();
for (int i=0; i<thermloops;i++)
{
acceptance=0;
for (int j=0;j<N;j++)
{
acceptance += trialmove(j);
//if (j<10) cout << walker[j] << " \t";
}
//cin.ignore();
if (i%acceptanceinterval == 0)
{
if (acceptance < minacceptance * N) dmax /= acceptancescale;
else if (acceptance > maxacceptance * N) dmax *= acceptancescale;
}
}
cout << "Finished Thermalization\n";
for (int i=0; i<measureloops;i++)
{
acceptance=0;
for (int j=0;j<N;j++)
{
acceptance += trialmove(j);
}
if (i%datainterval==0) savedata();
if (i%acceptanceinterval == 0)
{
if (acceptance < minacceptance * N) dmax /= acceptancescale;
else if (acceptance > maxacceptance * N) dmax *= acceptancescale;
}
}
cout << "Finished simulation\n";
return 0;
}
void savedata()
{
double energy=0;
for (int i=0;i<N;i++)
energy += -1./norm(walker[i]) - 0.5 * alpha * (alpha - 2./norm(walker[i]));
energy/=N;
ofstream file("data.dat",fstream::app);
file << energy << " " << dmax << " " << acceptance << endl;
file.close();
}
int trialmove(int j)
{
double newpos[3];
newpos[0] = walker[j][0] + 2 * (drand48() - 0.5) * dmax;
newpos[1] = walker[j][1] + 2 * (drand48() - 0.5) * dmax;
newpos[2] = walker[j][2] + 2 * (drand48() - 0.5) * dmax;
//double psiold=exp(-alpha * walker[j]*walker[j]);
//double psinew = exp(- alpha * (walker[j] + displacement) * (walker[j] + displacement);
//double prob = exp(-2 *alpha * ( d[0] * (2 * walker[j][0] + d[0]) + d[1] * (2 * walker[j][1] + d[1]) + d[2] * (2 * walker[j][2] + d[2]) ) );
double prob = exp(-2 *alpha * ( norm(newpos) - norm(walker[j]) ) );
if (prob > 1 || prob > drand48())
{
walker[j][0] = newpos[0];
walker[j][1] = newpos[1];
walker[j][2] = newpos[2];
return 1;
}
else
return 0;
}
void placewalkers()
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < 3; j++)
{
walker[i][j] = drand48() - 0.5;
}
}
}
double norm(double particle[])
{
return sqrt(particle[0]*particle[0] + particle[1]*particle[1] + particle[2]*particle[2]);
}