Index: trunk/src/Nucleus.h =================================================================== --- trunk/src/Nucleus.h (revision 453) +++ trunk/src/Nucleus.h (revision 454) @@ -1,76 +1,76 @@ //============================================================================== // Nucleus.h // // Copyright (C) 2010-2019 Tobias Toll and Thomas Ullrich // // This file is part of Sartre. // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation. // This program is distributed in the hope that it will be useful, // but without any warranty; without even the implied warranty of // merchantability or fitness for a particular purpose. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // Author: Thomas Ullrich // Last update: // $Date$ // $Author$ //============================================================================== #ifndef Nucleus_h #define Nucleus_h #include #include using namespace std; class TH1D; class Nucleus { public: Nucleus(); Nucleus(unsigned int A); Nucleus(const Nucleus&); virtual ~Nucleus(); Nucleus& operator=(const Nucleus&); virtual void init(unsigned int A); double T(double b) const; // b in fm, returns in GeV^2 double TofProton(double b); unsigned int A() const; unsigned int Z() const; float spin() const; // in hbar double radius() const; // in fm string name() const; int pdgID() const; // id of this nucleus int pdgID(int Z, int A) const; - double atomicMass() const; + double nuclearMass() const; void normalizationOfT(double eps = 1.e-8); // for checks only double rho0() const; //in fm protected: double rho(double, double); double rhoForIntegration(double*, double*); double TForIntegration(double*, double*) const; protected: unsigned int mA; unsigned int mZ; float mSpin; - double mMass; // atomic mass in GeV + double mMass; // nuclear mass in GeV double mRadius; // fm - Wood-Saxon double mSurfaceThickness; // fm - Wood-Saxon double mRho0; // fm^-3 - Wood-Saxon double mOmega; // Wood-Saxon double mHulthenA; // for Hulthen distribution double mHulthenB; string mName; unique_ptr mLookupTable; // T lookup table }; #endif Index: trunk/src/Nucleus.cpp =================================================================== --- trunk/src/Nucleus.cpp (revision 453) +++ trunk/src/Nucleus.cpp (revision 454) @@ -1,343 +1,355 @@ //============================================================================== // Nucleus.cpp // // Copyright (C) 2010-2019 Tobias Toll and Thomas Ullrich // // This file is part of Sartre. // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation. // This program is distributed in the hope that it will be useful, // but without any warranty; without even the implied warranty of // merchantability or fitness for a particular purpose. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // Author: Thomas Ullrich // Last update: // $Date$ // $Author$ //============================================================================== #include "Nucleus.h" #include "Constants.h" #include "TF1.h" #include "TH1.h" #include "TH1D.h" #include #include #define PR(x) cout << #x << " = " << (x) << endl; Nucleus::Nucleus() { mA = mZ = 0; mRadius = 0; mSpin = 0; mSurfaceThickness = 0; mRho0 = 0; mOmega = 0; mMass = 0; mHulthenA = 0; mHulthenB = 0; } Nucleus::Nucleus(unsigned int A) { mA = mZ = 0; mRadius = 0; mSpin = 0; mSurfaceThickness = 0; mRho0 = 0; mOmega = 0; mMass = 0; mHulthenA = 0; mHulthenB = 0; Nucleus::init(A); } Nucleus& Nucleus::operator=(const Nucleus& n) { if (this != &n) { mA = n.mA; mZ = n.mZ; mRadius = n.mRadius; mSpin = n.mSpin; mSurfaceThickness = n.mSurfaceThickness; mRho0 = n.mRho0; mOmega = n.mOmega; mMass = n.mMass; mName = n.mName; mHulthenA = n.mHulthenA; mHulthenB = n.mHulthenB; mLookupTable = unique_ptr(new TH1D(*(n.mLookupTable))); mLookupTable->SetDirectory(0); } return *this; } Nucleus::Nucleus(const Nucleus& n) { mA = n.mA; mZ = n.mZ; mRadius = n.mRadius; mSpin = n.mSpin; mSurfaceThickness = n.mSurfaceThickness; mRho0 = n.mRho0; mOmega = n.mOmega; mMass = n.mMass; mName = n.mName; mHulthenA = n.mHulthenA; mHulthenB = n.mHulthenB; mLookupTable = unique_ptr(new TH1D(*(n.mLookupTable))); mLookupTable->SetDirectory(0); } Nucleus::~Nucleus() { // // This is a temorary fix of a problem in the code that is not understood. // In the table generation code after all is calculated the ~TH1 of the // look up table histogram causes a crash. This appears (?) to be related // to issues in GSL and ROOT. Releasing the pointer causes a memory leak // but this is not a big problem since it happens at the end of the program. // mLookupTable.release(); } void Nucleus::init(unsigned int A) { mA = A; // // Set the parameters of the nucleus - // Woods-Saxon parameter are from Ramona Vogt's paper on nuclear geometry (table 1) + // Woods-Saxon parameter are from Ramona Vogt's paper on nuclear geometry (table 1). + // The parametrization is a 3 parameter fermi model (or 2 parameter with omega=0). // One exception is the deuteron where a Hulthen function is used (nucl-ex/0701025v1). // All version are defined such that Integral(d3r rho(r)) = A - // + // Masses from https://wwwndc.jaea.go.jp/NuC/ + // const double unifiedAtomicMass = 0.931494013; switch (mA) { case 208: // Pb mZ = 82; mRadius = 6.624; mSurfaceThickness = 0.549; mOmega = 0; mRho0 = 0.160; mName = "Pb"; - mMass = 207.2*unifiedAtomicMass; - mSpin = 1./2.; + mMass = 207.976651189*unifiedAtomicMass-mZ*electronMass; + mSpin = 0; break; case 197: // Au mZ = 79; mRadius = 6.38; mSurfaceThickness = 0.535; mOmega = 0; mRho0 = 0.1693; mName = "Au"; - mMass = 196.96655*unifiedAtomicMass; + mMass = 196.966568812*unifiedAtomicMass-mZ*electronMass; mSpin = 3./2.; break; case 110: // Cd mZ = 48; mRadius = 5.33; mSurfaceThickness = 0.535; mOmega = 0; mRho0 = 0.1577; mName = "Cd"; - mMass = 112.411*unifiedAtomicMass; - mSpin = 1./2.; - break; + mMass = 109.903004927*unifiedAtomicMass-mZ*electronMass; + mSpin = 0; + break; + case 90: // Zr + mZ = 40; + mRadius = 4.9736093; // from R. Vogt 1.19*A^(1/3)-1.61*A^(-1/3) + mSurfaceThickness = 0.54; // from R. Vogt + mOmega = 0; // from R. Vogt + mRho0 = 0.15643742; + mName = "Zr"; + mMass = 89.904696939*unifiedAtomicMass-mZ*electronMass; + mSpin = 0; + break; case 63: // Cu mZ = 29; mRadius = 4.214; mSurfaceThickness = 0.586; mOmega = 0; mRho0 = 0.1701; mName = "Cu"; - mMass = 63.546*unifiedAtomicMass; + mMass = 62.929597770*unifiedAtomicMass-mZ*electronMass; mSpin = 3./2.; break; case 40: // Ca mZ = 20; mRadius = 3.766; mSurfaceThickness = 0.586; mOmega = -0.161; mRho0 = 0.1699; mName = "Ca"; - mMass= 40.078*unifiedAtomicMass; - mSpin = 7./2.; + mMass= 39.962590863*unifiedAtomicMass-mZ*electronMass; + mSpin = 0; break; case 27: // Al mZ = 13; mRadius = 3.07; mSurfaceThickness = 0.519; mOmega = 0; mRho0 = 0.1739; mName = "Al"; - mMass = 26.981538*unifiedAtomicMass; + mMass = 26.981538578*unifiedAtomicMass-mZ*electronMass; mSpin = 5./2.; break; case 16: // O mZ = 8; mRadius = 2.608; mSurfaceThickness = 0.513; mOmega = -0.051; mRho0 = 0.1654; mName = "O"; - mMass = 15.9994*unifiedAtomicMass; - mSpin = 5./2.; + mMass = 15.99491461957*unifiedAtomicMass-mZ*electronMass; + mSpin = 0; break; case 2: // D mZ = 1; mHulthenA = 0.456; mHulthenB = 2.36; mRho0 = 0.39946312; mName = "D"; - mMass = 2.014102*unifiedAtomicMass; + mMass = 2.01410177812*unifiedAtomicMass-mZ*electronMass; mSpin = 1; mRadius = 2.116; // not used for density function - taken from Jager et al. break; case 1: // When generating this nucleus, only one nucleon is put at (0, 0, 0) mZ = 1; mRadius = 1.; mMass = protonMass; // 1.00794*unifiedAtomicMass mName = "p"; //The following 3 are dummies, needed for radial distribution etc.: mSurfaceThickness = 0.513; mOmega = -0.051; mRho0 = 0.1654; mSpin = 1./2.; break; default: cout << "Nucleus::init(): Error, cannot handle A=" << mA << ", no parameters defined for this mass number." << endl; exit(1); break; } // // Generate lookup table for overlap integral T // (b and z in fm) // double range = 3*mRadius; TF1* funcToIntegrate = new TF1("funcToIntegrate",this, &Nucleus::rhoForIntegration, -range, range, 1); int nbins = 5000; // size of lookup table mLookupTable = unique_ptr(new TH1D("mLookupTable","T lookup table", nbins, 0, range)); mLookupTable->SetDirectory(0); for (int i=1; i<=nbins; i++) { double b = mLookupTable->GetBinCenter(i); funcToIntegrate->SetNpx(1000); funcToIntegrate->SetParameter(0, b); double res = funcToIntegrate->Integral(-range, range, 1e-8); mLookupTable->SetBinContent(i, res); } delete funcToIntegrate; } unsigned int Nucleus::A() const { return mA; } unsigned int Nucleus::Z() const { return mZ; } float Nucleus::spin() const { return mSpin; } -double Nucleus::atomicMass() const { return mMass; } +double Nucleus::nuclearMass() const { return mMass; } string Nucleus::name() const { return mName; } double Nucleus::radius() const { return mRadius; } double Nucleus::rho(double b, double z) // returns value in units of fm^-3 { // b and z in fm double r = sqrt(b*b+z*z); if (mA == 2) { double term = (exp(-mHulthenA*r)/r) - (exp(-mHulthenB*r)/r); // Hulthen return mRho0*term*term; } else { return mRho0*(1+mOmega*(r/mRadius)*(r/mRadius))/(1+exp((r-mRadius)/mSurfaceThickness)); // 3pF } } double Nucleus::rhoForIntegration(double *x, double* par) { // b and z in fm double b = par[0]; double z = *x; return rho(b, z); } double Nucleus::T(double b) const { // // Returns overlap integral // b in fm, overlap function T in GeV^2 // Returns 0 if b exceeds table range // if (mA == 0) { cout << "Nucleus::T(): Error, instance is not initialized - cannot calculate overlap integral." << endl; return 0; } int bin = mLookupTable->FindBin(b); double res = mLookupTable->GetBinContent(bin); return res*hbarc2; } double Nucleus::TForIntegration(double *x, double*) const { double b = x[0]; return 2*b*M_PI*T(b)/hbarc2; } void Nucleus::normalizationOfT(double eps) { // // This is for internal checks only. // Normalization of rho/T is such that fully integrated // function should yield A. // double range = 3*mRadius; TF1* func = new TF1("func",this, &Nucleus::TForIntegration, 0, range, 0); double res = func->Integral(0, range, eps); cout << "Normalization of T: = " << res << endl; delete func; } double Nucleus::rho0() const { return mRho0; } double Nucleus::TofProton(double b) { // // Gaussian shape for proton // Units: // b in fm // const double BG = 4; // GeV^-2 double arg = b*b/(2*BG); arg /= hbarc2; return 1/(2*M_PI*BG) * exp(-arg); } int Nucleus::pdgID(int Z, int A) const { // PDG for nuclei 10LZZZAAAI // L = number of strange quark (for hypernuclei) // I = isomer level, with I = 0 corresponding to the // ground state and I > 0 to excitations, if (Z==1 && A==1) return 2212; else if (Z==0 && A==1) return 2112; else if (A > 1) return 1000000000 + 10000*Z + 10*A; else return 0; } int Nucleus::pdgID() const { return pdgID(mZ, mA); }