source: PSPA/Interface_Web/trunk/pspaWT/sources/controler/src/softwareMadx.cc @ 487

Last change on this file since 487 was 487, checked in by touze, 10 years ago

ajout de quadrupole et sextupole

File size: 10.8 KB
Line 
1
2#include "softwareMadx.h"
3#include "dataManager.h"
4
5#include "mathematicalConstants.h"
6#include "PhysicalConstants.h"
7
8#include <boost/filesystem.hpp>
9
10softwareMadx::softwareMadx() : abstractSoftware()
11{
12  nameOfSoftware_ = new nomDeLogiciel("madx");
13}
14
15softwareMadx::softwareMadx(string inputFileName,sectionToExecute* sect, dataManager* data) : abstractSoftware(inputFileName,sect,data)
16{
17  nameOfSoftware_ = new nomDeLogiciel("madx");
18}
19
20bool softwareMadx::createInputFile(particleBeam* beamBefore,string workingDir)
21{
22  cout << "***********************************" << endl;
23  cout << " softwareMadx::createInputFile(...) " << endl << endl;
24  dataManager_->consoleMessage(" softwareMadx::createInputFile");
25
26  string name = workingDir + inputFileName_;
27  ofstream outfile;
28  outfile.open(name.c_str(),ios::out);
29  if(!outfile) {
30    dataManager_->consoleMessage(" softwareMadx::createInputFile : error opening output stream ");
31    cerr << " error opening output stream " << name << endl;
32    return false;
33  }
34
35  sector* sector= getSectionToExecute()->getSector();
36  cout << " softwareMadx::createInputFile sector " << sector->getName() << endl;
37  ///////////////////////////////////////////
38 
39  unsigned firstIndex= 0;
40  string sbeam;
41  abstractElement* elPtr;
42  elPtr = getSectionToExecute()->getElements().front();
43  nomdElements::typedElement eType = elPtr->getNomdElement().getElementType();
44
45  if(eType == nomdElements::RFgun) {
46    // le 1er elt est RFgun
47    firstIndex = 1;
48    dataManager_->consoleMessage(" softwareMadx::createInputFile : set from RF cavity the quantities to be supplied to the madx BEAM command");
49    sbeam = RFgunData(elPtr->parametersToSoftware());
50  } else if(eType == nomdElements::beam) {
51    // le 1er elt est beam
52    firstIndex = 1;
53    dataManager_->consoleMessage(" softwareMadx::createInputFile : set from beam the quantities to be supplied to the madx BEAM command");
54    sbeam = beamData(elPtr->parametersToSoftware());
55  } else {
56    // on suppose qu'il y a déjà un faisceau
57    if(beamBefore == NULL) { 
58      // il n'y a pas de faisceau : erreur
59      dataManager_->consoleMessage(" softwareMadx::createInputFile : no input beam, input file not created");
60      return false;
61    } else { 
62      // il y a un faisceau : on le met au format madx
63      dataManager_->consoleMessage(" softwareMadx::createInputFile : extract from input beam the quantities to be supplied to the madx BEAM command");
64     
65      if (beamBefore->particleRepresentationOk()) {
66        // le faisceau est représenté à la "parmela"
67        cout << "passsage de la représentation macroparticules à la representation moments" << endl;
68        beamBefore->buildMomentRepresentation();
69      } else if(beamBefore->momentRepresentationOk()) {
70        // le faisceau est représenté à la "transport"
71        cout << "le faisceau est représenté par moments" << endl;
72      } else {
73        // représentation ni "macroparticules" ni "moments"
74        dataManager_->consoleMessage(" softwareMadx::createInputFile : that's unclear: the beam is represented neither by macroparticles neither by moments");
75        return false;
76      }
77      sbeam = beamData(beamBefore);
78    }
79  }
80  ///////////////////////////////////////////
81
82  // element label //////////////////////////
83  outfile << endl; // saut de ligne
84
85  ostringstream os;
86  os << "L: line=(";
87  unsigned nElts= getSectionToExecute()->getElements().size();
88  for(unsigned k = firstIndex; k < nElts; k++)
89    {
90      elPtr = getSectionToExecute()->getElements()[k];
91      cout << " debug:: element [" << k << "] " << elPtr->getNomdElement().getExpandedName() << endl;
92      vector<statements> v= elPtr->parametersToSoftware();
93      outfile << inputFormat(v);
94
95      if(k < nElts-1) 
96        os << elPtr->getLabel() << ",";
97      else
98        os << elPtr->getLabel() << ");" << endl;
99    }
100
101  // lines/sublines ///////////////////////////////
102  outfile << endl; // saut de ligne
103 
104  // relection and repetition ///////////////
105  os << "all: " << "line=(" << sector->getRepetitionNumber() << "*L);";
106  ///////////////////////////////////////////
107 
108  outfile << os.str() << endl;
109  outfile << endl; // saut de ligne
110  ///////////////////////////////////////////
111
112  outfile << sbeam << endl; // beam commnd p46
113  outfile << "use, period = all;" << endl << endl; // action commands p45
114 
115  outfile << "select,flag = twiss,column = name,s,betx,bety;" << endl; //p48
116  outfile << "twiss,save,centre,file = "+workingDir+"twiss.out;" << endl; //p51
117  outfile << "stop;" << endl;
118
119  outfile.close();
120  dataManager_->consoleMessage("input file done for madx");
121  return true;
122}
123
124string softwareMadx::beamData(const vector<statements>& v) const 
125{
126  // x  (cm)   = v.at(1).second.at(0)
127  // xp (mrad) = v.at(1).second.at(1)
128  // y  (cm)   = v.at(1).second.at(2)
129  // yp (mrad) = v.at(1).second.at(3)
130  // dl  (cm)   = v.at(2).second.at(0)
131  // del (mrad) = v.at(2).second.at(1)
132  // p0 (GeV/c) = v.at(3).second.at(0)
133 
134  ostringstream os;
135  os << "beam, PARTICLE = ELECTRON";
136
137  double PC = atof(v.at(3).second.at(0).c_str());
138  os << ", ENERGY = " << PC; // momentum of the central trajectory [GeV/c]
139
140  double x  = atof(v.at(1).second.at(0).c_str());
141  double xp = atof(v.at(1).second.at(1).c_str());
142  double y  = atof(v.at(1).second.at(2).c_str());
143  double yp = atof(v.at(1).second.at(3).c_str());
144  double dl = atof(v.at(2).second.at(0).c_str());
145  double del= atof(v.at(2).second.at(1).c_str());
146  beam2Moments mts(x,xp,y,yp,dl,del);
147  os << emittances(mts) << ";";
148  return os.str(); 
149}
150
151string softwareMadx::beamData(particleBeam* beam) const 
152{
153  // les commandes BEAM de madx sont :
154  // PARTICLE (defaut POSITRON)
155  // ENERGY (defaut 1 GeV) ou bien PC GeV/c
156  // EX et EY (defaut 1 m.rad)
157  // ET (defaut 1 m)
158
159  ostringstream os;
160  os << "beam, PARTICLE = ELECTRON";
161
162  double PC = beam->getP0Transport();
163  os << ", ENERGY = " << PC; // en GeV/c
164
165  const beam2Moments& mts = beam->getTransportMoments();
166  os << emittances(mts) << ";";
167  return os.str();
168}
169
170string softwareMadx::emittances(const beam2Moments& mts) const 
171{
172  const vector< vector<double> > rij= mts.getMoments();
173  ostringstream os;
174
175  // emittance (x,x')
176  double r10= rij.at(1).at(0); // r10 et s10 = s01= r10*r00*r11
177  double rac= 0.0;
178  if(r10*r10 < 1.0) rac= sqrt(1.0-r10*r10);
179  double EX = rij.at(0).at(0)*rij.at(1).at(1)*rac; // r00*r11*sqrt(1-s01*s10)
180  // r00 en cm (= 1E-02 m) et r11 en mrad (= 1E-03 rad)
181  os << ", EX = " << EX*1.E-05;
182
183  // emittance (y,y')
184  double r32= rij.at(3).at(2); // r32 et s32 = s23= r32*r22*r33
185  rac= 0.0;
186  if(r32*r32 < 1.0) rac= sqrt(1.0-r32*r32);
187  double EY = rij.at(2).at(2)*rij.at(3).at(3)*rac; // r22*r33*sqrt(1-s23*s32)
188  os << ", EY = " << EY*1.E-05;
189
190  return os.str();
191}
192
193string softwareMadx::RFgunData(const vector<statements>& v) const 
194{
195  //NPART = v.at(1).second.at(0);
196  //SIGT (m) = v.at(2).second.at(0) (ps)
197  //?? = sigma_r = v.at(2).second.at(1); en cm
198  //EX (m.rad) = v.at(3).second.at(0) (pi.mm.mrad)
199  //EY (m.rad) = v.at(3).second.at(1) (pi.mm.mrad)
200  //ENERGY (GeV) = v.at(4).second.at(0) (MeV)
201  //SIGE (GeV) = v.at(4).second.at(1) (MeV)
202  //CHARGE = v.at(6).second.at(0);
203
204  ostringstream os;
205  os << "beam, PARTICLE = ELECTRON";
206
207  // masse au repos (en GeV) E0 = 1.E-03*EREST_MeV
208  // energie cinetique (en GeV) T = 1.E-03*E_cin
209  // l'energie totale  (en Gev) W = E0+T
210  double W = 1.E-03*(EREST_MeV + atof(v.at(4).second.at(0).c_str()));
211  os << ", ENERGY = " << W; // total energy in [Gev]
212
213  // pi*EX = 1E-06*emit_x en pi.m.rad
214  double EX = 1.E-06*atof(v.at(3).second.at(0).c_str())/PI;
215  os << ", EX = " << EX; // horizontal emittance in [rad.m]
216  double EY = 1.E-06*atof(v.at(3).second.at(1).c_str())/PI;
217  os << ", EY = " << EY; // vertical emittance in [rad.m]
218
219  // SIGT = c*sigma_t*1E-12
220  double SIGT = 1.E-04*CLIGHT_E8*atof(v.at(2).second.at(0).c_str());
221  os << ", SIGT = " << SIGT; // bunch length in [m]
222
223  // SIGE = sigma_Ecin/(p0*c) ou p0 impulsion de la paricule de réf.
224  // os << ", SIGE = " << atof(v.at(4).second.at(1).c_str());
225
226  os << ";";
227  return os.str();
228}
229
230string softwareMadx::inputFormat(const vector<statements>& v) const 
231{
232  // v.at(0).first = "labelsGenericSpecific"
233  // v.at(0).second = vector<string> de 2 elements (type de l'element,label)
234  string keyword= v.at(0).second.at(0);
235  string label= v.at(0).second.at(1);
236  ostringstream os;
237  if(keyword == "drift") {
238    double length = atof(v.at(1).second.at(0).c_str());
239    os << label << ":" << " drift, l=" << 0.01*length << ";" << endl;
240
241  } else if(keyword == "mpole") {
242    double x[9]= {0.0}; // 0 <= n <= 9 in user's manual of MAD program 
243    int n= atoi(v.at(1).second.at(0).c_str());
244    x[n]= atof(v.at(1).second.at(1).c_str());
245    os << label << ":" << " multipole, knl={" << x[0];
246    for(int i = 1; i <= n; i++) {
247      os << "," << x[i];
248    }
249    os <<"};" << endl;
250   
251  } else if(keyword == "qpole") {
252    double ln = atof(v.at(1).second.at(0).c_str());
253    double k1 = atof(v.at(1).second.at(1).c_str());
254    os << label << ":" << " quadrupole, l=" << ln << ", k1= " << k1 << ";" << endl;
255
256  } else if(keyword == "spole") {
257    double ln = atof(v.at(1).second.at(0).c_str());
258    double k2 = atof(v.at(1).second.at(1).c_str());
259    os << label << ":" << " sextupole, l=" << ln << ", k2= " << k2 << ";" << endl;
260
261  } else {
262    cout << "softwareMadx::inputFormat ERROR : element type= " << keyword << " not defined" << endl;
263  }
264 
265  return os.str();
266}
267
268bool softwareMadx::execute(string workingDir)
269{
270  cout << "***********************************" << endl;
271  cout << " softwareMadx::execute(...) " << endl << endl;
272
273  dataManager_->consoleMessage(" softwareMadx::execute");
274  ostringstream sortie;
275  bool status= true;
276  string mjob = workingDir + "madx64";
277 
278  if(!boost::filesystem::exists(mjob.c_str())) { 
279    sortie << "Error:: " << mjob << " does not exist\n";
280    status = false;
281  } else {
282    mjob += string(" <  ");
283    mjob += workingDir + inputFileName_;
284    sortie << " run " << mjob << endl;
285    string resultOfRun;
286    bool success = launchJob(mjob,resultOfRun);
287    // xx sortie << resultOfRun << endl;
288    if ( !success ) {
289      //sortie << " launching of madx failed " << endl;
290      status = false;
291    } else {
292      sortie << " madx finished normally" << endl;
293      string nameOut = workingDir + "madx.output";
294      ofstream outfile;
295      outfile.open(nameOut.c_str(),ios::out);
296      if (!outfile) {
297        sortie << " error in opening madx output stream " << nameOut << endl;
298        status = false;
299      } else {
300        // on copie la sortie dans un fichier 'madx.out'
301        outfile << resultOfRun << endl;
302        outfile.close();
303      }
304    }
305  }
306
307  dataManager_->consoleMessage(sortie.str());
308  return status;
309}
310
311bool softwareMadx::buildBeamAfterElements(string workingDir)
312{
313  cout << "***********************************" << endl;
314  cout << " softwareMadx::buildBeamAfterElements(...) " << endl << endl;
315
316  dataManager_->consoleMessage(" softwareMadx::buildBeamAfterElements: not programmed :O((");
317  return false;
318}
Note: See TracBrowser for help on using the repository browser.