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 friend int operator==(const nuclear_dist::iterator &i1, 00117 const nuclear_dist::iterator &i2); 00118 00119 friend int operator!=(const nuclear_dist::iterator &i1, 00120 const nuclear_dist::iterator &i2); 00121 }; 00122 00123 /// The beginning of the distribution 00124 virtual iterator begin()=0; 00125 00126 /// The end of the distribution 00127 virtual iterator end()=0; 00128 00129 /// The number of nuclei in the distribution 00130 virtual size_t size()=0; 00131 }; 00132 00133 /// Compare two nuclei 00134 int operator==(const nuclear_dist::iterator &i1, 00135 const nuclear_dist::iterator &i2); 00136 00137 /// Compare two nuclei 00138 int operator!=(const nuclear_dist::iterator &i1, 00139 const nuclear_dist::iterator &i2); 00140 00141 /** 00142 \brief A simple nuclear distribution given a range in A and Z 00143 00144 The iterator for this distribution begins with the nucleus with 00145 the lowest Z and A, and increases A before incrementing Z and 00146 beginning again with the lowest A for that value of Z. In other 00147 words, it proceeds through all the isotopes of an element first, 00148 and then proceeds to the next element. 00149 00150 For example, to create a \collection of isotopes of Carbon, 00151 Nitrogen and Oxygen using the most recent (2003) Atomic Mass 00152 Evaluation, and then output the nuclei in the \collection 00153 \code 00154 ame_mass ame; 00155 simple_dist fd(6,8,2,30,&ame); 00156 for(nuclear_dist::iterator ndi=fd.begin();ndi!=fd.end();ndi++) { 00157 cout << ndi->Z << " " << ndi->A << " " << ndi->m << endl; 00158 } 00159 \endcode 00160 00161 \future Make the vector constructor into a template so it 00162 accepts any type. Do the same for set_dist(). 00163 */ 00164 class simple_dist : public nuclear_dist { 00165 public: 00166 00167 /// Create an empty distribution 00168 simple_dist(); 00169 00170 /** \brief Create a distribution from ranges in A specified 00171 for each Z 00172 00173 The length of the arrays minA and maxA should be exactly 00174 \f$\mathrm{maxZ}-\mathrm{minZ}+1\f$. 00175 */ 00176 simple_dist(int minZ, int maxZ, int minA[], int maxA[], 00177 nuclear_mass &nm); 00178 00179 /// Create a square distribution in A and Z 00180 simple_dist(int minZ, int maxZ, int minA, int maxA, 00181 nuclear_mass &nm); 00182 00183 virtual ~simple_dist(); 00184 00185 /// The beginning of the distribution 00186 virtual iterator begin() { 00187 return iterator(this,list); 00188 }; 00189 00190 /// The end of the distribution 00191 virtual iterator end() { 00192 return iterator(this,list+list_size); 00193 }; 00194 00195 /// The number of nuclei in the distribution 00196 virtual size_t size() { 00197 return list_size; 00198 }; 00199 00200 /** \brief Set the distribution from ranges in A specified 00201 for each Z 00202 00203 The length of the arrays minA and maxA should be exactly 00204 \f$\mathrm{maxZ}-\mathrm{minZ}+1\f$. 00205 */ 00206 int set_dist(int minZ, int maxZ, int minA[], int maxA[], 00207 nuclear_mass &nm); 00208 00209 /// Set a square distribution in A and Z 00210 int set_dist(int minZ, int maxZ, int minA, int maxA, 00211 nuclear_mass &nm); 00212 00213 #ifndef DOXYGENP 00214 00215 protected: 00216 00217 /// Specify how to move to the next nucleus 00218 virtual nucleus *next(nucleus *np) { 00219 return np+1; 00220 } 00221 00222 /// The distribution of nuclei as an array 00223 nucleus *list; 00224 00225 /// The size of \ref list array 00226 size_t list_size; 00227 00228 #endif 00229 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-1]); 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 and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page