Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4ChargeExchangeXS.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// -------------------------------------------------------------------
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"
41#include "Randomize.hh"
42#include "G4SystemOfUnits.hh"
43#include "G4NucleiProperties.hh"
44#include "G4Pow.hh"
45
46#include "G4PionZero.hh"
47#include "G4PionPlus.hh"
48#include "G4Eta.hh"
49#include "G4KaonZeroLong.hh"
50#include "G4KaonZeroShort.hh"
51#include "G4KaonPlus.hh"
52#include "G4KaonMinus.hh"
53#include "G4ParticleTable.hh"
54#include "G4ThreeVector.hh"
55
56namespace {
57 // V. Lyubovitsky parameterisation
58 const G4double piA[5] = {122., 78.8, 59.4, 24.0, 213.5};// A
59 const G4double pAP[5] = {1.23, 1.53, 1.35, 0.94, 0.94}; // 2 - 2alphaP
60 const G4double pC0[5] = {12.7, 6.0, 6.84, 6.5, 8.0}; // c0
61 const G4double pC1[5] = {1.57, 1.6, 1.7, 1.23, 2.6}; // c1
62 const G4double pG0[5] = {2.55, 4.6, 3.7, 5.5, 4.6}; // g0
63 const G4double pG1[5] = {-0.23, -0.5, 0., 0., -2.}; // g1
64
65 // parameterisation of intranuclear absorption
66 const G4double beta_prime_pi = 0.0036;
67
68 // For unit conversion
69 const G4double GeV2 = (CLHEP::GeV*CLHEP::GeV);
70 const G4double inv1e7 = 0.1/GeV2;
71 const G4double fact = 1e-30*CLHEP::cm2;
72 const G4double pfact = 0.1/CLHEP::GeV;
73 const G4double kfact = 56.3*fact;
74 const G4double csmax = 1e-16;
75}
76
78{
79 if (verboseLevel > 1) {
80 G4cout << "G4ChargeExchangeXS::G4ChargeExchangeXS" << G4endl;
81 }
82 fMassPi = G4PionPlus::PionPlus()->GetPDGMass();
83 g4calc = G4Pow::GetInstance();
85 const G4String nam[5] = {"pi0", "eta", "eta_prime", "omega", "f2(1270)"};
86 for (G4int i=0; i<5; ++i) {
87 fPionSecPD[i] = table->FindParticle(nam[i]);
88 if (nullptr == fPionSecPD[i]) {
90 ed << "### meson " << nam[i] << " is not found out in the particle table";
91 G4Exception("G4ChargeExchangeXS::G4ChargeExchangeXS()","had044",
92 FatalException, ed,"");
93 }
94 }
95}
96
97// Print the information of this .cc file
98void G4ChargeExchangeXS::CrossSectionDescription(std::ostream& outFile) const
99{
100 outFile << "G4ChargeExchangeXS calculates charge exchange cross section for "
101 << "pi+, pi-, K+, K-, KL\n";
102}
103
109
112 G4int Z, const G4Material* mat)
113{
114 G4double pE = dp->GetTotalEnergy();
115 return (pE > fEnergyLimit) ?
116 GetCrossSection(dp->GetDefinition(), mat, Z, pE) : 0.0;
117}
118
119G4double G4ChargeExchangeXS::GetCrossSection(const G4ParticleDefinition* part,
120 const G4Material* mat,
121 G4int ZZ, G4double pEtot)
122{
123 G4double result = 0.0;
124 G4int pdg = part->GetPDGEncoding();
125
126 // Get or calculate the proton mass, particle mass, and s(Lorentz invariant)
127 G4double tM = CLHEP::proton_mass_c2;
128 G4double pM = part->GetPDGMass();
129 G4double lorentz_s = tM*tM + 2*tM*pEtot + pM*pM;
130
131 if (lorentz_s <= (tM + pM)*(tM + pM)) { return result; }
132
133 const G4int Z = std::min(ZZ, ZMAXNUCLEARDATA);
134 const G4int A = G4lrint(aeff[Z]);
135
136 if (verboseLevel > 1) {
137 G4cout << "### G4ChargeExchangeXS: " << part->GetParticleName()
138 << " Z=" << Z << " A=" << A << " Etot(GeV)=" << pEtot/CLHEP::GeV
139 << " s(GeV^2)=" << lorentz_s/GeV2 << G4endl;
140 }
141
142 // The approximation of Glauber-Gribov formula -> extend it from interaction with
143 // proton to nuclei Z^(2/3). The factor g4calc->powA(A,-beta_prime_pi*G4Log(A))
144 // takes into account absorption of mesons within the nucleus
145
146 // pi- + p -> n + meson (0- pi0, 1- eta, 2- eta', 3- omega, 4- f2(1270))
147 if (pdg == -211) {
148 G4double z23 = g4calc->Z23(Z);
149 G4double x = lorentz_s*inv1e7;
150 G4double logX = G4Log(x);
151 G4double logA = g4calc->logZ(A);
152 G4double xf = fact*g4calc->powZ(A, -beta_prime_pi*(logA + 2*logA));
153 G4double sum = 0.0;
154 for (G4int i=0; i<5; ++i) {
155 G4double xg = std::max(1.0 + pG0[i] + pG1[i]*logX, 0.0);
156 G4double xc = std::max(pC0[i] + pC1[i]*logX, csmax);
157 G4double xs = z23*piA[i]*g4calc->powA(x, -pAP[i])*xf*xg/xc;
158 sum += xs;
159 fXSecPion[i] = sum;
160 }
161 result = sum;
162 }
163
164 // pi+ + n -> p + meson (0- pi0, 1- eta, 2- eta', 3- omega, 4- f2(1270))
165 else if (pdg == 211) {
166 G4double n23 = g4calc->Z23(A - Z);
167 G4double x = lorentz_s*inv1e7;
168 G4double logX = G4Log(x);
169 G4double logA = g4calc->logZ(A);
170 G4double xf = fact*g4calc->powZ(A, -beta_prime_pi*(logA + 2*logA));
171
172 // hydrogen target case Z = A = 1
173 // the cross section is defined by fraction of deuteron and tritium
174 if (1 == Z) { n23 = ComputeDeuteronFraction(mat); }
175 G4double sum = 0.0;
176 for (G4int i=0; i<5; ++i) {
177 G4double xg = std::max(1.0 + pG0[i] + pG1[i]*logX, 0.0);
178 G4double xc = std::max(pC0[i] + pC1[i]*logX, csmax);
179 G4double xs = n23*piA[i]*g4calc->powA(x, -pAP[i])*xf*xg/xc;
180 sum += xs;
181 fXSecPion[i] = sum;
182 }
183 result = sum;
184 }
185
186 // Kaon x-sections depend on the primary particles momentum
187 // K- + p -> Kbar + n
188 else if (pdg == -321) {
189 G4double p_momentum = std::sqrt(pEtot*pEtot - pM*pM)*pfact;
190 result = g4calc->Z23(Z)*g4calc->powA(p_momentum, -1.60)*kfact;
191 }
192
193 // K+ + n -> Kbar + p
194 else if (pdg == 321) {
195 G4double p_momentum = std::sqrt(pEtot*pEtot - pM*pM)*pfact;
196 G4double n23 = g4calc->Z23(A-Z);
197 // hydrogen target case Z = A = 1
198 // the cross section is defined by fraction of deuteron and tritium
199 if (1 == Z) { n23 = ComputeDeuteronFraction(mat); }
200 result = n23*g4calc->powA(p_momentum, -1.60)*kfact;
201 }
202
203 // KL
204 else if (pdg == 130) {
205 // Cross section of KL = 0.5*(Cross section of K+ + Cross section of K-)
206 const G4double p_momentum = std::sqrt(pEtot*pEtot - pM*pM)*pfact;
207 result = 0.5*(g4calc->Z23(Z) + g4calc->Z23(A-Z))*
208 g4calc->powA(p_momentum, -1.60)*kfact;
209 }
210 result *= fFactor;
211 if (verboseLevel > 1) {
212 G4cout << " Done for " << part->GetParticleName() << " Etot(GeV)="
213 << pEtot/CLHEP::GeV
214 << " res(mb)=" << result/CLHEP::millibarn << G4endl;
215 }
216 return result;
217}
218
221 const G4Material* mat,
222 G4int Z, G4int A, G4double etot)
223{
224 // index of pion partial x-section
225 findex = -1;
226 // recompute x-section for the element in complex material
227 GetCrossSection(part, mat, Z, etot);
228
229 const G4ParticleDefinition* pd = nullptr;
230 G4int pdg = std::abs(part->GetPDGEncoding());
231 G4cout << pdg << G4endl;
232 // pi- + p / pi+ + n
233 if (pdg == 211) {
234 pd = fPionSecPD[0];
235 G4double x = fXSecPion[4]*G4UniformRand();
236 for (findex = 0; findex < 5; ++findex) {
237 if (x <= fXSecPion[findex]) {
238 pd = fPionSecPD[findex];
239 break;
240 }
241 }
242 }
243
244 // K- + p / K+ + n
245 // Equal opportunity of producing k-short and k-long
246 else if (pdg == 321) {
247 if (G4UniformRand() >= 0.5) {
249 }
250 else {
252 }
253 }
254
255 // KL + nucleus
256 else if (pdg == 130) {
257 G4double prob = (G4double)Z/(G4double)A;
258 if (G4UniformRand() >= prob) {
260 }
261 else {
263 }
264 }
265 if (verboseLevel > 1) {
266 G4cout << "G4ChargeExchangeXS::SampleSecondaryType for "
267 << pd->GetParticleName() << " findex=" << findex
268 << G4endl;
269 }
270 return pd;
271}
272
274 const G4double ltmax) const
275{
276 G4double tmax = ltmax/GeV2;
277 G4double tM = CLHEP::proton_mass_c2;
278 G4double logX = G4Log((tM*tM + 2*tM*etot + fMassPi*fMassPi)*inv1e7);
279
280 G4double gl = pG0[findex] + pG1[findex]*logX;
281 G4double cl = pC0[findex] + pC1[findex]*logX;
282 G4double gc = gl*cl;
283
284 G4double t{0};
285 G4double sigmaMax = (gc > 0.0) ? gl*G4Exp(-(gl - 1.0)/gl) : 1.0;
286 for (G4int i = 0; i < 100000; ++i) {
287 t = tmax*G4UniformRand();
288 G4double sigma = (1.0 + gc*t)*G4Exp(-cl*t);
289 if (G4UniformRand()*sigmaMax <= sigma) {
290 return t*GeV2;
291 }
292 }
293 return 0.0;
294}
295
297G4ChargeExchangeXS::ComputeDeuteronFraction(const G4Material* mat) const
298{
299 for (auto const & elm : *mat->GetElementVector()) {
300 if (1 == elm->GetZasInt()) {
301 G4double ab = 0.0;
302 const G4int nIso = (G4int)elm->GetNumberOfIsotopes();
303 const G4double* abu = elm->GetRelativeAbundanceVector();
304 for (G4int j = 0; j < nIso; ++j) {
305 auto const iso = elm->GetIsotope(j);
306 ab += (iso->GetN() - iso->GetZ())*abu[j];
307 }
308 return ab;
309 }
310 }
311 return 0.0;
312}
313
315{
316 G4double res = 0.0;
317 if (0 == idx) { res = fXSecPion[0]; }
318 else if (0 < idx && 5 > idx) {
319 res = fXSecPion[idx] - fXSecPion[idx - 1];
320 }
321 return res;
322}
const G4double GeV2
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition G4Exp.hh:132
G4double G4Log(G4double x)
Definition G4Log.hh:169
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
const G4double A[17]
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition Randomize.hh:52
G4double SampleTforPion(const G4double etot, const G4double tmax) const
G4bool IsElementApplicable(const G4DynamicParticle *, G4int Z, const G4Material *) final
G4double GetPartialPionXS(G4int idx) const
void CrossSectionDescription(std::ostream &) const final
const G4ParticleDefinition * SampleSecondaryType(const G4ParticleDefinition *, const G4Material *, G4int Z, G4int A, G4double etot)
G4double GetElementCrossSection(const G4DynamicParticle *, G4int Z, const G4Material *) final
G4ParticleDefinition * GetDefinition() const
G4double GetTotalEnergy() const
static G4KaonMinus * KaonMinus()
static G4KaonPlus * KaonPlus()
static G4KaonZeroLong * KaonZeroLong()
static G4KaonZeroShort * KaonZeroShort()
const G4ElementVector * GetElementVector() const
const G4String & GetParticleName() const
static G4ParticleTable * GetParticleTable()
static G4PionPlus * PionPlus()
Definition G4PionPlus.cc:93
static G4Pow * GetInstance()
Definition G4Pow.cc:41
int G4lrint(double ad)
Definition templates.hh:134