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

Last change on this file since 314 was 314, checked in by lemeur, 12 years ago

energie cinetique pour parmela sans rfgun

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