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 }