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

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

Fix the bug to read files.

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