Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4MuonDecayChannelWithSpin.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// G4MuonDecayChannelWithSpin class implementation
27//
28// References:
29// - Florian Scheck "Muon Physics", in Physics Reports
30// (Review Section of Physics Letters) 44, No. 4 (1978)
31// 187-248. North-Holland Publishing Company, Amsterdam at page 210 cc.
32// - W.E. Fisher and F. Scheck, Nucl. Phys. B83 (1974) 25.
33
34// Authors: P.Gumplinger and T.MacPhail, 17 August 2004
35// --------------------------------------------------------------------
36
38
39#include "G4DecayProducts.hh"
40#include "G4LorentzVector.hh"
42#include "G4SystemOfUnits.hh"
43#include "Randomize.hh"
44
46 G4double theBR)
47 : G4MuonDecayChannel(theParentName, theBR)
48{}
49
52{
53 if (this != &right) {
56 rbranch = right.rbranch;
57
58 // copy parent name
59 delete parent_name;
60 parent_name = new G4String(*right.parent_name);
61
62 // clear daughters_name array
64
65 // recreate array
67 if (numberOfDaughters > 0) {
69 // copy daughters name
70 for (G4int index = 0; index < numberOfDaughters; ++index) {
71 daughters_name[index] = new G4String(*right.daughters_name[index]);
72 }
73 }
74 }
75 return *this;
76}
77
79{
80 // This version assumes V-A coupling with 1st order radiative correctons,
81 // the standard model Michel parameter values, but
82 // gives incorrect energy spectrum for neutrinos
83
84#ifdef G4VERBOSE
85 if (GetVerboseLevel() > 1) G4cout << "G4MuonDecayChannelWithSpin::DecayIt ";
86#endif
87
90
91 // parent mass
92 G4double parentmass = G4MT_parent->GetPDGMass();
93
94 G4double EMMU = parentmass;
95
96 // daughters'mass
97 G4double daughtermass[3];
98 // G4double sumofdaughtermass = 0.0;
99 for (G4int index = 0; index < 3; ++index) {
100 daughtermass[index] = G4MT_daughters[index]->GetPDGMass();
101 // sumofdaughtermass += daughtermass[index];
102 }
103
104 G4double EMASS = daughtermass[0];
105
106 // create parent G4DynamicParticle at rest
107 G4ThreeVector dummy;
108 auto parentparticle = new G4DynamicParticle(G4MT_parent, dummy, 0.0);
109 // create G4Decayproducts
110 auto products = new G4DecayProducts(*parentparticle);
111 delete parentparticle;
112
113 // calculate electron energy
114
115 G4double michel_rho = 0.75; // Standard Model Michel rho
116 G4double michel_delta = 0.75; // Standard Model Michel delta
117 G4double michel_xsi = 1.00; // Standard Model Michel xsi
118 G4double michel_eta = 0.00; // Standard Model eta
119
120 G4double rndm, x, ctheta;
121
122 G4double FG;
123 G4double FG_max = 2.00;
124
125 G4double W_mue = (EMMU * EMMU + EMASS * EMASS) / (2. * EMMU);
126 G4double x0 = EMASS / W_mue;
127
128 G4double x0_squared = x0 * x0;
129
130 // ***************************************************
131 // x0 <= x <= 1. and -1 <= y <= 1
132 //
133 // F(x,y) = f(x)*g(x,y); g(x,y) = 1.+g(x)*y
134 // ***************************************************
135
136 // ***** sampling F(x,y) directly (brute force) *****
137
138 const std::size_t MAX_LOOP = 10000;
139 for (std::size_t loop_count = 0; loop_count < MAX_LOOP; ++loop_count) {
140 // Sample the positron energy by sampling from F
141
142 rndm = G4UniformRand();
143
144 x = x0 + rndm * (1. - x0);
145
146 G4double x_squared = x * x;
147
148 G4double F_IS, F_AS, G_IS, G_AS;
149
150 F_IS = 1. / 6. * (-2. * x_squared + 3. * x - x0_squared);
151 F_AS = 1. / 6. * std::sqrt(x_squared - x0_squared) * (2. * x - 2. + std::sqrt(1. - x0_squared));
152
153 G_IS = 2. / 9. * (michel_rho - 0.75) * (4. * x_squared - 3. * x - x0_squared);
154 G_IS = G_IS + michel_eta * (1. - x) * x0;
155
156 G_AS = 3. * (michel_xsi - 1.) * (1. - x);
157 G_AS =
158 G_AS + 2. * (michel_xsi * michel_delta - 0.75) * (4. * x - 4. + std::sqrt(1. - x0_squared));
159 G_AS = 1. / 9. * std::sqrt(x_squared - x0_squared) * G_AS;
160
161 F_IS = F_IS + G_IS;
162 F_AS = F_AS + G_AS;
163
164 // *** Radiative Corrections ***
165
166 const G4double omega = std::log(EMMU / EMASS);
167 G4double R_IS = F_c(x, x0, omega);
168
169 G4double F = 6. * F_IS + R_IS / std::sqrt(x_squared - x0_squared);
170
171 // *** Radiative Corrections ***
172
173 G4double R_AS = F_theta(x, x0, omega);
174
175 rndm = G4UniformRand();
176
177 ctheta = 2. * rndm - 1.;
178
179 G4double G = 6. * F_AS - R_AS / std::sqrt(x_squared - x0_squared);
180
181 FG = std::sqrt(x_squared - x0_squared) * F * (1. + (G / F) * ctheta);
182
183 if (FG > FG_max) {
184 G4Exception("G4MuonDecayChannelWithSpin::DecayIt()", "PART113", JustWarning,
185 "Problem in Muon Decay: FG > FG_max");
186 FG_max = FG;
187 }
188
189 rndm = G4UniformRand();
190
191 if (FG >= rndm * FG_max) break;
192 }
193
194 G4double energy = x * W_mue;
195
196 rndm = G4UniformRand();
197
198 G4double phi = twopi * rndm;
199
200 if (energy < EMASS) energy = EMASS;
201
202 // Calculate daughter momentum
203 G4double daughtermomentum[3];
204
205 daughtermomentum[0] = std::sqrt(energy * energy - EMASS * EMASS);
206
207 G4double stheta = std::sqrt(1. - ctheta * ctheta);
208 G4double cphi = std::cos(phi);
209 G4double sphi = std::sin(phi);
210
211 // Coordinates of the decay positron with respect to the muon spin
212 G4double px = stheta * cphi;
213 G4double py = stheta * sphi;
214 G4double pz = ctheta;
215
216 G4ThreeVector direction0(px, py, pz);
217
218 direction0.rotateUz(parent_polarization);
219
220 auto daughterparticle0 =
221 new G4DynamicParticle(G4MT_daughters[0], daughtermomentum[0] * direction0);
222
223 products->PushProducts(daughterparticle0);
224
225 // daughter 1 ,2 (neutrinos)
226 // create neutrinos in the C.M frame of two neutrinos
227 G4double energy2 = parentmass - energy;
228 G4double vmass = std::sqrt((energy2 - daughtermomentum[0]) * (energy2 + daughtermomentum[0]));
229 G4double beta = -1.0 * daughtermomentum[0] / energy2;
230 G4double costhetan = 2. * G4UniformRand() - 1.0;
231 G4double sinthetan = std::sqrt((1.0 - costhetan) * (1.0 + costhetan));
232 G4double phin = twopi * G4UniformRand() * rad;
233 G4double sinphin = std::sin(phin);
234 G4double cosphin = std::cos(phin);
235
236 G4ThreeVector direction1(sinthetan * cosphin, sinthetan * sinphin, costhetan);
237 auto daughterparticle1 = new G4DynamicParticle(G4MT_daughters[1], direction1 * (vmass / 2.));
238 auto daughterparticle2 =
239 new G4DynamicParticle(G4MT_daughters[2], direction1 * (-1.0 * vmass / 2.));
240
241 // boost to the muon rest frame
243 p4 = daughterparticle1->Get4Momentum();
244 p4.boost(direction0.x() * beta, direction0.y() * beta, direction0.z() * beta);
245 daughterparticle1->Set4Momentum(p4);
246 p4 = daughterparticle2->Get4Momentum();
247 p4.boost(direction0.x() * beta, direction0.y() * beta, direction0.z() * beta);
248 daughterparticle2->Set4Momentum(p4);
249 products->PushProducts(daughterparticle1);
250 products->PushProducts(daughterparticle2);
251 daughtermomentum[1] = daughterparticle1->GetTotalMomentum();
252 daughtermomentum[2] = daughterparticle2->GetTotalMomentum();
253
254 // output message
255#ifdef G4VERBOSE
256 if (GetVerboseLevel() > 1) {
257 G4cout << "G4MuonDecayChannelWithSpin::DecayIt ";
258 G4cout << " create decay products in rest frame " << G4endl;
259 G4double TT = daughterparticle0->GetTotalEnergy() + daughterparticle1->GetTotalEnergy()
260 + daughterparticle2->GetTotalEnergy();
261 G4cout << "e " << daughterparticle0->GetTotalEnergy() / MeV << G4endl;
262 G4cout << "nu1" << daughterparticle1->GetTotalEnergy() / MeV << G4endl;
263 G4cout << "nu2" << daughterparticle2->GetTotalEnergy() / MeV << G4endl;
264 G4cout << "total" << (TT - parentmass) / keV << G4endl;
265 if (GetVerboseLevel() > 2) {
266 products->DumpInfo();
267 }
268 }
269#endif
270
271 return products;
272}
273
274G4double G4MuonDecayChannelWithSpin::R_c(G4double x, G4double omega)
275{
276 auto n_max = (G4int)(100. * x);
277
278 if (n_max < 10) n_max = 10;
279
280 G4double L2 = 0.0;
281
282 for (G4int n = 1; n <= n_max; ++n) {
283 L2 += std::pow(x, n) / (n * n);
284 }
285
286 G4double r_c;
287
288 r_c = 2. * L2 - (pi * pi / 3.) - 2.;
289 r_c = r_c + omega * (1.5 + 2. * std::log((1. - x) / x));
290 r_c = r_c - std::log(x) * (2. * std::log(x) - 1.);
291 r_c = r_c + (3. * std::log(x) - 1. - 1. / x) * std::log(1. - x);
292
293 return r_c;
294}
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
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
double x() const
double y() const
Hep3Vector & rotateUz(const Hep3Vector &)
HepLorentzVector & boost(double, double, double)
G4DecayProducts * DecayIt(G4double) override
G4MuonDecayChannelWithSpin(const G4String &theParentName, G4double theBR)
G4MuonDecayChannelWithSpin & operator=(const G4MuonDecayChannelWithSpin &)
G4ParticleDefinition ** G4MT_daughters
G4String ** daughters_name
G4int GetVerboseLevel() const
G4ParticleDefinition * G4MT_parent
G4ThreeVector parent_polarization