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

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

complements graphiques, legendes et unification unites

File size: 10.7 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#include "mixedTools.h"
8
9softwareParmela::softwareParmela() : abstractSoftware()
10{;}
11
12softwareParmela::softwareParmela(string inputFileName, globalParameters* globals, dataManager* dt) : abstractSoftware(inputFileName, globals, dt)
13{;}
14
15bool softwareParmela::createInputFile(particleBeam* beamBefore,unsigned int numeroDeb,unsigned int numeroFin,string workingDir)
16{
17  unsigned int k;
18   
19  if ( numeroDeb < 1 || numeroFin > dataManager_->getBeamLineSize() ) {
20    dataManager_->consoleMessage(" softwareParmela::createInputFile : numero of element out of limits " );
21    cerr << " numero of element out of limits " << endl;
22    return false;
23  }
24   
25  string name = workingDir + inputFileName_;
26  ofstream outfile;
27  outfile.open(name.c_str(), ios::out);
28  if (!outfile) {
29    dataManager_->consoleMessage(" softwareParmela::createInputFile : error opening output stream " );
30    cerr << " softwareParmela::createInputFile : error opening output stream " << name << endl;
31    return false;
32  }
33 
34  abstractElement* elPtr;
35  double initalKineticEnergy = 0.0;
36  elPtr = dataManager_->getElementPointerFromNumero(numeroDeb);
37  bool there_is_rfgun = ( elPtr->getNomdElement().getElementType() == RFgun );
38 
39  if ( !there_is_rfgun ) {
40    string nameOfInput = workingDir + "parin.input0";
41    if ( !beamToParmela(nameOfInput,beamBefore) ) return false;
42    initalKineticEnergy = beamBefore->referenceKineticEnergyMeV();
43    // les elements de parmela sont indexes de 1 à max, s'il n'y a pas de rfgun
44    offsetNumElem_ = numeroDeb -1;
45  } else {
46    elPtr->setPhaseStep( globParamPtr_->getIntegrationStep() );
47    initalKineticEnergy = elPtr->getInitialKineticEnergy();
48    // les elements de parmela sont indexes de 0 à max, s'il y a un rfgun
49    offsetNumElem_ = numeroDeb;
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  unsigned int premier = numeroDeb ;
57  if ( there_is_rfgun ) {
58    outfile << dataManager_->getElementPointerFromNumero(numeroDeb)->parmelaOutputFlow() << endl;
59    premier++;
60  } else {
61    outfile << "INPUT 0 /NP=" << beamBefore->getNbParticles() << endl;
62  }
63 
64  // commentaire :  si l'element est un snapshot ne rien ecrire dans inputFileName_ (= parmin) un saut de ligne perturbe l'execution de parmela
65  for ( k = premier; k <= numeroFin; k++)
66    {
67      elPtr = dataManager_->getElementPointerFromNumero(k);
68      if (elPtr) {
69        if(elPtr->getNomdElement().getElementType() == snapshot) continue;
70        outfile << elPtr->parmelaOutputFlow() << endl;
71      }
72    }
73   
74  outfile << "ZOUT" << endl;
75  outfile << "START /wt=0.0 /dwt=" << globParamPtr_->getIntegrationStep() << "  /nsteps=" << globParamPtr_->getNbSteps() << "  nsc=" << globParamPtr_->getScPeriod() << "  /nout=10" << endl;
76  outfile << "END" << endl;
77  outfile.close();
78  dataManager_->consoleMessage("fichier input termine pour PARMELA");
79  return true;
80}
81
82bool softwareParmela::execute(unsigned int numeroDeb,unsigned int numeroFin,string workingDir)
83{
84  bool ExecuteStatus = true;
85 
86  ostringstream sortie;
87  sortie << " EXECUTION DE PARMELA DE l'ELEMENT " << numeroDeb << " A L'ELEMENT " << numeroFin << endl;
88   
89  string parmelaJob = workingDir + "parmela";
90  parmelaJob += string("   ");
91  parmelaJob += workingDir;
92 
93  string resultOfRun;
94  bool success = launchJob(parmelaJob,resultOfRun);
95  sortie << resultOfRun << endl;
96  if ( !success ) {
97    sortie << " launching of parmela failed " << endl;
98    ExecuteStatus = false;
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  dataManager_->consoleMessage(sortie.str());
111  return ExecuteStatus;
112}
113
114
115
116bool softwareParmela::buildBeamAfterElements(unsigned int numeroDeb,unsigned int numeroFin, vector<particleBeam>& beams, string workingDir)
117{
118  bool result = true;
119  //cout << "debug:: debut " << numeroDeb << ", fin " << numeroFin << endl;
120 
121  // index du premier element de parmela
122  int id= numeroDeb-offsetNumElem_;
123 
124  for(unsigned k = numeroDeb; k <= numeroFin; k++)
125    {
126      abstractElement* elem = dataManager_->getElementPointerFromNumero(k);
127   
128      // si l'element est un snapshot, recuperer la sortie precedente
129      if(elem->getNomdElement().getElementType() == snapshot) {
130        int avantDernier = beams.size() - 1;
131        string* param = elem->getParametersString();
132        string cliche = workingDir + param[2].c_str();
133        if( beamToParmela(cliche,&beams.at(avantDernier)) ) {
134          cout  <<  "["  <<  k  <<  "] : ecrit sur fichier " << cliche << " le contenu de beam["<<avantDernier<<"]"<<endl;
135        }
136        // continue;
137      }
138     
139      // sinon c'est un element de parmela d'index id
140      beams.push_back(particleBeam());
141      cout << " creation diagn. no " << beams.size() << " par PARMELA " << endl;
142
143      vector<double> centroid;
144      bareParticle refPart;
145      vector<bareParticle> particles;
146      double freq= globParamPtr_->getFrequency();
147     
148      cout << " lecture PARMELA el no absolu " << k << " nom " << elem->getNomdElement().getElementName() << endl;
149      if(!beamFromParmela(workingDir,id,freq,centroid,refPart,particles))
150        {
151          if(elem->is_accepted_by_software(nomDeLogiciel::parmela) == TBoolIgnore) {
152            int avantDernier = beams.size() -2;
153            beams.back() = beams.at(avantDernier);
154          } else {
155            dataManager_->consoleMessage("softwareParmela::buildBeamAfterElements : reading parmdesz failed");
156            result = false;
157            break;
158          }
159         
160        } else {
161        beams.back().setWithParticles(centroid,refPart,particles);
162      }
163     
164      // l'element de parmela suivant
165      id++;
166    }
167 
168  return result;
169}
170
171bool softwareParmela::beamFromParmela(string workingDir,unsigned numeroParmel, double referencefrequency, vector<double>& centroid, bareParticle& refPart,vector<bareParticle>& particles )
172{   
173  string nomfilefais = workingDir + "parmdesz";
174  cout << " nom fichier desz : " << nomfilefais << endl;
175  FILE *filefais = fopen(nomfilefais.c_str(), "r");
176 
177  if ( filefais == (FILE*)0 ) {
178    dataManager_->consoleMessage(" beamFromParmela() erreur a l'ouverture du fichier 'parmdesz'");
179    cerr << " beamFromParmela() erreur a l'ouverture du fichier" << nomfilefais  << endl;
180    return false;
181  } else
182    cout << " beamFromParmela() : ouverture du fichier " << nomfilefais << endl;
183 
184  parmelaParticle partic;
185  std::vector<parmelaParticle> faisceau;
186  int testNombrePartRef =0;
187  double phaseRef = 0.0;
188 
189  while( partic.readFromParmelaFile(filefais) > 0 )
190    {
191     
192      if ( partic.ne == (int)numeroParmel ) {
193        if ( partic.np == 1 ) {
194          // en principe on est sur la particule de reference
195          if ( fabs(partic.xx) > EPSILON || fabs(partic.yy) > EPSILON || fabs(partic.xxp) > EPSILON  || fabs(partic.yyp) > EPSILON) {
196            printf(" ATTENTION part. reference douteuse  \n");
197            partic.imprim();
198          }
199          phaseRef = partic.phi;
200         
201          // le 'z' est 'absolu' (le long de la trajectoire)
202          TRIDVECTOR  posRef(partic.xx,partic.yy,partic.z);
203          TRIDVECTOR betagammaRef(partic.xxp*partic.begamz, partic.yyp*partic.begamz, partic.begamz);
204          refPart = bareParticle(posRef, betagammaRef);
205          testNombrePartRef++;
206          if ( testNombrePartRef != 1 ) {
207            dataManager_->consoleMessage(" beamFromParmela : nombre de part. de ref different de 1 :");
208            cerr << " nombre de part. de ref different de 1 : " << testNombrePartRef << " !! " << endl;
209            return false;
210          }
211        }
212        faisceau.push_back(partic);
213      }
214    } //while
215 
216  if ( faisceau.size() == 0)
217    {
218      string stringNum = mixedTools::intToString( (int)numeroParmel );
219      dataManager_->consoleMessage("beamFromParmela echec lecture  element numero relatif  parmela : " + stringNum);
220      cerr << " beamFromParmela echec lecture  element numero relatif  parmela " << numeroParmel << endl;
221      return false;
222    }
223 
224  // facteur  c/ 360. pour calculer (c dphi) / (360.freq)
225  // avec freq en Mhz et dphi en degres et résultat en cm:
226  double FACTEUR =  83.3333;  // ameliorer la precision
227 
228  // pour l'instant on choisit un centroid nul;
229  centroid.clear();
230  centroid = vector<double>(6,0.0);
231 
232  particles.clear();
233  particles.resize(faisceau.size(), bareParticle());
234  double x,xp,y,yp;
235  double betagammaz;
236  double betaz;
237  double deltaz;
238  double dephas;
239  double g;
240  TRIDVECTOR  pos;
241  TRIDVECTOR betagamma;
242  // contrairement a ce qu'indique la notice PARMELA, dans parmdesz, les xp et yp
243  // sont donnes en radians
244  for (unsigned k = 0; k < faisceau.size(); k++) {
245    x= faisceau.at(k).xx;
246    xp=faisceau.at(k).xxp;
247    y= faisceau.at(k).yy;
248    yp=faisceau.at(k).yyp;
249    // dephasage par rapport a la reference
250    dephas = faisceau.at(k).phi - phaseRef; // degrés
251    g = faisceau.at(k).wz/EREST_MeV;
252    betagammaz = faisceau.at(k).begamz;
253    betaz = betagammaz/(g+1.0);
254    deltaz = FACTEUR * betaz * dephas / referencefrequency;
255    x += xp * deltaz;
256    y += yp * deltaz;
257    pos.setComponents(x,y,deltaz);
258    betagamma.setComponents(xp*betagammaz, yp*betagammaz, betagammaz);
259    particles.at(k) = bareParticle(pos,betagamma);
260  }
261 
262  return true;
263}
264
265// sauvegarde d'un 'particleBeam' sur un fichier parmela, en guise d'INPUT
266// pour l'instant de nom standard 'parin.input0'
267bool softwareParmela::beamToParmela(string nameOfFile,particleBeam* beam)
268{
269    if ( !beam->particleRepresentationOk() ) {
270        dataManager_->consoleMessage("softwareParmela::beamToParmela : beam not in particles form : not yet programmed");
271        cout << " softwareParmela::beamToParmela : beam not in particles form : not yet programmed " << endl;
272        return false;
273    }
274   
275    ofstream outfile;
276    outfile.open(nameOfFile.c_str(),ios::out);
277    if (!outfile) {
278        dataManager_->consoleMessage(" softwareParmela::beamToParmela : error opening output stream ");
279        cerr << " softwareParmela::beamToParmela : error opening output stream " << nameOfFile << endl;
280        return false;
281    }
282   
283    const vector<bareParticle>& partic = beam->getParticleVector();
284    double weight = 1.0;
285    double xx,yy,zz;
286    double begamx, begamy, begamz;
287    for (unsigned k = 0; k < partic.size(); k++) {
288        partic.at(k).getPosition().getComponents(xx,yy,zz);
289        partic.at(k).getBetaGamma().getComponents(begamx,begamy,begamz);
290        outfile << xx << " " << begamx << " " <<  yy << " " << begamy << " " << zz << " " << begamz  << " " << weight << endl;
291    }
292    outfile.close();
293    return true;
294}
Note: See TracBrowser for help on using the repository browser.