source: PSPA/Interface_Web/trunk/pspaWT/sources/controler/src/softwareParmela.cc @ 298

Last change on this file since 298 was 298, checked in by lemeur, 11 years ago

interface software

File size: 7.4 KB
Line 
1#include "softwareParmela.h"
2#include "abstractElement.h"
3#include "parmelaParticle.h"
4#include "mathematicalConstants.h"
5#include "PhysicalConstants.h"
6
7
8softwareParmela::softwareParmela() : abstractSoftware()
9{
10  ;
11}
12
13softwareParmela::softwareParmela(globalParameters* globals, elementsCollection* beamLine) : abstractSoftware(globals, beamLine)
14{
15  ;
16}
17
18bool softwareParmela::createInputFile(particleBeam* beamBefore, unsigned int numeroDeb, unsigned int numeroFin, string workingDir)
19{
20  unsigned int k;
21
22  if ( numeroDeb < 1 || numeroFin > beamLinePtr_->size() ) {
23    cerr << " index of element out of limits " << endl;
24    return false;
25  }
26
27
28  unsigned indexDeb = numeroDeb - 1;
29  unsigned indexFin = numeroFin - 1;
30
31  ofstream outfile;
32  string name = workingDir + "parmin";
33  outfile.open(name.c_str(), ios::out);
34  if (!outfile) {
35    cerr << " error opening output stream " << name << endl;
36    return false;
37  }
38
39  abstractElement* elPtr;
40  double initalKineticEnergy = 0.0;
41  elPtr = beamLinePtr_->getElementPointerFromIndex(indexDeb);
42  if ( elPtr->getNomdElement().getElementType() != RFgun ) {
43    cerr << " dataManager::createInputFileParmela : the first element should be rfgun" << endl;
44    return false;
45  }
46  else {
47    elPtr->setPhaseStep( globParamPtr_->getIntegrationStep() );
48    initalKineticEnergy = elPtr->getInitialKineticEnergy();
49  }
50
51
52  outfile << "TITLE" << endl;
53  outfile << " titre provisoire " << endl;
54  outfile << "RUN /n0=1 /ip=999 /freq=" << globParamPtr_->getFrequency() << "  /z0=0.0 /W0=" << initalKineticEnergy << "  /itype=1" << endl;
55  outfile << "OUTPUT 0" << endl;
56   
57  for ( k = indexDeb; k <= indexFin; k++)
58    {
59      elPtr = beamLinePtr_->getElementPointerFromIndex(k);
60      outfile << elPtr->parmelaOutputFlow() << endl;
61    }
62
63  outfile << "ZOUT" << endl;
64  outfile << "START /wt=0.0 /dwt=" << globParamPtr_->getIntegrationStep() << "  /nsteps=" << globParamPtr_->getNbSteps() << "  nsc=" << globParamPtr_->getScPeriod() << "  /nout=10" << endl;
65  outfile << "END" << endl;
66  outfile.close();
67  return true;
68}
69
70
71bool  softwareParmela::execute(unsigned int numeroDeb,unsigned int numeroFin,string workingDir,string& resul)
72{
73  ostringstream sortie;
74  bool ExecuteStatus = true;
75  resul.clear();
76  // if ( !createInputFile(NULL,numeroDeb,numeroFin, workingDir) )
77  //   {
78  //     sortie << " error creating parmela input file "  << endl;
79  //     resul = sortie.str();
80  //     return false;
81  //   }
82
83  sortie << " EXECUTION DE PARMELA DE l'ELEMENT " << numeroDeb << " A L'ELEMENT " << numeroFin << endl;
84
85  char buf[132];
86  string parmelaJob = workingDir + "parmela";
87  parmelaJob += string("   ");
88  parmelaJob += workingDir;
89  //  cout << " job parmela= " << parmelaJob << endl;
90
91  string resultOfRun;
92  bool success = launchJob(parmelaJob, resultOfRun);
93  sortie << resultOfRun << endl;
94  if ( !success) {
95    sortie << " launching of parmela failed " << endl;
96    ExecuteStatus = false;
97  }
98  else {
99    cout << " execution parmela MARCHE " << endl;
100    sortie << resultOfRun;
101    string::size_type nn = (resultOfRun).find("normal");
102    if ( nn == string::npos ) 
103      {
104        sortie << " abnormal exit of parmela " << endl;
105        ExecuteStatus = false;
106      }
107    // else
108    //   {
109    //  ExecuteStatus = buildBeamAfterElements(numeroDeb,numeroFin, beamAfterElement, workingDir);
110    //  if ( !ExecuteStatus ) {
111    //            sortie << " reading parmdesz  failed " << endl;
112    //  }
113
114    //   }
115  }
116
117  resul =  sortie.str(); 
118  return ExecuteStatus;
119}
120
121
122bool  softwareParmela::buildBeamAfterElements(unsigned int numeroDeb,unsigned int numeroFin, vector<particleBeam>& beams, string workingDir) {
123  bool result = true;
124        unsigned k;
125        for ( k= numeroDeb; k <= numeroFin; k++)
126          {
127            beams.push_back(particleBeam());
128            vector<double> centroid;
129            bareParticle refPart;
130            vector<bareParticle> particles;
131            if (!beamFromParmela(workingDir,k, globParamPtr_->getFrequency(), centroid, refPart,particles ))
132              {
133                abstractElement* elem = beamLinePtr_->getElementPointerFromNumero(k);
134                if ( elem->is_accepted_by_software(nomDeLogiciel::parmela) == warning) {
135                  int avantDernier = beams.size() -2;
136                  beams.back() = beams.at(avantDernier);
137                } else {
138                  // sortie << " reading parmdesz  failed " << endl;
139                  result = false;
140                  break;
141                }
142              }
143            else {
144              beams.back().setWithParticles(centroid, refPart,particles); 
145            }
146          }
147        return result;
148}
149
150
151
152
153bool softwareParmela::beamFromParmela(string workingDir,unsigned numeroElement, double referencefrequency, vector<double>& centroid, bareParticle& refPart,vector<bareParticle>& particles ) {
154  unsigned  k;
155  FILE* filefais;
156  string nomfilefais = workingDir + "parmdesz";
157  cout << " nom fichier desz : " << nomfilefais << endl;
158  filefais = fopen(nomfilefais.c_str(), "r");
159
160  if ( filefais == (FILE*)0 ) {
161    cerr << " particleBeam::setFromParmela() erreur a l'ouverture du fichier" << nomfilefais  << endl;; 
162    return false;
163  }
164  else cout << " particleBeam::setFromParmela() : ouverture du fichier " << nomfilefais << endl; 
165
166  parmelaParticle partic;
167  std::vector<parmelaParticle> faisceau;
168
169  cout << " particleBeam::setFromParmela : numeroElement = " << numeroElement << endl;
170  unsigned indexElement = numeroElement-1;
171 
172
173
174
175  int testNombrePartRef =0;
176  double phaseRef;
177
178  while( partic.readFromParmelaFile(filefais) > 0 ) {
179    if ( partic.ne == (int)indexElement )
180      {
181        faisceau.push_back(partic);
182
183        if ( partic.np == 1 ) {
184          // en principe on est sur la particule de reference
185          if ( fabs(partic.xx) > EPSILON || fabs(partic.yy) > EPSILON || fabs(partic.xxp) > EPSILON  || fabs(partic.yyp) > EPSILON) {
186            printf(" ATTENTION part. reference douteuse  \n");
187            partic.imprim();
188          }
189          phaseRef = partic.phi;
190          TRIDVECTOR  posRef(partic.xx,partic.yy,0.0);
191          TRIDVECTOR betagammaRef(partic.xxp*partic.begamz, partic.yyp*partic.begamz, partic.begamz);
192          refPart = bareParticle(posRef, betagammaRef);
193          testNombrePartRef++;
194          if ( testNombrePartRef != 1 ) {
195            cerr << " TROP DE PART. DE REF : " << testNombrePartRef << " !! " << endl;
196            return false;
197          }
198        }
199      }
200  }
201
202  if ( faisceau.size() == 0) 
203    {
204      cerr << " particleBeam::setFromParmela echec lecture  element " << numeroElement << endl;
205      return false;
206    }
207 
208  // facteur  c/ 360. pour calculer (c dphi) / (360.freq)
209  // avec freq en Mhz et dphi en degres et résultat en cm:
210  double FACTEUR =  83.3333;  // ameliorer la precision
211
212
213
214  // pour l'instant on choisit un centroid nul;
215  centroid.clear();
216  centroid = vector<double>(6,0.0);
217
218  particles.clear();
219  particles.resize(faisceau.size(), bareParticle());
220  double x,xp,y,yp;
221  double betagammaz;
222  double betaz;
223  double deltaz;
224  double dephas;
225  double g;
226  TRIDVECTOR  pos;
227  TRIDVECTOR betagamma;
228  // contrairement a ce qu'indique la notice PARMELA, dans parmdesz, les xp et yp
229  // sont donnes en radians
230  for ( k=0; k < faisceau.size(); k++) {
231    x=faisceau.at(k).xx;
232    xp=faisceau.at(k).xxp;
233    y=faisceau.at(k).yy;
234    yp=faisceau.at(k).yyp;
235
236    // dephasage par rapport a la reference 
237    dephas = faisceau.at(k).phi - phaseRef; // degrés
238    g = faisceau.at(k).wz/ERESTMeV;
239    betagammaz = faisceau.at(k).begamz;
240    betaz = betagammaz/(g+1.0);
241    deltaz = FACTEUR * betaz * dephas / referencefrequency;
242    x += xp * deltaz;
243    y += yp * deltaz;
244    pos.setComponents(x,y,deltaz);
245    betagamma.setComponents(xp*betagammaz, yp*betagammaz, betagammaz);
246    particles.at(k) = bareParticle(pos,betagamma);
247  }
248  return true;
249}
Note: See TracBrowser for help on using the repository browser.