![]() |
Particles and Nuclei Sub-Library: Version 0.910
|
00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006-2012, 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_DIST_H 00024 #define O2SCL_NUCLEAR_DIST_H 00025 00026 #include <iostream> 00027 #include <o2scl/nucleus.h> 00028 #include <o2scl/nuclear_mass.h> 00029 00030 #ifndef DOXYGENP 00031 namespace o2scl { 00032 #endif 00033 00034 /** \brief A distribution of nuclei [abstract base] 00035 00036 The virtual base class for a collection of objects of type \ref 00037 nucleus . See \ref simple_dist and \ref full_dist for 00038 implmentations of this base class. 00039 */ 00040 class nuclear_dist { 00041 00042 #ifndef DOXYGENP 00043 00044 protected: 00045 00046 /// The function the iterator uses to compute the next nucleus 00047 virtual nucleus *next(nucleus *np)=0; 00048 00049 #endif 00050 00051 public: 00052 00053 virtual ~nuclear_dist() {} 00054 00055 /** \brief An iterator for the nuclear distribution 00056 00057 The standard usage of this iterator is something of the form: 00058 \code 00059 mnmsk_mass mth; 00060 simple_dist sd(5,6,10,12,&mth); 00061 for(nuclear_dist::iterator ndi=sd.begin();ndi!=sd.end();ndi++) { 00062 // do something here for each nucleus 00063 } 00064 \endcode 00065 which would create a list consisting of three isotopes (A=10, 00066 11, and 12) of boron and three isotopes carbon for a total 00067 of six nuclei. 00068 */ 00069 class iterator { 00070 00071 #ifndef DOXYGEN_INTERNAL 00072 00073 protected: 00074 00075 /// A pointer to the current nucleus 00076 nucleus *np; 00077 00078 /// A pointer to the distribution 00079 nuclear_dist *ndp; 00080 00081 #endif 00082 00083 public: 00084 00085 /** \brief Create an iterator from the given distribution using the 00086 nucleus specified in \c npp. 00087 */ 00088 iterator(nuclear_dist *ndpp, nucleus *npp) { 00089 ndp=ndpp; 00090 np=npp; 00091 } 00092 00093 /// Proceed to the next nucleus 00094 iterator operator++() { 00095 np=ndp->next(np); 00096 return iterator(ndp,np); 00097 } 00098 00099 /// Proceed to the next nucleus 00100 iterator operator++(int unused) { 00101 nucleus *tmp=np; 00102 np=ndp->next(np); 00103 return iterator(ndp,tmp); 00104 } 00105 00106 /// Pointing at operator 00107 nucleus *operator->() const { 00108 return np; 00109 } 00110 00111 /// Dereference the iterator 00112 nucleus &operator*() const { 00113 return *np; 00114 } 00115 00116 /// Give access to the == operator 00117 friend bool operator==(const nuclear_dist::iterator &i1, 00118 const nuclear_dist::iterator &i2); 00119 00120 /// Give access to the != operator 00121 friend bool operator!=(const nuclear_dist::iterator &i1, 00122 const nuclear_dist::iterator &i2); 00123 }; 00124 00125 /// The beginning of the distribution 00126 virtual iterator begin()=0; 00127 00128 /// The end of the distribution 00129 virtual iterator end()=0; 00130 00131 /// The number of nuclei in the distribution 00132 virtual size_t size()=0; 00133 }; 00134 00135 /// Compare two nuclei 00136 bool operator==(const nuclear_dist::iterator &i1, 00137 const nuclear_dist::iterator &i2); 00138 00139 /// Compare two nuclei 00140 bool operator!=(const nuclear_dist::iterator &i1, 00141 const nuclear_dist::iterator &i2); 00142 00143 /** \brief A simple nuclear distribution given a range in A and Z 00144 00145 The iterator for this distribution begins with the nucleus with 00146 the lowest Z and A, and increases A before incrementing Z and 00147 beginning again with the lowest A for that value of Z. In other 00148 words, it proceeds through all the isotopes of an element first, 00149 and then proceeds to the next element. 00150 00151 For example, to create a collection of isotopes of Carbon, 00152 Nitrogen and Oxygen using the most recent (2003) Atomic Mass 00153 Evaluation, and then output the nuclei in the collection 00154 \code 00155 ame_mass ame; 00156 simple_dist fd(6,8,2,30,&ame); 00157 for(nuclear_dist::iterator ndi=fd.begin();ndi!=fd.end();ndi++) { 00158 cout << ndi->Z << " " << ndi->A << " " << ndi->m << endl; 00159 } 00160 \endcode 00161 00162 \future Make the vector constructor into a template so it 00163 accepts any type. Do the same for set_dist(). 00164 */ 00165 class simple_dist : public nuclear_dist { 00166 public: 00167 00168 /// Create an empty distribution 00169 simple_dist(); 00170 00171 /** \brief Create a distribution from ranges in A specified 00172 for each Z 00173 00174 The length of the arrays minA and maxA should be exactly 00175 \f$\mathrm{maxZ}-\mathrm{minZ}+1\f$. 00176 */ 00177 simple_dist(int minZ, int maxZ, int minA[], int maxA[], 00178 nuclear_mass &nm); 00179 00180 /// Create a square distribution in A and Z 00181 simple_dist(int minZ, int maxZ, int minA, int maxA, 00182 nuclear_mass &nm); 00183 00184 virtual ~simple_dist(); 00185 00186 /// The beginning of the distribution 00187 virtual iterator begin() { 00188 return iterator(this,list); 00189 }; 00190 00191 /// The end of the distribution 00192 virtual iterator end() { 00193 return iterator(this,list+list_size); 00194 }; 00195 00196 /// The number of nuclei in the distribution 00197 virtual size_t size() { 00198 return list_size; 00199 }; 00200 00201 /** \brief Set the distribution from ranges in A specified 00202 for each Z 00203 00204 The length of the arrays minA and maxA should be exactly 00205 \f$\mathrm{maxZ}-\mathrm{minZ}+1\f$. 00206 */ 00207 int set_dist(int minZ, int maxZ, int minA[], int maxA[], 00208 nuclear_mass &nm); 00209 00210 /// Set a square distribution in A and Z 00211 int set_dist(int minZ, int maxZ, int minA, int maxA, 00212 nuclear_mass &nm); 00213 00214 #ifndef DOXYGENP 00215 00216 protected: 00217 00218 /// Specify how to move to the next nucleus 00219 virtual nucleus *next(nucleus *np) { 00220 return np+1; 00221 } 00222 00223 /// The distribution of nuclei as an array 00224 nucleus *list; 00225 00226 /// The size of \ref list array 00227 size_t list_size; 00228 00229 #endif 00230 00231 }; 00232 00233 /** \brief Full distribution including all nuclei from a 00234 discrete mass formula 00235 00236 For example, to create a collection of all nuclei from the most 00237 recent (2003) Atomic Mass Evaluation, and then output all the 00238 nuclei in the collection 00239 \code 00240 ame_mass ame; 00241 full_dist fd(&ame); 00242 for(nuclear_dist::iterator ndi=fd.begin();ndi!=fd.end();ndi++) { 00243 cout << ndi->Z << " " << ndi->A << " " << ndi->m << endl; 00244 } 00245 \endcode 00246 00247 */ 00248 class full_dist : public nuclear_dist { 00249 00250 public: 00251 00252 full_dist() { 00253 list_size=0; 00254 } 00255 00256 virtual ~full_dist() { 00257 if (list_size>0) delete[] list; 00258 } 00259 00260 /** \brief Create a distribution including all nuclei with atomic 00261 numbers less than \c maxA from the mass formula \c nm 00262 */ 00263 full_dist(nuclear_mass &nm, int maxA=400, bool include_neutron=false); 00264 00265 /** \brief Set the distribution to all nuclei with atomic 00266 numbers less than \c maxA from the mass formula \c nm 00267 00268 The information for the previous distribution is cleared 00269 before a new distribution is set. 00270 */ 00271 int set_dist(nuclear_mass &nm, int maxA=400, bool include_neutron=false); 00272 00273 /// The beginning of the distribution 00274 virtual iterator begin() { 00275 return iterator(this,&list[0]); 00276 }; 00277 00278 /// The end of the distribution 00279 virtual iterator end() { 00280 return iterator(this,&list[list_size]); 00281 }; 00282 00283 /// The number of nuclei in the distribution 00284 virtual size_t size() { 00285 return list_size; 00286 }; 00287 00288 #ifndef DOXYGENP 00289 00290 protected: 00291 00292 /// Specify how to move to the next nucleus 00293 virtual nucleus *next(nucleus *np) { 00294 return np+1; 00295 } 00296 00297 /// The distribution of nuclei as an array 00298 nucleus *list; 00299 00300 /// The size of \ref list array 00301 size_t list_size; 00302 00303 #endif 00304 00305 }; 00306 00307 #ifndef DOXYGENP 00308 } 00309 #endif 00310 00311 #endif
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).