7 std::size_t localDestroyNum, std::size_t oldDaughterLocal,
8 const Kokkos::View<ippl::Vector<double, 3>*>& parentR,
9 const Kokkos::View<ippl::Vector<double, 3>*>& parentP,
10 const Kokkos::View<double*>& parentDt,
11 const Kokkos::View<ippl::Vector<float, 3>*>& parentPol) {
12 using pc_size_type = ippl::detail::size_type;
23 const double asymSign = (chargeSign < 0) ? +1.0 : -1.0;
44 const double fMax = 2.0;
47 "MuonDecay::createDaughters",
static_cast<pc_size_type
>(localDestroyNum),
48 KOKKOS_LAMBDA(
const pc_size_type j) {
49 auto gen = pool.get_state();
54 x = xMin + (1.0 - xMin) * gen.drand(0.0, 1.0);
55 }
while (gen.drand(0.0, fMax) >= 2.0 * x * x * (3.0 - 2.0 * x));
58 const double eDaughter = x * eMax;
59 const double pMag = Kokkos::sqrt(
60 eDaughter * eDaughter - daughterMass * daughterMass);
89 double polX = 0.0, polY = 0.0, polZ = 0.0;
90 if (parentPol.extent(0) > 0) {
91 polX =
static_cast<double>(parentPol(j)[0]);
92 polY =
static_cast<double>(parentPol(j)[1]);
93 polZ =
static_cast<double>(parentPol(j)[2]);
95 const double polMag = Kokkos::sqrt(polX * polX + polY * polY + polZ * polZ);
97 const double alpha = (polMag > 0.0)
98 ? asymSign * polMag * (2.0 * x - 1.0) / (3.0 - 2.0 * x)
101 const double u = gen.drand(0.0, 1.0);
103 if (Kokkos::fabs(alpha) < 1.0e-12) {
104 cosTheta = 2.0 * u - 1.0;
107 const double aQ = alpha / 4.0;
108 const double bQ = 0.5;
109 const double cQ = 0.5 - alpha / 4.0 - u;
110 const double disc = bQ * bQ - 4.0 * aQ * cQ;
111 const double sq = Kokkos::sqrt(disc > 0.0 ? disc : 0.0);
112 const double r1 = (-bQ + sq) / (2.0 * aQ);
113 const double r2 = (-bQ - sq) / (2.0 * aQ);
115 const double pick = (r1 >= -1.0 && r1 <= 1.0) ? r1 : r2;
116 cosTheta = pick < -1.0 ? -1.0 : (pick > 1.0 ? 1.0 : pick);
118 const double sinTheta = Kokkos::sqrt(
119 1.0 - cosTheta * cosTheta > 0.0 ? 1.0 - cosTheta * cosTheta : 0.0);
120 const double phi = 2.0 *
Physics::pi * gen.drand(0.0, 1.0);
126 const double pLoc_x = pMag * sinTheta * Kokkos::cos(phi);
127 const double pLoc_y = pMag * sinTheta * Kokkos::sin(phi);
128 const double pLoc_z = pMag * cosTheta;
132 double pxRF, pyRF, pzRF;
133 if (polMag > 1.0e-30) {
134 const double nz_x = polX / polMag;
135 const double nz_y = polY / polMag;
136 const double nz_z = polZ / polMag;
138 double ex_x, ex_y, ex_z;
139 if (Kokkos::fabs(nz_x) <= Kokkos::fabs(nz_y)
140 && Kokkos::fabs(nz_x) <= Kokkos::fabs(nz_z)) {
141 const double n = Kokkos::sqrt(nz_y * nz_y + nz_z * nz_z);
145 }
else if (Kokkos::fabs(nz_y) <= Kokkos::fabs(nz_z)) {
146 const double n = Kokkos::sqrt(nz_x * nz_x + nz_z * nz_z);
151 const double n = Kokkos::sqrt(nz_x * nz_x + nz_y * nz_y);
157 const double ey_x = nz_y * ex_z - nz_z * ex_y;
158 const double ey_y = nz_z * ex_x - nz_x * ex_z;
159 const double ey_z = nz_x * ex_y - nz_y * ex_x;
160 pxRF = pLoc_x * ex_x + pLoc_y * ey_x + pLoc_z * nz_x;
161 pyRF = pLoc_x * ex_y + pLoc_y * ey_y + pLoc_z * nz_y;
162 pzRF = pLoc_x * ex_z + pLoc_y * ey_z + pLoc_z * nz_z;
174 const auto& parentMom = parentP(j);
175 const double bg2 = parentMom[0] * parentMom[0] + parentMom[1] * parentMom[1]
176 + parentMom[2] * parentMom[2];
177 const double gamma = Kokkos::sqrt(1.0 + bg2);
178 const double betaX = parentMom[0] / gamma;
179 const double betaY = parentMom[1] / gamma;
180 const double betaZ = parentMom[2] / gamma;
181 const double beta2 = bg2 / (gamma * gamma);
183 double pxLab, pyLab, pzLab;
185 const double betaDotP = betaX * pxRF + betaY * pyRF + betaZ * pzRF;
186 const double factor = (gamma - 1.0) * betaDotP / beta2 + gamma * eDaughter;
187 pxLab = pxRF + factor * betaX;
188 pyLab = pyRF + factor * betaY;
189 pzLab = pzRF + factor * betaZ;
198 const pc_size_type idx =
static_cast<pc_size_type
>(oldDaughterLocal) + j;
199 dR(idx) = parentR(j);
200 dP(idx)[0] = pxLab / daughterMass;
201 dP(idx)[1] = pyLab / daughterMass;
202 dP(idx)[2] = pzLab / daughterMass;
203 dDt(idx) = parentDt(j);
205 pool.free_state(gen);
void createDaughterParticles(std::size_t localDestroyNum, std::size_t oldDaughterLocal, const Kokkos::View< ippl::Vector< double, 3 > * > &parentR, const Kokkos::View< ippl::Vector< double, 3 > * > &parentP, const Kokkos::View< double * > &parentDt, const Kokkos::View< ippl::Vector< float, 3 > * > &parentPol) override
Create daughter particles from collected parent data.