#pragma hdrstop
#include <condefs.h>
#include<iostream.h>
#include<fstream.h>
#include <stdlib.h>
#include "grainsize.h"
#include <stdio.h>
#include <time.h>
#include <math.h>
#include "sio.h"
USEUNIT("Sio.cpp");
USEUNIT("grainsize.cpp");
//---------------------------------------------------------------------------
ofstream grainsizefile;
class monte2d
{
public:
int data[2000][2000];
int grain;
float en[2000][2000],mo[2000][2000];
int xdis[27],ydis[27],zdis[27];
int xlimit,ylimit;
float eold;
float encoeff;
float mobile;
int mcsnum;
int mcs[1000];
int mcsend;
void init();
void run();
void output();
float energy(int i,int j,int q);
};
void randinit()
{
time_t t;
srand((unsigned) time(&t));
}
void monte2d::init()
{
ifstream ins("emout.dat");
SND(ins);
ins>>grain;
int i;
for(i=1;i<=grain;i++)
{
SND(ins);
int te;
ins>>te;
if (te!=i)
{
cout<<" grain number wrong"<<endl;
exit(1);
}
en[0]=0;
en[0]=0;
for(int j=1;j<=grain;j++)
{
ins>>en[j];
}
}
en[0][0]=0;
mo[0][0]=0;
for( i=1;i<=grain;i++)
{
SND(ins);
int te;
ins>>te;
if (te!=i)
{
cout<<" grain number wrong"<<endl;
exit(1);
}
mo[0]=0;
mo[0]=0;
for(int j=1;j<=grain;j++)
{
ins>>mo[j];
}
}
ins.close();
randinit();
ifstream fdis("distri.dat");
SND(fdis);
fdis>>xlimit;
SND(fdis);
fdis>>ylimit;
for ( i=0;i<xlimit;i++)
for (int j=0;j<ylimit;j++)
{
int t;
fdis>>t;
data[j]=t;
}
int num=0;
for ( i=-1;i<2;i++)
for (int j=-1;j<2;j++)
{
xdis[num]=i;
ydis[num]=j;
num++;
}
}
float monte2d::energy(int i,int j,int q)//negative means energy decrease
{
int i1,j1,k1;
float e1;
int i2,j2,k2;
e1=0;
eold=0;
for (i1=i-1;i1<=i+1;i1++)
for (j1=j-1;j1<=j+1;j1++)
{
if ((i==i1)&&(j==j1))
continue;
if (i1<0)
i2=i1+xlimit;
else if (i1>xlimit-1)
i2=i1-xlimit;
else i2=i1;
if (j1<0)
j2=j1+ylimit;
else if (j1>ylimit-1)
j2=j1-ylimit;
else j2=j1;
if (data[i2][j2]!=q)
e1=e1+en[data[i2][j2]][q];
if (data[i2][j2]!=data[j])
{
eold=eold+en[data[i2][j2]][data[j]];
}
}
e1=e1-eold;
return(e1);
}
void monte2d::run()
{
int mci;
grainsizefile.open("size.dat");
for (mci=0;mci<mcsend;mci++)// one mcs
{
if ((mci%10)==0) cout<<mci<<endl;
for (int i=0;i<xlimit;i++)
for (int j=0;j<ylimit;j++)
{
if(data[j]==0) continue;
int t=rand()%9;
int i1,j1,k1;
int i2,j2,k2;
i1=i+xdis[t];
j1=j+ydis[t];
if ((i==i1)&&(j==j1))
continue;
if (i1<0)
i2=i1+xlimit;
else if (i1>xlimit-1)
i2=i1-xlimit;
else i2=i1;
if (j1<0)
j2=j1+ylimit;
else if (j1>ylimit-1)
j2=j1-ylimit;
else j2=j1;
t=data[i2][j2];
if (t==data[j]) continue;
if (t==0) continue;
float e=energy(i,j,t);
float p;
//cout<<eold<<" "<<e<<endl;
if (eold==0) continue;
if (e<0)
p=1;
else
p=exp(-encoeff*e/eold);
p=p*mo[data[j]][t];
if (p>mobile)
data[j]=t;
}
for( int te=0;te<mcsnum;te++)
{
if (mci==mcs[te])
{
grainsize2d *a=new grainsize2d;
if(!a)
{
exit(4);
}
a->init();
int i,j,k;
for(i=0;i<xlimit;i++)
for(j=0;j<ylimit;j++)
a->area[j]=data[j];
a->xlimit=xlimit;
a->ylimit=ylimit;
// a->calculate(121,104,100);
a->allarea();
grainsizefile<<"MCS= "<<mci<<endl;
grainsizefile<<"Grain number= "<<a->number<<endl;
ifstream tee("te.dat");
for (i=0;i<a->number;i++)
{
int ori,area;
int temp;
tee>>temp>>ori>>area;
grainsizefile<<i<<" "<< ori <<" "<< area<<endl;
}
tee.close();
delete a;
char s[300];
sprintf(s,"mcs%d.dat",mci);
ofstream outf(s);
outf<<"X grids number= "<<xlimit<<endl;
outf<<"Y grids number= "<<ylimit<<endl;
for (int i=0;i<xlimit;i++)
for (int j=0;j<ylimit;j++)
{
outf<<data[j]<<" ";
}
outf.close();
}
}
}
grainsizefile.close();
}
//---------------------------------------------------------------------------
int main()
{
monte2d * tmont=new(monte2d);
if (!tmont)
{
cout<<"not enought memory"<<endl;
exit(1);
}
tmont->encoeff=0.4;
tmont->mobile=0.5;
tmont->mcsend=10001;
tmont->mcsnum=18;
tmont->mcs[0]=1;
tmont->mcs[1]=10;
tmont->mcs[2]=20;
tmont->mcs[3]=50;
tmont->mcs[4]=100;
tmont->mcs[5]=200;
tmont->mcs[6]=500;
tmont->mcs[7]=1000;
tmont->mcs[8]=2000;
tmont->mcs[9]=3000;
tmont->mcs[10]=5000;
tmont->mcs[11]=8000;
tmont->mcs[12]=10000;
tmont->mcs[13]=15000;
tmont->mcs[14]=20000;
tmont->mcs[15]=80;
tmont->mcs[16]=800;
tmont->mcs[17]=300;
tmont->init();
tmont->run();
delete (tmont);
}