nuclear_mass.h

00001 /*
00002   -------------------------------------------------------------------
00003   
00004   Copyright (C) 2006, 2007, Andrew W. Steiner
00005   
00006   This file is part of O2scl.
00007   
00008   O2scl is free software; you can redistribute it and/or modify
00009   it under the terms of the GNU General Public License as published by
00010   the Free Software Foundation; either version 3 of the License, or
00011   (at your option) any later version.
00012   
00013   O2scl is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016   GNU General Public License for more details.
00017   
00018   You should have received a copy of the GNU General Public License
00019   along with O2scl. If not, see <http://www.gnu.org/licenses/>.
00020 
00021   -------------------------------------------------------------------
00022 */
00023 #ifndef O2SCL_NUCLEAR_MASS_H
00024 #define O2SCL_NUCLEAR_MASS_H
00025 
00026 #include <cmath>
00027 #include <string>
00028 #include <map>
00029 #include <o2scl/nucleus.h>
00030 #include <o2scl/constants.h>
00031 #include <o2scl/base_ioc.h>
00032 
00033 #ifndef DOXYGENP
00034 namespace o2scl {
00035 #endif
00036   
00037   /** 
00038       \brief Nuclear mass formula base
00039 
00040       \note Some mass formulas are undefined for sufficiently exotic 
00041       nuclei. Use the function is_included() to find if a particular
00042       nucleus is included or not.
00043 
00044       \note All descendants ought to set \c form_type to indicate
00045       whether the mass formula is discrete or continuous
00046       
00047       Elements 112-118 are named "Uub", "Uut", "Uuq", "Uup",
00048       "Uuh", "Uus", and "Uuo", respectively.
00049       
00050       The binding energy is defined
00051       \f[
00052       \mathrm{BE}=Z m_{H} + N m_{n} - m_{\mathrm{nuclide}}
00053       \f]
00054       where \f$m_{\mathrm{nuclide}}\f$ is the mass of the
00055       nucleus including the mass of the electrons.
00056       The mass excess is defined
00057       \f[
00058       m_{\mathrm{excess}} = m_{\mathrm{nuclide}} - A m_{u}
00059       \f]
00060       
00061       For example, for \f$ \mathrm{U}^{238} \f$, the binding energy is
00062       1801.695 MeV, the mass excess is 47.30366 MeV, and
00063       \f$m_{\mathrm{nuclide}}\f$ is 221742.9 MeV. This is consistent
00064       with the above, as \f$m_H\f$ is 938.7830 MeV, \f$m_n\f$ is
00065       939.5650 MeV, and \f$m_u\f$ is 931.494 MeV.
00066 
00067       Some common reaction Q-values and separation energies: \n
00068       \f$\mathrm{Q}(\beta^{-})=\mathrm{M(A,Z)}-\mathrm{M(A,Z+1)}\f$: 
00069       Beta-decay energy \n
00070       \f$\mathrm{Q}(2\beta^{-})=\mathrm{M(A,Z)}-\mathrm{M(A,Z+2)}\f$: 
00071       Double beta-decay energy \n
00072       \f$\mathrm{Q}(4\beta^{-})=\mathrm{M(A,Z)}-\mathrm{M(A,Z+4)}\f$: 
00073       Four beta-decay energy \n
00074       \f$\mathrm{Q}(\alpha)=\mathrm{M(A,Z)}-\mathrm{M(A-4,Z-2)}-
00075       \mathrm{M(He^{4})}\f$: 
00076       Alpha-decay energy \n
00077       \f$\mathrm{Q}(\beta-n)=\mathrm{M(A,Z)}-\mathrm{M(A-1,Z+1)}
00078       -\mathrm{M(n)}\f$: 
00079       Beta-delayed neutron emission decay energy \n
00080       \f$\mathrm{Q}(d,\alpha)=\mathrm{M(A,Z)}-\mathrm{M(A-2,Z-1)}
00081       -\mathrm{M(He^{4})}-\mathrm{M(H^{2})}\f$: 
00082       \f$(d,\alpha)\f$ reaction energy \n
00083       \f$\mathrm{Q}(\mathrm{EC})=\mathrm{M(A,Z)}-\mathrm{M(A,Z-1)}\f$: 
00084       Electron capture decay energy \n
00085       \f$\mathrm{Q}(\mathrm{ECp})=\mathrm{M(A,Z)}-\mathrm{M(A-1,Z-2)}\f$: 
00086       Electron capture with delayed proton emission decay energy \n
00087       \f$\mathrm{Q}(n,\alpha)=\mathrm{M(A,Z)}-\mathrm{M(A-3,Z-2)}
00088       -\mathrm{M(He^{4})}+\mathrm{M(n)}\f$: 
00089       \f$(n,\alpha)\f$ reaction energy \n
00090       \f$\mathrm{Q}(p,\alpha)=\mathrm{M(A,Z)}-\mathrm{M(A-3,Z-1)}
00091       -\mathrm{M(He^{4})}+\mathrm{M(p)}\f$: 
00092       \f$(p,\alpha)\f$ reaction energy \n
00093       \f$\mathrm{S}(n) = \mathrm{-M(A,Z)}+\mathrm{M(A-1,Z)}+
00094       \mathrm{M(n)}\f$: Neutron separation energy \n
00095       \f$\mathrm{S}(p) = \mathrm{-M(A,Z)}+\mathrm{M(A-1,Z-1)}+
00096       \mathrm{H^{1}}\f$: Proton separation energy \n
00097       \f$\mathrm{S}(2n) = \mathrm{-M(A,Z)}+\mathrm{M(A-2,Z)}+
00098       \mathrm{2M(n)}\f$: Two neutron separation energy \n
00099       \f$\mathrm{S}(2p) = \mathrm{-M(A,Z)}+\mathrm{M(A-2,Z-2)}+
00100       \mathrm{2 M(H^{1)}}\f$: Two proton separation energy \n
00101 
00102       \todo The presence or absence of the electron binding energy
00103       contribution is not so well documented here. 
00104 
00105   */
00106   class nuclear_mass {
00107   public:
00108     
00109     nuclear_mass();
00110     
00111     virtual ~nuclear_mass() {};
00112 
00113     /** 
00114         \brief Return false if the mass formula does not include 
00115         specified nucleus
00116     */
00117     virtual bool is_included(int Z, int N) {
00118       return true;
00119     }
00120     
00121     /** \brief Fill \c n with the information from nucleus with the given
00122         neutron and proton number
00123         
00124         All masses are given in \f$\mathrm{fm}^{-1}\f$. The total mass
00125         (withouth the electrons) is put in part::m, and the degeneracy
00126         (part::g) is arbitrarily set to 1 for even A nuclei and 2 for
00127         odd A nuclei.
00128     */
00129     int get_nucleus(int Z, int N, nucleus &n) {
00130       n.Z=Z;
00131       n.N=N;
00132       n.A=Z+N;
00133       n.mex=mass_excess(Z,N)/o2scl_const::hc_mev_fm;
00134       n.m=n.mex+((Z+N)*o2scl_fm::mass_amu-Z*o2scl_fm::mass_electron);
00135       n.ms=n.mex+((Z+N)*o2scl_fm::mass_amu-Z*o2scl_fm::mass_electron);
00136       n.be=(n.m-N*o2scl_fm::mass_neutron-Z*o2scl_fm::mass_proton);
00137       if (n.A%2==0) n.g=1.0;
00138       else n.g=2.0;
00139       return 0;
00140     }
00141     
00142     /// Given \c Z and \c N, return the mass excess in MeV
00143     virtual double mass_excess(int Z, int N) {
00144       if (form_type==cont_type) {
00145         return mass_excess_d(Z,N);
00146       }
00147       set_err("Using base class version of mass_excess().",gsl_nobase);
00148       return 0.0;
00149     }
00150     
00151 
00152     /// Given \c Z and \c N, return the mass excess in MeV
00153     virtual double mass_excess_d(double Z, double N) {
00154       if (form_type==disc_type) {
00155         int Z1=(int)Z;
00156         int N1=(int)N;
00157         double mz1n1=mass_excess(Z1,N1);
00158         double mz1n2=mass_excess(Z1,N1+1);
00159         double mz2n1=mass_excess(Z1+1,N1);
00160         double mz2n2=mass_excess(Z1+1,N1+1);
00161         double mz1=mz1n1+(N-N1)*(mz1n2-mz1n1);
00162         double mz2=mz2n1+(N-N1)*(mz2n2-mz2n1);
00163         return mz1+(Z-Z1)*(mz2-mz1);
00164       }
00165       set_err("Using base class version of mass_excess_d().",gsl_nobase);
00166       return 0.0;
00167     }
00168     
00169     /** 
00170         \brief Return the binding energy in MeV
00171         
00172         The binding energy is defined to be negative for bound 
00173         nuclei, thus the binding energy per baryon of Pb-208
00174         is about -8*208 = -1664 MeV.
00175     */
00176     virtual double binding_energy(int Z, int N) {
00177       return (mass_excess(Z,N)+
00178               ((Z+N)*o2scl_fm::mass_amu-Z*o2scl_fm::mass_electron-
00179                N*o2scl_fm::mass_neutron-Z*o2scl_fm::mass_proton)*
00180               o2scl_const::hc_mev_fm);
00181     }
00182 
00183     /** 
00184         \brief Return the binding energy in MeV
00185         
00186         The binding energy is defined to be negative for bound 
00187         nuclei, thus the binding energy per baryon of Pb-208
00188         is about -8*208 = -1664 MeV.
00189     */
00190     virtual double binding_energy_d(double Z, double N) {
00191       return (mass_excess_d(Z,N)+
00192               ((Z+N)*o2scl_fm::mass_amu-Z*o2scl_fm::mass_electron-
00193                N*o2scl_fm::mass_neutron-Z*o2scl_fm::mass_proton)*
00194               o2scl_const::hc_mev_fm);
00195     }
00196     
00197     /** \brief Return the total mass of the nucleus (without the electrons) 
00198         in MeV
00199     */
00200     virtual double total_mass(int Z, int N) {
00201       return (mass_excess(Z,N)+((Z+N)*o2scl_fm::mass_amu-
00202                                 Z*o2scl_fm::mass_electron)*
00203               o2scl_const::hc_mev_fm);
00204     }
00205 
00206     /** \brief Return the total mass of the nucleus (without the electrons) 
00207         in MeV
00208     */
00209     virtual double total_mass_d(double Z, double N) {
00210       return (mass_excess_d(Z,N)+((Z+N)*o2scl_fm::mass_amu-
00211                                   Z*o2scl_fm::mass_electron)*
00212               o2scl_const::hc_mev_fm);
00213     }
00214 
00215     /// Return Z given the element name
00216     int eltoZ(std::string el) {
00217       return element_table.find(el)->second;
00218     }
00219     
00220     /// Return the element name given Z
00221     std::string Ztoel(int Z) {
00222       return element_list[Z];
00223     }
00224     
00225     /** 
00226         \brief Parse a string of the form "Pb208"
00227         
00228         Note that this does not correctly interpret dashes,
00229         e.g. "Pb-208".  will not work.
00230      */
00231     int parse_elstring(std::string ela, int &Z, int &N, int &A) {
00232       if (ela.length()<2) {
00233         set_err_ret
00234           ("Element name too short in nuclear_mass::parse_elstring().",
00235            gsl_efailed);
00236       }
00237       if (ela.length()>3 && isalpha(ela[2])) {
00238         std::string el=ela.substr(0,3);
00239         Z=eltoZ(el);
00240         A=stoi(ela.substr(3,ela.length()-2));
00241         N=A-Z;
00242         return 0;
00243       }
00244       if (ela.length()>2 && isalpha(ela[1])) {
00245         std::string el=ela.substr(0,2);
00246         Z=eltoZ(el);
00247         A=stoi(ela.substr(2,ela.length()-2));
00248         N=A-Z;
00249         return 0;
00250       }
00251       std::string el=ela.substr(0,1);
00252       Z=eltoZ(el);
00253       A=stoi(ela.substr(1,ela.length()-1));
00254       N=A-Z;
00255       return 0;
00256     }
00257     
00258 #ifndef DOXYGEN_INTERNAL
00259 
00260   protected:
00261 
00262     /// String comparison operator for element_table
00263     struct string_less_than {
00264       bool operator()(const std::string s1, const std::string s2) const {
00265         return s1<s2;
00266       }
00267     };
00268     
00269     /// The number of elements (proton number)
00270     static const int nelements=119;
00271     
00272     /// A map containing the proton numbers organized by element name
00273     std::map<std::string,int,string_less_than> element_table;
00274     
00275     /// A convenient typedef for an iterator for element_table
00276     typedef std::map<std::string,int,string_less_than>::iterator table_it;
00277     
00278     /// The list of elements organized by proton number
00279     std::string element_list[nelements];
00280 
00281     /** 
00282         \name Indicate whether or not the mass formula is 
00283         discrete or continuous
00284     */
00285     //@{
00286     int form_type;
00287     static const int cont_type=1;
00288     static const int disc_type=2;
00289     //@}
00290 
00291 #endif
00292     
00293   };
00294 
00295   /** 
00296       \brief Fittable mass formula
00297   */
00298   class nuclear_mass_fit : public nuclear_mass {
00299     
00300   public:
00301     
00302     /// Number of fitting parameters
00303     size_t nfit;
00304 
00305     /// Fix parameters from an array for fitting
00306     virtual int fit_fun(size_t nv, const ovector_view &x) {
00307       return 0;
00308     }
00309     
00310     /// Fill array with guess from present values for fitting
00311     virtual int guess_fun(size_t nv, ovector_view &x) {
00312       return 0;
00313     }
00314 
00315   };
00316 
00317   /** 
00318       \brief Semi-empirical mass formula
00319 
00320       A naive semi-empirical mass formula. 
00321 
00322       \note The default parameters are arbitrary, and are not
00323       determined from a fit.
00324   */
00325   class semi_empirical_mass : public nuclear_mass_fit {
00326 
00327   public:
00328 
00329     /// Binding energy (negative and in MeV, default -16)
00330     double B;
00331 
00332     /// Symmetry energy (in MeV, default 23.7)
00333     double Sv;
00334 
00335     /// Surface energy (in MeV, default 18)
00336     double Ss;
00337 
00338     /// Coulomb energy (in MeV, default 0.7)
00339     double Ec;
00340 
00341     /// Pairing energy (MeV, default 13.0)
00342     double Epair;
00343     
00344     semi_empirical_mass() {
00345       B=-16.0;
00346       Ss=18.0;
00347       Ec=0.7;
00348       Sv=23.7;
00349       Epair=13.0;
00350       nfit=5;
00351       form_type=cont_type;
00352     }
00353 
00354     /// Given \c Z and \c N, return the mass excess in MeV
00355     virtual double mass_excess_d(double Z, double N) {
00356       double A=Z+N, cA=cbrt(A);
00357       double EoA=B+Ss/cA+Ec*Z*Z/cA/A+Sv*pow(1.0-2.0*Z/A,2.0);
00358       if (((int)(A-Z+0.01))%2==0 && ((int)(Z+0.01))%2==0) {
00359         EoA-=Epair/pow(A,1.5);
00360       } else if (((int)(A-Z+0.01))%2==1 && ((int)(Z+0.01))%2==1) {
00361         EoA+=Epair/pow(A,1.5);
00362       }
00363       double ret=EoA*A+Z*(o2scl_fm::mass_proton+o2scl_fm::mass_electron)*
00364         o2scl_const::hc_mev_fm+N*o2scl_fm::mass_neutron*
00365         o2scl_const::hc_mev_fm-A*o2scl_fm::mass_amu*o2scl_const::hc_mev_fm;
00366       return ret;
00367     }
00368     
00369     /// Fix parameters from an array for fitting
00370     virtual int fit_fun(size_t nv, const ovector_view &x) {
00371       B=-x[0]; Sv=x[1]; Ss=x[2]; Ec=x[3]; Epair=x[4];
00372       return 0;
00373     }
00374 
00375     /// Fill array with guess from present values for fitting
00376     virtual int guess_fun(size_t nv, ovector_view &x) {
00377       x[0]=-B; x[1]=Sv; x[2]=Ss; x[3]=Ec; x[4]=Epair;
00378       return 0;
00379     }
00380     
00381   };
00382   
00383   /** 
00384       \brief Mass formula entry structure for Moller, et al.
00385   */
00386   typedef struct mnms95_mass_entry_s {
00387     
00388     /// Neutron number
00389     int N;
00390     
00391     /// Proton number
00392     int Z;
00393     
00394     /// Atomic number
00395     int A;
00396     
00397     /** \name Ground state deformations (perturbed-spheroid parameterization)
00398      */
00399     //@{
00400     /// Quadrupole
00401     double eps2;
00402     /// Octupole
00403     double eps3;
00404     /// Hexadecapole
00405     double eps4;
00406     /// Hexacontatetrapole
00407     double eps6;
00408     /// Hexacontatetrapole without mass asymmetry
00409     double eps6sym;
00410     //@}
00411     
00412     /** \name Ground state deformations in the spherical-harmonics expansion
00413      */
00414     //@{
00415     /// Quadrupole
00416     double beta2;
00417     /// Octupole
00418     double beta3;
00419     /// Hexadecapole
00420     double beta4;
00421     /// Hexacontatetrapole
00422     double beta6;
00423     //@}
00424     
00425     /// The ground-state microscopic energy
00426     double Emic;
00427     
00428     /// The theoretical mass excess (in MeV)
00429     double Mth;
00430     
00431     /// The experimental mass excess (in MeV)
00432     double Mexp;
00433     
00434     /// Experimental mass excess error
00435     double sigmaexp;
00436     
00437     /// The ground-state microscopic energy in the FRLDM
00438     double EmicFL;
00439     
00440     /// The theoretical mass excess in the FRLDM
00441     double MthFL;
00442     
00443   } mnms95_mass_entry;
00444   
00445   template<> int io_tlate<mnms95_mass_entry>::input
00446     (cinput *co, in_file_format *ins, mnms95_mass_entry *t);
00447   template<> int io_tlate<mnms95_mass_entry>::output
00448     (coutput *co, out_file_format *outs, mnms95_mass_entry *t);
00449   template<> const char *io_tlate<mnms95_mass_entry>::type();
00450   
00451   typedef io_tlate<mnms95_mass_entry> mnms95_mass_entry_io_type;
00452   
00453   /** 
00454       \brief Mass formula from Moller, Nix, Myers and Swiatecki
00455       
00456       The data containing an object of type moller_mass_entry for 8979
00457       nuclei is automatically loaded by the constructor.  If the file
00458       (nndc/moller.dat.gz) is not found, then is_loaded() will return
00459       false and all calls to get_ZN() will return an object with \c
00460       N=Z=0.
00461 
00462       \todo Some the blank entries in the table have been replaced
00463       with zero. This is confusing, so it needs to be fixed by
00464       regenerating the data file and somehow correctly representing
00465       the blank entries.
00466       
00467   */
00468   class mnms95_mass : public nuclear_mass {
00469   public:
00470     
00471     mnms95_mass();
00472 
00473     /** 
00474         \brief Return false if the mass formula does not include 
00475         specified nucleus
00476     */
00477     virtual bool is_included(int Z, int N);
00478 
00479     /// Given \c Z and \c N, return the mass excess in MeV
00480     virtual double mass_excess(int Z, int N) {
00481       mnms95_mass_entry ret;
00482       ret=get_ZN(Z,N);
00483       if (ret.Z==0 && ret.N==0) return 0.0;
00484       return ret.Mth;
00485     }
00486     
00487     /** 
00488         \brief Get the entry for the specified proton and neutron number
00489         
00490         This method searches the table using a cached binary search
00491         algorithm. It is assumed that the table is sorted first by
00492         proton number and then by neutron number.
00493     */
00494     mnms95_mass_entry get_ZN(int l_Z, int l_N);
00495     
00496     /// Verify that the constructor properly loaded the table
00497     bool is_loaded() { return loaded; };
00498     
00499     /// The number of table entries
00500     int n;
00501     
00502     /// The array containing the table
00503     mnms95_mass_entry *mass;
00504 
00505 #ifndef DOXYGEN_INTERNAL
00506 
00507   protected:
00508     
00509     /// True if the table was successfully loaded
00510     bool loaded;
00511     
00512     /// The last table index for caching
00513     int last;
00514     
00515 #endif
00516     
00517   };
00518   
00519   /// The experimental values from Moller, Nix, Myers and Swiatecki
00520   class mnms95_mass_exp : public mnms95_mass {
00521 
00522   public:
00523 
00524     /** 
00525         \brief Return false if the mass formula does not include 
00526         specified nucleus
00527     */
00528     virtual bool is_included(int Z, int N);
00529 
00530     /// Given \c Z and \c N, return the mass excess in MeV
00531     virtual double mass_excess(int Z, int N) {
00532       mnms95_mass_entry ret;
00533       ret=get_ZN(Z,N);
00534       if (ret.Z==0 && ret.N==0) return 0.0;
00535       return ret.Mexp;
00536     }
00537 
00538   };
00539 
00540   /** 
00541       \brief Atomic mass entry structure
00542   */
00543   typedef struct ame_entry_s {
00544     
00545     /// N-Z
00546     int NMZ;
00547     
00548     /// Neutron number
00549     int N;
00550     
00551     /// Proton number
00552     int Z;
00553     
00554     /// Atomic number
00555     int A;
00556     
00557     /// Element name
00558     std::string el;
00559     
00560     /// Data origin
00561     std::string orig;
00562     
00563     /// Mass excess
00564     double mass;
00565     
00566     /// Mass excess uncertainty
00567     double dmass;
00568     
00569     /// Binding energy (given in the '95 data)
00570     double be;
00571     
00572     /// Binding energy uncertainty (given in the '95 data)
00573     double dbe;
00574     
00575     /// Binding energy / A (given in the '03 data)
00576     double beoa;
00577     
00578     /// Binding energy / A uncertainty (given in the '03 data)
00579     double dbeoa;
00580     
00581     /// Beta decay mode
00582     std::string bdmode;
00583     
00584     /// Beta-decay energy
00585     double bde;
00586 
00587     /// Beta-decay energy uncertainty
00588     double dbde;
00589     
00590     /// ?
00591     int A2;
00592     
00593     /// Atomic mass
00594     double amass;
00595     
00596     /// Atomic mass uncertainty
00597     double damass;
00598     
00599   } ame_entry;
00600   
00601   /** \brief A support class for I/O of the 1995 AME data
00602    */
00603   class ame_entry95_io_type : public io_tlate<ame_entry> {
00604   public:
00605     int input(cinput *co, in_file_format *ins, ame_entry *t);
00606     int output(coutput *co, out_file_format *outs, ame_entry *t);
00607     virtual const char *type();
00608   };
00609   
00610   /** \brief A support class for I/O of the 2003 AME data
00611    */
00612   class ame_entry03_io_type : public io_tlate<ame_entry> {
00613   public:
00614     int input(cinput *co, in_file_format *ins, ame_entry *t);
00615     int output(coutput *co, out_file_format *outs, ame_entry *t);
00616     virtual const char *type();
00617   };
00618   
00619   /** 
00620       \brief Mass formula from the Atomic Mass Evaluation (2005 and 1993)
00621       
00622       This class provides an interface to the atomic mass table using
00623       data from \ref Audi95 and \ref Audi03. The data is stored
00624       in ame::mass, which is an array of type ame_entry.
00625       
00626       There are four data sets, selected by the specification of the
00627       \c version string in the constructor.
00628       - "95rmd" - "Recommended" data from \ref Audi95 (ame95rmd.dat.gz)
00629       - "95exp" - "Experimental" data from \ref Audi95 (ame95exp.dat.gz)
00630       - "03round" - "Rounded" data from \ref Audi03 (ame03round.dat.gz)
00631       - "03" - Data from \ref Audi03 (default) (ame03.dat.gz)
00632       
00633       If any string other than these four is used, the default
00634       data is loaded. If the constructor cannot find the data file
00635       (e.g. because of a broken installation), then ame::is_loaded()
00636       returns false.
00637       
00638       The 1995 data provided the binding energy stored in
00639       ame_entry::be and ame_entry::dbe, while the 2003 data provided
00640       the binding energy divided by the atomic number stored in
00641       ame_entry::beoa and ame_entry::dbeoa. When the 1995 data is used
00642       ame_entry::beoa and ame_entry::dbeoa are calculated manually,
00643       and when the 2003 data is used ame_entry::be and ame_entry::dbe
00644       are calculated manually.
00645       
00646       Note that blank entries in the original table that correspond to
00647       columns represented by the type \c double are set to zero
00648       arbitrarily.
00649       
00650       Note that all uncertainties are 1 sigma uncertainties.
00651       
00652       \future Create a caching and more intelligent search system for
00653       the table. The table is sorted by A and then N, so we could
00654       probably just copy the search routine from mnms95_mass, which is
00655       sorted by Z and then N.
00656       \future There are strict definitions of the atomic mass unit
00657       and other constants that are defined by the 1995 and 2003
00658       atomic mass evaluations. These should be included properly.
00659   */
00660   class ame_mass : public nuclear_mass {
00661   public:
00662 
00663     /// Create a collection specified by \c version
00664     ame_mass(std::string version="");
00665     
00666     /** 
00667         \brief Return false if the mass formula does not include 
00668         specified nucleus
00669     */
00670     virtual bool is_included(int Z, int N);
00671 
00672     /// Given \c Z and \c N, return the mass excess in MeV
00673     virtual double mass_excess(int Z, int N) {
00674       ame_entry ret;
00675       ret=get_ZN(Z,N);
00676       if (ret.Z==0 && ret.N==0) return 0.0;
00677       return ret.mass/1.0e3;
00678     }
00679     
00680     /// Get element with Z=l_Z and N=l_N (e.g. 82,126).
00681     ame_entry get_ZN(int l_Z, int l_N);
00682     
00683     /// Get element with Z=l_Z and A=l_A (e.g. 82,208).
00684     ame_entry get_ZA(int l_Z, int l_A);
00685     
00686     /// Get element with name l_el and A=l_A (e.g. "Pb",208).
00687     ame_entry get_elA(std::string l_el, int l_A);
00688     
00689     /// Get element with string (e.g. "Pb208")
00690     ame_entry get(std::string nucleus);
00691     
00692     /// The number of entries (about 3000).
00693     int n;
00694     
00695     /// The short names of the columns (length 16)
00696     std::string *short_names;
00697     
00698     /// The long names of the columns (length 16)
00699     std::string *col_names;
00700     
00701     /// The reference for the original data
00702     std::string reference;
00703     
00704     /// The array containing the mass data of length ame::n
00705     ame_entry *mass;
00706     
00707     /// Returns true if the constructor succesfully loaded the data
00708     bool is_loaded() { return loaded; }
00709     
00710 #ifndef DOXYGEN_INTERNAL
00711 
00712   protected:
00713 
00714     /// True if loading the data was successful
00715     bool loaded;
00716 
00717 #endif
00718     
00719   };
00720   
00721 #ifndef DOXYGENP
00722 }
00723 #endif
00724 
00725 #endif

Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.

Project hosting provided by SourceForge.net Logo, O2scl Sourceforge Project Page