src/BDSSolenoid.cc

00001 //  
00002 //   BDSIM, (C) 2001-2007
00003 //   
00004 //   version 0.4
00005 //  
00006 //
00007 //
00008 //   Solenoid class
00009 //
00010 //
00011 //   History
00012 //
00013 //     21 Oct 2007 by Marchiori,  v.0.4
00014 //
00015 //
00016 
00017 
00018 #include "BDSGlobalConstants.hh" 
00019 
00020 #include "BDSSolenoid.hh"
00021 #include "G4Mag_UsualEqRhs.hh"
00022 #include "BDSSolenoidMagField.hh"
00023 #include "G4MagneticField.hh"
00024 #include "BDSSolenoidStepper.hh"
00025 #include "G4HelixImplicitEuler.hh"
00026 
00027 #include "G4Box.hh"
00028 #include "G4Tubs.hh"
00029 #include "G4VisAttributes.hh"
00030 #include "G4LogicalVolume.hh"
00031 #include "G4VPhysicalVolume.hh"
00032 #include "G4UserLimits.hh"
00033 #include "G4TransportationManager.hh"
00034 #include <map>
00035 
00036 //============================================================
00037 
00038 typedef std::map<G4String,int> LogVolCountMap;
00039 extern LogVolCountMap* LogVolCount;
00040 
00041 typedef std::map<G4String,G4LogicalVolume*> LogVolMap;
00042 extern LogVolMap* LogVol;
00043 
00044 extern BDSMaterials* theMaterials;
00045 //============================================================
00046 
00047 BDSSolenoid::BDSSolenoid(G4String aName, G4double aLength, 
00048                          G4double bpRad, G4double FeRad,
00049                          G4double bField, G4double outR,
00050                          std::list<G4double> blmLocZ, std::list<G4double> blmLocTheta,
00051                          G4String aTunnelMaterial, G4String aMaterial):
00052   BDSMultipole(aName, aLength, bpRad, FeRad, SetVisAttributes(), blmLocZ, blmLocTheta, aTunnelMaterial, aMaterial),
00053   itsBField(bField),
00054   itsMagField(NULL),itsStepper(NULL),itsEqRhs(NULL)
00055 {
00056   SetOuterRadius(outR);
00057   itsType="solenoid";
00058  
00059   if (!(*LogVolCount)[itsName])
00060     {
00061       //
00062       // build external volume
00063       // 
00064       BuildDefaultMarkerLogicalVolume();
00065 
00066       //
00067       // build beampipe (geometry + magnetic field)
00068       //
00069       BuildBPFieldAndStepper();
00070       BuildBPFieldMgr(itsStepper,itsMagField);
00071       BuildBeampipe();
00072 
00073       //
00074       // build magnet (geometry + magnetic field)
00075       //
00076       BuildDefaultOuterLogicalVolume(itsLength);
00077       if(BDSGlobalConstants::Instance()->GetIncludeIronMagFields())
00078         {
00079           G4cerr<<"IncludeIronMagFields option not implemented for solenoid class"<<G4endl;
00080         }
00081 
00082       BuildBLMs();
00083 
00084       //
00085       // define sensitive volumes for hit generation
00086       //
00087       if(BDSGlobalConstants::Instance()->GetSensitiveBeamPipe()){
00088         SetMultipleSensitiveVolumes(itsBeampipeLogicalVolume);
00089       }
00090       if(BDSGlobalConstants::Instance()->GetSensitiveComponents()){
00091         SetMultipleSensitiveVolumes(itsOuterLogicalVolume);
00092       }
00093 
00094       //
00095       // set visualization attributes
00096       //
00097       itsVisAttributes=SetVisAttributes();
00098       itsVisAttributes->SetForceSolid(true);
00099       itsOuterLogicalVolume->SetVisAttributes(itsVisAttributes);
00100 
00101       //
00102       // append marker logical volume to volume map
00103       //
00104       (*LogVolCount)[itsName]=1;
00105       (*LogVol)[itsName]=itsMarkerLogicalVolume;
00106     }
00107   else
00108     {
00109       (*LogVolCount)[itsName]++;
00110       if(BDSGlobalConstants::Instance()->GetSynchRadOn()&& BDSGlobalConstants::Instance()->GetSynchRescale())
00111         {
00112           // with synchrotron radiation, the rescaled magnetic field
00113           // means elements with the same name must have different
00114           //logical volumes, becuase they have different fields
00115           itsName+=BDSGlobalConstants::Instance()->StringFromInt((*LogVolCount)[itsName]);
00116 
00117           //
00118           // build external volume
00119           // 
00120           BuildDefaultMarkerLogicalVolume();
00121 
00122           //
00123           // build beampipe (geometry + magnetic field)
00124           //
00125           BuildBPFieldAndStepper();
00126           BuildBPFieldMgr(itsStepper,itsMagField);
00127           BuildBeampipe();
00128 
00129           //
00130           // build magnet (geometry + magnetic field)
00131           //
00132           BuildDefaultOuterLogicalVolume(itsLength);
00133           if(BDSGlobalConstants::Instance()->GetIncludeIronMagFields())
00134             {
00135               G4cerr<<"IncludeIronMagFields option not implemented for solenoid class"<<G4endl;
00136             }
00137           //When is SynchRescale(factor) called?
00138 
00139           //
00140           // define sensitive volumes for hit generation
00141           //
00142           if(BDSGlobalConstants::Instance()->GetSensitiveBeamPipe()){
00143             SetMultipleSensitiveVolumes(itsBeampipeLogicalVolume);
00144           }
00145           if(BDSGlobalConstants::Instance()->GetSensitiveComponents()){
00146             SetMultipleSensitiveVolumes(itsOuterLogicalVolume);
00147           }
00148           
00149           
00150           //
00151           // set visualization attributes
00152           //
00153           itsVisAttributes=new G4VisAttributes(G4Colour(1.,0.,0.)); //red
00154           itsVisAttributes->SetForceSolid(true);
00155           itsOuterLogicalVolume->SetVisAttributes(itsVisAttributes);
00156           
00157           //
00158           // append marker logical volume to volume map
00159           //
00160           (*LogVol)[itsName]=itsMarkerLogicalVolume;
00161         }
00162       else
00163         {
00164           //
00165           // use already defined marker volume
00166           //
00167           itsMarkerLogicalVolume=(*LogVol)[itsName];
00168         }      
00169     }
00170 }
00171   
00172 void BDSSolenoid::SynchRescale(G4double factor)
00173 {
00174 #ifdef _USE_GEANT4_STEPPER_
00175   itsMagField->SetBField(factor*itsBField);
00176 #else
00177   itsStepper->SetBField(factor*itsBField);
00178   itsMagField->SetFieldValue(G4ThreeVector(0.0,0.0,factor*itsBField));
00179 #endif
00180 #ifdef DEBUG 
00181   G4cout << "Solenoid " << itsName << " has been scaled" << G4endl;
00182 #endif
00183 }
00184 
00185 G4VisAttributes* BDSSolenoid::SetVisAttributes()
00186 {
00187   itsVisAttributes=new G4VisAttributes(G4Colour(1.,0.,0.)); //red
00188   return itsVisAttributes;
00189 }
00190 
00191 void BDSSolenoid::BuildBPFieldAndStepper()
00192 {
00193   // set up the magnetic field and stepper
00194 
00195 #ifdef _USE_GEANT4_STEPPER_
00196   // using Geant4
00197   itsMagField = new BDSSolenoidMagField(itsBField);
00198   itsEqRhs=new G4Mag_UsualEqRhs(itsMagField);
00199   itsStepper=new G4HelixImplicitEuler(itsEqRhs);
00200 #else
00201   // using BDSIM
00202   G4ThreeVector Bfield(0.,0.,itsBField);
00203   itsMagField=new G4UniformMagField(Bfield);
00204   itsEqRhs=new G4Mag_UsualEqRhs(itsMagField);
00205   itsStepper=new BDSSolenoidStepper(itsEqRhs);
00206   itsStepper->SetBField(itsBField);
00207 #endif
00208 }
00209 
00210 BDSSolenoid::~BDSSolenoid()
00211 {
00212   delete itsVisAttributes;
00213   delete itsMagField;
00214   delete itsEqRhs;
00215   delete itsStepper;
00216 }

Generated on 27 Aug 2013 for BDSIM by  doxygen 1.4.7