gpt4 book ai didi

c - Ising 1-Dimensional C - 程序

转载 作者:太空宇宙 更新时间:2023-11-04 06:25:08 25 4
gpt4 key购买 nike

我正在尝试模拟一维伊辛模型。该模型包含自旋链(100 次自旋),并使用 Mont Carlo - Metropolis 在系统能量(单一)下降或小于随机数时接受自旋翻转。在正确的程序中,能量和磁化强度都变为零,我们得到的结果是高斯分布的(能量或磁化强度的图形,由蒙特卡洛步骤数决定)。

我已经做了一些工作,但我认为我的随机生成器对此不正确,而且我不知道如何/在何处实现边界条件:链的最后一个旋转是第一个。我需要帮助才能完成它。欢迎任何帮助。谢谢。我正在粘贴我的 C 程序:

            #include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h> //necessary for function time()
#define LENGTH 100 //size of the chain of spins
#define TEMP 2 // Temperature in units of J
#define WARM 200 // Termalização
#define MCS 20000 //Monte Carlo Steps



void start( int spin[])
{
/* starts with all the spins 1 */
int i;
for (i = 0 ; i < 100; i++)
{
spin[i] = 1;
}
}
double energy( int spin[]) //of the change function J=1
{
int i;
double energyX=0;// because the begining Energy = -J*sum (until 100) =-100,

for (i = 0;i<100;i++)
energyX=energyX-spin[i]*spin[i+1];
return(energyX);
}
int randnum(){
int num;
srand(time(NULL));



/* srand(time(NULL)) objectives to initiate the random number generator
with the value of the function time(NULL). This is calculated as being the
total of seconds passed since january first of 1970 until the present date.
So, this way, for each execution the value of the "seed" will be different.

*/
srand(time(NULL));

//picking one spin randomly zero to 100
num=rand() % 100;
printf("num = %d ", num);
return num;
}
void montcarlo( int spin[])
{
int i,j,num;
double prob;
double energyA, energyB; // A -> old energy and B -> the new energy
int rnum1,rnum2;
prob=exp(-(energyB-energyA)/TEMP);

energyA = 0;
energyB = 0;

for (i = 0;i<100;i++)
{
for (j = 0;j<100;j++)
{

energyA=energy(spin);

rnum1=randnum();
rnum2=randnum(); // i think they will give me different numbers

spin[rnum1] = -spin[rnum1]; //flip of the randomly selected spin

energyB = energyB-spin[j]*spin[j+1];


if ((energyB-energyA<0)||((energyB-energyA>0)&&(rnum2>prob))){ // using rnum2 not to be correlated if i used rnum1
spin[rnum1]=spin[rnum1];} // keep the flip

else if((energyB-energyA>0)&&(rnum2<prob))
spin[rnum1]=-spin[rnum1]; // unflip

}
}

}
int Mag_Moment( int spin[] ) // isso é momento magnetico
{
int i;
int mag;


for (i = 0 ; i < 100; i++)
{
mag = mag + spin[i];

}


return(mag);
}


int main()
{
// starting the spin's chain
int spin[100];//the vector goes til LENGHT=100
int i,num,j;
int itime;
double mag_moment;

start(spin);

double energy_chain=0;
energy_chain=energy(spin); // that will give me -100 in the begining
printf("energy_chain starts with %f", energy_chain);// initially it gives -100
/*Warming it makes the spins not so ordered*/

for (i = 1 ; i <= WARM; i++)
{
itime = i;
montcarlo(spin);
}
printf("Configurtion after warming %d \n", itime);
for (j = 0 ; j < LENGTH; j++)
{
printf("%d",spin[j]);
}

printf("\n");

energy_chain=energy(spin); // new energy after the warming

/*openning a file to save the values of energy and magnet moment of the chain*/

FILE *fp; // declaring the file for the energy
FILE *fp2;// declaring the file for the mag moment
fp=fopen("energy_chain.txt","w");
fp2=fopen("mag_moment.txt","w");

int pures;// net value of i
int a;



/* using Monte Carlo metropolis for the whole chain */
for (i = (WARM + 1) ; i <= MCS; i++)
{
itime=i;//saving the i step for the final printf.
pures = i-(WARM+1);

montcarlo(spin);

energy_chain = energy_chain + energy(spin);// the spin chain is moodified by void montcarlo
mag_moment = mag_moment + Mag_Moment(spin);

a=pures%10000;// here i select a value to save in a txt file for 10000 steps to produce graphs

if (a==0){
fprintf(fp,"%.12f\n",energy_chain); // %.12f just to give a great precision
fprintf(fp2,"%.12f\n",mag_moment);
}


}
fclose(fp); // closing the files
fclose(fp2);

/* Finishing -- Printing */
printf("energy_chain = %.12f\n", energy_chain);
printf("mag_moment = %.12f \n", mag_moment);
printf("Temperature = %d,\n Size of the system = 100 \n", TEMP);
printf("Warm steps = %d, Montcarlo steps = %d \n", WARM , MCS);

printf("Configuration in time %d \n", itime);
for (j = 0 ; j < 100; j++)
{
printf("%d",spin[j]);
}
printf("\n");


return 0;
}

最佳答案

您应该在您的程序中只调用一次 srand(time(NULL));。每次你在同一秒内调用它,你都会得到相同的随机数序列。所以很可能两次调用 randnum 都会给你相同的数字。

只需在 main 的开头添加 srand(time(NULL)); 并将其从其他地方删除。

关于c - Ising 1-Dimensional C - 程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28094157/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com