00001 #include "BDSMagnetOuterFactoryLHC.hh"
00002 
00003 #include "BDSBeamPipe.hh"
00004 #include "BDSBeamPipeType.hh"
00005 #include "BDSBeamPipeFactory.hh"
00006 #include "BDSDebug.hh"
00007 #include "BDSExecOptions.hh"
00008 #include "BDSGeometryComponent.hh"
00009 #include "BDSGlobalConstants.hh"
00010 #include "BDSMagnetColours.hh"
00011 #include "BDSMaterials.hh"
00012 #include "BDSSDManager.hh"
00013 #include "BDSUtilities.hh"                 
00014 
00015 #include "globals.hh"                      
00016 #include "G4Box.hh"
00017 #include "G4Colour.hh"
00018 #include "G4CutTubs.hh"
00019 #include "G4IntersectionSolid.hh"
00020 #include "G4LogicalVolume.hh"
00021 #include "G4UnionSolid.hh"
00022 #include "G4Material.hh"
00023 #include "G4PVPlacement.hh"
00024 #include "G4SubtractionSolid.hh"
00025 #include "G4ThreeVector.hh"
00026 #include "G4Tubs.hh"
00027 #include "G4UserLimits.hh"
00028 #include "G4VisAttributes.hh"
00029 #include "G4VSolid.hh"
00030 #include <cmath>
00031 #include <utility>                         
00032 #include <algorithm>                       
00033 #include <vector>
00034 
00035 
00036 BDSMagnetOuterFactoryLHC::BDSMagnetOuterFactoryLHC(G4bool isLeftOffsetIn):
00037   isLeftOffset(isLeftOffsetIn)
00038 {
00039   CleanUp();
00040 }
00041 
00042 BDSGeometryComponent* BDSMagnetOuterFactoryLHC::CreateSectorBend(G4String      name,
00043                                                                  G4double      length,
00044                                                                  BDSBeamPipe*  beamPipe,
00045                                                                  G4double      outerDiameter,
00046                                                                  G4double      angle,
00047                                                                  G4Material*   outerMaterial)
00048 
00049 {
00050 #ifdef BDSDEBUG
00051   G4cout << __METHOD_NAME__ << G4endl;
00052 #endif
00053   CleanUp();
00054   
00055   
00056   
00057   
00058 
00059   
00060   TestInputParameters(beamPipe,outerDiameter,outerMaterial);
00061 
00062   
00063   
00064   
00065   
00066   
00067 
00068   
00069   
00070   
00071   G4double beamPipeAxisSeparation = 194.00*CLHEP::mm;             
00072   G4double massShift              = 0.5 * beamPipeAxisSeparation; 
00073   
00074   G4double collarBoxHalfWidth     = 22*CLHEP::mm;                 
00075 
00076   
00077   G4double containerInnerRadius   = beamPipe->GetContainerRadius()+1*CLHEP::um;
00078   G4double innerCoilInnerRadius   = containerInnerRadius + lengthSafety;
00079   G4double innerCoilInnerRadiusF  = 24.601*CLHEP::mm; 
00080   G4double innerCoilOuterRadius   = 42*CLHEP::mm;                        
00081   G4double outerCoilInnerRadius   = innerCoilOuterRadius + lengthSafety;
00082   G4double outerCoilInnerRadiusF  = innerCoilOuterRadius + lengthSafety; 
00083   G4double outerCoilOuterRadius   = 60*CLHEP::mm;                        
00084   G4double collarInnerRadius      = outerCoilOuterRadius + lengthSafety;
00085   G4double collarInnerRadiusF     = outerCoilOuterRadius + lengthSafety;
00086   G4double collarOuterRadius      = 101.18*CLHEP::mm;                    
00087   G4double yokeOuterRadius        = 570.0*0.5*CLHEP::mm;                 
00088 
00089   
00090   
00091   G4double poleInnerFullAngle = 33./180.*2; 
00092   G4double poleOuterFullAngle = 100./180.*2; 
00093   G4double coilInnerFullAngle = CLHEP::pi - poleInnerFullAngle - 1e-5; 
00094   G4double coilOuterFullAngle = CLHEP::pi - poleOuterFullAngle - 1e-5;
00095 
00096   
00097   
00098   G4bool buildInnerCoil           = true;
00099   G4bool buildOuterCoil           = true;
00100   G4bool buildCollar              = true; 
00101   if (innerCoilInnerRadius > innerCoilOuterRadius)
00102     {buildInnerCoil = false;}
00103   if ((innerCoilInnerRadius > outerCoilInnerRadius) && (innerCoilInnerRadius < outerCoilOuterRadius))
00104     {outerCoilInnerRadius = containerInnerRadius + lengthSafety;}
00105   if (innerCoilInnerRadius > outerCoilOuterRadius)
00106     {buildOuterCoil = false;}
00107   
00108   
00109   if ((innerCoilInnerRadius > collarInnerRadius) && (innerCoilInnerRadius < (massShift - collarBoxHalfWidth)))
00110     {collarInnerRadius = containerInnerRadius + lengthSafety;}
00111   if (innerCoilInnerRadius > (massShift - collarBoxHalfWidth))
00112     {buildCollar = false;}
00113   if (innerCoilInnerRadius > collarOuterRadius)
00114     {
00115       
00116       G4cerr << __METHOD_NAME__ << "this beam pipe is too big to use with the LHC dipole geometry" << G4endl;
00117       G4cerr << "Please consider using a different magnet geometry for this particular magnet" << G4endl;
00118       G4cerr << "Magnet named: " << name << G4endl;
00119       exit(1);
00120     }
00121 
00122   G4ThreeVector dipolePosition; 
00123   if (isLeftOffset)
00124     {
00125       dipolePosition = G4ThreeVector(massShift,0.,0.);
00126       beamPipeAxisSeparation  *= -1;
00127 #ifdef BDSDEBUG
00128       G4cout << __METHOD_NAME__ << "dipole to the left" << G4endl;
00129 #endif
00130     }
00131   else
00132     {
00133       dipolePosition = G4ThreeVector(-massShift,0.,0.);
00134       
00135 #ifdef BDSDEBUG
00136       G4cout << __METHOD_NAME__ << "dipole to the right" << G4endl;
00137 #endif
00138     }
00139 
00140   
00141   G4int orientation        = BDS::CalculateOrientation(angle);
00142   G4double zcomponent      = cos(fabs(angle*0.5)); 
00143   G4double xcomponent      = sin(fabs(angle*0.5)); 
00144   G4ThreeVector inputface  = G4ThreeVector(-orientation*xcomponent, 0.0, -1.0*zcomponent); 
00145   G4ThreeVector outputface = G4ThreeVector(-orientation*xcomponent, 0.0, zcomponent);   
00146 
00147   
00148   G4double centralHalfLength  = length*0.5 - orientation*0.5*beamPipeAxisSeparation*tan(fabs(angle*0.5)); 
00149   G4double secondBPHalfLength = length*0.5 - orientation*beamPipeAxisSeparation*tan(fabs(angle*0.5));     
00150   
00151   
00152   std::vector<G4LogicalVolume*> allLogicalVolumes;
00153   
00154   if (beamPipe->ContainerIsCircular())
00155     {
00156       
00157       
00158       
00159       G4VSolid* containerSolidOuter = new G4CutTubs(name + "_contiainer_solid_outer",  
00160                                                     0,                           
00161                                                     yokeOuterRadius,             
00162                                                     centralHalfLength,           
00163                                                     0,                           
00164                                                     CLHEP::twopi,                
00165                                                     inputface,                   
00166                                                     outputface);                 
00167       G4VSolid* containerSolidInner = new G4Tubs(name + "_contiainer_solid_inner",  
00168                                                  0,                                 
00169                                                  containerInnerRadius,              
00170                                                  length,                            
00171                                                  0,                                 
00172                                                  CLHEP::twopi);
00173       containerSolid = new G4SubtractionSolid(name + "_container_solid",   
00174                                               containerSolidOuter,         
00175                                               containerSolidInner,         
00176                                               0,                           
00177                                               -dipolePosition);            
00178     }
00179   else
00180     {
00181       
00182       G4VSolid* containerSolidOuter = new G4CutTubs(name + "_contiainer_solid_outer",  
00183                                                     0,                                 
00184                                                     yokeOuterRadius,                   
00185                                                     centralHalfLength,                 
00186                                                     0,                                 
00187                                                     CLHEP::twopi,                      
00188                                                     inputface,                         
00189                                                     outputface);                       
00190       containerSolid = new G4SubtractionSolid(name + "_container_solid",
00191                                               containerSolidOuter,
00192                                               beamPipe->GetContainerSubtractionSolid(),
00193                                               0,                
00194                                               -dipolePosition); 
00195     }
00196 
00197   G4Material* emptyMaterial = BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetEmptyMaterial());
00198   G4LogicalVolume* containerLV = new G4LogicalVolume(containerSolid,
00199                                                      emptyMaterial,
00200                                                      name + "_container_lv");
00201     
00202   
00203   G4VSolid*        coil1Inner   = NULL;
00204   G4VSolid*        coil1Outer   = NULL;
00205   G4VSolid*        coil2Inner   = NULL;
00206   G4VSolid*        coil2Outer   = NULL;
00207   G4LogicalVolume* coil1InnerLV = NULL;
00208   G4LogicalVolume* coil1OuterLV = NULL;
00209   G4LogicalVolume* coil2InnerLV = NULL;
00210   G4LogicalVolume* coil2OuterLV = NULL;
00211   G4Material*      nbti         = BDSMaterials::Instance()->GetMaterial("NbTi.1");
00212   G4Material* stainlesssteel    = BDSMaterials::Instance()->GetMaterial("stainlesssteel");
00213   G4VisAttributes* coilVisAtt   = new G4VisAttributes(G4Colour(0.9, 0.75, 0.)); 
00214   coilVisAtt->SetForceLineSegmentsPerCircle(nSegmentsPerCircle);
00215   G4VSolid*        collar1PoleTopInnerSolid     = NULL;
00216   G4VSolid*        collar1PoleBottomInnerSolid  = NULL;
00217   G4VSolid*        collar1PoleTopOuterSolid     = NULL;
00218   G4VSolid*        collar1PoleBottomOuterSolid  = NULL;
00219   G4LogicalVolume* collar1PoleTopInnerLV        = NULL;
00220   G4LogicalVolume* collar1PoleBottomInnerLV     = NULL;
00221   G4LogicalVolume* collar1PoleTopOuterLV        = NULL;
00222   G4LogicalVolume* collar1PoleBottomOuterLV     = NULL;
00223   G4VisAttributes* collarVisAtt = new G4VisAttributes(G4Colour(0.9, 0.9, 0.9)); 
00224   collarVisAtt->SetForceLineSegmentsPerCircle(nSegmentsPerCircle);
00225 
00226   if (buildInnerCoil)
00227     {
00228       coil1Inner = new G4CutTubs(name+"_coil1_inner_solid",            
00229                                  innerCoilInnerRadius,                 
00230                                  innerCoilOuterRadius,                 
00231                                  length*0.5-2*lengthSafety,            
00232                                  -coilInnerFullAngle*0.5,              
00233                                  coilInnerFullAngle,                   
00234                                  inputface,                            
00235                                  outputface);                          
00236       coil2Inner = new G4CutTubs(name+"_coil2_inner_solid",            
00237                                  innerCoilInnerRadius,                 
00238                                  innerCoilOuterRadius,                 
00239                                  length*0.5-2*lengthSafety,            
00240                                  CLHEP::pi-coilInnerFullAngle*0.5,     
00241                                  coilInnerFullAngle,                   
00242                                  inputface,                            
00243                                  outputface);                          
00244       coil1InnerLV =  new G4LogicalVolume(coil1Inner,
00245                                           nbti,
00246                                           name+"_coil1_Inner_lv");
00247       coil2InnerLV =  new G4LogicalVolume(coil2Inner,
00248                                           nbti,
00249                                           name+"_coil2_Inner_lv");
00250       coil1InnerLV->SetVisAttributes(coilVisAtt);
00251       coil2InnerLV->SetVisAttributes(coilVisAtt);
00252       allLogicalVolumes.push_back(coil1InnerLV);
00253       allLogicalVolumes.push_back(coil2InnerLV);
00254 
00255       new G4PVPlacement(0,                      
00256                         -dipolePosition,        
00257                         coil1InnerLV,           
00258                         name+"_coil1_inner_pv", 
00259                         containerLV,            
00260                         false,                  
00261                         0, 
00262                         checkOverlaps);
00263       new G4PVPlacement(0,                      
00264                         -dipolePosition,        
00265                         coil2InnerLV,           
00266                         name+"_coil2_inner_pv", 
00267                         containerLV,            
00268                         false,                  
00269                         0, 
00270                         checkOverlaps);
00271 
00272       collar1PoleTopInnerSolid    = new G4CutTubs(name+"_collar1_pole_inner_top",      
00273                                                   innerCoilInnerRadius,                
00274                                                   innerCoilOuterRadius,                
00275                                                   length*0.5 - 2*lengthSafety,         
00276                                                   CLHEP::pi*0.5-poleInnerFullAngle*0.5,
00277                                                   poleInnerFullAngle,                  
00278                                                   inputface,                           
00279                                                   outputface);                         
00280       collar1PoleBottomInnerSolid = new G4CutTubs(name+"_collar1_pole_inner_bottom",   
00281                                                   innerCoilInnerRadius,                
00282                                                   innerCoilOuterRadius,                
00283                                                   length*0.5 - 2*lengthSafety,         
00284                                                   CLHEP::pi*1.5-poleInnerFullAngle*0.5,
00285                                                   poleInnerFullAngle,                  
00286                                                   inputface,                           
00287                                                   outputface);                         
00288       collar1PoleTopInnerLV    = new G4LogicalVolume(collar1PoleTopInnerSolid,
00289                                                      stainlesssteel,
00290                                                      name+"_collar1_pole_top_inner_lv");
00291       collar1PoleBottomInnerLV = new G4LogicalVolume(collar1PoleBottomInnerSolid,
00292                                                      stainlesssteel,
00293                                                      name+"_collar1_pole_bottom_inner_lv");
00294       
00295       collar1PoleTopInnerLV->SetVisAttributes(collarVisAtt);
00296       collar1PoleBottomInnerLV->SetVisAttributes(collarVisAtt);
00297       
00298       allLogicalVolumes.push_back(collar1PoleTopInnerLV); 
00299       allLogicalVolumes.push_back(collar1PoleBottomInnerLV);
00300 
00301       new G4PVPlacement(0,                          
00302                         -dipolePosition,            
00303                         collar1PoleTopInnerLV,      
00304                         name+"_collar1_pole_top_inner_pv",
00305                         containerLV,                
00306                         false,                      
00307                         0,
00308                         checkOverlaps);
00309       new G4PVPlacement(0,                          
00310                         -dipolePosition,            
00311                         collar1PoleBottomInnerLV,   
00312                         name+"_collar1_pole_top_inner_pv",
00313                         containerLV,                
00314                         false,                      
00315                         0,
00316                         checkOverlaps);
00317     }
00318   
00319   if (buildOuterCoil)
00320     {
00321       coil1Outer = new G4CutTubs(name+"_coil1_outer_solid",            
00322                                  outerCoilInnerRadius,                 
00323                                  outerCoilOuterRadius,                 
00324                                  length*0.5-2*lengthSafety,            
00325                                  -coilOuterFullAngle*0.5,              
00326                                  coilOuterFullAngle,                   
00327                                  inputface,                            
00328                                  outputface);                          
00329       coil2Outer = new G4CutTubs(name+"_coil2_outer_solid",            
00330                                  outerCoilInnerRadius,                 
00331                                  outerCoilOuterRadius,                 
00332                                  length*0.5-2*lengthSafety,            
00333                                  CLHEP::pi-coilOuterFullAngle*0.5,     
00334                                  coilOuterFullAngle,                   
00335                                  inputface,                            
00336                                  outputface);                          
00337       coil1OuterLV =  new G4LogicalVolume(coil1Outer,
00338                                           nbti,
00339                                           name+"_coil1_Inner_lv");
00340       coil2OuterLV =  new G4LogicalVolume(coil2Outer,
00341                                           nbti,
00342                                           name+"_coil2_Inner_lv");
00343       coil1OuterLV->SetVisAttributes(coilVisAtt);
00344       coil2OuterLV->SetVisAttributes(coilVisAtt);
00345       allLogicalVolumes.push_back(coil1OuterLV);
00346       allLogicalVolumes.push_back(coil2OuterLV);
00347 
00348       new G4PVPlacement(0,                      
00349                         -dipolePosition,        
00350                         coil1OuterLV,           
00351                         name+"_coil1_outer_pv", 
00352                         containerLV,            
00353                         false,                  
00354                         0, 
00355                         checkOverlaps);
00356       new G4PVPlacement(0,                      
00357                         -dipolePosition,        
00358                         coil2OuterLV,           
00359                         name+"_coil2_outer_pv", 
00360                         containerLV,            
00361                         false,                  
00362                         0, 
00363                         checkOverlaps);
00364 
00365       collar1PoleTopOuterSolid    = new G4CutTubs(name+"_collar1_pole_outer_top",      
00366                                                   outerCoilInnerRadius,                
00367                                                   outerCoilOuterRadius,                
00368                                                   length*0.5 - 2*lengthSafety,         
00369                                                   CLHEP::pi*0.5-poleOuterFullAngle*0.5,
00370                                                   poleOuterFullAngle,                  
00371                                                   inputface,                           
00372                                                   outputface);                         
00373       collar1PoleBottomOuterSolid = new G4CutTubs(name+"_collar1_pole_outer_bottom",   
00374                                                   outerCoilInnerRadius,                
00375                                                   outerCoilOuterRadius,                
00376                                                   length*0.5 - 2*lengthSafety,         
00377                                                   CLHEP::pi*1.5-poleOuterFullAngle*0.5,
00378                                                   poleOuterFullAngle,                  
00379                                                   inputface,                           
00380                                                   outputface);                         
00381 
00382       collar1PoleTopOuterLV    = new G4LogicalVolume(collar1PoleTopOuterSolid,
00383                                                      stainlesssteel,
00384                                                      name+"_collar1_pole_top_outer_lv");
00385       collar1PoleBottomOuterLV = new G4LogicalVolume(collar1PoleBottomOuterSolid,
00386                                                      stainlesssteel,
00387                                                      name+"_collar1_pole_bottom_outer_lv");
00388       
00389       collar1PoleTopOuterLV->SetVisAttributes(collarVisAtt);
00390       collar1PoleBottomOuterLV->SetVisAttributes(collarVisAtt);
00391       
00392       allLogicalVolumes.push_back(collar1PoleTopOuterLV);
00393       allLogicalVolumes.push_back(collar1PoleBottomOuterLV);
00394 
00395       new G4PVPlacement(0,                                
00396                         -dipolePosition,                  
00397                         collar1PoleTopOuterLV,            
00398                         name+"_collar1_pole_top_inner_pv",
00399                         containerLV,                      
00400                         false,                            
00401                         0,
00402                         checkOverlaps);
00403       new G4PVPlacement(0,                                
00404                         -dipolePosition,                  
00405                         collar1PoleBottomOuterLV,         
00406                         name+"_collar1_pole_top_inner_pv",
00407                         containerLV,                      
00408                         false,                            
00409                         0,
00410                         checkOverlaps);
00411     }
00412   
00413   
00414   G4VSolid *coil3Inner = new G4CutTubs(name+"_coil3_inner_solid",            
00415                                        innerCoilInnerRadiusF,                
00416                                        innerCoilOuterRadius,                 
00417                                        secondBPHalfLength-2*lengthSafety,    
00418                                        -coilInnerFullAngle*0.5,              
00419                                        coilInnerFullAngle,                   
00420                                        inputface,                            
00421                                        outputface);                          
00422   G4VSolid *coil3Outer = new G4CutTubs(name+"_coil3_outer_solid",            
00423                                        outerCoilInnerRadiusF,                
00424                                        outerCoilOuterRadius,                 
00425                                        secondBPHalfLength-2*lengthSafety,    
00426                                        -coilOuterFullAngle*0.5,              
00427                                        coilOuterFullAngle,                   
00428                                        inputface,                            
00429                                        outputface);                          
00430   G4VSolid *coil4Inner = new G4CutTubs(name+"_coil4_inner_solid",            
00431                                        innerCoilInnerRadiusF,                
00432                                        innerCoilOuterRadius,                 
00433                                        secondBPHalfLength-2*lengthSafety,    
00434                                        CLHEP::pi-coilInnerFullAngle*0.5,     
00435                                        coilInnerFullAngle,                   
00436                                        inputface,                            
00437                                        outputface);                          
00438   G4VSolid *coil4Outer = new G4CutTubs(name+"_coil4_outer_solid",            
00439                                        outerCoilInnerRadiusF,                
00440                                        outerCoilOuterRadius,                 
00441                                        secondBPHalfLength-2*lengthSafety,    
00442                                        CLHEP::pi-coilOuterFullAngle*0.5,     
00443                                        coilOuterFullAngle,                   
00444                                        inputface,                            
00445                                        outputface);                          
00446   
00447   G4LogicalVolume* coil3InnerLV =  new G4LogicalVolume(coil3Inner,
00448                                                        nbti,
00449                                                        name+"_coil3_Inner_lv");
00450   G4LogicalVolume* coil3OuterLV =  new G4LogicalVolume(coil3Outer,
00451                                                        nbti,
00452                                                        name+"_coil3_Inner_lv");
00453   G4LogicalVolume* coil4InnerLV =  new G4LogicalVolume(coil4Inner,
00454                                                        nbti,
00455                                                        name+"_coil4_Inner_lv");
00456   G4LogicalVolume* coil4OuterLV =  new G4LogicalVolume(coil4Outer,
00457                                                        nbti,
00458                                                        name+"_coil4_Inner_lv");
00459   
00460   coil3InnerLV->SetVisAttributes(coilVisAtt);
00461   coil3OuterLV->SetVisAttributes(coilVisAtt);
00462   coil4InnerLV->SetVisAttributes(coilVisAtt);
00463   coil4OuterLV->SetVisAttributes(coilVisAtt);
00464   
00465   allLogicalVolumes.push_back(coil3InnerLV);
00466   allLogicalVolumes.push_back(coil3OuterLV);
00467   allLogicalVolumes.push_back(coil4InnerLV);
00468   allLogicalVolumes.push_back(coil4OuterLV);
00469 
00470   
00471   new G4PVPlacement(0,                      
00472                     dipolePosition,         
00473                     coil3InnerLV,           
00474                     name+"_coil3_inner_pv", 
00475                     containerLV,            
00476                     false,                  
00477                     0, 
00478                     checkOverlaps);
00479   new G4PVPlacement(0,                      
00480                     dipolePosition,         
00481                     coil3OuterLV,           
00482                     name+"_coil3_outer_pv", 
00483                     containerLV,            
00484                     false,                  
00485                     0, 
00486                     checkOverlaps);
00487   new G4PVPlacement(0,                      
00488                     dipolePosition,         
00489                     coil4InnerLV,           
00490                     name+"_coil4_inner_pv", 
00491                     containerLV,            
00492                     false,                  
00493                     0, 
00494                     checkOverlaps);
00495   new G4PVPlacement(0,                      
00496                     dipolePosition,         
00497                     coil4OuterLV,           
00498                     name+"_coil4_outer_pv", 
00499                     containerLV,            
00500                     false,                  
00501                     0, 
00502                     checkOverlaps);
00503   
00504   
00505   
00506   G4VSolid* collar2PoleTopInnerSolid    = new G4CutTubs(name+"_collar2_pole_inner_top",      
00507                                                         innerCoilInnerRadiusF,               
00508                                                         innerCoilOuterRadius,                
00509                                                         secondBPHalfLength-2*lengthSafety,   
00510                                                         CLHEP::pi*0.5-poleInnerFullAngle*0.5,
00511                                                         poleInnerFullAngle,                  
00512                                                         inputface,                           
00513                                                         outputface);                         
00514   G4VSolid* collar2PoleTopOuterSolid    = new G4CutTubs(name+"_collar2_pole_outer_top",      
00515                                                         outerCoilInnerRadiusF,               
00516                                                         outerCoilOuterRadius,                
00517                                                         secondBPHalfLength-2*lengthSafety,   
00518                                                         CLHEP::pi*0.5-poleOuterFullAngle*0.5,
00519                                                         poleOuterFullAngle,                  
00520                                                         inputface,                           
00521                                                         outputface);                         
00522   G4VSolid* collar2PoleBottomInnerSolid = new G4CutTubs(name+"_collar2_pole_inner_bottom",   
00523                                                         innerCoilInnerRadiusF,               
00524                                                         innerCoilOuterRadius,                
00525                                                         secondBPHalfLength-2*lengthSafety,   
00526                                                         CLHEP::pi*1.5-poleInnerFullAngle*0.5,
00527                                                         poleInnerFullAngle,                  
00528                                                         inputface,                           
00529                                                         outputface);                         
00530   G4VSolid* collar2PoleBottomOuterSolid = new G4CutTubs(name+"_collar2_pole_outer_bottom",   
00531                                                         outerCoilInnerRadiusF,               
00532                                                         outerCoilOuterRadius,                
00533                                                         secondBPHalfLength-2*lengthSafety,   
00534                                                         CLHEP::pi*1.5-poleOuterFullAngle*0.5,
00535                                                         poleOuterFullAngle,                  
00536                                                         inputface,                           
00537                                                         outputface);                         
00538   
00539   
00540   G4LogicalVolume* collar2PoleTopInnerLV    = new G4LogicalVolume(collar2PoleTopInnerSolid,
00541                                                                   stainlesssteel,
00542                                                                   name+"_collar2_pole_top_inner_lv");
00543   G4LogicalVolume* collar2PoleTopOuterLV    = new G4LogicalVolume(collar2PoleTopOuterSolid,
00544                                                                   stainlesssteel,
00545                                                                   name+"_collar2_pole_top_outer_lv");
00546   G4LogicalVolume* collar2PoleBottomInnerLV = new G4LogicalVolume(collar2PoleBottomInnerSolid,
00547                                                                   stainlesssteel,
00548                                                                   name+"_collar2_pole_bottom_inner_lv");
00549   G4LogicalVolume* collar2PoleBottomOuterLV = new G4LogicalVolume(collar2PoleBottomOuterSolid,
00550                                                                   stainlesssteel,
00551                                                                   name+"_collar2_pole_bottom_outer_lv");
00552 
00553   
00554   collar2PoleTopInnerLV->SetVisAttributes(collarVisAtt);
00555   collar2PoleTopOuterLV->SetVisAttributes(collarVisAtt);
00556   collar2PoleBottomInnerLV->SetVisAttributes(collarVisAtt);
00557   collar2PoleBottomOuterLV->SetVisAttributes(collarVisAtt);
00558   
00559   allLogicalVolumes.push_back(collar2PoleTopInnerLV);
00560   allLogicalVolumes.push_back(collar2PoleTopOuterLV);
00561   allLogicalVolumes.push_back(collar2PoleBottomInnerLV);
00562   allLogicalVolumes.push_back(collar2PoleBottomOuterLV);
00563   
00564   
00565   new G4PVPlacement(0,                                
00566                     dipolePosition,                   
00567                     collar2PoleTopInnerLV,            
00568                     name+"_collar2_pole_top_inner_pv",
00569                     containerLV,                      
00570                     false,                            
00571                     0,
00572                     checkOverlaps);
00573   new G4PVPlacement(0,                                
00574                     dipolePosition,                   
00575                     collar2PoleTopOuterLV,            
00576                     name+"_collar2_pole_top_inner_pv",
00577                     containerLV,                      
00578                     false,                            
00579                     0,
00580                     checkOverlaps);
00581   new G4PVPlacement(0,                                
00582                     dipolePosition,                   
00583                     collar2PoleBottomInnerLV,         
00584                     name+"_collar2_pole_top_inner_pv",
00585                     containerLV,                      
00586                     false,                            
00587                     0,
00588                     checkOverlaps);
00589   new G4PVPlacement(0,                                
00590                     dipolePosition,                   
00591                     collar2PoleBottomOuterLV,         
00592                     name+"_collar2_pole_top_inner_pv",
00593                     containerLV,                      
00594                     false,                            
00595                     0,
00596                     checkOverlaps);
00597   
00598   
00599   G4VSolid* collarAnnulus2 = new G4CutTubs(name+"_collar2_annulus_solid",    
00600                                            collarInnerRadiusF,               
00601                                            collarOuterRadius,                
00602                                            secondBPHalfLength-lengthSafety,  
00603                                            0,                                
00604                                            CLHEP::twopi,                     
00605                                            inputface,                        
00606                                            outputface);                      
00607   
00608   
00609   G4VSolid* collars = collarAnnulus2;
00610   
00611   if (buildCollar)
00612     {
00613       
00614       G4VSolid* collarAnnulus1 = new G4CutTubs(name+"_collar1_annulus_solid",      
00615                                                collarInnerRadius,                  
00616                                                collarOuterRadius,                  
00617                                                length*0.5-2*lengthSafety,          
00618                                                0,                                  
00619                                                CLHEP::twopi,                       
00620                                                inputface,                          
00621                                                outputface);                        
00622 
00623       collars = new G4UnionSolid(name + "_collars_solid", 
00624                                  collarAnnulus2,          
00625                                  collarAnnulus1,          
00626                                  0,                       
00627                                  -2*dipolePosition);      
00628     }
00629 
00630   
00631 
00632 
00633 
00634 
00635 
00636 
00637 
00638 
00639 
00640 
00641 
00642 
00643 
00644 
00645 
00646 
00647 
00648 
00649 
00650 
00651 
00652 
00653 
00654 
00655 
00656 
00657 
00658   G4VSolid* collarTotal = collars;
00659   
00660   G4LogicalVolume *collarsLV =  new G4LogicalVolume(collarTotal,
00661                                                     stainlesssteel,
00662                                                     name+"_collars_lv");
00663 
00664   
00665   collarsLV->SetVisAttributes(collarVisAtt);
00666 
00667   allLogicalVolumes.push_back(collarsLV); 
00668   
00669   new G4PVPlacement(0,                  
00670                     dipolePosition,     
00671                     collarsLV,          
00672                     name+"_collars_pv", 
00673                     containerLV,        
00674                     false,              
00675                     0,                  
00676                     checkOverlaps);  
00677   
00678   
00679   G4VSolid* yokeCylinder = new G4CutTubs(name+"_yoke_cylinder_solid",     
00680                                          0.,                              
00681                                          yokeOuterRadius - lengthSafety,  
00682                                          centralHalfLength-2*lengthSafety,
00683                                          0,                               
00684                                          CLHEP::twopi,                    
00685                                          inputface,                       
00686                                          outputface);                     
00687 
00688   
00689   G4VSolid* yokeSubtractionCylinder = new G4Tubs(name + "_yoke_subtraction_cyl_solid", 
00690                                                  0,                                    
00691                                                  collarOuterRadius + lengthSafety,     
00692                                                  length,                               
00693                                                  0,                                    
00694                                                  CLHEP::twopi);                        
00695 
00696   G4VSolid* yokeSubtractionSolid = new G4UnionSolid(name + "_yoke_subtraction_solid",  
00697                                                     yokeSubtractionCylinder,           
00698                                                     yokeSubtractionCylinder,           
00699                                                     0,                                 
00700                                                     2*dipolePosition);                 
00701 
00702   G4VSolid* yoke = new G4SubtractionSolid(name+"_yoke_solid",           
00703                                           yokeCylinder,                 
00704                                           yokeSubtractionSolid,         
00705                                           0,                            
00706                                           -dipolePosition);              
00707   
00708   G4LogicalVolume* yokeLV = new G4LogicalVolume(yoke,
00709                                                 BDSMaterials::Instance()->GetMaterial("Iron"),
00710                                                 name+"_yoke_lv");
00711 
00712   
00713   G4VisAttributes* LHCblue = new G4VisAttributes(G4Colour(0.0, 0.5, 1.0));
00714   LHCblue->SetForceLineSegmentsPerCircle(nSegmentsPerCircle);
00715   yokeLV->SetVisAttributes(LHCblue);
00716   
00717   allLogicalVolumes.push_back(yokeLV); 
00718 
00719   
00720   new G4PVPlacement((G4RotationMatrix*)0,         
00721                     G4ThreeVector(0,0,0),         
00722                     yokeLV,                       
00723                     name + "_yoke_pv",            
00724                     containerLV,                  
00725                     false,                        
00726                     0,                            
00727                     checkOverlaps);
00728   
00729   G4String defaultMaterialName = BDSGlobalConstants::Instance()->GetBeamPipeMaterialName();
00730   G4Material* beamPipeMaterial = BDSMaterials::Instance()->GetMaterial(defaultMaterialName);
00731   G4Material* vacuumMaterial   = BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetVacuumMaterial());
00732 
00733   
00734   BDSBeamPipe* secondBP = BDSBeamPipeFactory::Instance()->CreateBeamPipeAngledInOut(BDSBeamPipeType::lhcdetailed,
00735                                                                                     name,
00736                                                                                     2*secondBPHalfLength-2*lengthSafety,
00737                                                                                     -angle*0.5,        
00738                                                                                     -angle*0.5,        
00739                                                                                     2.202*CLHEP::cm,   
00740                                                                                     1.714*CLHEP::cm,   
00741                                                                                     2.202*CLHEP::cm,   
00742                                                                                     0,                 
00743                                                                                     vacuumMaterial,    
00744                                                                                     1*CLHEP::mm,       
00745                                                                                     beamPipeMaterial); 
00746   
00747   G4LogicalVolume* secondBPLV = secondBP->GetContainerLogicalVolume();
00748   allLogicalVolumes.push_back(secondBPLV);
00749   new G4PVPlacement((G4RotationMatrix*)0,         
00750                     dipolePosition,               
00751                     secondBPLV,                   
00752                     name + "_second_beampipe_pv", 
00753                     containerLV,                  
00754                     false,                        
00755                     0,                            
00756                     checkOverlaps);
00757   
00758   
00759   if (BDSExecOptions::Instance()->GetVisDebug())
00760     {containerLV->SetVisAttributes(BDSGlobalConstants::Instance()->GetVisibleDebugVisAttr());}
00761   else
00762     {containerLV->SetVisAttributes(BDSGlobalConstants::Instance()->GetInvisibleVisAttr());}
00763 
00764   
00765 #ifndef NOUSERLIMITS
00766   if (!allLogicalVolumes.empty()) {
00767     G4UserLimits* userLimits = new G4UserLimits("outer_cuts");
00768     userLimits->SetMaxAllowedStep( length * maxStepFactor );
00769     userLimits->SetUserMinEkine(BDSGlobalConstants::Instance()->GetThresholdCutCharged());
00770     userLimits->SetUserMaxTime(BDSGlobalConstants::Instance()->GetMaxTime());
00771     
00772     for (std::vector<G4LogicalVolume*>::iterator i = allLogicalVolumes.begin(); i != allLogicalVolumes.end(); ++i)
00773       {(*i)->SetUserLimits(userLimits);}
00774   }
00775 #endif
00776   
00777   
00778   
00779   G4double containerRadius = yokeOuterRadius;
00780   
00781   std::pair<double,double> extX = std::make_pair(-containerRadius+massShift,containerRadius+massShift); 
00782   std::pair<double,double> extY = std::make_pair(-containerRadius,containerRadius);
00783   std::pair<double,double> extZ = std::make_pair(-length*0.5,length*0.5);
00784   
00785   
00786   BDSGeometryComponent* outer = new BDSGeometryComponent(containerSolid,
00787                                                          containerLV,
00788                                                          extX, extY, extZ,
00789                                                          dipolePosition);
00790   
00791   outer->RegisterLogicalVolumes(secondBP->GetAllLogicalVolumes());
00792   outer->RegisterLogicalVolumes(allLogicalVolumes);
00793 
00794   
00795   outer->RegisterSensitiveVolumes(allLogicalVolumes);
00796   outer->RegisterSensitiveVolumes(secondBP->GetAllSensitiveVolumes());
00797 
00798   
00799   
00800   
00801   return outer;
00802 }
00803 
00804 BDSGeometryComponent* BDSMagnetOuterFactoryLHC::CreateRectangularBend(G4String      name,
00805                                                                       G4double      length,
00806                                                                       BDSBeamPipe*  beamPipe,
00807                                                                       G4double      boxSize,
00808                                                                       G4double      ,
00809                                                                       G4Material*   outerMaterial)
00810 {
00811 #ifdef BDSDEBUG
00812   G4cout << __METHOD_NAME__ << G4endl;
00813 #endif
00814   CleanUp();
00815   
00816   CreateCylindricalSolids(name, length, beamPipe, boxSize);
00817   return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("rectangularbend"));
00818 }
00819 
00820 BDSGeometryComponent* BDSMagnetOuterFactoryLHC::CreateQuadrupole(G4String      name,
00821                                                                  G4double      length,
00822                                                                  BDSBeamPipe*  beamPipe,
00823                                                                  G4double      outerDiameter,
00824                                                                  G4Material*   outerMaterial)
00825 
00826 {
00827 #ifdef BDSDEBUG
00828   G4cout << __METHOD_NAME__ << G4endl;
00829 #endif
00830   CleanUp();
00831 
00832   
00833   TestInputParameters(beamPipe,outerDiameter,outerMaterial);
00834 
00835   
00836   
00837   
00838   G4double beamPipeAxisSeparation = 194.00*CLHEP::mm;               
00839   G4double massShift              = 0.5 * beamPipeAxisSeparation;   
00840   
00841   G4double collarBoxHalfWidth     = 22*CLHEP::mm;                   
00842 
00843   
00844   G4double containerInnerRadius   = beamPipe->GetContainerRadius()+1*CLHEP::um;
00845   G4double coilInnerRadius        = containerInnerRadius + lengthSafety;
00846   G4double coilInnerRadiusF       = 24.601*CLHEP::mm; 
00847   G4double coilOuterRadius        = 60*CLHEP::mm;                   
00848   G4double collarInnerRadius      = coilOuterRadius + lengthSafety;
00849   G4double collarInnerRadiusF     = coilOuterRadius + lengthSafety;
00850   G4double collarOuterRadius      = 101.18*CLHEP::mm;               
00851   G4double yokeOuterRadius        = 570.0*0.5*CLHEP::mm;            
00852 
00853   
00854   
00855   G4double poleFullAngle    = CLHEP::pi/6.; 
00856   G4double coilFullAngle    = CLHEP::pi/2. - poleFullAngle - 1e-5; 
00857   G4double coilHalfAngle    = coilFullAngle*0.5;
00858   G4double coilStartAngle   = -coilHalfAngle;
00859   G4double poleStartAngle   = coilHalfAngle;
00860   G4RotationMatrix* coil2rm = new G4RotationMatrix();
00861   G4RotationMatrix* coil3rm = new G4RotationMatrix();
00862   G4RotationMatrix* coil4rm = new G4RotationMatrix();
00863   coil2rm->rotateZ(CLHEP::pi/2.0);
00864   coil3rm->rotateZ(CLHEP::pi);
00865   coil4rm->rotateZ(CLHEP::pi*1.5);
00866 
00867   
00868   
00869   G4bool buildCoil         = true;
00870   G4bool buildCollar       = true; 
00871   if (coilInnerRadius > coilOuterRadius)
00872     {buildCoil = false;}
00873   
00874   
00875   if ((coilInnerRadius > collarInnerRadius) && (coilInnerRadius < (massShift - collarBoxHalfWidth)))
00876     {collarInnerRadius = containerInnerRadius + lengthSafety;}
00877   if (coilInnerRadius > (massShift - collarBoxHalfWidth))
00878     {buildCollar = false;}
00879   if (coilInnerRadius > collarOuterRadius)
00880     {
00881       
00882       G4cerr << __METHOD_NAME__ << "this beam pipe is too big to use with the LHC dipole geometry" << G4endl;
00883       G4cerr << "Please consider using a different magnet geometry for this particular magnet" << G4endl;
00884       G4cerr << "Magnet named: " << name << G4endl;
00885       exit(1);
00886     }
00887 
00888   G4ThreeVector dipolePosition; 
00889   if (isLeftOffset)
00890     {
00891       dipolePosition = G4ThreeVector(massShift,0.,0.);
00892       beamPipeAxisSeparation  *= -1;
00893 #ifdef BDSDEBUG
00894       G4cout << __METHOD_NAME__ << "dipole to the left" << G4endl;
00895 #endif
00896     }
00897   else
00898     {
00899       dipolePosition = G4ThreeVector(-massShift,0.,0.);
00900       
00901 #ifdef BDSDEBUG
00902       G4cout << __METHOD_NAME__ << "dipole to the right" << G4endl;
00903 #endif
00904     }
00905 
00906   
00907   std::vector<G4LogicalVolume*> allLogicalVolumes;
00908   
00909   if (beamPipe->ContainerIsCircular())
00910     {
00911       
00912       
00913       
00914       G4VSolid* containerSolidOuter = new G4Tubs(name + "_contiainer_solid_outer",  
00915                                                  0,                           
00916                                                  yokeOuterRadius,             
00917                                                  length*0.5,                  
00918                                                  0,                           
00919                                                  CLHEP::twopi);               
00920                                                     
00921       G4VSolid* containerSolidInner = new G4Tubs(name + "_contiainer_solid_inner",  
00922                                                  0,                                 
00923                                                  containerInnerRadius,              
00924                                                  length,                            
00925                                                  0,                                 
00926                                                  CLHEP::twopi);
00927       containerSolid = new G4SubtractionSolid(name + "_container_solid",   
00928                                               containerSolidOuter,         
00929                                               containerSolidInner,         
00930                                               0,                           
00931                                               -dipolePosition);            
00932     }
00933   else
00934     {
00935       
00936       G4VSolid* containerSolidOuter = new G4Tubs(name + "_contiainer_solid_outer",  
00937                                                  0,                                 
00938                                                  yokeOuterRadius,                   
00939                                                  length*0.5,                        
00940                                                  0,                                 
00941                                                  CLHEP::twopi);                     
00942                                                  
00943       containerSolid = new G4SubtractionSolid(name + "_container_solid",
00944                                               containerSolidOuter,
00945                                               beamPipe->GetContainerSubtractionSolid(),
00946                                               0,                
00947                                               -dipolePosition); 
00948     }
00949 
00950   G4Material* emptyMaterial = BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetEmptyMaterial());
00951   G4LogicalVolume* containerLV = new G4LogicalVolume(containerSolid,
00952                                                      emptyMaterial,
00953                                                      name + "_container_lv");
00954 
00955   
00956   
00957   
00958   G4VSolid*        coil1     = NULL;
00959   G4VSolid*        coil2     = NULL;
00960   G4LogicalVolume* coil1LV   = NULL;
00961   G4LogicalVolume* coil2LV   = NULL;
00962 
00963   
00964   G4VSolid*        pole1     = NULL;
00965   G4VSolid*        pole2     = NULL;
00966   G4LogicalVolume* pole1LV   = NULL;
00967   G4LogicalVolume* pole2LV   = NULL;
00968 
00969   
00970   G4VSolid*        collar    = NULL;
00971   G4VSolid*        collars   = NULL; 
00972   G4LogicalVolume* collarsLV = NULL;
00973 
00974   
00975   G4Material* nbti              = BDSMaterials::Instance()->GetMaterial("NbTi.1");
00976   G4Material* iron              = BDSMaterials::Instance()->GetMaterial("iron");
00977   G4Material* stainlesssteel    = BDSMaterials::Instance()->GetMaterial("stainlesssteel");
00978   G4VisAttributes* coilVisAtt   = new G4VisAttributes(G4Colour(0.9, 0.75, 0.)); 
00979   coilVisAtt->SetForceLineSegmentsPerCircle(nSegmentsPerCircle);
00980   G4VisAttributes* collarVisAtt = new G4VisAttributes(G4Colour(0.9, 0.9, 0.9)); 
00981   collarVisAtt->SetForceLineSegmentsPerCircle(nSegmentsPerCircle);
00982   
00983   if (buildCoil)
00984     {
00985       
00986       coil1 = new G4Tubs(name+"_coil1_solid",          
00987                          coilInnerRadius,              
00988                          coilOuterRadius,              
00989                          length*0.5-2*lengthSafety,    
00990                          coilStartAngle,               
00991                          coilFullAngle);               
00992       
00993       coil1LV = new G4LogicalVolume(coil1,             
00994                                     nbti,              
00995                                     name+"_coil1_lv"); 
00996       coil1LV->SetVisAttributes(coilVisAtt);
00997       allLogicalVolumes.push_back(coil1LV);
00998 
00999       
01000       pole1 = new G4Tubs(name+"_pole1_solid",          
01001                          coilInnerRadius,              
01002                          coilOuterRadius,              
01003                          length*0.5 - lengthSafety,    
01004                          poleStartAngle,               
01005                          poleFullAngle);               
01006       pole1LV = new G4LogicalVolume(pole1,             
01007                                     stainlesssteel,    
01008                                     name+"_pole1_lv"); 
01009       pole1LV->SetVisAttributes(collarVisAtt);
01010       allLogicalVolumes.push_back(pole1LV);
01011 
01012       
01013       new G4PVPlacement(0,                  
01014                         -dipolePosition,    
01015                         coil1LV,            
01016                         name + "_coil1_pv", 
01017                         containerLV,        
01018                         false,              
01019                         0,                  
01020                         checkOverlaps);
01021       new G4PVPlacement(coil2rm,            
01022                         -dipolePosition,    
01023                         coil1LV,            
01024                         name + "_coil2_pv", 
01025                         containerLV,        
01026                         false,              
01027                         0,                  
01028                         checkOverlaps);
01029       new G4PVPlacement(coil3rm,            
01030                         -dipolePosition,    
01031                         coil1LV,            
01032                         name + "_coil3_pv", 
01033                         containerLV,        
01034                         false,              
01035                         0,                  
01036                         checkOverlaps);
01037       new G4PVPlacement(coil4rm,            
01038                         -dipolePosition,    
01039                         coil1LV,            
01040                         name + "_coil4_pv", 
01041                         containerLV,        
01042                         false,              
01043                         0,                  
01044                         checkOverlaps);
01045 
01046       
01047       new G4PVPlacement(0,                  
01048                         -dipolePosition,    
01049                         pole1LV,            
01050                         name + "_pole1_pv", 
01051                         containerLV,        
01052                         false,              
01053                         0,                  
01054                         checkOverlaps);
01055       new G4PVPlacement(coil2rm,            
01056                         -dipolePosition,    
01057                         pole1LV,            
01058                         name + "_pole2_pv", 
01059                         containerLV,        
01060                         false,              
01061                         0,                  
01062                         checkOverlaps);
01063       new G4PVPlacement(coil3rm,            
01064                         -dipolePosition,    
01065                         pole1LV,            
01066                         name + "_pole3_pv", 
01067                         containerLV,        
01068                         false,              
01069                         0,                  
01070                         checkOverlaps);
01071       new G4PVPlacement(coil4rm,            
01072                         -dipolePosition,    
01073                         pole1LV,            
01074                         name + "_pole4_pv", 
01075                         containerLV,        
01076                         false,              
01077                         0,                  
01078                         checkOverlaps);
01079     }
01080   
01081   
01082   coil2   = new G4Tubs(name+"_coil2_solid",          
01083                        coilInnerRadiusF,             
01084                        coilOuterRadius,              
01085                        length*0.5-2*lengthSafety,    
01086                        coilStartAngle,               
01087                        coilFullAngle);               
01088   coil2LV = new G4LogicalVolume(coil2,               
01089                                 nbti,                
01090                                 name+"_coil2_lv");   
01091   coil2LV->SetVisAttributes(coilVisAtt);
01092   allLogicalVolumes.push_back(coil2LV);
01093   
01094   
01095   pole2   = new G4Tubs(name+"_pole2_solid",          
01096                        coilInnerRadiusF,             
01097                        coilOuterRadius,              
01098                        length*0.5 - lengthSafety,    
01099                        poleStartAngle,               
01100                        poleFullAngle);               
01101   pole2LV = new G4LogicalVolume(pole2,               
01102                                 stainlesssteel,      
01103                                 name+"_pole2_lv");   
01104   pole2LV->SetVisAttributes(collarVisAtt);
01105   allLogicalVolumes.push_back(pole2LV);
01106   
01107   
01108   new G4PVPlacement(0,                  
01109                     dipolePosition,    
01110                     coil2LV,            
01111                     name + "_coil5_pv", 
01112                     containerLV,        
01113                     false,              
01114                     0,                  
01115                     checkOverlaps);
01116   new G4PVPlacement(coil2rm,            
01117                     dipolePosition,    
01118                     coil2LV,            
01119                     name + "_coil6_pv", 
01120                     containerLV,        
01121                     false,              
01122                     0,                  
01123                     checkOverlaps);
01124   new G4PVPlacement(coil3rm,            
01125                     dipolePosition,    
01126                     coil2LV,            
01127                     name + "_coil7_pv", 
01128                     containerLV,        
01129                     false,              
01130                     0,                  
01131                     checkOverlaps);
01132   new G4PVPlacement(coil4rm,            
01133                     dipolePosition,    
01134                     coil2LV,            
01135                     name + "_coil8_pv", 
01136                     containerLV,        
01137                     false,              
01138                     0,                  
01139                     checkOverlaps);
01140   
01141   
01142   new G4PVPlacement(0,                  
01143                     dipolePosition,    
01144                     pole2LV,            
01145                     name + "_pole5_pv", 
01146                     containerLV,        
01147                     false,              
01148                     0,                  
01149                     checkOverlaps);
01150   new G4PVPlacement(coil2rm,            
01151                     dipolePosition,    
01152                     pole2LV,            
01153                     name + "_pole6_pv", 
01154                     containerLV,        
01155                     false,              
01156                     0,                  
01157                     checkOverlaps);
01158   new G4PVPlacement(coil3rm,            
01159                     dipolePosition,    
01160                     pole2LV,            
01161                     name + "_pole7_pv", 
01162                     containerLV,        
01163                     false,              
01164                     0,                  
01165                     checkOverlaps);
01166   new G4PVPlacement(coil4rm,            
01167                     dipolePosition,    
01168                     pole2LV,            
01169                     name + "_pole8_pv", 
01170                     containerLV,        
01171                     false,              
01172                     0,                  
01173                     checkOverlaps);
01174   
01175   
01176   
01177   collar = new G4Tubs(name+"_collar_solid",        
01178                       collarInnerRadiusF,          
01179                       collarOuterRadius,           
01180                       length*0.5 - 2*lengthSafety, 
01181                       0,                           
01182                       CLHEP::twopi);               
01183   collars = collar;
01184   if (buildCollar)
01185     {
01186       if (collarInnerRadius == collarInnerRadiusF)
01187         {
01188           
01189           collars = new G4UnionSolid(name + "_collars_solid",  
01190                                      collar,                   
01191                                      collar,                   
01192                                      0,                        
01193                                      -2*dipolePosition);       
01194         }
01195       else
01196         {
01197           G4VSolid* collar2 = new G4Tubs(name+"_collar2_solid",      
01198                                          collarInnerRadius,          
01199                                          collarOuterRadius,          
01200                                          length*0.5-2*lengthSafety,  
01201                                          0,                          
01202                                          CLHEP::twopi);              
01203           collars = new G4UnionSolid(name + "_collars_solid", 
01204                                      collar,                  
01205                                      collar2,                 
01206                                      0,                       
01207                                      -2*dipolePosition);      
01208         }
01209     }
01210   
01211   collarsLV = new G4LogicalVolume(collars,
01212                                   stainlesssteel,
01213                                   name+"_collars_lv");
01214   collarsLV->SetVisAttributes(collarVisAtt);
01215   allLogicalVolumes.push_back(collarsLV); 
01216 
01217   new G4PVPlacement(0,                  
01218                     dipolePosition,     
01219                     collarsLV,          
01220                     name+"_collars_pv", 
01221                     containerLV,        
01222                     false,              
01223                     0,                  
01224                     checkOverlaps);
01225 
01226   
01227   
01228   G4VSolid* collarSubtractionCylinder = new G4Tubs(name+"_collar_subtraction_solid",  
01229                                                    0,                                 
01230                                                    collarOuterRadius + lengthSafety,  
01231                                                    length,                            
01232                                                    0,                                 
01233                                                    CLHEP::twopi);                     
01234 
01235   G4VSolid* collarSubtractionCylinders = new G4UnionSolid(name + "_collar_subtraction_cylinders", 
01236                                                           collarSubtractionCylinder,              
01237                                                           collarSubtractionCylinder,              
01238                                                           0,                                      
01239                                                           2*dipolePosition);                      
01240  
01241   
01242   G4VSolid* yokeCylinder = new G4Tubs(name+"_yoke_cylinder_solid",     
01243                                       0.,                              
01244                                       yokeOuterRadius,                 
01245                                       0.5*length-2*lengthSafety,       
01246                                       0,                               
01247                                       CLHEP::twopi * CLHEP::rad);      
01248 
01249   G4VSolid* yoke = new G4SubtractionSolid(name+"_yoke_solid",             
01250                                           yokeCylinder,                   
01251                                           collarSubtractionCylinders,     
01252                                           0,
01253                                           -dipolePosition);               
01254   
01255   G4LogicalVolume* yokeLV = new G4LogicalVolume(yoke,
01256                                                 iron,
01257                                                 name+"_yoke_lv");
01258 
01259   
01260   G4VisAttributes* LHCred = new G4VisAttributes(G4Colour(1.0, 0., 0.));
01261   LHCred->SetForceLineSegmentsPerCircle(nSegmentsPerCircle);
01262   yokeLV->SetVisAttributes(LHCred);
01263   
01264   allLogicalVolumes.push_back(yokeLV); 
01265 
01266   
01267   new G4PVPlacement((G4RotationMatrix*)0,         
01268                     G4ThreeVector(0,0,0),         
01269                     yokeLV,                       
01270                     name + "_yoke_pv",            
01271                     containerLV,                  
01272                     false,                        
01273                     0,                            
01274                     checkOverlaps);
01275 
01276   G4String defaultMaterialName = BDSGlobalConstants::Instance()->GetBeamPipeMaterialName();
01277   G4Material* beamPipeMaterial = BDSMaterials::Instance()->GetMaterial(defaultMaterialName);
01278   G4Material* vacuumMaterial   = BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetVacuumMaterial());
01279 
01280   
01281   
01282   BDSBeamPipe* secondBP = BDSBeamPipeFactory::Instance()->CreateBeamPipe(BDSBeamPipeType::lhcdetailed,
01283                                                                          name,
01284                                                                          length-2*lengthSafety,
01285                                                                          2.202*CLHEP::cm,   
01286                                                                          1.714*CLHEP::cm,   
01287                                                                          2.202*CLHEP::cm,   
01288                                                                          0,                 
01289                                                                          vacuumMaterial,    
01290                                                                          1*CLHEP::mm,       
01291                                                                          beamPipeMaterial); 
01292   
01293   G4LogicalVolume* secondBPLV = secondBP->GetContainerLogicalVolume();
01294   allLogicalVolumes.push_back(secondBPLV);
01295   new G4PVPlacement((G4RotationMatrix*)0,         
01296                     dipolePosition,               
01297                     secondBPLV,                   
01298                     name + "_second_beampipe_pv", 
01299                     containerLV,                  
01300                     false,                        
01301                     0,                            
01302                     checkOverlaps);
01303   
01304   
01305   if (BDSExecOptions::Instance()->GetVisDebug())
01306     {containerLV->SetVisAttributes(BDSGlobalConstants::Instance()->GetVisibleDebugVisAttr());}
01307   else
01308     {containerLV->SetVisAttributes(BDSGlobalConstants::Instance()->GetInvisibleVisAttr());}
01309 
01310   
01311 #ifndef NOUSERLIMITS
01312   if (!allLogicalVolumes.empty()) {
01313     G4UserLimits* userLimits = new G4UserLimits("outer_cuts");
01314     userLimits->SetMaxAllowedStep( length * maxStepFactor );
01315     userLimits->SetUserMinEkine(BDSGlobalConstants::Instance()->GetThresholdCutCharged());
01316     userLimits->SetUserMaxTime(BDSGlobalConstants::Instance()->GetMaxTime());
01317     
01318     for (std::vector<G4LogicalVolume*>::iterator i = allLogicalVolumes.begin(); i != allLogicalVolumes.end(); ++i)
01319       {(*i)->SetUserLimits(userLimits);}
01320   }
01321 #endif
01322     
01323   
01324   
01325   G4double containerRadius = yokeOuterRadius;
01326   
01327   std::pair<double,double> extX = std::make_pair(-containerRadius+massShift,containerRadius+massShift); 
01328   std::pair<double,double> extY = std::make_pair(-containerRadius,containerRadius);
01329   std::pair<double,double> extZ = std::make_pair(-length*0.5,length*0.5);
01330   
01331   
01332   BDSGeometryComponent* outer = new BDSGeometryComponent(containerSolid,
01333                                                          containerLV,
01334                                                          extX, extY, extZ,
01335                                                          dipolePosition);
01336   
01337   outer->RegisterLogicalVolumes(secondBP->GetAllLogicalVolumes());
01338   outer->RegisterLogicalVolumes(allLogicalVolumes);
01339   
01340   return outer;
01341 }
01342 
01343 BDSGeometryComponent* BDSMagnetOuterFactoryLHC::CreateSextupole(G4String      name,
01344                                                                 G4double      length,
01345                                                                 BDSBeamPipe*  beamPipe,
01346                                                                 G4double      boxSize,
01347                                                                 G4Material*   outerMaterial)
01348 {
01349   CreateCylindricalSolids(name, length, beamPipe, boxSize);
01350   return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("sextupole"));
01351 }
01352 
01353 BDSGeometryComponent* BDSMagnetOuterFactoryLHC::CreateOctupole(G4String      name,
01354                                                                G4double      length,
01355                                                                BDSBeamPipe*  beamPipe,
01356                                                                G4double      boxSize,
01357                                                                G4Material*   outerMaterial)
01358 {
01359 #ifdef BDSDEBUG
01360   G4cout << __METHOD_NAME__ << G4endl;
01361 #endif
01362   CreateCylindricalSolids(name, length, beamPipe, boxSize);
01363   return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("octupole"));
01364 }
01365 
01366 BDSGeometryComponent* BDSMagnetOuterFactoryLHC::CreateDecapole(G4String      name,
01367                                                                G4double      length,
01368                                                                BDSBeamPipe*  beamPipe,
01369                                                                G4double      boxSize,
01370                                                                G4Material*   outerMaterial)
01371 {
01372 #ifdef BDSDEBUG
01373   G4cout << __METHOD_NAME__ << G4endl;
01374 #endif
01375   CreateCylindricalSolids(name, length, beamPipe, boxSize);
01376   return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("decapole"));
01377 }
01378 
01379 BDSGeometryComponent* BDSMagnetOuterFactoryLHC::CreateSolenoid(G4String      name,
01380                                                                G4double      length,
01381                                                                BDSBeamPipe*  beamPipe,
01382                                                                G4double      boxSize,
01383                                                                G4Material*   outerMaterial)
01384 {
01385   CreateCylindricalSolids(name, length, beamPipe, boxSize);
01386   return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("solenoid"));
01387 }
01388 
01389 BDSGeometryComponent* BDSMagnetOuterFactoryLHC::CreateMultipole(G4String      name,
01390                                                                 G4double      length,
01391                                                                 BDSBeamPipe*  beamPipe,
01392                                                                 G4double      boxSize,
01393                                                                 G4Material*   outerMaterial)
01394 {
01395 #ifdef BDSDEBUG
01396   G4cout << __METHOD_NAME__ << G4endl;
01397 #endif
01398   CreateCylindricalSolids(name, length, beamPipe, boxSize);
01399   return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("multipole"));
01400 }
01401 
01402 BDSGeometryComponent* BDSMagnetOuterFactoryLHC::CreateRfCavity(G4String      name,
01403                                                                G4double      length,
01404                                                                BDSBeamPipe*  beamPipe,
01405                                                                G4double      boxSize,
01406                                                                G4Material*   outerMaterial)
01407 {
01408 #ifdef BDSDEBUG
01409   G4cout << __METHOD_NAME__ << G4endl;
01410 #endif
01411   CreateCylindricalSolids(name, length, beamPipe, boxSize);
01412   return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("rfcavity"));
01413 }
01414 
01415 BDSGeometryComponent* BDSMagnetOuterFactoryLHC::CreateMuSpoiler(G4String      name,
01416                                                                 G4double      length,
01417                                                                 BDSBeamPipe*  beamPipe,
01418                                                                 G4double      boxSize,
01419                                                                 G4Material*   outerMaterial)
01420 {
01421 #ifdef BDSDEBUG
01422   G4cout << __METHOD_NAME__ << G4endl;
01423 #endif
01424   CreateCylindricalSolids(name, length, beamPipe, boxSize);
01425   return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("muspoiler"));
01426 }
01427 
01428 BDSGeometryComponent* BDSMagnetOuterFactoryLHC::CreateKicker(G4String      name,
01429                                                              G4double      length,
01430                                                              BDSBeamPipe*  beamPipe,
01431                                                              G4double      boxSize,
01432                                                              G4bool        ,
01433                                                              G4Material*   outerMaterial)
01434 {
01435 #ifdef BDSDEBUG
01436   G4cout << __METHOD_NAME__ << G4endl;
01437 #endif
01438   
01439   
01440   CreateCylindricalSolids(name, length, beamPipe, boxSize);
01441   return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("hkicker"));
01442 }
01443 
01445 
01446 void BDSMagnetOuterFactoryLHC::CreateCylindricalSolids(G4String     name,
01447                                                        G4double     length,
01448                                                        BDSBeamPipe* beamPipe,
01449                                                        G4double     boxSize)
01450 {
01451   if (beamPipe->ContainerIsCircular())
01452     {
01453       
01454       yokeSolid = new G4Tubs(name + "_yoke_solid",       
01455                              beamPipe->GetContainerRadius() + 2*lengthSafety,  
01456                              boxSize*0.5,                 
01457                              length*0.5-2*lengthSafety,   
01458                              0,                           
01459                              CLHEP::twopi);               
01460 
01461       
01462       containerSolid = new G4Tubs(name + "_contiainer_solid",  
01463                                   beamPipe->GetContainerRadius() + lengthSafety, 
01464                                   boxSize*0.5 + lengthSafety,  
01465                                   length*0.5,                  
01466                                   0,                           
01467                                   CLHEP::twopi);               
01468     }
01469   else
01470     {
01471       G4VSolid* yokeSolidCylinder = new G4Tubs(name + "_yoke_solid_cylinder",  
01472                                                0,  
01473                                                boxSize*0.5,                 
01474                                                length*0.5-2*lengthSafety,   
01475                                                0,                           
01476                                                CLHEP::twopi);               
01477       yokeSolid = new G4SubtractionSolid(name + "_yoke_solid",
01478                                          yokeSolidCylinder,
01479                                          beamPipe->GetContainerSubtractionSolid());
01480       
01481       
01482       G4VSolid* containerSolidCylinder = new G4Tubs(name + "_container_solid_cylinder", 
01483                                                     0,  
01484                                                     boxSize*0.5 + lengthSafety,  
01485                                                     length*0.5,                  
01486                                                     0,                           
01487                                                     CLHEP::twopi);               
01488       containerSolid = new G4SubtractionSolid(name + "_container_solid",
01489                                               containerSolidCylinder,
01490                                               beamPipe->GetContainerSubtractionSolid());
01491     }
01492 }
01493 
01494 void BDSMagnetOuterFactoryLHC::TestInputParameters(BDSBeamPipe* ,
01495                                                    G4double&    outerDiameter,
01496                                                    G4Material*& outerMaterial)
01497 {
01498   
01499   
01500   if (!outerMaterial)
01501     {outerMaterial = BDSMaterials::Instance()->GetMaterial("stainlesssteel");}
01502 
01503   
01504   if (outerDiameter < 202*CLHEP::mm )
01505     {outerDiameter = 202*CLHEP::mm;}
01506 }
01507 
01510 BDSGeometryComponent* BDSMagnetOuterFactoryLHC::CommonFinalConstructor(G4String    name,
01511                                                                        G4double    length,
01512                                                                        G4double    boxSize,
01513                                                                        G4Material* outerMaterial,
01514                                                                        G4Colour*   colour)
01515 {
01516 #ifdef BDSDEBUG
01517   G4cout << __METHOD_NAME__ << G4endl;
01518 #endif
01519   
01520   
01521   G4LogicalVolume* yokeLV   = new G4LogicalVolume(yokeSolid,
01522                                                   outerMaterial,
01523                                                   name + "_yoke_lv");
01524 
01525   G4Material* emptyMaterial = BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetEmptyMaterial());
01526   G4LogicalVolume* containerLV = new G4LogicalVolume(containerSolid,
01527                                                      emptyMaterial,
01528                                                      name + "_container_lv");
01529   
01530   
01531   
01532   
01533   G4VisAttributes* outerVisAttr = new G4VisAttributes(*colour);
01534   outerVisAttr->SetVisibility(true);
01535   yokeLV->SetVisAttributes(outerVisAttr);
01536   
01537   
01538   if (BDSExecOptions::Instance()->GetVisDebug())
01539     {containerLV->SetVisAttributes(BDSGlobalConstants::Instance()->GetVisibleDebugVisAttr());}
01540   else
01541     {containerLV->SetVisAttributes(BDSGlobalConstants::Instance()->GetInvisibleVisAttr());}
01542 
01543   
01544 #ifndef NOUSERLIMITS
01545   G4UserLimits* outerUserLimits = new G4UserLimits("outer_cuts");
01546   outerUserLimits->SetMaxAllowedStep( length * maxStepFactor );
01547   outerUserLimits->SetUserMinEkine(BDSGlobalConstants::Instance()->GetThresholdCutCharged());
01548   outerUserLimits->SetUserMaxTime(BDSGlobalConstants::Instance()->GetMaxTime());
01549   
01550   yokeLV->SetUserLimits(outerUserLimits);
01551   containerLV->SetUserLimits(outerUserLimits);
01552 #endif
01553 
01554   
01555   
01556   
01557   
01558   new G4PVPlacement((G4RotationMatrix*)0,         
01559                     (G4ThreeVector)0,             
01560                     yokeLV,                       
01561                     name + "_outer_pv",           
01562                     containerLV,                  
01563                     false,                        
01564                     0,                            
01565                     checkOverlaps);               
01566   
01567   
01568   
01569   G4double containerRadius = boxSize + lengthSafety;
01570   std::pair<double,double> extX = std::make_pair(-containerRadius,containerRadius);
01571   std::pair<double,double> extY = std::make_pair(-containerRadius,containerRadius);
01572   std::pair<double,double> extZ = std::make_pair(-length*0.5,length*0.5);
01573   
01574   
01575   BDSGeometryComponent* outer = new BDSGeometryComponent(containerSolid,
01576                                                          containerLV,
01577                                                          extX, extY, extZ);
01578   
01579   outer->RegisterLogicalVolume(yokeLV); 
01580   
01581   return outer;
01582 }