Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/cross_sections/src/G4MuNeutrinoNucleusTotXsc.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 
 27 
 28 #include "G4MuNeutrinoNucleusTotXsc.hh"
 29 #include "G4PhysicalConstants.hh"
 30 #include "G4SystemOfUnits.hh"
 31 #include "G4DynamicParticle.hh"
 32 #include "G4ParticleTable.hh"
 33 #include "G4IonTable.hh"
 34 #include "G4HadTmpUtil.hh"
 35 #include "G4NistManager.hh"
 36 #include "G4Material.hh"
 37 #include "G4Element.hh"
 38 #include "G4Isotope.hh"
 39 #include "G4ElementVector.hh"
 40 
 41 #include "G4MuonMinus.hh"
 42 #include "G4MuonPlus.hh"
 43 
 44 using namespace std;
 45 using namespace CLHEP;
 46 
 47 G4MuNeutrinoNucleusTotXsc::G4MuNeutrinoNucleusTotXsc()
 48  : G4VCrossSectionDataSet("NuMuNuclTotXsc")
 49 {
 50   fCofXsc = 1.e-38*cm2/GeV;
 51 
 52   // G4cout<<"fCofXsc = "<<fCofXsc*GeV/cm2<<" cm2/GeV"<<G4endl;
 53 
 54   // PDG2016: sin^2 theta Weinberg
 55 
 56   fSin2tW = 0.23129; // 0.2312;
 57 
 58   // 9 <-> 6, 5/9 or 5/6 ?
 59 
 60   fCofS = 5.*fSin2tW*fSin2tW/9.;
 61   fCofL = 1. - fSin2tW + fCofS;
 62 
 63   // G4cout<<"fCosL = "<<fCofL<<", fCofS = "<<fCofS<<G4endl;
 64 
 65   fCutEnergy = 0.; // default value
 66 
 67   fBiasingFactor = 1.; // default as physics
 68   fEmc = 0.2*GeV;
 69   fIndex = 50;
 70 
 71   fTotXsc = 0.;
 72   fCcTotRatio = 0.75; // from nc/cc~0.33 ratio
 73   fCcFactor = fNcFactor = 1.;
 74   fQEratio = 0.5; // mean in the 1 GeV range
 75 
 76   // theMuonMinus = G4MuonMinus::MuonMinus(); 
 77   // theMuonPlus  = G4MuonPlus::MuonPlus(); 
 78 }
 79 
 80 G4MuNeutrinoNucleusTotXsc::~G4MuNeutrinoNucleusTotXsc() 
 81 {}
 82 
 83 //////////////////////////////////////////////////////
 84 
 85 G4bool 
 86 G4MuNeutrinoNucleusTotXsc::IsIsoApplicable( const G4DynamicParticle* aPart, G4int, G4int, const G4Element*, const G4Material*)
 87 {
 88   G4bool result  = false;
 89   G4String pName = aPart->GetDefinition()->GetParticleName();
 90   G4double tKin = aPart->GetKineticEnergy();
 91   
 92   if(      ( pName == "nu_mu"   || pName == "anti_nu_mu")  && tKin >= fEmc ) 
 93   {
 94     result = true;
 95   }
 96   return result;
 97 }
 98 
 99 //////////////////////////////////////
