伊辛模型的C ++模型

2023-09-11 06:31:14 作者:离人心上秋

我正在写一个code C ++中的二维伊辛模型。下面就是code应该做的:

在生成随机N×N个格子,每个站点+1或-1值。 在随机选择一个站点 如果网站时翻转(+1 -1 -1 +1)是较低的能源,翻转状态,即状态。如果DE< 0,翻转状态。如果翻转状态是高能量的,翻转与录取率W = E ^ { - B(DE)}。凡德是能量的变化,如果状态翻转。 4.Do这对所有的N×N的网站,没有重复。这被认为是一次扫描。 请像100扫描。

我在使用步骤1,2和3的麻烦,将AP preciate任何帮助!对于第1步,我设法创建和显示一个格子,但我似乎无法在位置(X,Y)提取网站的价值。步骤2和3,我如何使用某种形式的布尔EX pression根据接受概率翻转?

 的#include< cstdlib>
#包括<的ctime>
使用名字空间std;
#包括<的iostream>
INT主要()//随机生成的自旋配置
{
INT L, //的自旋人员共计数= N×N个
INT N = 30 //正方形长30格
双B = 1; //磁场
双米; //总磁化= SUM硅
双E; //总能量
INT T = 1.0;
INT nsweeps = 100; //扫描次数
INT日;翻转时的能源//改变
双层玻耳兹曼; //玻耳兹曼因子
INT X,Y; //随机选择的格子网站
INT I,J,A,C; //计数器
  INT行数= 5;
  INT COLS = 5;
  INT矩阵[行数] [COLS]
  函数srand(的static_cast&其中;无符号>(时间(0)));
  的for(int i = 0; I<行;我++)
  {
    对于(INT J = 0; J< COLS; J ++)
    {
      矩阵[I] [J] =兰特()%2 * 2-1;
    }
  }

 //显示在屏幕上的矩阵
    的for(int i = 0; I<行;我++)//循环3次,三线
    {
        对于(INT J = 0; J< COLS; J ++)//循环上线的三要素
        {
            COUT<<基质[I] [J]。 //显示当前元件出数组的
        }
    COUT<< ENDL; //当内循环后,进入一个新行
    }
    返回0; //返回0到OS。

//边界条件和范围
如果(X℃,)X + = N;
如果(X> =长)x  -  = N;
如果(Y< 0)Y + = N;
如果(Y> = L)Y  -  = N;

//计算配置的总能量
{INT邻居= 0; //近邻数

   的for(int i = 0; I< L,我++)
      对于(INT J = 0; J< L,J ++)
    {如果(自旋(I,J)==自旋第(i + 1,j))后//从每个自旋到右侧和上述计数
              邻居++;
           其他
              邻居 - ;
           如果(自旋(I,J)==自旋(I,J + 1))
              邻居++;
           其他
              邻居 - ;
    }

    E = -J *邻居 -  B * M;

//翻转旋
INT X = INT(srand48()* L); //检索从随机choosen网站旋
INT Y = INT(srand48()* L);

INT delta_M = -2 *自旋(X,Y); //计算改变磁化强度M
INT delta_neighbour =自旋(spinx-1,y)的自旋+(X + 1,y)的+旋转(X,Y-1)+自旋(X,Y + 1);
INT delta_neighbour = -2 *旋(X,Y)* INT delta_neighbour;

双delta_E = -J * delta_neighbour -B * delta_M;


//翻页或不
如果(delta_E&所述; = 0)
    {(X,Y)* = -1; //翻盖旋和更新值
           M + = delta_M;
           E + = delta_E;

        }



}
 

解决方案

要对我的评论跟进:

  伊辛模型的简介

有太多的问题与你的code为一个单一的答案。尝试   建立一步你的程序步骤。使用职能,执行一个   的东西,这一点,他们做的很好。个别如果测试每个功能   有必要尝试找出为什么它不工作。随后发布的具体   问题了。

为您开始:

存储您的格子为一个的std ::矢量< INT>网格(N * N) 访问元素(X,Y)数据[X + N * Y]

例如:

 的#include<载体>

结构IsingModel
{
    无符号size_;

    的std ::矢量< INT>格子_;

    //存取元件(X,Y)
    INT和放大器;在(INT X,int y)对{
        返回lattice_ [X + Y * size_]。
    }
    在INT(INT X,int y)对常量{
        返回lattice_ [X + Y * size_]。
    }

    //生成大小为x的大小格
    IsingModel(无符号的尺寸)
    :size_(大小),lattice_(尺寸*尺寸,+ 1){
    }

    静态INT BoolToSpin(布尔V){
        返回V' +1:-1;
    }

    //随机初始化旋
    无效initializeRandom(){
        对于(INT Y = 0; Y< size_; Y ++){
            为(中间体X = 0 X  - 其中; size_; X ++){
                在(X,Y)= BoolToSpin(兰特()%2);
            }
        }
    }

    静态INT能源(INT A,INT B){
        返回(A == B)? +1:-1;
    }

    //计算总能量
    无符号computeTotalEnergy()const的{
        无符号的能量= 0;
        对于(INT Y = 1; Y< size_-1; Y ++){
            为(中间体X = 1; X&所述; size_-1; X ++){
                能量+ =能源(于(x,y)时,于(x + 1,y))为;
                能量+ =能源(于(x,y)时,在(X,Y + 1));
            }
        }
        返回的能量;
    }

 };

 #包括<的iostream>
 #包括< cstdlib>
 #包括<的ctime>

 诠释的main(){
     函数srand(的static_cast&其中;无符号>(时间(0))); // intialize随机数发生器
     IsingModel即时(10);
     im.initializeRandom();
     无符号的能量= im.computeTotalEnergy();
     性病::法院<<能源<<的std :: ENDL; //打印能量
 }
 

I'm writing a code in C++ for a 2D Ising model. Here's what the code should do:

Generate random NxN lattice, with each site either +1 or -1 value. Select a site at random If site when flipped (+1 to -1 or -1 to +1) is a state of lower energy, flip state ie. if dE < 0, flip state. If flipped state is of higher energy, flip with acceptance rate w = e^{-b(dE)}. Where dE is the change in energy if state is flipped. 4.Do this for all NxN sites, without repetition. This is considered one sweep. Do like 100 sweeps.

I'm having trouble with steps 1, 2 and 3, would appreciate any help! For step 1, I managed to create and display a lattice, but I can't seem to extract the value of a site at location (x, y). Steps 2 and 3, how do I use a boolean expression of some sort to flip according to acceptance probability?

 #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;

        }



}

解决方案

To follow up on my comment:

There are too many issues with your code for a single answer. Try to build your program step by step. Use functions which perform one thing, and this they do well. Test each function individually and if necessary try to find out why it does not work. Then post specific questions again.

To get you started:

Store your lattice as a std::vector<int> lattice(N*N) Access element (x,y) with data[x+N*y].

Example:

#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
 }