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