Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/inclxx/incl_physics/src/G4INCLNuclearDensityFactory.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 // 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 
 38 #include "G4INCLNuclearDensityFactory.hh"
 39 #include "G4INCLNDFWoodsSaxon.hh"
 40 #include "G4INCLNDFModifiedHarmonicOscillator.hh"
 41 #include "G4INCLNDFGaussian.hh"
 42 #include "G4INCLNDFParis.hh"
 43 #include "G4INCLNDFHardSphere.hh"
 44 #include "G4INCLInvFInterpolationTable.hh"
 45 
 46 namespace 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 
 79     InterpolationTable *createRPCorrelationTable(const ParticleType t, const G4int A, const G4int Z) {
 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 
126     InterpolationTable *createRCDFTable(const ParticleType t, const G4int A, const G4int Z) {
127 // assert(t==Proton || t==Neutron || t==Lambda);
128 
129       if(!rCDFTableCache)
130         rCDFTableCache = new std::map<G4int,InterpolationTable*>;
131 
132       const G4int nuclideID = ((t==Proton) ? 1000 : -1000)*Z + A; // MCNP-style nuclide IDs
133       const std::map<G4int,InterpolationTable*>::const_iterator mapEntry = rCDFTableCache->find(nuclideID);
134       if(mapEntry == rCDFTableCache->end()) {
135 
136         IFunction1D *rDensityFunction;
137         if(A > 19) {
138           G4double radius = ParticleTable::getRadiusParameter(t, A, Z);
139           G4double diffuseness = ParticleTable::getSurfaceDiffuseness(t, A, Z);
140           G4double maximumRadius = ParticleTable::getMaximumNuclearRadius(t, A, Z);
141           rDensityFunction = new NuclearDensityFunctions::WoodsSaxon(radius, maximumRadius, diffuseness);
142         } else if(A <= 19 && A > 6) {
143           G4double radius = ParticleTable::getRadiusParameter(t, A, Z);
144           G4double diffuseness = ParticleTable::getSurfaceDiffuseness(t, A, Z);
145           G4double maximumRadius = ParticleTable::getMaximumNuclearRadius(t, A, Z);
146           rDensityFunction = new NuclearDensityFunctions::ModifiedHarmonicOscillator(radius, maximumRadius, diffuseness);
147         } else if(A <= 6 && A > 2) { // Gaussian distribution for light nuclei
148           G4double radius = ParticleTable::getRadiusParameter(t, A, Z);
149           G4double maximumRadius = ParticleTable::getMaximumNuclearRadius(t, A, Z);
150           rDensityFunction = new NuclearDensityFunctions::Gaussian(maximumRadius, Math::oneOverSqrtThree * radius);
151         } else if(A == 2 && Z == 1) { // density from the Paris potential for deuterons
152           rDensityFunction = new NuclearDensityFunctions::ParisR();
153         } else {
154           INCL_ERROR("No nuclear density function for target A = "
155                 << A << " Z = " << Z << '\n');
156           return NULL;
157         }
158 
159         InterpolationTable *theTable = rDensityFunction->inverseCDFTable();
160         delete rDensityFunction;
161         INCL_DEBUG("Creating inverse position CDF for A=" << A << ", Z=" << Z << ":" <<
162               '\n' << theTable->print() << '\n');
163 
164         (*rCDFTableCache)[nuclideID] = theTable;
165         return theTable;
166       } else {
167         return mapEntry->second;
168       }
169     }
170 
171     InterpolationTable *createPCDFTable(const ParticleType t, const G4int A, const G4int Z) {
172 // assert(t==Proton || t==Neutron || t==Lambda);
173 
174       if(!pCDFTableCache)
175         pCDFTableCache = new std::map<G4int,InterpolationTable*>;
176 
177       const G4int nuclideID = ((t==Proton) ? 1000 : -1000)*Z + A; // MCNP-style nuclide IDs
178       const std::map<G4int,InterpolationTable*>::const_iterator mapEntry = pCDFTableCache->find(nuclideID);
179       if(mapEntry == pCDFTableCache->end()) {
180         IFunction1D *pDensityFunction;
181         if(A > 19) {
182           const G4double theFermiMomentum = ParticleTable::getFermiMomentum(A, Z);
183           pDensityFunction = new NuclearDensityFunctions::HardSphere(theFermiMomentum);
184         } else if(A <= 19 && A > 2) { // Gaussian distribution for light nuclei
185           const G4double momentumRMS = Math::oneOverSqrtThree * ParticleTable::getMomentumRMS(A, Z);
186           pDensityFunction = new NuclearDensityFunctions::Gaussian(5.*momentumRMS, momentumRMS);
187         } else if(A == 2 && Z == 1) { // density from the Paris potential for deuterons
188           pDensityFunction = new NuclearDensityFunctions::ParisP();
189         } else {
190           INCL_ERROR("No nuclear density function for target A = "
191                 << A << " Z = " << Z << '\n');
192           return NULL;
193         }
194 
195         InterpolationTable *theTable = pDensityFunction->inverseCDFTable();
196         delete pDensityFunction;
197         INCL_DEBUG("Creating inverse momentum CDF for A=" << A << ", Z=" << Z << ":" <<
198               '\n' << theTable->print() << '\n');
199 
200         (*pCDFTableCache)[nuclideID] = theTable;
201         return theTable;
202       } else {
203         return mapEntry->second;
204       }
205     }
206 
207     void addRPCorrelationToCache(const G4int A, const G4int Z, const ParticleType t, InterpolationTable * const table) {
208 // assert(t==Proton || t==Neutron || t==Lambda);
209 
210       if(!rpCorrelationTableCache)
211         rpCorrelationTableCache = new std::map<G4int,InterpolationTable*>;
212 
213       const G4int nuclideID = ((t==Proton) ? 1000 : -1000)*Z + A; // MCNP-style nuclide IDs
214       const std::map<G4int,InterpolationTable*>::const_iterator mapEntry = rpCorrelationTableCache->find(nuclideID);
215       if(mapEntry != rpCorrelationTableCache->end())
216         delete mapEntry->second;
217 
218       (*rpCorrelationTableCache)[nuclideID] = table;
219     }
220 
221     void addDensityToCache(const G4int A, const G4int Z, NuclearDensity * const density) {
222       if(!nuclearDensityCache)
223         nuclearDensityCache = new std::map<G4int,NuclearDensity const *>;
224 
225       const G4int nuclideID = 1000*Z + A; // MCNP-style nuclide IDs
226       const std::map<G4int,NuclearDensity const *>::const_iterator mapEntry = nuclearDensityCache->find(nuclideID);
227       if(mapEntry != nuclearDensityCache->end())
228         delete mapEntry->second;
229 
230       (*nuclearDensityCache)[nuclideID] = density;
231     }
232 
233     void clearCache() {
234 
235       if(nuclearDensityCache) {
236         for(std::map<G4int,NuclearDensity const *>::const_iterator i = nuclearDensityCache->begin(); i!=nuclearDensityCache->end(); ++i)
237           delete i->second;
238         nuclearDensityCache->clear();
239         delete nuclearDensityCache;
240         nuclearDensityCache = NULL;
241       }
242 
243       if(rpCorrelationTableCache) {
244         for(std::map<G4int,InterpolationTable*>::const_iterator i = rpCorrelationTableCache->begin(); i!=rpCorrelationTableCache->end(); ++i)
245           delete i->second;
246         rpCorrelationTableCache->clear();
247         delete rpCorrelationTableCache;
248         rpCorrelationTableCache = NULL;
249       }
250 
251       if(rCDFTableCache) {
252         for(std::map<G4int,InterpolationTable*>::const_iterator i = rCDFTableCache->begin(); i!=rCDFTableCache->end(); ++i)
253           delete i->second;
254         rCDFTableCache->clear();
255         delete rCDFTableCache;
256         rCDFTableCache = NULL;
257       }
258 
259       if(pCDFTableCache) {
260         for(std::map<G4int,InterpolationTable*>::const_iterator i = pCDFTableCache->begin(); i!=pCDFTableCache->end(); ++i)
261           delete i->second;
262         pCDFTableCache->clear();
263         delete pCDFTableCache;
264         pCDFTableCache = NULL;
265       }
266     }
267 
268   } // namespace NuclearDensityFactory
269 
270 } // namespace G4INCL
271