Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/cross_sections/src/G4ChargeExchangeXS.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 // GEANT4 Class file
 29 //
 30 //
 31 // File name:    G4ChargeExchangeXS
 32 //
 33 
 34 #include "G4ChargeExchangeXS.hh"
 35 #include "G4DynamicParticle.hh"
 36 #include "G4ElementTable.hh"
 37 #include "G4Material.hh"
 38 #include "G4Element.hh"
 39 #include "G4IsotopeList.hh"
 40 #include "G4HadronicParameters.hh"
 41 #include "Randomize.hh"
 42 #include "G4SystemOfUnits.hh"
 43 #include "G4NucleiProperties.hh"  
 44 #include "G4Pow.hh"
 45 
 46 #include "G4PionZero.hh"
 47 #include "G4Eta.hh"
 48 #include "G4KaonZeroLong.hh"
 49 #include "G4KaonZeroShort.hh"
 50 #include "G4KaonPlus.hh"
 51 #include "G4KaonMinus.hh"
 52 #include "G4ParticleTable.hh"
 53 
 54 namespace {
 55   // V. Lyubovitsky parameterisation
 56   const G4double piA[5] = {430., 36.,  1.37,  2.0,  60.};  // A
 57   const G4double pAP[5] = {1.04, 1.26, 1.35,  0.94, 0.94}; // 2 - 2alphaP
 58   const G4double pC0[5] = {12.7, 6.0,  6.84,  6.5,  8.0};  // c0
 59   const G4double pC1[5] = {1.57, 1.6,  1.7,   1.23, 2.6};  // c1
 60   const G4double pG0[5] = {2.55, 4.6,  3.7,   5.5,  4.6};  // g0
 61   const G4double pG1[5] = {-0.23, -0.5,  0.,    0., -2.};  // g1
 62 
 63   const G4double beta_prime_pi = 0.0410;
 64 }
 65 
 66 G4ChargeExchangeXS::G4ChargeExchangeXS() 
 67 {
 68   if (verboseLevel > 1) {
 69     G4cout  << "G4ChargeExchangeXS::G4ChargeExchangeXS" << G4endl;
 70   }
 71   g4calc = G4Pow::GetInstance();
 72   auto table = G4ParticleTable::GetParticleTable();
 73   const G4String nam[5] = {"pi0", "eta", "eta_prime", "omega", "f2(1270)"};
 74   for (G4int i=0; i<5; ++i) {
 75     fPionSecPD[i] = table->FindParticle(nam[i]);
 76     if (nullptr == fPionSecPD[i]) {
 77       G4ExceptionDescription ed;
 78       ed << "### meson " << nam[i] << " is not found out in the particle table";
 79       G4Exception("G4ChargeExchangeXS::G4ChargeExchangeXS()","had044",
 80                   FatalException, ed,"");
 81     }
 82   }
 83 }
 84 
 85 // Print the information of this .cc file
 86 void G4ChargeExchangeXS::CrossSectionDescription(std::ostream& outFile) const
 87 {
 88   outFile << "G4ChargeExchangeXS calculates charge exchange cross section for "
 89           << "pi+, pi-, K+, K-, KL\n";
 90 }
 91 
 92 G4bool G4ChargeExchangeXS::IsElementApplicable(const G4DynamicParticle*,
 93                                                G4int, const G4Material*)
 94 {
 95   return true;
 96 }
 97 
 98 G4double
 99 G4ChargeExchangeXS::GetElementCrossSection(const G4DynamicParticle* aParticle, 
100                    G4int ZZ, const G4Material* mat)  
101 {
102   G4double result = 0.0;
103   const G4double pE = aParticle->GetTotalEnergy();
104   if (pE <= fEnergyLimit) { return result; }
105   
106   auto part = aParticle->GetDefinition();
107   G4int pdg = part->GetPDGEncoding();   
108 
109   // Get or calculate the proton mass, particle mass, and s(Lorentz invariant) 
110   G4double tM = CLHEP::proton_mass_c2;
111   G4double pM = part->GetPDGMass();
112   G4double lorentz_s = tM*tM + 2*tM*pE +  pM*pM;
113   if (lorentz_s <= (tM + pM)*(tM + pM)) { return result; }
114 
115   const G4int Z = std::min(ZZ, ZMAXNUCLEARDATA);
116   const G4int A = G4lrint(aeff[Z]);
117 
118   if (verboseLevel > 1) {
119     G4cout << "### G4ChargeExchangeXS: " << part->GetParticleName()
120      << " Z=" << Z << " A=" << A << " Etot(GeV)=" << pE/CLHEP::GeV
121      << " s(GeV^2)=" << lorentz_s/(CLHEP::GeV*CLHEP::GeV) << G4endl;
122   }
123 
124   // For unit conversion 
125   const G4double inv1e7 = 0.1/(CLHEP::GeV*CLHEP::GeV);
126   const G4double fact = 1e-30*CLHEP::cm2;
127   const G4double pfact = 0.1/CLHEP::GeV;
128   const G4double kfact = 56.3*fact;
129   const G4double csmax = 1e-16;
130 
131   // The approximation of Glauber-Gribov formula -> extend it from interaction with 
132   // proton to nuclei Z^(2/3). The factor g4calc->powA(A,-beta_prime_pi*G4Log(A))
133   // takes into account absorption of pi0 and eta 
134 
135   // pi- + p -> n + meson (0- pi0, 1- eta, 2- eta', 3- omega, 4- f2(1270))
136   if (pdg == -211) {
137     G4double z23 = g4calc->Z23(Z);
138     G4double x = lorentz_s*inv1e7;
139     G4double logX = G4Log(x);
140     G4double logA = g4calc->logZ(A);
141     G4double xf = g4calc->powZ(A, -beta_prime_pi*logA);
142     G4double sum = 0.0;
143     for (G4int i=0; i<5; ++i) {
144       G4double xg = std::max(1.0 + pG0[i] + pG1[i]*logX, 0.0);
145       G4double xc = std::max(pC0[i] + pC1[i]*logX, csmax);
146       G4double xs = z23*piA[i]*g4calc->powA(x, -pAP[i])*xf*xg/xc;
147       sum += xs;
148       fXSecPion[i] = sum;
149     }
150     result = sum*fact;
151   }
152 
153   // pi+ + n -> p + meson (0- pi0, 1- eta, 2- eta', 3- omega, 4- f2(1270))
154   else if (pdg == 211) {
155     G4double n23 = g4calc->Z23(A - Z);
156     G4double x = lorentz_s*inv1e7;
157     G4double logX = G4Log(x);
158     G4double logA = g4calc->logZ(A);
159     G4double xf = g4calc->powZ(A, -beta_prime_pi*logA);
160 
161     // hydrogen target case Z = A = 1
162     // the cross section is defined by fraction of deuteron and tritium
163     if (1 == Z) { n23 = ComputeDeuteronFraction(mat); }
164     G4double sum = 0.0;
165     for (G4int i=0; i<5; ++i) {
166       G4double xg = std::max(1.0 + pG0[i] + pG1[i]*logX, 0.0);
167       G4double xc = std::max(pC0[i] + pC1[i]*logX, csmax);
168       G4double xs = n23*piA[i]*g4calc->powA(x, -pAP[i])*xf*xg/xc;
169       sum += xs;
170       fXSecPion[i] = sum;
171     }
172     result = sum*fact;
173   }
174 
175   // Kaon x-sections depend on the primary particles momentum
176   // K- + p -> Kbar + n
177   else if (pdg == -321) {
178     G4double p_momentum = std::sqrt(pE*pE - pM*pM)*pfact;
179     result = g4calc->Z23(Z)*g4calc->powA(p_momentum, -1.60)*kfact;
180   }
181 
182   // K+ + n -> Kbar + p
183   else if (pdg == 321) {
184     G4double p_momentum = std::sqrt(pE*pE - pM*pM)*pfact;
185     G4double n23 = g4calc->Z23(A-Z);   
186     // hydrogen target case Z = A = 1
187     // the cross section is defined by fraction of deuteron and tritium
188     if (1 == Z) { n23 = ComputeDeuteronFraction(mat); }
189     result = n23*g4calc->powA(p_momentum, -1.60)*kfact;
190   }
191 
192   // KL 
193   else if (pdg == 130) {
194     // Cross section of KL = 0.5*(Cross section of K+ + Cross section of K-)
195     const G4double p_momentum = std::sqrt(pE*pE - pM*pM)*pfact;
196     result = 0.5*(g4calc->Z23(Z) + g4calc->Z23(A-Z))*
197       g4calc->powA(p_momentum, -1.60)*kfact;
198   }
199   result *= fFactor;
200   if (verboseLevel > 1) {
201     G4cout  << "   Done for " << part->GetParticleName() << " Etot(GeV)=" << pE/CLHEP::GeV
202       << " res(mb)=" << result/CLHEP::millibarn << G4endl;
203   }
204   return result;
205 }
206 
207 const G4ParticleDefinition*
208 G4ChargeExchangeXS::SampleSecondaryType(const G4ParticleDefinition* part,
209                                         const G4int Z, const G4int A)
210 {
211   const G4ParticleDefinition* pd = nullptr;
212   G4int pdg = std::abs(part->GetPDGEncoding());  
213 
214   // pi- + p /  pi+ + n  
215   if (pdg == 211) {
216     pd = fPionSecPD[0];
217     G4double x = fXSecPion[4]*G4UniformRand();
218     for (G4int i=0; i<5; ++i) {
219       if (x <= fXSecPion[i]) {
220         pd = fPionSecPD[i];
221   break;
222       }
223     }
224   }
225 
226   // K- + p /  K+ + n 
227   // Equal opportunity of producing k-short and k-long
228   else if (pdg == 321) {
229     if (G4UniformRand() >= 0.5) {
230       pd = G4KaonZeroLong::KaonZeroLong();
231     }
232     else {
233       pd = G4KaonZeroShort::KaonZeroShort();
234     }
235   }
236 
237   // KL + nucleus
238   else if (pdg == 130) {
239     G4double prob = (G4double)Z/(G4double)A;
240     if (G4UniformRand() >= prob) {
241       pd = G4KaonMinus::KaonMinus();
242     }
243     else {
244       pd = G4KaonPlus::KaonPlus();
245     }
246   }
247 
248   return pd;
249 } 
250 
251 G4double
252 G4ChargeExchangeXS::ComputeDeuteronFraction(const G4Material* mat)
253 {
254   for (auto const & elm : *mat->GetElementVector()) {
255     if (1 == elm->GetZasInt()) {
256       G4double ab = 0.0;
257       const G4int nIso = (G4int)elm->GetNumberOfIsotopes();
258       const G4double* abu = elm->GetRelativeAbundanceVector();
259       for (G4int j = 0; j < nIso; ++j) {
260   auto const iso = elm->GetIsotope(j);
261   ab += (iso->GetN() - iso->GetZ())*abu[j];
262       }
263       return ab;
264     }
265   }
266   return 0.0;
267 }
268