MoDeNa  1.0
Software framework facilitating sequential multi-scale modelling
spdistrib.c
1 #include <stdio.h>
2 #include <float.h>
3 #include <stdlib.h>
4 #include <time.h>
5 #include <math.h>
6 #include "spdeclarations.h"
7 
8 //Definitionen
9 #define PI 3.1415926535897932384626433832795
10 #define THRD 0.3333333333333333333333333333333
11 
12 //externe Variablen
13 extern int No_parts;
14 extern int Distrfunct;
15 extern double Alpha;
16 extern double Lambda;
17 extern double Mu;
18 extern double GSigma;
19 extern double Vv;
20 extern double Exp;
21 
22 extern double Dmin;
23 extern double Dmax;
24 
25 extern int seed;
26 
27 extern double *Percentage;
28 extern double *Perc_values;
29 extern int Perc_number;
30 extern double *Diam;
31 
32 /*
33 ****************************************************************
34 
35  Gleichverteilung
36 
37 ****************************************************************
38 */
39 double uniform_distr(double small, double large)
40 {
41  double x= 0.0;
42 
43  while(x< small)
44  x= ((double)rand()/RAND_MAX)*large;
45 
46  return x;
47 }
48 
49 /*
50 ****************************************************************
51 
52  Zweipunktverteilung
53 
54 ****************************************************************
55 */
56 double distr_2(double small, double large, double Vv)
57 {
58  double k3= (small/large)*(small/large)*(small/large);
59  double P= (Vv / (Vv + k3));
60 
61  return ((double)rand()/RAND_MAX < P) ? small : large;
62 }
63 
64 /*
65 ****************************************************************
66 
67  Gaußverteilung nach Box-Muller-Verfahren
68 
69 ****************************************************************
70 */
71 double gaussianBM(double g_sigma, double mu)
72 {
73  long seed = 0;
74  double erg= 0.0, u1= 0.0, u2= 0.0;
75  int i= 0;
76 
77  u1= (double)rand()/RAND_MAX;
78  u2= (double)rand()/RAND_MAX;
79 
80  erg= sqrt(-2*log(u1))*cos(2*PI*u2);
81 
82  erg= fabs(g_sigma*erg+mu);
83 
84  return erg;
85 }
86 
87 /*
88 ****************************************************************
89 
90  Logarithmische Normalverteilung
91 
92 ****************************************************************
93 */
94 double log_normal(double g_sigma, double mu)
95 {
96  double x= 0.0;
97 
98  return exp(gaussianBM(g_sigma, mu));
99 }
100 
101 /*
102 ****************************************************************
103 
104  begrenzte Potenzverteilung
105 
106 ****************************************************************
107 */
108 double power(double small, double large, double a)
109 {
110  static long seed = 0;
111  double x= 0.0, x0= pow(small, (a+1)), x1= pow(large, (a+1)), p= 0.0, y= 0.0;
112 
113  if (seed == 0)
114  {
115  time(&seed);
116  seed |= 1L;
117  srand((seed));
118  }
119 
120  do
121  {
122  y=((double)rand()/RAND_MAX);
123 
124  x= pow(((x1-x0)*y + x0), 1/(a+1));
125 
126  p=((double)rand()/RAND_MAX);
127  }
128  while(p< 0.95);
129 
130  return x;
131 }
132 
133 /*
134 ****************************************************************
135 
136  diskrete Verteilung (Prozentwerte)
137 
138 ****************************************************************
139 */
140 void percentage_dist(void)
141 {
142  double limit= 0;
143  int i, j;
144 
145  for(j= 0; j< Perc_number; j++)
146  {
147  *(Percentage+j+1)= *(Percentage+j+1) * (double)No_parts + *(Percentage+j);
148  for(i= (int)*(Percentage+j); i< *(Percentage+j+1); i++)
149  *(Diam+i)= *(Perc_values+j);
150  }
151 }
152 
153 /*
154 ****************************************************************
155 
156  Auswahl der Verteilung
157 
158 ****************************************************************
159 */
160 void setDistribution(int number, double *Diam)
161 {
162  int j= 0;
163 printf("dist: %d\n", number);
164  switch(number)
165  {
166  case 0://konstanter Durchmesser
167  for(j= 0; j< No_parts; j++)
168  {
169  *(Diam+j)= 1.0;
170  //printf("%.lf\n", *(Diam+j));
171  }
172  break;
173 
174  case 1://Two-Point
175  for(j= 0; j< No_parts; j++)
176  *(Diam+j)= distr_2(Dmin, Dmax, Vv);
177  break;
178 
179  case 2://uniform distribution - Gleichverteilung
180  for(j= 0; j< No_parts; j++)
181  *(Diam+j)= uniform_distr(Dmin, Dmax);
182  break;
183 
184  case 3://Normalverteilung
185  for(j= 0; j< No_parts; j++)
186  *(Diam+j)= gaussianBM(GSigma, Mu);
187  break;
188 
189  case 4://Logarithmische Normalverteilung
190  for(j= 0; j< No_parts; j++)
191  *(Diam+j)= log_normal(GSigma, Mu);
192  break;
193 
194  case 5://Potenzvert.
195  for(j= 0; j< No_parts; j++)
196  *(Diam+j)= power(Dmin, Dmax, Exp);
197  break;
198 
199  case 6://Prozentverteilung
200  percentage_dist();
201  break;
202 
203  default://gleiche Kugeln als Standard
204  for(j= 0; j< No_parts; j++)
205  *(Diam+j)= 1.0;
206  break;
207  }
208 }
real(dp), dimension(:), allocatable y
state variables
Definition: globals.f90:106
real(dp) time
time (s)
Definition: globals.f90:49