-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstatistics.c
127 lines (118 loc) · 3.21 KB
/
statistics.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/** @file */
#include <stdio.h>
#include <stdlib.h>
#include "config.h"
#include "colloid.h"
#include "parameters.h"
#include "statistics.h"
int binIndex(double,double,int);
void norm(Stats *stat, Config *c);
/**
* Create a new Stats struct
*
* @param bin Number of bins
* @return Pointer to the newly created Stats struct
*/
Stats *initStats(int bin){
Stats *stat = malloc(sizeof(Stats));
stat->bins = bin;
stat->rho1 = (long double *)calloc(bin,sizeof(long double));
stat->rho2 = (long double *)calloc(bin,sizeof(long double));
stat->f1 = (long double *)calloc(bin,sizeof(long double));
stat->f2 = (long double *)calloc(bin,sizeof(long double));
stat->samplingCount = 0;
return stat;
}
/**
* Print the collected statistics to c->statOut
*
* @param stat Pointer to Stats struct. Normalize before printing!
* @param c Configuration struct
*/
void printStats(Stats *stat, Config *c){
norm(stat, c);
FILE *statFile = fopen(c->statOut,"w");
if( statFile ){
int i;
fprintf(statFile,"#density profile\n#Position(middle of bin)\trho1\trho2\n");
for(i = 0; i < stat->bins; ++i){
fprintf(statFile,"%f\t%Lf\t%Lf\n",(i+0.5)/stat->bins*c->height,stat->rho1[i],stat->rho2[i]);
}
fprintf(statFile,"\n\n");
fprintf(statFile,"#bonds profile\n#Position(middle of bin)\tf1\tf2\n");
for(i = 0; i < stat->bins; ++i){
fprintf(statFile,"%f\t%Lf\t%Lf\n",(i+0.5)/stat->bins*c->height,stat->f1[i],stat->f2[i]);
}
}else{
printf("error writing statFile - %s\n",c->statOut);
}
fclose(statFile);
}
/**
* Normalize the collected statistics.
* Do this only after the simulation is over!
*
* @param stat Statistics struct
* @param c Configuration struct
*/
void norm(Stats *stat, Config *c){
int i;
for(i = 0;i<stat->bins;++i){
if ( stat->rho1[i] != 0 ) stat->f1[i] /= 3.0*stat->rho1[i];
if ( stat->rho2[i] != 0 ) stat->f2[i] /= 2.0*stat->rho2[i];
stat->rho1[i] /= stat->samplingCount*c->width*(c->height/stat->bins);
stat->rho2[i] /= stat->samplingCount*c->width*(c->height/stat->bins);
}
}
/**
* Calculate the correct bin for a z coordinate
*
* @param z z Coordinate
* @param height Height of the simulation box
* @param bins Number of bins
* @return Index of correct bin
*/
int binIndex(double z, double height, int bins){
int i = (int)(z/height*bins);
i = i < bins ? i : bins-1;
return i;
}
/**
* Update the density array
*
* @param z z Coordinate of current particle
* @param kind Which species does the particle belong to
* @param c Configuration struct
* @param stat Statistics struct
*/
void updateDensity(double z, species kind, Config *c, Stats *stat){
int i = binIndex(z,c->height,stat->bins);
switch(kind){
case THREEPATCH:
stat->rho1[i] += 1.0;
break;
case TWOPATCH:
stat->rho2[i] += 1.0;
break;
}
}
/**
* Update the bonds array
*
* @param z z Coordinate of current particle
* @param val How many bonds does the particle have
* @param kind Which species does the particle belong to
* @param c Configuration struct
* @param stat Statistics struct
*/
void updateF(double z, double val, species kind, Config *c, Stats *stat){
int i = binIndex(z,c->height,stat->bins);
switch(kind){
case THREEPATCH:
stat->f1[i] += val;
break;
case TWOPATCH:
stat->f2[i] += val;
break;
}
}