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