Warning, file /geant4/examples/extended/exoticphysics/dmparticle/src/G4LDMBremModel.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 #include "G4LDMBremModel.hh"
0041
0042 #include "TestParameters.hh"
0043
0044 #include "G4LDMPhoton.hh"
0045 #include "G4Log.hh"
0046 #include "G4ParticleChangeForLoss.hh"
0047 #include "G4PhysicalConstants.hh"
0048 #include "G4SystemOfUnits.hh"
0049
0050
0051
0052 using namespace std;
0053
0054 G4LDMBremModel::G4LDMBremModel(const G4ParticleDefinition* p, const G4String& nam)
0055 : G4MuBremsstrahlungModel(p, nam)
0056 {
0057 fEpsilon = TestParameters::GetPointer()->GetAlphaFactor();
0058 theLDMPhoton = G4LDMPhoton::LDMPhoton();
0059 fLDMPhotonMass = theLDMPhoton->GetPDGMass();
0060 minThreshold = 1.2 * fLDMPhotonMass;
0061 }
0062
0063
0064
0065 G4LDMBremModel::~G4LDMBremModel() {}
0066
0067
0068
0069 G4double G4LDMBremModel::ComputeDEDXPerVolume(const G4Material*, const G4ParticleDefinition*,
0070 G4double, G4double)
0071 {
0072 return 0.0;
0073 }
0074
0075
0076
0077 G4double G4LDMBremModel::ComputeDMicroscopicCrossSection(G4double tkin, G4double Z,
0078 G4double gammaEnergy)
0079
0080 {
0081 G4double dxsection = 0.;
0082
0083 if (gammaEnergy > tkin || tkin < minThreshold) return dxsection;
0084
0085
0086
0087
0088
0089
0090 G4double E = tkin + mass;
0091 G4double v = gammaEnergy / E;
0092 G4double delta = 0.5 * mass * mass * v / (E - gammaEnergy);
0093 G4double rab0 = delta * sqrte;
0094
0095 G4int iz = std::max(1, std::min(G4lrint(Z), 99));
0096
0097 G4double z13 = 1.0 / nist->GetZ13(iz);
0098 G4double dn = mass * nist->GetA27(iz) / (70. * MeV);
0099
0100 G4double b = btf;
0101 if (1 == iz) b = bh;
0102
0103
0104 G4double rab1 = b * z13;
0105 G4double fn =
0106 G4Log(rab1 / (dn * (electron_mass_c2 + rab0 * rab1)) * (mass + delta * (dn * sqrte - 2.)));
0107 if (fn < 0.) fn = 0.;
0108
0109 G4double x = 1.0 - v;
0110
0111 if (particle->GetPDGSpin() != 0) {
0112 x += 0.75 * v * v;
0113 }
0114
0115 dxsection = coeff * x * Z * Z * fn / gammaEnergy;
0116 return dxsection;
0117 }
0118
0119
0120
0121 G4double G4LDMBremModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*,
0122 G4double kineticEnergy, G4double Z, G4double,
0123 G4double cutEnergy, G4double maxEnergy)
0124 {
0125 G4double cross = 0.0;
0126
0127 if (kineticEnergy <= lowestKinEnergy) return cross;
0128
0129 G4double tmax = std::min(maxEnergy, kineticEnergy);
0130 G4double cut = std::min(cutEnergy, kineticEnergy);
0131
0132 cut = std::max(cut, minThreshold);
0133 if (cut >= tmax) return cross;
0134
0135 cross = ComputeMicroscopicCrossSection(kineticEnergy, Z, cut);
0136
0137 if (tmax < kineticEnergy) {
0138 cross -= ComputeMicroscopicCrossSection(kineticEnergy, Z, tmax);
0139 }
0140 cross *= fEpsilon * fEpsilon;
0141
0142 return cross;
0143 }
0144
0145
0146
0147 void G4LDMBremModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
0148 const G4MaterialCutsCouple* couple,
0149 const G4DynamicParticle* dp, G4double minEnergy,
0150 G4double maxEnergy)
0151 {
0152 G4double kineticEnergy = dp->GetKineticEnergy();
0153
0154 G4double tmax = std::min(kineticEnergy, maxEnergy);
0155 G4double tmin = std::min(kineticEnergy, minEnergy);
0156 tmin = std::max(tmin, minThreshold);
0157 if (tmin >= tmax) return;
0158
0159
0160
0161 G4ParticleMomentum partDirection = dp->GetMomentumDirection();
0162
0163
0164 const G4Element* anElement = SelectRandomAtom(couple, particle, kineticEnergy);
0165 G4double Z = anElement->GetZ();
0166
0167 G4double totalEnergy = kineticEnergy + mass;
0168 G4double totalMomentum = sqrt(kineticEnergy * (kineticEnergy + 2.0 * mass));
0169
0170 G4double func1 = tmin * ComputeDMicroscopicCrossSection(kineticEnergy, Z, tmin);
0171
0172 G4double lnepksi, epksi;
0173 G4double func2;
0174
0175 G4double xmin = G4Log(tmin / MeV);
0176 G4double xmax = G4Log(tmax / tmin);
0177
0178 do {
0179 lnepksi = xmin + G4UniformRand() * xmax;
0180 epksi = MeV * G4Exp(lnepksi);
0181 func2 = epksi * ComputeDMicroscopicCrossSection(kineticEnergy, Z, epksi);
0182
0183
0184 } while (func2 < func1 * G4UniformRand());
0185
0186 G4double gEnergy = std::max(epksi, fLDMPhotonMass);
0187 G4double gMomentum = std::sqrt((epksi - fLDMPhotonMass) * (epksi + fLDMPhotonMass));
0188
0189
0190
0191 G4double gam = totalEnergy / mass;
0192 G4double rmax = gam * std::min(1.0, totalEnergy / gEnergy - 1.0);
0193 G4double rmax2 = rmax * rmax;
0194 G4double x = G4UniformRand() * rmax2 / (1.0 + rmax2);
0195
0196 G4double theta = std::sqrt(x / (1.0 - x)) / gam;
0197 G4double sint = std::sin(theta);
0198 G4double phi = twopi * G4UniformRand();
0199 G4double dirx = sint * cos(phi), diry = sint * sin(phi), dirz = cos(theta);
0200
0201 G4ThreeVector gDirection(dirx, diry, dirz);
0202 gDirection.rotateUz(partDirection);
0203
0204 partDirection *= totalMomentum;
0205 partDirection -= gMomentum * gDirection;
0206 partDirection = partDirection.unit();
0207
0208
0209
0210 kineticEnergy -= gEnergy;
0211
0212 fParticleChange->SetProposedKineticEnergy(kineticEnergy);
0213 fParticleChange->SetProposedMomentumDirection(partDirection);
0214
0215
0216 G4DynamicParticle* aLDMPhoton = new G4DynamicParticle(theLDMPhoton, gDirection, gEnergy);
0217 vdp->push_back(aLDMPhoton);
0218 }
0219
0220