Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4MuonRadiativeDecayChannelWithSpin.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4MuonRadiativeDecayChannelWithSpin class implementation
27//
28// References:
29// - TRIUMF/TWIST Technote TN-55:
30// "Radiative muon decay" by P. Depommier and A. Vacheret
31// - Yoshitaka Kuno and Yasuhiro Okada
32// "Muon Decays and Physics Beyond the Standard Model"
33// Rev. Mod. Phys. 73, 151 (2001)
34//
35// Author: P.Gumplinger - Triumf, 25 July 2007
36// Revision: D.Mingming - Center for HEP, Tsinghua Univ., 10 August 2011
37// --------------------------------------------------------------------
38
40
41#include "G4DecayProducts.hh"
42#include "G4LorentzVector.hh"
44#include "G4SystemOfUnits.hh"
45#include "Randomize.hh"
46
48 const G4String& theParentName, G4double theBR)
49 : G4VDecayChannel("Radiative Muon Decay", 1)
50{
51 // set names for daughter particles
52 if (theParentName == "mu+") {
53 SetBR(theBR);
54 SetParent("mu+");
56 SetDaughter(0, "e+");
57 SetDaughter(1, "gamma");
58 SetDaughter(2, "nu_e");
59 SetDaughter(3, "anti_nu_mu");
60 }
61 else if (theParentName == "mu-") {
62 SetBR(theBR);
63 SetParent("mu-");
65 SetDaughter(0, "e-");
66 SetDaughter(1, "gamma");
67 SetDaughter(2, "anti_nu_e");
68 SetDaughter(3, "nu_mu");
69 }
70 else {
71#ifdef G4VERBOSE
72 if (GetVerboseLevel() > 0) {
73 G4cout << "G4RadiativeMuonDecayChannel::G4RadiativeMuonDecayChannel():";
74 G4cout << " parent particle is not muon but ";
75 G4cout << theParentName << G4endl;
76 }
77#endif
78 }
79}
80
83{
84 if (this != &right) {
87 rbranch = right.rbranch;
88
89 // copy parent name
90 parent_name = new G4String(*right.parent_name);
91
92 // clear daughters_name array
94
95 // recreate array
97 if (numberOfDaughters > 0) {
98 if (daughters_name != nullptr) ClearDaughtersName();
100 // copy daughters name
101 for (G4int index = 0; index < numberOfDaughters; ++index) {
102 daughters_name[index] = new G4String(*right.daughters_name[index]);
103 }
104 }
106 }
107 return *this;
108}
109
111{
112#ifdef G4VERBOSE
113 if (GetVerboseLevel() > 1) G4cout << "G4MuonRadiativeDecayChannelWithSpin::DecayIt()";
114#endif
115
118
119 // parent mass
120 G4double parentmass = G4MT_parent->GetPDGMass();
121
122 G4double EMMU = parentmass;
123
124 // daughters'mass
125 G4double daughtermass[4];
126 // G4double sumofdaughtermass = 0.0;
127 for (G4int index = 0; index < 4; ++index) {
128 daughtermass[index] = G4MT_daughters[index]->GetPDGMass();
129 // sumofdaughtermass += daughtermass[index];
130 }
131
132 G4double EMASS = daughtermass[0];
133
134 // create parent G4DynamicParticle at rest
135 G4ThreeVector dummy;
136 auto parentparticle = new G4DynamicParticle(G4MT_parent, dummy, 0.0);
137
138 // create G4Decayproducts
139 auto products = new G4DecayProducts(*parentparticle);
140 delete parentparticle;
141
142 G4double eps = EMASS / EMMU;
143
144 G4double som0, x, y, xx, yy, zz;
145 G4double cthetaE, cthetaG, cthetaGE, phiE, phiG;
146 const std::size_t MAX_LOOP = 10000;
147
148 for (std::size_t loop_counter1 = 0; loop_counter1 < MAX_LOOP; ++loop_counter1) {
149 for (std::size_t loop_counter2 = 0; loop_counter2 < MAX_LOOP; ++loop_counter2) {
150 // -------------------------------------------------------------------
151 // Build two vectors of random length and random direction, for the
152 // positron and the photon.
153 // x/y is the length of the vector, xx, yy and zz the components,
154 // phi is the azimutal angle, theta the polar angle.
155 // -------------------------------------------------------------------
156
157 // For the positron
158 //
159 x = G4UniformRand();
160
161 rn3dim(xx, yy, zz, x);
162
163 if (std::fabs((xx * xx) + (yy * yy) + (zz * zz) - (x * x)) > 0.001) {
164 G4cout << "Norm of x not correct" << G4endl;
165 }
166
167 phiE = atan4(xx, yy);
168 cthetaE = zz / x;
169 G4double sthetaE = std::sqrt((xx * xx) + (yy * yy)) / x;
170
171 // What you get:
172 //
173 // x = positron energy
174 // phiE = azimutal angle of positron momentum
175 // cthetaE = cosine of polar angle of positron momentum
176 // sthetaE = sine of polar angle of positron momentum
177 //
178 //// G4cout << " x, xx, yy, zz " << x << " " << xx << " "
179 //// << yy << " " << zz << G4endl;
180 //// G4cout << " phiE, cthetaE, sthetaE " << phiE << " "
181 //// << cthetaE << " "
182 //// << sthetaE << " " << G4endl;
183
184 // For the photon
185 //
186 y = G4UniformRand();
187
188 rn3dim(xx, yy, zz, y);
189
190 if (std::fabs((xx * xx) + (yy * yy) + (zz * zz) - (y * y)) > 0.001) {
191 G4cout << " Norm of y not correct " << G4endl;
192 }
193
194 phiG = atan4(xx, yy);
195 cthetaG = zz / y;
196 G4double sthetaG = std::sqrt((xx * xx) + (yy * yy)) / y;
197
198 // What you get:
199 //
200 // y = photon energy
201 // phiG = azimutal angle of photon momentum
202 // cthetaG = cosine of polar angle of photon momentum
203 // sthetaG = sine of polar angle of photon momentum
204 //
205 //// G4cout << " y, xx, yy, zz " << y << " " << xx << " "
206 //// << yy << " " << zz << G4endl;
207 //// G4cout << " phiG, cthetaG, sthetaG " << phiG << " "
208 //// << cthetaG << " "
209 //// << sthetaG << " " << G4endl;
210
211 // Calculate the angle between positron and photon (cosine)
212 //
213 cthetaGE = cthetaE * cthetaG + sthetaE * sthetaG * std::cos(phiE - phiG);
214
215 //// G4cout << x << " " << cthetaE << " " << sthetaE << " "
216 //// << y << " " << cthetaG << " " << sthetaG << " "
217 //// << cthetaGE
218
219 G4double term0 = eps * eps;
220 G4double term1 = x * ((1.0 - eps) * (1.0 - eps)) + 2.0 * eps;
221 G4double beta =
222 std::sqrt(x * ((1.0 - eps) * (1.0 - eps)) * (x * ((1.0 - eps) * (1.0 - eps)) + 4.0 * eps))
223 / term1;
224 G4double delta = 1.0 - beta * cthetaGE;
225
226 G4double term3 = y * (1.0 - (eps * eps));
227 G4double term6 = term1 * delta * term3;
228
229 G4double Qsqr = (1.0 - term1 - term3 + term0 + 0.5 * term6) / ((1.0 - eps) * (1.0 - eps));
230
231 // Check the kinematics.
232 //
233 if (Qsqr >= 0.0 && Qsqr <= 1.0) break;
234
235 } // end loop count
236
237 // Do the calculation for -1 muon polarization (i.e. mu+)
238 //
239 G4double Pmu = -1.0;
240 if (GetParentName() == "mu-") {
241 Pmu = +1.0;
242 }
243
244 som0 = fron(Pmu, x, y, cthetaE, cthetaG, cthetaGE);
245
246 // Sample the decay rate
247 //
248 if (G4UniformRand() * 177.0 <= som0) break;
249 }
250
251 G4double E = EMMU / 2. * (x * ((1. - eps) * (1. - eps)) + 2. * eps);
252 G4double G = EMMU / 2. * y * (1. - eps * eps);
253
254 if (E < EMASS) E = EMASS;
255
256 // calculate daughter momentum
257 G4double daughtermomentum[4];
258
259 daughtermomentum[0] = std::sqrt(E * E - EMASS * EMASS);
260
261 G4double sthetaE = std::sqrt(1. - cthetaE * cthetaE);
262 G4double cphiE = std::cos(phiE);
263 G4double sphiE = std::sin(phiE);
264
265 // Coordinates of the decay positron with respect to the muon spin
266
267 G4double px = sthetaE * cphiE;
268 G4double py = sthetaE * sphiE;
269 G4double pz = cthetaE;
270
271 G4ThreeVector direction0(px, py, pz);
272
273 direction0.rotateUz(parent_polarization);
274
275 auto daughterparticle0 =
276 new G4DynamicParticle(G4MT_daughters[0], daughtermomentum[0] * direction0);
277
278 products->PushProducts(daughterparticle0);
279
280 daughtermomentum[1] = G;
281
282 G4double sthetaG = std::sqrt(1. - cthetaG * cthetaG);
283 G4double cphiG = std::cos(phiG);
284 G4double sphiG = std::sin(phiG);
285
286 // Coordinates of the decay gamma with respect to the muon spin
287
288 px = sthetaG * cphiG;
289 py = sthetaG * sphiG;
290 pz = cthetaG;
291
292 G4ThreeVector direction1(px, py, pz);
293
294 direction1.rotateUz(parent_polarization);
295
296 auto daughterparticle1 =
297 new G4DynamicParticle(G4MT_daughters[1], daughtermomentum[1] * direction1);
298
299 products->PushProducts(daughterparticle1);
300
301 // daughter 3 ,4 (neutrinos)
302 // create neutrinos in the C.M frame of two neutrinos
303
304 G4double energy2 = parentmass - E - G;
305
306 G4ThreeVector P34 = -1. * (daughtermomentum[0] * direction0 + daughtermomentum[1] * direction1);
307 G4double vmass2 = energy2 * energy2 - P34.mag2();
308 G4double vmass = std::sqrt(vmass2);
309
310 G4double costhetan = 2. * G4UniformRand() - 1.0;
311 G4double sinthetan = std::sqrt((1.0 - costhetan) * (1.0 + costhetan));
312 G4double phin = twopi * G4UniformRand() * rad;
313 G4double sinphin = std::sin(phin);
314 G4double cosphin = std::cos(phin);
315
316 G4ThreeVector direction2(sinthetan * cosphin, sinthetan * sinphin, costhetan);
317
318 auto daughterparticle2 = new G4DynamicParticle(G4MT_daughters[2], direction2 * (vmass / 2.));
319 auto daughterparticle3 =
320 new G4DynamicParticle(G4MT_daughters[3], direction2 * (-1.0 * vmass / 2.));
321
322 // boost to the muon rest frame
323 G4double beta = P34.mag() / energy2;
324 G4ThreeVector direction34 = P34.unit();
325
326 G4LorentzVector p4 = daughterparticle2->Get4Momentum();
327 p4.boost(direction34.x() * beta, direction34.y() * beta, direction34.z() * beta);
328 daughterparticle2->Set4Momentum(p4);
329
330 p4 = daughterparticle3->Get4Momentum();
331 p4.boost(direction34.x() * beta, direction34.y() * beta, direction34.z() * beta);
332 daughterparticle3->Set4Momentum(p4);
333
334 products->PushProducts(daughterparticle2);
335 products->PushProducts(daughterparticle3);
336
337 daughtermomentum[2] = daughterparticle2->GetTotalMomentum();
338 daughtermomentum[3] = daughterparticle3->GetTotalMomentum();
339
340 // output message
341#ifdef G4VERBOSE
342 if (GetVerboseLevel() > 1) {
343 G4cout << "G4MuonRadiativeDecayChannelWithSpin::DecayIt() -";
344 G4cout << " create decay products in rest frame " << G4endl;
345 G4double TT = daughterparticle0->GetTotalEnergy() + daughterparticle1->GetTotalEnergy()
346 + daughterparticle2->GetTotalEnergy() + daughterparticle3->GetTotalEnergy();
347 G4cout << "e :" << daughterparticle0->GetTotalEnergy() / MeV << G4endl;
348 G4cout << "gamma:" << daughterparticle1->GetTotalEnergy() / MeV << G4endl;
349 G4cout << "nu2 :" << daughterparticle2->GetTotalEnergy() / MeV << G4endl;
350 G4cout << "nu2 :" << daughterparticle3->GetTotalEnergy() / MeV << G4endl;
351 G4cout << "total:" << (TT - parentmass) / keV << G4endl;
352 if (GetVerboseLevel() > 1) {
353 products->DumpInfo();
354 }
355 }
356#endif
357
358 return products;
359}
360
361G4double G4MuonRadiativeDecayChannelWithSpin::fron(G4double Pmu, G4double x, G4double y,
362 G4double cthetaE, G4double cthetaG,
363 G4double cthetaGE)
364{
365 G4double mu = 105.65;
366 G4double me = 0.511;
367 G4double rho = 0.75;
368 G4double del = 0.75;
369 G4double eps = 0.0;
370 G4double kap = 0.0;
371 G4double ksi = 1.0;
372
373 G4double delta = 1 - cthetaGE;
374
375 // Calculation of the functions f(x,y)
376
377 G4double f_1s = 12.0
378 * ((y * y) * (1.0 - y) + x * y * (2.0 - 3.0 * y) + 2.0 * (x * x) * (1.0 - 2.0 * y)
379 - 2.0 * (x * x * x));
380 G4double f0s = 6.0
381 * (-x * y * (2.0 - 3.0 * (y * y)) - 2.0 * (x * x) * (1.0 - y - 3.0 * (y * y))
382 + 2.0 * (x * x * x) * (1.0 + 2.0 * y));
383 G4double f1s =
384 3.0 * ((x * x) * y * (2.0 - 3.0 * y - 3.0 * (y * y)) - (x * x * x) * y * (4.0 + 3.0 * y));
385 G4double f2s = 1.5 * ((x * x * x) * (y * y) * (2.0 + y));
386
387 G4double f_1se = 12.0 * (x * y * (1.0 - y) + (x * x) * (2.0 - 3.0 * y) - 2.0 * (x * x * x));
388 G4double f0se = 6.0 * (-(x * x) * (2.0 - y - 2.0 * (y * y)) + (x * x * x) * (2.0 + 3.0 * y));
389 G4double f1se = -3.0 * (x * x * x) * y * (2.0 + y);
390 G4double f2se = 0.0;
391
392 G4double f_1sg = 12.0 * ((y * y) * (1.0 - y) + x * y * (1.0 - 2.0 * y) - (x * x) * y);
393 G4double f0sg =
394 6.0 * (-x * (y * y) * (2.0 - 3.0 * y) - (x * x) * y * (1.0 - 4.0 * y) + (x * x * x) * y);
395 G4double f1sg = 3.0 * ((x * x) * (y * y) * (1.0 - 3.0 * y) - 2.0 * (x * x * x) * (y * y));
396 G4double f2sg = 1.5 * (x * x * x) * (y * y * y);
397
398 G4double f_1v = 8.0
399 * ((y * y) * (3.0 - 2.0 * y) + 6.0 * x * y * (1.0 - y)
400 + 2.0 * (x * x) * (3.0 - 4.0 * y) - 4.0 * (x * x * x));
401 G4double f0v = 8.0
402 * (-x * y * (3.0 - y - (y * y)) - (x * x) * (3.0 - y - 4.0 * (y * y))
403 + 2.0 * (x * x * x) * (1.0 + 2.0 * y));
404 G4double f1v =
405 2.0 * ((x * x) * y * (6.0 - 5.0 * y - 2.0 * (y * y)) - 2.0 * (x * x * x) * y * (4.0 + 3.0 * y));
406 G4double f2v = 2.0 * (x * x * x) * (y * y) * (2.0 + y);
407
408 G4double f_1ve =
409 8.0 * (x * y * (1.0 - 2.0 * y) + 2.0 * (x * x) * (1.0 - 3.0 * y) - 4.0 * (x * x * x));
410 G4double f0ve =
411 4.0 * (-(x * x) * (2.0 - 3.0 * y - 4.0 * (y * y)) + 2.0 * (x * x * x) * (2.0 + 3.0 * y));
412 G4double f1ve = -4.0 * (x * x * x) * y * (2.0 + y);
413 G4double f2ve = 0.0;
414
415 G4double f_1vg = 8.0 * ((y * y) * (1.0 - 2.0 * y) + x * y * (1.0 - 4.0 * y) - 2.0 * (x * x) * y);
416 G4double f0vg =
417 4.0 * (2.0 * x * (y * y) * (1.0 + y) - (x * x) * y * (1.0 - 4.0 * y) + 2.0 * (x * x * x) * y);
418 G4double f1vg = 2.0 * ((x * x) * (y * y) * (1.0 - 2.0 * y) - 4.0 * (x * x * x) * (y * y));
419 G4double f2vg = 2.0 * (x * x * x) * (y * y * y);
420
421 G4double f_1t = 8.0
422 * ((y * y) * (3.0 - y) + 3.0 * x * y * (2.0 - y) + 2.0 * (x * x) * (3.0 - 2.0 * y)
423 - 2.0 * (x * x * x));
424 G4double f0t = 4.0
425 * (-x * y * (6.0 + (y * y)) - 2.0 * (x * x) * (3.0 + y - 3.0 * (y * y))
426 + 2.0 * (x * x * x) * (1.0 + 2.0 * y));
427 G4double f1t =
428 2.0 * ((x * x) * y * (6.0 - 5.0 * y + (y * y)) - (x * x * x) * y * (4.0 + 3.0 * y));
429 G4double f2t = (x * x * x) * (y * y) * (2.0 + y);
430
431 G4double f_1te = -8.0 * (x * y * (1.0 + 3.0 * y) + (x * x) * (2.0 + 3.0 * y) + 2.0 * (x * x * x));
432 G4double f0te = 4.0 * ((x * x) * (2.0 + 3.0 * y + 4.0 * (y * y)) + (x * x * x) * (2.0 + 3.0 * y));
433 G4double f1te = -2.0 * (x * x * x) * y * (2.0 + y);
434 G4double f2te = 0.0;
435
436 G4double f_1tg = -8.0 * ((y * y) * (1.0 + y) + x * y + (x * x) * y);
437 G4double f0tg = 4.0 * (x * (y * y) * (2.0 - y) + (x * x) * y * (1.0 + 2.0 * y) + (x * x * x) * y);
438 G4double f1tg = -2.0 * ((x * x) * (y * y) * (1.0 - y) + 2.0 * (x * x * x) * y);
439 G4double f2tg = (x * x * x) * (y * y * y);
440
441 G4double term = delta + 2.0 * (me * me) / ((mu * mu) * (x * x));
442 term = 1.0 / term;
443
444 G4double nss = term * f_1s + f0s + delta * f1s + (delta * delta) * f2s;
445 G4double nv = term * f_1v + f0v + delta * f1v + (delta * delta) * f2v;
446 G4double nt = term * f_1t + f0t + delta * f1t + (delta * delta) * f2t;
447
448 G4double nse = term * f_1se + f0se + delta * f1se + (delta * delta) * f2se;
449 G4double nve = term * f_1ve + f0ve + delta * f1ve + (delta * delta) * f2ve;
450 G4double nte = term * f_1te + f0te + delta * f1te + (delta * delta) * f2te;
451
452 G4double nsg = term * f_1sg + f0sg + delta * f1sg + (delta * delta) * f2sg;
453 G4double nvg = term * f_1vg + f0vg + delta * f1vg + (delta * delta) * f2vg;
454 G4double ntg = term * f_1tg + f0tg + delta * f1tg + (delta * delta) * f2tg;
455
456 G4double term1 = nv;
457 G4double term2 = 2.0 * nss + nv - nt;
458 G4double term3 = 2.0 * nss - 2.0 * nv + nt;
459
460 G4double term1e = 1.0 / 3.0 * (1.0 - 4.0 / 3.0 * del);
461 G4double term2e = 2.0 * nse + 5.0 * nve - nte;
462 G4double term3e = 2.0 * nse - 2.0 * nve + nte;
463
464 G4double term1g = 1.0 / 3.0 * (1.0 - 4.0 / 3.0 * del);
465 G4double term2g = 2.0 * nsg + 5.0 * nvg - ntg;
466 G4double term3g = 2.0 * nsg - 2.0 * nvg + ntg;
467
468 G4double som00 = term1 + (1.0 - 4.0 / 3.0 * rho) * term2 + eps * term3;
469 G4double som01 = Pmu * ksi
470 * (cthetaE * (nve - term1e * term2e + kap * term3e)
471 + cthetaG * (nvg - term1g * term2g + kap * term3g));
472
473 G4double som0 = (som00 + som01) / y;
474 som0 = fine_structure_const / 8. / (twopi * twopi * twopi) * som0;
475
476 return som0;
477}
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition Randomize.hh:52
double z() const
Hep3Vector unit() const
double x() const
double mag2() const
double y() const
double mag() const
Hep3Vector & rotateUz(const Hep3Vector &)
HepLorentzVector & boost(double, double, double)
G4MuonRadiativeDecayChannelWithSpin & operator=(const G4MuonRadiativeDecayChannelWithSpin &)
G4MuonRadiativeDecayChannelWithSpin(const G4String &theParentName, G4double theBR)
G4ParticleDefinition ** G4MT_daughters
const G4String & GetParentName() const
void SetBR(G4double value)
G4String ** daughters_name
G4int GetVerboseLevel() const
void SetNumberOfDaughters(G4int value)
G4ParticleDefinition * G4MT_parent
void SetDaughter(G4int anIndex, const G4ParticleDefinition *particle_type)
G4ThreeVector parent_polarization
void SetParent(const G4ParticleDefinition *particle_type)