/scratch0/jsnuveri/BDSIM/BDSIMgit/bdsim/src/BDSBeamPipeFactoryRectangular.cc

00001 #include "BDSBeamPipeFactoryBase.hh"
00002 #include "BDSBeamPipeFactoryRectangular.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"                 // geant4 globals / types
00011 #include "G4Box.hh"
00012 #include "G4CutTubs.hh"
00013 #include "G4IntersectionSolid.hh"
00014 #include "G4LogicalVolume.hh"
00015 #include "G4Material.hh"
00016 #include "G4SubtractionSolid.hh"
00017 #include "G4ThreeVector.hh"
00018 #include "G4Tubs.hh"
00019 #include "G4VSolid.hh"
00020 
00021 #include <cmath>                           // sin, cos, fabs
00022 #include <utility>                         // for std::pair
00023 
00024 
00025 BDSBeamPipeFactoryRectangular* BDSBeamPipeFactoryRectangular::_instance = 0;
00026 
00027 BDSBeamPipeFactoryRectangular* BDSBeamPipeFactoryRectangular::Instance()
00028 {
00029   if (_instance == 0)
00030     {_instance = new BDSBeamPipeFactoryRectangular();}
00031   return _instance;
00032 }
00033 
00034 BDSBeamPipeFactoryRectangular::BDSBeamPipeFactoryRectangular():BDSBeamPipeFactoryBase()
00035 {
00036 }
00037 
00038 BDSBeamPipeFactoryRectangular::~BDSBeamPipeFactoryRectangular()
00039 {
00040   _instance = 0;
00041 }
00042 
00043 BDSBeamPipe* BDSBeamPipeFactoryRectangular::CreateBeamPipe(G4String    nameIn,              // name
00044                                                            G4double    lengthIn,            // length [mm]
00045                                                            G4double    aper1In,             // aperture parameter 1
00046                                                            G4double    aper2In,             // aperture parameter 2
00047                                                            G4double    /*aper3In*/,         // aperture parameter 3
00048                                                            G4double    /*aper4In*/,         // aperture parameter 4
00049                                                            G4Material* vacuumMaterialIn,    // vacuum material
00050                                                            G4double    beamPipeThicknessIn, // beampipe thickness [mm]
00051                                                            G4Material* beamPipeMaterialIn   // beampipe material
00052                                                            )
00053 {
00054 #ifdef BDSDEBUG
00055   G4cout << __METHOD_NAME__ << G4endl;
00056 #endif
00057   // clean up after last usage
00058   CleanUp();
00059   
00060   // test input parameters - set global options as default if not specified
00061   TestInputParameters(vacuumMaterialIn,beamPipeThicknessIn,beamPipeMaterialIn,aper1In,aper2In);
00062 
00063   // build the solids
00064   vacuumSolid   = new G4Box(nameIn + "_vacuum_solid",       // name
00065                             aper1In,                        // x half width
00066                             aper2In,                        // y half width
00067                             (lengthIn*0.5)-2*lengthSafety); // half length
00068 
00069   G4VSolid* beamPipeSolidInner; // construct rectangular beam pipe by subtracting an inner
00070   G4VSolid* beamPipeSolidOuter; // box from an outer one - only way
00071   // beamPipeSolidInner will be the inner edge of the metal beampipe
00072   // therefore it has to be the width of the aperture + lengthSafety
00073   beamPipeSolidInner = new G4Box(nameIn + "_pipe_solid_inner",   // name
00074                                  aper1In + lengthSafety,         // x half width - length safety to avoid overlaps
00075                                  aper2In + lengthSafety,         // y half width
00076                                  lengthIn);                      // length - full length fo unambiguous subtraction
00077   // beamPipeSolidOuter will be the outer edge of the metal beampipe
00078   // therefore it has to be the width of the aperture + beampipeThickness
00079   beamPipeSolidOuter = new G4Box(nameIn + "_pipe_solid_outer",   // name
00080                                  aper1In + beamPipeThicknessIn,  // x half width
00081                                  aper2In + beamPipeThicknessIn,  // y half width
00082                                  (lengthIn*0.5)-2*lengthSafety); // half length - lengthSafety to fit in container
00083   beamPipeSolid = new G4SubtractionSolid(nameIn + "_pipe_solid",
00084                                          beamPipeSolidOuter,
00085                                          beamPipeSolidInner); // outer minus inner
00086   
00087   G4double containerXHalfWidth = aper1In + beamPipeThicknessIn + lengthSafety;
00088   G4double containerYHalfWidth = aper2In + beamPipeThicknessIn + lengthSafety;
00089   containerSolid = new G4Box(nameIn  + "_container_solid",  // name
00090                              containerXHalfWidth,           // x half width
00091                              containerYHalfWidth,           // y half width
00092                              (lengthIn*0.5)-lengthSafety);  // half length
00093                                         
00094   return CommonFinalConstruction(nameIn, vacuumMaterialIn, beamPipeMaterialIn, lengthIn, aper1In, aper2In, beamPipeThicknessIn);
00095 }
00096 
00097 BDSBeamPipe* BDSBeamPipeFactoryRectangular::CreateBeamPipeAngledInOut(G4String    nameIn,              // name
00098                                                                       G4double    lengthIn,            // length [mm]
00099                                                                       G4double    angleInIn,           // the normal angle of the input face
00100                                                                       G4double    angleOutIn,          // the normal angle of the input face
00101                                                                       G4double    aper1In,             // aperture parameter 1
00102                                                                       G4double    aper2In,             // aperture parameter 2
00103                                                                       G4double    /*aper3In*/,         // aperture parameter 3
00104                                                                       G4double    /*aper4In */,        // aperture parameter 4
00105                                                                       G4Material* vacuumMaterialIn,    // vacuum material
00106                                                                       G4double    beamPipeThicknessIn, // beampipe thickness [mm]
00107                                                                       G4Material* beamPipeMaterialIn   // beampipe material
00108                                                                       )
00109 {
00110 #ifdef BDSDEBUG
00111   G4cout << __METHOD_NAME__ << G4endl;
00112 #endif
00113   // clean up after last usage
00114   CleanUp();
00115   
00116    // test input parameters - set global options as default if not specified
00117   TestInputParameters(vacuumMaterialIn,beamPipeThicknessIn,beamPipeMaterialIn,aper1In,aper2In);
00118 
00119   std::pair<G4ThreeVector,G4ThreeVector> faces = CalculateFaces(angleInIn, angleOutIn);
00120   G4ThreeVector inputface  = faces.first;
00121   G4ThreeVector outputface = faces.second;
00122 
00123   CreateGeneralAngledSolids(nameIn, lengthIn, aper1In, aper2In, beamPipeThicknessIn, inputface, outputface);
00124   
00125   return CommonFinalConstruction(nameIn, vacuumMaterialIn, beamPipeMaterialIn, lengthIn, aper1In, aper2In, beamPipeThicknessIn);
00126 }
00127 
00129 
00131 void BDSBeamPipeFactoryRectangular::TestInputParameters(G4Material*&  vacuumMaterialIn,     // reference to a pointer
00132                                                         G4double&     beamPipeThicknessIn,
00133                                                         G4Material*&  beamPipeMaterialIn,
00134                                                         G4double&     aper1In,
00135                                                         G4double&     aper2In)
00136 {
00137   BDSBeamPipeFactoryBase::TestInputParameters(vacuumMaterialIn,beamPipeThicknessIn,beamPipeMaterialIn);
00138 
00139   if (aper1In < 1e-10)
00140     {aper1In = BDSGlobalConstants::Instance()->GetBeamPipeRadius();}
00141 
00142   if (aper2In < 1e-10)
00143     {aper2In = BDSGlobalConstants::Instance()->GetBeamPipeRadius();}
00144 }
00145 
00148 BDSBeamPipe* BDSBeamPipeFactoryRectangular::CommonFinalConstruction(G4String    nameIn,
00149                                                                     G4Material* vacuumMaterialIn,
00150                                                                     G4Material* beamPipeMaterialIn,
00151                                                                     G4double    lengthIn,
00152                                                                     G4double    aper1In,
00153                                                                     G4double    aper2In,
00154                                                                     G4double    beamPipeThicknessIn)
00155 {
00156 #ifdef BDSDEBUG
00157   G4cout << __METHOD_NAME__ << G4endl;
00158 #endif
00159   // prepare a longer container subtraction solid
00160   G4double containerXHalfWidth = aper1In + beamPipeThicknessIn + lengthSafety;
00161   G4double containerYHalfWidth = aper2In + beamPipeThicknessIn + lengthSafety;
00162   // doesn't have to be angled as it's only used for transverse subtraction
00163   containerSubtractionSolid = new G4Box(nameIn  + "_container_solid", // name
00164                                         containerXHalfWidth,          // x half width
00165                                         containerYHalfWidth,          // y half width
00166                                         lengthIn);                    // full length for unambiguous subtraction
00167 
00168   BDSBeamPipeFactoryBase::CommonConstruction(nameIn,
00169                                              vacuumMaterialIn,
00170                                              beamPipeMaterialIn,
00171                                              lengthIn);
00172   
00173   // record extents
00174   std::pair<double,double> extX = std::make_pair(-containerXHalfWidth,containerXHalfWidth);
00175   std::pair<double,double> extY = std::make_pair(-containerYHalfWidth,containerYHalfWidth);
00176   std::pair<double,double> extZ = std::make_pair(-lengthIn*0.5,lengthIn*0.5);
00177   // calculate radius if a tube were to be place around it
00178   G4double containerRadius = sqrt(containerXHalfWidth*containerXHalfWidth + containerYHalfWidth*containerYHalfWidth);
00179 
00180   BDSBeamPipe* aPipe = BuildBeamPipeAndRegisterVolumes(extX,extY,extZ,containerRadius);
00181 
00182   return aPipe;
00183 }
00184 
00185 
00188 void BDSBeamPipeFactoryRectangular::CreateGeneralAngledSolids(G4String      nameIn,
00189                                                               G4double      lengthIn,
00190                                                               G4double      aper1In,
00191                                                               G4double      aper2In,
00192                                                               G4double      beamPipeThicknessIn,
00193                                                               G4ThreeVector inputfaceIn,
00194                                                               G4ThreeVector outputfaceIn)
00195 {
00196   // this function will make a longer normal rectangular beampipe and chop it off
00197   // to make angled faces as required
00198   // achieve this using the intersection of the normal beampipe (but a little longer)
00199   // with a large G4CutTubs to get the angled faces.
00200   // note even if one face is flat, we don't save a boolean operation as the intersection
00201   // can be on both sides using a G4CutTubs.  Also, keeping one side flat would require
00202   // shifting the volume from 0 which causes headaches later with SDs.
00203 
00204   // build the solids - vacuum, beampipe and container solids
00205   // extra solids required for booleans
00206   G4VSolid* vacuumSolidLong;
00207   G4VSolid* beamPipeSolidLong;
00208   G4VSolid* angledFaceSolid;
00209   G4VSolid* containerSolidLong;
00210   G4VSolid* angledFaceSolidContainer;
00211 
00212   // build the solid with angled faces for intersection
00213   G4double angledFaceRadius = (std::max(aper1In,aper2In) + beamPipeThicknessIn)*2.0; //huge for unambiguous intersection
00214   angledFaceSolid = new G4CutTubs(nameIn + "_angled_face",       // name
00215                                   0,                             // inner radius
00216                                   angledFaceRadius,              // outer radius
00217                                   (lengthIn*0.5)-2*lengthSafety, // half length - must fit within container
00218                                   0,                             // rotation start angle
00219                                   CLHEP::twopi,                  // rotation sweep angle
00220                                   inputfaceIn,                   // input face normal
00221                                   outputfaceIn);                 // output face normal
00222   
00223   vacuumSolidLong = new G4Box(nameIn + "_vacuum_solid_long", // name
00224                               aper1In,                       // x half width
00225                               aper2In,                       // y half width
00226                               lengthIn);                     // full length for unambiguous boolean
00227   vacuumSolid     = new G4IntersectionSolid(nameIn + "_vacuum_solid",
00228                                             vacuumSolidLong,
00229                                             angledFaceSolid);
00230   
00231   G4VSolid* beamPipeSolidInner; // construct rectangular beam pipe by subtracting an inner
00232   G4VSolid* beamPipeSolidOuter; // box from an outer one - only way
00233   // beamPipeSolidInner will be the inner edge of the metal beampipe
00234   // therefore it has to be the width of the aperture + lengthSafety
00235   beamPipeSolidInner = new G4Box(nameIn + "_pipe_solid_inner",   // name
00236                                  aper1In + lengthSafety,         // x half width - length safety to avoid overlaps
00237                                  aper2In + lengthSafety,         // y half width
00238                                  2*lengthIn);                    // 2*length - full length fo unambiguous subtraction
00239   // beamPipeSolidOuter will be the outer edge of the metal beampipe
00240   // therefore it has to be the width of the aperture + beampipeThickness
00241   beamPipeSolidOuter = new G4Box(nameIn + "_pipe_solid_outer",   // name
00242                                  aper1In + beamPipeThicknessIn,  // x half width
00243                                  aper2In + beamPipeThicknessIn,  // y half width
00244                                  lengthIn);                      // full length for unambiguous intersection
00245   beamPipeSolidLong = new G4SubtractionSolid(nameIn + "_pipe_solid_long",
00246                                          beamPipeSolidOuter,
00247                                          beamPipeSolidInner); // outer minus inner
00248   beamPipeSolid = new G4IntersectionSolid(nameIn + "_pipe_solid",
00249                                           beamPipeSolidLong,
00250                                           angledFaceSolid);
00251   
00252   G4double containerXHalfWidth = aper1In + beamPipeThicknessIn + lengthSafety;
00253   G4double containerYHalfWidth = aper2In + beamPipeThicknessIn + lengthSafety;
00254   containerSolidLong = new G4Box(nameIn  + "_container_solid_long",// name
00255                                  containerXHalfWidth,              // x half width
00256                                  containerYHalfWidth,              // y half width
00257                                  lengthIn);                        // full length for unambiguous intersection
00258   angledFaceSolidContainer = new G4CutTubs(nameIn + "_angled_face_container",// name
00259                                            0,                                // inner radius
00260                                            angledFaceRadius,                 // outer radius
00261                                            (lengthIn*0.5)-lengthSafety,      // half length - must fit within magnet
00262                                            0,                                // rotation start angle
00263                                            CLHEP::twopi,                     // rotation finish angle
00264                                            inputfaceIn,                      // input face normal
00265                                            outputfaceIn);                    // output face normal
00266   containerSolid = new G4IntersectionSolid(nameIn + "_container_solid",
00267                                            containerSolidLong,
00268                                            angledFaceSolidContainer);
00269 }

Generated on 28 Jun 2015 for BDSIM by  doxygen 1.4.7