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

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

addition graphique (en cours)

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