00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 2009, 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 #include <o2scl/user_io.h> 00033 00034 #ifndef DOXYGENP 00035 namespace o2scl { 00036 #endif 00037 00038 /// Nuclear mass info 00039 class nuclear_mass_info { 00040 public: 00041 00042 nuclear_mass_info(); 00043 00044 /** 00045 \brief Parse a string representing an element 00046 00047 Accepts strings of one of the following forms: 00048 - <tt>Pb208</tt> 00049 - <tt>pb208</tt> 00050 - <tt>Pb 208</tt> 00051 - <tt>Pb-208</tt> 00052 - <tt>pb 208</tt> 00053 - <tt>pb-208</tt> 00054 or one of the special strings <tt>n</tt>, <tt>p</tt>, <tt>d</tt> 00055 or <tt>t</tt> for the neutron, proton, deuteron, and triton, 00056 respectively. 00057 00058 \note At present, this allows nuclei which don't make sense 00059 because A<Z, such as Carbon-5. 00060 00061 \future Allow A to precede Z. 00062 \future Right now, <tt>n4</tt> is interpreted incorrectly 00063 as Nitrogen-4, rather than the tetraneutron. 00064 00065 */ 00066 int parse_elstring(std::string ela, int &Z, int &N, int &A) { 00067 00068 bool removed=true; 00069 while (removed) { 00070 removed=false; 00071 for(size_t i=0;i<ela.size();i++) { 00072 if (!isalnum(ela[i])) { 00073 ela=ela.substr(0,i)+ela.substr(i+1,ela.size()-i-1); 00074 removed=true; 00075 } 00076 } 00077 } 00078 00079 // If its just a neutron 00080 if (ela=="n") { 00081 Z=0; 00082 N=1; 00083 A=1; 00084 return 0; 00085 } 00086 // If its just a proton 00087 if (ela=="p") { 00088 Z=1; 00089 N=0; 00090 A=1; 00091 return 0; 00092 } 00093 // If its just a deuteron 00094 if (ela=="d") { 00095 Z=1; 00096 N=1; 00097 A=2; 00098 return 0; 00099 } 00100 // If its just a triton; 00101 if (ela=="t") { 00102 Z=1; 00103 N=2; 00104 A=3; 00105 return 0; 00106 } 00107 // Change the first character to upper case if necessary 00108 if (ela[0]>='a' && ela[0]<='z') { 00109 ela[0]='A'+(ela[0]-'a'); 00110 } 00111 if (ela.length()<2) { 00112 O2SCL_ERR_RET 00113 ("Element name too short in nuclear_mass::parse_elstring().", 00114 gsl_efailed); 00115 } 00116 if (ela.length()>3 && isalpha(ela[2])) { 00117 std::string el=ela.substr(0,3); 00118 Z=eltoZ(el); 00119 A=stoi(ela.substr(3,ela.length()-2)); 00120 N=A-Z; 00121 return 0; 00122 } 00123 if (ela.length()>2 && isalpha(ela[1])) { 00124 std::string el=ela.substr(0,2); 00125 Z=eltoZ(el); 00126 A=stoi(ela.substr(2,ela.length()-2)); 00127 N=A-Z; 00128 return 0; 00129 } 00130 std::string el=ela.substr(0,1); 00131 Z=eltoZ(el); 00132 A=stoi(ela.substr(1,ela.length()-1)); 00133 N=A-Z; 00134 return 0; 00135 } 00136 00137 /** 00138 \brief Return Z given the element name 00139 00140 If the string parameter \c el is invalid, the error handler is 00141 called and the value -1 is returned. 00142 */ 00143 int eltoZ(std::string el) { 00144 std::map<std::string,int,string_less_than>::iterator 00145 eti=element_table.find(el); 00146 if (eti==element_table.end()) { 00147 O2SCL_ERR2_RET("Failed to find element in ", 00148 "nuclear_mass_info::eltoZ().",-1); 00149 } 00150 return eti->second; 00151 } 00152 00153 /** 00154 \brief Return the element name given Z 00155 00156 \note This function returns \c "n" indicating the neutron for 00157 Z=0, and if the argument \c Z is greater than 118, an empty 00158 string is returned after calling the error handler. 00159 */ 00160 std::string Ztoel(size_t Z) { 00161 if (((int)Z)>=nelements) { 00162 O2SCL_ERR("Invalid element in Ztoel().",gsl_einval); 00163 return ""; 00164 } 00165 return element_list[Z]; 00166 } 00167 00168 /** 00169 \brief Return a string of the form "Pb208" for a given Z and N 00170 00171 Note that if \c Z is zero, then and \c 'n' is 00172 used to indicate the a nucleus composed entirely of neutrons 00173 and if the argument \c Z is greater than 118, an 00174 empty string is returned (independ. 00175 */ 00176 std::string tostring(size_t Z, size_t N) { 00177 if (((int)Z)>=nelements) { 00178 O2SCL_ERR("Invalid element in Ztoel().",gsl_einval); 00179 return ""; 00180 } 00181 return element_list[Z]+itos(N+Z); 00182 } 00183 00184 #ifndef DOXYGEN_INTERNAL 00185 00186 protected: 00187 00188 /// String comparison operator for element_table 00189 struct string_less_than { 00190 bool operator()(const std::string s1, const std::string s2) const { 00191 return s1<s2; 00192 } 00193 }; 00194 00195 /// The number of elements (proton number) 00196 static const int nelements=119; 00197 00198 /// A map containing the proton numbers organized by element name 00199 std::map<std::string,int,string_less_than> element_table; 00200 00201 /// A convenient typedef for an iterator for element_table 00202 typedef std::map<std::string,int,string_less_than>::iterator table_it; 00203 00204 /// The list of elements organized by proton number 00205 std::string element_list[nelements]; 00206 00207 #endif 00208 00209 00210 }; 00211 00212 /** 00213 \brief Nuclear mass formula base [abstract base] 00214 00215 This base class provides some default functionality for 00216 the nuclear mass formulas. For typical usage, use 00217 \ref ame_mass, \ref mnmsk_mass, \ref mnmsk_mass_exp, 00218 or \ref semi_empirical_mass. 00219 00220 Elements 112-118 are named "Uub", "Uut", "Uuq", "Uup", 00221 "Uuh", "Uus", and "Uuo", respectively. 00222 00223 The binding energy is defined by 00224 \f[ 00225 \mathrm{BE}=Z m_{H} + N m_{n} - m_{\mathrm{nuclide}} 00226 \f] 00227 where \f$m_{\mathrm{nuclide}}\f$ is the mass of the 00228 nucleus including the mass of the electrons. 00229 The mass excess is defined by 00230 \f[ 00231 m_{\mathrm{excess}} = m_{\mathrm{nuclide}} - A m_{u} 00232 \f] 00233 00234 For example, for \f$ \mathrm{U}^{238} \f$, the binding energy is 00235 1801.695 MeV, the mass excess is 47.30366 MeV, and 00236 \f$m_{\mathrm{nuclide}}\f$ is 221742.9 MeV. This is consistent 00237 with the above, as \f$m_H\f$ is 938.7830 MeV, \f$m_n\f$ is 00238 939.5650 MeV, and \f$m_u\f$ is 931.494 MeV. 00239 00240 Some mass formulas are undefined for sufficiently exotic nuclei. 00241 You can use the function is_included() to find if a particular 00242 \nucleus is included or not. 00243 00244 \warning The treatment of the electron binding energy 00245 contribution is not necessarily consistent at present. 00246 00247 Some common reaction Q-values and separation energies: \n 00248 \f$\mathrm{Q}(\beta^{-})=\mathrm{M(A,Z)}-\mathrm{M(A,Z+1)}\f$: 00249 Beta-decay energy \n 00250 \f$\mathrm{Q}(2\beta^{-})=\mathrm{M(A,Z)}-\mathrm{M(A,Z+2)}\f$: 00251 Double beta-decay energy \n 00252 \f$\mathrm{Q}(4\beta^{-})=\mathrm{M(A,Z)}-\mathrm{M(A,Z+4)}\f$: 00253 Four beta-decay energy \n 00254 \f$\mathrm{Q}(\alpha)=\mathrm{M(A,Z)}-\mathrm{M(A-4,Z-2)}- 00255 \mathrm{M(He^{4})}\f$: 00256 Alpha-decay energy \n 00257 \f$\mathrm{Q}(\beta-n)=\mathrm{M(A,Z)}-\mathrm{M(A-1,Z+1)} 00258 -\mathrm{M(n)}\f$: 00259 Beta-delayed neutron emission decay energy \n 00260 \f$\mathrm{Q}(d,\alpha)=\mathrm{M(A,Z)}-\mathrm{M(A-2,Z-1)} 00261 -\mathrm{M(He^{4})}-\mathrm{M(H^{2})}\f$: 00262 \f$(d,\alpha)\f$ reaction energy \n 00263 \f$\mathrm{Q}(\mathrm{EC})=\mathrm{M(A,Z)}-\mathrm{M(A,Z-1)}\f$: 00264 Electron capture decay energy \n 00265 \f$\mathrm{Q}(\mathrm{ECp})=\mathrm{M(A,Z)}-\mathrm{M(A-1,Z-2)}\f$: 00266 Electron capture with delayed proton emission decay energy \n 00267 \f$\mathrm{Q}(n,\alpha)=\mathrm{M(A,Z)}-\mathrm{M(A-3,Z-2)} 00268 -\mathrm{M(He^{4})}+\mathrm{M(n)}\f$: 00269 \f$(n,\alpha)\f$ reaction energy \n 00270 \f$\mathrm{Q}(p,\alpha)=\mathrm{M(A,Z)}-\mathrm{M(A-3,Z-1)} 00271 -\mathrm{M(He^{4})}+\mathrm{M(p)}\f$: 00272 \f$(p,\alpha)\f$ reaction energy \n 00273 \f$\mathrm{S}(n) = \mathrm{-M(A,Z)}+\mathrm{M(A-1,Z)}+ 00274 \mathrm{M(n)}\f$: Neutron separation energy \n 00275 \f$\mathrm{S}(p) = \mathrm{-M(A,Z)}+\mathrm{M(A-1,Z-1)}+ 00276 \mathrm{H^{1}}\f$: Proton separation energy \n 00277 \f$\mathrm{S}(2n) = \mathrm{-M(A,Z)}+\mathrm{M(A-2,Z)}+ 00278 \mathrm{2M(n)}\f$: Two neutron separation energy \n 00279 \f$\mathrm{S}(2p) = \mathrm{-M(A,Z)}+\mathrm{M(A-2,Z-2)}+ 00280 \mathrm{2 M(H^{1)}}\f$: Two proton separation energy \n 00281 00282 \future Make the treatment of the electron binding energy 00283 contribution more consistent. 00284 00285 \future It might be useful to consider a fudge factor 00286 to ensure no problems with finite precision arithmetic 00287 when converting \c double to \c int. 00288 00289 */ 00290 class nuclear_mass : public nuclear_mass_info { 00291 public: 00292 00293 nuclear_mass(); 00294 00295 virtual ~nuclear_mass() {}; 00296 00297 /// Return the type, \c "nuclear_mass". 00298 virtual const char *type() { return "nuclear_mass"; } 00299 00300 /** 00301 \brief Return false if the mass formula does not include 00302 specified nucleus 00303 00304 \note By default, this returns false, so that children 00305 must overload this function if they do not provide masses 00306 for arbitrary nuclei. 00307 */ 00308 virtual bool is_included(int Z, int N) { 00309 return true; 00310 } 00311 00312 /** \brief Fill \c n with the information from nucleus with the given 00313 neutron and proton number 00314 00315 All masses are given in \f$\mathrm{fm}^{-1}\f$. The total mass 00316 (withouth the electrons) is put in part::m and part::ms, the 00317 binding energy is placed in nucleus::be, the mass excess in 00318 nucleus::mex and the degeneracy (part::g) is arbitrarily set 00319 to 1 for even A nuclei and 2 for odd A nuclei. 00320 00321 \warning The spin degeneracy is not handled particularly 00322 intelligently. This function simply assumes 0 spin for even A 00323 and spin 1/2 for odd A. 00324 */ 00325 int get_nucleus(int Z, int N, nucleus &n) { 00326 n.Z=Z; 00327 n.N=N; 00328 n.A=Z+N; 00329 n.mex=mass_excess(Z,N)/o2scl_const::hc_mev_fm; 00330 n.m=n.mex+((Z+N)*o2scl_fm::mass_amu-Z*o2scl_fm::mass_electron); 00331 n.ms=n.m; 00332 n.be=(n.m-N*o2scl_fm::mass_neutron-Z*o2scl_fm::mass_proton); 00333 if (n.A%2==0) n.g=1.0; 00334 else n.g=2.0; 00335 return 0; 00336 } 00337 00338 /// Given \c Z and \c N, return the mass excess in MeV 00339 virtual double mass_excess(int Z, int N)=0; 00340 00341 /// Given \c Z and \c N, return the mass excess in MeV 00342 virtual double mass_excess_d(double Z, double N)=0; 00343 00344 /** 00345 \brief Return the binding energy in MeV 00346 00347 The binding energy is defined to be negative for bound 00348 nuclei, thus the binding energy per baryon of Pb-208 00349 is about -8*208 = -1664 MeV. 00350 */ 00351 virtual double binding_energy(int Z, int N) { 00352 return (mass_excess(Z,N)+ 00353 ((Z+N)*o2scl_fm::mass_amu-Z*o2scl_fm::mass_electron- 00354 N*o2scl_fm::mass_neutron-Z*o2scl_fm::mass_proton)* 00355 o2scl_const::hc_mev_fm); 00356 } 00357 00358 /** 00359 \brief Return the binding energy in MeV 00360 00361 The binding energy is defined to be negative for bound 00362 nuclei, thus the binding energy per baryon of Pb-208 00363 is about -8*208 = -1664 MeV. 00364 */ 00365 virtual double binding_energy_d(double Z, double N) { 00366 return (mass_excess_d(Z,N)+ 00367 ((Z+N)*o2scl_fm::mass_amu-Z*o2scl_fm::mass_electron- 00368 N*o2scl_fm::mass_neutron-Z*o2scl_fm::mass_proton)* 00369 o2scl_const::hc_mev_fm); 00370 } 00371 00372 /** \brief Return the total mass of the nucleus (without the electrons) 00373 in MeV 00374 */ 00375 virtual double total_mass(int Z, int N) { 00376 return (mass_excess(Z,N)+((Z+N)*o2scl_fm::mass_amu- 00377 Z*o2scl_fm::mass_electron)* 00378 o2scl_const::hc_mev_fm); 00379 } 00380 00381 /** \brief Return the total mass of the nucleus (without the electrons) 00382 in MeV 00383 */ 00384 virtual double total_mass_d(double Z, double N) { 00385 return (mass_excess_d(Z,N)+((Z+N)*o2scl_fm::mass_amu- 00386 Z*o2scl_fm::mass_electron)* 00387 o2scl_const::hc_mev_fm); 00388 } 00389 00390 }; 00391 00392 /** \brief Discrete nuclear mass formula [abstract base] 00393 00394 This uses simple linear interpolation to obtain masses of 00395 nuclei with non-integer Z and N which may be particularly 00396 sensitive to the form of the pairing. 00397 */ 00398 class nuclear_mass_disc : public nuclear_mass { 00399 00400 public: 00401 00402 /// Given \c Z and \c N, return the mass excess in MeV 00403 virtual double mass_excess(int Z, int N)=0; 00404 00405 /// Given \c Z and \c N, return the mass excess in MeV 00406 virtual double mass_excess_d(double Z, double N) { 00407 int Z1=(int)Z; 00408 int N1=(int)N; 00409 double mz1n1=mass_excess(Z1,N1); 00410 double mz1n2=mass_excess(Z1,N1+1); 00411 double mz2n1=mass_excess(Z1+1,N1); 00412 double mz2n2=mass_excess(Z1+1,N1+1); 00413 double mz1=mz1n1+(N-N1)*(mz1n2-mz1n1); 00414 double mz2=mz2n1+(N-N1)*(mz2n2-mz2n1); 00415 return mz1+(Z-Z1)*(mz2-mz1); 00416 } 00417 00418 }; 00419 00420 /// Continuous nuclear mass formula [abstract base] 00421 class nuclear_mass_cont : public nuclear_mass { 00422 00423 public: 00424 00425 /// Given \c Z and \c N, return the mass excess in MeV 00426 virtual double mass_excess(int Z, int N) { 00427 return mass_excess_d(Z,N); 00428 } 00429 00430 /// Given \c Z and \c N, return the mass excess in MeV 00431 virtual double mass_excess_d(double Z, double N)=0; 00432 00433 }; 00434 00435 /** 00436 \brief Fittable mass formula 00437 00438 Nuclear mass formulas which are descendants of this class 00439 can be fit to experiment using \ref mass_fit. 00440 */ 00441 class nuclear_mass_fit : public nuclear_mass_cont { 00442 00443 public: 00444 00445 /// Return the type, \c "nuclear_mass_fit". 00446 virtual const char *type() { return "nuclear_mass_fit"; } 00447 00448 /// Number of fitting parameters 00449 size_t nfit; 00450 00451 /// Fix parameters from an array for fitting 00452 virtual int fit_fun(size_t nv, const ovector_base &x) { 00453 return 0; 00454 } 00455 00456 /// Fill array with guess from present values for fitting 00457 virtual int guess_fun(size_t nv, ovector_base &x) { 00458 return 0; 00459 } 00460 00461 }; 00462 00463 /** 00464 \brief Semi-empirical mass formula 00465 00466 A simple semi-empirical mass formula of the form 00467 \f[ 00468 E/A = B + S_s \frac{1}{A^{1/3}}+E_c \frac{Z^2}{A^{4/3}} 00469 + S_v \left(1-\frac{2Z}{A}\right)^2+E_{\mathrm{pair}}(Z,N) 00470 \f] 00471 where 00472 \f[ 00473 E_{\mathrm{pair}}(Z,N) = \frac{E_{\mathrm{pair}}}{A^{3/2}} 00474 \times 00475 \left\{ 00476 \begin{array}{rl} 00477 -1 & \mathrm{N~and~Z~even} \\ 00478 +1 & \mathrm{N~and~Z~odd} \\ 00479 0 & \mathrm{otherwise} 00480 \end{array} 00481 \right. 00482 \f] 00483 00484 \note The default parameters are arbitrary, and are not 00485 determined from a fit. 00486 00487 There is an example of the usage of this class given in 00488 \ref ex_mass_fit_sect. 00489 00490 */ 00491 class semi_empirical_mass : public nuclear_mass_fit { 00492 00493 public: 00494 00495 /// Binding energy (negative and in MeV, default -16) 00496 double B; 00497 00498 /// Symmetry energy (in MeV, default 23.7) 00499 double Sv; 00500 00501 /// Surface energy (in MeV, default 18) 00502 double Ss; 00503 00504 /// Coulomb energy (in MeV, default 0.7) 00505 double Ec; 00506 00507 /// Pairing energy (MeV, default 13.0) 00508 double Epair; 00509 00510 /// Return the type, \c "semi_empirical_mass". 00511 virtual const char *type() { return "semi_empirical_mass"; } 00512 00513 semi_empirical_mass() { 00514 B=-16.0; 00515 Ss=18.0; 00516 Ec=0.7; 00517 Sv=23.7; 00518 Epair=13.0; 00519 nfit=5; 00520 } 00521 00522 /// Given \c Z and \c N, return the mass excess in MeV 00523 virtual double mass_excess_d(double Z, double N) { 00524 double A=Z+N, cA=cbrt(A); 00525 double EoA=B+Ss/cA+Ec*Z*Z/cA/A+Sv*pow(1.0-2.0*Z/A,2.0); 00526 if (((int)(A-Z+0.01))%2==0 && ((int)(Z+0.01))%2==0) { 00527 EoA-=Epair/pow(A,1.5); 00528 } else if (((int)(A-Z+0.01))%2==1 && ((int)(Z+0.01))%2==1) { 00529 EoA+=Epair/pow(A,1.5); 00530 } 00531 double ret=EoA*A+Z*(o2scl_fm::mass_proton+o2scl_fm::mass_electron)* 00532 o2scl_const::hc_mev_fm+N*o2scl_fm::mass_neutron* 00533 o2scl_const::hc_mev_fm-A*o2scl_fm::mass_amu*o2scl_const::hc_mev_fm; 00534 return ret; 00535 } 00536 00537 /// Fix parameters from an array for fitting 00538 virtual int fit_fun(size_t nv, const ovector_base &x) { 00539 B=-x[0]; Sv=x[1]; Ss=x[2]; Ec=x[3]; Epair=x[4]; 00540 return 0; 00541 } 00542 00543 /// Fill array with guess from present values for fitting 00544 virtual int guess_fun(size_t nv, ovector_base &x) { 00545 x[0]=-B; x[1]=Sv; x[2]=Ss; x[3]=Ec; x[4]=Epair; 00546 return 0; 00547 } 00548 00549 }; 00550 00551 /** 00552 \brief Atomic mass entry structure 00553 */ 00554 typedef struct { 00555 00556 /// N-Z 00557 int NMZ; 00558 00559 /// Neutron number 00560 int N; 00561 00562 /// Proton number 00563 int Z; 00564 00565 /// Atomic number 00566 int A; 00567 00568 /// Element name 00569 std::string el; 00570 00571 /// Data origin 00572 std::string orig; 00573 00574 /// Mass excess 00575 double mass; 00576 00577 /// Mass excess uncertainty 00578 double dmass; 00579 00580 /// Binding energy (given in the '95 data) 00581 double be; 00582 00583 /// Binding energy uncertainty (given in the '95 data) 00584 double dbe; 00585 00586 /// Binding energy / A (given in the '03 data) 00587 double beoa; 00588 00589 /// Binding energy / A uncertainty (given in the '03 data) 00590 double dbeoa; 00591 00592 /// Beta decay mode 00593 std::string bdmode; 00594 00595 /// Beta-decay energy 00596 double bde; 00597 00598 /// Beta-decay energy uncertainty 00599 double dbde; 00600 00601 /// ? 00602 int A2; 00603 00604 /// Atomic mass 00605 double amass; 00606 00607 /// Atomic mass uncertainty 00608 double damass; 00609 00610 } ame_entry; 00611 00612 /** \brief A support class for I/O of the 1995 AME data 00613 */ 00614 class ame_entry95_io_type : public io_tlate<ame_entry> { 00615 public: 00616 int input(cinput *co, in_file_format *ins, ame_entry *t); 00617 int output(coutput *co, out_file_format *outs, ame_entry *t); 00618 virtual const char *type(); 00619 }; 00620 00621 /** \brief A support class for I/O of the 2003 AME data 00622 */ 00623 class ame_entry03_io_type : public io_tlate<ame_entry> { 00624 public: 00625 int input(cinput *co, in_file_format *ins, ame_entry *t); 00626 int output(coutput *co, out_file_format *outs, ame_entry *t); 00627 virtual const char *type(); 00628 }; 00629 00630 /** 00631 \brief Mass formula from the Atomic Mass Evaluation (2005 and 1993) 00632 00633 This class provides an interface to the atomic mass table using 00634 data from \ref Audi95 and \ref Audi03. 00635 00636 There are four data sets, selected by the specification of the 00637 \c version string in the constructor. 00638 - "95rmd" - "Recommended" data from \ref Audi95 (ame95rmd.o2) 00639 - "95exp" - "Experimental" data from \ref Audi95 (ame95exp.o2) 00640 - "03round" - "Rounded" data from \ref Audi03 (ame03round.o2) 00641 - "03" - Data from \ref Audi03 (default) (ame03.o2) 00642 00643 If any string other than these four is used, the default 00644 data is loaded. If the constructor cannot find the data file 00645 (e.g. because of a broken installation), then ame::is_loaded() 00646 returns false. 00647 00648 The 1995 data provided the binding energy stored in 00649 ame_entry::be and ame_entry::dbe, while the 2003 data provided 00650 the binding energy divided by the atomic number stored in 00651 ame_entry::beoa and ame_entry::dbeoa. When the 1995 data is used 00652 ame_entry::beoa and ame_entry::dbeoa are calculated automatically, 00653 and when the 2003 data is used ame_entry::be and ame_entry::dbe 00654 are calculated automatically. 00655 00656 Note that blank entries in the original table that correspond to 00657 columns represented by the type \c double are set to zero 00658 arbitrarily. 00659 00660 Note that all uncertainties are 1 sigma uncertainties. 00661 00662 \warning There are strict definitions of the atomic mass unit 00663 and other constants that are defined by the 1995 and 2003 00664 atomic mass evaluations which are not used at present. 00665 00666 \future Create a caching and more intelligent search system for 00667 the table. The table is sorted by A and then N, so we could 00668 probably just copy the search routine from mnmsk_mass, which is 00669 sorted by Z and then N. 00670 \future Use the atomic mass unit 00671 and other constants defined in the evaulation 00672 */ 00673 class ame_mass : public nuclear_mass_disc { 00674 public: 00675 00676 /// Create a collection specified by \c version 00677 ame_mass(std::string version=""); 00678 00679 /// Return the type, \c "ame_mass". 00680 virtual const char *type() { return "ame_mass"; } 00681 00682 /** 00683 \brief Return false if the mass formula does not include 00684 specified nucleus 00685 */ 00686 virtual bool is_included(int Z, int N); 00687 00688 /// Given \c Z and \c N, return the mass excess in MeV 00689 virtual double mass_excess(int Z, int N) { 00690 ame_entry ret; 00691 ret=get_ZN(Z,N); 00692 if (ret.Z==0 && ret.N==0) return 0.0; 00693 return ret.mass/1.0e3; 00694 } 00695 00696 /// Get element with Z=l_Z and N=l_N (e.g. 82,126). 00697 ame_entry get_ZN(int l_Z, int l_N); 00698 00699 /// Get element with Z=l_Z and A=l_A (e.g. 82,208). 00700 ame_entry get_ZA(int l_Z, int l_A); 00701 00702 /// Get element with name l_el and A=l_A (e.g. "Pb",208). 00703 ame_entry get_elA(std::string l_el, int l_A); 00704 00705 /// Get element with string (e.g. "Pb208") 00706 ame_entry get(std::string nucleus); 00707 00708 /// The number of entries (about 3000). 00709 int n; 00710 00711 /// The short names of the columns (length 16) 00712 std::string *short_names; 00713 00714 /// The long names of the columns (length 16) 00715 std::string *col_names; 00716 00717 /// The reference for the original data 00718 std::string reference; 00719 00720 /// The array containing the mass data of length ame::n 00721 ame_entry *mass; 00722 00723 /// Returns true if the constructor succesfully loaded the data 00724 bool is_loaded() { return loaded; } 00725 00726 #ifndef DOXYGEN_INTERNAL 00727 00728 protected: 00729 00730 /// True if loading the data was successful 00731 bool loaded; 00732 00733 #endif 00734 00735 }; 00736 00737 /** 00738 \brief Mass formula entry structure for Moller, et al. 00739 */ 00740 typedef struct { 00741 00742 /// Neutron number 00743 int N; 00744 00745 /// Proton number 00746 int Z; 00747 00748 /// Atomic number 00749 int A; 00750 00751 /** \name Ground state deformations (perturbed-spheroid parameterization) 00752 */ 00753 //@{ 00754 /// Quadrupole 00755 double eps2; 00756 /// Octupole 00757 double eps3; 00758 /// Hexadecapole 00759 double eps4; 00760 /// Hexacontatetrapole 00761 double eps6; 00762 /// Hexacontatetrapole without mass asymmetry 00763 double eps6sym; 00764 //@} 00765 00766 /** \name Ground state deformations in the spherical-harmonics expansion 00767 */ 00768 //@{ 00769 /// Quadrupole 00770 double beta2; 00771 /// Octupole 00772 double beta3; 00773 /// Hexadecapole 00774 double beta4; 00775 /// Hexacontatetrapole 00776 double beta6; 00777 //@} 00778 00779 /// The ground-state microscopic energy 00780 double Emic; 00781 00782 /// The theoretical mass excess (in MeV) 00783 double Mth; 00784 00785 /// The experimental mass excess (in MeV) 00786 double Mexp; 00787 00788 /// Experimental mass excess error 00789 double sigmaexp; 00790 00791 /// The ground-state microscopic energy in the FRLDM 00792 double EmicFL; 00793 00794 /// The theoretical mass excess in the FRLDM 00795 double MthFL; 00796 00797 /// Spin and pairity of odd proton 00798 std::string spinp; 00799 00800 /// Spin and pairity of odd neutron 00801 std::string spinn; 00802 00803 /// Lipkin-Nogami proton gap 00804 double gapp; 00805 00806 /// Lipkin-Nogami neutron gap 00807 double gapn; 00808 00809 /// Total binding energy 00810 double be; 00811 00812 /// One neutron separation energy 00813 double S1n; 00814 00815 /// Two neutron separation energy 00816 double S2n; 00817 00818 /** 00819 \brief Percentage of daughters generated in beta decay after 00820 beta-delayed neutron emission 00821 */ 00822 double PA; 00823 00824 /// Desc 00825 double PAm1; 00826 00827 /// Desc 00828 double PAm2; 00829 00830 /// Energy released in beta-decay 00831 double Qbeta; 00832 00833 /// Half-life w.r.t. GT beta-decay 00834 double Tbeta; 00835 00836 /// One proton separation energy 00837 double S1p; 00838 00839 /// Two proton separation energy 00840 double S2p; 00841 00842 /// Energy released in alpha-decay 00843 double Qalpha; 00844 00845 /// Half-life w.r.t. alpha-decay 00846 double Talpha; 00847 00848 00849 } mnmsk_mass_entry; 00850 00851 template<> int io_tlate<mnmsk_mass_entry>::input 00852 (cinput *co, in_file_format *ins, mnmsk_mass_entry *t); 00853 template<> int io_tlate<mnmsk_mass_entry>::output 00854 (coutput *co, out_file_format *outs, mnmsk_mass_entry *t); 00855 template<> const char *io_tlate<mnmsk_mass_entry>::type(); 00856 00857 typedef io_tlate<mnmsk_mass_entry> mnmsk_mass_entry_io_type; 00858 00859 /** 00860 \brief Mass formula from Moller, Nix, Myers and Swiatecki 00861 00862 The data containing an object of type moller_mass_entry for 8979 00863 nuclei is automatically loaded by the constructor. If the file 00864 (nucmass/mnmsk.o2) is not found, then is_loaded() will return 00865 false and all calls to get_ZN() will return an object with \c 00866 N=Z=0. 00867 00868 There are several entries in the original table which are 00869 blank because they are in some way not known, measured, or 00870 computable. To distinguish these values from zero, blank entries 00871 have been replaced by the number \c 1.0e99. For convenience, 00872 this value is returned by \ref blank(). 00873 */ 00874 class mnmsk_mass : public nuclear_mass_disc { 00875 public: 00876 00877 mnmsk_mass(); 00878 00879 virtual ~mnmsk_mass() { 00880 if (loaded) { 00881 delete[] mass; 00882 } 00883 } 00884 00885 /** 00886 \brief Return false if the mass formula does not include 00887 specified nucleus 00888 */ 00889 virtual bool is_included(int Z, int N); 00890 00891 /// Given \c Z and \c N, return the mass excess in MeV 00892 virtual double mass_excess(int Z, int N) { 00893 mnmsk_mass_entry ret; 00894 ret=get_ZN(Z,N); 00895 if (ret.Z==0 && ret.N==0) return 0.0; 00896 return ret.Mth; 00897 } 00898 00899 /** 00900 \brief Get the entry for the specified proton and neutron number 00901 00902 This method searches the table using a cached binary search 00903 algorithm. It is assumed that the table is sorted first by 00904 proton number and then by neutron number. 00905 */ 00906 mnmsk_mass_entry get_ZN(int l_Z, int l_N); 00907 00908 /// Verify that the constructor properly loaded the table 00909 bool is_loaded() { return loaded; }; 00910 00911 /// The number of table entries 00912 int n; 00913 00914 /// The array containing the table 00915 mnmsk_mass_entry *mass; 00916 00917 /// The value which corresponds to a blank entry 00918 double blank() { return 1.0e99; }; 00919 00920 /// Neither beta+ or beta- is possible 00921 double neither() { return 1.0e98; }; 00922 00923 /// The value which corresponds to a blank entry 00924 double beta_stable() { return 1.0e97; }; 00925 00926 /// Both beta+ and beta- are possible 00927 double beta_plus_and_minus() { return 1.0e96; }; 00928 00929 /// The value is greater than 100 00930 double greater_100() { return 1.0e95; }; 00931 00932 /// The value is greater than \f$ 10^{20} \f$ 00933 double very_large() { return 1.0e94; }; 00934 00935 /// Return the type, \c "mnmsk_mass". 00936 virtual const char *type() { return "mnmsk_mass"; } 00937 00938 #ifndef DOXYGEN_INTERNAL 00939 00940 protected: 00941 00942 /// True if the table was successfully loaded 00943 bool loaded; 00944 00945 /// The last table index for caching 00946 int last; 00947 00948 #endif 00949 00950 }; 00951 00952 /// The experimental values from Moller, Nix, Myers and Swiatecki 00953 class mnmsk_mass_exp : public mnmsk_mass { 00954 00955 public: 00956 00957 /** 00958 \brief Return false if the mass formula does not include 00959 specified nucleus 00960 */ 00961 virtual bool is_included(int Z, int N); 00962 00963 /// Given \c Z and \c N, return the mass excess in MeV 00964 virtual double mass_excess(int Z, int N) { 00965 mnmsk_mass_entry ret; 00966 ret=get_ZN(Z,N); 00967 if (ret.Z==0 && ret.N==0) return 0.0; 00968 return ret.Mexp; 00969 } 00970 00971 }; 00972 00973 /** 00974 \brief Mass formula entry structure for HFB mass formula 00975 */ 00976 typedef struct { 00977 00978 /// Neutron number 00979 int N; 00980 00981 /// Proton number 00982 int Z; 00983 00984 /// Atomic number 00985 int A; 00986 00987 /// Beta 2 deformation 00988 double bet2; 00989 00990 /// Beta 4 deformation 00991 double bet4; 00992 00993 /// RMS charge radius 00994 double Rch; 00995 00996 /// Deformation and Wigner energies 00997 double def_wig; 00998 00999 /// Neutron separation energy 01000 double Sn; 01001 01002 /// Proton separation energy 01003 double Sp; 01004 01005 /// Beta-decay energy 01006 double Qbet; 01007 01008 /// Calculated mass excess 01009 double Mcal; 01010 01011 /// Error between experimental and calculated mass excess 01012 double Err; 01013 01014 } hfb_mass_entry; 01015 01016 /** 01017 \brief HFB Mass formula 01018 */ 01019 class hfb_mass : public nuclear_mass_disc { 01020 01021 public: 01022 01023 /** \brief Create a new mass formula object using the specified model 01024 number 01025 01026 Valid values of \c model at present are 2, 8, and 14, corresponding 01027 to the HFB2 (\ref Goriely02), HFB8 (\ref Samyn04), and HFB14 01028 (\ref Goriely07). If a number other than these three is given, 01029 the error handler is called. 01030 */ 01031 hfb_mass(size_t model=14); 01032 01033 virtual ~hfb_mass() { 01034 if (loaded) { 01035 delete[] mass; 01036 } 01037 } 01038 01039 /** 01040 \brief Return false if the mass formula does not include 01041 specified nucleus 01042 */ 01043 virtual bool is_included(int Z, int N); 01044 01045 /// Given \c Z and \c N, return the mass excess in MeV 01046 virtual double mass_excess(int Z, int N) { 01047 hfb_mass_entry ret; 01048 ret=get_ZN(Z,N); 01049 if (ret.Z==0 && ret.N==0) return 0.0; 01050 return ret.Mcal; 01051 } 01052 01053 /** 01054 \brief Get the entry for the specified proton and neutron number 01055 01056 This method searches the table using a cached binary search 01057 algorithm. It is assumed that the table is sorted first by 01058 proton number and then by neutron number. 01059 */ 01060 hfb_mass_entry get_ZN(int l_Z, int l_N); 01061 01062 /// Verify that the constructor properly loaded the table 01063 bool is_loaded() { return loaded; }; 01064 01065 /// The number of table entries 01066 int n; 01067 01068 /// The array containing the table 01069 hfb_mass_entry *mass; 01070 01071 /// The value which corresponds to a blank entry 01072 double blank() { return 1.0e99; }; 01073 01074 /// Return the type, \c "hfb_mass". 01075 virtual const char *type() { return "hfb_mass"; } 01076 01077 #ifndef DOXYGEN_INTERNAL 01078 01079 protected: 01080 01081 /// True if the table was successfully loaded 01082 bool loaded; 01083 01084 /// The last table index for caching 01085 int last; 01086 01087 #endif 01088 01089 }; 01090 01091 01092 #ifndef DOXYGENP 01093 } 01094 #endif 01095 01096 #endif
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page