void ParticleState::setId(int newId) { id = newId; if (isNucleus(id)) { pmass = nuclearMass(id); charge = chargeNumber(id) * eplus; if (id < 0) charge *= -1; // anti-nucleus } else { // pmass missing for non-nuclei charge = HepPID::charge(id) * eplus; } }
void ParticleState::setId(int newId) { id = newId; if (isNucleus(id)) { pmass = nuclearMass(id); charge = chargeNumber(id) * eplus; if (id < 0) charge *= -1; // anti-nucleus } else { if (abs(id) == 11) pmass = mass_electron; charge = HepPID::charge(id) * eplus; } }
void NuclearDecay::betaDecay(Candidate *candidate, bool isBetaPlus) const { double gamma = candidate->current.getLorentzFactor(); int id = candidate->current.getId(); int A = massNumber(id); int Z = chargeNumber(id); // beta- decay int electronId = 11; // electron int neutrinoId = -12; // anti-electron neutrino int dZ = 1; // beta+ decay if (isBetaPlus) { electronId = -11; // positron neutrinoId = 12; // electron neutrino dZ = -1; } // update candidate, nuclear recoil negligible try { candidate->current.setId(nucleusId(A, Z + dZ)); } catch (std::runtime_error &e) { KISS_LOG_ERROR<< "Something went wrong in the NuclearDecay\n" << "Please report this error on https://github.com/CRPropa/CRPropa3/issues including your simulation setup and the following random seed:\n" << Random::instance().getSeed_base64(); throw; } candidate->current.setLorentzFactor(gamma); if (not (haveElectrons or haveNeutrinos)) return; // Q-value of the decay, subtract total energy of emitted photons double m1 = nuclearMass(A, Z); double m2 = nuclearMass(A, Z+dZ); double Q = (m1 - m2 - mass_electron) * c_squared; // generate cdf of electron energy, neglecting Coulomb correction // see Basdevant, Fundamentals in Nuclear Physics, eq. (4.92) std::vector<double> energies; std::vector<double> densities; // cdf(E), unnormalized energies.reserve(51); densities.reserve(51); double me = mass_electron * c_squared; double cdf = 0; for (int i = 0; i <= 50; i++) { double E = me + i / 50. * Q; cdf += E * sqrt(E * E - me * me) * pow(Q + me - E, 2); energies.push_back(E); densities.push_back(cdf); } // draw random electron energy and angle Random &random = Random::instance(); double E = interpolate(random.rand() * cdf, densities, energies); double p = sqrt(E * E - me * me); // p*c double cosTheta = 2 * random.rand() - 1; // boost to lab frame double Ee = gamma * (E - p * cosTheta); double Enu = gamma * (Q + me - E) * (1 + cosTheta); // pnu*c ~ Enu Vector3d pos = random.randomInterpolatedPosition(candidate->previous.getPosition(), candidate->current.getPosition()); if (haveElectrons) candidate->addSecondary(electronId, Ee, pos); if (haveNeutrinos) candidate->addSecondary(neutrinoId, Enu, pos); }