Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/inclxx/utils/src/G4INCLNuclearMassTable.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 /** \file G4INCLNuclearMassTable.cc
 39  * \brief Functions that encapsulate a mass table
 40  *
 41  * \date 22nd October 2013
 42  * \author Davide Mancusi
 43  */
 44 
 45 #ifndef INCLXX_IN_GEANT4_MODE
 46 
 47 #include "G4INCLNuclearMassTable.hh"
 48 #include "G4INCLParticleTable.hh"
 49 #include "G4INCLGlobals.hh"
 50 #include <algorithm>
 51 #include <istream>
 52 
 53 namespace G4INCL {
 54 
 55   namespace {
 56 
 57     G4ThreadLocal G4double **theTable = NULL;
 58     G4ThreadLocal G4int AMax = 0;
 59     G4ThreadLocal G4int *ZMaxArray = NULL;
 60     G4ThreadLocal G4double protonMass = 0.;
 61     G4ThreadLocal G4double neutronMass = 0.;
 62 
 63     const G4double amu = 931.494061; // atomic mass unit in MeV/c^2
 64     const G4double eMass = 0.5109988; // electron mass in MeV/c^2
 65 
 66     G4double getWeizsaeckerMass(const G4int A, const G4int Z) {
 67       const G4int Npairing = (A-Z)%2;                  // pairing
 68       const G4int Zpairing = Z%2;
 69       const G4double fA = (G4double) A;
 70       const G4double fZ = (G4double) Z;
 71       G4double binding =
 72         - 15.67*fA                          // nuclear volume
 73         + 17.23*Math::pow23(fA)                // surface energy
 74         + 93.15*((fA/2.-fZ)*(fA/2.-fZ))/fA       // asymmetry
 75         + 0.6984523*fZ*fZ*Math::powMinus13(fA);      // coulomb
 76       if( Npairing == Zpairing ) binding += (Npairing+Zpairing-1) * 12.0 / std::sqrt(fA);  // pairing
 77 
 78       return fZ*::G4INCL::ParticleTable::getRealMass(Proton)+((G4double)(A-Z))
 79         *::G4INCL::ParticleTable::getRealMass(Neutron)+binding;
 80     }
 81 
 82     void setMass(const G4int A, const G4int Z, const G4double mass) {
 83       theTable[A][Z] = mass;
 84     }
 85 
 86     class MassRecord {
 87       public:
 88         MassRecord() :
 89           A(0),
 90           Z(0),
 91           excess(0.)
 92       {}
 93 
 94         MassRecord(const G4int a, const G4int z, const G4double e) :
 95           A(a),
 96           Z(z),
 97           excess(e)
 98       {}
 99 
100         friend std::istream &operator>>(std::istream &in, MassRecord &record);
101 
102         G4int A;
103         G4int Z;
104         G4double excess;
105     };
106 
107     std::istream &operator>>(std::istream &in, MassRecord &record) {
108       return (in >> record.A >> record.Z >> record.excess);
109     }
110 
111     G4bool compareA(const MassRecord &lhs, const MassRecord &rhs) {
112       return (lhs.A < rhs.A);
113     }
114 
115   }
116 
117   namespace NuclearMassTable {
118 
119     void initialize(const std::string &path, const G4double pMass, const G4double nMass) {
120       protonMass = pMass;
121       neutronMass = nMass;
122 
123       // Clear the existing tables, if any
124       deleteTable();
125 
126       // File name
127       std::string fileName(path + "/walletlifetime.dat");
128       INCL_DEBUG("Reading real nuclear masses from file " << fileName << '\n');
129 
130       // Open the file stream
131       std::ifstream massTableIn(fileName.c_str());
132       if(!massTableIn.good()) {
133         std::cerr << "Cannot open " << fileName << " data file." << '\n';
134         std::abort();
135         return;
136       }
137 
138       // read the file
139       std::vector<MassRecord> records;
140       MassRecord record;
141       while(massTableIn.good()) { /* Loop checking, 10.07.2015, D.Mancusi */
142         massTableIn >> record;
143         records.push_back(record);
144       }
145       massTableIn.close();
146       INCL_DEBUG("Read " << records.size() << " nuclear masses" << '\n');
147 
148       // determine the max A
149       AMax = std::max_element(records.begin(), records.end(), compareA)->A;
150       INCL_DEBUG("Max A in nuclear-mass table = " << AMax << '\n');
151       ZMaxArray = new G4int[AMax+1];
152       std::fill(ZMaxArray, ZMaxArray+AMax+1, 0);
153       theTable = new G4double*[AMax+1];
154       std::fill(theTable, theTable+AMax+1, static_cast<G4double*>(NULL));
155 
156       // determine the max A per Z
157       for(std::vector<MassRecord>::const_iterator i=records.begin(), e=records.end(); i!=e; ++i) {
158         ZMaxArray[i->A] = std::max(ZMaxArray[i->A], i->Z);
159       }
160 
161       // allocate the arrays
162       for(G4int A=1; A<=AMax; ++A) {
163         theTable[A] = new G4double[ZMaxArray[A]+1];
164         std::fill(theTable[A], theTable[A]+ZMaxArray[A]+1, -1.);
165       }
166 
167       // fill the actual masses
168       for(std::vector<MassRecord>::const_iterator i=records.begin(), e=records.end(); i!=e; ++i) {
169         setMass(i->A, i->Z, i->A*amu + i->excess - i->Z*eMass);
170       }
171     }
172 
173     G4double getMass(const G4int A, const G4int Z) {
174       if(A>AMax || Z>ZMaxArray[A]) {
175         INCL_DEBUG("Real mass unavailable for isotope A=" << A << ", Z=" << Z
176                    << ", using Weizsaecker's formula"
177                    << '\n');
178         return getWeizsaeckerMass(A,Z);
179       }
180 
181       const G4double mass = theTable[A][Z];
182       if(mass<0.) {
183         INCL_DEBUG("Real mass unavailable for isotope A=" << A << ", Z=" << Z
184                    << ", using Weizsaecker's formula"
185                    << '\n');
186         return getWeizsaeckerMass(A,Z);
187       } else
188         return mass;
189     }
190     
191     G4double getMass(const G4int A, const G4int Z, const G4int S){
192     if(S>=0) return getMass(A,Z);
193     
194 // assert(A >= 1);
195 // assert(Z < A);
196 // assert(S*(-1)<=A);
197     
198     const G4double mL = ParticleTable::getRealMass(Lambda); // mLambda
199     if(A == (-1)*S) return A*mL;
200     
201     if( A==2 && Z == 0) { // No stable hypernuclei with A=2
202       return mL+ParticleTable::getRealMass(Neutron);
203     }
204     else if( Z == 0) { // No stable hypernuclei with Z=0
205       return (A+S)*ParticleTable::getRealMass(Neutron)-mL*S;
206     }
207     else if( A==2 && Z == 1) {
208       return mL+ParticleTable::getRealMass(Proton);
209     }
210 
211 
212     const G4double b7=25.; // (MeV)
213     const G4double b8=10.5; // Slope
214     const G4double a2=0.13; // BindingEnergy for d+Lambda(MeV)
215     const G4double a3=2.2;  // BindingEnergy for (t/He3)+Lamb(MeV)
216     const G4double eps =0.0001; // security value (MeV)
217 
218     G4double mass =  getMass(A+S, Z);
219     
220     G4double bs=0.;
221     if     (A+S ==2) bs=a2;         // for nnL,npL,ppL
222     else if(A+S ==3) bs=a3;         // for 3nL,2npL,n2pL,3pL
223     else if(A+S >3)  bs=b7*std::exp(-b8/(A+S+1.));
224     mass += (-1)*S*(mL-bs) + eps;
225 
226     return mass;
227   }
228 
229     void deleteTable() {
230       delete[] ZMaxArray;
231       ZMaxArray = NULL;
232       for(G4int A=1; A<=AMax; ++A)
233         delete[] theTable[A];
234       delete[] theTable;
235       theTable = NULL;
236     }
237   }
238 
239 }
240 
241 #endif // INCLXX_IN_GEANT4_MODE
242