100 
101 G4double G4MuNeutrinoNucleusTotXsc::GetElementCrossSection(const G4DynamicParticle* part,
102                  G4int Z,    const G4Material* mat )
103 {
104   G4int Zi(0);
105   size_t i(0), j(0);
106   const G4ElementVector* theElementVector = mat->GetElementVector();
107   
108   for ( i = 0; i < theElementVector->size(); ++i )
109   {
110     Zi = (*theElementVector)[i]->GetZasInt();
111     if( Zi == Z ) break;
112   }
113   const G4Element* elm = (*theElementVector)[i];
114   size_t nIso = elm->GetNumberOfIsotopes();    
115   G4double fact = 0.0;
116   G4double xsec = 0.0;
117   const G4Isotope* iso = nullptr;       
118   const G4IsotopeVector* isoVector = elm->GetIsotopeVector();
119   const G4double* abundVector = elm->GetRelativeAbundanceVector();
120 
121   for (j = 0; j<nIso; ++j)
122   {
123     iso = (*isoVector)[j];
124     G4int A = iso->GetN();
125     
126     if( abundVector[j] > 0.0 && IsIsoApplicable(part, Z, A, elm, mat) )
127     {
128       fact += abundVector[j];
129       xsec += abundVector[j]*GetIsoCrossSection( part, Z, A, iso, elm, mat);
130     }
131   }
132   if( fact > 0.0) { xsec /= fact; }
133   return xsec;
134 }
135 
136 ////////////////////////////////////////////////////
137 //
138 //
139 
140 G4double G4MuNeutrinoNucleusTotXsc::GetIsoCrossSection(const G4DynamicParticle* aPart, G4int Z, G4int A,  
141             const G4Isotope*, const G4Element*, const G4Material* )
142 {
143   fCcFactor   = fNcFactor = 1.;
144   fCcTotRatio = 0.25;
145 
146   G4double ccnuXsc, ccanuXsc, ncXsc, totXsc(0.);
147 
148   G4double energy  = aPart->GetTotalEnergy();
149   G4String pName   = aPart->GetDefinition()->GetParticleName();
150 
151   G4int index = GetEnergyIndex(energy);
152 
153   if( index >= fIndex )
154   {
155     G4double pm = proton_mass_c2;
156     G4double s2 = 2.*energy*pm+pm*pm;
157     G4double aa = 1.;
158     G4double bb = 1.085;
159     G4double mw = 80.385*GeV;
160     fCcFactor   = bb/(1.+ aa*s2/mw/mw);
161 
162     G4double mz = 91.1876*GeV;
163     fNcFactor   =  bb/(1.+ aa*s2/mz/mz);
164   }
165   ccnuXsc  = GetNuMuTotCsXsc(index, energy, Z, A);
166   ccnuXsc *= fCcFactor;
167   ccanuXsc = GetANuMuTotCsXsc(index, energy, Z, A);
168   ccanuXsc *= fCcFactor;
169 
170   if( pName == "nu_mu" )
171   {
172     ncXsc = fCofL*ccnuXsc + fCofS*ccanuXsc;
173     ncXsc *= fNcFactor/fCcFactor;
174     totXsc = ccnuXsc + ncXsc;
175     if( totXsc > 0.) fCcTotRatio = ccnuXsc/totXsc;
176   }
177   else if( pName == "anti_nu_mu" )
178   {
179     ncXsc = fCofL*ccanuXsc + fCofS*ccnuXsc;
180     ncXsc *= fNcFactor/fCcFactor;
181     totXsc = ccanuXsc + ncXsc;
182     if( totXsc > 0.) fCcTotRatio = ccanuXsc/totXsc;
183   }
184   else return totXsc;
185 
186   totXsc *= fCofXsc; 
187   totXsc *= energy; 
188   // totXsc *= A;  // incoherent sum over  all isotope nucleons
189 
190   totXsc *= fBiasingFactor; // biasing up, if set >1
191 
192   fTotXsc = totXsc;
193 
194   return totXsc;
195 }
196 
197 /////////////////////////////////////////////////////
198 //
199 // Return index of nu/anu energy array corresponding to the neutrino energy
200 
201 G4int G4MuNeutrinoNucleusTotXsc::GetEnergyIndex(G4double energy)
202 {
203   G4int i, eIndex = 0;
204 
205   for( i = 0; i < fIndex; i++)
206   {
207     if( energy <= fNuMuEnergy[i]*GeV ) 
208     {
209       eIndex = i;
210       break;
211     }
212   }
213   if( i >= fIndex ) eIndex = i;
214   // G4cout<<"eIndex = "<<eIndex<<G4endl;
215   return eIndex;
216 }
217 
218 /////////////////////////////////////////////////////
219 //
220 // nu_mu xsc for index-1, index linear over energy
221 
222 G4double G4MuNeutrinoNucleusTotXsc::GetNuMuTotCsXsc(G4int index, G4double energy, G4int zz, G4int aa)
223 {
224   G4double xsc(0.), qexsc(0.), inxsc(0.);
225   G4int nn = aa - zz;
226   if(nn < 1) nn = 0;
227 
228   // if( index <= 0 || energy < theMuonMinus->GetPDGMass() ) xsc = aa*fNuMuInXsc[0] + nn*fNuMuQeXsc[0];
229   if( index <= 0 || energy < fEmc ) xsc = aa*fNuMuInXsc[0] + nn*fNuMuQeXsc[0];
230   else if (index >= fIndex) xsc = aa*fNuMuInXsc[fIndex-1] + nn*fNuMuQeXsc[fIndex-1];
231   else
232   {
233     G4double x1 = fNuMuEnergy[index-1]*GeV;
234     G4double x2 = fNuMuEnergy[index]*GeV;
235     G4double y1 = fNuMuInXsc[index-1];
236     G4double y2 = fNuMuInXsc[index];
237     G4double z1 = fNuMuQeXsc[index-1];
238     G4double z2 = fNuMuQeXsc[index];
239 
240     if(x1 >= x2) return aa*fNuMuInXsc[index] + nn*fNuMuQeXsc[index];
241     else
242     {
243       G4double angle = (y2-y1)/(x2-x1);
244       inxsc = y1 + (energy-x1)*angle;
245       angle = (z2-z1)/(x2-x1);
246       qexsc = z1 + (energy-x1)*angle; 
247       qexsc *= nn;   
248       xsc = inxsc*aa + qexsc;
249 
250       if( xsc > 0.) fQEratio = qexsc/xsc;
251     }
252   }
253   return xsc;
254 }
255 
256 /////////////////////////////////////////////////////
257 //
258 // anu_mu xsc for index-1, index linear over energy
259 
260 G4double G4MuNeutrinoNucleusTotXsc::GetANuMuTotCsXsc(G4int index, G4double energy, G4int zz, G4int aa)
261 {
262   G4double xsc(0.), qexsc(0.), inxsc(0.);
263 
264   // if( index <= 0 || energy < theMuonPlus->GetPDGMass() ) xsc = aa*fANuMuInXsc[0] + zz*fANuMuQeXsc[0];
265   if( index <= 0 || energy < fEmc ) xsc = aa*fANuMuInXsc[0] + zz*fANuMuQeXsc[0];
266   else if (index >= fIndex) xsc = aa*fANuMuInXsc[fIndex-1] + zz*fANuMuQeXsc[fIndex-1];
267   else
268   {
269     G4double x1 = fNuMuEnergy[index-1]*GeV;
270     G4double x2 = fNuMuEnergy[index]*GeV;
271     G4double y1 = fANuMuInXsc[index-1];
272     G4double y2 = fANuMuInXsc[index];
273     G4double z1 = fANuMuQeXsc[index-1];
274     G4double z2 = fANuMuQeXsc[index];
275 
276     if( x1 >= x2 ) return aa*fANuMuInXsc[index] + zz*fANuMuQeXsc[index];
277     else
278     {
279       G4double angle = (y2-y1)/(x2-x1);
280       inxsc = y1 + (energy-x1)*angle;
281 
282       angle = (z2-z1)/(x2-x1);
283       qexsc = z1 + (energy-x1)*angle;
284       qexsc *= zz;    
285       xsc = inxsc*aa + qexsc;
286 
287       if( xsc > 0.) fQEratio = qexsc/xsc;
288     }
289   }
290   return xsc;
291 }
292 
293 ////////////////////////////////////////////////////////
294 //
295 // return fNuMuTotXsc[index] if the index is in the array range
296 
297 G4double G4MuNeutrinoNucleusTotXsc::GetNuMuTotCsArray( G4int index)
298 {
299   if( index >= 0 && index < fIndex) return fNuMuInXsc[index] + fNuMuQeXsc[index];
300   else 
301   {
302     G4cout<<"Improper index of fNuMuTotXsc array"<<G4endl;
303     return 0.;
304   }
305 }
306 
307 ////////////////////////////////////////////////////////
308 //
309 // return fANuMuTotXsc[index] if the index is in the array range
310 
311 G4double G4MuNeutrinoNucleusTotXsc::GetANuMuTotCsArray( G4int index)
312 {
313   if( index >= 0 && index < fIndex) return fANuMuInXsc[index] + fANuMuQeXsc[index];
314   else 
315   {
316     G4cout<<"Improper index of fANuMuTotXsc array"<<G4endl;
317     return 0.;
318   }
319 }
320 
321 
322 ///////////////////////////////////////////////////////
323 //
324 // E_nu in GeV, ( Eth = 111.603 MeV, EthW = 330.994 MeV) 
325 
326 const G4double G4MuNeutrinoNucleusTotXsc::fNuMuEnergy[50] = 
327 {
328   0.12, 0.141136, 0.165996, 0.195233, 0.229621, 
329   0.270066, 0.317634, 0.373581, 0.439382, 0.516773, 
330   0.607795, 0.714849, 0.84076, 0.988848, 1.16302, 
331   1.36787, 1.6088, 1.89217, 2.22545, 2.61743, 
332   3.07845, 3.62068, 4.25841, 5.00847, 5.89065, 
333   6.9282, 8.14851, 9.58376, 11.2718, 13.2572, 
334   15.5922, 18.3386, 21.5687, 25.3677, 29.8359, 
335   35.0911, 41.2719, 48.5413, 57.0912, 67.147, 
336   78.974, 92.8842, 109.244, 128.486, 151.117, 
337   177.735, 209.04, 245.86, 289.164, 340.097 };
338 
339 ////////////////////////////////////////////////////
340 //
341 // XS/E arrays in 10^-38cm2/GeV
342 
343 const G4double G4MuNeutrinoNucleusTotXsc::fNuMuInXsc[50] = 
344 {
345   0, 0, 0, 0, 0, 
346   0, 0, 0.0166853, 0.0649693, 0.132346, 
347   0.209102, 0.286795, 0.3595, 0.423961,  0.479009, 
348   0.524797, 0.562165, 0.592225, 0.61612,  0.63491, 
349   0.649524, 0.660751, 0.669245, 0.675546, 0.680092, 
350   0.683247, 0.685307, 0.686521, 0.687093, 0.687184, 
351   0.686919, 0.686384, 0.685631, 0.684689, 0.68357, 
352   0.682275, 0.680806, 0.67917, 0.677376, 0.675442, 
353   0.673387, 0.671229, 0.668985, 0.666665, 0.664272, 
354   0.661804, 0.65925, 0.656593, 0.65381, 0.650871    }; 
355 
356 const G4double G4MuNeutrinoNucleusTotXsc::fNuMuQeXsc[50] = 
357 {
358   0.20787, 0.411055, 0.570762, 0.705379, 0.814702, 
359   0.89543, 0.944299, 0.959743, 0.942906, 0.897917, 
360   0.831331, 0.750948, 0.66443, 0.578191, 0.496828, 
361   0.423071, 0.358103, 0.302016, 0.254241, 0.213889, 
362   0.179971, 0.151527, 0.12769, 0.107706, 0.0909373, 
363   0.0768491, 0.0649975, 0.0550143, 0.0465948, 0.0394861, 
364   0.0334782, 0.0283964, 0.0240945, 0.0204506, 0.0173623, 
365   0.0147437, 0.0125223, 0.0106374, 0.00903737, 0.00767892, 
366   0.00652531, 0.00554547, 0.0047131, 0.0040059, 0.003405, 
367   0.00289436, 0.00246039, 0.00209155, 0.00177804, 0.00151152  }; 
368 
369 
370 
371 //////////////////////////////////////////////////////////////////
372 
373 const G4double G4MuNeutrinoNucleusTotXsc::fANuMuInXsc[50] = 
374 {
375   0, 0, 0, 0, 0, 
376   0, 0, 0.00437363, 0.0161485, 0.0333162, 
377   0.0557621, 0.0814548, 0.108838, 0.136598, 0.163526, 
378   0.188908, 0.212041, 0.232727, 0.250872, 0.26631, 
379   0.279467, 0.290341, 0.299177, 0.306299, 0.311864, 
380   0.316108, 0.319378, 0.321892, 0.323583, 0.324909, 
381   0.325841, 0.326568, 0.327111, 0.327623, 0.32798, 
382   0.328412, 0.328704, 0.328988, 0.329326, 0.329559, 
383   0.329791, 0.330051, 0.330327, 0.33057, 0.330834, 
384   0.331115, 0.331416, 0.331678, 0.33192, 0.332124   };
385 
386 ////////////////////////////////////////////////////////////////// 
387 
388 const G4double G4MuNeutrinoNucleusTotXsc::fANuMuQeXsc[50] = 
389 {
390   0.0770264, 0.138754, 0.177006, 0.202417, 0.21804, 
391   0.225742, 0.227151, 0.223805, 0.21709, 0.208137, 
392   0.197763, 0.186496, 0.174651, 0.162429, 0.14999, 
393   0.137498, 0.125127, 0.113057, 0.101455, 0.0904642, 
394   0.0801914, 0.0707075, 0.0620483, 0.0542192, 0.0472011, 
395   0.0409571, 0.0354377, 0.0305862, 0.0263422, 0.0226451, 
396   0.0194358, 0.0166585, 0.0142613, 0.0121968, 0.0104221, 
397   0.00889912, 0.00759389, 0.00647662, 0.00552119, 0.00470487, 
398   0.00400791, 0.00341322, 0.00290607, 0.00247377, 0.0021054, 
399   0.00179162, 0.00152441, 0.00129691, 0.00110323, 0.000938345   }; 
400 
401 ////////////////////
402 
403