src/BDSMuSpoiler.cc

00001 /* BDSIM code.    Version 1.0
00002    Author: Grahame A. Blair, Royal Holloway, Univ. of London.
00003    Last modified 12.12.2004
00004    Copyright (c) 2004 by G.A.Blair.  ALL RIGHTS RESERVED. 
00005 */
00006 #include "BDSGlobalConstants.hh" 
00007 #include "BDSMuSpoiler.hh"
00008 #include "G4VisAttributes.hh"
00009 #include "G4LogicalVolume.hh"
00010 #include "G4VPhysicalVolume.hh"
00011 #include "G4PVPlacement.hh"               
00012 #include "G4SubtractionSolid.hh"
00013 #include "G4TransportationManager.hh"
00014 #include "G4SDManager.hh"
00015 #include "G4UserLimits.hh"
00016 #include "G4Tubs.hh"
00017 
00018 
00019 #include <map>
00020 
00021 //============================================================
00022 typedef std::map<G4String,int> LogVolCountMap;
00023 extern LogVolCountMap* LogVolCount;
00024 
00025 typedef std::map<G4String,G4LogicalVolume*> LogVolMap;
00026 extern LogVolMap* LogVol;
00027 //extern G4double BDS_Threshold_Energy;
00028 //============================================================
00029 
00030 BDSMuSpoiler::BDSMuSpoiler (G4String& aName,G4double aLength,G4double bpRad,
00031                             G4double rInner, G4double rOuter,G4double aBField, 
00032                             std::list<G4double> blmLocZ, std::list<G4double> blmLocTheta,
00033                             G4String aTunnelMaterial):
00034   BDSAcceleratorComponent(aName,
00035                          aLength,bpRad,bpRad,bpRad,
00036                           SetVisAttributes(), blmLocZ, blmLocTheta, aTunnelMaterial),
00037   itsPhysiComp(NULL),itsPhysiCompSoil(NULL),itsPhysiComp2(NULL),itsPhysiInnerBP(NULL),
00038   itsPhysiBP(NULL),itsSolidLogVol(NULL),itsInnerLogVol(NULL),itsBeampipeLogicalVolume(NULL),
00039   itsInnerBPLogicalVolume(NULL),itsBPTube(NULL),itsInnerBPTube(NULL),itsSoilTube(NULL),
00040   itsTunnelTube(NULL),itsInnerTunnelTube(NULL),itsInnerTunnelLogicalVolume(NULL),
00041   itsSoilTunnelLogicalVolume(NULL),itsTunnelUserLimits(NULL),itsSoilTunnelUserLimits(NULL),
00042   itsInnerTunnelUserLimits(NULL),itsVisAttributes(NULL),itsBPVisAttributes(NULL),
00043   itsEqRhs(NULL),
00044   itsBeampipeRadius(bpRad),
00045   itsInnerRadius(rInner),
00046   itsOuterRadius(rOuter),
00047   itsBField(aBField),
00048   itsMagField(NULL),itsFieldMgr(NULL)
00049 {
00050   G4double minInnRad =  itsBeampipeRadius + BDSGlobalConstants::Instance()->GetBeampipeThickness() + BDSGlobalConstants::Instance()->GetLengthSafety()/2.0;
00051   if( itsInnerRadius < minInnRad ){
00052     G4cout << "BDSMuSpoiler - WARNING - inner radius less than minimum. Changing inner radius from " << itsInnerRadius << " to " << minInnRad << G4endl;
00053     itsInnerRadius = minInnRad;
00054   }
00055 
00056   itsType="muspoiler";
00057   SetVisAttributes();
00058   SetBPVisAttributes();
00059   if ( (*LogVolCount)[itsName]==0)
00060     {
00061   G4double xLength, yLength;
00062   G4double totalTunnelRadius = BDSGlobalConstants::Instance()->GetTunnelRadius()+BDSGlobalConstants::Instance()->GetTunnelThickness()+BDSGlobalConstants::Instance()->GetTunnelSoilThickness()+std::max(BDSGlobalConstants::Instance()->GetTunnelOffsetX(),BDSGlobalConstants::Instance()->GetTunnelOffsetY());
00063   
00064   xLength = yLength = std::max(itsOuterRadius,BDSGlobalConstants::Instance()->GetComponentBoxSize()/2);
00065   xLength = yLength = std::max(xLength,totalTunnelRadius);
00066 
00067 #ifdef DEBUG 
00068   G4cout<<"marker volume : x/y="<<xLength/m<<
00069     " m, l= "<<  (itsLength+BDSGlobalConstants::Instance()->GetLengthSafety())/2/m <<" m"<<G4endl;
00070 #endif
00071 
00072   itsMarkerLogicalVolume=new G4LogicalVolume
00073     (new G4Box( itsName+"_solid",
00074                 xLength,
00075                 yLength,
00076                 (itsLength-BDSGlobalConstants::Instance()->GetLengthSafety())/2), //z half length 
00077      BDSMaterials::Instance()->GetMaterial("vacuum"),
00078      itsName+"_log");
00079 
00080   // now protect the fields inside the marker volume by giving the
00081   // marker a null magnetic field (otherwise G4VPlacement can
00082   // over-ride the already-created fields, by calling 
00083   // G4LogicalVolume::AddDaughter, which calls 
00084   // pDaughterLogical->SetFieldManager(fFieldManager, true) - the
00085   // latter 'true' over-writes all the other fields
00086       itsMarkerLogicalVolume->
00087         SetFieldManager(BDSGlobalConstants::Instance()->GetZeroFieldManager(),false);
00088       
00089       if(BDSGlobalConstants::Instance()->GetBuildTunnel()){
00090         BuildTunnel();
00091       }
00092       BuildMuSpoiler();
00093 
00094       (*LogVolCount)[itsName]=1;
00095       (*LogVol)[itsName]=itsMarkerLogicalVolume;
00096     }
00097   else
00098     {
00099       (*LogVolCount)[itsName]++;
00100       itsMarkerLogicalVolume=(*LogVol)[itsName];
00101     }  
00102 }
00103 
00104 void BDSMuSpoiler::BuildMuSpoiler()
00105 {
00106   itsSolidLogVol=
00107     new G4LogicalVolume(new G4Tubs(itsName+"_solid",
00108                                    itsInnerRadius+BDSGlobalConstants::Instance()->GetLengthSafety()/2.0,
00109                                    itsOuterRadius-BDSGlobalConstants::Instance()->GetLengthSafety()/2.0,
00110                                    itsLength/2-BDSGlobalConstants::Instance()->GetLengthSafety()/2.0,
00111                                    0,twopi*radian),
00112                         BDSMaterials::Instance()->GetMaterial("Iron"), 
00113                         itsName+"_solid");
00114 
00115   itsInnerLogVol=
00116     new G4LogicalVolume(new G4Tubs(itsName+"_inner",
00117                                    0.,
00118                                    itsInnerRadius,
00119                                    itsLength/2,
00120                                    0,twopi*radian),
00121                         BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetVacuumMaterial()),
00122                         itsName+"_inner");
00123 
00124   G4Material *bpMaterial = BDSMaterials::Instance()->GetMaterial( BDSGlobalConstants::Instance()->GetPipeMaterialName() );
00125 
00126   // build beampipe
00127 
00128 #ifdef DEBUG 
00129   G4cout << "Outer pipe :"
00130          << " r= " << itsBpRadius/m << " m"
00131          << " l= " << itsLength/(2.)/m << " m"
00132          << G4endl;
00133 #endif
00134 
00135   itsBPTube=new G4Tubs(itsName+"_bmp_solid",
00136                        itsBpRadius+BDSGlobalConstants::Instance()->GetLengthSafety()/2.0,
00137                        itsBpRadius+BDSGlobalConstants::Instance()->GetBeampipeThickness(),
00138                        itsLength/(2.),
00139                        0,twopi*radian);
00140 
00141 #ifdef DEBUG
00142   G4cout << "Inner pipe :"
00143          << " r= " << (itsBpRadius-BDSGlobalConstants::Instance()->GetBeampipeThickness() )/m
00144          << " m"
00145          << " l= " << itsLength/(2.)/m << " m"
00146          << G4endl;
00147 #endif
00148   
00149   itsInnerBPTube=new G4Tubs(itsName+"_inner_bmp_solid",
00150                                 0.,
00151                                 itsBpRadius,
00152                             itsLength/2 - BDSGlobalConstants::Instance()->GetLengthSafety()/2.0,
00153                                 0,twopi*radian);
00154 
00155   itsBeampipeLogicalVolume=     
00156     new G4LogicalVolume(itsBPTube,
00157                         bpMaterial,
00158                         itsName+"_bmp_log");
00159 
00160   itsInnerBPLogicalVolume=      
00161     new G4LogicalVolume(itsInnerBPTube,
00162                         BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetVacuumMaterial()),
00163                         itsName+"_inner_bmp_log");
00164 
00165 
00166 #ifndef NOUSERLIMITS
00167   G4UserLimits* AbsUserLimits =
00168     new G4UserLimits(DBL_MAX,DBL_MAX,BDSGlobalConstants::Instance()->GetMaxTime(),
00169                      BDSGlobalConstants::Instance()->GetThresholdCutCharged());
00170 
00171   AbsUserLimits->SetMaxAllowedStep(itsLength);
00172   itsInnerLogVol->SetUserLimits(AbsUserLimits);
00173 
00174   itsSolidLogVol->
00175     SetUserLimits(new G4UserLimits(DBL_MAX,DBL_MAX,BDSGlobalConstants::Instance()->GetMaxTime(),
00176                                        BDSGlobalConstants::Instance()->GetThresholdCutCharged()));
00177 
00178   itsInnerBPLogicalVolume->SetUserLimits(AbsUserLimits);
00179 
00180   itsBeampipeLogicalVolume->
00181     SetUserLimits(new G4UserLimits(DBL_MAX,DBL_MAX,BDSGlobalConstants::Instance()->GetMaxTime(),
00182                                        BDSGlobalConstants::Instance()->GetThresholdCutCharged()));
00183 #endif
00184   itsSolidLogVol->SetVisAttributes(itsVisAttributes);
00185   itsBeampipeLogicalVolume->SetVisAttributes(itsBPVisAttributes);
00186 
00187   if(itsBField)
00188     {
00189       itsMagField=new BDSMuSpoilerMagField(itsBField);
00190       itsFieldMgr=new G4FieldManager(itsMagField);
00191       itsSolidLogVol->SetFieldManager(itsFieldMgr,false);
00192     }
00193   
00194   itsPhysiComp2 = 
00195     new G4PVPlacement(
00196                       (G4RotationMatrix*)0,                // no rotation
00197                       (G4ThreeVector)0,                   // its position
00198                       itsInnerLogVol,      // its logical volume
00199                       itsName+"_combined", // its name
00200                       itsSolidLogVol,      // its mother  volume
00201                       false,               // no boolean operation
00202                       0, BDSGlobalConstants::Instance()->GetCheckOverlaps());              // copy number 
00203 
00204   //For geometric biasing etc.
00205   SetMultiplePhysicalVolumes(itsPhysiComp2);
00206 
00207   if(BDSGlobalConstants::Instance()->GetSensitiveComponents()){
00208     SetMultipleSensitiveVolumes(itsSolidLogVol);
00209   }
00210   if(BDSGlobalConstants::Instance()->GetSensitiveBeamPipe()){
00211     SetMultipleSensitiveVolumes(itsBeampipeLogicalVolume);
00212   }
00213 
00214   BuildBLMs();
00215 
00216   itsPhysiInnerBP = new G4PVPlacement(
00217                                    (G4RotationMatrix*)0,                        // no rotation
00218                                    (G4ThreeVector)0,                    // at (0,0,0)
00219                       itsInnerBPLogicalVolume,  // its logical volume
00220                       itsName+"_inner_bmp_phys",// its name
00221                       itsMarkerLogicalVolume,   // its mother  volume
00222                       false,                    // no boolean operation
00223                                    0, BDSGlobalConstants::Instance()->GetCheckOverlaps());                      // copy number
00224   
00225       itsPhysiBP = new G4PVPlacement(
00226                                   (G4RotationMatrix*)0,                      // no rotation
00227                                   (G4ThreeVector)0,                          // at (0,0,0)
00228                           itsBeampipeLogicalVolume,  // its logical volume
00229                           itsName+"_bmp_phys",       // its name
00230                           itsMarkerLogicalVolume,    // its mother  volume
00231                           false,                     // no boolean operation
00232                                   0, BDSGlobalConstants::Instance()->GetCheckOverlaps());                            // copy number
00233 
00234   itsPhysiComp = 
00235     new G4PVPlacement(
00236                       (G4RotationMatrix*)0,                  // no rotation
00237                       (G4ThreeVector)0,                     // its position
00238                       itsSolidLogVol,    // its logical volume
00239                       itsName+"_solid",      // its name
00240                       itsMarkerLogicalVolume, // its mother  volume
00241                       false,                 // no boolean operation
00242                       0, BDSGlobalConstants::Instance()->GetCheckOverlaps());                // copy number  
00243 
00244   //For geometric biasing etc.
00245   SetMultiplePhysicalVolumes(itsPhysiInnerBP);
00246   SetMultiplePhysicalVolumes(itsPhysiBP);
00247   SetMultiplePhysicalVolumes(itsPhysiComp);
00248 
00249 
00250 }
00251 
00252 void BDSMuSpoiler::BuildBLMs(){
00253   itsBlmLocationR=itsOuterRadius;
00254   BDSAcceleratorComponent::BuildBLMs();
00255 }
00256 
00257 
00258 G4VisAttributes* BDSMuSpoiler::SetVisAttributes()
00259 {
00260   itsVisAttributes=new G4VisAttributes(G4Colour(0.0,0.5,0.5));
00261   itsVisAttributes->SetForceSolid(true);
00262   itsVisAttributes->SetVisibility(true);
00263   return itsVisAttributes;
00264 }
00265 
00266 G4VisAttributes* BDSMuSpoiler::SetBPVisAttributes()
00267 {
00268   itsBPVisAttributes=new G4VisAttributes(G4Colour(0.2,0.2,0.2));
00269   itsBPVisAttributes->SetForceSolid(true);
00270   itsBPVisAttributes->SetVisibility(true);
00271   return itsBPVisAttributes;
00272 }
00273 
00274 
00275 BDSMuSpoiler::~BDSMuSpoiler()
00276 {
00277   delete itsVisAttributes;
00278   delete itsBPVisAttributes;
00279 
00280 //   delete itsInnerTunnelUserLimits;
00281 //   delete itsTunnelUserLimits;
00282 //   delete itsSoilTunnelUserLimits;
00283 
00284 //   delete itsSolidLogVol;
00285 //   delete itsInnerLogVol;
00286 //   delete itsBeampipeLogicalVolume;
00287 //   delete itsInnerBPLogicalVolume;
00288   
00289 //   delete itsBPTube;
00290 //   delete itsInnerBPTube;
00291 
00292   //  delete itsPhysiComp;
00293   //  delete itsPhysiComp2;
00294   //  delete itsPhysiInnerBP;
00295   //  delete itsPhysiBP;
00296   //  delete itsPhysiCompSoil;
00297 
00298   delete itsMagField;
00299   delete itsFieldMgr;
00300 
00301 //   delete itsSoilTube;
00302 //   delete itsTunnelTube;
00303 //   delete itsInnerTunnelTube;
00304 //   delete itsInnerTunnelLogicalVolume;
00305 //   delete itsSoilTunnelLogicalVolume;
00306 }

Generated on 27 Aug 2013 for BDSIM by  doxygen 1.4.7