Beispiel #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;
	}
}
Beispiel #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;
	}
}
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);
}