00001 #include "BDSBeamPipeFactoryBase.hh"
00002 #include "BDSBeamPipeFactoryLHCDetailed.hh"
00003 #include "BDSBeamPipe.hh"
00004
00005 #include "BDSDebug.hh"
00006 #include "BDSExecOptions.hh"
00007 #include "BDSGlobalConstants.hh"
00008 #include "BDSMaterials.hh"
00009 #include "BDSSDManager.hh"
00010
00011 #include "globals.hh"
00012 #include "G4Box.hh"
00013 #include "G4Colour.hh"
00014 #include "G4CutTubs.hh"
00015 #include "G4IntersectionSolid.hh"
00016 #include "G4LogicalVolume.hh"
00017 #include "G4Material.hh"
00018 #include "G4PVPlacement.hh"
00019 #include "G4SubtractionSolid.hh"
00020 #include "G4ThreeVector.hh"
00021 #include "G4Tubs.hh"
00022 #include "G4VisAttributes.hh"
00023 #include "G4VSolid.hh"
00024
00025 #include <cmath>
00026 #include <utility>
00027
00028
00029 BDSBeamPipeFactoryLHCDetailed* BDSBeamPipeFactoryLHCDetailed::_instance = 0;
00030
00031 BDSBeamPipeFactoryLHCDetailed* BDSBeamPipeFactoryLHCDetailed::Instance()
00032 {
00033 if (_instance == 0)
00034 {_instance = new BDSBeamPipeFactoryLHCDetailed();}
00035 return _instance;
00036 }
00037
00038 BDSBeamPipeFactoryLHCDetailed::BDSBeamPipeFactoryLHCDetailed():BDSBeamPipeFactoryBase()
00039 {
00040 coldBoreThickness = 1.5*CLHEP::mm;
00041 coolingPipeThickness = 0.53*CLHEP::mm;
00042 coolingPipeRadius = 3.7*CLHEP::mm*0.5;
00043 coolingPipeYOffset = 0.0;
00044 copperSkinThickness = 75*CLHEP::um;
00045 CleanUp();
00046 }
00047
00048 BDSBeamPipeFactoryLHCDetailed::~BDSBeamPipeFactoryLHCDetailed()
00049 {
00050 _instance = 0;
00051 }
00052
00053 void BDSBeamPipeFactoryLHCDetailed::CleanUp()
00054 {
00055 BDSBeamPipeFactoryBase::CleanUp();
00056 copperSkinSolid = NULL;
00057 screenSolid = NULL;
00058 coolingPipeSolid = NULL;
00059 copperSkinLV = NULL;
00060 screenLV = NULL;
00061 coolingPipeLV = NULL;
00062
00063 InitialiseGeometricalParameters();
00064 }
00065
00066 void BDSBeamPipeFactoryLHCDetailed::InitialiseGeometricalParameters()
00067 {
00068 vacRadius = 0, vacBoxX = 0, vacBoxY = 0;
00069
00070 cuInnerRadius = 0, cuInnerBoxX = 0, cuInnerBoxY = 0;
00071 cuOuterRadius = 0, cuOuterBoxX = 0, cuOuterBoxY = 0;
00072
00073 bsInnerRadius = 0, bsInnerBoxX = 0, bsInnerBoxY = 0;
00074 bsOuterRadius = 0, bsOuterBoxX = 0, bsOuterBoxY = 0;
00075
00076 cbInnerRadius = 0, cbOuterRadius = 0;
00077
00078 containerRadius = 0;
00079
00080 vacHalfLength = 0;
00081 halfLength = 0;
00082
00083 coolingPipeYOffset = 0;
00084 }
00085
00086
00087 G4double BDSBeamPipeFactoryLHCDetailed::GetFullWidthOfCoolingPipe()
00088 {
00089 return coolingPipeRadius + coolingPipeThickness + 2*lengthSafety;
00090 }
00091
00092 void BDSBeamPipeFactoryLHCDetailed::CalculateGeometricalParameters(G4double aper1,
00093 G4double aper2,
00094 G4double aper3,
00095 G4double beamPipeThickness,
00096 G4double length)
00097 {
00098
00099 vacRadius = aper3;
00100 vacBoxX = aper1;
00101 vacBoxY = aper2;
00102
00103
00104 cuInnerRadius = vacRadius + 1*CLHEP::um;
00105 cuInnerBoxX = vacBoxX + 1*CLHEP::um;
00106 cuInnerBoxY = vacBoxY + 1*CLHEP::um;
00107 cuOuterRadius = cuInnerRadius + copperSkinThickness;
00108 cuOuterBoxX = cuInnerBoxX + copperSkinThickness;
00109 cuOuterBoxY = cuInnerBoxY + copperSkinThickness;
00110
00111
00112 bsInnerRadius = cuOuterRadius + 1*CLHEP::um;
00113 bsInnerBoxX = cuOuterBoxX + 1*CLHEP::um;
00114 bsInnerBoxY = cuOuterBoxY + 1*CLHEP::um;
00115 bsOuterRadius = bsInnerRadius + beamPipeThickness;
00116 bsOuterBoxX = bsInnerBoxX + beamPipeThickness;
00117 bsOuterBoxY = bsInnerBoxY + beamPipeThickness;
00118
00119
00120 cbInnerRadius = bsOuterRadius + 1*CLHEP::um;
00121 cbOuterRadius = cbInnerRadius + coldBoreThickness;
00122
00123
00124 containerRadius = cbOuterRadius + 1*CLHEP::um;
00125
00126
00127 vacHalfLength = length*0.5 - lengthSafety;
00128 halfLength = length*0.5 - 1*CLHEP::um;
00129
00130
00131 coolingPipeYOffset = bsOuterBoxY + coolingPipeRadius + coolingPipeThickness + 1*CLHEP::um;
00132 }
00133
00134
00135 BDSBeamPipe* BDSBeamPipeFactoryLHCDetailed::CreateBeamPipe(G4String name,
00136 G4double length,
00137 G4double aper1,
00138 G4double aper2,
00139 G4double aper3,
00140 G4double ,
00141 G4Material* vacuumMaterial,
00142 G4double beamPipeThickness,
00143 G4Material* beamPipeMaterial
00144 )
00145 {
00146 #ifdef BDSDEBUG
00147 G4cout << __METHOD_NAME__ << G4endl;
00148 #endif
00149
00150 CleanUp();
00151
00152
00153 CalculateGeometricalParameters(aper1, aper2, aper3, beamPipeThickness, length);
00154
00155
00156 TestInputParameters(vacuumMaterial,beamPipeThickness,beamPipeMaterial,aper1,aper2,aper3);
00157
00158
00159
00160 G4VSolid* vacCylSolid = new G4Tubs(name + "_vacuum_cylinder",
00161 0,
00162 vacRadius,
00163 vacHalfLength,
00164 0,
00165 CLHEP::twopi);
00166
00167 G4VSolid* vacRectSolid = new G4Box(name + "_vacuum_box",
00168 vacBoxX,
00169 vacBoxY,
00170 length);
00171
00172 vacuumSolid = new G4IntersectionSolid(name + "_vacuum_solid",
00173 vacCylSolid,
00174 vacRectSolid);
00175
00176
00177
00178
00179 G4VSolid* cuInnerCylSolid = new G4Tubs(name + "_cu_inner_cylinder",
00180 0,
00181 cuInnerRadius,
00182 1.5*length,
00183 0,
00184 CLHEP::twopi);
00185
00186 G4VSolid* cuInnerRectSolid = new G4Box(name + "_cu_inner_box",
00187 cuInnerBoxX,
00188 cuInnerBoxY,
00189 1.7*length);
00190
00191 G4VSolid* cuInnerSolid = new G4IntersectionSolid(name + "_cu_inner_solid",
00192 cuInnerCylSolid,
00193 cuInnerRectSolid);
00194
00195
00196 G4VSolid* cuOuterCylSolid = new G4Tubs(name + "_cu_outer_cylinder",
00197 0,
00198 cuOuterRadius,
00199 halfLength,
00200 0,
00201 CLHEP::twopi);
00202
00203 G4VSolid* cuOuterRectSolid = new G4Box(name + "_cu_outer_box",
00204 cuOuterBoxX,
00205 cuOuterBoxY,
00206 length);
00207 G4VSolid* cuOuterSolid = new G4IntersectionSolid(name + "_cu_outer_solid",
00208 cuOuterCylSolid,
00209 cuOuterRectSolid);
00210 copperSkinSolid = new G4SubtractionSolid(name + "_copper_skin_solid",
00211 cuOuterSolid,
00212 cuInnerSolid);
00213
00214
00215
00216
00217 G4VSolid* screenInnerCylSolid = new G4Tubs(name + "_screen_inner_cylinder",
00218 0,
00219 bsInnerRadius,
00220 1.5*length,
00221 0,
00222 CLHEP::twopi);
00223
00224
00225 G4VSolid* screenInnerRectSolid = new G4Box(name + "_screen_inner_box",
00226 bsInnerBoxX,
00227 bsInnerBoxY,
00228 1.7*length);
00229
00230 G4VSolid* screenInnerSolid = new G4IntersectionSolid(name + "_screen_inner_solid",
00231 screenInnerCylSolid,
00232 screenInnerRectSolid);
00233
00234
00235 G4VSolid* screenOuterCylSolid = new G4Tubs(name + "_screen_outer_cylinder",
00236 0,
00237 bsOuterRadius,
00238 halfLength,
00239 0,
00240 CLHEP::twopi);
00241
00242 G4VSolid* screenOuterRectSolid = new G4Box(name + "_screen_outer_box",
00243 bsOuterBoxX,
00244 bsOuterBoxY,
00245 length);
00246 G4VSolid* screenOuterSolid = new G4IntersectionSolid(name + "_screen__outersolid",
00247 screenOuterCylSolid,
00248 screenOuterRectSolid);
00249 screenSolid = new G4SubtractionSolid(name + "_screen_solid",
00250 screenOuterSolid,
00251 screenInnerSolid);
00252
00253 coolingPipeSolid = new G4Tubs(name + "_cooling_pipe_solid",
00254 coolingPipeRadius,
00255 coolingPipeRadius + coolingPipeThickness,
00256 halfLength,
00257 0,
00258 CLHEP::twopi);
00259
00260
00261 beamPipeSolid = new G4Tubs(name + "_beampipe_solid",
00262 cbInnerRadius,
00263 cbOuterRadius,
00264 halfLength,
00265 0,
00266 CLHEP::twopi);
00267
00268
00269 containerSolid = new G4Tubs(name + "_container_cylinder",
00270 0,
00271 containerRadius,
00272 length*0.5,
00273 0,
00274 CLHEP::twopi);
00275
00276
00277 containerSubtractionSolid = new G4Tubs(name + "_subtraction_cylinder",
00278 0,
00279 containerRadius + lengthSafety,
00280 2*length,
00281 0,
00282 CLHEP::twopi);
00283
00284 return CommonFinalConstruction(name, vacuumMaterial, beamPipeMaterial, length, containerRadius);
00285 }
00286
00287 BDSBeamPipe* BDSBeamPipeFactoryLHCDetailed::CreateBeamPipeAngledInOut(G4String name,
00288 G4double length,
00289 G4double angleIn,
00290 G4double angleOut,
00291 G4double aper1,
00292 G4double aper2,
00293 G4double aper3,
00294 G4double ,
00295 G4Material* vacuumMaterial,
00296 G4double beamPipeThickness,
00297 G4Material* beamPipeMaterial
00298 )
00299 {
00300 #ifdef BDSDEBUG
00301 G4cout << __METHOD_NAME__ << G4endl;
00302 #endif
00303
00304 CleanUp();
00305
00306
00307 CalculateGeometricalParameters(aper1, aper2, aper3, beamPipeThickness, length);
00308
00309
00310 TestInputParameters(vacuumMaterial,beamPipeThickness,beamPipeMaterial,aper1,aper2,aper3);
00311
00312 std::pair<G4ThreeVector,G4ThreeVector> faces = CalculateFaces(angleIn, angleOut);
00313 G4ThreeVector inputface = faces.first;
00314 G4ThreeVector outputface = faces.second;
00315
00316 G4double containerRadius = CreateGeneralAngledSolids(name, length, inputface, outputface);
00317
00318 return CommonFinalConstruction(name, vacuumMaterial, beamPipeMaterial, length, containerRadius);
00319 }
00320
00322
00324 void BDSBeamPipeFactoryLHCDetailed::TestInputParameters(G4Material*& vacuumMaterial,
00325 G4double& beamPipeThickness,
00326 G4Material*& beamPipeMaterial,
00327 G4double& aper1,
00328 G4double& aper2,
00329 G4double& aper3)
00330 {
00331 BDSBeamPipeFactoryBase::TestInputParameters(vacuumMaterial,beamPipeThickness,beamPipeMaterial);
00332
00333 if (aper1 < 1e-10)
00334 {aper1 = BDSGlobalConstants::Instance()->GetBeamPipeRadius();}
00335
00336 if (aper2 < 1e-10)
00337 {aper2 = BDSGlobalConstants::Instance()->GetAper2();}
00338
00339 if (aper3 < 1e-10)
00340 {aper3 = BDSGlobalConstants::Instance()->GetAper3();}
00341 }
00342
00345 BDSBeamPipe* BDSBeamPipeFactoryLHCDetailed::CommonFinalConstruction(G4String name,
00346 G4Material* vacuumMaterial,
00347 G4Material* beamPipeMaterial,
00348 G4double length,
00349 G4double containerRadius)
00350 {
00351 #ifdef BDSDEBUG
00352 G4cout << __METHOD_NAME__ << G4endl;
00353 #endif
00354
00355 BDSBeamPipeFactoryBase::CommonConstruction(name,
00356 vacuumMaterial,
00357 beamPipeMaterial,
00358 length);
00359
00360
00361 std::pair<double,double> extX = std::make_pair(-containerRadius,containerRadius);
00362 std::pair<double,double> extY = std::make_pair(-containerRadius,containerRadius);
00363 std::pair<double,double> extZ = std::make_pair(-length*0.5,length*0.5);
00364
00365
00366 BDSBeamPipe* aPipe = BuildBeamPipeAndRegisterVolumes(extX,extY,extZ,containerRadius);
00367
00368
00369 aPipe->RegisterLogicalVolume(screenLV);
00370 aPipe->RegisterLogicalVolume(coolingPipeLV);
00371 aPipe->RegisterLogicalVolume(copperSkinLV);
00372
00373
00374 aPipe->RegisterSensitiveVolume(screenLV);
00375 aPipe->RegisterSensitiveVolume(coolingPipeLV);
00376 aPipe->RegisterSensitiveVolume(copperSkinLV);
00377
00378 return aPipe;
00379 }
00380
00381 void BDSBeamPipeFactoryLHCDetailed::BuildLogicalVolumes(G4String name,
00382 G4Material* vacuumMaterialIn,
00383 G4Material* beamPipeMaterialIn)
00384 {
00385 BDSBeamPipeFactoryBase::BuildLogicalVolumes(name,vacuumMaterialIn,beamPipeMaterialIn);
00386
00387
00388 G4Material* copper = BDSMaterials::Instance()->GetMaterial("Copper");
00389
00390
00391 copperSkinLV = new G4LogicalVolume(copperSkinSolid,
00392 copper,
00393 name + "_copper_lv");
00394
00395 screenLV = new G4LogicalVolume(screenSolid,
00396 beamPipeMaterialIn,
00397 name + "_screen_lv");
00398
00399 coolingPipeLV = new G4LogicalVolume(coolingPipeSolid,
00400 beamPipeMaterialIn,
00401 name + "_cooling_pipe_lv");
00402 }
00403
00404 void BDSBeamPipeFactoryLHCDetailed::SetVisAttributes()
00405 {
00406 BDSBeamPipeFactoryBase::SetVisAttributes();
00407
00408
00409 G4VisAttributes* cuVisAttr = new G4VisAttributes(G4Colour(0.722, 0.525, 0.043));
00410 cuVisAttr->SetForceLineSegmentsPerCircle(nSegmentsPerCircle);
00411 cuVisAttr->SetVisibility(true);
00412
00413
00414 G4VisAttributes* pipeVisAttr = new G4VisAttributes(G4Colour(0.4,0.4,0.4));
00415 pipeVisAttr->SetVisibility(true);
00416 pipeVisAttr->SetForceLineSegmentsPerCircle(nSegmentsPerCircle);
00417
00418 copperSkinLV->SetVisAttributes(cuVisAttr);
00419 screenLV->SetVisAttributes(pipeVisAttr);
00420 coolingPipeLV->SetVisAttributes(pipeVisAttr);
00421 }
00422
00423 G4UserLimits* BDSBeamPipeFactoryLHCDetailed::SetUserLimits(G4double length) {
00424
00425 G4UserLimits* beamPipeUserLimits = BDSBeamPipeFactoryBase::SetUserLimits(length);
00426 copperSkinLV->SetUserLimits(beamPipeUserLimits);
00427 screenLV->SetUserLimits(beamPipeUserLimits);
00428 coolingPipeLV->SetUserLimits(beamPipeUserLimits);
00429
00430 return beamPipeUserLimits;
00431 }
00432
00433 void BDSBeamPipeFactoryLHCDetailed::PlaceComponents(G4String name) {
00434 BDSBeamPipeFactoryBase::PlaceComponents(name);
00435
00436 new G4PVPlacement((G4RotationMatrix*)0,
00437 G4ThreeVector(0,0,0),
00438 copperSkinLV,
00439 name + "_copper_skin_pv",
00440 containerLV,
00441 false,
00442 0,
00443 checkOverlaps);
00444
00445 new G4PVPlacement((G4RotationMatrix*)0,
00446 (G4ThreeVector)0,
00447 screenLV,
00448 name + "_screen_pv",
00449 containerLV,
00450 false,
00451 0,
00452 checkOverlaps);
00453
00454 G4ThreeVector* coolingPipeTopPosition = new G4ThreeVector(0,coolingPipeYOffset,0);
00455 G4ThreeVector* coolingPipeBottomPosition = new G4ThreeVector(0,-coolingPipeYOffset,0);
00456
00457 new G4PVPlacement((G4RotationMatrix*)0,
00458 *coolingPipeTopPosition,
00459 coolingPipeLV,
00460 name + "_cooling_pipe_top_pv",
00461 containerLV,
00462 false,
00463 0,
00464 checkOverlaps);
00465
00466 new G4PVPlacement((G4RotationMatrix*)0,
00467 *coolingPipeBottomPosition,
00468 coolingPipeLV,
00469 name + "_cooling_pipe_bottom_pv",
00470 containerLV,
00471 false,
00472 0,
00473 checkOverlaps);
00474 }
00475
00478 G4double BDSBeamPipeFactoryLHCDetailed::CreateGeneralAngledSolids(G4String name,
00479 G4double length,
00480 G4ThreeVector inputface,
00481 G4ThreeVector outputface)
00482 {
00483 #ifdef BDSDEBUG
00484 G4cout << __METHOD_NAME__ << G4endl;
00485 #endif
00486
00487
00488
00489 G4VSolid* vacCylSolid = new G4CutTubs(name + "_vacuum_cylinder",
00490 0,
00491 vacRadius,
00492 vacHalfLength,
00493 0,
00494 CLHEP::twopi,
00495 inputface,
00496 outputface);
00497
00498 G4VSolid* vacRectSolid = new G4Box(name + "_vacuum_box",
00499 vacBoxX,
00500 vacBoxY,
00501 length);
00502
00503 vacuumSolid = new G4IntersectionSolid(name + "_vacuum_solid",
00504 vacCylSolid,
00505 vacRectSolid);
00506
00507
00508
00509
00510 G4VSolid* cuInnerCylSolid = new G4CutTubs(name + "_cu_inner_cylinder",
00511 0,
00512 cuInnerRadius,
00513 1.5*length,
00514 0,
00515 CLHEP::twopi,
00516 inputface,
00517 outputface);
00518
00519 G4VSolid* cuInnerRectSolid = new G4Box(name + "_cu_inner_box",
00520 cuInnerBoxX,
00521 cuInnerBoxY,
00522 1.7*length);
00523
00524 G4VSolid* cuInnerSolid = new G4IntersectionSolid(name + "_cu_inner_solid",
00525 cuInnerCylSolid,
00526 cuInnerRectSolid);
00527
00528
00529 G4VSolid* cuOuterCylSolid = new G4CutTubs(name + "_cu_outer_cylinder",
00530 0,
00531 cuOuterRadius,
00532 halfLength,
00533 0,
00534 CLHEP::twopi,
00535 inputface,
00536 outputface);
00537
00538 G4VSolid* cuOuterRectSolid = new G4Box(name + "_cu_outer_box",
00539 cuOuterBoxX,
00540 cuOuterBoxY,
00541 length);
00542 G4VSolid* cuOuterSolid = new G4IntersectionSolid(name + "_cu_outer_solid",
00543 cuOuterCylSolid,
00544 cuOuterRectSolid);
00545 copperSkinSolid = new G4SubtractionSolid(name + "_copper_skin_solid",
00546 cuOuterSolid,
00547 cuInnerSolid);
00548
00549
00550
00551 G4VSolid* screenInnerCylSolid = new G4CutTubs(name + "_screen_inner_cylinder",
00552 0,
00553 bsInnerRadius,
00554 1.5*length,
00555 0,
00556 CLHEP::twopi,
00557 inputface,
00558 outputface);
00559
00560 G4VSolid* screenInnerRectSolid = new G4Box(name + "_screen_inner_box",
00561 bsInnerBoxX,
00562 bsInnerBoxY,
00563 1.7*length);
00564
00565 G4VSolid* screenInnerSolid = new G4IntersectionSolid(name + "_screen_inner_solid",
00566 screenInnerCylSolid,
00567 screenInnerRectSolid);
00568
00569
00570 G4VSolid* screenOuterCylSolid = new G4CutTubs(name + "_screen_outer_cylinder",
00571 0,
00572 bsOuterRadius,
00573 halfLength,
00574 0,
00575 CLHEP::twopi,
00576 inputface,
00577 outputface);
00578
00579 G4VSolid* screenOuterRectSolid = new G4Box(name + "_screen_outer_box",
00580 bsOuterBoxX,
00581 bsOuterBoxY,
00582 length);
00583 G4VSolid* screenOuterSolid = new G4IntersectionSolid(name + "_pipe_outer_solid",
00584 screenOuterCylSolid,
00585 screenOuterRectSolid);
00586
00587
00588 screenSolid = new G4SubtractionSolid(name + "_screen_solid",
00589 screenOuterSolid,
00590 screenInnerSolid);
00591
00592 coolingPipeSolid = new G4CutTubs(name + "_cooling_pipe_solid",
00593 coolingPipeRadius,
00594 coolingPipeRadius + coolingPipeThickness,
00595 halfLength,
00596 0,
00597 CLHEP::twopi,
00598 inputface,
00599 outputface);
00600
00601
00602 beamPipeSolid = new G4CutTubs(name + "_beampipe_solid",
00603 cbInnerRadius,
00604 cbOuterRadius,
00605 halfLength,
00606 0,
00607 CLHEP::twopi,
00608 inputface,
00609 outputface);
00610
00611
00612 containerSolid = new G4CutTubs(name + "_container_cylinder",
00613 0,
00614 containerRadius,
00615 length*0.5,
00616 0,
00617 CLHEP::twopi,
00618 inputface,
00619 outputface);
00620
00621
00622 containerSubtractionSolid = new G4Tubs(name + "_subtraction_cylinder",
00623 0,
00624 containerRadius + lengthSafety,
00625 2*length,
00626 0,
00627 CLHEP::twopi);
00628
00629
00630 return containerRadius;
00631 }