00001 #include "BDSComponentFactory.hh"
00002
00003
00004 #include "BDSAwakeScintillatorScreen.hh"
00005 #include "BDSCollimatorElliptical.hh"
00006 #include "BDSCollimatorRectangular.hh"
00007 #include "BDSDrift.hh"
00008 #include "BDSDump.hh"
00009 #include "BDSElement.hh"
00010 #include "BDSKicker.hh"
00011 #include "BDSLaserWire.hh"
00012 #include "BDSLine.hh"
00013 #include "BDSMuSpoiler.hh"
00014 #include "BDSOctupole.hh"
00015 #include "BDSQuadrupole.hh"
00016 #include "BDSRBend.hh"
00017 #include "BDSRfCavity.hh"
00018 #include "BDSSampler.hh"
00019 #include "BDSSamplerCylinder.hh"
00020 #include "BDSScintillatorScreen.hh"
00021 #include "BDSSectorBend.hh"
00022 #include "BDSSextupole.hh"
00023 #include "BDSSolenoid.hh"
00024 #include "BDSTerminator.hh"
00025 #include "BDSTeleporter.hh"
00026 #include "BDSMultipole.hh"
00027 #include "BDSTransform3D.hh"
00028
00029
00030 #include "BDSBeamline.hh"
00031 #include "BDSBeamPipeType.hh"
00032 #include "BDSBeamPipeInfo.hh"
00033 #include "BDSDebug.hh"
00034 #include "BDSExecOptions.hh"
00035 #include "BDSMagnetOuterInfo.hh"
00036 #include "BDSMagnetGeometryType.hh"
00037 #include "BDSTunnelInfo.hh"
00038
00039 #include "parser/enums.h"
00040 #include "parser/elementlist.h"
00041
00042 #include <cmath>
00043 #include <sstream>
00044 #include <string>
00045
00046 #ifdef BDSDEBUG
00047 bool debug1 = true;
00048 #else
00049 bool debug1 = false;
00050 #endif
00051
00052 BDSComponentFactory::BDSComponentFactory(){
00053 verbose = BDSExecOptions::Instance()->GetVerbose();
00054 lengthSafety = BDSGlobalConstants::Instance()->GetLengthSafety();
00055
00056
00057
00058
00059
00060 _charge = BDSGlobalConstants::Instance()->GetParticleDefinition()->GetPDGCharge();
00061
00062
00063 _momentum = BDSGlobalConstants::Instance()->GetBeamMomentum()/CLHEP::GeV;
00064
00065 _brho = BDSGlobalConstants::Instance()->GetFFact()*( _momentum / 0.299792458);
00066
00067
00068 _brho *= (CLHEP::tesla*CLHEP::m);
00069
00070 if (verbose || debug1) G4cout << "Rigidity (Brho) : "<< fabs(_brho)/(CLHEP::tesla*CLHEP::m) << " T*m"<<G4endl;
00071 }
00072
00073 BDSComponentFactory::~BDSComponentFactory(){
00074 }
00075
00076 BDSAcceleratorComponent* BDSComponentFactory::createComponent(std::list<struct Element>::iterator elementIter, ElementList& beamline_list){
00077 #ifdef BDSDEBUG
00078 G4cout << "BDSComponentFactory::createComponent() making iterators" << G4endl;
00079 #endif
00080 _elementIter = elementIter;
00081 _previousElementIter = elementIter;
00082 _nextElementIter= elementIter;
00083 if(_elementIter != beamline_list.begin()){
00084 #ifdef BDSDEBUG
00085 G4cout << "BDSComponentFactory::createComponent() moving to previous element" << G4endl;
00086 #endif
00087 _previousElementIter--;
00088 }
00089
00090 _nextElementIter++;
00091 if(_nextElementIter == beamline_list.end()){
00092 #ifdef BDSDEBUG
00093 G4cout << "BDSComponentFactory::createComponent() at the end, not moving to next element" << G4endl;
00094 #endif
00095 _nextElementIter--;
00096 }
00097 #ifdef BDSDEBUG
00098 G4cout << "BDSComponentFactory::createComponent() creating and returning component..." << G4endl;
00099 #endif
00100 return createComponent(*_elementIter, *_previousElementIter, *_nextElementIter);
00101 }
00102
00103 BDSAcceleratorComponent* BDSComponentFactory::createComponent(Element& aElement, Element& previousElement, Element& nextElement){
00104 #ifdef BDSDEBUG
00105 G4cout << "BDSComponentFactory::createComponent() creating element..." << G4endl;
00106 #endif
00107 _element = aElement;
00108 #ifdef BDSDEBUG
00109 G4cout << "BDSComponentFactory::createComponent() creating previous element..." << G4endl;
00110 #endif
00111 _previousElement = previousElement;
00112 #ifdef BDSDEBUG
00113 G4cout << "BDSComponentFactory::createComponent() creating next element..." << G4endl;
00114 #endif
00115 _nextElement = nextElement;
00116 return createComponent();
00117 }
00118
00119 BDSAcceleratorComponent* BDSComponentFactory::createComponent(){
00120 #ifdef BDSDEBUG
00121 G4cout << "BDSComponentFactory::createComponent() element name = " << _element.name << G4endl;
00122 #endif
00123 BDSAcceleratorComponent* element = NULL;
00124
00125 switch(_element.type){
00126 case _SAMPLER:
00127 #ifdef BDSDEBUG
00128 G4cout << "BDSComponentFactory - creating sampler" << G4endl;
00129 #endif
00130 element = createSampler(); break;
00131 case _DRIFT:
00132 #ifdef BDSDEBUG
00133 G4cout << "BDSComponentFactory - creating drift" << G4endl;
00134 #endif
00135 element = createDrift(); break;
00136 case _RF:
00137 #ifdef BDSDEBUG
00138 G4cout << "BDSComponentFactory - creating rf" << G4endl;
00139 #endif
00140 element = createRF(); break;
00141 case _SBEND:
00142 #ifdef BDSDEBUG
00143 G4cout << "BDSComponentFactory - creating sbend" << G4endl;
00144 #endif
00145 element = createSBend(); break;
00146 case _RBEND:
00147 #ifdef BDSDEBUG
00148 G4cout << "BDSComponentFactory - creating rbend" << G4endl;
00149 #endif
00150 element = createRBend(); break;
00151 case _HKICK:
00152 #ifdef BDSDEBUG
00153 G4cout << "BDSComponentFactory - creating hkick" << G4endl;
00154 #endif
00155 element = createHKick(); break;
00156 case _VKICK:
00157 #ifdef BDSDEBUG
00158 G4cout << "BDSComponentFactory - creating vkick" << G4endl;
00159 #endif
00160 element = createVKick(); break;
00161 case _QUAD:
00162 #ifdef BDSDEBUG
00163 G4cout << "BDSComponentFactory - creating quadrupole" << G4endl;
00164 #endif
00165 element = createQuad(); break;
00166 case _SEXTUPOLE:
00167 #ifdef BDSDEBUG
00168 G4cout << "BDSComponentFactory - creating sextupole" << G4endl;
00169 #endif
00170 element = createSextupole(); break;
00171 case _OCTUPOLE:
00172 #ifdef BDSDEBUG
00173 G4cout << "BDSComponentFactory - creating octupole" << G4endl;
00174 #endif
00175 element = createOctupole(); break;
00176 case _MULT:
00177 #ifdef BDSDEBUG
00178 G4cout << "BDSComponentFactory - creating multipole" << G4endl;
00179 #endif
00180 element = createMultipole(); break;
00181 case _ELEMENT:
00182 #ifdef BDSDEBUG
00183 G4cout << "BDSComponentFactory - creating element" << G4endl;
00184 #endif
00185 element = createElement(); break;
00186 case _CSAMPLER:
00187 #ifdef BDSDEBUG
00188 G4cout << "BDSComponentFactory - creating csampler" << G4endl;
00189 #endif
00190 element = createCSampler(); break;
00191 case _DUMP:
00192 #ifdef BDSDEBUG
00193 G4cout << "BDSComponentFactory - creating dump" << G4endl;
00194 #endif
00195 element = createDump(); break;
00196 case _SOLENOID:
00197 #ifdef BDSDEBUG
00198 G4cout << "BDSComponentFactory - creating solenoid" << G4endl;
00199 #endif
00200 element = createSolenoid(); break;
00201 case _ECOL:
00202 #ifdef BDSDEBUG
00203 G4cout << "BDSComponentFactory - creating ecol" << G4endl;
00204 #endif
00205 element = createEllipticalCollimator(); break;
00206 case _RCOL:
00207 #ifdef BDSDEBUG
00208 G4cout << "BDSComponentFactory - creating rcol" << G4endl;
00209 #endif
00210 element = createRectangularCollimator(); break;
00211 case _MUSPOILER:
00212 #ifdef BDSDEBUG
00213 G4cout << "BDSComponentFactory - creating muspoiler" << G4endl;
00214 #endif
00215 element = createMuSpoiler(); break;
00216 case _LASER:
00217 #ifdef BDSDEBUG
00218 G4cout << "BDSComponentFactory - creating laser" << G4endl;
00219 #endif
00220 element = createLaser(); break;
00221 case _SCREEN:
00222 #ifdef BDSDEBUG
00223 G4cout << "BDSComponentFactory - creating screen" << G4endl;
00224 #endif
00225 element = createScreen(); break;
00226 case _AWAKESCREEN:
00227 #ifdef BDSDEBUG
00228 G4cout << "BDSComponentFactory - creating awake screen" << G4endl;
00229 #endif
00230 element = createAwakeScreen(); break;
00231 case _TRANSFORM3D:
00232 #ifdef BDSDEBUG
00233 G4cout << "BDSComponentFactory - creating transform3d" << G4endl;
00234 #endif
00235 element = createTransform3D(); break;
00236 case _TELEPORTER:
00237 #ifdef BDSDEBUG
00238 G4cout << "BDSComponentFactory - creating teleporter" << G4endl;
00239 #endif
00240 element = createTeleporter(); break;
00241 case _TERMINATOR:
00242 #ifdef BDSDEBUG
00243 G4cout << "BDSComponentFactory - creating terminator" << G4endl;
00244 #endif
00245 element = createTerminator(); break;
00246
00247
00248 case _MARKER:
00249 case _LINE:
00250 case _REV_LINE:
00251 case _MATERIAL:
00252 case _ATOM:
00253 case _SEQUENCE:
00254 case _GAS:
00255 case _TUNNEL:
00256 case _COLLIMATOR:
00257 element = NULL;
00258 break;
00259 default:
00260 #ifdef BDSDEBUG
00261 G4cout << "BDSComponentFactory: type: " << _element.type << G4endl;
00262 #endif
00263 G4Exception("Error: BDSComponentFactory: type not found.", "-1", FatalErrorInArgument, "");
00264 exit(1);
00265 break;
00266 }
00267
00268 if (element)
00269 {element->Initialise();}
00270
00271 return element;
00272 }
00273
00274 BDSAcceleratorComponent* BDSComponentFactory::createSampler(){
00275 return (new BDSSampler(_element.name, BDSGlobalConstants::Instance()->GetSamplerLength()));
00276 }
00277
00278 BDSAcceleratorComponent* BDSComponentFactory::createCSampler(){
00279 if( _element.l < 1.E-4 ) _element.l = 1.0 ;
00280 return (new BDSSamplerCylinder( _element.name,
00281 _element.l * CLHEP::m,
00282 _element.r * CLHEP::m ));
00283 }
00284
00285 BDSAcceleratorComponent* BDSComponentFactory::createDump(){
00286 return (new BDSDump( _element.name,
00287 BDSGlobalConstants::Instance()->GetSamplerLength()));
00288 }
00289
00290 BDSAcceleratorComponent* BDSComponentFactory::createTeleporter(){
00291
00292
00293 G4double teleporterlength = BDSGlobalConstants::Instance()->GetTeleporterLength();
00294 G4String name = "teleporter";
00295 #ifdef BDSDEBUG
00296 G4cout << "---->creating Teleporter,"
00297 << " name = " << name
00298 << ", l = " << teleporterlength/CLHEP::m << "m"
00299 << G4endl;
00300 #endif
00301
00302 return( new BDSTeleporter(name,
00303 teleporterlength ));
00304
00305 }
00306
00307 BDSAcceleratorComponent* BDSComponentFactory::createDrift()
00308 {
00309 if(!HasSufficientMinimumLength(_element))
00310 {return NULL;}
00311
00312 #ifdef BDSDEBUG
00313 G4cout << "---->creating Drift,"
00314 << " name= " << _element.name
00315 << " l= " << _element.l << "m"
00316 << G4endl;
00317 #endif
00318
00319 return (new BDSDrift( _element.name,
00320 _element.l*CLHEP::m,
00321 PrepareBeamPipeInfo(_element) ));
00322 }
00323
00324 BDSAcceleratorComponent* BDSComponentFactory::createRF()
00325 {
00326 if(!HasSufficientMinimumLength(_element))
00327 {return NULL;}
00328
00329 return (new BDSRfCavity( _element.name,
00330 _element.l * CLHEP::m,
00331 _element.gradient,
00332 PrepareBeamPipeInfo(_element),
00333 PrepareMagnetOuterInfo(_element)));
00334 }
00335
00336 BDSAcceleratorComponent* BDSComponentFactory::createSBend()
00337 {
00338 if(!HasSufficientMinimumLength(_element))
00339 {return NULL;}
00340
00341
00342 G4double length = _element.l*CLHEP::m;
00343 G4double magFieldLength = length;
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 G4double bField;
00354 if(_element.B != 0) {
00355 bField = _element.B * CLHEP::tesla;
00356 G4double rho = _brho/bField;
00357
00358 _element.angle = - magFieldLength/rho;
00359 }
00360 else {
00361 _element.angle *= -1;
00362
00363
00364
00365 bField = - _brho * _element.angle/magFieldLength * _charge * BDSGlobalConstants::Instance()->GetFFact();
00366 _element.B = bField/CLHEP::tesla;
00367 }
00368
00369
00370
00371 G4double bPrime = - _brho * (_element.k1 / CLHEP::m2);
00372
00373
00374
00375
00376 double aperturePrecision = 1.0;
00377
00378 int nSbends = (int) ceil(std::sqrt(std::abs(length*_element.angle/2/aperturePrecision)));
00379
00380 #ifdef BDSDEBUG
00381 G4cout << __METHOD_NAME__ << " splitting sbend into " << nSbends << " sbends" << G4endl;
00382 #endif
00383
00384 double semiangle = _element.angle / (double) nSbends;
00385 double semilength = length / (double) nSbends;
00386
00387 BDSLine* sbendline = new BDSLine("sbendline");
00388
00389 BDSBeamPipeInfo* bpInfo = PrepareBeamPipeInfo(_element);
00390 BDSMagnetOuterInfo moInfo = PrepareMagnetOuterInfo(_element);
00391 for (int i = 0; i < nSbends; ++i)
00392 {
00393 std::stringstream name;
00394 name << _element.name << "_" << i;
00395 std::string itsname = name.str();
00396 sbendline->addComponent( new BDSSectorBend( itsname,
00397 semilength,
00398 semiangle,
00399 bField,
00400 bPrime,
00401 bpInfo,
00402 moInfo) );
00403 }
00404 return sbendline;
00405 }
00406
00407 BDSAcceleratorComponent* BDSComponentFactory::createRBend()
00408 {
00409 if(!HasSufficientMinimumLength(_element))
00410 {return NULL;}
00411
00412
00413
00414
00415
00416 G4double outerRadius = PrepareOuterDiameter(_element)*0.5;
00417 G4double angle = _element.angle;
00418 G4double chordLength = _element.l*CLHEP::m;
00419 G4double straightSectionChord = outerRadius / (tan(0.5*fabs(angle)) + tan((0.5*CLHEP::pi) - (0.5*fabs(angle))) );
00420 G4double magFieldLength = chordLength - (2.0*straightSectionChord);
00421
00422
00423
00424 G4double bField;
00425 if(_element.B != 0){
00426
00427 bField = _element.B * CLHEP::tesla;
00428 G4double rho = _brho/bField;
00429
00430 _element.angle = - 2.0*asin(magFieldLength/2.0/rho);
00431 #ifdef BDSDEBUG
00432 G4cout << "calculated angle from field - now " << _element.angle << G4endl;
00433 #endif
00434 }
00435 else{
00436 _element.angle *= -1;
00437
00438
00439 G4double arclength = 0.5*magFieldLength * fabs(_element.angle) / sin(fabs(_element.angle)*0.5);
00440
00441
00442
00443 bField = - _brho * _element.angle / arclength * _charge * BDSGlobalConstants::Instance()->GetFFact();
00444 _element.B = bField/CLHEP::tesla;
00445 #ifdef BDSDEBUG
00446 G4cout << "calculated field from angle - angle,field = " << _element.angle << " " << _element.B << G4endl;
00447 #endif
00448 }
00449
00450
00451
00452 G4double bPrime = - _brho * (_element.k1 / CLHEP::m2);
00453
00454 return (new BDSRBend( _element.name,
00455 _element.l*CLHEP::m,
00456 bField,
00457 bPrime,
00458 _element.angle,
00459 PrepareBeamPipeInfo(_element),
00460 PrepareMagnetOuterInfo(_element)));
00461 }
00462
00463 BDSAcceleratorComponent* BDSComponentFactory::createHKick()
00464 {
00465 if(!HasSufficientMinimumLength(_element))
00466 {return NULL;}
00467
00468 G4double length = _element.l*CLHEP::m;
00469
00470
00471 G4double bField;
00472 if(_element.B != 0){
00473
00474 bField = _element.B * CLHEP::tesla;
00475 _element.angle = -bField * length / _brho;
00476 }
00477 else{
00478
00479
00480
00481 bField = - _brho * _element.angle / length * _charge * BDSGlobalConstants::Instance()->GetFFact();
00482 _element.B = bField/CLHEP::tesla;
00483 }
00484
00485
00486
00487 G4double bPrime = - _brho * (_element.k1 / CLHEP::m2);
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 return (new BDSKicker( _element.name,
00505 _element.l * CLHEP::m,
00506 bField,
00507 bPrime,
00508 _element.angle,
00509 false,
00510 PrepareBeamPipeInfo(_element),
00511 PrepareMagnetOuterInfo(_element)));
00512 }
00513
00514 BDSAcceleratorComponent* BDSComponentFactory::createVKick()
00515 {
00516 if(!HasSufficientMinimumLength(_element))
00517 {return NULL;}
00518
00519 G4double length = _element.l*CLHEP::m;
00520
00521
00522 G4double bField;
00523 if(_element.B != 0){
00524
00525 bField = _element.B * CLHEP::tesla;
00526 _element.angle = -bField * length / _brho;
00527 }
00528 else{
00529
00530
00531
00532 bField = - _brho * _element.angle / length * _charge * BDSGlobalConstants::Instance()->GetFFact();
00533 _element.B = bField/CLHEP::tesla;
00534 }
00535
00536
00537 G4double bPrime = - _brho * (_element.k1 / CLHEP::m2);
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 return (new BDSKicker( _element.name,
00556 _element.l * CLHEP::m,
00557 bField,
00558 bPrime,
00559 _element.angle,
00560 true,
00561 PrepareBeamPipeInfo(_element),
00562 PrepareMagnetOuterInfo(_element)
00563 ));
00564 }
00565
00566 BDSAcceleratorComponent* BDSComponentFactory::createQuad()
00567 {
00568 if(!HasSufficientMinimumLength(_element))
00569 {return NULL;}
00570
00571
00572
00573
00574 G4double bPrime = - _brho * (_element.k1 / CLHEP::m2);
00575
00576 return (new BDSQuadrupole( _element.name,
00577 _element.l * CLHEP::m,
00578 bPrime,
00579 PrepareBeamPipeInfo(_element),
00580 PrepareMagnetOuterInfo(_element)));
00581 }
00582
00583 BDSAcceleratorComponent* BDSComponentFactory::createSextupole()
00584 {
00585 if(!HasSufficientMinimumLength(_element))
00586 {return NULL;}
00587
00588
00589
00590
00591 G4double bDoublePrime = - _brho * (_element.k2 / CLHEP::m3);
00592
00593 #ifdef BDSDEBUG
00594 G4cout << "---->creating Sextupole,"
00595 << " name= " << _element.name
00596 << " l= " << _element.l << "m"
00597 << " k2= " << _element.k2 << "m^-3"
00598 << " brho= " << fabs(_brho)/(CLHEP::tesla*CLHEP::m) << "T*m"
00599 << " B''= " << bDoublePrime/(CLHEP::tesla/CLHEP::m2) << "T/m^2"
00600 << " tilt= " << _element.tilt << "rad"
00601 << " material= " << _element.outerMaterial
00602 << G4endl;
00603 #endif
00604
00605 return (new BDSSextupole( _element.name,
00606 _element.l * CLHEP::m,
00607 bDoublePrime,
00608 PrepareBeamPipeInfo(_element),
00609 PrepareMagnetOuterInfo(_element)));
00610 }
00611
00612 BDSAcceleratorComponent* BDSComponentFactory::createOctupole()
00613 {
00614 if(!HasSufficientMinimumLength(_element))
00615 {return NULL;}
00616
00617
00618
00619
00620 G4double bTriplePrime = - _brho * (_element.k3 / (CLHEP::m3*CLHEP::m));
00621
00622 #ifdef BDSDEBUG
00623 G4cout << "---->creating Octupole,"
00624 << " name= " << _element.name
00625 << " l= " << _element.l << "m"
00626 << " k3= " << _element.k3 << "m^-4"
00627 << " brho= " << fabs(_brho)/(CLHEP::tesla*CLHEP::m) << "T*m"
00628 << " B'''= " << bTriplePrime/(CLHEP::tesla/CLHEP::m3) << "T/m^3"
00629 << " tilt= " << _element.tilt
00630 << " material= " << _element.outerMaterial
00631 << G4endl;
00632 #endif
00633
00634 return ( new BDSOctupole( _element.name,
00635 _element.l * CLHEP::m,
00636 bTriplePrime,
00637 PrepareBeamPipeInfo(_element),
00638 PrepareMagnetOuterInfo(_element)));
00639 }
00640
00641 BDSAcceleratorComponent* BDSComponentFactory::createMultipole()
00642 {
00643 if(!HasSufficientMinimumLength(_element))
00644 {return NULL;}
00645
00646 #ifdef BDSDEBUG
00647 G4cout << "---->creating Multipole,"
00648 << " name= " << _element.name
00649 << " l= " << _element.l << "m"
00650 << " tilt= " << _element.tilt << "rad"
00651 << " material= " << _element.outerMaterial
00652 << G4endl;
00653 #endif
00654
00655 std::list<double>::iterator kit;
00656
00657 #ifdef BDSDEBUG
00658 G4cout << " knl={ ";
00659 #endif
00660 for(kit=(_element.knl).begin();kit!=(_element.knl).end();kit++)
00661 {
00662 #ifdef BDSDEBUG
00663 G4cout<<(*kit)<<", ";
00664 #endif
00665 (*kit) /= _element.l;
00666 }
00667 #ifdef BDSDEBUG
00668 G4cout << "}";
00669 #endif
00670
00671 #ifdef BDSDEBUG
00672 G4cout << " ksl={ ";
00673 #endif
00674 for(kit=(_element.ksl).begin();kit!=(_element.ksl).end();kit++)
00675 {
00676 #ifdef BDSDEBUG
00677 G4cout<<(*kit)<<" ";
00678 #endif
00679 (*kit) /= _element.l;
00680 }
00681 #ifdef BDSDEBUG
00682 G4cout << "}" << G4endl;
00683 #endif
00684
00685 return (new BDSMultipole( _element.name,
00686 _element.l * CLHEP::m,
00687 _element.knl,
00688 _element.ksl,
00689 PrepareBeamPipeInfo(_element),
00690 PrepareMagnetOuterInfo(_element)));
00691 }
00692
00693 BDSAcceleratorComponent* BDSComponentFactory::createElement()
00694 {
00695 if(!HasSufficientMinimumLength(_element))
00696 {return NULL;}
00697
00698 #ifdef BDSDEBUG
00699 G4cout << "---->creating Element,"
00700 << " name = " << _element.name
00701 << " l = " << _element.l << "m"
00702 << " outerDiameter = " << 0.5 * _element.outerDiameter << "m"
00703 << " bmapZOffset = " << _element.bmapZOffset * CLHEP::m
00704 << " precision region " << _element.precisionRegion
00705 << G4endl;
00706 #endif
00707
00708 return (new BDSElement(_element.name,
00709 _element.l * CLHEP::m,
00710 _element.geometryFile,
00711 _element.bmapFile,
00712 _element.bmapZOffset * CLHEP::m
00713 ));
00714 }
00715
00716 BDSAcceleratorComponent* BDSComponentFactory::createSolenoid()
00717 {
00718 if(!HasSufficientMinimumLength(_element))
00719 {return NULL;}
00720
00721
00722
00723
00724
00725 G4double bField;
00726 if(_element.B != 0){
00727 bField = _element.B * CLHEP::tesla;
00728 _element.ks = (bField/_brho) / CLHEP::m;
00729 }
00730 else{
00731 bField = (_element.ks/CLHEP::m) * _brho;
00732 _element.B = bField/CLHEP::tesla;
00733 }
00734
00735 #ifdef BDSDEBUG
00736 G4cout << "---->creating Solenoid,"
00737 << " name = " << _element.name
00738 << " l = " << _element.l << " m,"
00739 << " ks = " << _element.ks << " m^-1,"
00740 << " brho = " << fabs(_brho)/(CLHEP::tesla*CLHEP::m) << " T*m,"
00741 << " B = " << bField/CLHEP::tesla << " T,"
00742 << " material = \"" << _element.outerMaterial << "\""
00743 << G4endl;
00744 #endif
00745
00746 return (new BDSSolenoid( _element.name,
00747 _element.l * CLHEP::m,
00748 bField,
00749 PrepareBeamPipeInfo(_element),
00750 PrepareMagnetOuterInfo(_element)));
00751 }
00752
00753 BDSAcceleratorComponent* BDSComponentFactory::createRectangularCollimator()
00754 {
00755 if(!HasSufficientMinimumLength(_element))
00756 {return NULL;}
00757
00758 #ifdef BDSDEBUG
00759 G4cout << "--->creating " << typestr(_element.type) << ","
00760 << " name = " << _element.name << ","
00761 << " x half aperture = " << _element.xsize <<" m,"
00762 << " y half aperture = " << _element.ysize <<" m,"
00763 << " material = \"" << _element.material << "\""
00764 << G4endl;
00765 #endif
00766
00767 return new BDSCollimatorRectangular(_element.name,
00768 _element.l*CLHEP::m,
00769 _element.outerDiameter*CLHEP::m,
00770 _element.xsize*CLHEP::m,
00771 _element.ysize*CLHEP::m,
00772 _element.material);
00773 }
00774
00775 BDSAcceleratorComponent* BDSComponentFactory::createEllipticalCollimator()
00776 {
00777 if(!HasSufficientMinimumLength(_element))
00778 {return NULL;}
00779
00780 #ifdef BDSDEBUG
00781 G4cout << "--->creating " << typestr(_element.type) << ","
00782 << " name = " << _element.name
00783 << " x half aperture = " << _element.xsize <<" m,"
00784 << " y half aperture = " << _element.ysize <<" m,"
00785 << " material = \"" << _element.material << "\""
00786 << G4endl;
00787 #endif
00788
00789 return new BDSCollimatorElliptical(_element.name,
00790 _element.l*CLHEP::m,
00791 _element.outerDiameter*CLHEP::m,
00792 _element.xsize*CLHEP::m,
00793 _element.ysize*CLHEP::m,
00794 _element.material);
00795 }
00796
00797 BDSAcceleratorComponent* BDSComponentFactory::createMuSpoiler()
00798 {
00799 if(!HasSufficientMinimumLength(_element))
00800 {return NULL;}
00801
00802 #ifdef BDSDEBUG
00803 G4cout << "---->creating muspoiler,"
00804 << " name = " << _element.name
00805 << " length = " << _element.l
00806 << " B = " << _element.B
00807 << G4endl;
00808 #endif
00809
00810 #ifdef BDSDEBUG
00811 G4cout << "BDSMuSpoiler: " << _element.name << " " << _element.l*CLHEP::m << " mm " << " " << _element.B*CLHEP::tesla << " MT " << G4endl;
00812 #endif
00813
00814 return (new BDSMuSpoiler(_element.name,
00815 _element.l*CLHEP::m,
00816 _element.B * CLHEP::tesla,
00817 PrepareBeamPipeInfo(_element),
00818 PrepareMagnetOuterInfo(_element)));
00819 }
00820
00821 BDSAcceleratorComponent* BDSComponentFactory::createLaser()
00822 {
00823 if(!HasSufficientMinimumLength(_element))
00824 {return NULL;}
00825
00826 #ifdef BDSDEBUG
00827 G4cout << "---->creating Laser,"
00828 << " name= "<< _element.name
00829 << " l=" << _element.l <<"m"
00830 << " lambda= " << _element.waveLength << "m"
00831 << " xSigma= " << _element.xsize << "m"
00832 << " ySigma= " << _element.ysize << "m"
00833 << " xdir= " << _element.xdir
00834 << " ydir= " << _element.ydir
00835 << " zdir= " << _element.zdir
00836 << G4endl;
00837 #endif
00838
00839 G4double length = _element.l*CLHEP::m;
00840 G4double lambda = _element.waveLength*CLHEP::m;
00841
00842
00843 G4ThreeVector direction =
00844 G4ThreeVector(_element.xdir,_element.ydir,_element.zdir);
00845 G4ThreeVector position = G4ThreeVector(0,0,0);
00846
00847 return (new BDSLaserWire( _element.name,
00848 length,
00849 lambda,
00850 direction) );
00851
00852 }
00853
00854 BDSAcceleratorComponent* BDSComponentFactory::createScreen()
00855 {
00856 if(!HasSufficientMinimumLength(_element))
00857 {return NULL;}
00858
00859 #ifdef BDSDEBUG
00860 G4cout << "---->creating Screen,"
00861 << " name= "<< _element.name
00862 << " l=" << _element.l/CLHEP::m<<"m"
00863 << " tscint=" << _element.tscint/CLHEP::m<<"m"
00864 << " angle=" << _element.angle/CLHEP::rad<<"rad"
00865 << " scintmaterial=" << "ups923a"
00866 << " airmaterial=" << "vacuum"
00867 << G4endl;
00868 #endif
00869 return (new BDSScintillatorScreen( _element.name, _element.tscint*CLHEP::m, (_element.angle-0.78539816339)*CLHEP::rad, "ups923a",BDSGlobalConstants::Instance()->GetVacuumMaterial()));
00870 }
00871
00872
00873 BDSAcceleratorComponent* BDSComponentFactory::createAwakeScreen(){
00874
00875 #ifdef BDSDEBUG
00876 G4cout << "---->creating Awake Screen,"
00877 << "twindow = " << _element.twindow*1e3/CLHEP::um << " um"
00878 << "tscint = " << _element.tscint*1e3/CLHEP::um << " um"
00879 << "windowmaterial = " << _element.windowmaterial << " um"
00880 << "scintmaterial = " << _element.scintmaterial << " um"
00881 << G4endl;
00882 #endif
00883 return (new BDSAwakeScintillatorScreen(_element.name, _element.scintmaterial, _element.tscint*1e3, _element.angle, _element.twindow*1e3, _element.windowmaterial));
00884 }
00885
00886 BDSAcceleratorComponent* BDSComponentFactory::createTransform3D(){
00887
00888 #ifdef BDSDEBUG
00889 G4cout << "---->creating Transform3d,"
00890 << " name= " << _element.name
00891 << " xdir= " << _element.xdir/CLHEP::m << "m"
00892 << " ydir= " << _element.ydir/CLHEP::m << "m"
00893 << " zdir= " << _element.zdir/CLHEP::m << "m"
00894 << " phi= " << _element.phi/CLHEP::rad << "rad"
00895 << " theta= " << _element.theta/CLHEP::rad << "rad"
00896 << " psi= " << _element.psi/CLHEP::rad << "rad"
00897 << G4endl;
00898 #endif
00899
00900 return (new BDSTransform3D( _element.name,
00901 _element.xdir *CLHEP::m,
00902 _element.ydir *CLHEP::m,
00903 _element.zdir *CLHEP::m,
00904 _element.phi *CLHEP::rad,
00905 _element.theta *CLHEP::rad,
00906 _element.psi *CLHEP::rad ) );
00907
00908 }
00909
00910 BDSAcceleratorComponent* BDSComponentFactory::createTerminator()
00911 {
00912 G4String name = "terminator";
00913 G4double length = BDSGlobalConstants::Instance()->GetSamplerLength();
00914 #ifdef BDSDEBUG
00915 G4cout << "---->creating Terminator,"
00916 << " name = " << name
00917 << " l = " << length / CLHEP::m << "m"
00918 << G4endl;
00919 #endif
00920
00921 return (new BDSTerminator("terminator",
00922 length));
00923 }
00924
00925
00926 G4bool BDSComponentFactory::HasSufficientMinimumLength(Element& element)
00927 {
00928 if(element.l*CLHEP::m < 4*lengthSafety)
00929 {
00930 G4cerr << "---->NOT creating element, "
00931 << " name = " << _element.name
00932 << ", LENGTH TOO SHORT:"
00933 << " l = " << _element.l*CLHEP::m << "m"
00934 << G4endl;
00935 return false;
00936 }
00937 else
00938 {return true;}
00939 }
00940
00941 G4Material* BDSComponentFactory::PrepareBeamPipeMaterial(Element& element)
00942 {
00943 G4Material* beamPipeMaterial;
00944 if(element.beampipeMaterial == "")
00945 {
00946 G4String defaultMaterialName = BDSGlobalConstants::Instance()->GetBeamPipeMaterialName();
00947 beamPipeMaterial = BDSMaterials::Instance()->GetMaterial(defaultMaterialName);
00948 }
00949 else
00950 { beamPipeMaterial = BDSMaterials::Instance()->GetMaterial(element.beampipeMaterial); }
00951 return beamPipeMaterial;
00952 }
00953
00954 G4Material* BDSComponentFactory::PrepareVacuumMaterial(Element& )
00955 {
00956
00957
00958 return BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetVacuumMaterial());
00959 }
00960
00961 BDSMagnetOuterInfo BDSComponentFactory::PrepareMagnetOuterInfo(Element& element)
00962 {
00963 BDSMagnetOuterInfo info;
00964
00965 if (element.magnetGeometryType == "")
00966 info.geometryType = BDSGlobalConstants::Instance()->GetMagnetGeometryType();
00967 else
00968 info.geometryType = BDS::DetermineMagnetGeometryType(element.magnetGeometryType);
00969
00970
00971 G4double outerDiameter = element.outerDiameter*CLHEP::m;
00972 if (outerDiameter < 1e-6)
00973 {
00974 outerDiameter = BDSGlobalConstants::Instance()->GetOuterDiameter();
00975 }
00976 info.outerDiameter = outerDiameter;
00977
00978
00979 G4Material* outerMaterial;
00980 if(element.outerMaterial == "")
00981 {
00982 G4String defaultMaterialName = BDSGlobalConstants::Instance()->GetOuterMaterialName();
00983 outerMaterial = BDSMaterials::Instance()->GetMaterial(defaultMaterialName);
00984 }
00985 else
00986 {outerMaterial = BDSMaterials::Instance()->GetMaterial(element.outerMaterial);}
00987 info.outerMaterial = outerMaterial;
00988
00989 return info;
00990 }
00991
00992 G4double BDSComponentFactory::PrepareOuterDiameter(Element& element)
00993 {
00994 G4double outerDiameter = element.outerDiameter*CLHEP::m;
00995 if (outerDiameter < 1e-6)
00996 {
00997 outerDiameter = BDSGlobalConstants::Instance()->GetOuterDiameter();
00998 }
00999
01000 return outerDiameter;
01001 }
01002
01003 BDSBeamPipeInfo* BDSComponentFactory::PrepareBeamPipeInfo(Element& element)
01004 {
01005 BDSBeamPipeInfo* info = new BDSBeamPipeInfo;
01006 if (element.apertureType == "")
01007 info->beamPipeType = BDSGlobalConstants::Instance()->GetApertureType();
01008 else
01009 info->beamPipeType = BDS::DetermineBeamPipeType(element.apertureType);
01010
01011
01012
01013
01014 if (element.aper1 == 0)
01015 {info->aper1 = BDSGlobalConstants::Instance()->GetAper1();}
01016 else
01017 {info->aper1 = element.aper1*CLHEP::m;}
01018
01019 if (element.aper2 == 0)
01020 {info->aper2 = BDSGlobalConstants::Instance()->GetAper2();}
01021 else
01022 {info->aper2 = element.aper2*CLHEP::m;}
01023
01024 if (element.aper3 == 0)
01025 {info->aper3 = BDSGlobalConstants::Instance()->GetAper3();}
01026 else
01027 {info->aper3 = element.aper3*CLHEP::m;}
01028
01029 if (element.aper4 == 0)
01030 {info->aper4 = BDSGlobalConstants::Instance()->GetAper4();}
01031 else
01032 {info->aper4 = element.aper4*CLHEP::m;}
01033
01034 info->vacuumMaterial = PrepareVacuumMaterial(element);
01035 info->beamPipeThickness = element.beampipeThickness*CLHEP::m;
01036 if (info->beamPipeThickness < 1e-10)
01037 {info->beamPipeThickness = BDSGlobalConstants::Instance()->GetBeamPipeThickness();}
01038 info->beamPipeMaterial = PrepareBeamPipeMaterial(element);
01039 return info;
01040 }