用C ++编写Ising模型

时间:2014-04-09 20:51:46

标签: c++ algorithm boolean

我在C ++中为2D Ising模型编写代码。这是代码应该做的事情:

  1. 生成随机NxN网格,每个网站的值为+1或-1。
  2. 随机选择一个网站
  3. 如果翻转时的位置(+1到-1或-1到+1)是能量较低的状态,则翻转状态即。如果dE< 0,翻转状态。如果翻转状态具有更高的能量,则以接受率w = e ^ { - b(dE)}翻转。其中dE是状态被翻转时的能量变化。 4.对所有NxN站点执行此操作,不重复。这被认为是一次扫描。
  4. 喜欢100次扫描。
  5. 我在第1步,第2步和第3步遇到问题,我们将不胜感激!对于第1步,我设法创建并显示一个点阵,但我似乎无法在位置(x,y)提取站点的值。第2步和第3步,如何使用某种类型的布尔表达式根据接受概率进行翻转?

     #include <cstdlib>
    #include <ctime>
    using namespace std;
    #include <iostream>
    int main() //random generation of spin configuration
    {
    int L;              //Total number of spins L = NxN
    int N = 30          //A square lattice of length 30
    double B=1;         //magnetic field
    double M;           //Total Magnetization = Sum Si
    double E;           //Total Energy
    int T = 1.0;
    int nsweeps = 100;      //number of sweeps
    int de;             //change in energy when flipped
    double Boltzmann;       //Boltzmann factor
    int x,y;            //randomly chosen lattice site
    int i,j,a,c;            //counters
      int ROWS = 5;
      int COLS = 5;
      int matrix[ROWS][COLS];
      srand ( static_cast<unsigned> ( time ( 0 ) ) );
      for ( int i = 0; i < ROWS; i++ ) 
      {
        for ( int j = 0; j < COLS; j++ )
        {
          matrix[i][j] = rand () % 2 *2-1;
        }
      }
    
     // showing the matrix on the screen
        for(int i=0;i<ROWS;i++)  // loop 3 times for three lines
        {
            for(int j=0;j<COLS;j++)  // loop for the three elements on the line
            {
                cout<<matrix[i][j];  // display the current element out of the array
            }
        cout<<endl;  // when the inner loop is done, go to a new line
        }
        return 0;  // return 0 to the OS.
    
    //boundary conditions and range
    if(x<0) x += N;      
    if(x>=L) x -= N;
    if(y<0) y += N;
    if(y>=L) y -= N;
    
    //counting total energy of configuration
    {  int neighbour = 0;    // nearest neighbour count
    
       for(int i=0; i<L; i++)
          for(int j=0; j<L; j++)
        {  if(spin(i,j)==spin(i+1, j))     // count from each spin to the right and above 
                  neighbour++;
               else 
                  neighbour--;
               if(spin(i, j)==spin(i, j+1))
                  neighbour++;
               else
                  neighbour--;
        }
    
        E = -J*neighbour - B*M;
    
    //flipping spin
    int x = int(srand48()*L);   //retrieves spin from randomly choosen site
    int y = int(srand48()*L);
    
    int delta_M = -2*spin(x, y);    //calculate change in Magnetization M
    int delta_neighbour = spin(spinx-1, y) + spin(x+1, y)+ spin(x, y-1) + spin(x, y+1);
    int delta_neighbour = -2*spin(x,y)* int delta_neighbour;
    
    double delta_E = -J*delta_neighbour -B*delta_M;
    
    
    //flip or not
    if (delta_E<=0)
        {  (x, y) *= -1;     // flip spin and update values
               M += delta_M;
               E += delta_E;
    
            }
    
    
    
    }
    

1 个答案:

答案 0 :(得分:1)

跟进我的评论:

  

单个答案的代码存在太多问题。尝试   逐步构建您的程序。使用执行一个的功能   事情,他们做得很好。单独测试每个功能,如果   必要的尝试找出它为什么不起作用。然后发布具体   再次提问。

为了帮助您入门:

  • 将您的点阵存储为std::vector<int> lattice(N*N)
  • 使用(x,y)访问元素data[x+N*y]

示例:

#include <vector>

struct IsingModel
{ 
    unsigned size_;

    std::vector<int> lattice_;

    // access element (x,y)
    int& at(int x, int y) {
        return lattice_[x + y*size_];
    }
    int at(int x, int y) const {
        return lattice_[x + y*size_];
    }

    // generate size x size lattice
    IsingModel(unsigned size)
    : size_(size), lattice_(size*size, +1) {
    }

    static int BoolToSpin(bool v) {
        return v ? +1 : -1;
    }

    // initialize spin randomly
    void initializeRandom() {
        for(int y=0; y<size_; y++) {
            for(int x=0; x<size_; x++) {
                at(x,y) = BoolToSpin(rand()%2);
            }
        }
    }

    static int Energy(int a, int b) {
        return (a == b) ? +1 : -1;
    }

    // compute total energy
    unsigned computeTotalEnergy() const {
        unsigned energy = 0;
        for(int y=1; y<size_-1; y++) {
            for(int x=1; x<size_-1; x++) {
                energy += Energy(at(x,y), at(x+1,y));
                energy += Energy(at(x,y), at(x,y+1));
            }
        }
        return energy ;
    }

 };

 #include <iostream>     
 #include <cstdlib>
 #include <ctime>

 int main() {
     srand(static_cast<unsigned>(time(0))); // intialize random number generator
     IsingModel im(10);
     im.initializeRandom();
     unsigned energy = im.computeTotalEnergy();
     std::cout << energy << std::endl; // print energy
 }