Добавил:
yermolenkoigor9
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Stohastic / NuCleaReactor / main
.c#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define _USE_MATH_DEFINES
#define IA 16807// Минимальный компактный генератор случайных чисел Парка и Миллера
#define IM 2147483647// константы Льюиса-Гудмана-Миллера
#define AM (1./IM)
#define IQ 127773// константы Шаржа
#define IR 2836
#define MASK 123456789// маска чтоб не мешались нули
#define NTAB 32// числa Бейса-Дурхема
#define NWUP 8
#define NDIV (1+(IM-1)/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)
static long dummy;
// начальное значение для всех генераторов
void Seed(long dum) {dummy=dum;}
// возвращает случайное число на промежутке от 0 до 1
float unirand0(void) {
long k;
float ans;
dummy^=MASK;// избегаем dummy==0
k=dummy/IQ;
if((dummy=IA*(dummy-k*IQ)-IR*k)<0) dummy+=IM;
ans=AM*dummy;
dummy^=MASK;// восстанавливаем dummy
return(ans);
}
float unirand1(void) {
int j;
long k;
static long iy=0,iv[NTAB];
float temp;
// инициализация
if(dummy<=0 || !iy) {
// следим, чтобы значение было положительным
if(dummy<0) dummy=-dummy;
else if(dummy==0) dummy=1;
for(j=NTAB+NWUP-1;j>=0;j--) {
k=dummy/IQ;
if((dummy=IA*(dummy-k*IQ)-IR*k)<0) dummy+=IM;
if(j<NTAB) iv[j]=dummy;
}
// первый элемент из таблицы
iy=iv[0];
}
// генерируем новое число
k=dummy/IQ;
if((dummy=IA*(dummy-k*IQ)-IR*k)<0) dummy+=IM;
iy=iv[j=iy/NDIV];iv[j]=dummy;
if((temp=AM*iy)>RNMX) return(RNMX);
else return(temp);
}
int iDel(float *arrayX, float *arrayY, int lenAr, int nom)//функция удаления элемента из массивов
{
int i;
if((nom<lenAr)&&(nom>=0))//если номер удаляемого элемента не входит в размер массива сообщаем об ошибке
{
for(i=nom;i<lenAr-1;i++)
{
arrayX[i] = arrayX[i+1];//двигаем весь массив
arrayY[i] = arrayY[i+1];
}
lenAr--;//уменьшаем размер массива
}
else printf("error\n");//ошибка удаления
return lenAr;
}
int newgeneration(float a, int n, float *x, float *y)//новое поколение
{
float fi,l,P,Pu,Pa,Pf;
int k;
l = 1.7;//длина свободного пробега
Pa = 0.0152;//поглощение нейтрона без деления ядра
Pf = 0.0216;//поглощение нейтрона с делением ядра урана
//ps = 0.9632 − изотропное рассеяние нейтрона
for(k=0;k<n;k++)
{
fi = unirand1()*2*M_PI;//произвольный угол
x[k] += l*cos(fi);
y[k] += l*sin(fi);
if((x[k]>=a*0.5)||(y[k]>=a*0.5)||(x[k]<=-0.5*a)||(y[k]<=-0.5*a)) {n = iDel(x,y,n,k);k--;}//вышел за стенки - поглотился
//if(sqrt(x[k]*x[k]+y[k]*y[k])>=a*0.5) {n = iDel(x,y,n,k);k--;}//вышел за стенки - поглотился на круглом
else
{
P = unirand1();//столкновение с ядром
if(P<Pa) {n = iDel(x,y,n,k);k--;}//поглотился
else if(P<(Pa+Pf))
{
Pu = unirand1();
if(Pu<0.25) {n++; x[n]=x[k]; y[n]=y[k]; }
if((Pu>=0.25)&&(Pu<=0.5)){n+=2; x[n]=x[k]; y[n]=y[k]; x[n-1]=x[k]; y[n-1]=y[k];}
if((Pu>0.5)&&(Pu<=0.75)){n+=3; x[n]=x[k]; y[n]=y[k];x[n-1]=x[k]; y[n-1]=y[k]; x[n-2]=x[k]; y[n-2]=y[k];}
if(Pu>0.75){n+=4; x[n]=x[k]; y[n]=y[k];x[n-1]=x[k]; y[n-1]=y[k];x[n-2]=x[k]; y[n-2]=y[k];x[n-3]=x[k]; y[n-3]=y[k];}
}
//или скорей всего рассеялся
}
//printf("%d\n",n);
}
return n;
}
int main()
{
int k,t,N,T;
float x[600],y[600],a;
FILE *fp = fopen("neut.txt","w");
FILE *fp1= fopen("NT.txt","w");
N = 30;//начальное количество нейтронов в реакторе
a = 40;//размеры стенок квадратного реактора
T = 100;//ограничение времени
for(k=0;k<N;k++)
{
x[k] = unirand1()*a-a*0.5;//случайные начальные позиции нейтронов
y[k] = unirand1()*a-a*0.5;
}
fprintf(fp1,"%d \n",T);
for(t=0;t<T;t++)
{
N = newgeneration(a,N,x,y);
if(N==0){printf("Reactor extinguished %d\n",t);break;}
if(N>500){printf("Overcrowding! Risk of explosion! %d\n",t);break;}
printf("========%d\n",N);
fprintf(fp1,"%d\n",N);
fprintf(fp,"%d\n",N);
for(k=0;k<N;k++) fprintf(fp,"%f %f\n",x[k],y[k]);
}
fclose(fp);
fclose(fp1);
return 0;
}