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