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

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

Added comments...

File size: 50.6 KB
Line 
1#include <iostream>
2#include <vector>
3#include <string>
4#include <cmath>
5#include "lattice.h"
6using namespace std;
7
8int Lattice::count = 0;
9int Lattice::turn = -2;
10int Lattice::choicePart = 1;
11int Lattice::eltOutNber = 1561;
12
13
14
15//the following two constructors are just usefull for the initial tests
16
17Lattice::Lattice(Element element1, Element element2, StandardCollimator stdcolli, FlukaCollimator flukacolli, MagneticCollimator magnetcolli, const vector <int>& ips,  int size, int npcle)
18    : size_res(size), npart(npcle), ips(ips)
19{
20    addElement(&element1);
21    addElement(&element2);
22    addElement(&stdcolli);
23    addElement(&flukacolli);
24    addElement(&magnetcolli);
25    addCollimator(new StandardCollimator(stdcolli));
26    addCollimator(new FlukaCollimator(flukacolli));
27    addCollimator(new MagneticCollimator(magnetcolli));
28
29}
30
31
32Lattice::Lattice(Element start, const vector <int>& ips)
33    : size_res(1), npart(1), ips(ips)
34{
35    addElement(&start);
36}
37
38
39
40Lattice::~Lattice()
41{
42
43    for (int i(0); i < resColli.size(); ++i) {
44        delete resColli[i];
45    }
46    ipcoll.push_back(0);
47    ipcoll.clear();
48}
49
50
51
52void Lattice::setsize_res(int s)
53{
54    size_res = s;
55}
56
57
58void Lattice::addCollimator(Collimator* colli)
59{
60
61    resColli.push_back(colli);
62    cocount.push_back(0);
63}
64
65void Lattice::addElement(Element* elt)
66{
67
68    reseau.push_back(elt);
69
70}
71
72
73double Lattice::time(Particle& p, const double& l, const double& betgam, const int& elt)
74{
75
76    double c(2.99792458e8); //speed of light [m/s]
77    double beta(sqrt(betgam * betgam / (betgam * betgam + 1))); //relativistic beta
78    double gamma(betgam / beta); //relativistic gamma
79    double dist;
80    double dist2;
81
82
83    dist = sqrt(l * l + (p.coordonnees[1][0] - p.coordonnees[0][0]) * (p.coordonnees[1][0] - p.coordonnees[0][0]) + (p.coordonnees[1][2] - p.coordonnees[0][2]) * (p.coordonnees[1][2] - p.coordonnees[0][2]));
84
85    if (elt != reseau.size() - 1) {
86
87        dist2 = sqrt(l * l + (reseau[elt + 1]->XC - reseau[elt]->XC) * (reseau[elt + 1]->XC - reseau[elt]->XC) + (reseau[elt + 1]->YC - reseau[elt]->YC) * (reseau[elt + 1]->YC - reseau[elt]->YC));
88    } else {
89
90        dist2 = sqrt(l * l + (reseau[0]->XC - reseau[elt]->XC) * (reseau[0]->XC - reseau[elt]->XC) + (reseau[0]->YC - reseau[elt]->YC) * (reseau[0]->YC - reseau[elt]->YC));
91    }
92
93    p.dt = (dist - dist2) / (beta * c);
94
95    return (dist / (beta * c));
96}
97
98
99
100void Lattice::outCoord(const Particle& p, const int& indic, const string& fileOut)
101{
102
103    ofstream output;
104
105    int col(15);
106
107    if ((turn == -2) && (indic == 1)) {
108        output.open(fileOut.c_str());
109    } else {
110        output.open(fileOut.c_str(), ios::out | ios::app);
111    }
112
113    if (output.fail()) {
114
115        cerr << "Warning: problem openning the file " << fileOut << "!" << endl;
116    } else {
117
118        output << setw(col) << p.coordonnees[1][0] << setw(col) << p.coordonnees[1][1] << setw(col) << p.coordonnees[1][2] << setw(col) << p.coordonnees[1][3] << setw(col) << p.coordonnees[1][4] << setw(col) << p.coordonnees[1][5] <<  endl;
119
120    }
121
122    output.close();
123
124}
125
126
127void Lattice::outPunct(const int& elt, const Particle& p, const Particle& p2, const double& var, string outputpath)
128{
129
130    ofstream outstream;
131    string file;
132    file = outputpath + "/coordinates_punctual.dat";
133
134    int col(40);
135
136    if (elt == eltOutNber) {
137
138        if ((turn == -2) || (turn == -1)) {
139            outstream.open(file.c_str());
140        } else {
141            outstream.open(file.c_str(), ios::out | ios::app);
142        }
143
144        if (outstream.fail()) {
145            cerr << "Warning: problem openning the file " << file << "!" << endl;
146        } else {
147
148            outstream << setw(col) << p.coordonnees[1][0] << setw(col) << p.coordonnees[1][1] << setw(col) << p.coordonnees[1][2] << setw(col) << p.coordonnees[1][3] << setw(col) << p.coordonnees[1][4] << setw(col) << p.coordonnees[1][5] <<  endl;
149        }
150
151        outstream.close();
152    }
153
154}
155
156void Lattice::outElt(const int& elt, const Particle& p, string outputpath, int& indication)
157{
158
159    ofstream tusors;
160    string file;
161    file = outputpath + "/coordinates_elt.dat";
162
163    int col(35);
164
165    if (elt == eltOutNber) {
166
167        if (((turn == -2) || (turn == -1)) && (indication == 1)) {
168            tusors.open(file.c_str());
169            indication = 0;
170        } else {
171            tusors.open(file.c_str(), ios::out | ios::app);
172        }
173
174        if (tusors.fail()) {
175            cerr << "Warning: problem openning the file " << file << "!" << endl;
176        } else {
177
178            tusors << p.coordonnees[1][0] << setw(col) << p.coordonnees[1][1] << setw(col) << p.coordonnees[1][2] << setw(col) << p.coordonnees[1][3] << setw(col) << p.coordonnees[1][4] << setw(col) << p.coordonnees[1][5] <<  endl;
179
180        }
181
182        tusors.close();
183    }
184}
185
186
187
188void Lattice::outrf(const double& x1, const double& x2, string outputpath)
189{
190
191    ofstream print;
192    string fich;
193    fich = outputpath + "/valuestestrf.dat";
194
195    int col(30);
196
197    if ((turn == -1) || (turn == 0)) {
198        print.open(fich.c_str());
199    } else {
200        print.open(fich.c_str(), ios::out | ios::app);
201    }
202
203    if (print.fail()) {
204        cerr << "Warning: problem openning the file " << fich << "!" << endl;
205    } else {
206
207        print << setw(col) << setprecision(15) << x1 << setw(col) << setprecision(15) << x2 << endl;
208    }
209
210    print.close();
211}
212
213void Lattice::read(vector <Particle>& bunch)
214{
215
216    ifstream lecture;
217    string nomfich;
218    nomfich = "../sample/output_data_120GeV_500pt.txt";
219    //nomfich = "test.txt";
220
221    lecture.open(nomfich.c_str());
222
223    if (lecture.fail()) {
224
225        cerr << "Warning: problem with the file " << nomfich << " !" << endl;
226    } else {
227
228        bunch.clear();
229        double var;
230        int id;
231        Particle p;
232        string phrase;
233
234        lecture >> ws;
235
236        for (int k(0); k < 500; ++k) {
237
238            //getline(lecture, phrase);
239
240            lecture >> var;
241            p.coordonnees[0][0] = var;
242            p.coordonnees[1][0] = var;
243            lecture >> var;
244            p.coordonnees[0][1] = var;
245            p.coordonnees[1][1] = var;
246            lecture >> var;
247            p.coordonnees[0][2] = var;
248            p.coordonnees[1][2] = var;
249            lecture >> var;
250            p.coordonnees[0][3] = var;
251            p.coordonnees[1][3] = var;
252            lecture >> var;
253            p.coordonnees[0][4] = var;
254            p.coordonnees[1][4] = var;
255            lecture >> var;
256            p.coordonnees[0][5] = var;
257            p.coordonnees[1][5] = var;
258            //lecture >> id;
259            p.Ap0 = 1;
260            p.Zp0 = 1;
261
262            bunch.push_back(p);
263            bunch[bunch.size() - 1].inabs = 1;
264        }
265
266        lecture.close();
267    }
268}
269
270
271/*
272 *
273 */
274void Lattice::trackensemblelinearnew(vector <Particle>& bunch, vector <Particle>& bunchhit, const int& nrev, const double& blowup2, const int& blowupperiod)
275{
276
277  /*nip: number of primary collimators in the accelerator; niph: number of primary collimators hit by the particles; nrevhitp: number of turns when the particle hit the primary collimators */
278    int nip=0, niph=0, nrevhitp=0; 
279    vector <int> iph;
280    double blowup=0.0; /* sqrt(blowup2), beam blow up strength*/
281
282    //we only take the primary collimators into account here, as well as the first and the last elements of the lattice
283    nip = ip.size();//the number of primary collimators
284    niph = nip + 1;
285
286    //ip --> ip-1
287
288    iph.push_back(0);
289
290    for (int j(0); j < ip.size(); ++j) {
291        iph.push_back(ip[j] - 1);
292    }
293    iph.push_back(reseau.size() - 1);
294    blowup = sqrt(blowup2);
295
296    for (int q(0); q < bunch.size(); ++q) {
297        bunch[q].in = 1;
298    }
299
300  //  cout <<" "<<endl;
301   //   cout <<"********************************"<<endl;
302    cout << "Initialising LINEAR R-Matrix (solutions of Hill's equations using the Floquet theory, based on the Twiss parameters)." << endl;
303
304    for (int i(0); i < niph; ++i) { //making matrices for the Twiss transform
305
306        long double cx, sx, cy, sy;
307
308        cx = cos(2 * M_PI * (reseau[iph[i + 1]]->MUX - reseau[iph[i]]->MUX));
309        sx = sin(2 * M_PI * (reseau[iph[i + 1]]->MUX - reseau[iph[i]]->MUX));
310        R11X.push_back(sqrt(reseau[iph[i + 1]]->BETX / reseau[iph[i]]->BETX) * (cx + reseau[iph[i]]->ALFX * sx));
311        R12X.push_back(sqrt(reseau[iph[i + 1]]->BETX * reseau[iph[i]]->BETX)*sx);
312        R21X.push_back(((reseau[iph[i]]->ALFX - reseau[iph[i + 1]]->ALFX)*cx - (1 + reseau[iph[i]]->ALFX * reseau[iph[i + 1]]->ALFX)*sx) / sqrt(reseau[iph[i + 1]]->BETX * reseau[iph[i]]->BETX));
313        R22X.push_back(sqrt(reseau[iph[i]]->BETX / reseau[iph[i + 1]]->BETX) * (cx - reseau[iph[i + 1]]->ALFX * sx));
314
315
316        cy = cos(2 * M_PI * (reseau[iph[i + 1]]->MUY - reseau[iph[i]]->MUY));
317        sy = sin(2 * M_PI * (reseau[iph[i + 1]]->MUY - reseau[iph[i]]->MUY));
318        R11Y.push_back(sqrt(reseau[iph[i + 1]]->BETY / reseau[iph[i]]->BETY) * (cy + reseau[iph[i]]->ALFY * sy));
319        R12Y.push_back(sqrt(reseau[iph[i + 1]]->BETY * reseau[iph[i]]->BETY)*sy);
320        R21Y.push_back(((reseau[iph[i]]->ALFY - reseau[iph[i + 1]]->ALFY)*cy - (1 + reseau[iph[i]]->ALFY * reseau[iph[i + 1]]->ALFY)*sy) / sqrt(reseau[iph[i + 1]]->BETY * reseau[iph[i]]->BETY));
321        R22Y.push_back(sqrt(reseau[iph[i]]->BETY / reseau[iph[i + 1]]->BETY) * (cy - reseau[iph[i + 1]]->ALFY * sy));
322    }
323
324    int count(0);
325    int total(bunch.size());
326    for (int k(0); k < nrev; ++k) { //loop over the number of revolution
327        vector <Particle> bunchtemp;
328
329        ++turn;
330
331        for (int w(0); w < bunch.size(); ++w) {
332            bunchtemp.push_back(bunch[w]);
333        }
334        for (int i(0); i < niph; ++i) { //loop through the primary collimators
335            for (int p(0); p < bunch.size(); ++p) { //loop through the particles
336                if (bunch[p].in == 1) { //to assure the particle is still remainding in the accelerator
337
338                    long double pdepth=0.0, pdepth2=0.0;
339
340                    bunch[p].coordonnees[1][0] = R11X[i] * bunch[p].coordonnees[0][0] + R12X[i] * bunch[p].coordonnees[0][1] + (reseau[iph[i + 1]]->DX - R11X[i] * reseau[iph[i]]->DX - R12X[i] * reseau[iph[i]]->DPX) * bunch[p].coordonnees[0][4];
341                    bunch[p].coordonnees[1][1] = R21X[i] * bunch[p].coordonnees[0][0] + R22X[i] * bunch[p].coordonnees[0][1] + (reseau[iph[i + 1]]->DPX - R21X[i] * reseau[iph[i]]->DX - R22X[i] * reseau[iph[i]]->DPX) * bunch[p].coordonnees[0][4];
342                    bunch[p].coordonnees[1][2] = R11Y[i] * bunch[p].coordonnees[0][2] + R12Y[i] * bunch[p].coordonnees[0][3] + (reseau[iph[i + 1]]->DY - R11Y[i] * reseau[iph[i]]->DY - R12Y[i] * reseau[iph[i]]->DPY) * bunch[p].coordonnees[0][4];
343                    bunch[p].coordonnees[1][3] = R21Y[i] * bunch[p].coordonnees[0][2] + R22Y[i] * bunch[p].coordonnees[0][3] + (reseau[iph[i + 1]]->DPY - R21Y[i] * reseau[iph[i]]->DY - R22Y[i] * reseau[iph[i]]->DPY) * bunch[p].coordonnees[0][4];
344
345                    if (i < niph - 1) {
346                        long double lcoll=0.0, sa=0.0, ca=0.0;
347
348                        sa = sin(resColli[ipcoll[i]]->tcang);//sinus of the collimator's angle
349                        lcoll = resColli[ipcoll[i]]->L;//length of the collimator
350                       
351
352                        if (sa == 0) {
353                            pdepth = abs(bunch[p].coordonnees[1][0]) - resColli[ipcoll[i]]->hgap;//impact parameter at the beginning of the collimaator
354                            pdepth2 = abs(bunch[p].coordonnees[1][0] + lcoll * bunch[p].coordonnees[1][1]) - resColli[ipcoll[i]]->hgap2; //impact parameter at the end of the collimator
355
356                        } else {
357
358                            long double xl, xsl;
359                            ca = cos(resColli[ipcoll[i]]->tcang);
360                            xl = bunch[p].coordonnees[1][0] * ca + bunch[p].coordonnees[1][2] * sa;
361                            xsl = bunch[p].coordonnees[1][1] * ca + bunch[p].coordonnees[1][3] * sa;
362                            pdepth = abs(xl) - resColli[ipcoll[i]]->hgap;
363                            pdepth2 = abs(xl + lcoll * xsl) - resColli[ipcoll[i]]->hgap2;
364                        }
365
366                        if ((pdepth <= 0) && (pdepth2 <= 0)) { //we only continue with the particles that have not disappeared
367                            bunch[p].coordonnees[0][0] = bunch[p].coordonnees[1][0];
368                            bunch[p].coordonnees[0][1] = bunch[p].coordonnees[1][1];
369                            bunch[p].coordonnees[0][2] = bunch[p].coordonnees[1][2];
370                            bunch[p].coordonnees[0][3] = bunch[p].coordonnees[1][3];
371                        } else {
372                            bunch[p].in = false;
373                            count = count + 1;
374                            bunchhit.push_back(bunchtemp[p]);
375                            bunch[p].nrevhitp = k + 1;
376                            apdepth.push_back(pdepth);
377                            apdepth2.push_back(pdepth2);
378                            cocount[i] = cocount[i] + 1;
379                        }
380                    }//end (if i<niph)
381                    else {//we only continue with the particles that have not disappeared
382                        bunch[p].coordonnees[0][0] = bunch[p].coordonnees[1][0];
383                        bunch[p].coordonnees[0][1] = bunch[p].coordonnees[1][1];
384                        bunch[p].coordonnees[0][2] = bunch[p].coordonnees[1][2];
385                        bunch[p].coordonnees[0][3] = bunch[p].coordonnees[1][3];
386                    }
387                }//end if in
388
389                //the following part can be uncommented to have an output of the x- and  y-coordinates of a particle in the file coordinates.dat
390
391                /*if(bunch[p].getidentification() == choicePart){
392                  outCoord(bunch[p], i+1, "coordinates.dat");
393                  }*/
394
395            }//end loop over the particles
396        }//end loop over i
397
398       // cout << "Revolution: " << k + 1 << ", number of particles left: " << total - count << endl;
399
400        if (total - count == 0) { //we return if all the particles are gone
401            return;
402        }
403
404        vector <Particle> tempinabs;
405
406        //we continue just with particles that are not lost
407        for (int w(0); w < bunch.size(); ++w) {
408            if (bunch[w].in != 0) {
409                tempinabs.push_back(bunch[w]);
410            }
411        }
412
413        bunch.clear();
414
415        for (int w(0); w < tempinabs.size(); ++w) {
416            bunch.push_back(tempinabs[w]);
417        }
418
419        tempinabs.clear();
420
421        for (int p(0); p < bunch.size(); ++p) {
422            if ((k + 1) % blowupperiod == 0) { //blowup/diffusion
423                if (bunch[p].in == 1) {
424                //    cout << "Blow-up!!" << k+1 << endl;
425                    int im=0;
426                    im = reseau.size() - 1;
427                    bunch[p].coordonnees[0][0] = (bunch[p].coordonnees[0][0] - reseau[im]->DX * bunch[p].coordonnees[0][4]) * blowup + reseau[im]->DX * bunch[p].coordonnees[0][4];
428                    bunch[p].coordonnees[0][1] = (bunch[p].coordonnees[0][1] - reseau[im]->DPX * bunch[p].coordonnees[0][4]) * blowup + reseau[im]->DPX * bunch[p].coordonnees[0][4];
429                    bunch[p].coordonnees[0][2] = (bunch[p].coordonnees[0][2] - reseau[im]->DY * bunch[p].coordonnees[0][4]) * blowup + reseau[im]->DY * bunch[p].coordonnees[0][4];
430                    bunch[p].coordonnees[0][3] = (bunch[p].coordonnees[0][3] - reseau[im]->DPY * bunch[p].coordonnees[0][4]) * blowup + reseau[im]->DPY * bunch[p].coordonnees[0][4];
431                }
432            }
433        }
434
435    }//end loop over k
436
437}
438
439
440void Lattice::trackensemblechrom(vector <Particle>& bunch, const int& irev, const int& i0, const int& im, const double& Apr, const double& Zpr, const double& wecolli, const double& betgam, const int& nonlinflag, const int& scaleorbit, double& attr1, const int& idpart, const int& idelt, const int& outcoord, const string& plotflag, vector <vector <double> >& xco, vector <vector <double> >& yco, string outputpath, int RFflag, int& indication)
441{
442
443  cout << "bunch size is: " << bunch.size() << endl;
444 
445 
446    if (idpart >= 0) {
447        if (idpart > bunch.size()) {
448            cerr << "Warning, the particle that you want to spy using IDPART does not exist!" << "  idpart = " << idpart << ",  bunch.size = " << bunch.size() <<endl;
449        } else {
450            choicePart = idpart;
451        }
452    }
453
454    if (idelt >= 0) {
455        if (idelt >= reseau.size()) {
456            cerr << "Warning, the element after which you want to spy using IDELT does not exist!" << endl;
457        } else {
458            eltOutNber = idelt;
459        }
460    }
461
462    ++turn;
463
464    if (nhitcolli.size() < resColli.size()) {
465        for (int k(0); k < resColli.size(); ++k) {
466            nhitcolli.push_back(0);
467        }
468    }
469
470    if (plotflag == "Yes") {
471        xco.clear();
472        yco.clear();
473        vector <double> temp1, temp2;
474        for (int k(0); k < bunch.size(); ++k) {
475            temp1.push_back(bunch[k].coordonnees[0][0]);
476            temp2.push_back(bunch[k].coordonnees[0][2]);
477        }
478
479        xco.push_back(temp1);
480        yco.push_back(temp2);
481
482        temp1.clear();
483        temp2.clear();
484    }
485
486    //we set the revolution number (trackensemblechrom is called two times during the first turn)
487    int rev;
488
489    if (irev == 0) {
490        rev = 1;
491    } else {
492        rev = irev;
493    }
494
495    if (irev == 0) {
496        cout << "Initialising NONLINEAR R-matrix." << endl;
497
498        double K=0.0;
499        double cx=0.0, sx=0.0, cy=0.0, sy=0.0;
500
501        R11X.clear();
502        R12X.clear();
503        R21X.clear();
504        R22X.clear();
505        R11Y.clear();
506        R12Y.clear();
507        R21Y.clear();
508        R22Y.clear();
509        turn = -2;
510
511        Lelem.push_back(0);
512        R11X.push_back(0);
513        R12X.push_back(0);
514        R21X.push_back(0);
515        R22X.push_back(0);
516        R11Y.push_back(0);
517        R12Y.push_back(0);
518        R21Y.push_back(0);
519        R22Y.push_back(0);
520        R11XC.push_back(0);
521        R12XC.push_back(0);
522        R21XC.push_back(0);
523        R22XC.push_back(0);
524        R11YC.push_back(0);
525        R12YC.push_back(0);
526        R21YC.push_back(0);
527        R22YC.push_back(0);
528
529        for (int i(1); i < size_res; ++i) {
530
531            Lelem.push_back(reseau[i]->S - reseau[i - 1]->S);
532           
533            if (reseau[i]->K1L > 0) {
534                if (Lelem[i] == 0) {
535                    Lelem[i] = 0.001;
536                }
537
538                K = reseau[i]->K1L / Lelem[i];
539                cx = cos(sqrt(K) * Lelem[i]);
540                sx = sin(sqrt(K) * Lelem[i]);
541                R11XC.push_back(0.5 * sqrt(K)*Lelem[i]*sx);
542                R12XC.push_back(-0.5 * Lelem[i]*cx + 0.5 / sqrt(K)*sx);
543                R21XC.push_back(0.5 * K * Lelem[i]*cx + 0.5 * sqrt(K)*sx);
544                R22XC.push_back(0.5 * sqrt(K)*Lelem[i]*sx);
545                cy = cosh(sqrt(K) * Lelem[i]);
546                sy = sinh(sqrt(K) * Lelem[i]);
547                R11YC.push_back(-0.5 * sqrt(K)*Lelem[i]*sy);
548                R12YC.push_back(-0.5 * Lelem[i]*cy + 0.5 / sqrt(K)*sy);
549                R21YC.push_back(-0.5 * K * Lelem[i]*cy - 0.5 * sqrt(K)*sy);
550                R22YC.push_back(-0.5 * sqrt(K)*Lelem[i]*sy);
551            } else if (reseau[i]->K1L < 0) {
552                if (Lelem[i] == 0) {
553                    Lelem[i] = 0.001;
554                }
555
556                K = -reseau[i]->K1L / Lelem[i];
557                cx = cosh(sqrt(K) * Lelem[i]);
558                sx = sinh(sqrt(K) * Lelem[i]);
559                R11XC.push_back(-0.5 * sqrt(K)*Lelem[i]*sx);
560                R12XC.push_back(-0.5 * Lelem[i]*cx + 0.5 / sqrt(K)*sx);
561                R21XC.push_back(-0.5 * K * Lelem[i]*cx - 0.5 * sqrt(K)*sx);
562                R22XC.push_back(-0.5 * sqrt(K)*Lelem[i]*sx);
563                cy = cos(sqrt(K) * Lelem[i]);
564                sy = sin(sqrt(K) * Lelem[i]);
565                R11YC.push_back(0.5 * sqrt(K)*Lelem[i]*sy);
566                R12YC.push_back(-0.5 * Lelem[i]*cy + 0.5 / sqrt(K)*sy);
567                R21YC.push_back(0.5 * K * Lelem[i]*cy + 0.5 * sqrt(K)*sy);
568                R22YC.push_back(0.5 * sqrt(K)*Lelem[i]*sy);
569            } else {
570                R11XC.push_back(0);
571                R12XC.push_back(0);
572                R21XC.push_back(0);
573                R22XC.push_back(0);
574                R11YC.push_back(0);
575                R12YC.push_back(0);
576                R21YC.push_back(0);
577                R22YC.push_back(0);
578            }
579
580            cx = cos(2 * M_PI * (reseau[i]->MUX - reseau[i - 1]->MUX));
581            sx = sin(2 * M_PI * (reseau[i]->MUX - reseau[i - 1]->MUX));
582            R11X.push_back(sqrt(reseau[i]->BETX / reseau[i - 1]->BETX) * (cx + reseau[i - 1]->ALFX * sx));
583            R12X.push_back(sqrt(reseau[i]->BETX * reseau[i - 1]->BETX)*sx);
584            R21X.push_back(((reseau[i - 1]->ALFX - reseau[i]->ALFX)*cx - (1 + reseau[i - 1]->ALFX * reseau[i]->ALFX)*sx) / sqrt(reseau[i]->BETX * reseau[i - 1]->BETX));
585            R22X.push_back(sqrt(reseau[i - 1]->BETX / reseau[i]->BETX) * (cx - reseau[i]->ALFX * sx));
586
587
588            cy = cos(2 * M_PI * (reseau[i]->MUY - reseau[i - 1]->MUY));
589            sy = sin(2 * M_PI * (reseau[i]->MUY - reseau[i - 1]->MUY));
590            R11Y.push_back(sqrt(reseau[i]->BETY / reseau[i - 1]->BETY) * (cy + reseau[i - 1]->ALFY * sy));
591            R12Y.push_back(sqrt(reseau[i]->BETY * reseau[i - 1]->BETY)*sy);
592            R21Y.push_back(((reseau[i - 1]->ALFY - reseau[i]->ALFY)*cy - (1 + reseau[i - 1]->ALFY * reseau[i]->ALFY)*sy) / sqrt(reseau[i]->BETY * reseau[i - 1]->BETY));
593            R22Y.push_back(sqrt(reseau[i - 1]->BETY / reseau[i]->BETY) * (cy - reseau[i]->ALFY * sy));
594
595        }
596
597    }
598
599
600    // loop througt the elements in the machine
601
602    for (int i(i0 + 1); i <= im; ++i) { //i is the element number along the ring (similar numbering as s)
603
604        /*if(i == 2822){
605          read(bunch);
606          }*/
607       
608       
609        for (int p(0); p < bunch.size(); ++p) { //loop througt the particles
610
611            double dpopeff;
612
613            // .inabs = 0, particle lost, .inabs = 1, particle not lost
614            if (bunch[p].inabs == 1) {
615
616                //cout <<"Element " << i << endl;
617
618                int icop(-1);
619
620                for (int k(0); k < ips.size(); ++k) {
621                    if (i == ips[k]) { //element is a collimator
622                        icop = k;//The element is the 'icop'th collimator
623                    }
624                }
625
626                if (icop != -1) { //the element we consider is a collimator
627
628//cout << "icop = "<<icop << endl;
629
630                    if (resColli[icop]->method == "standard") {
631
632                        resColli[icop]->collipass(bunch[p], dpopeff, scaleorbit, R11X[i], R12X[i], R21X[i], R22X[i], R11Y[i], R12Y[i], R21Y[i], R22Y[i], reseau[i - 1]->DX, reseau[i - 1]->DPX, reseau[i - 1]->DY, reseau[i - 1]->DPY, reseau[i]->S - reseau[i - 1]->S, Apr, Zpr, betgam);
633
634                        if (bunch[p].Ap0 != 0) {
635                            bunch[p].coordonnees[1][5] = bunch[p].coordonnees[0][5] + time(bunch[p], reseau[i]->L, betgam, i);
636                        }
637
638                    }
639#if defined(FLUKA)
640                    else if (resColli[icop]->method == "fluka") {
641
642                        vector <Particle> temp;
643
644                        if (p == 0) { //we send all the bunch at the same time to Fluka only one time per element
645
646                            vector <Particle> bunchend;//bunch after the passage through Fluka
647
648                            for (int y(0); y < bunch.size(); ++y) {
649                                temp.push_back(bunch[y]);
650                            }
651
652                            resColli[icop]->collipassfluka(bunch, bunchend, conn, turn, momentum);
653
654
655                            nhitcolli[icop] = bunch.size() - bunchend.size(); //nhitcolli(icop) gives the number particles getting lost in collimator number icop,
656
657                            int creation(0);
658
659                            bunch.clear();
660
661                            for (int g(0); g < bunchend.size(); ++g) {
662                                if (bunchend[g].getidentification() == 0) {
663                                    bunch.push_back(bunchend[g]);
664                                    break;
665                                }
666                            }
667
668                            for (int g(0); g < bunchend.size(); ++g) {
669                                if (bunchend[g].getidentification() == bunch[bunch.size() - 1].getidentification() + 1) {
670                                    bunch.push_back(bunchend[g]);
671                                } else if (bunchend[g].getidentification() == bunch[bunch.size() - 1].getidentification() + 10000) {
672                                    bunch.push_back(bunchend[g]);
673                                    ++creation;
674                                } else if ((bunchend[g].getidentification() == bunch[bunch.size() - 1].getidentification()) && (bunchend[g].getidentification() != 0)) {
675                                    bunch.push_back(bunchend[g]);
676                                    ++creation;
677                                } else if (bunchend[g].getidentification() == bunch[bunch.size() - 1].getidentification() - 10000 + 1) {
678                                    bunch.push_back(bunchend[g]);
679                                }
680                            }
681
682                            nhitcolli[icop] = nhitcolli[icop] + creation;
683
684                            cout << creation << " particles created." << endl;
685
686                            int uu(1);
687                            int rr0, rr1;
688                            long double tps;
689                            bunch[0].coordonnees[0][5] = temp[0].coordonnees[0][5];
690                            rr0 = bunch[0].getidentification();
691                            bunch[0].setidentification(temp[0].getidentification());
692                            for (int g(1); g < bunch.size(); ++g) {
693                                rr1 = bunch[g].getidentification();
694                                if (bunch[g].getidentification() == rr0 + 1) {
695                                    bunch[g].setidentification(temp[uu].getidentification());
696                                    bunch[g].coordonnees[0][5] = temp[uu].coordonnees[0][5];
697                                    rr0 = rr1;
698                                } else {
699                                    tps = temp[uu - 1].coordonnees[0][5];
700                                    while (bunch[g].getidentification() == rr1) {
701                                        bunch[g].coordonnees[0][5] = tps;
702                                        ++g;
703                                    }
704                                    --g;
705                                    --uu;
706                                }
707                                ++uu;
708                            }
709
710                            for (int g(0); g < bunch.size(); ++g) {
711                                bunch[g].coordonnees[1][0] = bunch[g].coordonnees[0][0];
712                                bunch[g].coordonnees[1][1] = bunch[g].coordonnees[0][1];
713                                bunch[g].coordonnees[1][2] = bunch[g].coordonnees[0][2];
714                                bunch[g].coordonnees[1][3] = bunch[g].coordonnees[0][3];
715                                bunch[g].coordonnees[1][4] = bunch[g].coordonnees[0][4];
716                            }
717
718                        }
719
720                        bunch[p].coordonnees[1][5] = bunch[p].coordonnees[0][5] + time(bunch[p], reseau[i]->L, betgam, i);
721
722                        for (int k(0); k < bunch.size(); ++k) {
723                            bunch[k].inabs = 1;
724                        }
725
726                        temp.clear();
727
728                    }
729#endif
730                    else if (resColli[icop]->method == "magnetic") {
731
732                        if (p == 0) {
733                            resColli[icop]->hgap = resColli[icop]->hgap + resColli[icop]->deltaGap;
734                            resColli[icop]->hgap2 = resColli[icop]->hgap2 + resColli[icop]->deltaGap;
735                        }
736
737
738                        resColli[icop]->collipass(bunch[p], dpopeff, scaleorbit, R11X[i], R12X[i], R21X[i], R22X[i], R11Y[i], R12Y[i], R21Y[i], R22Y[i], reseau[i - 1]->DX, reseau[i - 1]->DPX, reseau[i - 1]->DY, reseau[i - 1]->DPY, reseau[i]->S - reseau[i - 1]->S, Apr, Zpr, betgam);
739
740
741                        if (bunch[p].Ap0 != 0) {
742                            bunch[p].coordonnees[1][5] = bunch[p].coordonnees[0][5] + time(bunch[p], reseau[i]->L, betgam, i);
743                        }
744
745                    } else if (resColli[icop]->method == "crystal") {
746
747                        if (p == 0) { //we send all the bunch at the same time through collipassCrystal
748
749                            int lost(bunch.size());
750                             
751                            long int nhit = 0;
752                           
753                            resColli[icop]->collipassCrystal(bunch, betgam, turn, nhit, outputpath);
754
755                            //nhitcolli[icop] = lost - bunch.size(); //nhitcolli(icop) gives the number particles getting lost in collimator number icop,
756                           
757                             nhitcolli[icop] = nhit; 
758
759                         //    cout << "after the crystal: bunch size = " << bunch.size()<< endl;
760                        }
761
762                        bunch[p].coordonnees[1][5] = bunch[p].coordonnees[0][5] + time(bunch[p], reseau[i]->L, betgam, i);
763
764                    } else {
765
766                        cerr << "Error: unknown type of collimator, the method is not good defined!!" << endl;
767                    }
768
769                    //we test if the particle is lost in the preceeding collimator
770                    if (bunch[p].Ap0 == 0) {
771                        nhitcolli[icop] = nhitcolli[icop] + 1;
772                        bunch[p].inabs = 0;
773                    }
774
775                } else {//element not collimator
776
777                    if ((reseau[i]->KEYWORD == "RFCAVITY") && (RFflag == 1)) { //attention: voir jusqu ou aller avec le else (est-ce qu on controle l aperture hit?? pour le moment oui...)
778
779                        //Note thate the phase is taken here to be equal to pi.
780
781                        double period(rfharmonic / freqrf);
782                        double omega;
783                        double phase(0);
784                        double phi;
785                        double beta(sqrt(betgam * betgam / (betgam * betgam + 1))); //relativistic beta
786                        long double c(2.99792458e8);//speed of light [m/s]
787                        long double e(1.60218e-19);//elementary charge [C]
788
789
790                        omega = 2 * M_PI * (freqrf / rfharmonic);
791                        phi = phase + omega * bunch[p].coordonnees[0][5];
792
793                        bunch[p].coordonnees[1][0] = bunch[p].coordonnees[0][0];
794                        bunch[p].coordonnees[1][1] = bunch[p].coordonnees[0][1];
795                        bunch[p].coordonnees[1][2] = bunch[p].coordonnees[0][2];
796                        bunch[p].coordonnees[1][3] = bunch[p].coordonnees[0][3];
797
798                        double attr;
799                        attr = bunch[p].Zp0 * sin(phi) * (rfvoltage) / (beta * momentum);
800                        attr1 =  attr;
801                        bunch[p].coordonnees[1][4] = bunch[p].dpoporiginal + attr;//attention vraiment pas sur des parametre (surtout p dans la formule)
802
803                        bunch[p].coordonnees[1][5] = bunch[p].coordonnees[0][5];
804
805                        //uncomment the following line to have output related to the rf-cavity (cf lattice.h)
806                        //outrf(bunch[p].coordonnees[1][5], phi);
807
808
809                    }
810
811
812                    dpopeff = (bunch[p].Ap0 * Zpr) / (bunch[p].Zp0 * Apr) * (1 + bunch[p].coordonnees[0][4]) - 1;
813
814                    if (Lelem[i] == 0) {
815
816                        bunch[p].coordonnees[1][0] = bunch[p].coordonnees[0][0];
817                        bunch[p].coordonnees[1][1] = bunch[p].coordonnees[0][1];
818                        bunch[p].coordonnees[1][2] = bunch[p].coordonnees[0][2];
819                        bunch[p].coordonnees[1][3] = bunch[p].coordonnees[0][3];
820                        bunch[p].coordonnees[1][4] = bunch[p].coordonnees[0][4];
821                        bunch[p].coordonnees[1][5] = bunch[p].coordonnees[0][5];
822
823                    } else if ((reseau[i]->K1L != 0) && (nonlinflag == 1)) {
824
825                        double R11Xh, R12Xh, R21Xh, R22Xh, R11Yh, R12Yh, R21Yh, R22Yh;
826
827
828                        R11Xh = R11X[i] + R11XC[i] * dpopeff;
829                        R12Xh = R12X[i] + R12XC[i] * dpopeff;
830                        R21Xh = R21X[i] + R21XC[i] * dpopeff;
831                        R22Xh = R22X[i] + R22XC[i] * dpopeff;
832                        R11Yh = R11Y[i] + R11YC[i] * dpopeff;
833                        R12Yh = R12Y[i] + R12YC[i] * dpopeff;
834                        R21Yh = R21Y[i] + R21YC[i] * dpopeff;
835                        R22Yh = R22Y[i] + R22YC[i] * dpopeff;
836
837                        bunch[p].coordonnees[1][0] = R11Xh * bunch[p].coordonnees[0][0] + R12Xh * bunch[p].coordonnees[0][1] + (reseau[i]->DX - R11Xh * reseau[i - 1]->DX - R12Xh * reseau[i - 1]->DPX) * dpopeff;
838                        bunch[p].coordonnees[1][1] = R21Xh * bunch[p].coordonnees[0][0] + R22Xh * bunch[p].coordonnees[0][1] + (reseau[i]->DPX - R21Xh * reseau[i - 1]->DX - R22Xh * reseau[i - 1]->DPX) * dpopeff;
839                        bunch[p].coordonnees[1][2] = R11Yh * bunch[p].coordonnees[0][2] + R12Yh * bunch[p].coordonnees[0][3] + (reseau[i]->DY - R11Yh * reseau[i - 1]->DY - R12Yh * reseau[i - 1]->DPY) * dpopeff;
840                        bunch[p].coordonnees[1][3] = R21Yh * bunch[p].coordonnees[0][2] + R22Yh * bunch[p].coordonnees[0][3] + (reseau[i]->DPY - R21Yh * reseau[i - 1]->DY - R22Yh * reseau[i - 1]->DPY) * dpopeff;
841                        bunch[p].coordonnees[1][4] = bunch[p].coordonnees[0][4];
842
843                        bunch[p].coordonnees[1][5] = bunch[p].coordonnees[0][5] + time(bunch[p], reseau[i]->L, betgam, i);
844
845                    } else if ((reseau[i]->K2L != 0) && (nonlinflag == 1)) {
846                        double Lelemha(Lelem[i] / 2);
847                        double dxha(reseau[i - 1]->DX + reseau[i - 1]->DPX * Lelemha);
848                        double dyha(reseau[i - 1]->DY + reseau[i - 1]->DPY * Lelemha);
849
850                        bunch[p].coordonnees[1][0] = bunch[p].coordonnees[0][0] + Lelemha * bunch[p].coordonnees[0][1] + (dxha - reseau[i - 1]->DX - Lelemha * reseau[i - 1]->DPX) * dpopeff;
851                        bunch[p].coordonnees[1][2] = bunch[p].coordonnees[0][2] + Lelemha * bunch[p].coordonnees[0][3] + (dyha - reseau[i - 1]->DY - Lelemha * reseau[i - 1]->DPY) * dpopeff;
852
853                        bunch[p].coordonnees[1][1] = bunch[p].coordonnees[0][1] - 0.5 * reseau[i]->K2L * (bunch[p].coordonnees[1][0] * bunch[p].coordonnees[1][0] - bunch[p].coordonnees[1][2] * bunch[p].coordonnees[1][2]);
854                        bunch[p].coordonnees[1][3] = bunch[p].coordonnees[0][3] + reseau[i]->K2L * (bunch[p].coordonnees[1][0] * bunch[p].coordonnees[1][2]);
855                        bunch[p].coordonnees[1][0] = bunch[p].coordonnees[1][0] + Lelemha * bunch[p].coordonnees[1][1] + (reseau[i]->DX - dxha - Lelemha * reseau[i - 1]->DPX) * dpopeff;
856                        bunch[p].coordonnees[1][2] = bunch[p].coordonnees[1][2] + Lelemha * bunch[p].coordonnees[1][3] + (reseau[i]->DY - dyha - Lelemha * reseau[i - 1]->DPY) * dpopeff;
857                        bunch[p].coordonnees[1][4] = bunch[p].coordonnees[0][4];
858
859                        bunch[p].coordonnees[1][5] = bunch[p].coordonnees[0][5] + time(bunch[p], reseau[i]->L, betgam, i);
860                    } else {
861
862                        bunch[p].coordonnees[1][0] = R11X[i] * bunch[p].coordonnees[0][0] + R12X[i] * bunch[p].coordonnees[0][1] + (reseau[i]->DX - R11X[i] * reseau[i - 1]->DX - R12X[i] * reseau[i - 1]->DPX) * dpopeff;
863                        bunch[p].coordonnees[1][1] = R21X[i] * bunch[p].coordonnees[0][0] + R22X[i] * bunch[p].coordonnees[0][1] + (reseau[i]->DPX - R21X[i] * reseau[i - 1]->DX - R22X[i] * reseau[i - 1]->DPX) * dpopeff;
864                        bunch[p].coordonnees[1][2] = R11Y[i] * bunch[p].coordonnees[0][2] + R12Y[i] * bunch[p].coordonnees[0][3] + (reseau[i]->DY - R11Y[i] * reseau[i - 1]->DY - R12Y[i] * reseau[i - 1]->DPY) * dpopeff;
865                        bunch[p].coordonnees[1][3] = R21Y[i] * bunch[p].coordonnees[0][2] + R22Y[i] * bunch[p].coordonnees[0][3] + (reseau[i]->DPY - R21Y[i] * reseau[i - 1]->DY - R22Y[i] * reseau[i - 1]->DPY) * dpopeff;
866
867                        if ((reseau[i]->KEYWORD != "RFCAVITY") && (RFflag == 1)) {
868                            bunch[p].coordonnees[1][4] = bunch[p].coordonnees[0][4];
869                        }
870
871                        bunch[p].coordonnees[1][5] = bunch[p].coordonnees[0][5] + time(bunch[p], reseau[i]->L, betgam, i);
872
873                    }
874
875                }
876
877                if ((nonlinflag == 1) && ((icop == -1) || (resColli[icop]->method == "standard") || (resColli[icop]->method == "magnetic")) && (bunch[p].inabs != 0)) {
878
879                    int ixcor(-1), iycor (-1);
880
881                    for (int k(0); k < ixcormag.size(); ++k) {
882                        if (ixcormag[k] == i) {
883                            ixcor = k;
884                        }
885                    }
886
887                    if (ixcor != -1) {
888                        bunch[p].coordonnees[1][0] = bunch[p].coordonnees[1][0] + scaleorbit * (reseau[i]->S - reseau[i - 1]->S) / 2 * xcormag[ixcor] * (1 + dpopeff);
889                        bunch[p].coordonnees[1][1] = bunch[p].coordonnees[1][1] + scaleorbit * xcormag[ixcor] * (1 + dpopeff);
890                    }
891
892                    for (int k(0); k < iycormag.size(); ++k) {
893                        if (iycormag[k] == i) {
894                            iycor = k;
895                        }
896                    }
897
898                    if (iycor != -1) {
899                        bunch[p].coordonnees[1][2] = bunch[p].coordonnees[1][2] + scaleorbit * (reseau[i]->S - reseau[i - 1]->S) / 2 * ycormag[iycor] * (1 + dpopeff);
900                        bunch[p].coordonnees[1][3] = bunch[p].coordonnees[1][3] + scaleorbit * ycormag[iycor] * (1 + dpopeff);
901                    }
902
903                }
904
905
906
907                //checking for aperture hits
908                if (bunch[p].inabs == 1) {
909
910                    if ((icop == -1) || (resColli[icop]->method == "standard") || (resColli[icop]->method == "magnetic") || (resColli[icop]->method == "crystal")) {
911
912                        bool inside(false);
913
914                        if (reseau[i]->APERTYPE == "RECTANGLE") {
915                            if ((abs(bunch[p].coordonnees[1][0]) < reseau[i]->aperx) && (abs(bunch[p].coordonnees[1][2]) < reseau[i]->apery) && (abs(bunch[p].coordonnees[0][0]) < reseau[i]->aperx) && (abs(bunch[p].coordonnees[0][2]) < reseau[i]->apery)) {
916                                inside = true;
917                            }
918                        } else if ((reseau[i]->APERTYPE == "ELLIPSE") || (reseau[i]->APERTYPE == "CIRCLE") || (reseau[i]->APERTYPE == "RECTELLIPSE")) {
919                            if ((((bunch[p].coordonnees[1][0] / reseau[i]->aperx) * (bunch[p].coordonnees[1][0] / reseau[i]->aperx) + (bunch[p].coordonnees[1][2] / reseau[i]->apery) * (bunch[p].coordonnees[1][2] / reseau[i]->apery)) < 1) && (((bunch[p].coordonnees[0][0] / reseau[i]->aperx) * (bunch[p].coordonnees[0][0] / reseau[i]->aperx) + (bunch[p].coordonnees[0][2] / reseau[i]->apery) * (bunch[p].coordonnees[0][2] / reseau[i]->apery)) < 1)) {
920                                inside = true;
921
922                            }
923                        } else {
924                            cerr << "Error for the " << i << "th element: unknown aperture type!" << endl;
925                        }
926
927                        double L;
928
929                        L = reseau[i]->S - reseau[i - 1]->S; //distance to next element in the accelerator
930
931                        double Ap0h, Zp0h, xh0, xh, xhs, yh0, yh, yhs;
932                        int nh(0);//number of lost particles
933
934                        if (inside == false) {
935                            cout <<"The particle is lost at element " << reseau[i]->NAME << endl;
936//                           cout << "Particle ID is: " << p << endl;
937//                           cout << "bunch size is: " << bunch.size() << endl;
938//                           cout << "bunch status is: " << bunch[p].inabs << endl;
939//                           
940                            xh0 = bunch[p].coordonnees[0][0];
941                            bunch[p].inabs = 0;
942
943                            if (L == 0) {
944                                nh = nh + 1;
945                                hits.push_back(reseau[i]->S);//saving the value of s where the particles get lost
946                                Aphit.push_back(bunch[p].Ap0);//saving the mass of the lost particles
947                                Zphit.push_back(bunch[p].Zp0);//saving the charge of the lost particles
948                            } else {
949
950                                xh = bunch[p].coordonnees[1][0];
951                                xhs = (xh - xh0) / L;
952
953                                yh0 = bunch[p].coordonnees[0][2];
954                                yh = bunch[p].coordonnees[1][2];
955                                yhs = (yh - yh0) / L;
956
957                                Aphit.push_back(bunch[p].Ap0);
958                                Zphit.push_back(bunch[p].Zp0);
959
960                                double slostx, slosty, splus, sminus;
961
962                                if (reseau[i]->APERTYPE == "RECTANGLE") {
963
964                                    //find hit position in x
965
966                                    if ((abs(xh0) < reseau[i]->aperx) && (abs(xh) < reseau[i]->aperx)) { //both points inside aperture - particle lost in y instead
967                                        slostx = reseau[i]->S;
968
969                                    } else if (abs(xh0) > reseau[i]->aperx) { //first point outside - particle lost already at the entrance of the element
970                                        slostx = reseau[i - 1]->S;
971
972                                    } else {//first point inside, second point outside - do a linear interpolation
973
974                                        splus = (reseau[i]->aperx - xh0) / xhs;
975                                        sminus = (-reseau[i]->aperx - xh0) / xhs;
976
977                                        if (splus > sminus) { //choose the correct point where the straight line hits the aperture, at +-a. The highest s-value is correct
978                                            slostx = splus + reseau[i - 1]->S;
979
980                                        } else {
981                                            slostx = sminus + reseau[i - 1]->S;
982
983                                        }
984                                    }
985
986                                    //find hit position in y
987
988                                    if ((abs(yh0) < reseau[i]->apery) && (abs(yh) < reseau[i]->apery)) { //both points inside aperture - particle lost in x instead
989                                        slosty = reseau[i]->S;
990                                    } else if (abs(yh0) > reseau[i]->apery) { //first point outside - particle lost already at the entrance of the element
991                                        slosty = reseau[i - 1]->S;
992                                    } else {//first point inside, second point outside - do a linear interpolation
993
994                                        splus = (reseau[i]->apery - yh0) / yhs;
995                                        sminus = (-reseau[i]->apery - yh0) / yhs;
996
997                                        if (splus > sminus) { //choose the right point where the straight line hits the aperture, at +-b. The highest s-value is correct
998                                            slosty = splus + reseau[i - 1]->S;
999                                        } else {
1000                                            slosty = sminus + reseau[i - 1]->S;
1001                                        }
1002                                    }
1003
1004                                    //choose the point where the particle hits first, x or y
1005
1006                                    if (slostx < slosty) {
1007                                        hits.push_back(slostx);
1008                                    } else {
1009                                        hits.push_back(slosty);
1010                                    }
1011                                } else if (reseau[i]->APERTYPE == "ELLIPSE") {
1012
1013                                    double sqrarg;
1014                                    sqrarg = reseau[i]->apery * reseau[i]->apery * xhs * xhs - xhs * xhs * yh0 * yh0 + 2 * xh0 * xhs * yh0 * yhs + reseau[i]->aperx * reseau[i]->aperx * yhs * yhs - xh0 * xh0 * yhs * yhs;
1015                                    if (sqrarg < 0) {
1016                                        cout << "Warning, sqrarg < 0" << endl;
1017                                        hits.push_back(reseau[i - 1]->S);
1018                                    } else {
1019                                        double stry;
1020
1021                                        stry = (-reseau[i]->apery * reseau[i]->apery * xh0 * xhs - reseau[i]->aperx * reseau[i]->aperx * yh0 * yhs - reseau[i]->aperx * reseau[i]->apery * sqrt(sqrarg)) / (reseau[i]->apery * reseau[i]->apery * xhs * xhs + reseau[i]->aperx * reseau[i]->aperx * yhs * yhs);
1022
1023                                        if ((stry > 0) && (stry < L)) {
1024                                            hits.push_back(reseau[i - 1]->S + stry);
1025                                        } else {
1026
1027                                            double stry2;
1028
1029                                            stry2 = (-reseau[i]->apery * reseau[i]->apery * xh0 * xhs - reseau[i]->aperx * reseau[i]->aperx * yh0 * yhs + reseau[i]->aperx * reseau[i]->aperx * sqrt(sqrarg)) / (reseau[i]->apery * reseau[i]->apery * xhs * xhs + reseau[i]->aperx * reseau[i]->aperx * yhs * yhs);
1030
1031                                            if ((stry2 > 0) && (stry2 < L)) {
1032                                                hits.push_back(reseau[i - 1]->S + stry2);
1033                                            } else {
1034                                                hits.push_back(reseau[i - 1]->S);
1035                                            }
1036                                        }
1037                                    }
1038                                }//end if ELLIPSE
1039                                else if (reseau[i]->APERTYPE == "RECTELLIPSE") {
1040
1041                                    double sqrarg;
1042                                    sqrarg = reseau[i]->apery * reseau[i]->apery * xhs * xhs - xhs * xhs * yh0 * yh0 + 2 * xh0 * xhs * yh0 * yhs + reseau[i]->aperx * reseau[i]->aperx * yhs * yhs - xh0 * xh0 * yhs * yhs;
1043                                    if (sqrarg < 0) {
1044                                        cout << "Warning, sqrarg < 0" << endl;
1045                                        hits.push_back(reseau[i - 1]->S);
1046                                    } else {
1047                                        double stry;
1048                                        stry = (-reseau[i]->apery * reseau[i]->apery * xh0 * xhs - reseau[i]->aperx * reseau[i]->aperx * yh0 * yhs - reseau[i]->aperx * reseau[i]->apery * sqrt(sqrarg)) / (reseau[i]->apery * reseau[i]->apery * xhs * xhs + reseau[i]->aperx * reseau[i]->aperx * yhs * yhs);
1049
1050                                        if ((stry > 0) && (stry < L)) {
1051                                            hits.push_back(reseau[i - 1]->S + stry);
1052                                        } else {
1053                                            double stry2;
1054
1055                                            stry2 = (-reseau[i]->apery * reseau[i]->apery * xh0 * xhs - reseau[i]->aperx * reseau[i]->aperx * yh0 * yhs + reseau[i]->aperx * reseau[i]->apery * sqrt(sqrarg)) / (reseau[i]->apery * reseau[i]->apery * xhs * xhs + reseau[i]->aperx * reseau[i]->aperx * yhs * yhs);
1056
1057                                            if ((stry2 > 0) && (stry2 < L)) {
1058                                                hits.push_back(reseau[i - 1]->S + stry2);
1059                                            } else {
1060                                                hits.push_back(reseau[i - 1]->S);
1061                                            }
1062                                        }
1063                                    }
1064                                }//end RECTELLIPSE
1065                            }//end else after if L == 0
1066
1067                        }//end si particle lost
1068                        else {
1069                            //cout << "No losses, all the particles stay in the experience." << endl;
1070                        }
1071                    }//end if icop==vide ||...
1072
1073                }
1074            }
1075
1076            //Different ways to print the coordinates of the particle through the parameters IDPART and OUTCOORD (see manual)
1077
1078            if ((outcoord != 0) && (bunch[p].inabs != 0)) {
1079
1080                if (outcoord == 1) {
1081
1082                    cout << "Particle " <<  p + 1 << " after the passage through element: " << i << " " << reseau[i]->NAME << endl;
1083                    bunch[p].afficheCoordonnees();
1084                    cout << "Turn number " << turn << endl;
1085                    cout << "Massnumber: " << bunch[p].Ap0 << " Chargestate: " << bunch[p].Zp0 << endl;
1086                    cout << "Particle ID: " << bunch[p].getidentification() << endl;
1087                } else if (outcoord == 3) {
1088
1089                    if (bunch[p].getidentification() == choicePart) {
1090                        outCoord(bunch[p], i, outputpath + "/coordinates.dat");
1091                    }
1092                } else if (outcoord == 4) {
1093
1094                    if (bunch[p].getidentification() == choicePart) {
1095                        outPunct(i, bunch[p], bunch[0], attr1, outputpath);
1096                    }
1097                }
1098
1099                else if (outcoord == 2) {
1100                    outElt(i, bunch[p], outputpath, indication);
1101                }
1102            }
1103
1104
1105        }//end loop over particles
1106
1107
1108        //we prepare the particles for the next element
1109        for (int b(0); b < bunch.size(); ++b) {
1110            if (bunch[b].inabs != 0) {
1111                for (int r(0); r < 6; ++r) {
1112                    bunch[b].coordonnees[0][r] = bunch[b].coordonnees[1][r];
1113                }
1114            }
1115        }
1116    //    cout << "bunch size is ...." << bunch.size() << endl;
1117
1118        if (plotflag == "Yes") {
1119
1120            vector <double> temp1, temp2;
1121
1122            for (int h(0); h < bunch.size(); ++h) {
1123                if (bunch[h].inabs != 0) {
1124                    temp1.push_back(bunch[h].coordonnees[0][0]);
1125                    temp2.push_back(bunch[h].coordonnees[0][2]);
1126                } else {
1127                    temp1.push_back(100);
1128                    temp2.push_back(100);
1129                }
1130            }
1131
1132            xco.push_back(temp1);
1133            yco.push_back(temp2);
1134
1135            temp1.clear();
1136            temp2.clear();
1137        }
1138
1139
1140        //if there are no more particles, we return
1141        if (bunch.size() == 0) {
1142            return;
1143        }
1144
1145    }//end loop elements
1146
1147    vector <Particle> tempinabs;
1148
1149    //we contine to track for the next turn; just with particles that are not lost
1150    for (int w(0); w < bunch.size(); ++w) {
1151        if (bunch[w].inabs != 0) {
1152            tempinabs.push_back(bunch[w]);
1153        }
1154    }
1155
1156 //   cout << "bunch size before the turn: "<< bunch.size() << endl;
1157   
1158    bunch.clear();
1159
1160    for (int w(0); w < tempinabs.size(); ++w) {
1161        bunch.push_back(tempinabs[w]);
1162    }
1163
1164    tempinabs.clear();
1165
1166   // cout << "bunch size after the turn " <<bunch.size() << endl;
1167}
Note: See TracBrowser for help on using the repository browser.