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"
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>
00022 #include <utility>
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,
00044 G4double lengthIn,
00045 G4double aper1In,
00046 G4double aper2In,
00047 G4double ,
00048 G4double ,
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);
00062
00063
00064 vacuumSolid = new G4Box(nameIn + "_vacuum_solid",
00065 aper1In,
00066 aper2In,
00067 (lengthIn*0.5)-2*lengthSafety);
00068
00069 G4VSolid* beamPipeSolidInner;
00070 G4VSolid* beamPipeSolidOuter;
00071
00072
00073 beamPipeSolidInner = new G4Box(nameIn + "_pipe_solid_inner",
00074 aper1In + lengthSafety,
00075 aper2In + lengthSafety,
00076 lengthIn);
00077
00078
00079 beamPipeSolidOuter = new G4Box(nameIn + "_pipe_solid_outer",
00080 aper1In + beamPipeThicknessIn,
00081 aper2In + beamPipeThicknessIn,
00082 (lengthIn*0.5)-2*lengthSafety);
00083 beamPipeSolid = new G4SubtractionSolid(nameIn + "_pipe_solid",
00084 beamPipeSolidOuter,
00085 beamPipeSolidInner);
00086
00087 G4double containerXHalfWidth = aper1In + beamPipeThicknessIn + lengthSafety;
00088 G4double containerYHalfWidth = aper2In + beamPipeThicknessIn + lengthSafety;
00089 containerSolid = new G4Box(nameIn + "_container_solid",
00090 containerXHalfWidth,
00091 containerYHalfWidth,
00092 (lengthIn*0.5)-lengthSafety);
00093
00094 return CommonFinalConstruction(nameIn, vacuumMaterialIn, beamPipeMaterialIn, lengthIn, aper1In, aper2In, beamPipeThicknessIn);
00095 }
00096
00097 BDSBeamPipe* BDSBeamPipeFactoryRectangular::CreateBeamPipeAngledInOut(G4String nameIn,
00098 G4double lengthIn,
00099 G4double angleInIn,
00100 G4double angleOutIn,
00101 G4double aper1In,
00102 G4double aper2In,
00103 G4double ,
00104 G4double ,
00105 G4Material* vacuumMaterialIn,
00106 G4double beamPipeThicknessIn,
00107 G4Material* beamPipeMaterialIn
00108 )
00109 {
00110 #ifdef BDSDEBUG
00111 G4cout << __METHOD_NAME__ << G4endl;
00112 #endif
00113
00114 CleanUp();
00115
00116
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,
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
00160 G4double containerXHalfWidth = aper1In + beamPipeThicknessIn + lengthSafety;
00161 G4double containerYHalfWidth = aper2In + beamPipeThicknessIn + lengthSafety;
00162
00163 containerSubtractionSolid = new G4Box(nameIn + "_container_solid",
00164 containerXHalfWidth,
00165 containerYHalfWidth,
00166 lengthIn);
00167
00168 BDSBeamPipeFactoryBase::CommonConstruction(nameIn,
00169 vacuumMaterialIn,
00170 beamPipeMaterialIn,
00171 lengthIn);
00172
00173
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
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
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 G4VSolid* vacuumSolidLong;
00207 G4VSolid* beamPipeSolidLong;
00208 G4VSolid* angledFaceSolid;
00209 G4VSolid* containerSolidLong;
00210 G4VSolid* angledFaceSolidContainer;
00211
00212
00213 G4double angledFaceRadius = (std::max(aper1In,aper2In) + beamPipeThicknessIn)*2.0;
00214 angledFaceSolid = new G4CutTubs(nameIn + "_angled_face",
00215 0,
00216 angledFaceRadius,
00217 (lengthIn*0.5)-2*lengthSafety,
00218 0,
00219 CLHEP::twopi,
00220 inputfaceIn,
00221 outputfaceIn);
00222
00223 vacuumSolidLong = new G4Box(nameIn + "_vacuum_solid_long",
00224 aper1In,
00225 aper2In,
00226 lengthIn);
00227 vacuumSolid = new G4IntersectionSolid(nameIn + "_vacuum_solid",
00228 vacuumSolidLong,
00229 angledFaceSolid);
00230
00231 G4VSolid* beamPipeSolidInner;
00232 G4VSolid* beamPipeSolidOuter;
00233
00234
00235 beamPipeSolidInner = new G4Box(nameIn + "_pipe_solid_inner",
00236 aper1In + lengthSafety,
00237 aper2In + lengthSafety,
00238 2*lengthIn);
00239
00240
00241 beamPipeSolidOuter = new G4Box(nameIn + "_pipe_solid_outer",
00242 aper1In + beamPipeThicknessIn,
00243 aper2In + beamPipeThicknessIn,
00244 lengthIn);
00245 beamPipeSolidLong = new G4SubtractionSolid(nameIn + "_pipe_solid_long",
00246 beamPipeSolidOuter,
00247 beamPipeSolidInner);
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",
00255 containerXHalfWidth,
00256 containerYHalfWidth,
00257 lengthIn);
00258 angledFaceSolidContainer = new G4CutTubs(nameIn + "_angled_face_container",
00259 0,
00260 angledFaceRadius,
00261 (lengthIn*0.5)-lengthSafety,
00262 0,
00263 CLHEP::twopi,
00264 inputfaceIn,
00265 outputfaceIn);
00266 containerSolid = new G4IntersectionSolid(nameIn + "_container_solid",
00267 containerSolidLong,
00268 angledFaceSolidContainer);
00269 }