Particles and Nuclei Sub-Library: Version 0.910
nuclear_dist.h
00001 /*
00002   -------------------------------------------------------------------
00003   
00004   Copyright (C) 2006-2012, 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   /** \brief A distribution of nuclei [abstract base]
00035       
00036       The virtual base class for a collection of objects of type \ref
00037       nucleus . See \ref simple_dist and \ref full_dist for
00038       implmentations of this base class.
00039    */
00040   class nuclear_dist {
00041 
00042 #ifndef DOXYGENP
00043 
00044   protected:
00045 
00046     /// The function the iterator uses to compute the next nucleus
00047     virtual nucleus *next(nucleus *np)=0;
00048 
00049 #endif
00050     
00051   public:
00052 
00053     virtual ~nuclear_dist() {}
00054     
00055     /** \brief An iterator for the nuclear distribution
00056         
00057         The standard usage of this iterator is something of the form:
00058         \code
00059         mnmsk_mass mth;
00060         simple_dist sd(5,6,10,12,&mth);
00061         for(nuclear_dist::iterator ndi=sd.begin();ndi!=sd.end();ndi++) {
00062         // do something here for each nucleus
00063         }
00064         \endcode
00065         which would create a list consisting of three isotopes (A=10,
00066         11, and 12) of boron and three isotopes carbon for a total
00067         of six nuclei.
00068     */
00069     class iterator {
00070       
00071 #ifndef DOXYGEN_INTERNAL
00072 
00073     protected:
00074 
00075       /// A pointer to the current nucleus 
00076       nucleus *np;
00077 
00078       /// A pointer to the distribution
00079       nuclear_dist *ndp;
00080 
00081 #endif
00082 
00083     public:
00084 
00085       /** \brief Create an iterator from the given distribution using the
00086           nucleus specified in \c npp.
00087       */
00088       iterator(nuclear_dist *ndpp, nucleus *npp) {
00089         ndp=ndpp;
00090         np=npp;
00091       }
00092 
00093       /// Proceed to the next nucleus
00094       iterator operator++() {
00095         np=ndp->next(np);
00096         return iterator(ndp,np);
00097       }
00098 
00099       /// Proceed to the next nucleus
00100       iterator operator++(int unused) {
00101         nucleus *tmp=np;
00102         np=ndp->next(np);
00103         return iterator(ndp,tmp);
00104       }
00105 
00106       /// Pointing at operator
00107       nucleus *operator->() const {
00108         return np;
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   /** \brief A simple nuclear distribution given a range in A and Z
00144       
00145       The iterator for this distribution begins with the nucleus with
00146       the lowest Z and A, and increases A before incrementing Z and
00147       beginning again with the lowest A for that value of Z. In other
00148       words, it proceeds through all the isotopes of an element first,
00149       and then proceeds to the next element.
00150 
00151       For example, to create a collection of isotopes of Carbon,
00152       Nitrogen and Oxygen using the most recent (2003) Atomic Mass
00153       Evaluation, and then output the nuclei in the collection
00154       \code
00155       ame_mass ame;
00156       simple_dist fd(6,8,2,30,&ame);
00157       for(nuclear_dist::iterator ndi=fd.begin();ndi!=fd.end();ndi++) {
00158         cout << ndi->Z << " " << ndi->A << " " << ndi->m << endl;
00159       }
00160       \endcode
00161 
00162       \future Make the vector constructor into a template so it
00163       accepts any type. Do the same for set_dist().
00164   */
00165   class simple_dist : public nuclear_dist {
00166   public:
00167 
00168     /// Create an empty distribution
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 size of \ref list array
00227     size_t list_size;
00228 
00229 #endif
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]);
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
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Friends

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.