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::process(Candidate *candidate) const { // the loop should be processed at least once for limiting the next step double step = candidate->getCurrentStep(); double z = candidate->getRedshift(); do { // check if nucleus int id = candidate->current.getId(); if (not (isNucleus(id))) return; int A = massNumber(id); int Z = chargeNumber(id); int N = A - Z; // check if particle can decay const std::vector<DecayMode> &decays = decayTable[Z * 31 + N]; if (decays.size() == 0) return; // find interaction mode with minimum random decay distance Random &random = Random::instance(); double randDistance = std::numeric_limits<double>::max(); int channel; double totalRate = 0; for (size_t i = 0; i < decays.size(); i++) { double rate = decays[i].rate; rate /= candidate->current.getLorentzFactor(); // relativistic time dilation rate /= (1 + z); // rate per light travel distance -> rate per comoving distance totalRate += rate; double d = -log(random.rand()) / rate; if (d > randDistance) continue; randDistance = d; channel = decays[i].channel; } // check if interaction doesn't happen if (step < randDistance) { // limit next step to a fraction of the mean free path candidate->limitNextStep(limit / totalRate); return; } // interact and repeat with remaining step performInteraction(candidate, channel); step -= randDistance; } while (step > 0); }
double NuclearDecay::meanFreePath(int id, double gamma) { if (not (isNucleus(id))) return std::numeric_limits<double>::max(); int A = massNumber(id); int Z = chargeNumber(id); int N = A - Z; // check if particle can decay const std::vector<DecayMode> &decays = decayTable[Z * 31 + N]; if (decays.size() == 0) return std::numeric_limits<double>::max(); double totalRate = 0; for (size_t i = 0; i < decays.size(); i++) { double rate = decays[i].rate; rate /= gamma; totalRate += rate; } return 1. / totalRate; }