00001 #include "BDSMagnetOuterFactoryCylindrical.hh"
00002
00003 #include "BDSBeamPipe.hh"
00004 #include "BDSDebug.hh"
00005 #include "BDSExecOptions.hh"
00006 #include "BDSGeometryComponent.hh"
00007 #include "BDSGlobalConstants.hh"
00008 #include "BDSMagnetColours.hh"
00009 #include "BDSMaterials.hh"
00010 #include "BDSSDManager.hh"
00011 #include "BDSUtilities.hh"
00012
00013 #include "globals.hh"
00014 #include "G4Colour.hh"
00015 #include "G4CutTubs.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 "G4UserLimits.hh"
00023 #include "G4VisAttributes.hh"
00024 #include "G4VSolid.hh"
00025
00026 #include <cmath>
00027 #include <utility>
00028 #include <algorithm>
00029
00030
00031 BDSMagnetOuterFactoryCylindrical* BDSMagnetOuterFactoryCylindrical::_instance = 0;
00032
00033 BDSMagnetOuterFactoryCylindrical* BDSMagnetOuterFactoryCylindrical::Instance()
00034 {
00035 if (_instance == 0)
00036 {_instance = new BDSMagnetOuterFactoryCylindrical();}
00037 return _instance;
00038 }
00039
00040 BDSMagnetOuterFactoryCylindrical::BDSMagnetOuterFactoryCylindrical()
00041 {;}
00042
00043 BDSMagnetOuterFactoryCylindrical::~BDSMagnetOuterFactoryCylindrical()
00044 {
00045 _instance = 0;
00046 }
00047
00048 BDSGeometryComponent* BDSMagnetOuterFactoryCylindrical::CreateSectorBend(G4String name,
00049 G4double length,
00050 BDSBeamPipe* beamPipe,
00051 G4double boxSize,
00052 G4double angle,
00053 G4Material* outerMaterial)
00054 {
00055 #ifdef BDSDEBUG
00056 G4cout << __METHOD_NAME__ << G4endl;
00057 #endif
00058
00059 CleanUp();
00060
00061
00062 TestInputParameters(beamPipe,boxSize,outerMaterial);
00063
00064 G4int orientation = BDS::CalculateOrientation(angle);
00065 G4double zcomponent = cos(fabs(angle*0.5));
00066 G4double xcomponent = sin(fabs(angle*0.5));
00067 G4ThreeVector inputface = G4ThreeVector(-orientation*xcomponent, 0.0, -1.0*zcomponent);
00068 G4ThreeVector outputface = G4ThreeVector(-orientation*xcomponent, 0.0, zcomponent);
00069
00070 if (beamPipe->ContainerIsCircular())
00071 {
00072
00073 yokeSolid = new G4CutTubs(name + "_yoke_solid",
00074 beamPipe->GetContainerRadius() + 2*lengthSafety,
00075 boxSize*0.5,
00076 length*0.5-2*lengthSafety,
00077 0,
00078 CLHEP::twopi,
00079 inputface,
00080 outputface);
00081
00082
00083 containerSolid = new G4CutTubs(name + "_contiainer_solid",
00084 beamPipe->GetContainerRadius() + lengthSafety,
00085 boxSize*0.5 + lengthSafety,
00086 length*0.5,
00087 0,
00088 CLHEP::twopi,
00089 inputface,
00090 outputface);
00091 }
00092 else
00093 {
00094 G4VSolid* yokeSolidCylinder = new G4CutTubs(name + "_yoke_solid_cylinder",
00095 0,
00096 boxSize*0.5,
00097 length*0.5-2*lengthSafety,
00098 0,
00099 CLHEP::twopi,
00100 inputface,
00101 outputface);
00102 yokeSolid = new G4SubtractionSolid(name + "_yoke_solid",
00103 yokeSolidCylinder,
00104 beamPipe->GetContainerSubtractionSolid());
00105
00106
00107 G4VSolid* containerSolidCylinder = new G4CutTubs(name + "_container_solid_cylinder",
00108 0,
00109 boxSize*0.5 + lengthSafety,
00110 length*0.5,
00111 0,
00112 CLHEP::twopi,
00113 inputface,
00114 outputface);
00115 containerSolid = new G4SubtractionSolid(name + "_container_solid",
00116 containerSolidCylinder,
00117 beamPipe->GetContainerSubtractionSolid());
00118 }
00119 return CommonFinalConstructor(name,length,boxSize,outerMaterial,BDSMagnetColours::Instance()->GetMagnetColour("sectorbend"));
00120 }
00121
00122 BDSGeometryComponent* BDSMagnetOuterFactoryCylindrical::CreateRectangularBend(G4String name,
00123 G4double length,
00124 BDSBeamPipe* beamPipe,
00125 G4double boxSize,
00126 G4double ,
00127 G4Material* outerMaterial)
00128 {
00129 #ifdef BDSDEBUG
00130 G4cout << __METHOD_NAME__ << G4endl;
00131 #endif
00132
00133 CreateCylindricalSolids(name, length, beamPipe, boxSize);
00134 return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("rectangularbend"));
00135 }
00136
00137 BDSGeometryComponent* BDSMagnetOuterFactoryCylindrical::CreateQuadrupole(G4String name,
00138 G4double length,
00139 BDSBeamPipe* beamPipe,
00140 G4double boxSize,
00141 G4Material* outerMaterial)
00142 {
00143 #ifdef BDSDEBUG
00144 G4cout << __METHOD_NAME__ << G4endl;
00145 #endif
00146 CreateCylindricalSolids(name, length, beamPipe, boxSize);
00147 return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("quadrupole"));
00148 }
00149
00150 BDSGeometryComponent* BDSMagnetOuterFactoryCylindrical::CreateSextupole(G4String name,
00151 G4double length,
00152 BDSBeamPipe* beamPipe,
00153 G4double boxSize,
00154 G4Material* outerMaterial)
00155 {
00156 CreateCylindricalSolids(name, length, beamPipe, boxSize);
00157 return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("sextupole"));
00158 }
00159
00160 BDSGeometryComponent* BDSMagnetOuterFactoryCylindrical::CreateOctupole(G4String name,
00161 G4double length,
00162 BDSBeamPipe* beamPipe,
00163 G4double boxSize,
00164 G4Material* outerMaterial)
00165 {
00166 #ifdef BDSDEBUG
00167 G4cout << __METHOD_NAME__ << G4endl;
00168 #endif
00169 CreateCylindricalSolids(name, length, beamPipe, boxSize);
00170 return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("octupole"));
00171 }
00172
00173 BDSGeometryComponent* BDSMagnetOuterFactoryCylindrical::CreateDecapole(G4String name,
00174 G4double length,
00175 BDSBeamPipe* beamPipe,
00176 G4double boxSize,
00177 G4Material* outerMaterial)
00178 {
00179 #ifdef BDSDEBUG
00180 G4cout << __METHOD_NAME__ << G4endl;
00181 #endif
00182 CreateCylindricalSolids(name, length, beamPipe, boxSize);
00183 return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("decapole"));
00184 }
00185
00186 BDSGeometryComponent* BDSMagnetOuterFactoryCylindrical::CreateSolenoid(G4String name,
00187 G4double length,
00188 BDSBeamPipe* beamPipe,
00189 G4double boxSize,
00190 G4Material* outerMaterial)
00191 {
00192 CreateCylindricalSolids(name, length, beamPipe, boxSize);
00193 return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("solenoid"));
00194 }
00195
00196 BDSGeometryComponent* BDSMagnetOuterFactoryCylindrical::CreateMultipole(G4String name,
00197 G4double length,
00198 BDSBeamPipe* beamPipe,
00199 G4double boxSize,
00200 G4Material* outerMaterial)
00201 {
00202 #ifdef BDSDEBUG
00203 G4cout << __METHOD_NAME__ << G4endl;
00204 #endif
00205 CreateCylindricalSolids(name, length, beamPipe, boxSize);
00206 return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("multipole"));
00207 }
00208
00209 BDSGeometryComponent* BDSMagnetOuterFactoryCylindrical::CreateRfCavity(G4String name,
00210 G4double length,
00211 BDSBeamPipe* beamPipe,
00212 G4double boxSize,
00213 G4Material* outerMaterial)
00214 {
00215 #ifdef BDSDEBUG
00216 G4cout << __METHOD_NAME__ << G4endl;
00217 #endif
00218 CreateCylindricalSolids(name, length, beamPipe, boxSize);
00219 return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("rfcavity"));
00220 }
00221
00222 BDSGeometryComponent* BDSMagnetOuterFactoryCylindrical::CreateMuSpoiler(G4String name,
00223 G4double length,
00224 BDSBeamPipe* beamPipe,
00225 G4double boxSize,
00226 G4Material* outerMaterial)
00227 {
00228 #ifdef BDSDEBUG
00229 G4cout << __METHOD_NAME__ << G4endl;
00230 #endif
00231 CreateCylindricalSolids(name, length, beamPipe, boxSize);
00232 return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("muspoiler"));
00233 }
00234
00235 BDSGeometryComponent* BDSMagnetOuterFactoryCylindrical::CreateKicker(G4String name,
00236 G4double length,
00237 BDSBeamPipe* beamPipe,
00238 G4double boxSize,
00239 G4bool ,
00240 G4Material* outerMaterial)
00241 {
00242 #ifdef BDSDEBUG
00243 G4cout << __METHOD_NAME__ << G4endl;
00244 #endif
00245
00246
00247 CreateCylindricalSolids(name, length, beamPipe, boxSize);
00248 return CommonFinalConstructor(name, length, boxSize, outerMaterial, BDSMagnetColours::Instance()->GetMagnetColour("hkicker"));
00249 }
00250
00252
00253 void BDSMagnetOuterFactoryCylindrical::CreateCylindricalSolids(G4String name,
00254 G4double length,
00255 BDSBeamPipe* beamPipe,
00256 G4double boxSize)
00257 {
00258
00259 CleanUp();
00260
00261 if (beamPipe->ContainerIsCircular())
00262 {
00263
00264 yokeSolid = new G4Tubs(name + "_yoke_solid",
00265 beamPipe->GetContainerRadius() + 2*lengthSafety,
00266 boxSize*0.5,
00267 length*0.5-2*lengthSafety,
00268 0,
00269 CLHEP::twopi);
00270
00271
00272 containerSolid = new G4Tubs(name + "_contiainer_solid",
00273 beamPipe->GetContainerRadius() + lengthSafety,
00274 boxSize*0.5 + lengthSafety,
00275 length*0.5,
00276 0,
00277 CLHEP::twopi);
00278 }
00279 else
00280 {
00281 G4VSolid* yokeSolidCylinder = new G4Tubs(name + "_yoke_solid_cylinder",
00282 0,
00283 boxSize*0.5,
00284 length*0.5-2*lengthSafety,
00285 0,
00286 CLHEP::twopi);
00287 yokeSolid = new G4SubtractionSolid(name + "_yoke_solid",
00288 yokeSolidCylinder,
00289 beamPipe->GetContainerSubtractionSolid());
00290
00291
00292 G4VSolid* containerSolidCylinder = new G4Tubs(name + "_container_solid_cylinder",
00293 0,
00294 boxSize*0.5 + lengthSafety,
00295 length*0.5,
00296 0,
00297 CLHEP::twopi);
00298 containerSolid = new G4SubtractionSolid(name + "_container_solid",
00299 containerSolidCylinder,
00300 beamPipe->GetContainerSubtractionSolid());
00301 }
00302 }
00303
00304 void BDSMagnetOuterFactoryCylindrical::TestInputParameters(BDSBeamPipe* beamPipe,
00305 G4double& boxSize,
00306 G4Material*& outerMaterial)
00307 {
00308
00309
00310 if (!outerMaterial)
00311 {outerMaterial = BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetEmptyMaterial());}
00312
00313
00314 if (beamPipe->ContainerIsCircular()) {
00315
00316 if (boxSize < 2*(beamPipe->GetContainerRadius()) )
00317 {boxSize = 2*(beamPipe->GetContainerRadius()) + 1*CLHEP::mm;}
00318 } else {
00319
00320
00321 G4double extentX = beamPipe->GetExtentX().second - beamPipe->GetExtentX().first;
00322 G4double extentY = beamPipe->GetExtentY().second - beamPipe->GetExtentY().first;
00323 if ( (boxSize < extentX) || (boxSize < extentY) ) {
00324
00325 boxSize = std::max(extentX,extentY) + 1*CLHEP::mm;
00326 }
00327 }
00328
00329 }
00330
00333 BDSGeometryComponent* BDSMagnetOuterFactoryCylindrical::CommonFinalConstructor(G4String name,
00334 G4double length,
00335 G4double boxSize,
00336 G4Material* outerMaterial,
00337 G4Colour* colour)
00338 {
00339 #ifdef BDSDEBUG
00340 G4cout << __METHOD_NAME__ << G4endl;
00341 #endif
00342
00343
00344 G4LogicalVolume* yokeLV = new G4LogicalVolume(yokeSolid,
00345 outerMaterial,
00346 name + "_yoke_lv");
00347
00348 G4Material* emptyMaterial = BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetEmptyMaterial());
00349 G4LogicalVolume* containerLV = new G4LogicalVolume(containerSolid,
00350 emptyMaterial,
00351 name + "_container_lv");
00352
00353
00354
00355
00356 G4VisAttributes* outerVisAttr = new G4VisAttributes(*colour);
00357 outerVisAttr->SetVisibility(true);
00358 outerVisAttr->SetForceLineSegmentsPerCircle(nSegmentsPerCircle);
00359 yokeLV->SetVisAttributes(outerVisAttr);
00360
00361 if (BDSExecOptions::Instance()->GetVisDebug())
00362 {containerLV->SetVisAttributes(BDSGlobalConstants::Instance()->GetVisibleDebugVisAttr());}
00363 else
00364 {containerLV->SetVisAttributes(BDSGlobalConstants::Instance()->GetInvisibleVisAttr());}
00365
00366
00367 #ifndef NOUSERLIMITS
00368 G4UserLimits* outerUserLimits = new G4UserLimits("outer_cuts");
00369 outerUserLimits->SetMaxAllowedStep( length * maxStepFactor );
00370 outerUserLimits->SetUserMinEkine(BDSGlobalConstants::Instance()->GetThresholdCutCharged());
00371 outerUserLimits->SetUserMaxTime(BDSGlobalConstants::Instance()->GetMaxTime());
00372
00373 yokeLV->SetUserLimits(outerUserLimits);
00374 containerLV->SetUserLimits(outerUserLimits);
00375 #endif
00376
00377
00378
00379
00380 new G4PVPlacement((G4RotationMatrix*)0,
00381 (G4ThreeVector)0,
00382 yokeLV,
00383 name + "_yoke_pv",
00384 containerLV,
00385 false,
00386 0,
00387 checkOverlaps);
00388
00389
00390
00391 G4double containerRadius = boxSize + lengthSafety;
00392 std::pair<double,double> extX = std::make_pair(-containerRadius,containerRadius);
00393 std::pair<double,double> extY = std::make_pair(-containerRadius,containerRadius);
00394 std::pair<double,double> extZ = std::make_pair(-length*0.5,length*0.5);
00395
00396
00397 BDSGeometryComponent* outer = new BDSGeometryComponent(containerSolid,
00398 containerLV,
00399 extX, extY, extZ);
00400
00401 outer->RegisterLogicalVolume(yokeLV);
00402
00403
00404 outer->RegisterSensitiveVolume(yokeLV);
00405
00406 return outer;
00407 }