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

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"                      // geant4 globals / types
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>                         // for std::pair
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,              // name
00044                                                            G4double    lengthIn,            // length [mm]
00045                                                            G4double    aper1In,             // rect half width
00046                                                            G4double    aper2In,             // rect half height
00047                                                            G4double    aper3In,             // radius of circle
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,aper3In,aper4In);
00062 
00063   // build the solids
00064   //vacuum cylindrical solid (circular cross-section)
00065   G4VSolid* vacCylSolid = new G4EllipticalTube(nameIn + "_vacuum_ellipsoid", // name
00066                                                aper3In,                      // horizontal semi-axis
00067                                                aper4In,                      // vertical semi-axis
00068                                                lengthIn*0.5-2*lengthSafety); // half length
00069   //vacuum box solid (rectangular cross-section)
00070   G4VSolid* vacRectSolid = new G4Box(nameIn + "_vacuum_box", // name
00071                                      aper1In,                // x half width
00072                                      aper2In,                // y half width
00073                                      lengthIn); // z full width (long for unambiguous intersection)
00074   //intersection of both of these gives the desired shape
00075   vacuumSolid = new G4IntersectionSolid(nameIn + "_vacuum_solid", // name
00076                                         vacCylSolid,              // solid 1
00077                                         vacRectSolid);            // solid 2
00078 
00079   //beampipe solid
00080   //beampipe inner edge for subtraction (actually just like vacuum + lengthSafety)
00081   G4VSolid* bpInnerCylSolid = new G4EllipticalTube(nameIn + "_pipe_inner_ellipsoid",// name
00082                                                    aper3In + lengthSafety,          // horizontal semi-axis
00083                                                    aper4In + lengthSafety,          // vertical semi-axis
00084                                                    1.5*lengthIn); // length big for unambiguous subtraction (but < outerlength)
00085   //beampipe inner edge box solid (rectangular cross-section)
00086   G4VSolid* bpInnerRectSolid = new G4Box(nameIn + "_pipe_inner_box", // name
00087                                          aper1In + lengthSafety,     // x half width
00088                                          aper2In + lengthSafety,     // y half width
00089                                          1.7*lengthIn); // z long for unambiguous intersection
00090   //beampipe inner intersection - 1.5*length long which is > half length for unambiguous subtraction later
00091   G4VSolid* bpInnerSolid = new G4IntersectionSolid(nameIn + "_pipe_inner_solid", // name
00092                                                    bpInnerCylSolid,              // solid 1
00093                                                    bpInnerRectSolid);            // solid 2
00094 
00095   //beampipe outer edge for subtraction (actually just like vacuum + lengthSafety)x
00096   G4VSolid* bpOuterCylSolid = new G4EllipticalTube(nameIn + "_pipe_inner_ellipsoid",// name
00097                                                    aper3In + beamPipeThicknessIn,   // horizontal semi-axis
00098                                                    aper4In + beamPipeThicknessIn,   // hotizontal semi-axis
00099                                                    (lengthIn*0.5)-2*lengthSafety);  // half length
00100   //beampipe outer edge box solid (rectangular cross-section)
00101   G4VSolid* bpOuterRectSolid = new G4Box(nameIn + "_pipe_inner_box",    // name
00102                                          aper1In + beamPipeThicknessIn, // x half width
00103                                          aper2In + beamPipeThicknessIn, // y half width
00104                                          lengthIn); // z full width (long for unambiguous intersection)
00105   G4VSolid* bpOuterSolid = new G4IntersectionSolid(nameIn + "_pipe_inner_solid", // name
00106                                                    bpOuterCylSolid,              // solid 1
00107                                                    bpOuterRectSolid);            // solid 2
00108   //beampipe final subtraction between outer and inner edge
00109   beamPipeSolid = new G4SubtractionSolid(nameIn + "_pipe_solid",  // name
00110                                          bpOuterSolid,            // this
00111                                          bpInnerSolid);           // minus this
00112   
00113   //container cylindrical solid (circular cross-section)
00114   G4VSolid* contCylSolid = new G4EllipticalTube(nameIn + "_vacuum_ellipsoid", // name
00115                                                 aper3In + beamPipeThicknessIn + lengthSafety, // horizontal semi-axis
00116                                                 aper4In + beamPipeThicknessIn + lengthSafety, // vertical semi-axis
00117                                                 lengthIn*0.5); // half length
00118   //vacuum box solid (rectangular cross-section)
00119   G4VSolid* contRectSolid = new G4Box(nameIn + "_vacuum_box",                       // name
00120                                       aper1In + beamPipeThicknessIn + lengthSafety, // x half width
00121                                       aper2In + beamPipeThicknessIn + lengthSafety, // y half width
00122                                       lengthIn); // z full width (long for unambiguous intersection)
00123   //intersection of both of these gives the desired shape
00124   containerSolid = new G4IntersectionSolid(nameIn + "_vacuum_solid", // name
00125                                            contCylSolid,             // solid 1
00126                                            contRectSolid);           // solid 2
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,              // name
00137                                                                       G4double    lengthIn,            // length [mm]
00138                                                                       G4double    angleInIn,           // the normal angle of the input face
00139                                                                       G4double    angleOutIn,          // the normal angle of the input face
00140                                                                       G4double    aper1In,             // aperture parameter 1
00141                                                                       G4double    aper2In,             // aperture parameter 2
00142                                                                       G4double    aper3In,             // aperture parameter 3
00143                                                                       G4double    aper4In,             // aperture parameter 4
00144                                                                       G4Material* vacuumMaterialIn,    // vacuum material
00145                                                                       G4double    beamPipeThicknessIn, // beampipe thickness [mm]
00146                                                                       G4Material* beamPipeMaterialIn   // beampipe material
00147                                                                       )
00148 {
00149 #ifdef BDSDEBUG
00150   G4cout << __METHOD_NAME__ << G4endl;
00151 #endif
00152   // clean up after last usage
00153   CleanUp();
00154   
00155    // test input parameters - set global options as default if not specified
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,     // reference to a pointer
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   // record extents
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   // build the BDSBeamPipe instance and return it
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   // build the solids
00237   // we can get the rectangular ellipse as in the straight case with the intersection of
00238   // an elliptical tube (always solid) and then we can use another intersection solid
00239   // with a larger (wider and taller) G4CutTubs to get the angled faces.
00240   //vacuum cylindrical solid (circular cross-section)
00241   G4VSolid* vacCylSolid = new G4EllipticalTube(nameIn + "_vacuum_ellipsoid",// name
00242                                                aper3In,                     // horizontal semi-axis
00243                                                aper4In,                     // vertical semi-axis
00244                                                lengthIn); // z full width (long for unambiguous intersection)
00245   //vacuum box solid (rectangular cross-section)
00246   G4VSolid* vacRectSolid = new G4Box(nameIn + "_vacuum_box", // name
00247                                      aper1In,                // x half width
00248                                      aper2In,                // y half width
00249                                      lengthIn); // z full width (long for unambiguous intersection)
00250   //intersection of both of these gives the desired shape
00251   G4VSolid* longVacuumSolid = new G4IntersectionSolid(nameIn + "_vacuum_long_solid", // name
00252                                                       vacCylSolid,                   // solid 1
00253                                                       vacRectSolid);                 // solid 2
00254   //prepare angled face large cylinder for intersection get angled faces
00255   //we can actually use this for the beampipe too later on - whew
00256   G4double angledFaceRadius = (std::max(std::max(aper1In,aper2In),std::max(aper3In,aper4In)) + beamPipeThicknessIn) * 4;
00257   G4VSolid* vacuumAngledSolid = new G4CutTubs(nameIn + "_pipe_angled_faces",     // name
00258                                               0,                                 // inner radius
00259                                               angledFaceRadius,                  // outer radius
00260                                               (lengthIn*0.5) - (2*lengthSafety), // accurate length
00261                                               0,                                 // rotation start angle
00262                                               CLHEP::twopi,                      // rotation sweep angle
00263                                               inputfaceIn,                       // input face normal
00264                                               outputfaceIn);                     // output face normal
00265   vacuumSolid = new G4IntersectionSolid(nameIn + "_vacuum_solid", // name
00266                                         longVacuumSolid,          // solid 1
00267                                         vacuumAngledSolid);       // solid 2
00268 
00269   //beampipe cylindrical solid (circular cross-section)
00270   //beampipe inner edge for subtraction (actually just like vacuum + lengthSafety)x
00271   G4VSolid* bpInnerCylSolid = new G4EllipticalTube(nameIn + "_pipe_inner_ellipsoid", // name
00272                                                    aper3In + lengthSafety,          // horizontal semi-axis
00273                                                    aper4In + lengthSafety,          // vertical semi-axis
00274                                                    1.5*lengthIn); // length big for unambiguous subtraction (but < outerlength)
00275   //beampipe inner edge box solid (rectangular cross-section)
00276   G4VSolid* bpInnerRectSolid = new G4Box(nameIn + "_pipe_inner_box", // name
00277                                          aper1In + lengthSafety,     // x half width
00278                                          aper2In + lengthSafety,     // y half width
00279                                          1.7*lengthIn); // z long for unambiguous intersection
00280   //beampipe inner intersection - 1.5*length long which is > half length for unambiguous subtraction later
00281   G4VSolid* bpInnerSolid = new G4IntersectionSolid(nameIn + "_pipe_inner_solid", // name
00282                                                    bpInnerCylSolid,              // solid 1
00283                                                    bpInnerRectSolid);            // solid 2
00284 
00285   //beampipe outer edge for subtraction (actually just like vacuum + lengthSafety)
00286   //this length should be less than bpInnerSolid above but longer than the actual length for later intersection
00287   G4VSolid* bpOuterCylSolid = new G4EllipticalTube(nameIn + "_pipe_inner_ellipsoid", // name
00288                                                    aper3In + beamPipeThicknessIn,    // horizontal semi-axis
00289                                                    aper4In + beamPipeThicknessIn,    // vertical semi-axis
00290                                                    lengthIn);                        // length
00291   //beampipe outer edge box solid (rectangular cross-section)
00292   G4VSolid* bpOuterRectSolid = new G4Box(nameIn + "_pipe_inner_box",    // name
00293                                          aper1In + beamPipeThicknessIn, // x half width
00294                                          aper2In + beamPipeThicknessIn, // y half width
00295                                          1.1*lengthIn); // z full width (long for unambiguous intersection)
00296   G4VSolid* bpOuterSolid = new G4IntersectionSolid(nameIn + "_pipe_inner_solid", // name
00297                                                    bpOuterCylSolid,              // solid 1
00298                                                    bpOuterRectSolid);            // solid 2
00299   //correct solid shape but too long
00300   G4VSolid* longBeamPipeSolid = new G4SubtractionSolid(nameIn + "_long_pipe_solid",  // name
00301                                                        bpOuterSolid,            // this
00302                                                        bpInnerSolid);           // minus this
00303   //final beampipe solid with correct shape and angled faces
00304   beamPipeSolid = new G4IntersectionSolid(nameIn + "_pipe_solid", // name
00305                                           longBeamPipeSolid,      // solid1
00306                                           vacuumAngledSolid);     // solid2
00307 
00308   //container solid
00309   //container cylindrical solid (circular cross-section)
00310   G4VSolid* contCylSolid = new G4EllipticalTube(nameIn + "_vacuum_ellipsoid",                 // name
00311                                                 aper3In + beamPipeThicknessIn + lengthSafety, // horizontal semi-axis
00312                                                 aper4In + beamPipeThicknessIn + lengthSafety, // vertical semi-axis
00313                                                 lengthIn*0.5);                                // half length
00314   //vacuum box solid (rectangular cross-section)
00315   G4VSolid* contRectSolid = new G4Box(nameIn + "_vacuum_box", // name
00316                                       aper1In + beamPipeThicknessIn + lengthSafety, // x half width
00317                                       aper2In + beamPipeThicknessIn + lengthSafety, // y half width
00318                                       lengthIn); // z full width (long for unambiguous intersection)
00319   //intersection of both of these gives the desired shape
00320   G4VSolid* longContainerSolid = new G4IntersectionSolid(nameIn + "_long_container_solid", // name
00321                                                          contCylSolid,                     // solid 1
00322                                                          contRectSolid);                   // solid 2
00323 
00324   containerSolid = new G4IntersectionSolid(nameIn + "_container_solid", // name
00325                                            longContainerSolid,          // solid 1
00326                                            vacuumAngledSolid);          // solid 2
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   //container cylindrical solid (circular cross-section)
00338   G4VSolid* contSubCylSolid = new G4EllipticalTube(nameIn + "_subtraction_ellipsoid", // name
00339                                                    aper3In + beamPipeThicknessIn + lengthSafety, // horizontal semi-axis
00340                                                    aper4In + beamPipeThicknessIn + lengthSafety, // vertical semi-axis
00341                                                    2*lengthIn);                  // long length for unambiguous subtraction
00342   //vacuum box solid (rectangular cross-section)
00343   G4VSolid* contSubRectSolid = new G4Box(nameIn + "_subtraction_box",                  // name
00344                                          aper1In + beamPipeThicknessIn + lengthSafety, // x half width
00345                                          aper2In + beamPipeThicknessIn + lengthSafety, // y half width
00346                                          1.7*lengthIn); // z full width (long for unambiguous intersection)
00347   //intersection of both of these gives the desired shape
00348   containerSubtractionSolid = new G4IntersectionSolid(nameIn + "_subtraction_solid", // name
00349                                                       contSubCylSolid,               // solid 1
00350                                                       contSubRectSolid);             // solid 2
00351 }

Generated on 28 Jun 2015 for BDSIM by  doxygen 1.4.7