Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4INCLNuclearDensityFactory.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// INCL++ intra-nuclear cascade model
27// Alain Boudard, CEA-Saclay, France
28// Joseph Cugnon, University of Liege, Belgium
29// Jean-Christophe David, CEA-Saclay, France
30// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
31// Sylvie Leray, CEA-Saclay, France
32// Davide Mancusi, CEA-Saclay, France
33//
34#define INCLXX_IN_GEANT4_MODE 1
35
36#include "globals.hh"
37
41#include "G4INCLNDFGaussian.hh"
42#include "G4INCLNDFParis.hh"
45
46namespace G4INCL {
47
48 namespace NuclearDensityFactory {
49
50 namespace {
51
52 G4ThreadLocal std::map<G4int,NuclearDensity const *> *nuclearDensityCache = NULL;
53 G4ThreadLocal std::map<G4int,InterpolationTable*> *rpCorrelationTableCache = NULL;
54 G4ThreadLocal std::map<G4int,InterpolationTable*> *rCDFTableCache = NULL;
55 G4ThreadLocal std::map<G4int,InterpolationTable*> *pCDFTableCache = NULL;
56
57 }
58
59 NuclearDensity const *createDensity(const G4int A, const G4int Z, const G4int S) {
60 if(!nuclearDensityCache)
61 nuclearDensityCache = new std::map<G4int,NuclearDensity const *>;
62
63 const G4int nuclideID = 1000*Z + A; // MCNP-style nuclide IDs
64 const std::map<G4int,NuclearDensity const *>::const_iterator mapEntry = nuclearDensityCache->find(nuclideID);
65 if(mapEntry == nuclearDensityCache->end()) {
66 InterpolationTable *rpCorrelationTableProton = createRPCorrelationTable(Proton, A, Z);
67 InterpolationTable *rpCorrelationTableNeutron = createRPCorrelationTable(Neutron, A, Z);
68 InterpolationTable *rpCorrelationTableLambda = createRPCorrelationTable(Lambda, A, Z);
69 if(!rpCorrelationTableProton || !rpCorrelationTableNeutron || !rpCorrelationTableLambda)
70 return NULL;
71 NuclearDensity const *density = new NuclearDensity(A, Z, S, rpCorrelationTableProton, rpCorrelationTableNeutron, rpCorrelationTableLambda);
72 (*nuclearDensityCache)[nuclideID] = density;
73 return density;
74 } else {
75 return mapEntry->second;
76 }
77 }
78
80// assert(t==Proton || t==Neutron || t==Lambda);
81
82 if(!rpCorrelationTableCache)
83 rpCorrelationTableCache = new std::map<G4int,InterpolationTable*>;
84
85 const G4int nuclideID = ((t==Proton) ? 1000 : -1000)*Z + A; // MCNP-style nuclide IDs
86 const std::map<G4int,InterpolationTable*>::const_iterator mapEntry = rpCorrelationTableCache->find(nuclideID);
87 if(mapEntry == rpCorrelationTableCache->end()) {
88
89 INCL_DEBUG("Creating r-p correlation function for " << ((t==Proton) ? "protons" : ((t==Neutron) ? "neutrons" : "lambdas")) << " in A=" << A << ", Z=" << Z << std::endl);
90
91 IFunction1D *rpCorrelationFunction;
92 if(A > 19) {
93 const G4double radius = ParticleTable::getRadiusParameter(t, A, Z);
94 const G4double diffuseness = ParticleTable::getSurfaceDiffuseness(t, A, Z);
95 const G4double maximumRadius = ParticleTable::getMaximumNuclearRadius(t, A, Z);
96 rpCorrelationFunction = new NuclearDensityFunctions::WoodsSaxonRP(radius, maximumRadius, diffuseness);
97 INCL_DEBUG(" ... Woods-Saxon; R0=" << radius << ", a=" << diffuseness << ", Rmax=" << maximumRadius << std::endl);
98 } else if(A <= 19 && A > 6) {
99 const G4double radius = ParticleTable::getRadiusParameter(t, A, Z);
100 const G4double diffuseness = ParticleTable::getSurfaceDiffuseness(t, A, Z);
101 const G4double maximumRadius = ParticleTable::getMaximumNuclearRadius(t, A, Z);
102 rpCorrelationFunction = new NuclearDensityFunctions::ModifiedHarmonicOscillatorRP(radius, maximumRadius, diffuseness);
103 INCL_DEBUG(" ... MHO; param1=" << radius << ", param2=" << diffuseness << ", Rmax=" << maximumRadius << std::endl);
104 } else if(A <= 6 && A > 1) { // Gaussian distribution for light nuclei
105 const G4double radius = ParticleTable::getRadiusParameter(t, A, Z);
106 const G4double maximumRadius = ParticleTable::getMaximumNuclearRadius(t, A, Z);
107 rpCorrelationFunction = new NuclearDensityFunctions::GaussianRP(maximumRadius, Math::oneOverSqrtThree * radius);
108 INCL_DEBUG(" ... Gaussian; sigma=" << radius << ", Rmax=" << maximumRadius << std::endl);
109 } else {
110 INCL_ERROR("No r-p correlation function for " << ((t==Proton) ? "protons" : "neutrons") << " in A = "
111 << A << " Z = " << Z << '\n');
112 return NULL;
113 }
114
115 InterpolationTable *theTable = rpCorrelationFunction->inverseCDFTable(Math::pow13);
116 delete rpCorrelationFunction;
117 INCL_DEBUG(" ... here comes the table:\n" << theTable->print() << '\n');
118
119 (*rpCorrelationTableCache)[nuclideID] = theTable;
120 return theTable;
121 } else {
122 return mapEntry->second;
123 }
124 }
125
127// assert(t==Proton || t==Neutron || t==Lambda || t==antiNeutron || t==antiProton);
128
129 if(!rCDFTableCache)
130 rCDFTableCache = new std::map<G4int,InterpolationTable*>;
131
132 G4int nuclideID = ((t==Proton) ? 1000 : -1000)*Z + A; // MCNP-style nuclide IDs
133 if (A<0){
134 nuclideID = ((t==antiProton) ? 1000 : -1000)*(-Z) + (-A);
135 }
136 const std::map<G4int,InterpolationTable*>::const_iterator mapEntry = rCDFTableCache->find(nuclideID);
137 if(mapEntry == rCDFTableCache->end()) {
138
139 IFunction1D *rDensityFunction;
140 if(A > 19) {
144 rDensityFunction = new NuclearDensityFunctions::WoodsSaxon(radius, maximumRadius, diffuseness);
145 } else if(A <= 19 && A > 6) {
149 rDensityFunction = new NuclearDensityFunctions::ModifiedHarmonicOscillator(radius, maximumRadius, diffuseness);
150 } else if(A <= 6 && A > 2) { // Gaussian distribution for light nuclei
153 rDensityFunction = new NuclearDensityFunctions::Gaussian(maximumRadius, Math::oneOverSqrtThree * radius);
154 } else if((A == 2 && Z == 1) || (A ==-2 && Z==-1)){ // density from the Paris potential for deuterons & antideuterons
155 rDensityFunction = new NuclearDensityFunctions::ParisR();
156 } else {
157 INCL_ERROR("No nuclear density function for target A = "
158 << A << " Z = " << Z << '\n');
159 return NULL;
160 }
161
162 InterpolationTable *theTable = rDensityFunction->inverseCDFTable();
163 delete rDensityFunction;
164 INCL_DEBUG("Creating inverse position CDF for A=" << A << ", Z=" << Z << ":" <<
165 '\n' << theTable->print() << '\n');
166
167 (*rCDFTableCache)[nuclideID] = theTable;
168 return theTable;
169 } else {
170 return mapEntry->second;
171 }
172 }
173
175// assert(t==Proton || t==Neutron || t==Lambda || t==antiNeutron || t==antiProton);
176
177 if(!pCDFTableCache)
178 pCDFTableCache = new std::map<G4int,InterpolationTable*>;
179
180 G4int nuclideID = ((t==Proton) ? 1000 : -1000)*Z + A; // MCNP-style nuclide IDs
181 if (A<0){
182 nuclideID = ((t==antiProton) ? 1000 : -1000)*(-Z) + (-A);
183 }
184 const std::map<G4int,InterpolationTable*>::const_iterator mapEntry = pCDFTableCache->find(nuclideID);
185 if(mapEntry == pCDFTableCache->end()) {
186 IFunction1D *pDensityFunction;
187 if(A > 19) {
188 const G4double theFermiMomentum = ParticleTable::getFermiMomentum(A, Z);
189 pDensityFunction = new NuclearDensityFunctions::HardSphere(theFermiMomentum);
190 } else if(A <= 19 && A > 2) { // Gaussian distribution for light nuclei
192 pDensityFunction = new NuclearDensityFunctions::Gaussian(5.*momentumRMS, momentumRMS);
193 } else if((A == 2 && Z == 1) || (A ==-2 && Z==-1)) { // density from the Paris potential for deuterons & antideuterons
194 pDensityFunction = new NuclearDensityFunctions::ParisP();
195 } else {
196 INCL_ERROR("No nuclear density function for target A = "
197 << A << " Z = " << Z << '\n');
198 return NULL;
199 }
200
201 InterpolationTable *theTable = pDensityFunction->inverseCDFTable();
202 delete pDensityFunction;
203 INCL_DEBUG("Creating inverse momentum CDF for A=" << A << ", Z=" << Z << ":" <<
204 '\n' << theTable->print() << '\n');
205
206 (*pCDFTableCache)[nuclideID] = theTable;
207 return theTable;
208 } else {
209 return mapEntry->second;
210 }
211 }
212
213 void addRPCorrelationToCache(const G4int A, const G4int Z, const ParticleType t, InterpolationTable * const table) {
214// assert(t==Proton || t==Neutron || t==Lambda);
215
216 if(!rpCorrelationTableCache)
217 rpCorrelationTableCache = new std::map<G4int,InterpolationTable*>;
218
219 const G4int nuclideID = ((t==Proton) ? 1000 : -1000)*Z + A; // MCNP-style nuclide IDs
220 const std::map<G4int,InterpolationTable*>::const_iterator mapEntry = rpCorrelationTableCache->find(nuclideID);
221 if(mapEntry != rpCorrelationTableCache->end())
222 delete mapEntry->second;
223
224 (*rpCorrelationTableCache)[nuclideID] = table;
225 }
226
227 void addDensityToCache(const G4int A, const G4int Z, NuclearDensity * const density) {
228 if(!nuclearDensityCache)
229 nuclearDensityCache = new std::map<G4int,NuclearDensity const *>;
230
231 const G4int nuclideID = 1000*Z + A; // MCNP-style nuclide IDs
232 const std::map<G4int,NuclearDensity const *>::const_iterator mapEntry = nuclearDensityCache->find(nuclideID);
233 if(mapEntry != nuclearDensityCache->end())
234 delete mapEntry->second;
235
236 (*nuclearDensityCache)[nuclideID] = density;
237 }
238
239 void clearCache() {
240
241 if(nuclearDensityCache) {
242 for(std::map<G4int,NuclearDensity const *>::const_iterator i = nuclearDensityCache->begin(); i!=nuclearDensityCache->end(); ++i)
243 delete i->second;
244 nuclearDensityCache->clear();
245 delete nuclearDensityCache;
246 nuclearDensityCache = NULL;
247 }
248
249 if(rpCorrelationTableCache) {
250 for(std::map<G4int,InterpolationTable*>::const_iterator i = rpCorrelationTableCache->begin(); i!=rpCorrelationTableCache->end(); ++i)
251 delete i->second;
252 rpCorrelationTableCache->clear();
253 delete rpCorrelationTableCache;
254 rpCorrelationTableCache = NULL;
255 }
256
257 if(rCDFTableCache) {
258 for(std::map<G4int,InterpolationTable*>::const_iterator i = rCDFTableCache->begin(); i!=rCDFTableCache->end(); ++i)
259 delete i->second;
260 rCDFTableCache->clear();
261 delete rCDFTableCache;
262 rCDFTableCache = NULL;
263 }
264
265 if(pCDFTableCache) {
266 for(std::map<G4int,InterpolationTable*>::const_iterator i = pCDFTableCache->begin(); i!=pCDFTableCache->end(); ++i)
267 delete i->second;
268 pCDFTableCache->clear();
269 delete pCDFTableCache;
270 pCDFTableCache = NULL;
271 }
272 }
273
274 } // namespace NuclearDensityFactory
275
276} // namespace G4INCL
G4double S(G4double temp)
Simple interpolation table for the inverse of a IFunction1D functor.
#define INCL_ERROR(x)
#define INCL_DEBUG(x)
Class for Gaussian density.
NDF* class for the deuteron density according to the HardSphere potential.
Class for modified harmonic oscillator density.
NDF* class for the deuteron density according to the Paris potential.
Class for Woods-Saxon density.
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
const G4double A[17]
InterpolationTable * inverseCDFTable(ManipulatorFunc fWrap=0, const G4int nNodes=60) const
Return a pointer to the inverse of the CDF of this function.
Class for interpolating the of a 1-dimensional function.
G4double pow13(G4double x)
const G4double oneOverSqrtThree
InterpolationTable * createRPCorrelationTable(const ParticleType t, const G4int A, const G4int Z)
void addDensityToCache(const G4int A, const G4int Z, NuclearDensity *const density)
InterpolationTable * createPCDFTable(const ParticleType t, const G4int A, const G4int Z)
NuclearDensity const * createDensity(const G4int A, const G4int Z, const G4int S)
void addRPCorrelationToCache(const G4int A, const G4int Z, const ParticleType t, InterpolationTable *const table)
InterpolationTable * createRCDFTable(const ParticleType t, const G4int A, const G4int Z)
G4ThreadLocal FermiMomentumFn getFermiMomentum
G4double getRadiusParameter(const ParticleType t, const G4int A, const G4int Z)
G4double getMaximumNuclearRadius(const ParticleType t, const G4int A, const G4int Z)
G4double getSurfaceDiffuseness(const ParticleType t, const G4int A, const G4int Z)
G4double getMomentumRMS(const G4int A, const G4int Z)
Return the RMS of the momentum distribution (light clusters).
#define G4ThreadLocal
Definition tls.hh:77