24小时热门版块排行榜    

查看: 2422  |  回复: 7
【奖励】 本帖被评价4次,作者zyj8119增加金币 3

[资源] 【转帖】2维无外场Ising模型的Monte Carlo模拟的C++实现

CODE:
// Copyright(c)2010 Ma Chengzhang
#include
#include
#include //tr1随机数调用
#include //设置随机数种子用
#include

using namespace std; //cout,endl等简单语句必须
using namespace std::tr1; //tr1随机数调用

inline unsigned __int64 ReadTSC()//为取到精确的随机数种子,嵌入汇编程序取系统时钟
{
__asm _emit 0x0F
  __asm _emit 0x31
}

double totalE(vector >& SpinGrid,int GridL,double JBound)
{
int nn_count = 0;//最近邻计数
// 每个格点只考虑右键和上键
for(int i=0; i {
  for(int j=0; j   {
   if(SpinGrid[i][j]==SpinGrid[i+1][j]) // 考虑右键
    nn_count++;
   else
    nn_count--;
   if(SpinGrid[i][j]==SpinGrid[i][j+1]) // 考虑上键
    nn_count++;
   else
    nn_count--;
  }
}
//周期性边界情况
for(int i=0; i {
  if(SpinGrid[i][GridL-1]==SpinGrid[i+1][GridL-1]) // 右键
   nn_count++;
  else
   nn_count--;
  if(SpinGrid[i][GridL-1]==SpinGrid[i][0]) // 上键
   nn_count++;
  else
   nn_count--;
}
for(int j=0; j {
  if(SpinGrid[GridL-1][j]==SpinGrid[0][j]) // 右键
   nn_count++;
  else
   nn_count--;
  if(SpinGrid[GridL-1][j]==SpinGrid[GridL-1][j+1]) // 上键
   nn_count++;
  else
   nn_count--;
}
//右上顶点
if(SpinGrid[GridL-1][GridL-1]==SpinGrid[0][GridL-1]) // 右键
  nn_count++;
else
  nn_count--;
if(SpinGrid[GridL-1][GridL-1]==SpinGrid[GridL-1][0]) // 上键
  nn_count++;
else
  nn_count--;
return -JBound*nn_count;
}

void main()
{
//物理常数定义
double kB=1.0; //Boltzmann常数
double JBound=0.5; //交换作用系数
int GridL=20; //网格大小,长宽一样,即 GridL x GridL 网格

mt19937 RandEngine; //Mersenne Twister算法随机数生成器,核心引擎类
unsigned long RandSeed = (unsigned long)ReadTSC(); //用 CPU 时钟作为随机数种子
RandEngine.seed(RandSeed);
uniform_int RandInt(0, GridL-1);//产生0到GridL-1之间的随机整数,
// 含0和GridL-1,即[0,GridL-1]而不是(0,GridL-1)
uniform_real RandFloat(0,1); //产生0到1之间的随机数

double MaxTemp=5.00; //要模拟的最高温度,温度以J/kB为单位,kB是波尔兹曼常数
double MinTemp=0.1; //要模拟的最低温度,温度以J/kB为单位,kB是波尔兹曼常数
unsigned int BeforeEquilSteps=10000; //在达到平衡前要演化的步数
unsigned int TotalSteps=BeforeEquilSteps+10000; //每温度要演化的总步数,包含前面的BeforeEquilSteps
int DiscardedSteps=50; //达到平衡态后,为实现无偏统计抽样,每DiscardedSteps演化步数才统计一次
double TempInterval=0.1; //扫描温度间隔,温度以J/kB为单位,kB是波尔兹曼常数
double beta; //当前beta=1/(kB*T)

vector< vector > SpinGrid(GridL, vector(GridL,-1)); //网格定义,格点初始值都取-1

//统计量定义
double TotalEnergy=0; //网格总能量
double persiteEnergy=0; //每格点能量
double persiteAveEnergy=0; //每格点平均能量
ofstream fileout("Ising2D.dat");

//Monte Carlo 部分
for(double CurrentTemp=MinTemp;CurrentTemp {
  int count=0; //此变量记录达到平衡后演化步数,每当count达到DiscardedSteps时归零
  int Outcount=0; //记录累计统计次数
  int left,right,bottom,top; //辅助变量
  beta=1/(kB*CurrentTemp);
  for(unsigned int mcStep=0;mcStep   {
   //随机选择格点反转自旋,随机数算法取自:C++ tr1 Mersenne Twister算法
   int i=RandInt(RandEngine); //第i列
   int j=RandInt(RandEngine); //第j行

   //采用周期性边界条件
   if(i!=0)
    left = SpinGrid[i-1][j];
   else
    left = SpinGrid[GridL-1][j];
   if(i!=GridL-1)
    right = SpinGrid[i+1][j];
   else
    right = SpinGrid[0][j];
   if(j!=0)
    bottom = SpinGrid[i][j-1];
   else
    bottom = SpinGrid[i][GridL-1];
   if(j!=GridL-1)
    top = SpinGrid[i][j+1];
   else
    top = SpinGrid[i][0];

   int spinSum=top+bottom+left+right;
   //double oldEnergy=-JBound*SpinGrid[i][j]*spinSum;
   //double newEnergy=-oldEnergy;
   double EDiff=2*JBound*SpinGrid[i][j]*spinSum;//EDiff=newEnergy-oldEnergy
   //cout<<"EDiff="<
   //判断是否反转自旋

   if( EDiff<0)
    SpinGrid[i][j]=-SpinGrid[i][j];
   else
   {
    if(RandFloat(RandEngine)      SpinGrid[i][j]=-SpinGrid[i][j];
   }


   //如果mcStep达到了指定步数,就认为达到了平衡态,可以进行状态分析了
   //但是只是每隔DiscardedSteps步数才分析一次
   if(mcStep>BeforeEquilSteps)
   {
    count=count+1;
    if(count==DiscardedSteps)
    {
     count=0; //count归零,重新开始计数

     TotalEnergy=totalE(SpinGrid,GridL,JBound);
     persiteEnergy=TotalEnergy/(GridL*GridL);  
     persiteAveEnergy=(persiteAveEnergy*Outcount+persiteEnergy)/(Outcount+1);
     Outcount++;
    }
   }
  }
  //输出数据到数据文件
  fileout<< CurrentTemp <<" "<
  //统计量归零
  persiteAveEnergy=0;
  Outcount=0;
}
//Monte Carlo 部分结束
fileout.close();
////输出测试
////测试随机整数
//for(int i = 0; i < 50; ++i) //产生均匀分布的在0到19之间的50个整数随机数
//{
// std::cout << RandInt(RandEngine) << endl;
//}
//cout<<"*************"< //for(int i = 0; i < 50; ++i) //产生均匀分布的在0到1之间的50个随机数
//{
// std::cout << RandFloat(RandEngine) << endl;
//}
////测试随机整数毕
//cout< //cout<<"TotalSteps = "< //cout<<"RandSeed = "< ///////////////////////////////////////////////////////////////////////
cout< char c;
cin>>c;
}

下面是用Mathematica处理数据的结果:


[ Last edited by zyj8119 on 2010-9-10 at 17:51 ]
回复此楼

» 收录本帖的淘贴专辑推荐

资源收集 graphene 学习 量子蒙特卡洛模拟

» 猜你喜欢

» 本主题相关价值贴推荐,对您同样有帮助:

已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
★ ★ ★ ★ ★ ★ ★
zh1987hs(金币+5):谢谢yahoohoo的精彩回复 2010-09-10 22:54:51
lei0736(金币+2):谢谢 2010-09-11 08:44:08
引用回帖:
Originally posted by zyj8119 at 2010-09-10 17:49:48:
[code]// Copyright(c)2010 Ma Chengzhang <Machengzhang@126.com>
#include
#include
#include //tr1随机数调用
#include //设置随机 ...

这是你自己写的程序吗?很不错啊,:-)。

这是个巨正则系综下的Monte Carlo模拟,因为总的自旋 $ S = \sum_i {s_i} $ 是变化的。

随机数的种子是无所谓精确与否的,代码中的做法只是为了使得不同的模拟使用不同的随机数序列。

建议将程序模块话,比如 Ising MC的一般模块为:

void INIT(); // Set initial configuration

double totalEnergy(); // Calc total energy

double SpinEnergy(int i, int j); // Energy of a given spin

void flip(); // flip a randomly chosen spin

主程序部分的周期性边界条件处理可以更快:

int iRight = i + 1, iLeft = i - 1, jUp = j + 1, jDown = j - 1;
if (iRight = BOXLX) iRight = 0;
if (iLeft = -1) iLeft = BOXLXM1; // BOXLXM1 = BOXLX - 1;
if (jUp = BOXLY) jUp = 0;
if (jDown = -1) jDown = BOXLYM1; // BOXLYM1 = BOXLY - 1;

这样做的好处是将if else 分支结构转变成单独的if, 既形式简单又速度更快

能量判断可以简单写成如下代码:

double dE = Enew - Eold;
if (dE <= 0 || rng.gen_open0_open1() < exp(-BETA * dE)) { // 这样的好处是如果dE <= 0 成立那么后面的部分就不用计算
  // ACCEPTED
}
else {
  // REJECTED
}

关于能量与温度的关系,建议能量用 $ E/NJ $, 这样的话在低温区,所有的自旋方向一致,那么构象能为 $ E_{min} = -2 N |J| $。所以最低能量应该为 $ E / NJ = -2 $。而在高温区,自旋向上与向下的概率相等,因为每个自旋近邻的四个自旋和为0,因为总能量也为0。根据这两点,模拟得到的结果是有问题的。

[ Last edited by yahoohoo on 2010-9-10 at 21:13 ]
2楼2010-09-10 21:05:59
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
引用回帖:
Originally posted by yahoohoo at 2010-09-10 21:05:59:


这是你自己写的程序吗?很不错啊,:-)。

这是个巨正则系综下的Monte Carlo模拟,因为总的自旋 $ S = \sum_i {s_i} $ 是变化的。

随机数的种子是无所谓精确与否的,代码中的做法只是为了使得不同的模拟使 ...

谢谢建议!!
3楼2010-09-10 22:56:11
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
引用回帖:
Originally posted by yahoohoo at 2010-09-10 21:05:59:


这是你自己写的程序吗?很不错啊,:-)。

这是个巨正则系综下的Monte Carlo模拟,因为总的自旋 $ S = \sum_i {s_i} $ 是变化的。

随机数的种子是无所谓精确与否的,代码中的做法只是为了使得不同的模拟使 ...

不是我写的,我是转帖的。
4楼2010-09-11 12:02:55
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

咔咔咔咔

新虫 (初入文坛)


★★★★★ 五星级,优秀推荐

用vc6.0可以不
5楼2012-04-26 19:13:43
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

yaneehan2010

银虫 (正式写手)


★★★★★ 五星级,优秀推荐

你好,我是刚接触分子模拟的菜鸟,做的是气体分子扩散系数和分子间碰撞情况。我该怎么着手呢?不知道有没有类似的程序可以下载呢?在哪里可以下载的到呀,请指条明路,万分感谢、、
6楼2012-05-23 00:43:45
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

马pi精

新虫 (小有名气)


★★★ 三星级,支持鼓励

楼主试过画出T在0~1内的比热曲线吗? 求交流
7楼2012-08-17 23:18:37
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

quantumage

金虫 (小有名气)


★★★★★ 五星级,优秀推荐

给介绍几本量子monet carlo的学习书籍呗!我也想自己算一下Ising模型,和XY模型!
8楼2013-01-09 00:15:45
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
相关版块跳转 我要订阅楼主 zyj8119 的主题更新
☆ 无星级 ★ 一星级 ★★★ 三星级 ★★★★★ 五星级
普通表情 高级回复(可上传附件)
最具人气热帖推荐 [查看全部] 作者 回/看 最后发表
[教师之家] 试用期辞职 +11 ZHONGWU_U 2024-06-18 20/1000 2024-06-23 08:26 by shl2112501
[考博] 申请25博士,可以提前进组做科研助理 +3 逐梦途中w 2024-06-22 3/150 2024-06-23 01:08 by faine..
[基金申请] 江苏省333人才工程 出校后被刷的概率大不大? +6 maxbirdzhang 2024-06-19 9/450 2024-06-23 00:33 by kobe0107
[硕博家园] 怎么带研究生? +17 豆豆小小2 2024-06-20 18/900 2024-06-23 00:14 by renxiangdzkd
[基金申请] 工材口青年基金大概什么样能上会? +15 今晚推荐22 2024-06-20 21/1050 2024-06-22 23:04 by qbn0326
[公派出国] CSC博士联培对将来就业有用吗 +3 也就这样 2024-06-22 3/150 2024-06-22 22:04 by 326lhpqk
[基金申请] 国自然青年基金,1A4B能上会吗?青年和面上的上会标准是一样的吗? +17 今晚推荐22 2024-06-20 24/1200 2024-06-22 18:45 by 今晚推荐22
[有机交流] 高温酯化反应喷料 20+3 hl24678 2024-06-21 5/250 2024-06-22 16:37 by zyp0009928
[教师之家] 有没有今年的影响因子? +4 jurkat.1640 2024-06-22 6/300 2024-06-22 16:37 by 潇湘之迷
[基金申请] 江南大学到瑞士招聘,称取消非升即走,改预聘+长聘 +24 babu2015 2024-06-18 29/1450 2024-06-22 16:29 by 风今25
[考博] 有机化学迷茫学生 +6 佛系摸鱼5 2024-06-18 11/550 2024-06-22 15:47 by yuanjijoy
[基金申请] 青年和面上,哪个上会难度更大 +12 今晚推荐22 2024-06-21 15/750 2024-06-22 12:12 by 今晚推荐22
[有机交流] 间氨基苯甲酸甲酯合成 5+3 pengdatao 2024-06-19 6/300 2024-06-22 10:58 by zyp0009928
[基金申请] 刚刚收到科研之友邮件 +25 olivermiaoer 2024-06-19 38/1900 2024-06-21 18:46 by 6543yes
[硕博家园] 豫北虫友互识 +13 xuhongli903 2024-06-18 14/700 2024-06-21 18:24 by 雨后春笋!
[论文投稿] 审稿 +8 香瓜木香 2024-06-19 9/450 2024-06-21 15:51 by season7865
[基金申请] 有人中过人文社科类的博后特助吗? +4 outsider1986 2024-06-16 7/350 2024-06-21 09:54 by kyukitu
[有机交流] 怎么萃取出锡盐内包裹的化合物 +4 硕六过 2024-06-19 5/250 2024-06-21 09:50 by 光超嘟嘟
[基金申请] 青年基金会评专家到底是怎么会评的呀?主审专家是不是一般不会改动系统按函评给的顺序 5+4 他山攻玉之石 2024-06-18 18/900 2024-06-20 16:33 by 他山攻玉之石
[基金申请] 太卷了 +14 laoyuefubio 2024-06-17 27/1350 2024-06-20 09:52 by htjwqy
信息提示
请填处理意见