Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/particles/management/src/G4MuonDecayChannelWithSpin.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 
 37 #include "G4MuonDecayChannelWithSpin.hh"
 38 
 39 #include "G4DecayProducts.hh"
 40 #include "G4LorentzVector.hh"
 41 #include "G4PhysicalConstants.hh"
 42 #include "G4SystemOfUnits.hh"
 43 #include "Randomize.hh"
 44 
 45 G4MuonDecayChannelWithSpin::G4MuonDecayChannelWithSpin(const G4String& theParentName,
 46                                                        G4double theBR)
 47   : G4MuonDecayChannel(theParentName, theBR)
 48 {}
 49 
 50 G4MuonDecayChannelWithSpin&
 51 G4MuonDecayChannelWithSpin::operator=(const G4MuonDecayChannelWithSpin& right)
 52 {
 53   if (this != &right) {
 54     kinematics_name = right.kinematics_name;
 55     verboseLevel = right.verboseLevel;
 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
 63     ClearDaughtersName();
 64 
 65     // recreate array
 66     numberOfDaughters = right.numberOfDaughters;
 67     if (numberOfDaughters > 0) {
 68       daughters_name = new G4String*[numberOfDaughters];
 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 
 78 G4DecayProducts* G4MuonDecayChannelWithSpin::DecayIt(G4double)
 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 
 88   CheckAndFillParent();
 89   CheckAndFillDaughters();
 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
242   G4LorentzVector p4;
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 
274 G4double 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 }
295