一次元イジングモデル
前に書いた2次元のモデルと比較したかったので、
一次元イジングモデルのシュミレーションを行なうコードを書いて見ました。
温度を徐々に変化させながら全体の磁化を出力させています。
結果を見ると2次元の場合に比べて、低い温度(逆温度betaが高いところ)でスピンが揃い初めることが分かります。
理論によれば 一次元の場合有限温度でスピンが揃うことは無いはずですが、系の大きさが有限であるために、beta~4程度でスピンは完全に揃ってしまいました。
#include <iostream> #include <vector> #include <cmath> #include <ctime> using namespace std; typedef vector<int> Sv; const int L = 10000; const int M = 200; const double J = 1.0; const double B = 0.0; double beta = 0; Sv spin(L, 1); double ran() { return (double)rand()/((double)RAND_MAX+1); } double dE(int i,int Pre) { return -J *( Pre - spin[i])* ( (i == 0 ? 0 : spin[i-1]) + (i == L-1 ? 0 : spin[i+1])) -B*(Pre - spin[i]); } void sweep_1(int i) { double r = ran(); int Pre = -spin[i]; double difE = dE(i, Pre); if(difE < 0) { spin[i] = Pre; } else if(r < exp(-beta*difE) ) { spin[i] = Pre; } } void sweep_all() { for(int i = 0; i < L ; i++) { sweep_1(i); } } double cl(int n) { double sum = 0; for(int i = 0; i < L; i++ ) { sum += (double) spin[i] * spin[i]; } return sum; } double magnet() { double sum = 0; for(int i = 0 ; i < M; i++) { for(int s = 0; s < L; s++) { sum += spin[s]; } sweep_all(); } return sum / (M * L); } void output() { for(beta = 0; beta < 10; beta += 0.1) { cout << beta << " " << magnet() << endl; } } int main(int argc, char **argv) { srand( (unsigned)time(NULL)); output(); return 0; }