-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathpotts.cpp
More file actions
168 lines (124 loc) · 4.77 KB
/
potts.cpp
File metadata and controls
168 lines (124 loc) · 4.77 KB
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
/*
This program will simulate a two-dimensional potts-model.
*/
#include "ising.hpp"
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
#include "string"
using namespace std;
void readFile(string fileName) {
ifstream myReadFile;
myReadFile.open(fileName);
}
void MonteCarloSim(Lattice myLattice,int nCycles) {
ofstream energyFile;
energyFile.open("potts.out");
energyFile << "#iCycle \t Energy \t Magnetization[0] \t Magnetization[1] \t Magnetization[2] \n";
int nSpins = pow(myLattice.getSideLength(),2);
int sampleTime = 1;
int attemptedMoves = 0;
int acceptedMoves = 0;
float oldEnergy = myLattice.calcTotalEnergy();
float oldMagnetization [3] = {0.0, 0.0, 0.0};
float newEnergy = 0.0;
float newMagnetization = 0.0;
float preFlipEnergy = 0.0;
float postFlipEnergy = 0.0;
int spinPreFlip = 0;
int spinPostFlip = 0;
float deltaE = 0.0;
float deltaS = 0.0;
// oldMagnetization contains the net # of spins aligned with each direction
myLattice.calcMagnetization(oldMagnetization);
energyFile << "0\t" + std::to_string(oldEnergy) + "\t" +
std::to_string(oldMagnetization[0]/nSpins) + "\t" +
std::to_string(oldMagnetization[1]/nSpins) + "\t" +
std::to_string(oldMagnetization[2]/nSpins) + "\n";
std::cout << "Energy of lattice at the beginning = " << oldEnergy << endl;
std::cout << "Magnetization of lattice at the beginning = "
<< oldMagnetization[0]/nSpins << ","
<< oldMagnetization[1]/nSpins << ","
<< oldMagnetization[2]/nSpins << endl;
myLattice.printLattice();
//Loop over the designated number of MCSweeps
for (int iCycle = 0; iCycle < nCycles; iCycle++) {
//For each sweep, loop through entire lattice
for (int idex = 0; idex < myLattice.getSideLength(); idex++){
for (int jdex = 0; jdex < myLattice.getSideLength(); jdex++){
attemptedMoves = attemptedMoves + 1;
/*
With the Potts model and # states > 2, we must calculate the deltaE
of the spin flip explicitly, due to the possible interactions.
*/
preFlipEnergy = myLattice.calcDifferenceInEnergy(idex,jdex);
spinPreFlip = myLattice.getSpin(idex,jdex);
myLattice.flipSpin(idex,jdex);
postFlipEnergy = myLattice.calcDifferenceInEnergy(idex,jdex);
spinPostFlip = myLattice.getSpin(idex,jdex);
deltaE = postFlipEnergy - preFlipEnergy;
newEnergy = oldEnergy + deltaE;
if (newEnergy > oldEnergy){
double randNum = (double)rand()/(double)RAND_MAX;
// compare new energy to a thermal distribution
if (randNum <= exp(-1.0/myLattice.getTemperature())*(newEnergy - oldEnergy)) {
acceptedMoves = acceptedMoves + 1;
oldEnergy = newEnergy;
oldMagnetization[spinPreFlip - 1] -= 1;
oldMagnetization[spinPostFlip - 1] += 1;
}
// new energy is too large when compared to a thermal distribution
// flip spin again to go back to old configuration.
else {
myLattice.revertSpin(idex,jdex, spinPreFlip);
}
}
// if the new energy configuration is lower than old, keep the move
else {
acceptedMoves = acceptedMoves + 1;
oldEnergy = newEnergy;
oldMagnetization[spinPreFlip - 1] -= 1;
oldMagnetization[spinPostFlip - 1] += 1;
}
} // idex loop
} // jdex loop
energyFile << std::to_string(iCycle+1) + "\t" +
std::to_string(oldEnergy) + "\t" +
std::to_string(oldMagnetization[0]/nSpins) + "\t" +
std::to_string(oldMagnetization[1]/nSpins) + "\t" +
std::to_string(oldMagnetization[2]/nSpins) + "\n";
}// iCycle loop
myLattice.calcMagnetization(oldMagnetization);
std::cout << "Magnetization of lattice at the end = "
<< oldMagnetization[0] << "," << oldMagnetization[1] << ","
<< oldMagnetization[2] << endl;
std::cout << "Printing out lattice after all MC steps are completed" << endl;
myLattice.printLattice();
std::cout << "Energy at end = " << oldEnergy << endl;
std::cout << "attemptedMoves = " << attemptedMoves << endl;
std::cout << "acceptedMoves = " << acceptedMoves << endl;
ofstream latticeOutFile;
latticeOutFile.open("latticeConfig.out");
latticeOutFile << "#Configuration of the lattice after simulation \n";
for (int idex = 0; idex < myLattice.getSideLength(); idex++){
latticeOutFile << " ";
for (int jdex = 0; jdex < myLattice.getSideLength(); jdex++){
latticeOutFile << std::to_string(myLattice.getSpin(idex,jdex)) + " ";
}
latticeOutFile << "\n";
}
}
int main() {
// string fileName;
// std::cout << "Please enter a file name to be read in." << endl;
// std::cin >> fileName;
// readFile(fileName);
Lattice myLattice;
myLattice.initializeLattice();
int nCycles;
std::cout << "Please enter the number of Monte Carlo Sweeps:" << endl;
std::cin >> nCycles;
MonteCarloSim(myLattice, nCycles);
return 0;
}