19#include "BDSAppropriateTubs.hh"
20#include "BDSBeamPipe.hh"
21#include "BDSBeamPipeInfo.hh"
22#include "BDSBeamPipeType.hh"
23#include "BDSBeamPipeFactory.hh"
24#include "BDSColours.hh"
26#include "BDSException.hh"
27#include "BDSExtent.hh"
28#include "BDSGeometryComponent.hh"
29#include "BDSGlobalConstants.hh"
30#include "BDSMagnetOuter.hh"
31#include "BDSMagnetOuterFactoryCylindrical.hh"
32#include "BDSMagnetOuterFactoryLHC.hh"
33#include "BDSMagnetOuterInfo.hh"
34#include "BDSMaterials.hh"
35#include "BDSSDType.hh"
36#include "BDSUtilities.hh"
40#include "G4CutTubs.hh"
42#include "G4LogicalVolume.hh"
43#include "G4UnionSolid.hh"
44#include "G4Material.hh"
45#include "G4PVPlacement.hh"
46#include "G4SubtractionSolid.hh"
47#include "G4ThreeVector.hh"
49#include "G4VisAttributes.hh"
52#include "CLHEP/Units/SystemOfUnits.h"
63BDSMagnetOuterFactoryLHC::BDSMagnetOuterFactoryLHC(G4bool isLeftOffsetIn):
64 isLeftOffset(isLeftOffsetIn)
69BDSMagnetOuterFactoryLHC::~BDSMagnetOuterFactoryLHC()
77 G4double containerLength,
80 return CreateLHCDipole(name, length, beamPipe, containerLength, recipe, YokeColour::dipole);
86 G4double containerLength,
92 G4double horizontalWidth = recipe->horizontalWidth;
93 G4double angleIn = recipe->angleIn;
94 G4double angleOut = recipe->angleOut;
115 G4double massShift = 0.5 * beamPipeAxisSeparation;
117 G4double collarBoxHalfWidth = 22*CLHEP::mm;
122 G4double innerCoilInnerRadiusF = 24.601*CLHEP::mm;
123 G4double innerCoilOuterRadius = 42*CLHEP::mm;
126 G4double outerCoilOuterRadius = 60*CLHEP::mm;
129 G4double collarOuterRadius = 101.18*CLHEP::mm;
130 G4double yokeOuterRadius = 570.0*0.5*CLHEP::mm;
135 G4double poleInnerFullAngle = 33./180.*2;
136 G4double poleOuterFullAngle = 100./180.*2;
137 G4double coilInnerFullAngle = CLHEP::pi - poleInnerFullAngle - 1e-3;
138 G4double coilOuterFullAngle = CLHEP::pi - poleOuterFullAngle - 1e-3;
142 G4bool buildInnerCoil =
true;
143 G4bool buildOuterCoil =
true;
144 G4bool buildCollar =
true;
145 if (innerCoilInnerRadius > innerCoilOuterRadius)
146 {buildInnerCoil =
false;}
147 if ((innerCoilInnerRadius > outerCoilInnerRadius) && (innerCoilInnerRadius < outerCoilOuterRadius))
148 {outerCoilInnerRadius = containerInnerRadius +
lengthSafety;}
149 if (innerCoilInnerRadius > outerCoilOuterRadius)
150 {buildOuterCoil =
false;}
153 if ((innerCoilInnerRadius > collarInnerRadius) && (innerCoilInnerRadius < (massShift - collarBoxHalfWidth)))
154 {collarInnerRadius = containerInnerRadius +
lengthSafety;}
155 if (innerCoilInnerRadius > (massShift - collarBoxHalfWidth))
156 {buildCollar =
false;}
157 if (innerCoilInnerRadius > collarOuterRadius)
159 throw BDSException(__METHOD_NAME__,
"error in component \"" + name +
"\"\n" +
160 "this beam pipe is too big to use with the LHC dipole geometry\n" +
161 "Please consider using a different magnet geometry for this particular magnet");
164 G4ThreeVector dipolePosition;
167 dipolePosition = G4ThreeVector(massShift,0.,0.);
168 beamPipeAxisSeparation *= -1;
170 G4cout << __METHOD_NAME__ <<
"dipole to the left" << G4endl;
175 dipolePosition = G4ThreeVector(-massShift,0.,0.);
178 G4cout << __METHOD_NAME__ <<
"dipole to the right" << G4endl;
183 G4double angle = angleIn + angleOut;
186 inputFaceNormal = faces.first;
187 outputFaceNormal = faces.second;
190 G4double centralHalfLength = length*0.5 - orientation*0.5*beamPipeAxisSeparation*tan(fabs(angle*0.5));
192 G4double centralContainerLength = containerLength - orientation*beamPipeAxisSeparation*tan(fabs(angle*0.5));
194 G4double secondBPHalfLength = length*0.5 - orientation*beamPipeAxisSeparation*tan(fabs(angle*0.5));
197 G4cout << __METHOD_NAME__ <<
"all calculated parameters: " << G4endl;
198 G4cout <<
"container inner radius: " << containerInnerRadius << G4endl;
199 G4cout <<
"inner coil inner radius: " << innerCoilInnerRadius << G4endl;
200 G4cout <<
"inner coil outer radius: " << innerCoilOuterRadius << G4endl;
201 G4cout <<
"outer coil inner radius: " << outerCoilInnerRadius << G4endl;
202 G4cout <<
"outer coil outer radius: " << outerCoilOuterRadius << G4endl;
203 G4cout <<
"collar inner radius: " << collarInnerRadius << G4endl;
204 G4cout <<
"collar outer radius: " << collarOuterRadius << G4endl;
205 G4cout <<
"yoke outer radius: " << yokeOuterRadius << G4endl;
208 G4VSolid* containerSolidOuter = BDS::AppropriateTubs(name +
"_container_solid_outer",
217 allSolids.insert(containerSolidOuter);
218 G4VSolid* containerSolidInner;
224 containerSolidInner =
new G4Tubs(name +
"_container_solid_inner",
226 containerInnerRadius,
230 allSolids.insert(containerSolidInner);
234 containerSolid =
new G4SubtractionSolid(name +
"_outer_container_solid",
246 magnetContainerLV =
new G4LogicalVolume(magnetContainerSolid,
248 name +
"_container_lv");
250 containerLV =
new G4LogicalVolume(containerSolid,
252 name +
"_outer_container_lv");
255 G4VSolid* coil1Inner =
nullptr;
256 G4VSolid* coil1Outer =
nullptr;
257 G4VSolid* coil2Inner =
nullptr;
258 G4VSolid* coil2Outer =
nullptr;
259 G4VSolid* coil3Inner =
nullptr;
260 G4VSolid* coil3Outer =
nullptr;
261 G4VSolid* coil4Inner =
nullptr;
262 G4VSolid* coil4Outer =
nullptr;
263 G4LogicalVolume* coil1InnerLV =
nullptr;
264 G4LogicalVolume* coil1OuterLV =
nullptr;
265 G4LogicalVolume* coil2InnerLV =
nullptr;
266 G4LogicalVolume* coil2OuterLV =
nullptr;
267 G4LogicalVolume* coil3InnerLV =
nullptr;
268 G4LogicalVolume* coil3OuterLV =
nullptr;
269 G4LogicalVolume* coil4InnerLV =
nullptr;
270 G4LogicalVolume* coil4OuterLV =
nullptr;
271 G4PVPlacement* coil1InnerPV =
nullptr;
272 G4PVPlacement* coil1OuterPV =
nullptr;
273 G4PVPlacement* coil2InnerPV =
nullptr;
274 G4PVPlacement* coil2OuterPV =
nullptr;
275 G4PVPlacement* coil3InnerPV =
nullptr;
276 G4PVPlacement* coil3OuterPV =
nullptr;
277 G4PVPlacement* coil4InnerPV =
nullptr;
278 G4PVPlacement* coil4OuterPV =
nullptr;
284 G4VisAttributes* coilVisAtt =
new G4VisAttributes(*
BDSColours::Instance()->GetColour(
"LHCcoil"));
286 allVisAttributes.insert(coilVisAtt);
287 G4VSolid* collar1PoleTopInnerSolid =
nullptr;
288 G4VSolid* collar1PoleBottomInnerSolid =
nullptr;
289 G4VSolid* collar1PoleTopOuterSolid =
nullptr;
290 G4VSolid* collar1PoleBottomOuterSolid =
nullptr;
291 G4LogicalVolume* collar1PoleTopInnerLV =
nullptr;
292 G4LogicalVolume* collar1PoleBottomInnerLV =
nullptr;
293 G4LogicalVolume* collar1PoleTopOuterLV =
nullptr;
294 G4LogicalVolume* collar1PoleBottomOuterLV =
nullptr;
295 G4PVPlacement* collar1PoleTopInnerPV =
nullptr;
296 G4PVPlacement* collar1PoleBottomInnerPV =
nullptr;
297 G4PVPlacement* collar1PoleTopOuterPV =
nullptr;
298 G4PVPlacement* collar1PoleBottomOuterPV =
nullptr;
299 G4VSolid* collar2PoleTopInnerSolid =
nullptr;
300 G4VSolid* collar2PoleBottomInnerSolid =
nullptr;
301 G4VSolid* collar2PoleTopOuterSolid =
nullptr;
302 G4VSolid* collar2PoleBottomOuterSolid =
nullptr;
303 G4LogicalVolume* collar2PoleTopInnerLV =
nullptr;
304 G4LogicalVolume* collar2PoleBottomInnerLV =
nullptr;
305 G4LogicalVolume* collar2PoleTopOuterLV =
nullptr;
306 G4LogicalVolume* collar2PoleBottomOuterLV =
nullptr;
307 G4PVPlacement* collar2PoleTopInnerPV =
nullptr;
308 G4PVPlacement* collar2PoleBottomInnerPV =
nullptr;
309 G4PVPlacement* collar2PoleTopOuterPV =
nullptr;
310 G4PVPlacement* collar2PoleBottomOuterPV =
nullptr;
311 G4LogicalVolume* collarsLV =
nullptr;
312 G4PVPlacement* collarsPV =
nullptr;
313 G4LogicalVolume* secondBPLV =
nullptr;
314 G4PVPlacement* secondBPPV =
nullptr;
318 G4VisAttributes* collarVisAtt =
new G4VisAttributes(*
BDSColours::Instance()->GetColour(
"LHCcollar"));
320 allVisAttributes.insert(collarVisAtt);
325 coil1Inner = BDS::AppropriateTubs(name+
"_coil1_inner_solid",
329 -coilInnerFullAngle*0.5,
334 coil2Inner = BDS::AppropriateTubs(name+
"_coil2_inner_solid",
338 CLHEP::pi-coilInnerFullAngle*0.5,
343 coil1InnerLV =
new G4LogicalVolume(coil1Inner,
345 name+
"_coil1_Inner_lv");
346 coil2InnerLV =
new G4LogicalVolume(coil2Inner,
348 name+
"_coil2_Inner_lv");
349 coil1InnerLV->SetVisAttributes(coilVisAtt);
350 coil2InnerLV->SetVisAttributes(coilVisAtt);
352 coil1InnerPV =
new G4PVPlacement(
nullptr,
355 name+
"_coil1_inner_pv",
360 coil2InnerPV =
new G4PVPlacement(
nullptr,
363 name+
"_coil2_inner_pv",
369 allSolids.insert(coil1Inner);
370 allSolids.insert(coil2Inner);
371 allLogicalVolumes.insert(coil1InnerLV);
372 allLogicalVolumes.insert(coil2InnerLV);
373 allPhysicalVolumes.insert(coil1InnerPV);
374 allPhysicalVolumes.insert(coil2InnerPV);
376 collar1PoleTopInnerSolid = BDS::AppropriateTubs(name+
"_collar1_pole_inner_top",
380 CLHEP::pi*0.5-poleInnerFullAngle*0.5,
385 collar1PoleBottomInnerSolid = BDS::AppropriateTubs(name+
"_collar1_pole_inner_bottom",
389 CLHEP::pi*1.5-poleInnerFullAngle*0.5,
394 collar1PoleTopInnerLV =
new G4LogicalVolume(collar1PoleTopInnerSolid,
395 stainlesssteel_316LN_2K,
396 name+
"_collar1_pole_top_inner_lv");
397 collar1PoleBottomInnerLV =
new G4LogicalVolume(collar1PoleBottomInnerSolid,
398 stainlesssteel_316LN_2K,
399 name+
"_collar1_pole_bottom_inner_lv");
401 collar1PoleTopInnerLV->SetVisAttributes(collarVisAtt);
402 collar1PoleBottomInnerLV->SetVisAttributes(collarVisAtt);
404 collar1PoleTopInnerPV =
new G4PVPlacement(
nullptr,
406 collar1PoleTopInnerLV,
407 name+
"_collar1_pole_top_inner_pv",
412 collar1PoleBottomInnerPV =
new G4PVPlacement(
nullptr,
414 collar1PoleBottomInnerLV,
415 name+
"_collar1_pole_top_inner_pv",
421 allSolids.insert(collar1PoleTopInnerSolid);
422 allSolids.insert(collar1PoleBottomInnerSolid);
423 allLogicalVolumes.insert(collar1PoleTopInnerLV);
424 allLogicalVolumes.insert(collar1PoleBottomInnerLV);
425 allPhysicalVolumes.insert(collar1PoleTopInnerPV);
426 allPhysicalVolumes.insert(collar1PoleBottomInnerPV);
431 coil1Outer = BDS::AppropriateTubs(name+
"_coil1_outer_solid",
432 outerCoilInnerRadius,
433 outerCoilOuterRadius,
435 -coilOuterFullAngle*0.5,
440 coil2Outer = BDS::AppropriateTubs(name+
"_coil2_outer_solid",
441 outerCoilInnerRadius,
442 outerCoilOuterRadius,
444 CLHEP::pi-coilOuterFullAngle*0.5,
449 coil1OuterLV =
new G4LogicalVolume(coil1Outer,
451 name+
"_coil1_Inner_lv");
452 coil2OuterLV =
new G4LogicalVolume(coil2Outer,
454 name+
"_coil2_Inner_lv");
455 coil1OuterLV->SetVisAttributes(coilVisAtt);
456 coil2OuterLV->SetVisAttributes(coilVisAtt);
458 coil1OuterPV =
new G4PVPlacement(
nullptr,
461 name+
"_coil1_outer_pv",
466 coil2OuterPV =
new G4PVPlacement(
nullptr,
469 name+
"_coil2_outer_pv",
475 allSolids.insert(coil1Outer);
476 allSolids.insert(coil2Outer);
477 allLogicalVolumes.insert(coil1OuterLV);
478 allLogicalVolumes.insert(coil2OuterLV);
479 allPhysicalVolumes.insert(coil1OuterPV);
480 allPhysicalVolumes.insert(coil2OuterPV);
482 collar1PoleTopOuterSolid = BDS::AppropriateTubs(name+
"_collar1_pole_outer_top",
483 outerCoilInnerRadius,
484 outerCoilOuterRadius,
486 CLHEP::pi*0.5-poleOuterFullAngle*0.5,
491 collar1PoleBottomOuterSolid = BDS::AppropriateTubs(name+
"_collar1_pole_outer_bottom",
492 outerCoilInnerRadius,
493 outerCoilOuterRadius,
495 CLHEP::pi*1.5-poleOuterFullAngle*0.5,
501 collar1PoleTopOuterLV =
new G4LogicalVolume(collar1PoleTopOuterSolid,
502 stainlesssteel_316LN_2K,
503 name+
"_collar1_pole_top_outer_lv");
504 collar1PoleBottomOuterLV =
new G4LogicalVolume(collar1PoleBottomOuterSolid,
505 stainlesssteel_316LN_2K,
506 name+
"_collar1_pole_bottom_outer_lv");
508 collar1PoleTopOuterLV->SetVisAttributes(collarVisAtt);
509 collar1PoleBottomOuterLV->SetVisAttributes(collarVisAtt);
511 collar1PoleTopOuterPV =
new G4PVPlacement(
nullptr,
513 collar1PoleTopOuterLV,
514 name+
"_collar1_pole_top_inner_pv",
519 collar1PoleBottomOuterPV =
new G4PVPlacement(
nullptr,
521 collar1PoleBottomOuterLV,
522 name+
"_collar1_pole_top_inner_pv",
528 allSolids.insert(collar1PoleTopOuterSolid);
529 allSolids.insert(collar1PoleBottomOuterSolid);
530 allLogicalVolumes.insert(collar1PoleTopOuterLV);
531 allLogicalVolumes.insert(collar1PoleBottomOuterLV);
532 allPhysicalVolumes.insert(collar1PoleTopOuterPV);
533 allPhysicalVolumes.insert(collar1PoleBottomOuterPV);
537 coil3Inner = BDS::AppropriateTubs(name+
"_coil3_inner_solid",
538 innerCoilInnerRadiusF,
539 innerCoilOuterRadius,
541 -coilInnerFullAngle*0.5,
546 coil3Outer = BDS::AppropriateTubs(name+
"_coil3_outer_solid",
547 outerCoilInnerRadiusF,
548 outerCoilOuterRadius,
550 -coilOuterFullAngle*0.5,
555 coil4Inner = BDS::AppropriateTubs(name+
"_coil4_inner_solid",
556 innerCoilInnerRadiusF,
557 innerCoilOuterRadius,
559 CLHEP::pi-coilInnerFullAngle*0.5,
564 coil4Outer = BDS::AppropriateTubs(name+
"_coil4_outer_solid",
565 outerCoilInnerRadiusF,
566 outerCoilOuterRadius,
568 CLHEP::pi-coilOuterFullAngle*0.5,
574 coil3InnerLV =
new G4LogicalVolume(coil3Inner,
576 name+
"_coil3_Inner_lv");
577 coil3OuterLV =
new G4LogicalVolume(coil3Outer,
579 name+
"_coil3_Inner_lv");
580 coil4InnerLV =
new G4LogicalVolume(coil4Inner,
582 name+
"_coil4_Inner_lv");
583 coil4OuterLV =
new G4LogicalVolume(coil4Outer,
585 name+
"_coil4_Inner_lv");
587 coil3InnerLV->SetVisAttributes(coilVisAtt);
588 coil3OuterLV->SetVisAttributes(coilVisAtt);
589 coil4InnerLV->SetVisAttributes(coilVisAtt);
590 coil4OuterLV->SetVisAttributes(coilVisAtt);
592 allSolids.insert(coil3Inner);
593 allSolids.insert(coil3Outer);
594 allSolids.insert(coil4Inner);
595 allSolids.insert(coil4Outer);
596 allLogicalVolumes.insert(coil3InnerLV);
597 allLogicalVolumes.insert(coil3OuterLV);
598 allLogicalVolumes.insert(coil4InnerLV);
599 allLogicalVolumes.insert(coil4OuterLV);
603 coil3InnerPV =
new G4PVPlacement(
nullptr,
606 name+
"_coil3_inner_pv",
611 coil3OuterPV =
new G4PVPlacement(
nullptr,
614 name+
"_coil3_outer_pv",
619 coil4InnerPV =
new G4PVPlacement(
nullptr,
622 name+
"_coil4_inner_pv",
627 coil4OuterPV =
new G4PVPlacement(
nullptr,
630 name+
"_coil4_outer_pv",
635 allPhysicalVolumes.insert(coil3InnerPV);
636 allPhysicalVolumes.insert(coil3OuterPV);
637 allPhysicalVolumes.insert(coil4InnerPV);
638 allPhysicalVolumes.insert(coil4OuterPV);
642 collar2PoleTopInnerSolid = BDS::AppropriateTubs(name+
"_collar2_pole_inner_top",
643 innerCoilInnerRadiusF,
644 innerCoilOuterRadius,
646 CLHEP::pi*0.5-poleInnerFullAngle*0.5,
651 collar2PoleTopOuterSolid = BDS::AppropriateTubs(name+
"_collar2_pole_outer_top",
652 outerCoilInnerRadiusF,
653 outerCoilOuterRadius,
655 CLHEP::pi*0.5-poleOuterFullAngle*0.5,
660 collar2PoleBottomInnerSolid = BDS::AppropriateTubs(name+
"_collar2_pole_inner_bottom",
661 innerCoilInnerRadiusF,
662 innerCoilOuterRadius,
664 CLHEP::pi*1.5-poleInnerFullAngle*0.5,
669 collar2PoleBottomOuterSolid = BDS::AppropriateTubs(name+
"_collar2_pole_outer_bottom",
670 outerCoilInnerRadiusF,
671 outerCoilOuterRadius,
673 CLHEP::pi*1.5-poleOuterFullAngle*0.5,
680 collar2PoleTopInnerLV =
new G4LogicalVolume(collar2PoleTopInnerSolid,
681 stainlesssteel_316LN_2K,
682 name+
"_collar2_pole_top_inner_lv");
683 collar2PoleTopOuterLV =
new G4LogicalVolume(collar2PoleTopOuterSolid,
684 stainlesssteel_316LN_2K,
685 name+
"_collar2_pole_top_outer_lv");
686 collar2PoleBottomInnerLV =
new G4LogicalVolume(collar2PoleBottomInnerSolid,
687 stainlesssteel_316LN_2K,
688 name+
"_collar2_pole_bottom_inner_lv");
689 collar2PoleBottomOuterLV =
new G4LogicalVolume(collar2PoleBottomOuterSolid,
690 stainlesssteel_316LN_2K,
691 name+
"_collar2_pole_bottom_outer_lv");
694 collar2PoleTopInnerLV->SetVisAttributes(collarVisAtt);
695 collar2PoleTopOuterLV->SetVisAttributes(collarVisAtt);
696 collar2PoleBottomInnerLV->SetVisAttributes(collarVisAtt);
697 collar2PoleBottomOuterLV->SetVisAttributes(collarVisAtt);
699 allSolids.insert(collar2PoleTopInnerSolid);
700 allSolids.insert(collar2PoleTopOuterSolid);
701 allSolids.insert(collar2PoleBottomInnerSolid);
702 allSolids.insert(collar2PoleBottomOuterSolid);
703 allLogicalVolumes.insert(collar2PoleTopInnerLV);
704 allLogicalVolumes.insert(collar2PoleTopOuterLV);
705 allLogicalVolumes.insert(collar2PoleBottomInnerLV);
706 allLogicalVolumes.insert(collar2PoleBottomOuterLV);
709 collar2PoleTopInnerPV =
new G4PVPlacement(
nullptr,
711 collar2PoleTopInnerLV,
712 name+
"_collar2_pole_top_inner_pv",
717 collar2PoleTopOuterPV =
new G4PVPlacement(
nullptr,
719 collar2PoleTopOuterLV,
720 name+
"_collar2_pole_top_inner_pv",
725 collar2PoleBottomInnerPV =
new G4PVPlacement(
nullptr,
727 collar2PoleBottomInnerLV,
728 name+
"_collar2_pole_top_inner_pv",
733 collar2PoleBottomOuterPV =
new G4PVPlacement(
nullptr,
735 collar2PoleBottomOuterLV,
736 name+
"_collar2_pole_top_inner_pv",
742 allPhysicalVolumes.insert(collar2PoleTopInnerPV);
743 allPhysicalVolumes.insert(collar2PoleTopOuterPV);
744 allPhysicalVolumes.insert(collar2PoleBottomInnerPV);
745 allPhysicalVolumes.insert(collar2PoleBottomOuterPV);
748 G4VSolid* collarAnnulus2 = BDS::AppropriateTubs(name+
"_collar2_annulus_solid",
758 allSolids.insert(collarAnnulus2);
760 G4VSolid* collars = collarAnnulus2;
766 G4VSolid* collarAnnulus1 = BDS::AppropriateTubs(name+
"_collar1_annulus_solid",
776 collars =
new G4UnionSolid(name +
"_collars_solid",
781 allSolids.insert(collarAnnulus1);
782 allSolids.insert(collars);
813 G4VSolid* collarTotal = collars;
815 collarsLV =
new G4LogicalVolume(collarTotal,
816 stainlesssteel_316LN_2K,
820 collarsLV->SetVisAttributes(collarVisAtt);
822 allLogicalVolumes.insert(collarsLV);
824 collarsPV =
new G4PVPlacement(
nullptr,
832 allPhysicalVolumes.insert(collarsPV);
835 G4VSolid* yokeCylinder = BDS::AppropriateTubs(name+
"_yoke_cylinder_solid",
846 G4VSolid* yokeSubtractionCylinder =
new G4Tubs(name +
"_yoke_subtraction_cyl_solid",
853 G4VSolid* yokeSubtractionSolid =
new G4UnionSolid(name +
"_yoke_subtraction_solid",
854 yokeSubtractionCylinder,
855 yokeSubtractionCylinder,
859 yokeSolid =
new G4SubtractionSolid(name+
"_yoke_solid",
861 yokeSubtractionSolid,
864 allSolids.insert(yokeSubtractionCylinder);
865 allSolids.insert(yokeSubtractionSolid);
868 stainlesssteel_304L_2K,
872 G4Colour* yokeColour;
875 case YokeColour::dipole:
877 case YokeColour::kicker:
878 {yokeColour = recipe->colour;
break;}
882 G4VisAttributes* yokeVis =
new G4VisAttributes(*yokeColour);
884 allVisAttributes.insert(yokeVis);
885 yokeLV->SetVisAttributes(yokeVis);
887 allLogicalVolumes.insert(yokeLV);
890 yokePV =
new G4PVPlacement(
nullptr,
891 G4ThreeVector(0,0,0),
898 allPhysicalVolumes.insert(yokePV);
916 stainlesssteel_316LN_2K);
931 stainlesssteel_316LN_2K);
935 secondBPPV =
new G4PVPlacement(
nullptr,
938 name +
"_second_beampipe_pv",
943 allPhysicalVolumes.insert(secondBPPV);
950 for (
auto lv : allLogicalVolumes)
957 G4double containerRadius = yokeOuterRadius;
960 -containerRadius,containerRadius,
961 -length*0.5,length*0.5);
990 G4double containerLength,
999 G4double containerLength,
1002 G4double horizontalWidth = recipe->horizontalWidth;
1012 G4double massShift = 0.5 * beamPipeAxisSeparation;
1014 G4double collarBoxHalfWidth = 22*CLHEP::mm;
1019 G4double coilInnerRadiusF = 24.601*CLHEP::mm;
1020 G4double coilOuterRadius = 60*CLHEP::mm;
1023 G4double collarOuterRadius = 101.18*CLHEP::mm;
1024 G4double yokeOuterRadius = 570.0*0.5*CLHEP::mm;
1029 G4double poleFullAngle = CLHEP::pi/6.;
1030 G4double coilFullAngle = CLHEP::pi/2. - poleFullAngle - 1e-3;
1031 G4double coilHalfAngle = coilFullAngle*0.5;
1032 G4double coilStartAngle = -coilHalfAngle;
1033 G4double poleStartAngle = coilHalfAngle;
1034 G4RotationMatrix* coil2rm =
new G4RotationMatrix();
1035 G4RotationMatrix* coil3rm =
new G4RotationMatrix();
1036 G4RotationMatrix* coil4rm =
new G4RotationMatrix();
1037 coil2rm->rotateZ(CLHEP::pi/2.0);
1038 coil3rm->rotateZ(CLHEP::pi);
1039 coil4rm->rotateZ(CLHEP::pi*1.5);
1040 allRotationMatrices.insert(coil2rm);
1041 allRotationMatrices.insert(coil3rm);
1042 allRotationMatrices.insert(coil4rm);
1046 G4bool buildCoil =
true;
1047 G4bool buildCollar =
true;
1048 if (coilInnerRadius > coilOuterRadius)
1049 {buildCoil =
false;}
1052 if ((coilInnerRadius > collarInnerRadius) && (coilInnerRadius < (massShift - collarBoxHalfWidth)))
1053 {collarInnerRadius = containerInnerRadius +
lengthSafety;}
1054 if (coilInnerRadius > (massShift - collarBoxHalfWidth))
1055 {buildCollar =
false;}
1056 G4bool buildAtAll = containerInnerRadius > (beamPipeAxisSeparation - collarOuterRadius - 1*CLHEP::mm);
1057 if ((coilInnerRadius > collarOuterRadius) || buildAtAll)
1059 throw BDSException(__METHOD_NAME__,
"error in component \"" + name +
"\"\n" +
1060 "this beam pipe is too big to use with the LHC dipole geometry\n" +
1061 "Please consider using a different magnet geometry for this particular magnet");
1064 G4ThreeVector dipolePosition;
1067 dipolePosition = G4ThreeVector(massShift,0.,0.);
1068 beamPipeAxisSeparation *= -1;
1070 G4cout << __METHOD_NAME__ <<
"dipole to the left" << G4endl;
1075 dipolePosition = G4ThreeVector(-massShift,0.,0.);
1078 G4cout << __METHOD_NAME__ <<
"dipole to the right" << G4endl;
1087 G4VSolid* containerSolidOuter =
new G4Tubs(name +
"_contiainer_solid_outer",
1094 G4VSolid* containerSolidInner =
new G4Tubs(name +
"_contiainer_solid_inner",
1096 containerInnerRadius,
1100 allSolids.insert(containerSolidOuter);
1101 allSolids.insert(containerSolidInner);
1102 containerSolid =
new G4SubtractionSolid(name +
"_container_solid",
1103 containerSolidOuter,
1104 containerSolidInner,
1111 G4VSolid* containerSolidOuter =
new G4Tubs(name +
"_contiainer_solid_outer",
1117 allSolids.insert(containerSolidOuter);
1118 containerSolid =
new G4SubtractionSolid(name +
"_container_solid",
1119 containerSolidOuter,
1132 magnetContainerLV =
new G4LogicalVolume(magnetContainerSolid,
1134 name +
"_container_lv");
1135 containerLV =
new G4LogicalVolume(containerSolid,
1137 name +
"_container_lv");
1142 G4VSolid* coil1 =
nullptr;
1143 G4VSolid* coil2 =
nullptr;
1144 G4LogicalVolume* coil1LV =
nullptr;
1145 G4LogicalVolume* coil2LV =
nullptr;
1146 G4VPhysicalVolume* coil1PV =
nullptr;
1147 G4VPhysicalVolume* coil2PV =
nullptr;
1148 G4VPhysicalVolume* coil3PV =
nullptr;
1149 G4VPhysicalVolume* coil4PV =
nullptr;
1150 G4VPhysicalVolume* coil5PV =
nullptr;
1151 G4VPhysicalVolume* coil6PV =
nullptr;
1152 G4VPhysicalVolume* coil7PV =
nullptr;
1153 G4VPhysicalVolume* coil8PV =
nullptr;
1156 G4VSolid* pole1 =
nullptr;
1157 G4VSolid* pole2 =
nullptr;
1158 G4LogicalVolume* pole1LV =
nullptr;
1159 G4LogicalVolume* pole2LV =
nullptr;
1160 G4VPhysicalVolume* pole1PV =
nullptr;
1161 G4VPhysicalVolume* pole2PV =
nullptr;
1162 G4VPhysicalVolume* pole3PV =
nullptr;
1163 G4VPhysicalVolume* pole4PV =
nullptr;
1164 G4VPhysicalVolume* pole5PV =
nullptr;
1165 G4VPhysicalVolume* pole6PV =
nullptr;
1166 G4VPhysicalVolume* pole7PV =
nullptr;
1167 G4VPhysicalVolume* pole8PV =
nullptr;
1170 G4VSolid* collar =
nullptr;
1171 G4VSolid* collars =
nullptr;
1172 G4LogicalVolume* collarsLV =
nullptr;
1179 G4VisAttributes* coilVisAtt =
new G4VisAttributes(*
BDSColours::Instance()->GetColour(
"LHCcoil"));
1181 G4VisAttributes* collarVisAtt =
new G4VisAttributes(*
BDSColours::Instance()->GetColour(
"LHCcollar"));
1183 allVisAttributes.insert(coilVisAtt);
1184 allVisAttributes.insert(collarVisAtt);
1189 coil1 =
new G4Tubs(name+
"_coil1_solid",
1196 coil1LV =
new G4LogicalVolume(coil1,
1199 coil1LV->SetVisAttributes(coilVisAtt);
1200 allSolids.insert(coil1);
1201 allLogicalVolumes.insert(coil1LV);
1204 pole1 =
new G4Tubs(name+
"_pole1_solid",
1210 pole1LV =
new G4LogicalVolume(pole1,
1211 stainlesssteel_316LN_2K,
1213 pole1LV->SetVisAttributes(collarVisAtt);
1214 allSolids.insert(pole1);
1215 allLogicalVolumes.insert(pole1LV);
1218 coil1PV =
new G4PVPlacement(
nullptr,
1226 coil2PV =
new G4PVPlacement(coil2rm,
1234 coil3PV =
new G4PVPlacement(coil3rm,
1242 coil4PV =
new G4PVPlacement(coil4rm,
1250 allPhysicalVolumes.insert(coil1PV);
1251 allPhysicalVolumes.insert(coil2PV);
1252 allPhysicalVolumes.insert(coil3PV);
1253 allPhysicalVolumes.insert(coil4PV);
1256 pole1PV =
new G4PVPlacement(
nullptr,
1264 pole2PV =
new G4PVPlacement(coil2rm,
1272 pole3PV =
new G4PVPlacement(coil3rm,
1280 pole4PV =
new G4PVPlacement(coil4rm,
1288 allPhysicalVolumes.insert(pole1PV);
1289 allPhysicalVolumes.insert(pole2PV);
1290 allPhysicalVolumes.insert(pole3PV);
1291 allPhysicalVolumes.insert(pole4PV);
1295 coil2 =
new G4Tubs(name+
"_coil2_solid",
1301 coil2LV =
new G4LogicalVolume(coil2,
1304 coil2LV->SetVisAttributes(coilVisAtt);
1305 allSolids.insert(coil2);
1306 allLogicalVolumes.insert(coil2LV);
1309 pole2 =
new G4Tubs(name+
"_pole2_solid",
1315 pole2LV =
new G4LogicalVolume(pole2,
1316 stainlesssteel_316LN_2K,
1318 pole2LV->SetVisAttributes(collarVisAtt);
1319 allSolids.insert(pole2);
1320 allLogicalVolumes.insert(pole2LV);
1323 coil5PV =
new G4PVPlacement(
nullptr,
1331 coil6PV =
new G4PVPlacement(coil2rm,
1339 coil7PV =
new G4PVPlacement(coil3rm,
1347 coil8PV =
new G4PVPlacement(coil4rm,
1355 allPhysicalVolumes.insert(coil5PV);
1356 allPhysicalVolumes.insert(coil6PV);
1357 allPhysicalVolumes.insert(coil7PV);
1358 allPhysicalVolumes.insert(coil8PV);
1361 pole5PV =
new G4PVPlacement(
nullptr,
1369 pole6PV =
new G4PVPlacement(coil2rm,
1377 pole7PV =
new G4PVPlacement(coil3rm,
1385 pole8PV =
new G4PVPlacement(coil4rm,
1394 allPhysicalVolumes.insert(pole5PV);
1395 allPhysicalVolumes.insert(pole6PV);
1396 allPhysicalVolumes.insert(pole7PV);
1397 allPhysicalVolumes.insert(pole8PV);
1401 collar =
new G4Tubs(name+
"_collar_solid",
1407 allSolids.insert(collar);
1411 if (collarInnerRadius == collarInnerRadiusF)
1414 collars =
new G4UnionSolid(name +
"_collars_solid",
1422 G4VSolid* collar2 =
new G4Tubs(name+
"_collar2_solid",
1428 allSolids.insert(collar2);
1429 collars =
new G4UnionSolid(name +
"_collars_solid",
1435 allSolids.insert(collars);
1438 collarsLV =
new G4LogicalVolume(collars,
1439 stainlesssteel_316LN_2K,
1440 name+
"_collars_lv");
1441 collarsLV->SetVisAttributes(collarVisAtt);
1442 allLogicalVolumes.insert(collarsLV);
1444 G4PVPlacement* collarPV =
new G4PVPlacement(
nullptr,
1452 allPhysicalVolumes.insert(collarPV);
1456 G4VSolid* collarSubtractionCylinder =
new G4Tubs(name+
"_collar_subtraction_solid",
1463 G4VSolid* collarSubtractionCylinders =
new G4UnionSolid(name +
"_collar_subtraction_cylinders",
1464 collarSubtractionCylinder,
1465 collarSubtractionCylinder,
1470 G4VSolid* yokeCylinder =
new G4Tubs(name+
"_yoke_cylinder_solid",
1475 CLHEP::twopi * CLHEP::rad);
1477 yokeSolid =
new G4SubtractionSolid(name+
"_yoke_solid",
1479 collarSubtractionCylinders,
1482 allSolids.insert(collarSubtractionCylinder);
1483 allSolids.insert(collarSubtractionCylinders);
1484 allSolids.insert(yokeCylinder);
1486 stainlesssteel_304L_2K,
1490 G4VisAttributes* LHCred =
new G4VisAttributes(*
BDSColours::Instance()->GetColour(
"LHCyokered"));
1492 allVisAttributes.insert(LHCred);
1493 yokeLV->SetVisAttributes(LHCred);
1495 allLogicalVolumes.insert(yokeLV);
1498 yokePV =
new G4PVPlacement(
nullptr,
1499 G4ThreeVector(0,0,0),
1506 allPhysicalVolumes.insert(yokePV);
1521 stainlesssteel_316LN_2K);
1524 G4PVPlacement* secondBPPV =
new G4PVPlacement(
nullptr,
1527 name +
"_second_beampipe_pv",
1532 allPhysicalVolumes.insert(secondBPPV);
1539 for (
auto lv : allLogicalVolumes)
1546 G4double containerRadius = yokeOuterRadius;
1549 -containerRadius,containerRadius,
1550 -length*0.5,length*0.5);
1577 G4double containerLength,
1586 G4double containerLength,
1595 G4double containerLength,
1604 G4double containerLength,
1613 G4double containerLength,
1622 G4double containerLength,
1631 G4double containerLength,
1640 G4double containerLength,
1644 return CreateLHCDipole(name, length, beamPipe, containerLength, recipe, YokeColour::kicker);
1649 G4double& horizontalWidth)
1652 if (horizontalWidth < 202*CLHEP::mm )
1653 {horizontalWidth = 202*CLHEP::mm;}
static BDSBeamPipeFactory * Instance()
Singleton accessor.
Holder class for all information required to describe a beam pipe model.
G4Material * vacuumMaterial
Public member for direct access.
A holder class for a piece of beam pipe geometry.
G4VSolid * GetContainerSubtractionSolid() const
default destructor sufficient as G4 manages solids and LVs
G4double GetContainerRadius() const
If it is circular, we need the radius.
G4bool ContainerIsCircular() const
static BDSColours * Instance()
singleton pattern
G4Colour * GetColour(const G4String &type, G4bool normaliseTo255=true)
Get colour from name.
General exception with possible name of object and message.
Holder for +- extents in 3 dimensions.
G4bool checkOverlaps
Cache of global constants variable.
G4double lengthSafety
Cache of global constants variable.
G4VisAttributes * containerVisAttr
Cache of global constants variable.
G4double lengthSafetyLarge
Cache of global constants variable.
G4int nSegmentsPerCircle
Cache of global constants variable.
G4UserLimits * defaultUserLimits
Cache of global constants variable.
A generic geometry component for a bdsim model.
G4LogicalVolume * GetContainerLogicalVolume() const
Accessor - see member for more info.
void RegisterRotationMatrix(G4RotationMatrix *rotationMatrix)
void RegisterDaughter(BDSGeometryComponent *anotherComponent)
void RegisterLogicalVolume(G4LogicalVolume *logicalVolume)
void RegisterPhysicalVolume(G4VPhysicalVolume *physicalVolume)
void RegisterVisAttributes(G4VisAttributes *visAttribute)
void RegisterSolid(G4VSolid *solid)
void RegisterSensitiveVolume(G4LogicalVolume *sensitiveVolume, BDSSDType sensitivityType)
static BDSGlobalConstants * Instance()
Access method.
virtual BDSMagnetOuter * CreateSolenoid(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)=0
solenoid outer volume
virtual void CleanUp()
Empty containers for next use - factories are never deleted so can't rely on scope.
void SetFaceNormals(BDSMagnetOuter *outer)
Copy face normals from members to an instance of outer.
virtual BDSMagnetOuter * CreateDecapole(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)=0
decapole outer volume
virtual BDSMagnetOuter * CreateMuonSpoiler(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)=0
muon spoiler outer volume
virtual BDSMagnetOuter * CreateMultipole(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)=0
general multipole outer volume - could be any 2N order multipole
G4VSolid * yokeSolid
Solid for outer part that connects all poles.
virtual BDSMagnetOuter * CreateOctupole(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)=0
octupole outer volume
virtual BDSMagnetOuter * CreateRfCavity(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)=0
RF cavity outer volume.
virtual BDSMagnetOuter * CreateSextupole(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)=0
sextupole outer volume
void BuildMagnetContainerSolidStraight(const G4String &name, G4double magnetContainerLength, G4double magnetContainerRadius)
void BuildMagnetContainerSolidAngled(const G4String &name, G4double magnetContainerLength, G4double magnetContainerRadius, G4bool flatFaces=false)
Factory that produces cylindrical magnet geometry.
virtual BDSMagnetOuter * CreateRfCavity(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)
RF cavity outer volume.
virtual BDSMagnetOuter * CreateSectorBend(G4String name, G4double length, const BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)
sector bend outer volume
static const G4double beamSeparation
Used in many places - make it a constant in the code and put here as most relevant.
virtual BDSMagnetOuter * CreateSolenoid(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)
solenoid outer volume
virtual BDSMagnetOuter * CreateMuonSpoiler(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)
muon spoiler outer volume
virtual BDSMagnetOuter * CreateDecapole(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)
decapole outer volume
YokeColour
Enum up front for yoke colouring.
virtual BDSMagnetOuter * CreateSextupole(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)
sextupole outer volume
virtual BDSMagnetOuter * CreateQuadrupole(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)
quadrupole outer volume
BDSMagnetOuterFactoryBase * cylindrical
Default factory to fall back to.
virtual BDSMagnetOuter * CreateOctupole(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)
octupole outer volume
virtual BDSMagnetOuter * CreateRectangularBend(G4String name, G4double length, const BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)
rectangular bend outer volume
virtual BDSMagnetOuter * CreateMultipole(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)
general multipole outer volume - could be any 2N order multipole
virtual BDSMagnetOuter * CreateKicker(G4String name, G4double length, const BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe, G4bool vertical)
horizontal and vertical kicker outer volume
BDSMagnetOuter * CreateLHCDipole(const G4String &name, G4double length, const BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe, YokeColour colourIn)
void TestInputParameters(const BDSBeamPipe *beamPipe, G4double &horizontalWidthIn)
test inputs for no null pointers or overlapping volumes due to poorly defined sizes
Holder struct of all information required to create the outer geometry of a magnet.
An object for both the returned magnet outer body but also a tight fitting container for the whole ma...
static BDSMaterials * Instance()
Singleton pattern access.
G4Material * GetMaterial(G4String material) const
Get material by name.
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())
G4int CalculateOrientation(G4double angle)
std::pair< G4ThreeVector, G4ThreeVector > CalculateFaces(G4double angleInIn, G4double angleOutIn)
Calculate input and output normal vector.