Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Программа для подсчета термодинамических средних величин на заданном интервале температур.
- * На вход получает плотность вероятности состояний, на выходе выдает термодинамически усредненные значения.
- *
- * Входной файл должен состоять из двух столбцов, разделенных знаком табуляции:
- * энергия E и ln(g(E)) где g(E) - количество конфигураций системы,
- * которым соответствует энергия E. Все значения столбца g(e) могут быть нормированы, т.е.
- * поделены на любую константу. Соответственно при записи ln(g(e)) из всех значений вычтется константа.
- * На результат это не повлияет.
- *
- * В результате работы программа выдаст 4 столбца с данными.
- * 1 - температура
- * 2 - средняя энергия
- * 3 - теплоемкость
- * 4 - энтропия
- *
- * При запуске программа запросит 4 параметра:
- * 1. Имя входного файла
- * 2. Минимальная температура
- * 3. Максимальная температура
- * 4. Число спинов системы
- **/
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- //Сколько выделить ячеек памяти под считанный из файла массив данных
- #define nlamax (100000)
- double iener[nlamax+1];
- double g[nlamax+1];
- int main(void){
- int nla;
- double x,beta;
- int ix,itmin,itmax;
- double tmin,tmax;
- int ie;
- double gmax;
- int count;
- double a0,ae,ae2,aecp,cv,as,as2,ddummy;
- double weight;
- char cdummy[10000];
- FILE *fpw;
- char filename[100];
- printf("# Please, input target filename: ");
- if( scanf("%s",filename)==1){}
- else{printf("Error! Can not find the file!");return 0;}
- fpw=fopen(filename,"r");
- if(fpw == 0){
- printf("Error with open file");
- return 0;
- }
- printf("# Enter min and max temperature \n");
- if(scanf("%lf\t%lf",&tmin,&tmax)==2){}
- else{printf("Error! Failed to read min and max temperature!"); return 0;}
- printf("# Enter number of spins \n");
- if(scanf("%d",&nla)==1){}
- else{printf("Error! Failed to read number of spins!"); return 0;}
- char c;
- for(c=fgetc(fpw);c=='\n'||c=='\r'||c=='#';c=fgetc(fpw)) //пропуск комментариев
- fgets(cdummy,10000,fpw);
- fseek(fpw,-1,SEEK_CUR); // сдвиг курсора на один символ назад
- ie=0;
- // !обязательно! первые две колонки должны быть энергия и ln(g[E])
- while(fscanf(fpw,"%lf %lf",&iener[ie],&g[ie]) != EOF)
- {
- c=fgetc(fpw);
- if(c=='\n'||c=='\r'){}
- else
- fgets(cdummy,10000,fpw);
- if(ie<1){
- printf("# %lf %e\n",iener[ie],g[ie]);
- }
- ie++;
- }
- fclose(fpw);
- count=ie;
- itmin=tmin*1000;
- itmax=tmax*1000;
- for(ix=itmin; ix<=itmax; ix++){
- x=0.001*ix;
- beta=1./x;
- gmax=-1000.;
- for(ie=0; ie<count; ie++){
- if(g[ie]-beta*(iener[ie]-iener[0])>gmax){
- gmax=g[ie]-beta*(iener[ie]-iener[0]);
- }
- }
- a0=0;
- ae=0;
- ae2=0;
- aecp=0; //edited
- as2=0; //edited
- for(ie=0; ie<count; ie++){
- weight=exp(g[ie]-beta*(iener[ie]-iener[0])-gmax);
- a0 += weight;
- ae += weight*iener[ie];
- ae2 += weight*iener[ie]*iener[ie];
- }
- aecp=ae; //edited
- ae /= (double)nla;
- ae2 /= (double)nla*(double)nla;
- ae /= a0;
- ae2 /= a0;
- aecp /= a0; //edited
- as2 = (log(a0) + gmax - beta*iener[0] + aecp*beta)/(double)nla; //edited
- cv = beta*beta*(ae2-ae*ae)*(double)nla;
- printf("%f %e %e %e \n",x,ae,cv,as2); //edited
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement