示例#1
0
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;
	}
}
示例#2
0
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;
	}
}
示例#3
0
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);
}
示例#4
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;
}