Warning, file /geant4/examples/advanced/underground_physics/src/DMXParticleSource.cc was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 #include <cmath>
0049
0050 #include "DMXParticleSource.hh"
0051
0052 #include "G4PhysicalConstants.hh"
0053 #include "G4SystemOfUnits.hh"
0054 #include "G4PrimaryParticle.hh"
0055 #include "G4Event.hh"
0056 #include "Randomize.hh"
0057 #include "G4TransportationManager.hh"
0058 #include "G4VPhysicalVolume.hh"
0059 #include "G4PhysicalVolumeStore.hh"
0060 #include "G4ParticleTable.hh"
0061 #include "G4ParticleDefinition.hh"
0062 #include "G4IonTable.hh"
0063 #include "G4Ions.hh"
0064 #include "G4TrackingManager.hh"
0065 #include "G4Track.hh"
0066
0067
0068 DMXParticleSource::DMXParticleSource() {
0069
0070 NumberOfParticlesToBeGenerated = 1;
0071 particle_definition = nullptr;
0072 G4ThreeVector zero(0., 0., 0.);
0073 particle_momentum_direction = G4ParticleMomentum(1., 0., 0.);
0074 particle_energy = 1.0*MeV;
0075 particle_position = zero;
0076 particle_time = 0.0;
0077 particle_polarization = zero;
0078 particle_charge = 0.0;
0079
0080 SourcePosType = "Volume";
0081 Shape = "NULL";
0082 halfz = 0.;
0083 Radius = 0.;
0084 CentreCoords = zero;
0085 Confine = false;
0086 VolName = "NULL";
0087
0088 AngDistType = "iso";
0089 MinTheta = 0.;
0090 MaxTheta = pi;
0091 MinPhi = 0.;
0092 MaxPhi = twopi;
0093
0094 EnergyDisType = "Mono";
0095 MonoEnergy = 1*MeV;
0096
0097 verbosityLevel = 0;
0098
0099 theMessenger = new DMXParticleSourceMessenger(this);
0100 gNavigator = G4TransportationManager::GetTransportationManager()
0101 ->GetNavigatorForTracking();
0102 }
0103
0104 DMXParticleSource::~DMXParticleSource()
0105 {
0106 delete theMessenger;
0107 }
0108
0109 void DMXParticleSource::SetPosDisType(G4String PosType)
0110 {
0111 SourcePosType = PosType;
0112 }
0113
0114 void DMXParticleSource::SetPosDisShape(G4String shapeType)
0115 {
0116 Shape = shapeType;
0117 }
0118
0119 void DMXParticleSource::SetCentreCoords(G4ThreeVector coordsOfCentre)
0120 {
0121 CentreCoords = coordsOfCentre;
0122 }
0123
0124 void DMXParticleSource::SetHalfZ(G4double zhalf)
0125 {
0126 halfz = zhalf;
0127 }
0128
0129 void DMXParticleSource::SetRadius(G4double radius)
0130 {
0131 Radius = radius;
0132 }
0133
0134 void DMXParticleSource::ConfineSourceToVolume(G4String Vname)
0135 {
0136 VolName = Vname;
0137 if(verbosityLevel == 2) G4cout << VolName << G4endl;
0138
0139
0140 G4VPhysicalVolume *tempPV = nullptr;
0141 G4PhysicalVolumeStore *PVStore = nullptr;
0142 G4String theRequiredVolumeName = VolName;
0143 PVStore = G4PhysicalVolumeStore::GetInstance();
0144 G4bool found = false;
0145 if(verbosityLevel == 2) G4cout << PVStore->size() << G4endl;
0146
0147 tempPV = PVStore->GetVolume(theRequiredVolumeName, false);
0148 if (tempPV != nullptr) { found = true; }
0149
0150
0151 if(found == true) {
0152 if(verbosityLevel >= 1)
0153 G4cout << "Volume " << VolName << " exists" << G4endl;
0154 Confine = true;
0155 }
0156 else if(VolName=="NULL")
0157 Confine = false;
0158 else {
0159 G4cout << " **** Error: Volume does not exist **** " << G4endl;
0160 G4cout << " Ignoring confine condition" << G4endl;
0161 VolName = "NULL";
0162 Confine = false;
0163 }
0164 }
0165
0166 void DMXParticleSource::SetAngDistType(G4String atype)
0167 {
0168 AngDistType = atype;
0169 }
0170
0171 void DMXParticleSource::GeneratePointSource()
0172 {
0173
0174 if(SourcePosType == "Point")
0175 particle_position = CentreCoords;
0176 else
0177 if(verbosityLevel >= 1)
0178 G4cout << "Error SourcePosType is not set to Point" << G4endl;
0179 }
0180
0181 void DMXParticleSource::GeneratePointsInVolume()
0182 {
0183 G4ThreeVector RandPos;
0184 G4double x=0., y=0., z=0.;
0185
0186 if(SourcePosType != "Volume" && verbosityLevel >= 1)
0187 G4cout << "Error SourcePosType not Volume" << G4endl;
0188
0189 if(Shape == "Sphere") {
0190 x = Radius*2.;
0191 y = Radius*2.;
0192 z = Radius*2.;
0193 while(((x*x)+(y*y)+(z*z)) > (Radius*Radius)) {
0194 x = G4UniformRand();
0195 y = G4UniformRand();
0196 z = G4UniformRand();
0197
0198 x = (x*2.*Radius) - Radius;
0199 y = (y*2.*Radius) - Radius;
0200 z = (z*2.*Radius) - Radius;
0201 }
0202 }
0203
0204 else if(Shape == "Cylinder") {
0205 x = Radius*2.;
0206 y = Radius*2.;
0207 while(((x*x)+(y*y)) > (Radius*Radius)) {
0208 x = G4UniformRand();
0209 y = G4UniformRand();
0210 z = G4UniformRand();
0211 x = (x*2.*Radius) - Radius;
0212 y = (y*2.*Radius) - Radius;
0213 z = (z*2.*halfz) - halfz;
0214 }
0215 }
0216
0217 else
0218 G4cout << "Error: Volume Shape Does Not Exist" << G4endl;
0219
0220 RandPos.setX(x);
0221 RandPos.setY(y);
0222 RandPos.setZ(z);
0223 particle_position = CentreCoords + RandPos;
0224
0225 }
0226
0227 G4bool DMXParticleSource::IsSourceConfined()
0228 {
0229
0230
0231 if(Confine == false)
0232 G4cout << "Error: Confine is false" << G4endl;
0233 G4ThreeVector null_vec(0.,0.,0.);
0234 G4ThreeVector *ptr = &null_vec;
0235
0236
0237 G4VPhysicalVolume *theVolume;
0238 theVolume=gNavigator->LocateGlobalPointAndSetup(particle_position,ptr,true);
0239 G4String theVolName = theVolume->GetName();
0240 if(theVolName == VolName) {
0241 if(verbosityLevel >= 1)
0242 G4cout << "Particle is in volume " << VolName << G4endl;
0243 return(true);
0244 }
0245 else
0246 return(false);
0247 }
0248
0249 void DMXParticleSource::SetParticleMomentumDirection
0250 (G4ParticleMomentum aDirection) {
0251
0252 particle_momentum_direction = aDirection.unit();
0253 }
0254
0255 void DMXParticleSource::GenerateIsotropicFlux()
0256 {
0257
0258 G4double rndm, rndm2;
0259 G4double px, py, pz;
0260
0261 G4double sintheta, sinphi, costheta, cosphi;
0262 rndm = G4UniformRand();
0263 costheta = std::cos(MinTheta) - rndm * (std::cos(MinTheta)
0264 - std::cos(MaxTheta));
0265 sintheta = std::sqrt(1. - costheta*costheta);
0266
0267 rndm2 = G4UniformRand();
0268 Phi = MinPhi + (MaxPhi - MinPhi) * rndm2;
0269 sinphi = std::sin(Phi);
0270 cosphi = std::cos(Phi);
0271
0272 px = -sintheta * cosphi;
0273 py = -sintheta * sinphi;
0274 pz = -costheta;
0275
0276 G4double ResMag = std::sqrt((px*px) + (py*py) + (pz*pz));
0277 px = px/ResMag;
0278 py = py/ResMag;
0279 pz = pz/ResMag;
0280
0281 particle_momentum_direction.setX(px);
0282 particle_momentum_direction.setY(py);
0283 particle_momentum_direction.setZ(pz);
0284
0285
0286 if(verbosityLevel >= 2)
0287 G4cout << "Generating isotropic vector: "
0288 << particle_momentum_direction << G4endl;
0289 }
0290
0291 void DMXParticleSource::SetEnergyDisType(G4String DisType)
0292 {
0293 EnergyDisType = DisType;
0294 }
0295
0296 void DMXParticleSource::SetMonoEnergy(G4double menergy)
0297 {
0298 MonoEnergy = menergy;
0299 }
0300
0301 void DMXParticleSource::GenerateMonoEnergetic()
0302 {
0303 particle_energy = MonoEnergy;
0304 }
0305
0306 void DMXParticleSource::SetVerbosity(int vL)
0307 {
0308 verbosityLevel = vL;
0309 G4cout << "Verbosity Set to: " << verbosityLevel << G4endl;
0310 }
0311
0312 void DMXParticleSource::SetParticleDefinition
0313 (G4ParticleDefinition* aParticleDefinition)
0314 {
0315 particle_definition = aParticleDefinition;
0316 particle_charge = particle_definition->GetPDGCharge();
0317 }
0318
0319 void DMXParticleSource::GeneratePrimaryVertex(G4Event *evt)
0320 {
0321
0322 if(particle_definition==nullptr) {
0323 G4cout << "No particle has been defined!" << G4endl;
0324 return;
0325 }
0326
0327
0328 G4bool srcconf = false;
0329 G4int LoopCount = 0;
0330
0331 while(srcconf == false) {
0332 if(SourcePosType == "Point")
0333 GeneratePointSource();
0334 else if(SourcePosType == "Volume")
0335 GeneratePointsInVolume();
0336 else {
0337 G4cout << "Error: SourcePosType undefined" << G4endl;
0338 G4cout << "Generating point source" << G4endl;
0339 GeneratePointSource();
0340 }
0341 if(Confine == true) {
0342 srcconf = IsSourceConfined();
0343
0344
0345 }
0346 else if(Confine == false)
0347 srcconf = true;
0348
0349 ++LoopCount;
0350 if(LoopCount == 100000) {
0351 G4cout << "*************************************" << G4endl;
0352 G4cout << "LoopCount = 100000" << G4endl;
0353 G4cout << "Either the source distribution >> confinement" << G4endl;
0354 G4cout << "or any confining volume may not overlap with" << G4endl;
0355 G4cout << "the source distribution or any confining volumes" << G4endl;
0356 G4cout << "may not exist"<< G4endl;
0357 G4cout << "If you have set confine then this will be ignored" <<G4endl;
0358 G4cout << "for this event." << G4endl;
0359 G4cout << "*************************************" << G4endl;
0360 srcconf = true;
0361 }
0362 }
0363
0364
0365 if(AngDistType == "iso")
0366 GenerateIsotropicFlux();
0367 else if(AngDistType == "direction")
0368 SetParticleMomentumDirection(particle_momentum_direction);
0369 else
0370 G4cout << "Error: AngDistType has unusual value" << G4endl;
0371
0372 if(EnergyDisType == "Mono")
0373 GenerateMonoEnergetic();
0374 else
0375 G4cout << "Error: EnergyDisType has unusual value" << G4endl;
0376
0377
0378 G4PrimaryVertex* vertex =
0379 new G4PrimaryVertex(particle_position,particle_time);
0380
0381 if(verbosityLevel >= 2)
0382 G4cout << "Creating primaries and assigning to vertex" << G4endl;
0383
0384 G4double mass = particle_definition->GetPDGMass();
0385 G4double energy = particle_energy + mass;
0386 G4double pmom = std::sqrt(energy*energy-mass*mass);
0387 G4double px = pmom*particle_momentum_direction.x();
0388 G4double py = pmom*particle_momentum_direction.y();
0389 G4double pz = pmom*particle_momentum_direction.z();
0390
0391 if(verbosityLevel >= 1){
0392 G4cout << "Particle name: "
0393 << particle_definition->GetParticleName() << G4endl;
0394 G4cout << " Energy: "<<particle_energy << G4endl;
0395 G4cout << " Position: "<<particle_position<< G4endl;
0396 G4cout << " Direction: "<<particle_momentum_direction << G4endl;
0397 G4cout << " NumberOfParticlesToBeGenerated: "
0398 << NumberOfParticlesToBeGenerated << G4endl;
0399 }
0400
0401 for( G4int i=0; i<NumberOfParticlesToBeGenerated; ++i ) {
0402 G4PrimaryParticle* particle =
0403 new G4PrimaryParticle(particle_definition,px,py,pz);
0404 particle->SetMass( mass );
0405 particle->SetCharge( particle_charge );
0406 particle->SetPolarization(particle_polarization.x(),
0407 particle_polarization.y(),
0408 particle_polarization.z());
0409 vertex->SetPrimary( particle );
0410 }
0411 evt->AddPrimaryVertex( vertex );
0412 if(verbosityLevel > 1)
0413 G4cout << " Primary Vetex generated "<< G4endl;
0414 }