00001 #include "BDSBeamPipeFactoryBase.hh"
00002 #include "BDSBeamPipeFactoryRectEllipse.hh"
00003 #include "BDSBeamPipe.hh"
00004 
00005 #include "BDSDebug.hh"
00006 #include "BDSExecOptions.hh"
00007 #include "BDSGlobalConstants.hh"
00008 #include "BDSSDManager.hh"
00009 
00010 #include "globals.hh"                      
00011 #include "G4Box.hh"
00012 #include "G4CutTubs.hh"
00013 #include "G4EllipticalTube.hh"
00014 #include "G4IntersectionSolid.hh"
00015 #include "G4LogicalVolume.hh"
00016 #include "G4Material.hh"
00017 #include "G4SubtractionSolid.hh"
00018 #include "G4ThreeVector.hh"
00019 #include "G4Tubs.hh"
00020 #include "G4VSolid.hh"
00021 
00022 #include <cmath>
00023 #include <utility>                         
00024 
00025 BDSBeamPipeFactoryRectEllipse* BDSBeamPipeFactoryRectEllipse::_instance = 0;
00026 
00027 BDSBeamPipeFactoryRectEllipse* BDSBeamPipeFactoryRectEllipse::Instance()
00028 {
00029   if (_instance == 0)
00030     {_instance = new BDSBeamPipeFactoryRectEllipse();}
00031   return _instance;
00032 }
00033 
00034 BDSBeamPipeFactoryRectEllipse::BDSBeamPipeFactoryRectEllipse():BDSBeamPipeFactoryBase()
00035 {
00036 }
00037 
00038 BDSBeamPipeFactoryRectEllipse::~BDSBeamPipeFactoryRectEllipse()
00039 {
00040   _instance = 0;
00041 }
00042 
00043 BDSBeamPipe* BDSBeamPipeFactoryRectEllipse::CreateBeamPipe(G4String    nameIn,              
00044                                                            G4double    lengthIn,            
00045                                                            G4double    aper1In,             
00046                                                            G4double    aper2In,             
00047                                                            G4double    aper3In,             
00048                                                            G4double    aper4In,             
00049                                                            G4Material* vacuumMaterialIn,    
00050                                                            G4double    beamPipeThicknessIn, 
00051                                                            G4Material* beamPipeMaterialIn   
00052                                                            )
00053 {
00054 #ifdef BDSDEBUG
00055   G4cout << __METHOD_NAME__ << G4endl;
00056 #endif
00057   
00058   CleanUp();
00059   
00060   
00061   TestInputParameters(vacuumMaterialIn,beamPipeThicknessIn,beamPipeMaterialIn,aper1In,aper2In,aper3In,aper4In);
00062 
00063   
00064   
00065   G4VSolid* vacCylSolid = new G4EllipticalTube(nameIn + "_vacuum_ellipsoid", 
00066                                                aper3In,                      
00067                                                aper4In,                      
00068                                                lengthIn*0.5-2*lengthSafety); 
00069   
00070   G4VSolid* vacRectSolid = new G4Box(nameIn + "_vacuum_box", 
00071                                      aper1In,                
00072                                      aper2In,                
00073                                      lengthIn); 
00074   
00075   vacuumSolid = new G4IntersectionSolid(nameIn + "_vacuum_solid", 
00076                                         vacCylSolid,              
00077                                         vacRectSolid);            
00078 
00079   
00080   
00081   G4VSolid* bpInnerCylSolid = new G4EllipticalTube(nameIn + "_pipe_inner_ellipsoid",
00082                                                    aper3In + lengthSafety,          
00083                                                    aper4In + lengthSafety,          
00084                                                    1.5*lengthIn); 
00085   
00086   G4VSolid* bpInnerRectSolid = new G4Box(nameIn + "_pipe_inner_box", 
00087                                          aper1In + lengthSafety,     
00088                                          aper2In + lengthSafety,     
00089                                          1.7*lengthIn); 
00090   
00091   G4VSolid* bpInnerSolid = new G4IntersectionSolid(nameIn + "_pipe_inner_solid", 
00092                                                    bpInnerCylSolid,              
00093                                                    bpInnerRectSolid);            
00094 
00095   
00096   G4VSolid* bpOuterCylSolid = new G4EllipticalTube(nameIn + "_pipe_inner_ellipsoid",
00097                                                    aper3In + beamPipeThicknessIn,   
00098                                                    aper4In + beamPipeThicknessIn,   
00099                                                    (lengthIn*0.5)-2*lengthSafety);  
00100   
00101   G4VSolid* bpOuterRectSolid = new G4Box(nameIn + "_pipe_inner_box",    
00102                                          aper1In + beamPipeThicknessIn, 
00103                                          aper2In + beamPipeThicknessIn, 
00104                                          lengthIn); 
00105   G4VSolid* bpOuterSolid = new G4IntersectionSolid(nameIn + "_pipe_inner_solid", 
00106                                                    bpOuterCylSolid,              
00107                                                    bpOuterRectSolid);            
00108   
00109   beamPipeSolid = new G4SubtractionSolid(nameIn + "_pipe_solid",  
00110                                          bpOuterSolid,            
00111                                          bpInnerSolid);           
00112   
00113   
00114   G4VSolid* contCylSolid = new G4EllipticalTube(nameIn + "_vacuum_ellipsoid", 
00115                                                 aper3In + beamPipeThicknessIn + lengthSafety, 
00116                                                 aper4In + beamPipeThicknessIn + lengthSafety, 
00117                                                 lengthIn*0.5); 
00118   
00119   G4VSolid* contRectSolid = new G4Box(nameIn + "_vacuum_box",                       
00120                                       aper1In + beamPipeThicknessIn + lengthSafety, 
00121                                       aper2In + beamPipeThicknessIn + lengthSafety, 
00122                                       lengthIn); 
00123   
00124   containerSolid = new G4IntersectionSolid(nameIn + "_vacuum_solid", 
00125                                            contCylSolid,             
00126                                            contRectSolid);           
00127 
00128   G4double width  = aper3In + beamPipeThicknessIn + lengthSafety;
00129   G4double height = aper2In + beamPipeThicknessIn + lengthSafety;
00130 
00131   CreateContainerSubtractionSolid(nameIn, lengthIn, beamPipeThicknessIn, aper1In, aper2In, aper3In, aper4In);
00132   
00133   return CommonFinalConstruction(nameIn, vacuumMaterialIn, beamPipeMaterialIn, lengthIn, width, height);
00134 }
00135 
00136 BDSBeamPipe* BDSBeamPipeFactoryRectEllipse::CreateBeamPipeAngledInOut(G4String    nameIn,              
00137                                                                       G4double    lengthIn,            
00138                                                                       G4double    angleInIn,           
00139                                                                       G4double    angleOutIn,          
00140                                                                       G4double    aper1In,             
00141                                                                       G4double    aper2In,             
00142                                                                       G4double    aper3In,             
00143                                                                       G4double    aper4In,             
00144                                                                       G4Material* vacuumMaterialIn,    
00145                                                                       G4double    beamPipeThicknessIn, 
00146                                                                       G4Material* beamPipeMaterialIn   
00147                                                                       )
00148 {
00149 #ifdef BDSDEBUG
00150   G4cout << __METHOD_NAME__ << G4endl;
00151 #endif
00152   
00153   CleanUp();
00154   
00155    
00156   TestInputParameters(vacuumMaterialIn,beamPipeThicknessIn,beamPipeMaterialIn,aper1In,aper2In,aper3In,aper4In);
00157 
00158   std::pair<G4ThreeVector,G4ThreeVector> faces = CalculateFaces(angleInIn, angleOutIn);
00159   G4ThreeVector inputface  = faces.first;
00160   G4ThreeVector outputface = faces.second;
00161 
00162   G4double width  = std::max(aper1In,aper3In) + beamPipeThicknessIn + lengthSafety;
00163   G4double height = std::max(aper2In,aper4In) + beamPipeThicknessIn + lengthSafety;
00164   
00165   CreateGeneralAngledSolids(nameIn, lengthIn, aper1In, aper2In, aper3In, aper4In, beamPipeThicknessIn, inputface, outputface);
00166   CreateContainerSubtractionSolid(nameIn, lengthIn, beamPipeThicknessIn, aper1In, aper2In, aper3In, aper4In);
00167   
00168   return CommonFinalConstruction(nameIn, vacuumMaterialIn, beamPipeMaterialIn, lengthIn, width, height);
00169 }
00170 
00172 
00174 void BDSBeamPipeFactoryRectEllipse::TestInputParameters(G4Material*&  vacuumMaterialIn,     
00175                                                         G4double&     beamPipeThicknessIn,
00176                                                         G4Material*&  beamPipeMaterialIn,
00177                                                         G4double&     aper1In,
00178                                                         G4double&     aper2In,
00179                                                         G4double&     aper3In,
00180                                                         G4double&     aper4In)
00181 {
00182     BDSBeamPipeFactoryBase::TestInputParameters(vacuumMaterialIn,beamPipeThicknessIn,beamPipeMaterialIn);
00183 
00184   if (aper1In < 1e-10)
00185     {aper1In = BDSGlobalConstants::Instance()->GetBeamPipeRadius();}
00186 
00187   if (aper2In < 1e-10)
00188     {aper2In = BDSGlobalConstants::Instance()->GetAper2();}
00189 
00190   if (aper3In < 1e-10)
00191     {aper3In = BDSGlobalConstants::Instance()->GetAper3();}
00192 
00193   if (aper4In < 1e-10)
00194     {aper4In = BDSGlobalConstants::Instance()->GetAper4();}
00195 }
00196 
00199 BDSBeamPipe* BDSBeamPipeFactoryRectEllipse::CommonFinalConstruction(G4String    nameIn,
00200                                                                     G4Material* vacuumMaterialIn,
00201                                                                     G4Material* beamPipeMaterialIn,
00202                                                                     G4double    lengthIn,
00203                                                                     G4double    containerWidthIn,
00204                                                                     G4double    containerHeightIn)
00205 {
00206 #ifdef BDSDEBUG
00207   G4cout << __METHOD_NAME__ << G4endl;
00208 #endif
00209 
00210   BDSBeamPipeFactoryBase::CommonConstruction(nameIn,
00211                                              vacuumMaterialIn,
00212                                              beamPipeMaterialIn,
00213                                              lengthIn);
00214   
00215   
00216   std::pair<double,double> extX = std::make_pair(-containerWidthIn,containerWidthIn);
00217   std::pair<double,double> extY = std::make_pair(-containerHeightIn,containerHeightIn);
00218   std::pair<double,double> extZ = std::make_pair(-lengthIn*0.5,lengthIn*0.5);
00219   
00220   
00221   return BuildBeamPipeAndRegisterVolumes(extX,extY,extZ,containerWidthIn);
00222 }
00223 
00226 void BDSBeamPipeFactoryRectEllipse::CreateGeneralAngledSolids(G4String      nameIn,
00227                                                               G4double      lengthIn,
00228                                                               G4double      aper1In,
00229                                                               G4double      aper2In,
00230                                                               G4double      aper3In,
00231                                                               G4double      aper4In,
00232                                                               G4double      beamPipeThicknessIn,
00233                                                               G4ThreeVector inputfaceIn,
00234                                                               G4ThreeVector outputfaceIn)
00235 {
00236   
00237   
00238   
00239   
00240   
00241   G4VSolid* vacCylSolid = new G4EllipticalTube(nameIn + "_vacuum_ellipsoid",
00242                                                aper3In,                     
00243                                                aper4In,                     
00244                                                lengthIn); 
00245   
00246   G4VSolid* vacRectSolid = new G4Box(nameIn + "_vacuum_box", 
00247                                      aper1In,                
00248                                      aper2In,                
00249                                      lengthIn); 
00250   
00251   G4VSolid* longVacuumSolid = new G4IntersectionSolid(nameIn + "_vacuum_long_solid", 
00252                                                       vacCylSolid,                   
00253                                                       vacRectSolid);                 
00254   
00255   
00256   G4double angledFaceRadius = (std::max(std::max(aper1In,aper2In),std::max(aper3In,aper4In)) + beamPipeThicknessIn) * 4;
00257   G4VSolid* vacuumAngledSolid = new G4CutTubs(nameIn + "_pipe_angled_faces",     
00258                                               0,                                 
00259                                               angledFaceRadius,                  
00260                                               (lengthIn*0.5) - (2*lengthSafety), 
00261                                               0,                                 
00262                                               CLHEP::twopi,                      
00263                                               inputfaceIn,                       
00264                                               outputfaceIn);                     
00265   vacuumSolid = new G4IntersectionSolid(nameIn + "_vacuum_solid", 
00266                                         longVacuumSolid,          
00267                                         vacuumAngledSolid);       
00268 
00269   
00270   
00271   G4VSolid* bpInnerCylSolid = new G4EllipticalTube(nameIn + "_pipe_inner_ellipsoid", 
00272                                                    aper3In + lengthSafety,          
00273                                                    aper4In + lengthSafety,          
00274                                                    1.5*lengthIn); 
00275   
00276   G4VSolid* bpInnerRectSolid = new G4Box(nameIn + "_pipe_inner_box", 
00277                                          aper1In + lengthSafety,     
00278                                          aper2In + lengthSafety,     
00279                                          1.7*lengthIn); 
00280   
00281   G4VSolid* bpInnerSolid = new G4IntersectionSolid(nameIn + "_pipe_inner_solid", 
00282                                                    bpInnerCylSolid,              
00283                                                    bpInnerRectSolid);            
00284 
00285   
00286   
00287   G4VSolid* bpOuterCylSolid = new G4EllipticalTube(nameIn + "_pipe_inner_ellipsoid", 
00288                                                    aper3In + beamPipeThicknessIn,    
00289                                                    aper4In + beamPipeThicknessIn,    
00290                                                    lengthIn);                        
00291   
00292   G4VSolid* bpOuterRectSolid = new G4Box(nameIn + "_pipe_inner_box",    
00293                                          aper1In + beamPipeThicknessIn, 
00294                                          aper2In + beamPipeThicknessIn, 
00295                                          1.1*lengthIn); 
00296   G4VSolid* bpOuterSolid = new G4IntersectionSolid(nameIn + "_pipe_inner_solid", 
00297                                                    bpOuterCylSolid,              
00298                                                    bpOuterRectSolid);            
00299   
00300   G4VSolid* longBeamPipeSolid = new G4SubtractionSolid(nameIn + "_long_pipe_solid",  
00301                                                        bpOuterSolid,            
00302                                                        bpInnerSolid);           
00303   
00304   beamPipeSolid = new G4IntersectionSolid(nameIn + "_pipe_solid", 
00305                                           longBeamPipeSolid,      
00306                                           vacuumAngledSolid);     
00307 
00308   
00309   
00310   G4VSolid* contCylSolid = new G4EllipticalTube(nameIn + "_vacuum_ellipsoid",                 
00311                                                 aper3In + beamPipeThicknessIn + lengthSafety, 
00312                                                 aper4In + beamPipeThicknessIn + lengthSafety, 
00313                                                 lengthIn*0.5);                                
00314   
00315   G4VSolid* contRectSolid = new G4Box(nameIn + "_vacuum_box", 
00316                                       aper1In + beamPipeThicknessIn + lengthSafety, 
00317                                       aper2In + beamPipeThicknessIn + lengthSafety, 
00318                                       lengthIn); 
00319   
00320   G4VSolid* longContainerSolid = new G4IntersectionSolid(nameIn + "_long_container_solid", 
00321                                                          contCylSolid,                     
00322                                                          contRectSolid);                   
00323 
00324   containerSolid = new G4IntersectionSolid(nameIn + "_container_solid", 
00325                                            longContainerSolid,          
00326                                            vacuumAngledSolid);          
00327 }
00328 
00329 void BDSBeamPipeFactoryRectEllipse::CreateContainerSubtractionSolid(G4String& nameIn,
00330                                                                     G4double& lengthIn,
00331                                                                     G4double& beamPipeThicknessIn,
00332                                                                     G4double& aper1In,
00333                                                                     G4double& aper2In,
00334                                                                     G4double& aper3In,
00335                                                                     G4double& aper4In)
00336 {
00337   
00338   G4VSolid* contSubCylSolid = new G4EllipticalTube(nameIn + "_subtraction_ellipsoid", 
00339                                                    aper3In + beamPipeThicknessIn + lengthSafety, 
00340                                                    aper4In + beamPipeThicknessIn + lengthSafety, 
00341                                                    2*lengthIn);                  
00342   
00343   G4VSolid* contSubRectSolid = new G4Box(nameIn + "_subtraction_box",                  
00344                                          aper1In + beamPipeThicknessIn + lengthSafety, 
00345                                          aper2In + beamPipeThicknessIn + lengthSafety, 
00346                                          1.7*lengthIn); 
00347   
00348   containerSubtractionSolid = new G4IntersectionSolid(nameIn + "_subtraction_solid", 
00349                                                       contSubCylSolid,               
00350                                                       contSubRectSolid);             
00351 }