source: ZHANGProjects/ICOSIM/CPP/trunk/source/Particle.cc @ 2

Last change on this file since 2 was 2, checked in by zhangj, 10 years ago

Initial import

File size: 8.9 KB
Line 
1#include <iostream>
2#include <vector>
3#include <string>
4#include <cmath>
5#include "Particle.h"
6using namespace std;
7
8
9//==================================Constructors, destructor====================================
10
11Particle::Particle(double x, double dx, double y, double dy, double deltaE, double t, double mass, double charge, double moment)
12    : Ap0(mass), Zp0(charge), dpoporiginal(moment)
13{
14    coordonnees[0][0] = x;
15    coordonnees[0][1] = dx;
16    coordonnees[0][2] = y;
17    coordonnees[0][3] = dy;
18    coordonnees[0][4] = deltaE;
19    coordonnees[0][5] = t;
20    inabs = 1;
21    coordonnees[1][0] = 0;
22    coordonnees[1][1] = 0;
23    coordonnees[1][2] = 0;
24    coordonnees[1][3] = 0;
25    coordonnees[1][4] = 0;
26    coordonnees[1][5] = 0;
27}
28
29
30
31Particle::Particle(const Particle& obj)
32    : Ap0(obj.Ap0),
33      Zp0(obj.Zp0),
34      in(obj.in),
35      inabs(obj.inabs),
36      nrevhitp(obj.nrevhitp),
37      dpoporiginal(obj.dpoporiginal),
38      dt(obj.dt)
39
40{
41    coordonnees[0][0] = obj.coordonnees[0][0];
42    coordonnees[0][1] = obj.coordonnees[0][1];
43    coordonnees[0][2] = obj.coordonnees[0][2];
44    coordonnees[0][3] = obj.coordonnees[0][3];
45    coordonnees[0][4] = obj.coordonnees[0][4];
46    coordonnees[0][5] = obj.coordonnees[0][5];
47    identification = obj.getidentification();
48}
49
50
51
52void Particle::afficheCoordonnees()
53{
54
55    for (int j(0); j < 2; ++j) {
56        for (int i(0); i < 6; ++i) {
57            cout << "Here is the " << i + 1 << "th coordinate of the particle at the " << j + 1 << "th interpolation point: " << coordonnees[j][i] << endl;
58        }
59    }
60
61}
62
63
64
65void Particle::afficheFirstCoordonnees()
66{
67    for (int i(0); i < 6; ++i) {
68        cout << "Here is the " << i + 1 << "th coordinate of the particle:" << coordonnees[0][i] << endl;
69    }
70}
71
72
73int Particle::incog(double a, double x, double& gin, double& gim, double& gip)
74{
75
76    double xam, r, s, ga, t0;
77    int k;
78
79    if ((a < 0.0) || (x < 0)) {
80        return 1;
81    }
82    xam = -x + a * log(x);
83    if ((xam > 700) || ( a > 170.0)) {
84        return 1;
85    }
86    if (x == 0.0) {
87        gin = 0.0;
88        gim = exp(gamma(a));
89        gip = 0.0;
90        return 0;
91    }
92    if (x <= 1.0 + a) {
93        s = 1.0 / a;
94        r = s;
95        for (k = 1; k <= 60; k++) {
96            r *= x / (a + k);
97            s += r;
98            if (fabs(r / s) < 1e-15) {
99                break;
100            }
101        }
102        gin = exp(xam) * s;
103        ga = exp(gamma(a));
104        gip = gin / ga;
105        gim = ga - gin;
106    } else {
107        t0 = 0.0;
108        for (k = 60; k >= 1; k--) {
109            t0 = (k - a) / (1.0 + k / (x + t0));
110        }
111        gim = exp(xam) / (x + t0);
112        ga = exp(gamma(a));
113        gin = ga - gim;
114        gip = 1.0 - gim / ga;
115    }
116    return 0;
117}
118
119
120int Particle::getidentification() const
121{
122    return identification;
123}
124
125
126void Particle::setidentification(int id)
127{
128    identification = id;
129}
130
131
132Particle& Particle::operator=(Particle const& source)
133{
134    Ap0 = source.Ap0;
135    Zp0 = source.Zp0;
136    inabs = source.inabs;
137    for (int i(0); i < 2; ++i) {
138        for (int j(0); j < 6; ++j) {
139            coordonnees[i][j] = source.coordonnees[i][j];
140        }
141    }
142    nrevhitp = source.nrevhitp;
143    in = source.in;
144    identification = source.getidentification();
145
146    return *this;
147}
148
149
150double Particle::random()
151{
152    double num;
153    num = rand() / double(RAND_MAX);
154    return -num;
155    //return -0.5;//this lign can be uncomment to fix the randomness for tests (see the file randomness.txt)
156}
157
158
159void Particle::genpartdist(const int& i0, const int& n, const string& type, const double& r1r2skin, const double& emx, const double& emy, const double& sigdpp, const double& bx, const double& ax, const double& dx, const double& dpx, const double& by, const double& ay, const double& dy, const double& dpy, const double& nsigi)
160{
161
162    int nh;
163    double nr, sum, Rx, Ry;
164    vector < vector < double > > h1, h;
165    vector < double > hsum1, hsum, xh, yh, xsh, ysh;
166
167    nh = (int)ceil(n / 0.29);
168    nr = 0;
169
170    //after this loop:
171    //h is 4 x nr, where nr>=n
172    //length of all columns is less than 1
173    //elements of h uniformly distributed between -1 and 1
174
175    while (nr < n) {
176
177        hsum.clear();
178        hsum1.clear();
179        h.clear();
180        h1.clear();
181
182        for (int i(0); i < 4; ++i) {
183            h.push_back(vector <double> (nh));
184            for (int j(0); j < nh; ++j) {
185                h[i][j] = (-2 * random() - 1); //uniformly distributed numbers in [-1,1]
186            }
187        }
188
189        for (int k(0); k < nh; ++k) {
190            sum = 0;
191            for (int l(0); l < 4; ++l) {
192                sum = sum + (h[k][l] * h[k][l]);
193            }
194
195            hsum.push_back(sum);
196        }
197
198        int incr(0);
199
200        for (int i(0); i < nh; ++i) {
201            if (hsum[i] < 1) {
202                h1.push_back(vector < double > (4));
203                for (int l(0); l < 4; ++l) {
204                    h1[incr][l] = h[i][l];
205                }
206                hsum1.push_back(hsum[i]);
207                ++incr;
208            }
209        }
210
211        nr = hsum1.size();
212
213    }//end while
214
215    for (int i(0); i < nr; ++i) {
216        hsum1[i] = sqrt(hsum1[i]);
217    }
218
219    h.clear();
220    hsum.clear();
221
222    for (int j(0); j < n; ++j) {
223        h.push_back(h1[j]);
224        hsum.push_back(hsum1[j]);
225    }
226
227    if (type == "kv") {
228        for (int i(0); i < n; ++i) {
229            for (int j(0); j < 4; ++j) {
230                h[i][j] = h[i][j] / hsum[i]; //normalizes the columns of h
231            }
232        }
233
234        Rx = sqrt(emx);
235        Ry = sqrt(emy);
236
237        for (int k(0); k < n; ++k) {
238            xh.push_back(Rx * h[k][0]);
239            yh.push_back(Ry * h[k][1]);
240            xsh.push_back(Rx * h[k][2]);
241            ysh.push_back(Ry * h[k][3]);
242        }
243
244    } //end if
245
246    else if (type == "waterbag") {
247        //xh uniformly distributed on [-sqrt(emx) sqrt(emx)]
248        //similarly yh, xsh, ysh
249        //BUT such that length([xh/sqrt(emx) ...])>1
250        Rx = sqrt(emx);
251        Ry = sqrt(emy);
252
253        for (int k(0); k < n; ++k) {
254            xh.push_back(Rx * h[k][0]);
255            yh.push_back(Ry * h[k][1]);
256            xsh.push_back(Rx * h[k][2]);
257            ysh.push_back(Ry * h[k][3]);
258        }
259    }
260
261    else if (type == "r1r2") {
262        double R2 , rv;
263        R2 = sqrt(r1r2skin);
264        rv = pow(((R2 * R2 * R2 * R2 - 1) * (-random() + 1 / (R2 * R2 * R2 * R2 - 1))), 0.25);
265
266        for (int i(0); i < n; ++i) {
267            for (int j(0); j < 4; ++j) {
268                h[i][j] = rv * h[i][j] / hsum[i];
269            }
270        }
271
272        Rx = sqrt(emx);
273        Ry = sqrt(emy);
274
275        for (int k(0); k < n; ++k) {
276            xh.push_back(Rx * h[k][0]);
277            yh.push_back(Ry * h[k][1]);
278            xsh.push_back(Rx * h[k][2]);
279            ysh.push_back(Ry * h[k][3]);
280        }
281    } else if (type == "gauss") {
282
283        int p(3);
284        vector <double> rh, fh;
285        int step, temp, count;
286        double gin1, gim1, gip1, gin2, gim2, gip2, randnumber, rv;
287
288        rh.push_back(0);
289
290        step = (int)(nsigi / 0.001) + 1;
291
292        for (int u(0); u < step; ++u) {
293            rh.push_back(rh[rh.size() - 1] + 0.001);
294        }
295        temp = incog((1 + p) / 2, 0.5 * nsigi * nsigi, gin2, gim2, gip2);
296
297        for (int u(0); u <= step; ++u) {
298            temp = incog((1 + p) / 2, 0.5 * rh[u] * rh[u], gin1, gim1, gip1);
299            fh.push_back(gin1 / gin2);
300        }
301
302        randnumber = -random();
303
304        count = 0;
305        for (int k(0); k < step; ++k) {
306            if ((randnumber > fh[k]) && (randnumber < fh[k + 1])) {
307                break;
308            } else {
309                ++ count;
310            }
311        }
312
313        rv = interp1(fh[count], rh[count], fh[count + 1], rh[count + 1], randnumber);
314
315        for (int i(0); i < n; ++i) {
316            for (int j(0); j < 4; ++j) {
317                h[i][j] = rv * h[i][j] / hsum[i];
318            }
319        }
320
321        Rx = sqrt(emx);
322        Ry = sqrt(emy);
323
324        for (int k(0); k < n; ++k) {
325            xh.push_back(Rx * h[k][0]);
326            yh.push_back(Ry * h[k][1]);
327            xsh.push_back(Rx * h[k][2]);
328            ysh.push_back(Ry * h[k][3]);
329        }
330
331    } else {
332
333        cerr << "GENPARTDIST ERROR: Distribution type " << type << " not implemented !" << endl;
334    }
335
336
337    //generating a normal random variable using Box Muller method
338
339
340    this->coordonnees[0][4] = sigdpp * sqrt(-2 * log(-random())) * cos(2 * M_PI * (-random()));
341    this->coordonnees[0][0] = sqrt(bx) * xh[0] + dx * this->coordonnees[0][4];
342    this->coordonnees[0][1] = -ax / sqrt(bx) * xh[0] + xsh[0] / sqrt(bx) + dpx * this->coordonnees[0][4];
343    this->coordonnees[0][2] = sqrt(by) * yh[0] + dy * this->coordonnees[0][4];
344    this->coordonnees[0][3] = -ay / sqrt(by) * yh[0] + ysh[0] / sqrt(by) + dpy * this->coordonnees[0][4];
345    this->dt = 0;
346    this->dpoporiginal = this->coordonnees[0][4];
347
348    //afficheFirstCoordonnees();
349
350
351}
352
353
354double Particle::interp1(double x1, double y1, double x2, double y2, double x)
355{
356
357    double d1(x1 - x2);
358    double d2(y1 - y2);
359
360    double y;
361
362    y = (x - x1) * (d2 / d1) + y1;
363
364    return y;
365}
366
367
Note: See TracBrowser for help on using the repository browser.