29 m_cosThetaMin(std::cos(
m_cfg.thetaMin)),
32 m_cosThetaMax(std::nextafter(std::cos(
m_cfg.thetaMax),
33 std::numeric_limits<
double>::max())),
35 m_etaMin(-std::log(std::tan(0.5 *
m_cfg.thetaMin))),
36 m_etaMax(-std::log(std::tan(0.5 *
m_cfg.thetaMax))) {}
40 using UniformIndex = std::uniform_int_distribution<unsigned int>;
41 using UniformReal = std::uniform_real_distribution<double>;
45 UniformIndex particleTypeChoice(0
u,
m_cfg.randomizeCharge ? 1
u : 0
u);
51 const double qChoices[] = {
56 UniformReal cosThetaDist(m_cosThetaMin, m_cosThetaMax);
57 UniformReal
etaDist(m_etaMin, m_etaMax);
61 particles.reserve(
m_cfg.numParticles);
64 for (
size_t ip = 1; ip <=
m_cfg.numParticles; ++ip) {
69 const unsigned int type = particleTypeChoice(rng);
71 const double q = qChoices[
type];
73 double p = pDist(rng);
79 if (not
m_cfg.etaUniform) {
80 cosTheta = cosThetaDist(rng);
81 sinTheta = std::sqrt(1 - cosTheta * cosTheta);
84 const double theta = 2 * std::atan(std::exp(-eta));
85 sinTheta = std::sin(theta);
86 cosTheta = std::cos(theta);
95 p *=
m_cfg.pTransverse ? 1. / sinTheta : 1.;
99 particles.insert(particles.end(),
std::move(particle));