00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 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 // The iterator is really just a wrapper for the pointer 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 \todo This takes a nuclear_mass pointer as input. It should 00162 probably be a reference instead? (3/18/08 - Yeah, I think 00163 it should be a reference.) 00164 \todo Add error checking in constructors and set functions 00165 */ 00166 class simple_dist : public nuclear_dist { 00167 public: 00168 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 minimum atomic number for a given Z 00227 int *min_A; 00228 00229 /// The maximum atomic number for a given Z 00230 int *max_A; 00231 00232 /// The minimum proton number 00233 int min_Z; 00234 00235 /// The maximum proton number 00236 int max_Z; 00237 00238 /// The size of \ref list array 00239 size_t list_size; 00240 00241 /// True if memory has been allocated 00242 bool alloc; 00243 00244 #endif 00245 00246 }; 00247 00248 /** 00249 \brief Full distribution including all nuclei from a 00250 discrete mass formula 00251 00252 For example, to create a collection of all nuclei from the most 00253 recent (2003) Atomic Mass Evaluation, and then output all the 00254 nuclei in the collection 00255 \code 00256 ame_mass ame; 00257 full_dist fd(&ame); 00258 for(nuclear_dist::iterator ndi=fd.begin();ndi!=fd.end();ndi++) { 00259 cout << ndi->Z << " " << ndi->A << " " << ndi->m << endl; 00260 } 00261 \endcode 00262 00263 */ 00264 class full_dist : public nuclear_dist { 00265 00266 public: 00267 00268 full_dist() { 00269 list_size=0; 00270 } 00271 00272 virtual ~full_dist() { 00273 if (list_size>0) delete[] list; 00274 } 00275 00276 /** \brief Create a distribution including all nuclei with atomic 00277 numbers less than \c maxA from the mass formula \c nm 00278 */ 00279 full_dist(nuclear_mass *nm, int maxA=400, bool include_neutron=false); 00280 00281 /** \brief Set the distribution to all nuclei with atomic 00282 numbers less than \c maxA from the mass formula \c nm 00283 00284 The information for the previous distribution is cleared 00285 before a new distribution is set. 00286 */ 00287 int set_dist(nuclear_mass *nm, int maxA=400, bool include_neutron=false); 00288 00289 /// The beginning of the distribution 00290 virtual iterator begin() { 00291 return iterator(this,&list[0]); 00292 }; 00293 00294 /// The end of the distribution 00295 virtual iterator end() { 00296 return iterator(this,&list[list_size-1]); 00297 }; 00298 00299 /// The number of nuclei in the distribution 00300 virtual size_t size() { 00301 return list_size; 00302 }; 00303 00304 #ifndef DOXYGENP 00305 00306 protected: 00307 00308 /// Specify how to move to the next nucleus 00309 virtual nucleus *next(nucleus *np) { 00310 return np+1; 00311 } 00312 00313 /// The distribution of nuclei as an array 00314 nucleus *list; 00315 00316 /// The size of \ref list array 00317 size_t list_size; 00318 00319 #endif 00320 00321 }; 00322 00323 #ifndef DOXYGENP 00324 } 00325 #endif 00326 00327 #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